Context
Sub A1 of #13221 (Neural Link mutation undo, Slice-1), built on the merged #13238 (agentId, sessionId) 2-tuple TransactionService core. The first wiring slice: capture the reverse of a set_instance_properties write so it becomes undoable. (The undo NL tool + two-agent e2e = Sub A2; create_component / remove_component capture = Sub B.)
The Fix
Neo.ai.Client owns a per-heap TransactionService (sibling to WriteGuard, same singleton shape).
Neo.ai.client.InstanceService.setInstanceProperties captures the reverse-op (set⁻¹ = set(oldValues)) post-enforcement-grant, keyed on the live {agentId, sessionId} context, via a begin/record/commit per write. buildSetReverse captures the pre-set values + the audit targetSubtreePath; recordUndo commits the single-op tx best-effort.
Acceptance Criteria
Out of Scope
- The
undo NL tool (6-site wiring) + the two-agent e2e — Sub A2.
create_component / remove_component capture (needs a node-side marker, since they arrive app-side as generic call_method add/destroy) — Sub B.
Related
Authored by @neo-opus-vega (Claude Opus 4.8, Claude Code). Origin Session ID: 4cc428e3-cf36-4324-8646-1b96cb23fa4a.
Context
Sub A1 of #13221 (Neural Link mutation undo, Slice-1), built on the merged #13238
(agentId, sessionId)2-tupleTransactionServicecore. The first wiring slice: capture the reverse of aset_instance_propertieswrite so it becomes undoable. (TheundoNL tool + two-agent e2e = Sub A2;create_component/remove_componentcapture = Sub B.)The Fix
Neo.ai.Clientowns a per-heapTransactionService(sibling toWriteGuard, same singleton shape).Neo.ai.client.InstanceService.setInstancePropertiescaptures the reverse-op (set⁻¹ = set(oldValues)) post-enforcement-grant, keyed on the live{agentId, sessionId}context, via abegin/record/commitper write.buildSetReversecaptures the pre-set values + the audittargetSubtreePath;recordUndocommits the single-op tx best-effort.Acceptance Criteria
Clientowns a per-heapTransactionService.set_instance_propertiesagent write capturesset⁻¹(the pre-set values) onto the writer's(agentId, sessionId)stack; multiple writes accumulate as separate committed transactions.context) applies but is not captured (no writer identity ⇒ no per-writer stack).abort), never thrown into the forward write path.Out of Scope
undoNL tool (6-site wiring) + the two-agent e2e — Sub A2.create_component/remove_componentcapture (needs a node-side marker, since they arrive app-side as genericcall_method add/destroy) — Sub B.Related
Authored by @neo-opus-vega (Claude Opus 4.8, Claude Code). Origin Session ID: 4cc428e3-cf36-4324-8646-1b96cb23fa4a.