Context
Leaf 1 of #14477 (runtime freshness + restart control) — the read-only, unblocked, smallest honest slice, named in the epic's steward decomposition (issuecomment on #14477). The advisory boot-identity PRODUCER is fully built + spec-covered but is instantiated/injected nowhere live, so the control-plane surface that would consume it always degrades to advisory-unknown. This wires it — no restart authority, no drain, no #13033 dependency (that gates only the Electron arm).
⚠️ Correction (cycle-2 V-B-A — the carrier is CROSS-PROCESS, not direct injection)
This supersedes the "The Fix" and AC-1 wording below. V-B-A on the live process topology corrected the original in-process-injection prescription: FleetControlBridge runs in the separate fleet-bridge-server process (devFleetServer → dispatchFleetRequest), NOT the orchestrator — so the orchestrator cannot inject bootIdentitySource in-process there. The shipped design (PR #15080):
- The orchestrator composes the source once at start (
Orchestrator.initBootIdentitySource()) with the genuine process-boot time + the REM-consolidation cadence, and WRITES its advisory fact each poll() (recordBootIdentityFact) to a shared runtime-state file.
- The carrier (
bootIdentityFactStore) is an explicit cross-process snapshot contract: a versioned envelope, concurrency-safe atomic replace (unique per-write temp → rename), a byte bound, canonical-codebook validation (classification ∈ BOOT_FRESHNESS_CLASS, advisory === true, non-empty reason), and a stale-prior-process → advisory-unknown horizon.
- The fleet-server READS it (
createBootIdentityReadSource + wireBootIdentityReadSource) as FleetControlBridge.bootIdentitySource.
- Mode-agnostic: Electron in-process (Option A) and dev cross-process (Option B) read the same file.
The Problem
A long-lived Agent-OS process (orchestrator, MCP, bridge) can keep running pre-merge source after the tree advanced; config/schema-digest freshness cannot see it (Node does not hot-reload). The epic's answer is an advisory boot-identity fact — which checkout / source is this process actually running — that distinguishes a false-positive stale-wake (e.g. the 7.2h REM-stall probe where the process was healthy, REM merely deferred) from real staleness, without a false restart. The producer for that fact exists; nothing surfaces it.
The Architectural Reality (V-B-A'd on current dev)
ai/daemons/orchestrator/services/BootIdentityHealthService.mjs — produceBootIdentityFact() returns {fact, classification, advisory:true, reason}; construction takes an injected factGatherer, freshnessConfig ({designedCadenceMs, marginMs}), nowFn. Spec-covered (bootIdentityFreshness.spec).
ai/daemons/orchestrator/services/bootIdentityFactGatherer.mjs — createBootIdentityFactGatherer({bootAt, readRecentRemRunStates, remRunStateDir, …}) reads the last scheduler cycle from the REM run-state store (the same source the consolidation liveness watchdog reads). Spec-covered.
ai/services/fleet/FleetControlBridge.mjs — the consumer seam is built: getBootIdentity() returns this.bootIdentitySource.produceBootIdentityFact() (R3-correct: read-only advisory on the authenticated control-plane channel), wired as a fleetWireMethods verb. It runs in the separate fleet-bridge-server process (see the Correction above) — hence the cross-process file carrier rather than in-process injection.
- The gap (now closed):
FleetControlBridge.bootIdentitySource defaulted null and was assigned nowhere live — so getBootIdentity() always returned the advisory-unknown fallback.
The Fix (as shipped — cross-process carrier, per the Correction above)
- The orchestrator composes the source at start (
Orchestrator.initBootIdentitySource(): createBootIdentityFactGatherer({bootAt, readRecentRemRunStates, remRunStateDir}) → BootIdentityHealthService with freshnessConfig = the REM-consolidation stall threshold + an injected nowFn) and, each poll(), persists the produced fact to the shared runtime-state dir via recordBootIdentityFact (fail-soft, onError-observable).
- The fleet-bridge-server, at its boot, wires
FleetControlBridge.bootIdentitySource = createBootIdentityReadSource({dir}) over the same shared file (wireBootIdentityReadSource, reading AiConfig.orchestrator.dataDir at the use site).
- Fail-soft throughout: a boot-identity wiring/gather/write failure never aborts orchestrator boot or gates a poll — an unwired/absent/stale source keeps the honest advisory-
unknown, never fabricated liveness.
- Scope stays boot-identity only;
activitySource (the A2A/PR activity feed, #14572/#14573 arc) is a separate uncomposed seam, not bundled here. sourceRef/deferralReason/schedulerResumeState remain the gatherer's declared optional refine-in-place resolvers (out of this wiring leaf).
Decision Record impact
aligned-with ADR-0026 (controller-blind actuator family; this is the read-observe half, no actuation) + ADR-0025/0027 (immune-system). No new config leaf beyond reading the existing freshness cadence + dataDir at the use site; ADR-0019-clean (read-at-use-site, no primitive-local default; the composition uses the global Neo, no non-entrypoint import).
Acceptance Criteria
Post-merge residual
- The live two-process control-plane probe (a real orchestrator writing + a real fleet-bridge-server reading across the OS boundary) is an L3 NL-verify residual — the unit caller-level test runs both halves in one process over a shared tmp dir. Annotated on PR #15080.
Out of Scope
- Restart authority / R2 drain / R3 trigger (Leaf 2/3 of #14477; the restart-actuator canonical shape already exists —
control-plane/restartActuator.mjs/#14760).
activitySource wiring (separate seam, #14572/#14573 arc).
- The Electron arm (#13033/#13377).
RuntimeFreshnessService config/schema-digest freshness (orthogonal, per the epic).
Related
Parent epic #14477 (its Leaf 1) · producer BootIdentityHealthService + bootIdentityFactGatherer · carrier bootIdentityFactStore · consumer seam FleetControlBridge.getBootIdentity · #13015 (FM control-plane owner) · the stale-wake false-positive class this distinguishes (#14486 closed).
Origin Session ID: 01f4cc68-8b8e-43e6-b51c-55b4f421f4e0
Retrieval Hint: "boot-identity health surface wiring FleetControlBridge bootIdentitySource orchestrator REM run-state fact-gatherer advisory unknown cross-process carrier bootIdentityFactStore"
Authored by Ada (@neo-opus-ada, Claude Opus 4.8, Claude Code).
Context
Leaf 1 of #14477 (runtime freshness + restart control) — the read-only, unblocked, smallest honest slice, named in the epic's steward decomposition (issuecomment on #14477). The advisory boot-identity PRODUCER is fully built + spec-covered but is instantiated/injected nowhere live, so the control-plane surface that would consume it always degrades to advisory-
unknown. This wires it — no restart authority, no drain, no #13033 dependency (that gates only the Electron arm).⚠️ Correction (cycle-2 V-B-A — the carrier is CROSS-PROCESS, not direct injection)
This supersedes the "The Fix" and AC-1 wording below. V-B-A on the live process topology corrected the original in-process-injection prescription:
FleetControlBridgeruns in the separate fleet-bridge-server process (devFleetServer→dispatchFleetRequest), NOT the orchestrator — so the orchestrator cannot injectbootIdentitySourcein-process there. The shipped design (PR #15080):Orchestrator.initBootIdentitySource()) with the genuine process-boot time + the REM-consolidation cadence, and WRITES its advisory fact eachpoll()(recordBootIdentityFact) to a shared runtime-state file.bootIdentityFactStore) is an explicit cross-process snapshot contract: a versioned envelope, concurrency-safe atomic replace (unique per-write temp →rename), a byte bound, canonical-codebook validation (classification ∈ BOOT_FRESHNESS_CLASS,advisory === true, non-emptyreason), and a stale-prior-process → advisory-unknownhorizon.createBootIdentityReadSource+wireBootIdentityReadSource) asFleetControlBridge.bootIdentitySource.The Problem
A long-lived Agent-OS process (orchestrator, MCP, bridge) can keep running pre-merge source after the tree advanced; config/schema-digest freshness cannot see it (Node does not hot-reload). The epic's answer is an advisory boot-identity fact — which checkout / source is this process actually running — that distinguishes a false-positive stale-wake (e.g. the 7.2h REM-stall probe where the process was healthy, REM merely deferred) from real staleness, without a false restart. The producer for that fact exists; nothing surfaces it.
The Architectural Reality (V-B-A'd on current dev)
ai/daemons/orchestrator/services/BootIdentityHealthService.mjs—produceBootIdentityFact()returns{fact, classification, advisory:true, reason}; construction takes an injectedfactGatherer,freshnessConfig({designedCadenceMs, marginMs}),nowFn. Spec-covered (bootIdentityFreshness.spec).ai/daemons/orchestrator/services/bootIdentityFactGatherer.mjs—createBootIdentityFactGatherer({bootAt, readRecentRemRunStates, remRunStateDir, …})reads the last scheduler cycle from the REM run-state store (the same source the consolidation liveness watchdog reads). Spec-covered.ai/services/fleet/FleetControlBridge.mjs— the consumer seam is built:getBootIdentity()returnsthis.bootIdentitySource.produceBootIdentityFact()(R3-correct: read-only advisory on the authenticated control-plane channel), wired as afleetWireMethodsverb. It runs in the separate fleet-bridge-server process (see the Correction above) — hence the cross-process file carrier rather than in-process injection.FleetControlBridge.bootIdentitySourcedefaultednulland was assigned nowhere live — sogetBootIdentity()always returned the advisory-unknownfallback.The Fix (as shipped — cross-process carrier, per the Correction above)
Orchestrator.initBootIdentitySource():createBootIdentityFactGatherer({bootAt, readRecentRemRunStates, remRunStateDir})→BootIdentityHealthServicewithfreshnessConfig= the REM-consolidation stall threshold + an injectednowFn) and, eachpoll(), persists the produced fact to the shared runtime-state dir viarecordBootIdentityFact(fail-soft,onError-observable).FleetControlBridge.bootIdentitySource = createBootIdentityReadSource({dir})over the same shared file (wireBootIdentityReadSource, readingAiConfig.orchestrator.dataDirat the use site).unknown, never fabricated liveness.activitySource(the A2A/PR activity feed, #14572/#14573 arc) is a separate uncomposed seam, not bundled here.sourceRef/deferralReason/schedulerResumeStateremain the gatherer's declared optional refine-in-place resolvers (out of this wiring leaf).Decision Record impact
aligned-with ADR-0026(controller-blind actuator family; this is the read-observe half, no actuation) + ADR-0025/0027 (immune-system). No new config leaf beyond reading the existing freshness cadence +dataDirat the use site; ADR-0019-clean (read-at-use-site, no primitive-local default; the composition uses the globalNeo, no non-entrypoint import).Acceptance Criteria
initBootIdentitySource()at start +recordBootIdentityFacteachpoll()) to the shared runtime-state file, and the fleet-bridge-server wirescreateBootIdentityReadSourceasFleetControlBridge.bootIdentitySource, sogetBootIdentity()returns a real advisory boot-identity fact (not theunknownfallback) on the control-plane channel. (Supersedes the original in-process-injection wording.)BOOT_FRESHNESS_CLASS+ advisory + reason validation, stale-prior-process →unknown).unknownand never aborts orchestrator boot or gates a poll; a genuine write failure is observable (onError).Orchestrator.initBootIdentitySource()+poll()seam proving a codebook-valid fact is written + served cross-process.Post-merge residual
Out of Scope
control-plane/restartActuator.mjs/#14760).activitySourcewiring (separate seam, #14572/#14573 arc).RuntimeFreshnessServiceconfig/schema-digest freshness (orthogonal, per the epic).Related
Parent epic #14477 (its Leaf 1) · producer
BootIdentityHealthService+bootIdentityFactGatherer· carrierbootIdentityFactStore· consumer seamFleetControlBridge.getBootIdentity· #13015 (FM control-plane owner) · the stale-wake false-positive class this distinguishes (#14486 closed).Origin Session ID: 01f4cc68-8b8e-43e6-b51c-55b4f421f4e0
Retrieval Hint: "boot-identity health surface wiring FleetControlBridge bootIdentitySource orchestrator REM run-state fact-gatherer advisory unknown cross-process carrier bootIdentityFactStore"
Authored by Ada (@neo-opus-ada, Claude Opus 4.8, Claude Code).