# ADR-007: Decision Tree and Correction

**Status:** Accepted  
**Date:** 2026-02-16  
**Supersedes:** None  
**Author(s):** Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com>  
**Approver(s):** Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com>

## Context

When an AI system generates a plan and executes it, individual decisions along the way may prove incorrect — a strategy choice may be suboptimal, a resource selection may be wrong, or the original prompt may be too vague. Without a persistent record of what decisions were made, why, and how they relate to each other, correction requires re-running the entire plan from scratch. For large, hierarchically decomposed plans, this is prohibitively expensive.

The system needs a structured decision graph that captures every choice point, its rationale, its context, and its downstream dependencies — enabling targeted correction that only invalidates and re-runs the affected subtree.

## Decision

Every plan maintains a **persistent decision tree** where each node is a typed decision record. The tree captures the prompt, invariant enforcement, strategy choices, resource selections, child plan blueprints, tool invocations, error recoveries, validation responses, and user interventions. All corrections — including prompt corrections — use a unified `agents plan correct` command that operates on decision nodes by ID.

## Design

### Decision Types

The system defines eleven decision types:

| Type | Description | Phase |
|------|-------------|-------|
| `prompt_definition` | The prompt/description for this plan (root decision) | Strategize |
| `invariant_enforced` | An invariant applicable to this plan, added as a constraint | Strategize |
| `strategy_choice` | High-level approach decision | Strategize |
| `implementation_choice` | How to implement a specific task | Execute |
| `resource_selection` | Which resources to read/modify | Strategize or Execute |
| `subplan_spawn` | Decision to create a child plan | Strategize |
| `subplan_parallel_spawn` | Decision to spawn a group of child plans concurrently | Strategize |
| `tool_invocation` | Which tool to use | Execute |
| `error_recovery` | How to handle a failure | Execute |
| `validation_response` | Response to a validation failure | Execute |
| `user_intervention` | User-provided guidance or correction | Any |

### The Prompt as Root Decision

The prompt passed to the strategy actor is the root `prompt_definition` decision node. This is significant because:

- Parent plans create child plan prompts as `prompt_definition` decisions in their own tree, which become root decisions of child plan trees.
- Invariants are recorded as `invariant_enforced` decisions, making them explicit tree nodes that constrain downstream decisions.
- Correcting the prompt uses the same mechanism as correcting any other decision.

### Decision Record Structure

Each decision record contains:

**Identity**: `decision_id` (ULID), `plan_id`, `parent_decision_id` (for tree structure), `sequence_number`.

**Classification**: `decision_type` (one of the eleven types above).

**The decision itself**: `question` (what was being answered), `chosen_option`, `alternatives_considered`, `confidence_score` (0.0-1.0, optional).

**Context snapshot**: `hot_context_hash`, `hot_context_ref`, `relevant_resources` (list of resource references), `actor_state_ref` (LangGraph checkpoint).

**Rationale**: `rationale` (why this option was chosen), `actor_reasoning` (raw LLM reasoning, optional).

**Downstream impact** (populated during Execute): `downstream_decision_ids`, `downstream_plan_ids`, `artifacts_produced`.

**Correction metadata**: `is_correction`, `corrects_decision_id`, `correction_reason`, `superseded_by`.

### Decision Timing

| Phase | Activity |
|-------|----------|
| Strategize | Initial decisions are created: `prompt_definition`, `invariant_enforced`, `strategy_choice`, `subplan_spawn`, `subplan_parallel_spawn`. `downstream_plan_ids` is empty. |
| Execute | Child plans are spawned and `downstream_plan_ids` is populated. Additional decisions may be created (`implementation_choice`, `resource_selection`, `tool_invocation`, `error_recovery`), constrained by Strategize-phase decisions. |
| Apply | No new decisions. History may be flagged for cleanup after successful apply. |

### Decision Making and Autonomy

Who makes decisions depends on the automation profile:

- `auto_decisions_strategize = 1.0` (always manual): User is prompted for each decision during Strategize.
- `auto_decisions_strategize = 0.0` (always automatic): Strategy actor decides autonomously, records reasoning.
- Intermediate thresholds: Auto-decide only when the confidence score meets or exceeds the threshold; otherwise prompt the user.

The same pattern applies to `auto_decisions_execute` for Execute-phase decisions.

### Unified Correction Mechanism

