LearnNewsExamplesServices
Frontmatter
id13483
titleOrchestrator-supervise the local Neural Link Bridge (singleton-safe)
stateClosed
labels
enhancementaiarchitecture
assigneesneo-gpt
createdAtJun 19, 2026, 12:07 AM
updatedAtJun 19, 2026, 6:32 AM
githubUrlhttps://github.com/neomjs/neo/issues/13483
authorneo-opus-vega
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 19, 2026, 6:32 AM

Orchestrator-supervise the local Neural Link Bridge (singleton-safe)

Closed v13.1.0/archive-v13-1-0-chunk-3 enhancementaiarchitecture
neo-opus-vega
neo-opus-vega commented on Jun 19, 2026, 12:07 AM

Context

Operator-observed (2026-06-18): the Neural Link Bridge is not part of the local orchestrator — the operator starts it manually each session (npm run ai:server-neural-linkai/mcp/server/neural-link/run-bridge.mjs, port 8081). The orchestrator (ai/daemons/orchestrator/) supervises chroma / wake / embed daemons but not the NL bridge.

Release classification: post-release (local-dev orchestrator stability/self-healing; boardless — not a v13 release gate).

Live latest-open sweep: checked latest 25 open issues on 2026-06-18; no equivalent orchestrator NL-bridge supervision ticket. A2A in-flight sweep: latest 20 messages; no competing [lane-claim].

The Problem

Manual NL-bridge start is forgotten-start friction (Neural Link tools silently fail until the bridge is up) plus no auto-restart on crash. The bridge is the NL transport (Brain↔Body possession surface); its absence breaks inspection / possession with a non-obvious failure mode.

The Architectural Reality

  • package.json ai:server-neural-link = node ./ai/mcp/server/neural-link/run-bridge.mjs (port 8081) — the manual start path.
  • taskDefinitions.mjs has no run-bridge task. The bridgeDaemon task there is the wake daemon (a frozen lane-taxonomy name kept verbatim across the wake-daemon rename — see the in-code comment), not the NL bridge. So nothing in the orchestrator supervises the NL Bridge today.
  • The NL bridge on :8081 is shared infra — multiple Neo clones + the ConnectionService.spawnBridge path can target the same port. Supervision MUST be singleton-safe (cf. the chroma task's singletonPort reap-duplicate discipline). Managing/killing the shared :8081 bridge is operator-authority territory, so the task must never stomp a running or peer-clone bridge.

The Fix

Add a neuralLinkBridge continuous task to buildTaskDefinitions():

  • runs node ai/mcp/server/neural-link/run-bridge.mjs (port 8081),
  • livenessProbe against :8081 + singletonPort: 8081 so it never spawns a second bridge if one is already listening (manual or peer-clone),
  • gated LOCAL-only via a new aiConfig.orchestrator.localOnly.neuralLinkBridgeEnabled leaf (cloud has its own NL topology); orchestrator-side probe timeout via aiConfig.orchestrator.neuralLinkBridge.livenessProbeTimeoutMs. The bridge port is owned by the NL config SSOT (ai/mcp/server/neural-link/config.mjs, NEO_NL_PORT) — the orchestrator consumes it (neuralLinkConfig.port), never re-defines it.

Contract Ledger

Target Surface Source of Authority Proposed Behavior Fallback / Edge Case Docs Evidence
neuralLinkBridge orchestrator task taskDefinitions.mjs + Orchestrator continuousTasks Supervise run-bridge.mjs :8081, restart-on-death singletonPort: 8081 defers if a bridge already listens (manual / peer-clone) — never double-spawns shared infra Inline task JSDoc Unit test: task-def shape + singleton gating
aiConfig.orchestrator.localOnly.neuralLinkBridgeEnabled ai/config.template.mjs (ADR 0019 leaf) LOCAL-only gate (off under cloud deploymentMode); lives under localOnly, mirroring chromaDaemonEnabled / bridgeDaemonEnabled Absent leaf → conservative local default / fail-loud per ADR 0019 config.template JSDoc ai:lint-config-template-ssot
aiConfig.orchestrator.neuralLinkBridge.livenessProbeTimeoutMs ai/config.template.mjs (ADR 0019 leaf) Orchestrator-side TCP liveness-probe timeout (default 1000ms). Bridge port NOT here — owned by ai/mcp/server/neural-link/config.mjs (NEO_NL_PORT), consumed via neuralLinkConfig.port Absent leaf → conservative default config.template JSDoc config.template.spec inline assertion

Ledger reconciled to shipped reality (PR #13489, Grace's Required Action): the enabled gate lives under orchestrator.localOnly.neuralLinkBridgeEnabled (not neuralLinkBridge.enabled), and the bridge port is not duplicated in the orchestrator config — it stays owned by the NL config SSOT (NEO_NL_PORT). The orchestrator-side neuralLinkBridge leaf carries only livenessProbeTimeoutMs. This is a cleaner shape than the original {enabled,port} scoping.

Decision Record impact

none — aligned-with the orchestrator's daemon-supervision design + ADR 0019 (the config leaf).

Acceptance Criteria

  • The local orchestrator supervises the NL Bridge (run-bridge.mjs, :8081), auto-restarting on death.
  • Singleton-safe: NEVER spawns a second bridge if :8081 already has a listener (manual or peer-clone) — uses the chroma-style singletonPort discipline.
  • LOCAL-only: gated via aiConfig.orchestrator.localOnly.neuralLinkBridgeEnabled (cloud orchestrator never launches it).
  • Does not regress or conflate with the wake-daemon bridgeDaemon task (distinct lane, frozen name).
  • Unit coverage for the task definition + singleton gating.

Out of Scope

  • Cloud NL topology.
  • The wake daemon (the separate bridgeDaemon task).
  • ConnectionService.spawnBridge (the in-service spawn path stays as-is).
  • #13056 (extended-NL coordination — H3-deferred; this is plain bridge supervision).

Avoided Traps

  • Conflating with the wake daemon (bridgeDaemon is the wake daemon — frozen name).
  • Stomping the shared :8081 bridge — singleton-safe, operator-authority infra.
  • Running it in the cloud orchestrator (LOCAL-only gate).

Related

  • Refs #13012 (Agent Harness — NL is the possession transport the harness rides).
  • Sibling stability ticket filed alongside: orchestrator-supervised local dev-server.

Origin Session ID: d1903453-9b2d-4f5d-bb5a-cf51ac2f7538

Handoff Retrieval Hints: query_raw_memories("orchestrator supervise neural link bridge run-bridge 8081 singletonPort shared infra local taskDefinitions"). Anchors: ai/daemons/orchestrator/taskDefinitions.mjs, package.json ai:server-neural-link, ai/mcp/server/neural-link/run-bridge.mjs.

Authored by Claude Opus 4.8 (Claude Code), @neo-opus-vega (Vega), at @tobiu's request.