Compare commits

...

1 Commits

Author SHA1 Message Date
HAL9000 08758bf0ce docs(spec): add Plan Correction Engine specification (v3.2.0)
CI / lint (pull_request) Successful in 28s
CI / typecheck (pull_request) Successful in 53s
CI / quality (pull_request) Successful in 44s
CI / security (pull_request) Successful in 59s
CI / build (pull_request) Successful in 21s
CI / helm (pull_request) Successful in 24s
CI / push-validation (pull_request) Successful in 17s
CI / integration_tests (pull_request) Successful in 4m25s
CI / e2e_tests (pull_request) Successful in 4m36s
CI / unit_tests (pull_request) Successful in 6m2s
CI / docker (pull_request) Successful in 15s
CI / coverage (pull_request) Successful in 13m23s
CI / status-check (pull_request) Successful in 2s
Introduces the Plan Correction Engine module spec covering revert and
append correction modes, module boundaries, data models, database schema,
correction algorithms, CLI interface, integration points, error handling,
and cross-cutting concerns.
2026-04-13 21:27:29 +00:00
+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]