feat(runtime): execute the transactional parent merge of child changesets#321
Conversation
…sets Phase B / PR-3 of moving mutating parallel subagents toward `safe` (stacked on #320's changeset export). The merge plan is no longer just descriptive: after a run_subagents run whose plan requires a parent merge, the parent now APPLIES each child's exported changeset transactionally. - execute_subagent_changeset_merge: each mutating child is one transaction boundary. Its changeset is scope-revalidated (defense-in-depth against a tampered payload), baseline-verified (every entry's preimage must still match the live workspace via the existing drift comparator — an unverifiable baseline refuses the merge just like real drift), then applied as a unit. A mid-apply failure restores that child's captured baseline in reverse order; siblings are unaffected. Conflicted children are NEVER auto-applied — they surface as conflicted_unresolved for explicit resolution (deterministic AutoMerger routing lands in PR-4). - Each applied child is recorded as a parent mutation snapshot with transaction id subagent_merge:<child-id>, so the parent's existing rollback_transaction tool can undo exactly one child's merge. - run_subagents now reports merge_plan + merge_execution in its action data; the action only stays ok when every appliable changeset applied (applied/noop). Mutating delegation inside an open model-managed batch is refused up front (mutating_subagents_in_open_batch) before any child spawns. Tests: end-to-end parent run (real confined changeset child; file lands on the shared workspace via the parent; merge_execution recorded with the per-child transaction id), baseline drift refused with workspace intact, mid-apply failure rolled back (first entry restored), applied child undone via rollback_transaction, conflicted children kept unapplied, and delegation refused inside an open parent batch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Oleg Miagkov <mrobenner@gmail.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review (3)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|



Context — Phase B / PR-3 of "mutating subagents → safe"
The merge plan stops being descriptive: after a
run_subagentsrun whose plan requires a parent merge, the parent now applies each child's exported changeset transactionally.What changes (
generic_edit.py)execute_subagent_changeset_merge— each mutating child is one transaction boundary:write_scope.subagent_merge:<child-id>— the parent's existingrollback_transactiontool undoes exactly one child's merge.conflicted_unresolvedfor explicit resolution (deterministic AutoMerger routing is PR-4).run_subagentswiring: action data now carriesmerge_plan+merge_execution; the action staysokonly when every appliable changeset applied (applied/noop). Mutating delegation inside an open model-managed batch is refused up front (mutating_subagents_in_open_batch) before any child spawns.Tests (6 new, 233 passed in the runtime file; 398 across the surface)
merge_execution.applied_result_ids == ["edit-a"], per-child transaction id recorded.rollback_transaction("subagent_merge:edit-a")→ file restored to baseline.conflicted_unresolved, nothing applied.🤖 Generated with Claude Code