273 lines
9.1 KiB
Markdown
273 lines
9.1 KiB
Markdown
# Plan Correction API (v3.2.0 / v3.3.0)
|
||
|
||
The correction subsystem allows operators to modify a plan's decision tree after
|
||
execution by either **reverting** a subtree of decisions or **appending** new guidance
|
||
as a child plan. This page documents the CLI commands, correction modes, and the
|
||
subplan system that powers append-mode corrections.
|
||
|
||
---
|
||
|
||
## Overview
|
||
|
||
Plan corrections introduced across **v3.2.0** and **v3.3.0** provide two complementary
|
||
modes for adapting a plan's strategy without discarding accumulated context:
|
||
|
||
| Mode | Effect |
|
||
|------|--------|
|
||
| `revert` | Invalidates the targeted decision and all descendants; re-executes from that point |
|
||
| `append` | Preserves the original decision; spawns a new child plan with operator guidance |
|
||
|
||
Corrections never mutate existing decisions. Instead, a new `Decision` is created with
|
||
`is_correction=True` and `corrects_decision_id` pointing to the original. The original
|
||
decision has its `superseded_by` field set to the new decision's ID.
|
||
|
||
---
|
||
|
||
## CLI Reference
|
||
|
||
### `agents plan correct`
|
||
|
||
Apply a correction to a plan's decision tree.
|
||
|
||
```bash
|
||
agents plan correct <PLAN_ID> --decision <DECISION_ID> --mode <MODE> --guidance <TEXT> [OPTIONS]
|
||
```
|
||
|
||
**Options:**
|
||
|
||
| Flag | Description |
|
||
|------|-------------|
|
||
| `--decision` | ULID of the decision to correct (required) |
|
||
| `--mode` | Correction mode: `revert` or `append` (required) |
|
||
| `--guidance` | Operator guidance text (1–10,000 characters, required) |
|
||
| `--dry-run` | Preview impact without making changes |
|
||
| `--yes`, `-y` | Skip the interactive confirmation prompt |
|
||
| `--format`, `-f` | Output format: `json`, `yaml`, `plain`, `table`, `rich` |
|
||
|
||
**Revert mode — re-execute from a targeted decision point:**
|
||
|
||
```bash
|
||
agents plan correct 01HXYZ... \
|
||
--decision 01HABC... \
|
||
--mode=revert \
|
||
--guidance "Use a safer database migration approach"
|
||
```
|
||
|
||
This invalidates the targeted decision and every descendant reachable via BFS traversal.
|
||
Associated artifacts are archived and affected child plans are rolled back. The plan then
|
||
re-executes from the targeted decision point using the operator's guidance.
|
||
|
||
**Append mode — add guidance without recomputing:**
|
||
|
||
```bash
|
||
agents plan correct 01HXYZ... \
|
||
--decision 01HABC... \
|
||
--mode=append \
|
||
--guidance "Add input validation to the API endpoint"
|
||
```
|
||
|
||
This preserves the original decision and spawns a **new child plan** rooted at the target
|
||
node. The child plan carries the operator's guidance and produces additional decisions
|
||
without disturbing the existing tree.
|
||
|
||
**Dry-run preview:**
|
||
|
||
```bash
|
||
agents plan correct 01HXYZ... \
|
||
--decision 01HABC... \
|
||
--mode=revert \
|
||
--guidance "..." \
|
||
--dry-run
|
||
```
|
||
|
||
The dry-run report includes:
|
||
|
||
- **impact** — Affected decisions, files, child plans, estimated cost, and risk level.
|
||
- **decisions_to_invalidate** — Decision IDs that *would* be marked invalid (revert only).
|
||
- **child_plans_to_rollback** — Child plans that *would* be rolled back.
|
||
- **estimated_recompute_time_seconds** — Wall-clock estimate.
|
||
- **warnings** — Human-readable cautions (e.g. high risk).
|
||
|
||
---
|
||
|
||
## Correction Modes in Detail
|
||
|
||
### Revert Mode
|
||
|
||
Invalidates the targeted decision and every descendant reachable via BFS traversal:
|
||
|
||
```
|
||
┌─── D1 (target) ◄── revert starts here
|
||
│ │
|
||
│ ┌──┴──┐
|
||
│ D2 D3 ← all invalidated
|
||
│ │
|
||
│ D4 ← also invalidated
|
||
```
|
||
|
||
**Risk classification** based on affected decision count:
|
||
|
||
| Affected Count | Risk Level |
|
||
|----------------|------------|
|
||
| ≤ 3 | low |
|
||
| 4 – 10 | medium |
|
||
| > 10 | high |
|
||
|
||
### Append Mode
|
||
|
||
Preserves the original decision and spawns a new child plan:
|
||
|
||
```
|
||
D1 (target)
|
||
│
|
||
┌──┴──────────┐
|
||
D2 (original) CP-new ← child plan appended
|
||
```
|
||
|
||
The child plan runs in its own sandbox and its results are merged back into the parent
|
||
plan using the configured merge strategy.
|
||
|
||
---
|
||
|
||
## Correction Status Lifecycle
|
||
|
||
```
|
||
PENDING → ANALYZING → EXECUTING → APPLIED
|
||
→ FAILED
|
||
PENDING → CANCELLED
|
||
ANALYZING → CANCELLED
|
||
```
|
||
|
||
Each execution of a correction is tracked as a `CorrectionAttemptRecord`. Multiple
|
||
attempts may exist for a single correction (e.g. if a first attempt fails and the
|
||
operator retries).
|
||
|
||
---
|
||
|
||
## Subplan System Overview
|
||
|
||
The **append** correction mode relies on the subplan system to spawn and execute child
|
||
plans. Subplans are also used directly during Strategize when the strategy actor decides
|
||
to decompose work into parallel or sequential child plans.
|
||
|
||
### Spawning Child Plans
|
||
|
||
When a `subplan_spawn` or `subplan_parallel_spawn` decision is recorded during
|
||
Strategize, the `SubplanService` handles the spawn workflow:
|
||
|
||
1. Extract spawn decisions from `DecisionService`.
|
||
2. Build `SpawnEntry` objects from those decisions.
|
||
3. Validate resource scopes, merge strategy, and parallelism bounds.
|
||
4. Create `SubplanStatus` and `SpawnMetadata` for each entry.
|
||
5. Return the result for the caller to persist on the parent plan.
|
||
|
||
### Execution Modes
|
||
|
||
| Mode | Description |
|
||
|------|-------------|
|
||
| `sequential` | Execute one at a time in order |
|
||
| `parallel` | Execute concurrently (up to `max_parallel`, default 5) |
|
||
| `dependency_ordered` | Respect DAG dependencies via topological sort |
|
||
|
||
### Three-Way Merge
|
||
|
||
After subplans complete, their sandbox outputs are merged using the configured
|
||
`SubplanMergeStrategy`:
|
||
|
||
| Strategy | Description |
|
||
|----------|-------------|
|
||
| `git_three_way` | Three-way merge via `git merge-file` (default) |
|
||
| `sequential_apply` | Apply changes in completion order |
|
||
| `fail_on_conflict` | Raise `MergeConflictError` on any conflict |
|
||
| `last_wins` | Final subplan's output overwrites earlier ones |
|
||
|
||
The `git_three_way` strategy uses `git merge-file` to combine non-overlapping changes
|
||
from different subplans automatically. Overlapping changes produce conflict markers in
|
||
the output.
|
||
|
||
### Subplan Configuration
|
||
|
||
```yaml
|
||
subplan_config:
|
||
execution_mode: parallel # sequential | parallel | dependency_ordered
|
||
merge_strategy: git_three_way # git_three_way | sequential_apply | fail_on_conflict | last_wins
|
||
max_parallel: 5 # 1-50, for parallel mode
|
||
fail_fast: false # stop all on first failure
|
||
timeout_per_subplan_seconds: ~ # optional per-subplan timeout
|
||
retry_failed: true # auto-retry failed subplans
|
||
max_retries: 2 # 0-5, max retry attempts
|
||
```
|
||
|
||
---
|
||
|
||
## Phase Reversion
|
||
|
||
When corrections cannot be resolved within the current strategy, the plan may revert to
|
||
an earlier lifecycle phase:
|
||
|
||
| Source Phase | Target Phase | Trigger |
|
||
|-------------|-------------|---------|
|
||
| Execute | Strategize | Validation failures block apply; constraints too restrictive |
|
||
| Apply (constrained) | Strategize | Cannot proceed within current strategy constraints |
|
||
|
||
Phase reversion is subject to a **loop guard**: each plan may revert at most **3 times**
|
||
(`Plan.MAX_REVERSIONS`). Once this limit is reached, both automatic and manual
|
||
reversions are blocked.
|
||
|
||
Manual reversion via CLI:
|
||
|
||
```bash
|
||
agents plan revert <plan_id> --to-phase strategize --reason "constraints too strict"
|
||
```
|
||
|
||
---
|
||
|
||
## Python API
|
||
|
||
```python
|
||
from cleveragents.application.services.correction_service import CorrectionService
|
||
from cleveragents.domain.models.core.correction import CorrectionMode
|
||
|
||
correction_service = CorrectionService(unit_of_work=uow)
|
||
|
||
# Request a correction
|
||
correction = correction_service.request_correction(
|
||
plan_id="01HV...",
|
||
original_decision_id="01HABC...",
|
||
mode=CorrectionMode.REVERT,
|
||
guidance="Use a safer database migration approach",
|
||
)
|
||
|
||
# Preview impact (dry run)
|
||
report = correction_service.generate_dry_run_report(correction.id)
|
||
print(f"Risk: {report.impact.risk_level}, Affected: {len(report.decisions_to_invalidate)}")
|
||
|
||
# Execute the correction
|
||
correction_service.execute_correction(correction.id)
|
||
```
|
||
|
||
**Key service methods:**
|
||
|
||
| Method | Description |
|
||
|--------|-------------|
|
||
| `request_correction()` | Create a new correction request |
|
||
| `analyze_impact()` | BFS impact analysis on the decision tree |
|
||
| `generate_dry_run_report()` | Full report without side effects |
|
||
| `execute_revert()` | Invalidate subtree + archive artifacts |
|
||
| `execute_append()` | Spawn child plan preserving original decision |
|
||
| `execute_correction()` | Dispatch to revert or append based on mode |
|
||
| `get_correction()` | Retrieve a correction by ID |
|
||
| `list_corrections()` | List corrections (optional plan_id filter) |
|
||
| `cancel_correction()` | Cancel a pending/analyzing correction |
|
||
|
||
---
|
||
|
||
## See Also
|
||
|
||
- [`docs/reference/decision_correction.md`](../reference/decision_correction.md) — Full correction domain model reference
|
||
- [`docs/reference/subplans.md`](../reference/subplans.md) — Subplan execution and merge strategies
|
||
- [`docs/reference/phase_reversion.md`](../reference/phase_reversion.md) — Phase reversion state machine
|
||
- [`docs/api/decisions.md`](decisions.md) — Decision recording and tree CLI reference
|
||
- [`docs/api/checkpoints.md`](checkpoints.md) — Checkpoint and rollback CLI reference
|
||
- [ADR-007: Decision Tree & Correction](../adr/ADR-007-decision-tree-and-correction.md)
|