PlatformHalt is a consequence of the Policy::Required
diff --git a/docs/src/design/orchestrator/orchestrator-machine.md b/docs/src/design/orchestrator/orchestrator-machine.md index b4945f8..d6c8103 100644 --- a/docs/src/design/orchestrator/orchestrator-machine.md +++ b/docs/src/design/orchestrator/orchestrator-machine.md
@@ -34,7 +34,7 @@ Recovering --> PreSupervision : Restored [retry < max_retry]<br/>(re-verify) Recovering --> PreSupervision : Restored [retry ≥ max_retry, Isolable/Cascading]<br/>/ AssertReset (skip — held) - Recovering --> Locked : Restored [retry ≥ max_retry, PlatformHalt]<br/>(self-emits RecoveryFailed) / LatchLockdown + Recovering --> Locked : Restored [retry ≥ max_retry, Required]<br/>(self-emits RecoveryFailed) / LatchLockdown Locked --> Locked : (terminal — all events ignored) ``` @@ -54,7 +54,7 @@ | `held` | `Vec<ComponentId, N>` | Components skipped because their recovery was **exhausted**: an `Isolable` component, or a `Cascading` component plus its `depends_on` dependents. Not verified during the walk — held in reset, cursor advances past them. Populated in `Recovering` when `retry_count` reaches `max_retry`; persists across re-walks; cleared on `Ready` entry. | | `failed` | `Option<ComponentId>` | The component whose recovery episode is in progress; `None` while healthy. Set on any `VerificationFailed`, `Timeout`, or `CorruptionDetected` of a managed component. | | `retry_count` | `u8` | Number of consecutive failed restore attempts in the current recovery episode. Cleared to 0 in `Ready`'s entry action — consecutive only (INV7). | -| `max_retry` | `u8` | Shell-chosen ceiling for `retry_count`. When `retry_count >= max_retry` recovery is **exhausted** and the failed component's recovery-failure policy (`Isolable`/`Cascading`/`PlatformHalt`) is applied. | +| `max_retry` | `u8` | Shell-chosen ceiling for `retry_count`. When `retry_count >= max_retry` recovery is **exhausted** and the failed component's recovery-failure policy (`Isolable`/`Cascading`/`Required`) is applied. | | `awaiting` | `Option<ComponentId>` | The `Active` component whose iRoT readiness is currently outstanding. `Some` only while in `AwaitingReady`; `None` everywhere else (INV9). | The effect buffer is deliberately **absent** from `Rot`. Effects flow through the @@ -111,7 +111,7 @@ When advancing the cursor, any component in `held` is skipped without verification — it stays in reset and no `ReadFirmware`/`VerifyFirmware` is emitted -for it. The recovery-failure policy (`Isolable`/`Cascading`/`PlatformHalt`) is +for it. The recovery-failure policy (`Isolable`/`Cascading`/`Required`) is **not** consulted here; it is applied later, in `Recovering`, only if the restore attempts are exhausted. @@ -192,7 +192,7 @@ | `Restored(_)` | `retry_count + 1 < max_retry` | — | `PreSupervision` (re-verify — the restored image may pass) | | `Restored(_)` | cap reached, `failed` `Isolable` | `AssertReset(failed)` | `PreSupervision` (recovery exhausted: add `failed` to `held`, clear `failed`; the re-walk skips it) | | `Restored(_)` | cap reached, `failed` `Cascading` | `AssertReset(failed)` · `AssertReset(dependent…)` | `PreSupervision` (recovery exhausted: add `failed` + `depends_on` dependents to `held`, clear `failed`) | -| `Restored(_)` | cap reached, `failed` `PlatformHalt` | `Effect::Emit(RecoveryFailed)` | `Handled` (orchestrator queues `RecoveryFailed` next — INV7) | +| `Restored(_)` | cap reached, `failed` `Required` | `Effect::Emit(RecoveryFailed)` | `Handled` (orchestrator queues `RecoveryFailed` next — INV7) | | `RecoveryFailed` | — | — | `Locked` | | anything else | — | — | `Outcome::Super` → `SupervisingPlatform` | @@ -209,19 +209,20 @@ booting the rest of the platform. - `Cascading` — skip this component *and* its `depends_on` dependents; continue booting the remainder. -- `PlatformHalt` — stop entirely: self-emit `RecoveryFailed`, which drives the - machine to `Locked`. +- `Required` — stop entirely: self-emit `RecoveryFailed`, which drives the + machine to `Locked`. (CSA's narrative docs call this outcome "platform + halt" — same behavior, `Required` is the type-level name.) This mirrors the CSA Boot Sequence **Recovery Policy**: recovery (region restore) is attempted for *every* failed device first, and the `Isolable`/`Cascading`/ -`Platform-halt` classification applies only *after* a recovery attempt itself +`Required` classification applies only *after* a recovery attempt itself fails. `Effect::Emit(RecoveryFailed)` is the *feedback-as-data* mechanism. It is easiest to understand by asking why the machine doesn't just jump straight to `Locked` -when a `PlatformHalt` component's retry cap is hit. +when a `Required` component's retry cap is hit. -When a `PlatformHalt` component's last restore attempt fails, the machine has a +When a `Required` component's last restore attempt fails, the machine has a decision to make: give up and lock down. It could act on that decision silently, transitioning directly from `Recovering` to `Locked` inside the handler. Instead it does something that
diff --git a/docs/src/design/orchestrator/orchestrator-overview.md b/docs/src/design/orchestrator/orchestrator-overview.md index d0e5453..f4c2f56 100644 --- a/docs/src/design/orchestrator/orchestrator-overview.md +++ b/docs/src/design/orchestrator/orchestrator-overview.md
@@ -46,7 +46,7 @@ Recovering --> PreSupervision : Restored [retry < max_retry] Recovering --> PreSupervision : Restored [retry >= max_retry, Isolable or Cascading] - Recovering --> Locked : Restored [retry >= max_retry, PlatformHalt] + Recovering --> Locked : Restored [retry >= max_retry, Required] Locked --> [*] ```
diff --git a/docs/src/design/orchestrator/orchestrator-sm-transitions.md b/docs/src/design/orchestrator/orchestrator-sm-transitions.md index f057c59..3edad16 100644 --- a/docs/src/design/orchestrator/orchestrator-sm-transitions.md +++ b/docs/src/design/orchestrator/orchestrator-sm-transitions.md
@@ -85,7 +85,7 @@ recovery-failure policy, the machine records it in `failed` and enters `Recovering` to attempt restoration. The component is **not** skipped here — it is held in reset (never released, so it never runs unverified code) and given a -recovery attempt first. The `Isolable`/`Cascading`/`PlatformHalt` decision is +recovery attempt first. The `Isolable`/`Cascading`/`Required` decision is deferred until recovery has actually failed. ### held components → skipped (no transition) @@ -243,9 +243,9 @@ `depends_on` names it, adds them all to `held`, clears `failed`, and re-walks to continue booting the remainder. -### `Restored` [cap reached, `failed` is `PlatformHalt`] → `Recovering` (self, then `Locked`) +### `Restored` [cap reached, `failed` is `Required`] → `Recovering` (self, then `Locked`) -Restore attempts are exhausted and the component's policy is `PlatformHalt`, +Restore attempts are exhausted and the component's policy is `Required`, meaning the platform cannot safely continue without it. Rather than jump straight to lockdown, the machine emits `Effect::Emit(RecoveryFailed)` — a follow-up event — and returns `Handled`. The orchestrator re-dispatches `RecoveryFailed`
diff --git a/docs/src/design/orchestrator/orchestrator-sm-walkthru.md b/docs/src/design/orchestrator/orchestrator-sm-walkthru.md index fae756e..2b9387b 100644 --- a/docs/src/design/orchestrator/orchestrator-sm-walkthru.md +++ b/docs/src/design/orchestrator/orchestrator-sm-walkthru.md
@@ -45,7 +45,7 @@ PreSupervision --> Ready : Passive chain verified PreSupervision --> Recovering : verification failure Recovering --> PreSupervision : restored (re-verify) - Recovering --> Locked : recovery exhausted (PlatformHalt) + Recovering --> Locked : recovery exhausted (Required) Locked --> [*] ``` @@ -184,7 +184,7 @@ never runs unverified code) and handed to the recovery phase. The decision about whether to eventually *skip* it or *halt* is deferred until recovery has actually been tried and failed — see [Phase 5](#phase-5--two-stage-recovery). This is the -crux of CSA compliance: the classification (`Isolable`/`Cascading`/`PlatformHalt`) +crux of CSA compliance: the classification (`Isolable`/`Cascading`/`Required`) is a *recovery-failure* policy, not a first-failure policy. --- @@ -328,17 +328,17 @@ |---|---|---| | `Isolable` | Skip just this component: hold it in reset (`held`), continue booting the rest. | *Isolable — skip the failed device and continue.* | | `Cascading` | Skip this component **and** its `depends_on` dependents, then continue. | *Cascading — skip the failed device and any device configured as dependent on it.* | -| `PlatformHalt` | Stop entirely: self-emit `RecoveryFailed`, which drives the machine to `Locked`. | *Platform halt — stop the boot sequence entirely and enter manual/out-of-band recovery.* | +| `Required` | Stop entirely: self-emit `RecoveryFailed`, which drives the machine to `Locked`. | *Platform halt — stop the boot sequence entirely and enter manual/out-of-band recovery.* | The essential point — and the reason this matches CSA — is the ordering: **recovery is attempted for every failed component first**, and `Isolable` / -`Cascading` / `PlatformHalt` are consulted **only after** a recovery attempt +`Cascading` / `Required` are consulted **only after** a recovery attempt itself fails. A component is never skipped without first being given a chance to recover. ### Lockdown as visible data -When a `PlatformHalt` component exhausts recovery, the machine does not silently +When a `Required` component exhausts recovery, the machine does not silently jump to `Locked`. It emits `RecoveryFailed` as an *effect* — a follow-up event — which the orchestrator re-dispatches immediately, and *that* event drives the transition to `Locked`. The give-up decision therefore appears in the effect @@ -363,7 +363,7 @@ 1. Power-on with an unprovisioned eRoT. 2. Power-on with a failed eRoT self-check. -3. A `PlatformHalt` component whose recovery was exhausted. +3. A `Required` component whose recovery was exhausted. --- @@ -380,7 +380,7 @@ | Recovery scope = recovery region (restore together) | `RegionId`; `RestoreGoldenImage` restores the whole region | | Recover first for every failed device | Any `VerificationFailed` → `Recovering` | | Classify only after recovery fails (Isolable/Cascading/halt) | `Recovering` applies the policy when `retry_count` reaches `max_retry` | -| Platform halt on unrecoverable failure | `PlatformHalt` → `RecoveryFailed` → `Locked` | +| Platform halt on unrecoverable failure | `Required` → `RecoveryFailed` → `Locked` | | Measurements form attestation evidence | `AttestationChallenge` → `SignAttestation` in `SupervisingPlatform` | ---