LearnNewsExamplesServices
Frontmatter
id13257
titleNeural Link mutation undo — Sub-A2: the `undo` NL tool (peek → re-dispatch reverse → consume)
stateClosed
labels
enhancement
assigneesneo-opus-vega
createdAtJun 14, 2026, 9:14 PM
updatedAtJun 14, 2026, 10:02 PM
githubUrlhttps://github.com/neomjs/neo/issues/13257
authorneo-opus-vega
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 14, 2026, 10:02 PM

Neural Link mutation undo — Sub-A2: the undo NL tool (peek → re-dispatch reverse → consume)

neo-opus-vega
neo-opus-vega commented on Jun 14, 2026, 9:14 PM

Context

Sub-A2 of #13221 (NL mutation undo — Slice-1). The TransactionService core (#13230/#13231) and the set_instance_properties reverse-capture hook (Sub-A1, #13248/#13249) have merged. This sub adds the undo NL tool — the layer that makes captured reverses actually invocable, so an agent can say "undo that" and the live app reverts. Pillar-2 / #13012, parent #9848.

Scope — the tool layer (no core change)

The TransactionService core already exposes everything needed: undo({id}) pops the last committed tx, marks it undone, and returns reverseOps (reverse capture order); stackOf({id}) is a non-consuming peek. So Sub-A2 is purely the NL-tool wiring + orchestration:

  • undo execution: peek the requester's last committed tx (stackOf) → if none, recoverable nothing-to-undo. Re-dispatch each captured reverse op ({tool, args}) through the normal enforced dispatch (Client.handleRequest) so it re-enters admitWrite as the current caller, with subtreePath re-derived on the live tree. On full success, call undo() to consume (mark undone).
  • Capture-suppression during replay: the re-dispatch carries a context.undoReplay marker; the capture-hook skips recording — undo must not create a new undoable tx (single-level Slice-1; redo is Slice-2).
  • Preserve-on-fail: a denied / unresolvable re-dispatch → no-op (tx stays committed, not consumed) + recoverable error. (Safe: capture is suppressed during replay + the App Worker is single-threaded, so the peeked last-committed tx is stable through the consume.)

Acceptance Criteria

  • undo NL tool (write-locked tier) reverts the requester's last committed transaction, re-dispatching the captured reverse via the enforced dispatch path (re-enters admitWrite as the current caller; subtreePath re-derived on the live tree — NOT the stored audit path). Generic admin call_method is NOT undoable (only the 3 whitelisted tools).
  • Capture is suppressed during undo-replay (no new undoable tx).
  • Preserve-on-fail: denied / unresolvable-target re-dispatch → no-op (tx preserved) + recoverable error; nothing-to-undo → recoverable error.
  • 6-site NL-tool wiring complete: openapi.yaml (path + tier + schema), Client serviceMap, the service method, the 2 OpenApiValidatorCompliance fixtures (expectedNeuralLinkToolTiers + neuralLinkDangerousReadForbidden), unit test (autoConnect=false before import).
  • Unit coverage: undo-of-set success; nothing-to-undo; denied / unresolvable preserve-on-fail; capture-suppression-during-replay. e2e: agent sets a property → undo → reverts in the live tree, stack consumed.

Out of Scope

  • create_component / remove_component reverse-capture + their undo e2e → Sub-B (this tool re-dispatches whatever reverse is captured, so it works for those once Sub-B lands; only set is captured today, so only undo-of-set is e2e-proven here).
  • redo, named/atomic batching → Slice-2 (#13221 out-of-scope). Memory-Core persistence → Slice-3.

Related

  • Parent: #13221 (Slice-1). Slice-tracking parent: #9848. Pillar-2: #13012.
  • Core: src/ai/TransactionService.mjs (undo, stackOf). Capture-hook: src/ai/client/InstanceService.mjs (#13249). Enforcement: src/ai/admitWrite.mjs, deriveSubtreePath.

Authored by @neo-opus-vega (Claude Opus 4.8, Claude Code). Origin Session ID: 4cc428e3-cf36-4324-8646-1b96cb23fa4a.

tobiu referenced in commit 1035769 - "feat(ai): the undo Neural Link tool — peek, re-dispatch reverse, consume (#13257) (#13259) on Jun 14, 2026, 10:02 PM
tobiu closed this issue on Jun 14, 2026, 10:02 PM