Files
cleveragents-core/features/plan_correct_tree_wiring.feature
T
freemo 61fc70d84b
CI / lint (push) Successful in 15s
CI / build (push) Successful in 18s
CI / quality (push) Successful in 18s
CI / security (push) Successful in 35s
CI / typecheck (push) Successful in 37s
CI / benchmark-regression (push) Has been skipped
CI / unit_tests (push) Successful in 2m11s
CI / docker (push) Successful in 42s
CI / integration_tests (push) Successful in 3m12s
CI / coverage (push) Successful in 4m40s
CI / benchmark-publish (push) Successful in 16m46s
fix(cli): pass decision tree and influence edges to CorrectionService in plan correct handler (#639)
## Summary

Fixes the `plan correct` CLI handler which never passes the decision tree or influence edges to `CorrectionService`, producing single-node impact analysis regardless of the plan's actual decision structure.

Closes #606

## Root Cause

The `correct_decision()` handler in `plan.py` created a bare `CorrectionService()` and called `analyze_impact()` and `execute_correction()` without passing `decision_tree` or `influence_edges`. Both parameters default to `None` -> empty dicts, causing `_compute_affected_subtree()` BFS to return only the single target decision, ignoring all descendants and influence-DAG dependents.

## Changes

### Production Fix (`src/cleveragents/cli/commands/plan.py`)
- Resolve `DecisionService` via `get_container()` (following the pattern used by `plan explain` and `plan tree`)
- Build structural tree adjacency list from `decision_svc.list_decisions(plan_id)` using `parent_decision_id` relationships
- Fetch influence edges from `decision_svc.get_influence_edges(plan_id)`
- Pass both `decision_tree` and `influence_edges` to `svc.analyze_impact()` and `svc.execute_correction()`

### Existing Test Fixups
- Updated 4 step definition files that mock `CorrectionService` to also mock the new `DecisionService` resolution path

### New Tests
- **Behave BDD**: 3 scenarios verifying tree/edge forwarding (dry-run subtree, execution subtree, leaf node)
- **Robot Framework**: 3 integration smoke tests
- **ASV Benchmark**: Tree building and analyze_impact overhead benchmarks

## Quality Gates

- `nox -s lint` — PASSED
- `nox -s typecheck` — 0 errors
- `nox -s unit_tests` — 9,109 scenarios, 0 failures
- `nox -s coverage_report` — 97%

ISSUES CLOSED: #606

Reviewed-on: #639
Co-authored-by: Jeffrey Phillips Freeman <jeffrey.freeman@cleverthis.com>
Co-committed-by: Jeffrey Phillips Freeman <jeffrey.freeman@cleverthis.com>
2026-03-08 23:28:05 +00:00

32 lines
1.7 KiB
Gherkin

@unit
Feature: plan correct passes decision tree and influence edges to CorrectionService
The plan correct CLI handler must resolve DecisionService via the DI
container, build the structural tree and influence DAG edges, and
forward them to CorrectionService.analyze_impact() and
CorrectionService.execute_correction() so that the BFS subtree
traversal reports the full affected subtreenot just the single
target decision.
Fixes: https://git.cleverthis.com/cleveragents/cleveragents-core/issues/606
Scenario: plan correct dry-run reports full affected subtree (not just target)
Given pctw a plan with a three-level decision tree
And pctw a CorrectionService that records analyze_impact arguments
When pctw I invoke plan correct in dry-run mode
Then pctw the dry-run output should list all three affected decisions
And pctw analyze_impact received the decision_tree and influence_edges
Scenario: plan correct execution reverts full affected subtree
Given pctw a plan with a three-level decision tree
And pctw a CorrectionService that records execute_correction arguments
When pctw I invoke plan correct in execution mode
Then pctw the execution output should show reverted decisions
And pctw execute_correction received the decision_tree and influence_edges
Scenario: plan correct with no children reports single decision
Given pctw a plan with a single leaf decision
And pctw a CorrectionService that records analyze_impact arguments
When pctw I invoke plan correct in dry-run mode for a leaf
Then pctw the dry-run output should list only the target decision
And pctw analyze_impact received empty tree and edges