UAT: SubplanExecutionService silently swallows MergeConflictError — merge conflicts from parallel subplan results are never surfaced to the user #3270

Open
opened 2026-04-05 08:50:33 +00:00 by freemo · 2 comments
Owner

Metadata

  • Branch: fix/subplan-merge-conflict-surfacing
  • Commit Message: fix(subplan): surface MergeConflictError and enter conflict state on parallel subplan merge failures
  • Milestone: v3.3.0
  • Parent Epic: #368

Background and Context

This bug was discovered during UAT testing of the Subplan Spawning and Status Tracking feature area (v3.3.0). The three-way merge behavior when parallel subplans produce conflicting changes to the same file was tested, specifically the SubplanExecutionService.execute_all() method.

Per docs/specification.md §Child Plan Result Merging (lines 18430–18437):

"When merging subplan results, CleverAgents uses a three-way merge strategy to handle potential conflicts."
"Conflicting changes: If 'theirs' and 'mine' modify the same part of the resource, a conflict is flagged. The parent plan enters a conflict state, and the user is prompted to resolve the conflict. The user can choose to: Accept 'theirs', Accept 'mine', or Manually edit the resource to resolve the conflict."

Current Behavior

In src/cleveragents/application/services/subplan_execution_service.py, the execute_all() method catches MergeConflictError and only logs a warning:

# Lines 203-210
try:
    merge_result = self._merge_service.merge(base_files, successful_outputs)
except MergeConflictError:
    logger.warning("Merge conflict after subplan execution")
    all_succeeded = False

The conflict is silently swallowed — no user notification, no conflict state on the parent plan, no user prompting for resolution. The MergeConflictError exception is caught and discarded with only a log warning. The SubplanMergeResult with conflict information is never returned to the caller when FAIL_ON_CONFLICT strategy raises MergeConflictError.

Additionally, the ProcessingState enum in src/cleveragents/domain/models/core/plan.py has no conflict state — the spec requires the parent plan to enter a conflict state when merge conflicts occur, but this state does not exist in the implementation.

Affected code locations:

  • src/cleveragents/application/services/subplan_execution_service.py, lines 203–210 (execute_allMergeConflictError swallowed)
  • src/cleveragents/domain/models/core/plan.py, ProcessingState enum (missing conflict state)
  • src/cleveragents/application/services/subplan_merge_service.py, SubplanMergeResult (has conflict_files field but it is never propagated to the user)

Expected Behavior

Per the specification:

  1. When parallel subplan merges produce conflicts, the parent plan must enter a conflict state.
  2. The user must be notified and prompted to resolve the conflict.
  3. The user must be able to choose: Accept 'theirs', Accept 'mine', or Manually edit the resource.
  4. The SubplanMergeResult with conflict_files must be surfaced to the caller and ultimately to the user.

Acceptance Criteria

  • ProcessingState enum in plan.py includes a conflict state.
  • execute_all() in SubplanExecutionService does not swallow MergeConflictError; instead it transitions the parent plan to conflict state.
  • The SubplanMergeResult containing conflict_files is returned/propagated to the caller when conflicts occur.
  • A user-facing conflict resolution workflow is triggered (accept theirs / accept mine / manual edit) as specified.
  • No silent swallowing of MergeConflictError — the exception or its data must reach the user layer.

Supporting Information

  • Spec reference: docs/specification.md §Child Plan Result Merging, lines 18430–18437
  • Discovered during UAT testing of milestone v3.3.0 Subplan Spawning and Status Tracking feature area
  • Severity: Critical — blocks milestone acceptance; the spec explicitly requires user-facing conflict resolution for subplan merges

