Skip to content

feat(runtime): execute the transactional parent merge of child changesets#321

Merged
OBenner merged 1 commit into
feat/subagent-changeset-exportfrom
feat/subagent-transactional-parent-merge
Jun 10, 2026
Merged

feat(runtime): execute the transactional parent merge of child changesets#321
OBenner merged 1 commit into
feat/subagent-changeset-exportfrom
feat/subagent-transactional-parent-merge

Conversation

@OBenner

@OBenner OBenner commented Jun 10, 2026

Copy link
Copy Markdown
Owner

Context — Phase B / PR-3 of "mutating subagents → safe"

Stacked on #320 (changeset export) — base branch is feat/subagent-changeset-export. After #320 merges, I'll retarget this PR to develop.

The merge plan stops being descriptive: after a run_subagents run 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:

  1. Scope revalidation (defense-in-depth): every entry path must sit inside the child's declared write_scope.
  2. Baseline verification: every entry's preimage must still match the live workspace (existing drift comparator). An unverifiable baseline refuses the merge exactly like real drift — no transactional rollback guarantee, no apply.
  3. Atomic apply per child: postimages applied in order; a mid-apply failure restores that child's captured baseline in reverse — siblings unaffected.
  4. One parent transaction per child: each applied changeset is recorded as a parent mutation snapshot with transaction id subagent_merge:<child-id> — the parent's existing rollback_transaction tool undoes exactly one child's merge.
  5. Conflicts are never auto-applied: overlapping-scope children surface as conflicted_unresolved for explicit resolution (deterministic AutoMerger routing is PR-4).

run_subagents wiring: action data now carries merge_plan + merge_execution; the action stays ok only 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)

  • End-to-end: parent (promoted direct-API session, bold) delegates to a REAL confined changeset child → the child's staged edit lands on the shared workspace via the parent, merge_execution.applied_result_ids == ["edit-a"], per-child transaction id recorded.
  • Baseline drift → refused, workspace intact, no snapshot recorded.
  • Mid-apply failure → first entry rolled back, nothing leaks.
  • rollback_transaction("subagent_merge:edit-a") → file restored to baseline.
  • Conflicted children → both conflicted_unresolved, nothing applied.
  • Delegation inside an open parent batch → refused, factory never invoked.

🤖 Generated with Claude Code

…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>
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (3)
  • develop
  • release/*
  • hotfix/*

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6a7f9819-1dd0-40e8-a901-d409f53e939e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/subagent-transactional-parent-merge

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud

Copy link
Copy Markdown

@OBenner OBenner merged commit a4c9d30 into feat/subagent-changeset-export Jun 10, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant