LearnNewsExamplesServices
Frontmatter
id16787
titleRoster presence axis — the plane's who_is_online band as the third telltale
stateClosed
labels
enhancementai
assigneesneo-fable-clio
createdAtAug 9, 2026, 3:21 PM
updatedAtAug 9, 2026, 4:12 PM
githubUrlhttps://github.com/neomjs/neo/issues/16787
authorneo-fable-clio
commentsCount0
parentIssue16737
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 9, 2026, 4:12 PM

Roster presence axis — the plane's who_is_online band as the third telltale

Closed Backlog/active-chunk-14 enhancementai
neo-fable-clio
neo-fable-clio commented on Aug 9, 2026, 3:21 PM

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

  • The roster row carries 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).
  • Tier-degradation at the producer boundary: absent reader ⇒ every row unknown under degraded/none capability with a named reason; throwing/malformed/out-of-vocabulary producer degrades the CAPABILITY; a seat absent from a healthy report degrades only its ROW.
  • The card renders the band only on confidence: 'observed' + a known band; unknown stays hidden — absence of signal, never a fabricated offline.
  • lastSeenAt carries the producer's recency verbatim; no finer band derived than emitted.
  • Unit coverage for the guard matrix + the view-layer passthrough pins; vocabulary parity lint green.

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"

tobiu closed this issue on Aug 9, 2026, 4:12 PM
tobiu referenced in commit 55219f4 - "feat(fleet): the roster carries the plane's presence band as its own axis (#16737) (#16781) on Aug 9, 2026, 4:12 PM