Split leaf of #16737 (the presence-contract half), filed during PR #16781's review cycle 1 so the PR's close target matches its delivered scope exactly — the reviewer's Close-Target Audit correctly found Resolves #16737 would auto-close a tracker whose viewer-scoping, beacon-horizon, wake-route-health, and identity-binding ACs remain open. Per the close-target rule, the honest delivered leaf gets filed and closed; the parent keeps tracking the rest.
Context
FM's roster rendered every peer benched / offline because no presence tier existed: the cockpit's wake axis reported delivery axes honest-unknown pending a plane vouching surface, and the plane's who_is_online observation never reached the roster row. The operator's framing (2026-08-09): before FM connects to the in-docker graph, it can never show live MC data — all peers offline. This leaf delivers the presence half of #16737's truth-preserving contract: the plane's band observation as its OWN roster axis.
The Architectural Reality
The plane already produces the observation (WakeSubscriptionService._projectAgentLiveness emits {identity, state, reason, signals} with signals.activityRecency.lastActivityAt), and plane-mode devFleetServer already constructs the identity-proven reader (createPlaneWhoIsOnlineReader) — but only the decomposed wake-routes verb consumed it. The roster DTO carried wake + throttle telltales with no presence sibling.
The Fix (delivered by PR #16781)
ai/services/fleet/fleetPresenceStateAdapter.mjs — the sibling-pattern adapter: bulk readPresence seam (same producer contract as the routes verb), per-agent band join, capability envelope. PRESENCE_STATES exported here as the vocabulary's one home (routes source now imports it).
FleetManager.fleetPresenceStatus() + presenceStateOptions seam; plane-branch wiring in devFleetServer; FleetControlBridge.fleetRoster() joins the axis; fleetCockpitStatus DTO + cockpitSources twin (parity-linted).
- Body side:
FleetAgent.presence passthrough field, mapRosterRow carry, AgentCard ◉ band element — rendered ONLY on an OBSERVED band.
Acceptance Criteria
Out of Scope
The remaining #16737 ACs: viewer scoping via the S5 grant family (post-S2/fold), beacon-horizon band vocabulary (post plane vouching), identity-binding third-signal render, wake-route health from subscription state (#16741's lane).
Related
Parent #16737 · D#16720 Concept 4 (graduated authority) · PR #16781 (delivers this leaf) · #16786 (Phoebe's family-wide StateOptions trap, filed from the same review) · #16741 (delivery-axis sibling).
Decision Record impact: aligned-with ADR 0038 (Concept 4's presence contract; no new authority).
Live latest-open sweep: checked latest 20 open issues at 2026-08-09T13:20Z — no equivalent leaf; A2A in-flight sweep clean (no competing claim on this scope).
Contract Ledger (exact-shape, per hop)
(Added during PR #16781 review cycle 2 per the Contract Completeness Audit. Every row anchor verified at the PR head; evidence column names the pinning spec.)
| Hop |
Surface |
Exact shape |
Authority |
Evidence |
| Producer |
plane who_is_online {verbose: true} row |
{identity, state, reason?, signals.activityRecency.lastActivityAt?} — state ∈ PRESENCE_STATES |
WakeSubscriptionService._projectAgentLiveness (plane-side) |
consumed identically by the shipped wake-routes sibling |
| Reader |
createPlaneWhoIsOnlineReader(planeClient) → readPresence() |
passes the parsed payload through; throws on missing agents array |
planeWhoIsOnlineReader.mjs |
planeWhoIsOnlineReader.spec.mjs |
| Identity join |
presenceIdentityForAgent(agent) (exported) |
@<login> — leading @s stripped, single canonical prefix; accepts the registry's FULL production domain (defineAgent stores githubUsername unchanged) |
fleetPresenceStateAdapter.mjs |
adapter spec: leading-@ domain + degenerate-stacking + id-fallback + cardinality rows |
| Adapter row |
readFleetPresenceSnapshot().states[] |
{agentId, presence, lastSeenAt, confidence, source} + reason iff unknown |
adapter |
guard-matrix spec rows (both degradation directions, row-local absent-seat) |
| Capability |
envelope |
{source, state: wired|degraded, confidence: observed|none, capturedAt, reason} — no partial tier by design (one bulk report) |
adapter |
spec: producer-health rows |
| Manager |
FleetManager.fleetPresenceStatus() + presenceStateOptions seam |
delegates registry roster + injected options; null options ⇒ honest degraded |
FleetManager.mjs (class-static write path — family pattern tracked in #16786) |
reviewer-traced live path (PR #16781 cycle 1) |
| DTO row |
fleetCockpitStatus rows[].presence |
{source, state, confidence, lastSeenAt} + reason? — state CLOSED over online|idle|dark|benched|neverConnected|unknown |
fleetCockpitStatus.mjs + cockpitSources.mjs twin (parity lint) |
fleetCockpitStatus.spec.mjs: not-wired mirror + wired-travel rows |
| DTO wiring |
rows[].sources.presence + capabilities.presence |
{source, state: wired|not-wired, confidence} |
same |
same |
| Model |
FleetAgent.presence |
passthrough field, defaultValue: null — the view never re-derives |
FleetAgent.mjs |
fleetCockpit.spec.mjs passthrough pins (presence: null absent-axis honesty) |
| Card |
AgentCard card-presence element |
hidden unless confidence === 'observed' AND state ∈ PRESENCE_BAND_LABEL; text ◉ <label>; never fused into the session-state word |
AgentCard.mjs + AgentCard.scss token class |
agentCard.spec.mjs: render → unknown-clears → out-of-vocabulary-refused |
Origin Session ID: 7b51208b-bfd4-4372-94c6-49f6242e709d
Retrieval Hint: "roster presence axis who_is_online band third telltale tier-degradation"
Split leaf of
#16737(the presence-contract half), filed during PR #16781's review cycle 1 so the PR's close target matches its delivered scope exactly — the reviewer's Close-Target Audit correctly foundResolves #16737would auto-close a tracker whose viewer-scoping, beacon-horizon, wake-route-health, and identity-binding ACs remain open. Per the close-target rule, the honest delivered leaf gets filed and closed; the parent keeps tracking the rest.Context
FM's roster rendered every peer
benched / offlinebecause no presence tier existed: the cockpit's wake axis reporteddelivery axes honest-unknown pending a plane vouching surface, and the plane'swho_is_onlineobservation never reached the roster row. The operator's framing (2026-08-09): before FM connects to the in-docker graph, it can never show live MC data — all peers offline. This leaf delivers the presence half of#16737's truth-preserving contract: the plane's band observation as its OWN roster axis.The Architectural Reality
The plane already produces the observation (
WakeSubscriptionService._projectAgentLivenessemits{identity, state, reason, signals}withsignals.activityRecency.lastActivityAt), and plane-modedevFleetServeralready constructs the identity-proven reader (createPlaneWhoIsOnlineReader) — but only the decomposed wake-routes verb consumed it. The roster DTO carried wake + throttle telltales with no presence sibling.The Fix (delivered by PR #16781)
ai/services/fleet/fleetPresenceStateAdapter.mjs— the sibling-pattern adapter: bulkreadPresenceseam (same producer contract as the routes verb), per-agent band join, capability envelope.PRESENCE_STATESexported here as the vocabulary's one home (routes source now imports it).FleetManager.fleetPresenceStatus()+presenceStateOptionsseam; plane-branch wiring indevFleetServer;FleetControlBridge.fleetRoster()joins the axis;fleetCockpitStatusDTO +cockpitSourcestwin (parity-linted).FleetAgent.presencepassthrough field,mapRosterRowcarry,AgentCard◉ bandelement — rendered ONLY on an OBSERVED band.Acceptance Criteria
presence: {source, state, confidence, lastSeenAt, reason?}as a closed-enum axis (online | idle | dark | benched | neverConnected | unknown), independent from wake and throttle (three-signals rule: no axis infers another).unknownunderdegraded/nonecapability with a named reason; throwing/malformed/out-of-vocabulary producer degrades the CAPABILITY; a seat absent from a healthy report degrades only its ROW.confidence: 'observed'+ a known band; unknown stays hidden — absence of signal, never a fabricated offline.lastSeenAtcarries the producer's recency verbatim; no finer band derived than emitted.Out of Scope
The remaining
#16737ACs: viewer scoping via the S5 grant family (post-S2/fold), beacon-horizon band vocabulary (post plane vouching), identity-binding third-signal render, wake-route health from subscription state (#16741's lane).Related
Parent
#16737· D#16720 Concept 4 (graduated authority) · PR #16781 (delivers this leaf) ·#16786(Phoebe's family-wide StateOptions trap, filed from the same review) ·#16741(delivery-axis sibling).Decision Record impact: aligned-with ADR 0038 (Concept 4's presence contract; no new authority).
Live latest-open sweep: checked latest 20 open issues at 2026-08-09T13:20Z — no equivalent leaf; A2A in-flight sweep clean (no competing claim on this scope).
Contract Ledger (exact-shape, per hop)
(Added during PR #16781 review cycle 2 per the Contract Completeness Audit. Every row anchor verified at the PR head; evidence column names the pinning spec.)
who_is_online {verbose: true}row{identity, state, reason?, signals.activityRecency.lastActivityAt?}—state ∈ PRESENCE_STATESWakeSubscriptionService._projectAgentLiveness(plane-side)createPlaneWhoIsOnlineReader(planeClient)→readPresence()agentsarrayplaneWhoIsOnlineReader.mjsplaneWhoIsOnlineReader.spec.mjspresenceIdentityForAgent(agent)(exported)@<login>— leading@s stripped, single canonical prefix; accepts the registry's FULL production domain (defineAgentstoresgithubUsernameunchanged)fleetPresenceStateAdapter.mjsreadFleetPresenceSnapshot().states[]{agentId, presence, lastSeenAt, confidence, source}+reasoniffunknown{source, state: wired|degraded, confidence: observed|none, capturedAt, reason}— nopartialtier by design (one bulk report)FleetManager.fleetPresenceStatus()+presenceStateOptionsseamFleetManager.mjs(class-static write path — family pattern tracked in#16786)fleetCockpitStatusrows[].presence{source, state, confidence, lastSeenAt}+reason?—stateCLOSED overonline|idle|dark|benched|neverConnected|unknownfleetCockpitStatus.mjs+cockpitSources.mjstwin (parity lint)fleetCockpitStatus.spec.mjs: not-wired mirror + wired-travel rowsrows[].sources.presence+capabilities.presence{source, state: wired|not-wired, confidence}FleetAgent.presencedefaultValue: null— the view never re-derivesFleetAgent.mjsfleetCockpit.spec.mjspassthrough pins (presence: nullabsent-axis honesty)AgentCardcard-presenceelementconfidence === 'observed'ANDstate ∈ PRESENCE_BAND_LABEL; text◉ <label>; never fused into the session-state wordAgentCard.mjs+AgentCard.scsstoken classagentCard.spec.mjs: render → unknown-clears → out-of-vocabulary-refusedOrigin Session ID: 7b51208b-bfd4-4372-94c6-49f6242e709d Retrieval Hint: "roster presence axis who_is_online band third telltale tier-degradation"