Context
The unblocked foundation of #13221 (NL mutation undo, Slice-1). Splitting #13221: its capture-hook + undo tool are blocked-by #13226 (the InstanceService enforcement grant-gate, at the human-merge-gate), but the in-heap transaction-stack core depends on neither the grant-gate nor the (agentId,sessionId) context — it is a pure stack authority, buildable + unit-provable in isolation, exactly as LockRegistry (#13125) / WriteGuard (#13134) / resolveWriteLock (#13208) shipped as standalone cores before their wiring. This ticket ships that core now; #13221 retains the capture-hook + undo-tool wiring on top, once #13226 merges.
Graduated shape: Discussion #13216 (§6.2 quorum). OQ2-C (in-memory now), the reverse-record schema (OQ1+OQ5), the open→committed→undone/aborted/timedOut state machine, and the caps are the converged ACs implemented here.
The Architectural Reality
Neo.ai.TransactionService is a per-heap, in-heap authority owned by Neo.ai.Client (sibling to Neo.ai.WriteGuard) — src/ai/TransactionService.mjs. It is the active undo stack, distinct by design from the forward-only RecorderService / nl_action_log audit ledger (D#13216 STEP_BACK #7). Pure over its inputs (reverse-capture, the enforcement grant, and the live tree live in the caller), so it is unit-testable via event sequences with no live-heap or socket dependency.
The Fix
src/ai/TransactionService.mjs + test/playwright/unit/ai/TransactionService.spec.mjs. State: per-session Map keyed by {neuralLinkSessionId, requesterAgentId, requesterSessionId} → {open, committed[]}. Lifecycle API: begin / record / commit / undo / abort / sweep / stackOf.
Acceptance Criteria
Out of Scope (→ #13221, post-#13226-merge)
- The
InstanceService capture-hook (post-enforcement-grant reverse-capture) — blocked-by #13226.
- The
undo Neural Link tool (6-site wiring) + the e2e — #13221.
redo + named batching (Slice-2), Memory-Core persistence (Slice-3), systemRollback — later #9848 children.
Related
- Parent: #13221 (Slice-1; this is its in-heap-core foundation). Slice-tracking grandparent: #9848. Epic: #13012 (Pillar-2).
- Pattern siblings:
LockRegistry (#13125), WriteGuard (#13134), resolveWriteLock (#13208), admitWrite (#13226).
- Graduated from Discussion #13216.
Release classification: post-release (Agent Harness Pillar-2 feature) — boardless.
Origin Session ID: 4cc428e3-cf36-4324-8646-1b96cb23fa4a
Authored by @neo-opus-vega (Claude Opus 4.8, Claude Code).
Context
The unblocked foundation of #13221 (NL mutation undo, Slice-1). Splitting #13221: its capture-hook +
undotool are blocked-by #13226 (the InstanceService enforcement grant-gate, at the human-merge-gate), but the in-heap transaction-stack core depends on neither the grant-gate nor the(agentId,sessionId)context — it is a pure stack authority, buildable + unit-provable in isolation, exactly asLockRegistry(#13125) /WriteGuard(#13134) /resolveWriteLock(#13208) shipped as standalone cores before their wiring. This ticket ships that core now; #13221 retains the capture-hook +undo-tool wiring on top, once #13226 merges.Graduated shape: Discussion #13216 (§6.2 quorum). OQ2-C (in-memory now), the reverse-record schema (OQ1+OQ5), the
open→committed→undone/aborted/timedOutstate machine, and the caps are the converged ACs implemented here.The Architectural Reality
Neo.ai.TransactionServiceis a per-heap, in-heap authority owned byNeo.ai.Client(sibling toNeo.ai.WriteGuard) —src/ai/TransactionService.mjs. It is the active undo stack, distinct by design from the forward-onlyRecorderService/nl_action_logaudit ledger (D#13216 STEP_BACK #7). Pure over its inputs (reverse-capture, the enforcement grant, and the live tree live in the caller), so it is unit-testable via event sequences with no live-heap or socket dependency.The Fix
src/ai/TransactionService.mjs+test/playwright/unit/ai/TransactionService.spec.mjs. State: per-sessionMapkeyed by{neuralLinkSessionId, requesterAgentId, requesterSessionId}→{open, committed[]}. Lifecycle API:begin/record/commit/undo/abort/sweep/stackOf.Acceptance Criteria
begin → record → commit → undoround-trips a transaction;undoreturns the reverse-ops in reverse capture order (last mutation undone first), single-level (most-recent committed).originWriter:{agentId, sessionId}(provenance only) +targetSubtreePath(audit only) +sequenceId+forward/reverse+label; provenance is preserved through undo.open → committed → undone,aborted(failure/teardown), with empty transactions dropped (not undoable).beginaborts a prior still-open transaction (no leak).txId(begin); no-open /txIdmismatch (record/commit); malformed op; non-serializable (cyclic) reverse (data-not-code guard); the caps below.maxStackDepth(oldest committed evicted past it — no longer undoable),maxOpsPerTransaction,maxReversePayloadBytes.sweepretires a session entirely (the transaction-side ofWriteGuard.releaseAgent, fail-closed on incomplete identity).stackOfreturns a deep copy (mutating it never affects the live stack).Out of Scope (→ #13221, post-#13226-merge)
InstanceServicecapture-hook (post-enforcement-grant reverse-capture) — blocked-by #13226.undoNeural Link tool (6-site wiring) + the e2e — #13221.redo+ named batching (Slice-2), Memory-Core persistence (Slice-3),systemRollback— later #9848 children.Related
LockRegistry(#13125),WriteGuard(#13134),resolveWriteLock(#13208),admitWrite(#13226).Release classification: post-release (Agent Harness Pillar-2 feature) — boardless.
Origin Session ID: 4cc428e3-cf36-4324-8646-1b96cb23fa4a
Authored by @neo-opus-vega (Claude Opus 4.8, Claude Code).