Context
The identity transport is complete on dev: Leaf A auth (#13181) + the (1b) sidecar emit (#13196/#13199) merged — the Bridge now stamps {type:'agent_message', agentId, sessionId, message} with a per-connection sessionId. But src/ai/parseAgentEnvelope.mjs (Leaf B, #13173) still extracts only agentId into the request context, silently dropping the sessionId. WriteGuard's writer identity is the (agentId, sessionId) pair (LockRegistry requires a non-empty sessionId), so the enforcement leaf cannot key correctly until the Client threads both.
This is the first, mechanical slice of Leaf C (the WriteGuard enforcement, #13056 / #13167 row 4–6): thread the sessionId so it reaches the write services. The enforcement itself (InstanceService → WriteGuard.requestWrite + the agent_disconnected → releaseAll wiring) is the follow-up slice.
The Fix
src/ai/parseAgentEnvelope.mjs: for an agent_message frame, also validate + extract sessionId (same shape as agentId: non-empty string → value, else null fail-closed marker), returning context: {agentId, sessionId}. The bare/legacy path is unchanged (context: null).
Forward-compatible: nothing consumes sessionId yet, but the merged (1b) emit already supplies it, so this closes the drop. A null sessionId (absent/malformed) is a fail-closed marker so the enforcement leaf denies rather than mutates.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
parseAgentEnvelope context |
this ticket |
{agentId, sessionId} for agent_message (both validated, null fail-closed) |
bare frame → context: null (unchanged) |
JSDoc + spec |
(1b) emit verified on dev to carry sessionId |
Acceptance Criteria
Out of Scope
- The
WriteGuard.requestWrite enforcement + releaseAll disconnect wiring (the next Leaf C slice).
Related
- Sub of #13167 (Extended-NL umbrella, row 3 extension) / #13056. Consumes the (1b) emit #13196/#13199; precedes the enforcement slice.
Live latest-open sweep: checked immediately before filing; no equivalent.
Authored by Claude Opus 4.8 (Claude Code), @neo-opus-ada.
Origin Session ID: 4c598c8f-d8a7-4288-9420-e825a45d310e
Context
The identity transport is complete on
dev: Leaf A auth (#13181) + the (1b) sidecar emit (#13196/#13199) merged — the Bridge now stamps{type:'agent_message', agentId, sessionId, message}with a per-connectionsessionId. Butsrc/ai/parseAgentEnvelope.mjs(Leaf B, #13173) still extracts onlyagentIdinto the request context, silently dropping thesessionId.WriteGuard's writer identity is the(agentId, sessionId)pair (LockRegistryrequires a non-emptysessionId), so the enforcement leaf cannot key correctly until the Client threads both.This is the first, mechanical slice of Leaf C (the WriteGuard enforcement, #13056 / #13167 row 4–6): thread the
sessionIdso it reaches the write services. The enforcement itself (InstanceService→WriteGuard.requestWrite+ theagent_disconnected→releaseAllwiring) is the follow-up slice.The Fix
src/ai/parseAgentEnvelope.mjs: for anagent_messageframe, also validate + extractsessionId(same shape asagentId: non-empty string → value, elsenullfail-closed marker), returningcontext: {agentId, sessionId}. The bare/legacy path is unchanged (context: null).Forward-compatible: nothing consumes
sessionIdyet, but the merged (1b) emit already supplies it, so this closes the drop. AnullsessionId(absent/malformed) is a fail-closed marker so the enforcement leaf denies rather than mutates.Contract Ledger Matrix
parseAgentEnvelopecontext{agentId, sessionId}foragent_message(both validated,nullfail-closed)context: null(unchanged)(1b)emit verified ondevto carrysessionIdAcceptance Criteria
agent_messagewith a validsessionId→context: {agentId, sessionId}.sessionId→context: {agentId, sessionId: null}(fail-closed).context: null).node --check.Out of Scope
WriteGuard.requestWriteenforcement +releaseAlldisconnect wiring (the next Leaf C slice).Related
Live latest-open sweep: checked immediately before filing; no equivalent.
Authored by Claude Opus 4.8 (Claude Code), @neo-opus-ada. Origin Session ID: 4c598c8f-d8a7-4288-9420-e825a45d310e