# Entities — Data Models Reference

## Plan

A Plan is the fundamental unit of orchestration. Plans are ULID-identified and progress through four phases (Action → Strategize → Execute → Apply).

**Key fields:**
- `plan_id`: ULID (immutable)
- `parent_plan_id`: ULID? (null for root plans; child plans have this set)
- `root_plan_id`: ULID (top-most plan in hierarchy)
- `attempt`: int (increments on correction or re-run)
- `phase`: action | strategize | execute | apply
- `state`: queued | processing | complete | errored | cancelled | applied | constrained
- `automation_profile`: resolved profile (locked at plan creation time)
- `projects`: list of project names the plan targets

Top-level plans carry a namespaced name (`[[server:]namespace/]name`). Child plans are identified solely by plan_id.

---

## Decision

A decision is a persisted choice point in the plan's decision tree.

**10 Decision Types:**

| Type | Phase Created | Creator |
|------|--------------|---------|
| `prompt_definition` | System | Plan lifecycle engine (root decision — always exactly 1 per plan) |
| `invariant_enforced` | Strategize | Invariant Reconciliation Actor |
| `strategy_choice` | Strategize | Strategy actor |
| `resource_selection` | Strategize | Strategy actor |
| `subplan_spawn` | Strategize | Strategy actor |
| `subplan_parallel_spawn` | Strategize | Strategy actor |
| `implementation_choice` | Execute | Execution actor |
| `tool_invocation` | Execute | Execution actor |
| `error_recovery` | Execute | Execution actor |
| `validation_response` | Execute | Execution actor |
| `user_intervention` | Any | System (when user provides guidance/correction) |

**Key fields:**
- `decision_id`: ULID
- `plan_id`: ULID (parent plan)
- `parent_decision_id`: ULID? (structural tree parent — not the same as influence DAG)
- `sequence_number`: int (monotonically increasing, never reused; gaps = superseded decisions)
- `question`: str
- `chosen_option`: str
- `alternatives_considered`: list[str]
- `confidence_score`: float? (0.0–1.0)
- `rationale`: str
- `context_snapshot`: {hot_context_hash, hot_context_ref, actor_state_ref}
- `downstream_decision_ids`: list[ULID] (populated during Execute)
- `downstream_plan_ids`: list[ULID] (child plans spawned because of this decision)
- `artifacts_produced`: list[ArtifactRef]
- `is_correction`: bool
- `corrects_decision_id`: ULID?
- `superseded_by`: ULID? (null = still active)

**Dual structure:**
- **Structural tree** (`parent_decision_id`): rendering, navigation, `agents plan tree`
- **Influence DAG** (`decision_dependencies` table): impact analysis, `agents plan correct` subtree computation

**Superseded decisions are NEVER deleted.** They remain as permanent history. `agents plan tree --show-superseded` renders both current and historical branches.

---

## Action

An Action is a reusable plan template (project-agnostic). Identified by namespaced name, not ULID.

**Key fields:**
- `name`: namespaced name (`[[server:]namespace/]name`)
- `short_description` / `long_description`
- `definition_of_done`: required; explicit and testable
- `strategy_actor`: required
- `execution_actor`: required
- `estimation_actor`: optional
- `invariant_actor`: optional
- `reusable`: bool (default: true; if false, action auto-deletes after first use)
- `read_only`: bool (default: false; if true, only read-only tools allowed)
- `inputs_schema`: typed argument declarations
- `automation_profile`: default profile for plans created from this action

---

## Session

A Session is a persistent conversation thread with an orchestrator actor.

**Key fields:**
- `session_id`: stable ID (must be resumable across CLI invocations)
- `actor`: the orchestrator actor bound to this session
- `message_history`: maintained across plans in this session
- `active_plans`: references to in-progress plans

**Requirements:**
- Stable IDs (not regenerated each run)
- Resumable across CLI invocations
- Storage backend must be configured explicitly
- No silent history loss if persistence is disabled

---

## Invariant

An Invariant is a natural-language constraint on plan execution.

**Scopes:** global | project | action | plan

**Precedence (highest to lowest):** plan > action > project > global

**Exception:** Global invariants marked `non_overridable: true` ALWAYS take precedence, even over plan-level invariants.

**Key fields:**
- `invariant_id`: identifier
- `scope`: global | project | action | plan
- `text`: natural-language constraint text
- `non_overridable`: bool (only meaningful on global scope)
- `scope_ref`: reference to project/action/plan it's attached to

---

## Automation Profile

Controls which plan operations proceed automatically vs. require human approval.

**Key fields:**
- `name`: namespaced name (built-ins use no namespace: `manual`, `review`, etc.)
- `description`: human-readable description
- 11 confidence threshold fields (0.0–1.0): `decompose_task`, `create_tool`, `select_tool`, `edit_code`, `execute_command`, `create_file`, `delete_content`, `access_network`, `install_dependency`, `modify_config`, `approve_plan`
- `safety`: SafetyProfile (composed sub-model)

---

## Safety Profile

A composed sub-model of AutomationProfile (also usable standalone on Actions).

| Field | Type | Default |
|-------|------|---------|
| `require_sandbox` | bool | `true` |
| `require_checkpoints` | bool | `true` |
| `allow_unsafe_tools` | bool | `false` |
| `require_human_approval` | bool | `false` |
| `allowed_skill_categories` | list[str] | `[]` (all allowed) |
| `max_cost_per_plan` | float? | `null` (no limit) |
| `max_total_cost` | float? | `null` (no limit) |
| `max_retries_per_step` | int | `3` |

---

## Automation Guard (optional sub-model)

Runtime enforcement hooks gating individual tool invocations.

| Field | Default | Description |
|-------|---------|-------------|
| `max_tool_calls_per_step` | null | Max tool invocations per step before requiring approval |
| `max_total_cost` | null | Per-invocation budget cap |
| `tool_allowlist` | null | Only these tools allowed automatically |
| `tool_denylist` | null | These tools always require human approval |
| `require_approval_for_writes` | false | Require human approval for write operations |
| `require_approval_for_apply` | false | Require human approval before apply phase |

**Evaluation order**: denylist → allowlist → tool call limit → budget cap → write approval → apply approval

---

## Namespace Format

Format: `[[server:]namespace/]name`

| Namespace | Scope | Storage |
|-----------|-------|---------|
| `local/` | Current machine only | Local SQLite |
| `<username>/` | Personal server namespace | Server PostgreSQL |
| `<orgname>/` | Organization namespace | Server PostgreSQL |
| `openai/`, `anthropic/`, etc. | Built-in LLM actors | N/A (built-in) |

Default when omitted: `local/`

ULID-identified: plans, decisions, resources, correction attempts, validation attachments, checkpoints
Name-identified: projects, actions, actors, tools, skills, resource types, automation profiles
