docs(spec): add Plan Correction Engine specification (v3.2.0) #8627

Closed
HAL9000 wants to merge 1 commits from spec/plan-correction-engine-v3.2.0 into master
+169
View File
@@ -47095,3 +47095,172 @@ These architectural invariants must be maintained across all milestones:
8. **BDD tests**: All unit-level tests expressed as Behave/Gherkin scenarios. No xUnit-style tests.
9. **File size limit**: No source file exceeds 500 lines. Split into modules if approaching limit.
10. **Atomic commits**: One logical change per commit. No mixed concerns.
---
## Plan Correction Engine (v3.2.0)
### Overview
The Plan Correction Engine allows users to retroactively correct decisions in a plan's decision tree. It supports two correction modes:
- **Revert mode** (`--mode revert`): Re-executes the plan from the targeted decision point with new guidance. The affected subtree is recomputed; only the branch from the target decision forward is re-executed.
- **Append mode** (`--mode append`): Adds guidance to the plan without recomputing past decisions. Future decisions will include the correction annotation in their context.
Correction triggers selective subtree recomputation — only the affected branch is re-executed, not the entire plan.
### Module Boundaries
- **Module**: `cleveragents.corrections`
- **Layer**: Application (orchestrates Domain modules)
- **Responsibilities**:
- Accepting correction requests from CLI
- Identifying the affected subtree for recomputation
- Orchestrating re-execution of the affected subtree
- Merging corrected results back into the plan
- Persisting correction history
- **Public Interfaces**:
- `PlanCorrectionEngine` — main entry point for correction operations
- `CorrectionRequest` — value object representing a correction request
- `CorrectionResult` — value object representing the outcome of a correction
- **Allowed Dependencies**:
- `cleveragents.decisions.DecisionTreeQuery` — to find affected subtree
- `cleveragents.plans.PlanExecutor` — to re-execute affected subtree
- `cleveragents.invariants.InvariantEnforcer` — to apply invariants during re-execution
- **Forbidden Dependencies**: Must not import from `cleveragents.cli` or `cleveragents.tui`
### Data Models
#### CorrectionRequest
```python
@dataclass
class CorrectionRequest:
plan_id: UUID
target_decision_id: UUID # The decision to correct from
mode: Literal["revert", "append"]
guidance: str # User-provided correction guidance
requested_by: str
requested_at: datetime
```
#### CorrectionResult
```python
@dataclass
class CorrectionResult:
correction_id: UUID
plan_id: UUID
mode: Literal["revert", "append"]
affected_decision_ids: list[UUID] # Decisions that were recomputed (revert mode)
new_decision_ids: list[UUID] # New decisions created
status: Literal["success", "partial", "failed"]
summary: str
```
#### CorrectionRecord (persisted)
```python
@dataclass
class CorrectionRecord:
id: UUID
plan_id: UUID
target_decision_id: UUID
mode: Literal["revert", "append"]
guidance: str
requested_by: str
requested_at: datetime
completed_at: Optional[datetime]
status: Literal["pending", "running", "success", "failed"]
result: Optional[CorrectionResult]
```
### Database Schema
```sql
CREATE TABLE correction_records (
id UUID PRIMARY KEY,
plan_id UUID NOT NULL REFERENCES plans(id) ON DELETE CASCADE,
target_decision_id UUID NOT NULL REFERENCES decisions(id),
mode VARCHAR(10) NOT NULL CHECK (mode IN ('revert', 'append')),
guidance TEXT NOT NULL,
requested_by VARCHAR(255) NOT NULL,
requested_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
completed_at TIMESTAMPTZ,
status VARCHAR(20) NOT NULL DEFAULT 'pending'
CHECK (status IN ('pending', 'running', 'success', 'failed')),
result JSONB
);
CREATE INDEX idx_corrections_plan_id ON correction_records(plan_id);
CREATE INDEX idx_corrections_target_decision ON correction_records(target_decision_id);
```
### Correction Algorithms
#### Revert Mode Algorithm
1. Identify the target decision node in the decision tree via `DecisionTreeQuery`
2. Find all descendant decisions (the "affected subtree") using `DecisionTreeQuery.get_subtree(target_decision_id)`
3. Mark all affected decisions as `superseded` in the database
4. Re-execute the plan from the target decision point with the correction guidance injected into the LLM context
5. New decisions are recorded via `DecisionRecorder` and replace the superseded subtree
6. Plan state is updated to reflect the new execution path
7. `CorrectionRecord` is updated with status `success` and the result
#### Append Mode Algorithm
1. Identify the target decision node
2. Add the correction guidance as a `CorrectionAnnotation` on the target decision (stored in `correction_records`)
3. Do NOT recompute any past decisions
4. Future decisions in the plan will include the correction annotation in their context window
5. `CorrectionRecord` is updated with status `success`
### CLI Interface Specification
#### `agents plan correct <plan-id> --mode revert --decision <decision-id> --guidance "<text>"`
- Triggers revert-mode correction
- Required flags: `--mode revert|append`, `--decision <decision-id>`, `--guidance <text>`
- Optional flags:
- `--dry-run` — shows what would be recomputed without executing
- `--yes` — skip confirmation prompt
- Shows progress as subtree is recomputed
- Output: Summary of affected decisions and new decisions created
#### `agents plan correct <plan-id> --mode append --decision <decision-id> --guidance "<text>"`
- Triggers append-mode correction
- Adds guidance annotation without recomputation
- Output: Confirmation with correction record ID
### Integration Points
| Integration | Direction | Description |
|---|---|---|
| Decision Recording System | Uses | `DecisionTreeQuery` to identify affected subtree; new decisions recorded via `DecisionRecorder` |
| Plan Executor | Uses | Re-execution uses `PlanExecutor` with correction context injected |
| Invariant System | Uses | Active invariants re-applied during revert-mode re-execution |
| CLI | Called by | `agents plan correct` command delegates to `PlanCorrectionEngine` |
### Error Handling
- `CorrectionTargetNotFoundError(decision_id)` — target decision does not exist
- `CorrectionConflictError(plan_id)` — another correction is already running on this plan
- `CorrectionSubtreeError(decision_id, reason)` — subtree identification failed
- `CorrectionExecutionError(correction_id, reason)` — re-execution failed
All errors are application-layer exceptions (not domain or infrastructure exceptions).
### Cross-Cutting Concerns
- **Idempotency**: Each correction gets a unique ID; re-submitting the same correction is a no-op if already completed
- **Concurrency**: Only one correction may run per plan at a time (enforced by optimistic locking on `correction_records.status`)
- **Logging**: All correction operations logged at INFO level with correction ID and plan ID
- **Audit Trail**: All corrections are persisted in `correction_records` for audit purposes
- **Dry Run**: `--dry-run` flag shows the affected subtree without executing; useful for previewing impact
---
**Automated by CleverAgents Bot**
Supervisor: Architecture | Agent: architecture-pool-supervisor
Worker: [AUTO-ARCH-3B]