LearnNewsExamplesServices
Frontmatter
id13173
titleNeural Link Client: unwrap agent-message envelope + thread agent context
stateClosed
labels
enhancementaiarchitecture
assigneesneo-opus-ada
createdAtJun 14, 2026, 3:50 AM
updatedAtJun 21, 2026, 2:17 AM
githubUrlhttps://github.com/neomjs/neo/issues/13173
authorneo-opus-ada
commentsCount0
parentIssue13167
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 14, 2026, 8:37 AM

Neural Link Client: unwrap agent-message envelope + thread agent context

Closed v13.1.0/archive-v13-1-0-chunk-2 enhancementaiarchitecture
neo-opus-ada
neo-opus-ada commented on Jun 14, 2026, 3:50 AM

Context

Leaf B of #13167 (Extended-NL identity-transport — the contract umbrella). The first landable + backward-compatible half of the Body-side enforcement wiring: the Client learns to unwrap the Bridge's {type:'agent_message', agentId, message} sidecar (per @neo-opus-grace's locked contract) and thread the verified agentId as a request context to the service dispatch — before the Bridge starts emitting the sidecar. That ordering is the cross-leaf finding @neo-opus-grace surfaced: a Client that already understands agent_message never breaks the live agent→app channel (Leaf A #13172 = the Bridge auth; the (1b) emit is split off as the final flip, sequenced last).

The Problem

Client.onSocketMessage accepts bare JSON-RPC and calls handleRequest(method, params) with no request context (src/ai/Client.mjs:253 / :186). The enforcement (Leaf C) needs the verified agentId threaded to the write services. This leaf adds the unwrap + the context thread, backward-compatibly: a bare frame is dispatched exactly as today (legacy / non-agent, unenforced); an agent_message frame yields a {agentId} context (the enforcement keys on it; a malformed / absent agentId yields a fail-closed marker).

The Fix

  • src/ai/parseAgentEnvelope.mjs — a pure parseAgentEnvelope(frame){jsonrpc, context}: agent_message{jsonrpc: frame.message, context: {agentId}} (null agentId if absent/invalid → fail-closed marker); bare → {jsonrpc: frame, context: null} (legacy, unenforced); non-object → {jsonrpc: null, context: null}.
  • Client.onSocketMessage consumes it: dispatch handleRequest(jsonrpc.method, jsonrpc.params, context) when jsonrpc?.method.
  • Client.handleRequest(method, params, context) — forwards context to the service call (fn.call(service, params, context)); existing service fns ignore the extra arg (backward-compat).

Contract Ledger

Inherits #13167's ledger. This leaf delivers row 3 (Client request dispatch → handleRequest(method, params, context) with {agentId} when present; reads unaffected) + the consume side of row 2 (the Client unwraps the {type:'agent_message', agentId, message} sidecar; raw read path unchanged). The write-service WriteGuard enforcement (rows 4–6) is Leaf C.

Acceptance Criteria

  • parseAgentEnvelope(frame) (pure): agent_message{jsonrpc: frame.message, context: {agentId}}; null / invalid agentId → {..., context: {agentId: null}} (fail-closed marker); bare → {jsonrpc: frame, context: null}; non-object → {jsonrpc: null, context: null}.
  • Client.onSocketMessage dispatches the unwrapped JSON-RPC + context; a bare frame is handled exactly as today (backward-compat).
  • Client.handleRequest accepts + forwards context to the service; existing (read) services are unaffected by the extra arg.
  • Unit spec for parseAgentEnvelope (pure); the Client wiring is a thin backward-compat diff (node --check; live dispatch is whitebox-e2e under Leaf C).

Out of Scope

  • The write-service WriteGuard enforcement (Leaf C — ledger rows 4–6; needs the live parent-chain + an e2e proof).
  • The Bridge auth (Leaf A / #13172) + the (1b) emit-flip (@neo-opus-grace).

Decision Record impact

aligned-with #13167 — implements its ledger row 3 + the consume side of row 2.

Related

  • Parent #13167 (umbrella + Contract Ledger); grandparent #13056. Sequenced before the (1b) emit (the ordering @neo-opus-grace found). Leaf A = #13172.

Live latest-open sweep: this leaf was just split off #13167 with @neo-opus-grace (2026-06-14T01:43Z); no equivalent open ticket.

Release classification: post-release (Agent Harness product line).

Origin Session ID: 4c598c8f-d8a7-4288-9420-e825a45d310e