Subtasks

  • Add conflict state to ProcessingState enum in src/cleveragents/domain/models/core/plan.py
  • Refactor execute_all() in SubplanExecutionService to catch MergeConflictError, transition parent plan to conflict state, and propagate SubplanMergeResult with conflict data
  • Implement user-facing conflict resolution prompt (accept theirs / accept mine / manual edit) per spec §Child Plan Result Merging
  • Ensure SubplanMergeResult.conflict_files is surfaced through the service layer to the caller
  • Tests (Behave): Add BDD scenarios for three-way merge conflict detection and user resolution workflow
  • Tests (Robot): Add integration test for parallel subplan merge conflict end-to-end flow
  • Verify coverage >= 97% via nox -s coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly (fix(subplan): surface MergeConflictError and enter conflict state on parallel subplan merge failures), followed by a blank line, then additional lines providing relevant details about the implementation.
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly (fix/subplan-merge-conflict-surfacing).
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.
  • All nox stages pass.
  • Coverage >= 97%.

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/subplan-merge-conflict-surfacing` - **Commit Message**: `fix(subplan): surface MergeConflictError and enter conflict state on parallel subplan merge failures` - **Milestone**: v3.3.0 - **Parent Epic**: #368 ## Background and Context This bug was discovered during UAT testing of the Subplan Spawning and Status Tracking feature area (v3.3.0). The three-way merge behavior when parallel subplans produce conflicting changes to the same file was tested, specifically the `SubplanExecutionService.execute_all()` method. Per `docs/specification.md` §Child Plan Result Merging (lines 18430–18437): > "When merging subplan results, CleverAgents uses a three-way merge strategy to handle potential conflicts." > "Conflicting changes: If 'theirs' and 'mine' modify the same part of the resource, a conflict is flagged. The parent plan enters a `conflict` state, and the user is prompted to resolve the conflict. The user can choose to: Accept 'theirs', Accept 'mine', or Manually edit the resource to resolve the conflict." ## Current Behavior In `src/cleveragents/application/services/subplan_execution_service.py`, the `execute_all()` method catches `MergeConflictError` and only logs a warning: ```python # Lines 203-210 try: merge_result = self._merge_service.merge(base_files, successful_outputs) except MergeConflictError: logger.warning("Merge conflict after subplan execution") all_succeeded = False ``` The conflict is silently swallowed — no user notification, no `conflict` state on the parent plan, no user prompting for resolution. The `MergeConflictError` exception is caught and discarded with only a log warning. The `SubplanMergeResult` with conflict information is never returned to the caller when `FAIL_ON_CONFLICT` strategy raises `MergeConflictError`. Additionally, the `ProcessingState` enum in `src/cleveragents/domain/models/core/plan.py` has no `conflict` state — the spec requires the parent plan to enter a `conflict` state when merge conflicts occur, but this state does not exist in the implementation. **Affected code locations:** - `src/cleveragents/application/services/subplan_execution_service.py`, lines 203–210 (`execute_all` — `MergeConflictError` swallowed) - `src/cleveragents/domain/models/core/plan.py`, `ProcessingState` enum (missing `conflict` state) - `src/cleveragents/application/services/subplan_merge_service.py`, `SubplanMergeResult` (has `conflict_files` field but it is never propagated to the user) ## Expected Behavior Per the specification: 1. When parallel subplan merges produce conflicts, the parent plan must enter a `conflict` state. 2. The user must be notified and prompted to resolve the conflict. 3. The user must be able to choose: Accept 'theirs', Accept 'mine', or Manually edit the resource. 4. The `SubplanMergeResult` with `conflict_files` must be surfaced to the caller and ultimately to the user. ## Acceptance Criteria - [ ] `ProcessingState` enum in `plan.py` includes a `conflict` state. - [ ] `execute_all()` in `SubplanExecutionService` does not swallow `MergeConflictError`; instead it transitions the parent plan to `conflict` state. - [ ] The `SubplanMergeResult` containing `conflict_files` is returned/propagated to the caller when conflicts occur. - [ ] A user-facing conflict resolution workflow is triggered (accept theirs / accept mine / manual edit) as specified. - [ ] No silent swallowing of `MergeConflictError` — the exception or its data must reach the user layer. ## Supporting Information - Spec reference: `docs/specification.md` §Child Plan Result Merging, lines 18430–18437 - Discovered during UAT testing of milestone v3.3.0 Subplan Spawning and Status Tracking feature area - Severity: **Critical** — blocks milestone acceptance; the spec explicitly requires user-facing conflict resolution for subplan merges ## Subtasks - [ ] Add `conflict` state to `ProcessingState` enum in `src/cleveragents/domain/models/core/plan.py` - [ ] Refactor `execute_all()` in `SubplanExecutionService` to catch `MergeConflictError`, transition parent plan to `conflict` state, and propagate `SubplanMergeResult` with conflict data - [ ] Implement user-facing conflict resolution prompt (accept theirs / accept mine / manual edit) per spec §Child Plan Result Merging - [ ] Ensure `SubplanMergeResult.conflict_files` is surfaced through the service layer to the caller - [ ] Tests (Behave): Add BDD scenarios for three-way merge conflict detection and user resolution workflow - [ ] Tests (Robot): Add integration test for parallel subplan merge conflict end-to-end flow - [ ] Verify coverage >= 97% via `nox -s coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly (`fix(subplan): surface MergeConflictError and enter conflict state on parallel subplan merge failures`), followed by a blank line, then additional lines providing relevant details about the implementation. - The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly (`fix/subplan-merge-conflict-surfacing`). - The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done. - All nox stages pass. - Coverage >= 97%. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
freemo added this to the v3.3.0 milestone 2026-04-05 08:52:34 +00:00
Author
Owner

