feat(runtime): deterministic conflict path for subagent merges - #323
Conversation
|
Warning Review limit reached
More reviews will be available in 14 minutes and 42 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (3)
✨ 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 |
d35c416 to
bdced72
Compare
Phase B / PR-4 of moving mutating parallel subagents toward `safe` (stacked on #322's parent-merge executor). Conflicts stop being a dead end: false positives auto-apply, real ones block finish until the parent resolves them explicitly. No AI merging anywhere on this path. - Real-conflict refinement: the merge plan flags children by DECLARED write-scope overlap; the executor now treats a child as conflicted only when its changeset's ACTUAL paths intersect another declared-conflicted child's actual paths. Overlapping scopes with disjoint edits — the common false positive — apply deterministically like any other child. - Real conflicts surface as conflicted_unresolved (now with conflict_paths) and are registered as pending on the parent session. Finish is vetoed (stop_reason=unresolved_subagent_conflicts, recoverable) until every pending conflict is resolved. - New local action resolve_subagent_conflict {result_id, resolution}: 'apply' merges that child's changeset onto the CURRENT workspace through the same baseline-verified transactional executor (recorded as subagent_merge:<id>, so it still rolls back as one unit; a sibling that already changed the file makes the baseline check fail — reconcile and retry, or discard); 'discard' drops the changeset. Validation errors list the pending ids. The action is mutating (blocked inside open batches) and schema'd; both prompt templates teach the rule. Tests: declared-overlap/disjoint-edit auto-apply; finishing with pending conflicts terminates recoverably with nothing applied; apply+discard resolutions land exactly the chosen child's content and unblock finish (transaction id asserted); resolve-action input validation. 392 passed across the affected surface. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Oleg Miagkov <mrobenner@gmail.com>
The resolve_subagent_conflict apply path now reports mutation_snapshot_ids / mutated_paths / affected_paths like an applied run_subagents merge, so transaction summaries record the parent-side mutation and later failures in the same turn become partial_failure. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Oleg Miagkov <mrobenner@gmail.com>
bdced72 to
36b734a
Compare
|
Phase D / PR-7 — the final step of "mutating subagents -> safe" (stacked on the PR-6 gate requirement). The protocol is no longer scaffolded: - children are write-scope confined with runtime enforcement (#319), - they stage mutations and export changesets without touching the shared workspace (#320), - the parent applies each child transactionally with per-child rollback and baseline verification (#322), - real conflicts are never auto-applied — they block finish until the parent resolves explicitly (#323), - the whole mechanism is covered by the deterministic subagent_merge_probe (PR-5) which the promotion gate now requires (PR-6). With that evidence chain in place, AutonomyLevel.SAFE now defaults mutating_subagents_enabled=True. bold's remaining distinction is skipping the evidence gate. The explicit AUTO_CODE_MUTATING_SUBAGENTS=false override still opts out (covered by a new test), per ADR-006 precedence. ADR-006's level table updated. The .env.example and UI level descriptions live on the still-open #309/#318 branches and are updated there. Tests: safe-level expectations flipped (autonomy level + direct-API runtime policy grant); explicit env opt-out covered. 694 passed across the affected surface. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Oleg Miagkov <mrobenner@gmail.com>
Phase D / PR-7 — the final step of "mutating subagents -> safe" (stacked on the PR-6 gate requirement). The protocol is no longer scaffolded: - children are write-scope confined with runtime enforcement (#319), - they stage mutations and export changesets without touching the shared workspace (#320), - the parent applies each child transactionally with per-child rollback and baseline verification (#322), - real conflicts are never auto-applied — they block finish until the parent resolves explicitly (#323), - the whole mechanism is covered by the deterministic subagent_merge_probe (PR-5) which the promotion gate now requires (PR-6). With that evidence chain in place, AutonomyLevel.SAFE now defaults mutating_subagents_enabled=True. bold's remaining distinction is skipping the evidence gate. The explicit AUTO_CODE_MUTATING_SUBAGENTS=false override still opts out (covered by a new test), per ADR-006 precedence. ADR-006's level table updated. The .env.example and UI level descriptions live on the still-open #309/#318 branches and are updated there. Tests: safe-level expectations flipped (autonomy level + direct-API runtime policy grant); explicit env opt-out covered. 694 passed across the affected surface. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Oleg Miagkov <mrobenner@gmail.com>
…326) * chore: retrigger CI after base retarget to develop Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Oleg Miagkov <mrobenner@gmail.com> * feat(autonomy): enable mutating parallel subagents at the safe level Phase D / PR-7 — the final step of "mutating subagents -> safe" (stacked on the PR-6 gate requirement). The protocol is no longer scaffolded: - children are write-scope confined with runtime enforcement (#319), - they stage mutations and export changesets without touching the shared workspace (#320), - the parent applies each child transactionally with per-child rollback and baseline verification (#322), - real conflicts are never auto-applied — they block finish until the parent resolves explicitly (#323), - the whole mechanism is covered by the deterministic subagent_merge_probe (PR-5) which the promotion gate now requires (PR-6). With that evidence chain in place, AutonomyLevel.SAFE now defaults mutating_subagents_enabled=True. bold's remaining distinction is skipping the evidence gate. The explicit AUTO_CODE_MUTATING_SUBAGENTS=false override still opts out (covered by a new test), per ADR-006 precedence. ADR-006's level table updated. The .env.example and UI level descriptions live on the still-open #309/#318 branches and are updated there. Tests: safe-level expectations flipped (autonomy level + direct-API runtime policy grant); explicit env opt-out covered. 694 passed across the affected surface. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Oleg Miagkov <mrobenner@gmail.com> * chore: retrigger CI after base retarget to develop Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Oleg Miagkov <mrobenner@gmail.com> * chore: retrigger CI on develop base Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Oleg Miagkov <mrobenner@gmail.com> --------- Signed-off-by: Oleg Miagkov <mrobenner@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>



Context — Phase B / PR-4 of "mutating subagents → safe"
Conflicts stop being a dead end — and stay deterministic: false positives auto-apply, real ones block finish until the parent resolves explicitly. No AI merging anywhere on this path (semantic AutoMerger strategies can be layered behind
boldlater).What changes
1. Real-conflict refinement. The merge plan flags children by declared write-scope overlap; the executor now treats a child as conflicted only when its changeset's actual paths intersect another declared-conflicted child's actual paths. Overlapping scopes with disjoint edits — the common false positive — apply deterministically like any other child.
2. Finish-blocking conflict checkpoint. Real conflicts surface as
conflicted_unresolved(now withconflict_paths) and register as pending on the parent session. Finish is vetoed —stop_reason=unresolved_subagent_conflicts, recoverable — until every pending conflict is resolved. Same rails asunresolved_partial_failure.3. Explicit resolution action —
resolve_subagent_conflict {result_id, resolution}:applymerges that child's changeset onto the current workspace through the same baseline-verified transactional executor (recorded assubagent_merge:<id>— still rolls back as one unit). If a sibling already changed the file, the baseline check fails honestly: reconcile (e.g.rollback_transactionthe sibling) and retry, or discard.discarddrops the changeset.Tests (4 new, 392 passed across the surface)
session_state.stop_reason == unresolved_subagent_conflicts.applyedit-a +discardedit-b → exactly edit-a's content lands (transaction id asserted), finish unblocked.🤖 Generated with Claude Code