Files
cleveragents-core/docs/reference/decision_model.md
T

123 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Decision Domain Model
The decision subsystem records every choice point in a plan's lifecycle
as a **Decision** node in a persistent tree. Decisions are created
during the Strategize and Execute phases and form the basis for
targeted correction and replay.
## Decision Types
| Type | Phase | Description |
|--------------------------|------------|------------------------------------------|
| `prompt_definition` | Strategize | Root decision — the plan prompt |
| `invariant_enforced` | Strategize | An invariant constraint was applied |
| `strategy_choice` | Strategize | High-level approach chosen |
| `implementation_choice` | Execute | How to implement a specific task |
| `resource_selection` | Execute | Which resources to read / modify |
| `subplan_spawn` | Strategize | Decision to create a child plan |
| `subplan_parallel_spawn` | Strategize | Spawn a group of child plans in parallel |
| `tool_invocation` | Execute | Which skill / tool to use |
| `error_recovery` | Execute | How to handle a failure |
| `validation_response` | Execute | Response to a validation failure |
| `user_intervention` | Any | User-provided guidance / correction |
## Decision Fields
### Identity
- **decision_id** — ULID, auto-generated
- **plan_id** — ULID of the parent plan (required)
- **parent_decision_id** — ULID of the parent decision, or `None` for the root
- **sequence_number** — monotonic order within the plan (0-indexed, never reused)
### Classification
- **decision_type** — one of the 11 `DecisionType` enum values
### Content
- **question** — what question was being answered (required, non-empty)
- **chosen_option** — the option that was selected (required, non-empty)
- **alternatives_considered** — list of other options evaluated
- **confidence_score** — float 0.01.0, or `None` if not applicable
### Context Snapshot
Every decision captures a `ContextSnapshot` for replay:
- **hot_context_hash** — cryptographic hash of the context window
- **hot_context_ref** — storage pointer to the full serialised context
- **relevant_resources** — list of `ResourceRef` entries (resource_id + optional path)
- **actor_state_ref** — LangGraph actor checkpoint reference
### Rationale
- **rationale** — human-readable explanation
- **actor_reasoning** — raw LLM reasoning trace, if available
### Downstream Impact
- **downstream_decision_ids** — ULIDs of decisions that depend on this one
- **downstream_plan_ids** — ULIDs of child plans spawned from this decision
- **artifacts_produced** — list of `ArtifactRef` (artifact_path + artifact_type)
### Timestamps
- **created_at** — UTC datetime, auto-set on creation
### Correction Metadata
- **is_correction** — boolean, True if this decision corrects another
- **corrects_decision_id** — ULID of the original decision
- **correction_reason** — why the correction was made
- **superseded_by** — ULID of the decision that replaced this one
## Tree Structure
Decisions form a tree via `parent_decision_id`:
```
prompt_definition (root, parent=None)
├── invariant_enforced
├── strategy_choice
│ ├── implementation_choice
│ │ ├── resource_selection
│ │ └── tool_invocation
│ └── subplan_spawn
└── strategy_choice
```
The `prompt_definition` type is always the root and must have
`parent_decision_id = None`. This is enforced by a model validator.
## Correction Lifecycle
Corrections never mutate existing decisions. Instead:
1. A new `Decision` is created with `is_correction=True` and
`corrects_decision_id` pointing to the original.
2. The original decision has its `superseded_by` field set to the
new decision's ID.
3. All downstream decisions of the original are also superseded.
The **current tree** consists of all decisions where
`superseded_by IS NULL`.
## Validation Rules
- `plan_id` must be a valid ULID
- `parent_decision_id`, `corrects_decision_id`, `superseded_by` must
be valid ULIDs or None
- `confidence_score` must be in [0.0, 1.0] or None
- `prompt_definition` decisions must have `parent_decision_id = None`
- If `is_correction` is True, `corrects_decision_id` must be set
- If `corrects_decision_id` is set, `is_correction` must be True
## Source
- Domain model: `src/cleveragents/domain/models/core/decision.py`
- Specification: `docs/specification.md` L18390L18521
- ADR-007: Decision tree and correction
- ADR-033: Decision recording protocol
- ADR-034: Decision tree versioning and history