feat(plan): decision correction recomputes only affected subtree #845

Closed
opened 2026-03-13 21:58:12 +00:00 by freemo · 1 comment
Owner

Metadata

  • Commit Message: feat(plan): decision correction recomputes only affected subtree
  • Branch: feature/m4-correction-subtree

Background

M4 (v3.3.0) acceptance criterion: the correction engine must target only the affected subtree when recomputing decisions, rather than reprocessing the entire plan tree. This is critical for performance and correctness — corrections should not disturb unrelated branches.

Per the E2E verification suite (m6_e2e_verification.robot line 49), the test creates a decision tree, targets one child for correction, and verifies the CorrectionImpact excludes the root and sibling decisions. It also tests rollback_tier and dry-run report output.

Expected Behavior

When a decision correction is triggered on a specific node in the plan tree:

  1. Only the targeted node and its descendants are recomputed
  2. The root decision and sibling subtrees are left untouched
  3. CorrectionImpact accurately reports which decisions are affected vs excluded
  4. rollback_tier is correctly set based on the depth of the correction target
  5. A dry-run report can be generated before applying the correction

Acceptance Criteria

  • CorrectionEngine.correct() accepts a target decision ID and recomputes only that subtree
  • CorrectionImpact model excludes root and sibling decisions from the affected set
  • rollback_tier is computed correctly based on target depth in the decision tree
  • Dry-run mode produces a report without applying changes
  • Robot E2E test Decision Correction Recomputes Only Affected Subtree passes
  • Unit tests cover: single-node correction, leaf correction, multi-level subtree correction

Supporting Information

  • E2E test: robot/m6_e2e_verification.robot line 49
  • Related: #822 (checkpoint rollback), #823 (subplan spawn orchestration)
  • Spec reference: docs/specification.md — Correction Engine architecture

Subtasks

  • Implement subtree-scoped correction in CorrectionEngine
  • Add CorrectionImpact model with affected/excluded decision tracking
  • Implement rollback_tier computation based on tree depth
  • Implement dry-run report generation
  • Tests (Behave): Add scenarios for subtree correction edge cases
  • Tests (Robot): Verify E2E acceptance test passes
  • 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, 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.
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.
## Metadata - **Commit Message**: `feat(plan): decision correction recomputes only affected subtree` - **Branch**: `feature/m4-correction-subtree` ## Background M4 (v3.3.0) acceptance criterion: the correction engine must target only the affected subtree when recomputing decisions, rather than reprocessing the entire plan tree. This is critical for performance and correctness — corrections should not disturb unrelated branches. Per the E2E verification suite (`m6_e2e_verification.robot` line 49), the test creates a decision tree, targets one child for correction, and verifies the `CorrectionImpact` excludes the root and sibling decisions. It also tests `rollback_tier` and dry-run report output. ## Expected Behavior When a decision correction is triggered on a specific node in the plan tree: 1. Only the targeted node and its descendants are recomputed 2. The root decision and sibling subtrees are left untouched 3. `CorrectionImpact` accurately reports which decisions are affected vs excluded 4. `rollback_tier` is correctly set based on the depth of the correction target 5. A dry-run report can be generated before applying the correction ## Acceptance Criteria - [ ] `CorrectionEngine.correct()` accepts a target decision ID and recomputes only that subtree - [ ] `CorrectionImpact` model excludes root and sibling decisions from the affected set - [ ] `rollback_tier` is computed correctly based on target depth in the decision tree - [ ] Dry-run mode produces a report without applying changes - [ ] Robot E2E test `Decision Correction Recomputes Only Affected Subtree` passes - [ ] Unit tests cover: single-node correction, leaf correction, multi-level subtree correction ## Supporting Information - E2E test: `robot/m6_e2e_verification.robot` line 49 - Related: #822 (checkpoint rollback), #823 (subplan spawn orchestration) - Spec reference: `docs/specification.md` — Correction Engine architecture ## Subtasks - [ ] Implement subtree-scoped correction in `CorrectionEngine` - [ ] Add `CorrectionImpact` model with affected/excluded decision tracking - [ ] Implement `rollback_tier` computation based on tree depth - [ ] Implement dry-run report generation - [ ] Tests (Behave): Add scenarios for subtree correction edge cases - [ ] Tests (Robot): Verify E2E acceptance test passes - [ ] 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, 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. - The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done.
freemo added this to the v3.3.0 milestone 2026-03-13 21:58:17 +00:00
Member

