LearnNewsExamplesServices
Frontmatter
id16360
titlebootstrap reads the wake transport from a template that cannot describe one
stateClosed
labels
bugai
assigneesneo-opus-grace
createdAtAug 2, 2026, 3:52 PM
updatedAtAug 2, 2026, 7:00 PM
githubUrlhttps://github.com/neomjs/neo/issues/16360
authorneo-opus-grace
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 2, 2026, 7:00 PM

bootstrap reads the wake transport from a template that cannot describe one

neo-opus-grace
neo-opus-grace commented on Aug 2, 2026, 3:52 PM

Context

Split out of #16310 — the delivered leaf, so a PR can close fully-delivered scope while #16310 keeps the arming half. Found by @neo-opus-vega, who traced a wake that never fired to the manifest builder rather than to her own seat and enumerated all four identity templates.

Live latest-open sweep 2026-08-02T13:52:09Z; #16355 (session-start auto-arm) is adjacent and disjoint — it owns the invocation, this owns what the invoked call produces.

The Problem

WakeSubscriptionService.bootstrap() reads harnessTarget from the identity's static subscriptionTemplate. All four template-bearing identities declare:

ai/graph/identityRoots.mjs:98   @neo-opus-ada    harnessTarget: 'bridge-daemon'
ai/graph/identityRoots.mjs:177  @neo-opus-vega   harnessTarget: 'bridge-daemon'
ai/graph/identityRoots.mjs:295  @neo-gemini-pro  harnessTarget: 'bridge-daemon'
ai/graph/identityRoots.mjs:350  @neo-gpt         harnessTarget: 'bridge-daemon'

buildReceiverManifest.mjs:72 sets DELIVERABLE_HARNESS_TARGET = 'a2a-webhook'; :167 withdraws the route of anything else. So bootstrap mints rows the builder is designed to reject, returns status: 'created', and leaves the seat reading status: 'active' while unreachable.

Consequence: invoking bootstrap() at boot would arm zero seats — which is what #16310 originally proposed.

The Architectural Reality — why migrating the templates cannot fix it

Deliverability requires two things a committed file cannot hold:

  1. The signing keycrypto.randomBytes(32), minted server-side at subscribe-time per ADR 0002 §6.2.3, and only on the a2a-webhook branch (WakeSubscriptionService.mjs:1017).
  2. The receiver address — per-machine, and reaching the service only through the boot envelope.

bridge-daemon is precisely the branch that skips minting, so a template naming it can never acquire a key by any later edit. A static template is structurally incapable of describing a deliverable route. The templates did not rot; they encode a transport from before deliverability required minted keys.

Corollary that decides the fix's shape: cleaning the seed does not rewrite subscriptionTemplate on nodes already persisted in a graph. Reading a cleaned template would reproduce the defect on every existing deployment while passing on a fresh one.

The Fix

Derive the transport from DELIVERABLE_HARNESS_TARGET — the same constant the manifest builder enforces — rather than reading it from the template. The template retains what it can legitimately own: policy (trigger, filters) and GUI dispatch hints.

Acceptance Criteria

  • bootstrap() does not read harnessTarget from the template; it derives from the constant the manifest builder enforces.
  • Derivation wins over a stale persisted template — a spec leaves bridge-daemon in place and asserts the derived target, because that is the live shape on any existing plane.
  • The four templates declare no transport, guarded by a spec asserting absence rather than a correct value — no value is correct.
  • A bootstrapped row is one buildWakeReceiverManifest publishes, asserted across both sides rather than pinned as strings on each.
  • With no receiver URL available, bootstrap refuses by name and leaves no partial row, instead of minting an undeliverable one and reporting success.
  • Existing specs that asserted harnessTarget: 'bridge-daemon' are updated — they pinned the defect.

Out of Scope

  • Where the receiver URL comes from. Nothing supplies it today: the boot envelope carries the GUI instance tuple, and no config leaf holds it. That is the remaining half of #16310 and this ticket deliberately leaves bootstrap refusing rather than inventing a source.
  • Invoking arming at boot#16310 / #16355.
  • Receiver-side manifest reload — #16352.

Avoided Traps

  • Migrating the templates to a2a-webhook. Looks like the obvious fix and cannot work: the key is minted only on that branch at subscribe-time, and the address is per-machine. Both are un-committable.
  • Reading a cleaned template instead of deriving. Passes on a fresh seed, reproduces the defect on every plane that already stored the old value.
  • Teaching the route-matcher to accept bridge-daemon. It would re-teach the system a transport the builder refuses, to avoid a two-boot self-heal.

Related

  • #16310 — parent; keeps the arming half (invocation + URL source)
  • #16355 — session-start auto-arm; owns invocation, disjoint from this
  • #16323 — the arming verdict, which reports the Memory-Core leg only
  • #16300rotate-key, the repair for a row that lost its key

Origin Session ID: 713db0da-2239-44ea-ba5b-931be90d34fc

Retrieval Hint: query_raw_memories("bootstrap template bridge-daemon derive DELIVERABLE_HARNESS_TARGET cannot hold minted key")

tobiu referenced in commit 47d998f - "fix(memory-core): bootstrap derives the wake transport instead of reading a template that cannot hold one (#16360) (#16361) on Aug 2, 2026, 7:00 PM
tobiu closed this issue on Aug 2, 2026, 7:00 PM