v0.162.0 — R-71(a): the apply-bridge settle-gate (kills the F10 day-0 race)
The day-0 race (DIAG-f10): a fresh box boots below the operator floor, the apply-bridge consumes the single-use offsite password, then ~35s later the managed auto-floor update replaces the container mid-install -> the new process finds no installed key -> consume -> 404 -> offsite dead until an operator Re-issue. Recurs on every onboarding whose ISO floor lags the managed floor. Ordering-only fix (consume/install/persist internals + the 404-no-oracle contract + the Consumer UNTOUCHED; R-71(b) rejected-by-design): - New seam offsiteapply.SettleProvider.SettleState() + SettleFunc adapter over the self-updater's own GetFloor()/IsUpdateRunning() (no second floor path). - Bridge.AwaitSettle polls 10s BEFORE the 3-min Reconcile ctx: defers while an update runs or the box is below the known floor; GOes at/above floor on the first poll with zero added latency (B'). Bounds 90s floor sub-bound / 5min overall, both GO+WARN (hub that can't serve a floor can't serve a consume -> no burn risk; R-71c is the belt). ReconcileWhenSettled = gate then reconcile. - main.go: bridge goroutine moved after the updater is built; wired only when an updater exists (nil Settle = reconcile immediately, old behavior). Finding: the floor is in-memory (report-ACK ~5-10s), NOT persisted -> unknown on any restart until the first ACK; the 90s sub-bound is sized to that. Tests (injectable clock, fake SettleState, recorded Consumer): A-E + nil-provider + cancelled-gate. Four red-proofs all observed FAIL then restored: gate removed / updateRunning branch / floor sub-bound / overall bound. Deferral paths ship unit-proven + red-proofed, NOT live-fired -- their precondition is now structurally prevented by the v1.25.0 build gate. Layering: gate prevents, (a) defers, (c) heals. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7Drmtm2RzoqbkJZCNSFNQ
This commit is contained in:
@@ -1058,6 +1058,21 @@ not just those with HDD data. Non-HDD apps can configure destination, method, an
|
||||
> recovery for a genuinely-spent password on a fresh guest.
|
||||
> - **Staged-secret wipe (v0.107.0):** confirm-escrow calls the agent's `DELETE /escrow/stage-secret`
|
||||
> (agent ≥ v0.78.0) whenever `EscrowState` flips to `escrowed` — best-effort, loud-logged on failure.
|
||||
> - **Settle-gate (R-71a, v0.162.0) — the day-0 race removed.** The apply-bridge runs BEHIND a
|
||||
> settle-gate (`Bridge.AwaitSettle` → `ReconcileWhenSettled`): before the consume/install path it
|
||||
> polls the self-updater's own state via the `SettleProvider` seam (a `SettleFunc` adapter over
|
||||
> `updater.GetFloor()`/`IsUpdateRunning()` in main.go — no second floor-fetch path). While a managed
|
||||
> update is running OR the box is below the operator floor (an auto-floor update is imminent), the
|
||||
> gate WAITS rather than consume the single-use password — the update's restart would otherwise kill
|
||||
> the bridge mid-install and burn it (the F10 day-0 shape). At/above floor with no update in flight,
|
||||
> it GOes on the first poll with zero added latency (B′). Bounds: 10 s poll, 90 s floor-knowledge
|
||||
> sub-bound (sized to the ~5–10 s report-ACK floor latency; the floor is in-memory, not persisted,
|
||||
> so it is unknown until the first ACK on any restart), 5 min overall — both bounds GO+WARN and lean
|
||||
> on the R-71c hub self-heal as the belt (a hub that cannot serve a floor cannot serve a consume, so
|
||||
> proceeding never burns a password). The gate is wired only when a self-updater exists (no updater
|
||||
> → no floor-update to race → reconcile immediately). Ordering-only: the consume/install/persist
|
||||
> internals and the 404-no-oracle contract are untouched. Three-layer defense: the v1.25.0
|
||||
> golden≥floor build gate PREVENTS the trigger, (a) DEFERS it, R-71c HEALS a burn.
|
||||
|
||||
> **NAS network storage (v0.92.0, Part A2; pairs with agent v0.50.0).** A customer NAS share (NFS or SMB)
|
||||
> is a **distinct storage KIND** from a physical drive (`StoragePath.Kind == "network"`), for **bulk media**.
|
||||
|
||||
Reference in New Issue
Block a user