All corrections use:

```
agents plan correct <decision_id> --mode=<mode> --guidance "<text>"
```

**Parameters**: `decision_id` (ULID), `--mode` (`revert` — rollback and re-run, or `append` — add fix at end), `--guidance` (free-form corrected decision text).

Correcting a decision automatically invalidates all downstream decisions in the affected subtree (including child plans). The system knows the dependency graph and can re-run only the invalidated portion.

### Correction Scenarios

| Situation | Approach |
|---|---|
| Original request was too vague | Correct the `prompt_definition` decision |
| Strategy actor made a bad specific choice | Correct that specific `strategy_choice` decision |
| Parent gave child a bad prompt | Correct the child's `prompt_definition` |
| An invariant should not apply | Correct (remove) the `invariant_enforced` decision |
| A missing constraint should be added | Add a new `invariant_enforced` decision |
| Sequential children should be parallel | Correct decisions to use `subplan_parallel_spawn` |

### Storage Schema

Decisions are stored in a `decisions` table with columns for all record fields, plus `decision_dependencies` (parent-child edges) and `correction_attempts` (correction history with attempt number, mode, guidance, and outcomes).

## Constraints

- Every decision must have a `decision_type` from the eleven defined types. No untyped decisions.
- The `prompt_definition` decision is always the root of a plan's decision tree. Every plan has exactly one.
- Decisions created during Execute must be constrained by Strategize-phase decisions. Violation of this rule triggers phase reversion, not silent override.
- Correction of a decision must invalidate all downstream decisions in the subtree. Partial invalidation is not permitted.
- The `context_snapshot` must be sufficient to replay the decision in isolation (hash of hot context, pointer to full snapshot, actor state checkpoint).

## Consequences

### Positive
- Targeted correction avoids re-executing entire plans. Only the invalidated subtree is re-run.
- The persistent decision graph enables full auditability — every choice can be traced to its context and rationale.
- Treating the prompt as a decision node unifies the correction mechanism — no special case for prompt changes.
- The context snapshot enables debugging and replay of any individual decision.

### Negative
- Storing context snapshots and full decision records for every choice consumes significant storage, especially for large plans with many tool invocations.
- The dependency graph tracking adds complexity to the plan execution engine.
- Correction with downstream invalidation requires careful coordination when child plans are running concurrently.

### Risks
- Context snapshot storage could grow unbounded without retention policies.
- Correction cascades in deep hierarchies could invalidate large portions of completed work.
- The confidence score threshold mechanism depends on LLM-provided confidence values, which may not be well-calibrated.

## Alternatives Considered

**Flat decision log (append-only, no tree structure)** — Simpler to implement but does not support targeted correction. Correcting a single decision would require identifying all dependent decisions manually, which is error-prone and infeasible for large plans.

**No persistent decision tracking (re-run from scratch on correction)** — Adequate for small plans but prohibitively expensive for hierarchically decomposed plans where only a small subtree needs correction.

## Compliance

- **Decision type coverage tests**: Unit tests verify that all eleven decision types can be created, stored, retrieved, and corrected.
- **Correction cascade tests**: Tests verify that correcting a decision invalidates exactly the right downstream subtree — no more, no less.
- **Context snapshot integrity**: Tests verify that replaying a decision from its context snapshot produces consistent results.
- **BDD scenarios**: Behave features exercise correction workflows including prompt correction, strategy revision, and cross-hierarchy correction.
- **Storage retention tests**: Tests verify that decision history cleanup respects retention policies.

## Related ADRs

| ADR | Title | Relationship |
|-----|-------|-------------|
| [ADR-006](ADR-006-plan-lifecycle.md) | Plan Lifecycle | Decision trees are built during lifecycle phases and drive phase transitions |
| [ADR-016](ADR-016-invariant-system.md) | Invariant System | Enforced invariants are recorded as decision nodes in the tree |
| [ADR-017](ADR-017-automation-profiles.md) | Automation Profiles | Confidence thresholds determine which decisions require human intervention |

## Acceptance

### Votes For

| Voter | Comment |
|-------|---------|
| Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com> | Persistent decision graphs enable targeted correction without re-running entire plans |

**Total: 1**

### Votes Against

| Voter | Comment |
|-------|---------|

**Total: 0**

### Abstentions

| Voter | Comment |
|-------|---------|

**Total: 0**