Implementation Notes

Changes (commit dd820af5)

  1. analyze_impact() now populates excluded_decisions: After computing the affected subtree via BFS, the method collects all plan decisions and sets excluded_decisions = all_decisions - affected_decisions. This gives full visibility into which parts of the decision tree are untouched by a correction.

  2. compute_rollback_tier() added: Walks from the target decision up to the root counting parent hops. Tier 0 = root targeted (entire tree affected), Tier N = N levels deep. Added helper methods _find_root(), _find_parent(), and _compute_rollback_tier_depth().

  3. Enhanced dry-run report: generate_dry_run_report() now includes:

    • rollback_tier_depth in the report
    • Excluded decisions list
    • Warning when tier 0 (root targeted): "Tier 0: root decision targeted — entire tree will be affected"
  4. validate_subtree_isolation(): New validation method confirming root exclusion and sibling non-contamination for non-root corrections. Returns a boolean result.

Key Code Locations (commit dd820af5)

  • cleveragents.application.services.correction_service.CorrectionService.compute_rollback_tier()
  • cleveragents.application.services.correction_service.CorrectionService.validate_subtree_isolation()
  • cleveragents.application.services.correction_service.CorrectionService._collect_all_decisions()
  • cleveragents.domain.models.core.correction.CorrectionImpact.rollback_tier_depth (new field)
  • cleveragents.domain.models.core.correction.CorrectionDryRunReport.rollback_tier_depth (new field)

Test Coverage

  • Behave: 15 scenarios in features/correction_subtree_isolation.feature — leaf/middle/root targeting, tier computation at 4 depths, dry-run enhancements, isolation validation, edge cases
  • Robot: 8 integration tests in robot/correction_subtree_isolation.robot
  • Overall coverage: 97%, correction.py at 100%

Quality Gates

Session Result
lint PASS
typecheck PASS (0 errors)
unit_tests PASS (11,508 scenarios)
integration_tests PASS
coverage 97%

PR

PR #1075Closes #845

## Implementation Notes ### Changes (commit `dd820af5`) 1. **`analyze_impact()` now populates `excluded_decisions`**: After computing the affected subtree via BFS, the method collects all plan decisions and sets `excluded_decisions = all_decisions - affected_decisions`. This gives full visibility into which parts of the decision tree are untouched by a correction. 2. **`compute_rollback_tier()` added**: Walks from the target decision up to the root counting parent hops. Tier 0 = root targeted (entire tree affected), Tier N = N levels deep. Added helper methods `_find_root()`, `_find_parent()`, and `_compute_rollback_tier_depth()`. 3. **Enhanced dry-run report**: `generate_dry_run_report()` now includes: - `rollback_tier_depth` in the report - Excluded decisions list - Warning when tier 0 (root targeted): "Tier 0: root decision targeted — entire tree will be affected" 4. **`validate_subtree_isolation()`**: New validation method confirming root exclusion and sibling non-contamination for non-root corrections. Returns a boolean result. ### Key Code Locations (commit `dd820af5`) - `cleveragents.application.services.correction_service.CorrectionService.compute_rollback_tier()` - `cleveragents.application.services.correction_service.CorrectionService.validate_subtree_isolation()` - `cleveragents.application.services.correction_service.CorrectionService._collect_all_decisions()` - `cleveragents.domain.models.core.correction.CorrectionImpact.rollback_tier_depth` (new field) - `cleveragents.domain.models.core.correction.CorrectionDryRunReport.rollback_tier_depth` (new field) ### Test Coverage - **Behave**: 15 scenarios in `features/correction_subtree_isolation.feature` — leaf/middle/root targeting, tier computation at 4 depths, dry-run enhancements, isolation validation, edge cases - **Robot**: 8 integration tests in `robot/correction_subtree_isolation.robot` - Overall coverage: 97%, `correction.py` at 100% ### Quality Gates | Session | Result | |---|---| | lint | PASS | | typecheck | PASS (0 errors) | | unit_tests | PASS (11,508 scenarios) | | integration_tests | PASS | | coverage | 97% | ### PR PR #1075 — `Closes #845`
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#845
No description provided.