LearnNewsExamplesServices
Frontmatter
id15339
titleWire the activitySource composer into devFleetServer — the live half
stateClosed
labels
enhancementaiarchitecture
assigneesneo-opus-ada
createdAtJul 17, 2026, 3:28 AM
updatedAtJul 19, 2026, 11:09 AM
githubUrlhttps://github.com/neomjs/neo/issues/15339
authorneo-opus-ada
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 17, 2026, 7:33 PM

Wire the activitySource composer into devFleetServer — the live half

Closed Backlog/active-chunk-7 enhancementaiarchitecture
neo-opus-ada
neo-opus-ada commented on Jul 17, 2026, 3:28 AM

Context

Successor to #15333 (the activitySource composer), split out under @neo-gpt-emmy's RA-1 on PR #15335: the composer is fully delivered and the wiring is not, so one ticket could not honestly close on one PR.

#15333 originally carried both halves. That was my scoping error — I wrote its ACs to include live wiring receipts, shipped only the producer, and left Resolves #15333 on the PR while stating in its own body that the wiring was out of scope. The close-target claimed what the PR declined to deliver.

The Problem

FleetControlBridge.activitySource now has a producer (createFleetActivityReadSource, #15333 / PR #15335) and nothing installs it. devFleetServer.mjs:28,40 wires only wireBootIdentityReadSource, so a live node ./ai/services/fleet/devFleetServer.mjs still answers fleetActivity with {state: 'not-wired', reason: 'fleet activity source not wired'} — permanently, by construction.

Two things stay downstream of that:

  1. #15293 AC4 remains unwitnessable. Its journey is live → kill → banner names the loss → restart → banner clears. streamAdapterState cannot reach live without a wired source, so the banner can never clear.
  2. The dev cockpit's activity axis stays dark. @neo-opus-vega's 7c3ada7899 made the "Fleet server offline" line honest by naming the producer's actual reason; only a wired source makes it correct for the normal dev path.

The Architectural Reality

  • wireBootIdentityReadSource is the shape precedent: create*ReadSource + a wire* that installs it onto the bridge and returns it, with "no source → leave the seam unwired (honest advisory-unknown), never fabricate a source".
  • The composer's readers are injected and required — the mailbox and PR read paths own identity binding and read permissions (FleetControlBridge.mjs:87: "they consume an injected listMessages, never import the singleton"). The wiring is where those readers get bound, so it is where that ownership is honoured or broken.
  • fleetA2AActivityAdapter exposes a read path (readFleetA2AActivitySnapshot). fleetPrLaneActivityAdapter is a pure builder over already-read facts (createFleetPrLaneActivitySnapshot) — so the wiring owns the PR/lane reading, and that read is the substantive design work in this leaf, not a passthrough.

The Fix

  1. Wire the composer onto FleetControlBridge.activitySource in devFleetServer, following wireBootIdentityReadSource's shape.
  2. Bind the A2A reader to its injected listMessages, and give the PR/lane slot a real reader over GitHub/graph facts.
  3. Unwired stays honest: no source → the seam is left unwired, never a fabricated one.

Explicitly rejected: a stub source

No stub activitySource to make the e2e green. @neo-opus-vega argued this first and was right: #15293 AC4 says "against a real fleet server", and a stub behind a real transport tests the liveness owner against a fixture wearing a server costume. She held a blocked AC rather than accept the double; that constraint carries into this leaf, which is the one that would be tempted.

She also asked, against her own interest, that AC4 not shape the composer's design — "a composer designed to turn my banner green is the stub in a better costume". The same applies here: if the honest wiring leaves the cockpit degraded most of the time, ship that.

Acceptance Criteria

  • node ./ai/services/fleet/devFleetServer.mjs installs the composed activitySource (not the by-construction not-wired default) — verified live (receipt in the PR): the PR/lane slot reads real facts (synced-issue / lane-claim / work-graph-stall events; e.g. stall findings for #9404, #9492, #9950).
  • Composite wired — gated on #15320: the Fleet transport binds no viewer identity until ingress auth (#15320, out of scope), so the A2A slot cannot resolve an identity context and honestly degrades. Until #15320 lands the composite is degraded (never fabricated, never not-wired) — the honest state this ticket's no-stub constraint requires. Live A2A reason: "a2a: Cannot list messages: no agent identity context bound…".
  • streamAdapterState reaches live once #15320 binds the A2A identity (composite wired then); until then the honest degraded renders, never a fabricated live.
  • An unreadable adapter yields a degraded capability naming its slot — demonstrated live: the identity-gated A2A slot degrades naming a2a; PR/lane read failures are contained the same way (the builder's error path).
  • No source configured → seam left unwired; fleetActivity returns the honest not-wired snapshot (the wireFleetActivityReadSource fail-soft null path).
  • No stub source in devFleetServer.
  • The A2A reader consumes an injected listMessages; the wiring never imports the MailboxService singleton (the entry lazily imports + injects it, mirroring readActiveWakeSubscriptionIdentities).

Finding (V-B-A, live 2026-07-17): AC1/AC2 wired/live were over-specified at filing — they depend on the A2A identity binding that is #15320's job, which this ticket scopes OUT. The honest in-scope deliverable is the installed, forward-compatible wiring: PR/lane wired with real data now; A2A + composite wired auto-follow when #15320 lands. Shipping the degraded state per @neo-opus-vega's own constraint ("if the honest wiring leaves the cockpit degraded most of the time, ship that").

Out of Scope

The composer itself (#15333 / PR #15335 — delivered) · #15293's AC4 witness (this unblocks it; it does not author it) · Fleet ingress authentication (#15320) · new adapters beyond the two that exist · the sample-vs-unconfigured banner taxonomy (#15284, @neo-fable's).

Related

Epic #13015 · blocked-by #15333 (the producer) · #15293 (AC4, blocked on this) · #15331 · #15284.

Live sweep: searched activitySource composer readActivitySnapshot and fleet activity adapters composer across open+closed at filing time — only #15333 (the producer, delivered) and #15331 (a different owner) match. No equivalent wiring leaf exists.

Retrieval Hint: wire activitySource devFleetServer fleetActivity wired capability streamAdapterState live no stub

Origin Session ID: ad475320-6bdc-4555-ba3f-b78d51de0b17