LearnNewsExamplesServices
Frontmatter
id17100
titleFleet-server wake receiver + SSE fan-out — push over the ingress (S7 slice 2)
stateClosed
labels
enhancementaiarchitecture
assigneesneo-fable-clio
createdAtAug 14, 2026, 10:14 AM
updatedAtAug 14, 2026, 2:49 PM
githubUrlhttps://github.com/neomjs/neo/issues/17100
authorneo-fable-clio
commentsCount0
parentIssue16741
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 14, 2026, 2:49 PM

Fleet-server wake receiver + SSE fan-out — push over the ingress (S7 slice 2)

Closed Backlog/active-chunk-16 enhancementaiarchitecture
neo-fable-clio
neo-fable-clio commented on Aug 14, 2026, 10:14 AM

Context

Slice 2 of #16741 (S7, epic #16168), per the on-ticket reshaped fork (author comment 2026-08-09T14:45Z, unchallenged since): push for latency, poll for truth. Slice 1 (#16800, PR #16796) shipped the truth half — poll-digest derives the caller's digest at read time. This slice builds the latency half: the wake daemon pushes to the composed fleet-server (a webhook target with a stable in-composition service-DNS name — no host bridging, no port drift), and the fleet-server fans out to connected cockpits over the authenticated ingress via SSE.

Producer correction (source-verified at intake, 2026-08-14): the signed dispatcher is WebhookDeliveryService.deliver (ai/services/memory-core/WebhookDeliveryService.mjs — HMAC-SHA256 over the exact body, the four X-Neo-Wake-* headers receiver.mjs verifies, refuses unsigned delivery, full backoff/degrade/resume machinery). It is URL-generic via harnessTargetMetadata.url, so a service-DNS target rides it unchanged — zero dispatcher changes. The daemon's deliverViaWebhookUrl (daemon.mjs:2795) is the UNSIGNED legacy channel and is NOT this slice's producer.

Key custody (source-verified): subscribe returns the minted server-issued signingKey to the caller (WakeSubscriptionService.mjs:1143) and rotate-key re-mints (:1302). The fleet-server self-arms at boot per subscription: ensure → rotate-key → hold the key in process memory only (process-bearer custody class; restart = rotation). No deployment secret.

Fan-out shape: per-viewer relay subscriptions — each authenticated SSE connect ensures a wake subscription for THAT identity targeting the fleet-server's /wake; an incoming digest routes ONLY to streams authenticated as its subscription's identity. No cross-identity fan-out; the content-grant separation holds by construction. The delegate pattern (fleet-server's plane credential + explicit target identity) follows the shipped relay precedent (planeMailboxClient); if an MC-side permission gate bites, it surfaces in this slice's PR as its own finding.

The Fix

  1. POST /wake on fleetServer.mjs (427 lines; exact-route siblings GET /fleet/probe:318, POST /fleet:330) — the class-6 signed-wake receiver: HMAC verification per the subscription secret (ADR 0038 §2.5.1 row 6 — wake HMAC carries ZERO read/write authority), then fan-out + last-received bookkeeping (observational). Compose-internal only: no ingress exposure for /wake (the daemon reaches it via service DNS).
  2. SSE endpoint (e.g. GET /fleet/events) behind fleetIngressAuth admission — one EventSource per cockpit, server fan-out on the existing trust boundary. Ingress-exposed (Caddy passes SSE natively); add the exact route beside /fleet + /fleet/probe in ai/deploy/Caddyfile (+ local-agent-os variant, both arms).
  3. Service-DNS wake subscription — provisioning/seeding for the fleet-server's own subscription (target http://fleet-server:8083/wake), route class distinct from host-listener routes.
  4. Honest-degraded is an AC, not an aftermath (v1.1 fold): the SSE channel's death must render as absence-with-reason on the client contract — this slice defines the event/error vocabulary the slice-3 consumer renders.

Contract Ledger

Surface Today After Consumers V-B-A anchor
POST /wake (fleet-server, compose-internal) absent HMAC-verified wake receiver (mirrors receiver.mjs contract; imports verifyWakeSignature) MC WebhookDeliveryService (signed Shape-B dispatcher, unchanged) WebhookDeliveryService.mjs:125-146 signs + sends the four verified headers
SSE endpoint (ingress-exposed) absent authenticated event stream, fan-out of received wake digests slice-3 cockpit consumer fleetIngressAuth.mjs (123 lines, admission precedent)
Wake subscriptions (service-DNS target, per viewer identity) host-listener targets only + per-viewer relay subscriptions, self-armed at SSE connect; keys held in fleet-server process memory (boot rotate-key) MC dispatch (CoalescingEngineServiceWebhookDeliveryService) WakeSubscriptionService.mjs:1070/:1143 subscribe returns key; :1302 rotate-key
ai/deploy/Caddyfile* /fleet + /fleet/probe exact routes + SSE exact route (NOT /wake) ingress Caddyfile:57-60 handle_path prohibition note
Credential surface NONE added — HMAC = existing class 6; SSE rides existing admission ADR 0038 §2.5.1 non-alias rule

Acceptance Criteria

  • MC's WebhookDeliveryService delivers to the fleet-server via its service-DNS URL unchanged; the receiver verifies the class-6 HMAC (shared verifyWakeSignature contract) and rejects unsigned/invalid/unknown-subscription posts with the receiver's own error vocabulary.
  • Connected SSE clients receive the fan-out within the push path's latency (no polling involved); disconnected clients lose nothing durable (derive-at-read recovery is slice 1's shipped property, consumed in slice 3).
  • /wake is NOT ingress-reachable; the SSE endpoint IS, behind admission (negative + positive route tests).
  • Unit coverage per the memory-core/fleet service spec siblings; e2e deferred to slice 3 (the consumer journey).

Out of Scope

  • The cockpit consumer + delivery-axis wiring (slice 3), pull-route telemetry (slice 4), any daemon changes, any new credential class.

Related

Parent: #16741 (S7) · sibling slice 1: #16800 (merged, PR #16796) · epic #16168 · ADR 0038 §2.5.1 row 6 + §2.8 remote-only journey AC · design authority: #16741 comments (Iris Design v1/v1.1 + author falsification pass + reshaped fork).

Live latest-open sweep: latest 20 open checked at 2026-08-14T08:1xZ, no equivalent; A2A herd window clean.

Origin Session ID: c4996813-01b9-4234-8bdd-ed3bf22c0970

Retrieval Hint: query_raw_memories("fleet-server wake receiver SSE fan-out service-DNS slice 2")

tobiu referenced in commit 9e0862f - "feat(fleet): signed wake receiver + SSE fan-out on the composed fleet server (#17100) (#17103) on Aug 14, 2026, 2:49 PM
tobiu closed this issue on Aug 14, 2026, 2:49 PM