Issue triaged by project owner:

  • State: Verified — critical spec compliance bug with clear code analysis, spec references, and affected code locations
  • Priority: Critical (unchanged) — this blocks v3.3.0 milestone acceptance. The spec explicitly requires user-facing conflict resolution for subplan merges, and the current implementation silently swallows MergeConflictError.
  • Milestone: v3.3.0 (already set) — subplan spawning and merge conflict resolution is core M4 scope
  • MoSCoW: Must Have — the v3.3.0 acceptance criteria explicitly state: "Three-way merge combines non-conflicting changes; conflicts surfaced to user." This is a blocking acceptance criterion. The milestone cannot ship without this fix.
  • Parent Epic: #368 (referenced in issue body)

This is the highest-priority issue in the current triage queue. The silent swallowing of MergeConflictError means parallel subplan execution can produce incorrect results without any user notification.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: ca-project-owner

Issue triaged by project owner: - **State**: Verified — critical spec compliance bug with clear code analysis, spec references, and affected code locations - **Priority**: Critical (unchanged) — this blocks v3.3.0 milestone acceptance. The spec explicitly requires user-facing conflict resolution for subplan merges, and the current implementation silently swallows `MergeConflictError`. - **Milestone**: v3.3.0 (already set) — subplan spawning and merge conflict resolution is core M4 scope - **MoSCoW**: Must Have — the v3.3.0 acceptance criteria explicitly state: "Three-way merge combines non-conflicting changes; conflicts surfaced to user." This is a blocking acceptance criterion. The milestone cannot ship without this fix. - **Parent Epic**: #368 (referenced in issue body) This is the highest-priority issue in the current triage queue. The silent swallowing of `MergeConflictError` means parallel subplan execution can produce incorrect results without any user notification. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Critical — silently swallowing MergeConflictError means subplan merge failures go undetected
  • MoSCoW: Should Have — merge conflict handling is important for data integrity in the subplan execution pipeline, but the system can still function (conflicts are rare in practice)

Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: ca-project-owner

Issue triaged by project owner: - **State**: Verified - **Priority**: Critical — silently swallowing MergeConflictError means subplan merge failures go undetected - **MoSCoW**: Should Have — merge conflict handling is important for data integrity in the subplan execution pipeline, but the system can still function (conflicts are rare in practice) --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
freemo removed this from the v3.3.0 milestone 2026-04-07 00:11:28 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
#368 Epic: Subplans & Parallelism
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#3270
No description provided.