diff --git a/services/orchestrator/capabilities/src/recovery.rs b/services/orchestrator/capabilities/src/recovery.rs index 9f011638..3564964a 100644 --- a/services/orchestrator/capabilities/src/recovery.rs +++ b/services/orchestrator/capabilities/src/recovery.rs @@ -34,7 +34,7 @@ pub enum RestoreOutcome { /// and the orchestrator gates the component per its failure policy right /// away instead of waiting for the retry cap. Errors are actuation faults /// only, such as an unreachable source or a failed write, and the -/// orchestrator treats them fail-closed. Source exhaustion travels on the +/// orchestrator treats them fail-secure. Source exhaustion travels on the /// `Ok` side because it is a known condition: the orchestrator applies /// per-component policy to it instead of locking unconditionally. /// diff --git a/services/orchestrator/driver/README.md b/services/orchestrator/driver/README.md index 2cb47cea..cf2ef4d5 100644 --- a/services/orchestrator/driver/README.md +++ b/services/orchestrator/driver/README.md @@ -31,6 +31,6 @@ loop { ``` Implemented executors: `ReadFirmware`, `VerifyFirmware`, `ReleaseReset` -(arms the boot walk), `AssertReset` (stops it). Everything else fails closed +(arms the boot walk), `AssertReset` (stops it). Everything else fails secure until its pillar lands (recovery, update path, attestation, reporting, lockdown latch). diff --git a/services/orchestrator/driver/src/board.rs b/services/orchestrator/driver/src/board.rs index 8f965078..f2571c0a 100644 --- a/services/orchestrator/driver/src/board.rs +++ b/services/orchestrator/driver/src/board.rs @@ -138,7 +138,7 @@ pub enum Report { /// /// Infallible by design: a report names something that already happened, so /// an undeliverable one costs information, not containment. An error channel -/// would put reports on the fail-closed path, letting the act of reporting a +/// would put reports on the fail-secure path, letting the act of reporting a /// contained failure escalate it. pub trait ReportSink { /// Receives one report. A sink that cannot deliver immediately queues on diff --git a/services/orchestrator/driver/src/driver.rs b/services/orchestrator/driver/src/driver.rs index 1be72838..ad8dc9ef 100644 --- a/services/orchestrator/driver/src/driver.rs +++ b/services/orchestrator/driver/src/driver.rs @@ -35,7 +35,7 @@ pub enum DriverError { /// The component's boot control could not actuate the reset line. BootControlFault, /// A floor commit was asked for a component with no verified image, - /// so the SVN to advance to is unknown; fail closed. + /// so the SVN to advance to is unknown; fail secure. NoVerifiedImage, /// The component's SVN floor could not be advanced. SvnFloorFault, @@ -214,7 +214,7 @@ impl PlatformDriver { /// component the staged candidate is for and `len` as how much of the /// staging region the candidate occupies. Must succeed BEFORE /// [`Event::UpdateRequest`] is dispatched; `AuthenticateStageUpdate` - /// with no stored job fails closed. Refuses an unknown id and a + /// with no stored job fails secure. Refuses an unknown id and a /// second submit while one update is in flight; nothing is stored on /// refusal, so a refused request can never surface as an update /// event. @@ -370,7 +370,7 @@ impl PlatformDriver { } Step::Staged => { job.phase = UpdatePhase::Staged; - // Fail closed: no UpdateVerified until the crypto + // Fail secure: no UpdateVerified until the crypto // verify-client is wired. The pump parks here. UpdatePoll::idle() } @@ -595,7 +595,7 @@ impl PlatformDriver { /// Restore `id`'s image from its recovery source. The verdict travels /// as an event, not an error: `Restored` and `SourceExhausted` are /// outcomes the SM handles per failure policy, while an `Err` from - /// the mechanism is a genuine actuation fault that fails closed. + /// the mechanism is a genuine actuation fault that fails secure. pub fn recover_component( &mut self, id: ComponentId, @@ -614,7 +614,7 @@ impl PlatformDriver { } /// Hands one report to the board's sink. Cannot fail, so reporting stays - /// off the fail-closed path; reports arrive in the order the SM emitted + /// off the fail-secure path; reports arrive in the order the SM emitted /// them. pub fn report(&mut self, report: Report) { self.board.report_sink.report(report); @@ -660,7 +660,7 @@ impl Platform for PlatformDriver { /// variant must get an executor before this compiles. Synchronous /// results (the verification verdict) come back as the returned event; /// every executor error reports as [`EffectError`], the SM treats all - /// actuation failures the same, fail-closed. + /// actuation failures the same, fail-secure. fn execute(&mut self, effect: Effect) -> Result, EffectError> { match effect { Effect::ReadFirmware(id) => self.stage_firmware(id).map(|_| None), @@ -668,7 +668,7 @@ impl Platform for PlatformDriver { Effect::ReleaseReset(id) => self.release_reset(id).map(|_| None), Effect::AssertReset(id) => self.assert_reset(id).map(|_| None), Effect::CommitSvnFloor(id) => self.commit_svn_floor(id).map(|_| None), - // Reports carry no error, so they never reach the fail-closed + // Reports carry no error, so they never reach the fail-secure // group below. Effect::ReportIsolated(id) => { self.report(Report::Isolated(id)); @@ -707,7 +707,7 @@ impl Platform for PlatformDriver { Effect::ActivateUpdate => self.activate_update().map(|_| None), Effect::DiscardStaged => self.discard_staged().map(|_| None), // No board capability is composed for these seams yet, so they - // fail closed here instead of behind stub methods. + // fail secure here instead of behind stub methods. Effect::SignAttestation | Effect::LatchLockdown => return Err(EffectError), // Emit is consumed by the orchestrator; receiving one is a // driver bug. diff --git a/services/orchestrator/driver/src/lib.rs b/services/orchestrator/driver/src/lib.rs index b19145e8..7279dc0a 100644 --- a/services/orchestrator/driver/src/lib.rs +++ b/services/orchestrator/driver/src/lib.rs @@ -7,7 +7,7 @@ //! [`PlatformDriver`] implements the SM's [`Platform`] seam, delegating each //! `Effect` to a board-composed capability per the platform-boundary contract //! (`docs/src/design/orchestrator/orchestrator-model.md` §6). Effects whose -//! capability is not composed yet fail closed in `execute`; the driver grows +//! capability is not composed yet fail secure in `execute`; the driver grows //! an executor only when the capability it delegates to exists. //! //! Synchronous results (the verification verdict) return through `execute`; diff --git a/services/orchestrator/driver/src/tests.rs b/services/orchestrator/driver/src/tests.rs index ebeec55a..6c34ea09 100644 --- a/services/orchestrator/driver/src/tests.rs +++ b/services/orchestrator/driver/src/tests.rs @@ -1410,7 +1410,7 @@ fn floor_fault_is_reported() { } // Every report effect reaches the board's sink, in emission order, and none -// hands back an error for the SM to fail closed on. +// hands back an error for the SM to fail secure on. #[test] fn reports_reach_the_board_sink() { let mut driver = PlatformDriver::::new( @@ -1443,7 +1443,7 @@ fn reports_reach_the_board_sink() { // An Isolable component is contained and reported, and the platform keeps // running: executing a report returns no error, so it never reaches the -// fail-closed path. +// fail-secure path. #[test] fn reporting_an_isolated_component_does_not_lock_the_platform() { let mut driver = PlatformDriver::::new( diff --git a/services/orchestrator/sm/src/model.rs b/services/orchestrator/sm/src/model.rs index c5abb60c..da67ff29 100644 --- a/services/orchestrator/sm/src/model.rs +++ b/services/orchestrator/sm/src/model.rs @@ -282,7 +282,7 @@ pub enum Event { /// when it executes [`Effect::ActivateUpdate`] and cancels it on /// [`Effect::CommitSvnFloor`]. CommitTimeout, - /// The platform driver could not carry out an emitted [`Effect`]; fail-closed, it + /// The platform driver could not carry out an emitted [`Effect`]; fail-secure, it /// latches to [`State::Locked`] from any state. Injected by the driver when /// a [`Platform::execute`](crate::Platform::execute) call fails; never /// produced by a handler. @@ -302,7 +302,7 @@ impl Event { /// [`Event::UpdateRequest`] is the exception: it carries a component but /// returns `None`. The caller records the job before dispatching it, so /// dropping the event here would leave that job with nothing to answer it - /// and wedge every later request. An unknown target instead fails closed in + /// and wedge every later request. An unknown target instead fails secure in /// the executor, which has the board's component list to check against. pub(crate) fn component_id(&self) -> Option { match self { @@ -476,7 +476,7 @@ impl State { /// Build one with [`TryFrom`]/[`TryInto`] from a `heapless::Vec` of /// `(ComponentId, ComponentAttrs)` pairs. The conversion is the single place /// the state machine's structural invariants are enforced, so a malformed chain -/// fails closed at the boundary instead of misbehaving later: +/// fails secure at the boundary instead of misbehaving later: /// /// - the chain is non-empty, /// - every [`ComponentId`] is unique, diff --git a/services/orchestrator/sm/src/orchestrator.rs b/services/orchestrator/sm/src/orchestrator.rs index dc4f6abe..ff3897c7 100644 --- a/services/orchestrator/sm/src/orchestrator.rs +++ b/services/orchestrator/sm/src/orchestrator.rs @@ -79,7 +79,7 @@ impl Orchestrator { /// /// If `on_effect` reports an [`EffectError`], the orchestrator injects an /// [`Event::EffectFailed`] at the *front* of the queue, so a failed - /// actuation is handled fail-closed: the latch settles next, and feedback + /// actuation is handled fail-secure: the latch settles next, and feedback /// still queued behind it drains into [`State::Locked`] (discarded) /// instead of actuating hardware after a failure. A pending-queue /// overflow is handled the same way: losing a returned event would break @@ -89,7 +89,7 @@ impl Orchestrator { event: Event, mut on_effect: impl FnMut(Effect) -> Result, EffectError>, ) { - // Fail-closed latch: `EffectFailed` goes to the *front*, so it settles + // Fail-secure latch: `EffectFailed` goes to the *front*, so it settles // next and everything still queued drains into `Locked` (discarded) // instead of actuating hardware after a failure. Prefer evicting the // newest queued event over losing the latch itself. @@ -122,7 +122,7 @@ impl Orchestrator { external => match on_effect(external) { Ok(follow_up) => follow_up, Err(_) => { - // Fail-closed AND fail-fast: abandon the rest of + // Fail-secure AND fail-fast: abandon the rest of // this batch. `step` has already advanced the // state as if the whole batch applied, and the // latch overrides that transition, so nothing @@ -140,7 +140,7 @@ impl Orchestrator { && !failed { // Queue full: `next` would be lost, breaking the - // honest-feedback contract. Fail closed instead. + // honest-feedback contract. Fail secure instead. failed = true; latch(&mut pending); break; diff --git a/services/orchestrator/sm/src/platform.rs b/services/orchestrator/sm/src/platform.rs index 0f276078..cc1d0c20 100644 --- a/services/orchestrator/sm/src/platform.rs +++ b/services/orchestrator/sm/src/platform.rs @@ -5,7 +5,7 @@ use crate::model::{Effect, Event}; /// Signals that the platform driver could not carry out an [`Effect`]. The machine does /// not need the driver's error detail — **every** actuation failure is treated -/// the same, fail-closed: the orchestrator injects [`Event::EffectFailed`] and the +/// the same, fail-secure: the orchestrator injects [`Event::EffectFailed`] and the /// machine latches to [`State::Locked`]. This blanket policy is deliberate and /// is what lets the failure signal stay a payload-less marker; a future design /// that needs per-effect recovery must add a *new*, descriptive event rather @@ -56,7 +56,7 @@ pub struct EffectError; /// component are exhausted, it feeds back [`Event::RecoveryUnavailable`] /// instead — never [`EffectError`]. `EffectError` from a `RecoverComponent` /// call is reserved for a genuine actuation fault (e.g. a bus error during -/// the image swap), which fails closed to [`State::Locked`] unconditionally. +/// the image swap), which fails secure to [`State::Locked`] unconditionally. /// Reporting "out of images" that way would lock the whole platform down /// even for an `Isolable`/`Cascading` component, instead of letting it be /// gated per [`FailurePolicy`] like the count-driven exhaustion path. diff --git a/services/orchestrator/sm/src/rot.rs b/services/orchestrator/sm/src/rot.rs index cd4b30e2..b193f818 100644 --- a/services/orchestrator/sm/src/rot.rs +++ b/services/orchestrator/sm/src/rot.rs @@ -596,7 +596,7 @@ impl Rot { Outcome::Handled } // Commit watchdog. If the activated-but-not-committed window is - // still open, fail closed: never commit an unproven image, and + // still open, fail secure: never commit an unproven image, and // never leave the downgrade window open indefinitely. Outside // the window this is a stale watchdog fire and is dropped. Event::CommitTimeout => { diff --git a/services/orchestrator/sm/src/sink.rs b/services/orchestrator/sm/src/sink.rs index 9c45b543..e35dbf60 100644 --- a/services/orchestrator/sm/src/sink.rs +++ b/services/orchestrator/sm/src/sink.rs @@ -11,7 +11,7 @@ use crate::model::{Effect, State}; /// pops as it settles, so this bounds *in-flight* events, not a run's total /// length: one batch can queue at most one `Emit` follow-up plus one returned /// event per external effect. Executors that return an event for many effects -/// of one batch can overflow this; overflow is fail-closed (see +/// of one batch can overflow this; overflow is fail-secure (see /// `dispatch_with`), never silent loss. pub(crate) const PENDING_CAP: usize = 8; @@ -63,7 +63,7 @@ impl Sink { /// handler emits more than `2 * N + 2` effects into one `Sink`, so the push /// below can never fail. A `cfg(test)` assert catches a stale derivation /// in the test suite; in the release binary the push is unchecked - /// (fail-closed: fewer effects means more lockdown, never less). + /// (fail-secure: fewer effects means more lockdown, never less). /// /// The driver runs the effects from one handler in the order they were /// emitted, and it does not run them as a single all-or-nothing group: if diff --git a/services/orchestrator/sm/src/tests.rs b/services/orchestrator/sm/src/tests.rs index 0f643d6f..d52361e2 100644 --- a/services/orchestrator/sm/src/tests.rs +++ b/services/orchestrator/sm/src/tests.rs @@ -2106,7 +2106,7 @@ fn svn_floor_commits_on_boot_confirmed_not_on_activation() { /// Commit-or-lock watchdog: while the activated-but-not-committed window is /// open (update activated, `BootConfirmed` not yet seen), a `CommitTimeout` -/// fails closed — the machine latches `Locked` rather than leaving the +/// fails secure — the machine latches `Locked` rather than leaving the /// downgrade window open indefinitely, and never commits the unproven image. #[test] fn commit_timeout_while_pending_latches_locked() { @@ -2438,7 +2438,7 @@ impl Platform for FailOn { } } -/// A failed reset actuation is fail-closed: the orchestrator injects `EffectFailed` +/// A failed reset actuation is fail-secure: the orchestrator injects `EffectFailed` /// and the machine latches to `Locked`, emitting `LatchLockdown`. #[test] fn effect_failure_latches_lockdown() { @@ -2456,7 +2456,7 @@ fn effect_failure_latches_lockdown() { assert!(plat.recorded.contains(&Effect::LatchLockdown)); } -/// A failed isolation actuation (`AssertReset`) is equally fail-closed: even a +/// A failed isolation actuation (`AssertReset`) is equally fail-secure: even a /// non-required component's containment failing latches the platform. #[test] fn failed_isolation_actuation_latches_lockdown() { @@ -2477,7 +2477,7 @@ fn failed_isolation_actuation_latches_lockdown() { assert!(plat.recorded.contains(&Effect::LatchLockdown)); } -/// A failed recovery actuation is fail-closed too: if the platform driver cannot even +/// A failed recovery actuation is fail-secure too: if the platform driver cannot even /// recover a required component, the platform latches rather /// than continuing with an unrecovered component. #[test] @@ -2964,7 +2964,7 @@ fn returned_verdicts_settle_in_one_dispatch() { } /// A batch whose executors return more events than the pending queue holds -/// fails closed: the run latches `Locked` instead of losing feedback. +/// fails secure: the run latches `Locked` instead of losing feedback. #[test] fn returned_event_overflow_latches_locked() { struct Chatty;