# CleverAgents Documentation (Detailed Spec)

## Overview

CleverAgents is your **command center for AI agents**—a unified platform for orchestrating any task you want agents to accomplish, from developing large software projects to writing comprehensive technical papers, administering databases, managing cloud infrastructure, or any complex multi-step workflow. The core value proposition is enabling **long-running, complex, large-scale tasks to execute autonomously with minimal human intervention**, making it ideal for building entire software systems, producing extensive documentation, or managing sophisticated operations largely hands-off.

In **server mode**, CleverAgents becomes a collaborative hub where teams can share resources—prompts, actors, actions, and projects—while executing plans in the cloud. This enables a consistent experience across all your devices: start a complex task on your laptop, check progress from your phone, and review results from any machine.

While CleverAgents leverages LangGraph and LangChain for the underlying LLM runtime primitives (tool calling, graphs, routing), its value lies in what it builds on top:

**CleverAgents** provides:

  * A **first-class plan lifecycle** (Action templates driving Strategize/Execute/Apply phases) for breaking down and tracking complex work,
  * A **project + resource model** for grounding tasks in real codebases, databases, documents, and infrastructure,
  * A consistent **actor abstraction** for defining and composing intelligent agents,
  * An independently registered **resource abstraction** for representing anything that can be read, written, or queried,
  * An independently registered **tool abstraction** for reusable, callable operations with resource bindings,
  * A **validation abstraction** that extends the tool concept with pass/fail semantics and resource-centric attachment with optional project/plan scoping,
  * A consistent **skill abstraction** for organizing tools into composable capability collections,
  * A **sandbox + checkpoint** safety model for safe, reversible execution,
  * A **CLI/TUI/Web UX** for controlling and monitoring large multi-step autonomous work.
  * A scalable **Advanced Context Management System (ACMS)** with a Universal Knowledge Ontology (UKO), a demand-driven Context Request Protocol (CRP), pluggable context strategies, a fusion coordinator, and hot/warm/cold tiers with per-actor views.
  * **Invariants** as first-class constraints (global, project, action, and plan scoped) that flow into the decision tree, with precedence-based conflict resolution via the Invariant Reconciliation Actor.
  * A future-facing correction model where the user can "edit the decision tree" and only recompute affected subtrees.

## Glossary (Terms Used Precisely)

* **Plan**: A hierarchical, stateful unit of work that progresses through three runtime phases (Strategize → Execute → Apply), instantiated from an Action template. Plans persist a decision tree, can spawn child plans, and are identified by ULID. Namespaced as `[[server:]namespace/]name`.
* **Action**: A reusable, project-agnostic plan template defined via a YAML configuration file. Specifies a description, definition of done, strategy and execution actors, typed arguments, and optional invariants. Bound to one or more projects via `agents plan use` to produce a plan. Namespaced as `[[server:]namespace/]name`.
* **Strategize**: The read-only planning phase of the plan lifecycle. The strategy actor produces all decisions — strategy choices, invariant enforcement, resource selections, and child plan blueprints — that govern subsequent execution. No resources are modified.
* **Execute**: The sandboxed implementation phase of the plan lifecycle. The execution actor realizes the decisions from Strategize: invoking tools, spawning child plans, producing artifacts, and creating checkpoints. All changes are confined to the sandbox.
* **Apply**: The commit phase of the plan lifecycle. Merges the sandbox changeset into real project resources after validations pass, transitioning the plan to terminal `applied` state.
* **Project**: A named collection of linked resources, context policies, and invariants that defines the scope of where plans operate. Validations may be attached to resources through a project, scoping them to only apply when a plan targets that project. The project's namespaced name (`[[server:]namespace/]name`) serves as its globally unique identifier — no separate ID is generated. Projects reference resources from the Resource Registry (they do not own them); a single resource can be linked to multiple projects. May be local or remote.
* **Resource**: An independently registered entity representing anything that can be read, written, or queried (git repos, filesystems, databases, etc.). Classified as either physical or virtual, typed by a resource type (which is namespaced), and organized in a DAG of parent/child relationships. Registered in the Resource Registry and linked to projects. Extends the MCP resource concept with write support. Every resource is identified by a system-assigned ULID. User-added resources also have a namespaced name (`[[server:]namespace/]name`) specified at creation time; auto-discovered child resources are identified by ULID only. They have a type and may have a description.
* **Resource Type**: A schema-level definition constraining a category of resources. Specifies accepted CLI arguments, physical/virtual classification, allowed parent/child type relationships, auto-discovery rules, sandbox strategy, and handler implementation. Built-in types (git-checkout, fs-mount, etc.) are unnamespaced; custom types are defined in YAML and namespaced as `[[server:]namespace/]name`.
* **Physical Resource**: A resource representing a specific, concrete, located artifact — a particular file at a particular path, a particular git repo at a particular URL. Directly readable and writable by tools. Distinct instances even when content-identical.
* **Virtual Resource**: A resource representing an abstract equivalence identity that links physical resources sharing the same content, hash, or name. Has no location; cannot be directly read or written. Equivalence relationships are updated when the underlying physical resources diverge.
* **Resource Binding**: The association between a tool and the resources it operates on, declared via typed resource slots. Slots are resolved through contextual binding (from the plan's project), static binding (hardcoded at registration), or parameter binding (passed at invocation).
* **Resource Registry**: The persistent catalog of all registered resources and their DAG relationships (parent/child links). One of the three core registries alongside the Tool Registry and Skill Registry.
* **Skill**: A namespaced, composable collection of tools assembled by referencing named tools, defining inline anonymous tools, including other skills, or exposing MCP server / Agent Skills Standard tools. Actors reference skills by name to acquire capabilities. Namespaced as `[[server:]namespace/]name`.
* **Tool**: A namespaced, independently registered callable operation — the atomic unit of execution. Defined by a JSON Schema for inputs/outputs, capability metadata (read-only, writes, checkpointable), and a `discover`/`activate`/`execute`/`deactivate` lifecycle. Sources: MCP servers, Agent Skills Standard folders, built-in operations, or custom Python. Can be grouped into skills or used directly as tool nodes in actor graphs. Namespaced as `[[server:]namespace/]name`.
* **Validation**: A specialized subtype of Tool that extends the Tool class with validation-specific metadata. A Validation inherits all base Tool properties (name, description, source, input_schema, output_schema, capability, resource bindings, lifecycle hooks, etc.) and adds: a `mode` field (`required` or `informational`) indicating whether failure blocks execution, and a structured JSON return format with a mandatory `passed` boolean field, an optional `data` field for arbitrary informational output, and an optional `message` field. Validations are **always read-only** — they observe and report but never modify resources (`writes` is always `false`, `checkpointable` is always `false`). Because Validation extends Tool, it can be backed by custom code, MCP servers, or Agent Skills, can take arguments, can exist as a tool node in an actor graph, and is handled through the same registries and resolution mechanisms as any tool. A Validation can also **wrap** an existing plain Tool via the `wraps` field, reusing the Tool's implementation and interpreting its output through a `transform` function — avoiding code duplication when the Tool already performs the needed work. Validations and plain Tools share the **same naming namespace** — a Validation and a Tool cannot have the same name. A Validation can be used anywhere a Tool is expected (it IS a Tool), but a plain Tool cannot be used where a Validation is specifically required. Since Validations are registered in the Tool Registry, they are listed via `agents tool list` (with a `--type validation` filter), inspected via `agents tool show`, and removed via `agents tool remove`; only registration (`agents validation add`), attachment (`agents validation attach`), and detachment (`agents validation detach`) have validation-specific commands. Validations are always attached to a resource. When attached directly (without `--project` or `--plan`), the validation is always active for that resource regardless of which plan or project accesses it. When attached to a resource with `--project` or `--plan`, the validation is scoped: it only runs for that resource when it is being interacted with through the specified project or plan. The same validation can be attached to the same resource multiple times — directly, through different projects, and through different plans — and since validations accept arguments, attaching the same validation to the same resource multiple times with different arguments is a useful configuration pattern. Each attachment is identified by a system-assigned ULID, returned by `agents validation attach` and used by `agents validation detach` to remove a specific attachment. When multiple attachment scopes apply, the union of all applicable validations is used. The same resource binding and resolution mechanisms used for tools apply to validations. Namespaced as `[[server:]namespace/]name`.
* **Anonymous Tool**: An inline tool definition embedded directly in a skill YAML or actor graph node. Uses the same format as a named tool but is unregistered, unnamespaced, and scoped only to its defining context.
* **Actor**: A conversational unit that may be a single LLM/agent or a composed LangGraph of actors and tool nodes. Defined via YAML configuration files. Specialized roles include strategy actor, execution actor, estimation actor, and invariant reconciliation actor. Namespaced as `[[server:]namespace/]name`.
* **Session**: A persistent user conversation thread tied to an orchestrator actor. Maintains message history across multiple plans and serves as the interface for natural-language interaction.
* **Server**: An optional shared service providing multi-user storage, namespace resolution, and remote plan execution.
* **Namespace**: The scoping component in the full name format `[[server:]namespace/]name`, controlling ownership and visibility. When namespace is omitted, it defaults to `local/`. When server is omitted and namespace is `local/`, server is not applicable. When server is omitted and namespace is something other than `local/`, the default configured server is assumed. `local/` is reserved for local-only items; `<username>/` and `<orgname>/` are server-stored. Built-in LLM actors use provider prefixes (`openai/`, `anthropic/`). Built-in resource types are unnamespaced.
* **Decision**: A persisted choice point in a plan's decision tree, created during Strategize. Records the question, chosen option, alternatives, confidence score, rationale, context snapshot, and downstream dependencies. Types include `prompt_definition`, `invariant_enforced`, `strategy_choice`, `subplan_spawn`, `subplan_parallel_spawn`, and others. Supports targeted correction and selective subtree recomputation.
* **Invariant**: A natural-language constraint on plan execution, scoped to global, project, action, or plan level. Precedence flows plan > project > global. Reconciled by the Invariant Reconciliation Actor at the start of Strategize and recorded as `invariant_enforced` decisions that propagate to child plans.
* **Automation Profile**: A named set of confidence thresholds (0.0–1.0) controlling which plan operations proceed automatically vs. require human approval. Thresholds gate phase transitions, decision autonomy, self-repair, child plan spawning, and safety requirements. 0.0 = always automatic; 1.0 = always manual. Eight built-in profiles range from `manual` to `full-auto`. Custom profiles follow `[[server:]namespace/]name`.
* **ULID**: Universally Unique Lexicographically Sortable Identifier. Used for plan, decision, resource, correction attempt, and validation attachment IDs. Preferred over UUID for time-sortability. Note: Projects, actions, skills, and tools do not use ULIDs — their namespaced name is their unique identifier. Resources use both: a ULID (always) and a namespaced name (for user-added resources only; auto-discovered child resources have ULID only). Validation attachments use a ULID to uniquely identify each attachment of a validation to a resource (with its optional project or plan scope).
* **ACMS (Advanced Context Management System)**: The fully pluggable, strategy-driven framework for assembling context for actors. Built around the UKO, CRP, and a pluggable strategy framework with a fusion coordinator.
* **UKO (Universal Knowledge Ontology)**: An inheritance-based RDF ontology hierarchy that represents any resource (source code, documents, databases, infrastructure) at multiple levels of abstraction, with full provenance and temporal versioning. Organized in four layers: Layer 0 (universal foundation), Layer 1 (general software), Layer 2 (paradigm specializations), Layer 3 (language-specific).
* **CRP (Context Request Protocol)**: A structured vocabulary through which actors (via skills) declare what information they need, at what detail level, and with what scope, during reasoning. Uses the `builtin/context` skill with tools like `request_context`, `query_history`, and `get_context_budget`.
* **Context Strategy**: A pluggable component that searches for and assembles context fragments using a specific retrieval approach (e.g., keyword search, semantic embedding, breadth-depth graph navigation, temporal archaeology). Strategies are registered with the Strategy Coordinator and run in parallel during context assembly.
* **Strategy Coordinator**: The orchestrator component within the ACMS that receives `ContextRequest` objects, selects applicable strategies, allocates budget proportionally by confidence, runs strategies in parallel, and passes results to the Fusion Engine.
* **Fusion Engine**: The ACMS component that deduplicates, merges, and orders context fragments from multiple strategies into a single budget-respecting context payload. Resolves detail-level conflicts, applies hierarchical weighting, and runs greedy knapsack packing.
* **ContextFragment**: The atomic unit of context returned by strategies. Contains a UKO node reference, rendered text, token count, detail level, relevance score, provenance, and metadata.
* **DetailLevel**: An enumeration of abstraction levels for context content: `SIGNATURE` (declarations only), `SUMMARY` (LLM-generated or docstring summaries), `STUB` (signatures + key logic), `FULL` (complete content).
* **ScopedBackendView**: A filtering layer that automatically restricts all backend queries (text index, vector index, graph store) to only the resources belonging to the current plan's project(s). Ensures actors never see resources outside their project scope.
* **Skeleton (context)**: A compressed representation of a plan's accumulated context, produced by the skeleton compressor. Propagated from parent plans to child plans as inherited context. Controlled by the `skeleton_ratio` budget parameter.

## CLI Commands

### Command Synopsis

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">agents|cleveragents</span> [<span style="color: cyan;">--data-dir</span> <span style="color: #66cc66;">&lt;DATA_PATH&gt;</span>] [<span style="color: cyan;">--config-path</span> <span style="color: #66cc66;">&lt;CONFIG_PATH&gt;</span>]
                     [<span style="color: cyan;">--format</span> (<span style="color: magenta;">rich|color|table|plain|json|yaml</span>)]
                     [<span style="color: cyan;">--help</span>|<span style="color: yellow;">-h</span>] [<span style="color: cyan;">--version</span>]
                     [<span style="color: cyan;">--install-completion</span> [<span style="color: #66cc66;">&lt;INST_SHELL&gt;</span>]] [<span style="color: cyan;">--show-completion</span> [<span style="color: #66cc66;">&lt;SHOW_SHELL&gt;</span>]]
                     [<span style="color: yellow;">-v</span>...] <span style="color: #66cc66;">&lt;COMMAND&gt;</span> [<span style="color: #66cc66;">&lt;ARGS&gt;</span>...]

<span style="color: cyan; font-weight: 600;">agents</span> version
<span style="color: cyan; font-weight: 600;">agents</span> info
<span style="color: cyan; font-weight: 600;">agents</span> diagnostics
<span style="color: cyan; font-weight: 600;">agents</span> init [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>]

<span style="color: cyan; font-weight: 600;">agents</span> session create [<span style="color: cyan;">--actor</span> <span style="color: #66cc66;">&lt;ACTOR&gt;</span>]
<span style="color: cyan; font-weight: 600;">agents</span> session list
<span style="color: cyan; font-weight: 600;">agents</span> session show <span style="color: #66cc66;">&lt;SESSION_ID&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> session delete [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;SESSION_ID&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> session export [(<span style="color: magenta;"><span style="color: cyan;">--output</span>|<span style="color: yellow;">-o</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span>] <span style="color: #66cc66;">&lt;SESSION_ID&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> session import (<span style="color: magenta;"><span style="color: cyan;">--input</span>|<span style="color: yellow;">-i</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> session tell <span style="color: cyan;">--session</span> <span style="color: #66cc66;">&lt;SESSION_ID&gt;</span> [<span style="color: cyan;">--actor</span> <span style="color: #66cc66;">&lt;ACTOR&gt;</span>] [<span style="color: cyan;">--stream</span>] <span style="color: #66cc66;">&lt;PROMPT&gt;</span>

<span style="color: cyan; font-weight: 600;">agents</span> project create [(<span style="color: magenta;"><span style="color: cyan;">--description</span>|<span style="color: yellow;">-d</span></span>) <span style="color: #66cc66;">&lt;DESC&gt;</span>] [<span style="color: cyan;">--resource</span> <span style="color: #66cc66;">&lt;RESOURCE&gt;</span>]...
                     [<span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">&lt;INVARIANT&gt;</span>]... [<span style="color: cyan;">--invariant-actor</span> <span style="color: #66cc66;">&lt;ACTOR&gt;</span>] <span style="color: #66cc66;">&lt;NAME&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> project link-resource [<span style="color: cyan;">--read-only</span>] <span style="color: #66cc66;">&lt;PROJECT&gt;</span> <span style="color: #66cc66;">&lt;RESOURCE&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> project unlink-resource [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;PROJECT&gt;</span> <span style="color: #66cc66;">&lt;RESOURCE_NAME&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> project list [(<span style="color: magenta;"><span style="color: cyan;">--namespace</span>|<span style="color: yellow;">-n</span></span>) NS] [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]
<span style="color: cyan; font-weight: 600;">agents</span> project show <span style="color: #66cc66;">&lt;PROJECT&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> validation add (<span style="color: magenta;"><span style="color: cyan;">--config</span>|<span style="color: yellow;">-c</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span> [<span style="color: cyan;">--update</span>]
<span style="color: cyan; font-weight: 600;">agents</span> validation attach [<span style="color: cyan;">--project</span> <span style="color: #66cc66;">&lt;PROJECT&gt;</span>|<span style="color: cyan;">--plan</span> <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span>]
                         <span style="color: #66cc66;">&lt;RESOURCE&gt;</span> <span style="color: #66cc66;">&lt;VALIDATION&gt;</span> [<span style="color: #66cc66;">&lt;ARGS&gt;</span>...]
<span style="color: cyan; font-weight: 600;">agents</span> validation detach [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;ATTACHMENT_ID&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> project delete [<span style="color: cyan;">--force</span>|<span style="color: yellow;">-f</span>] [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;NAME&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> project context set[<span style="color: cyan;">--view</span> (<span style="color: magenta;">strategize|execute|apply|default</span>)]
                          [<span style="color: cyan;">--include-resource</span> <span style="color: #66cc66;">&lt;INCLUDE_RESOURCE&gt;</span>]...
                          [<span style="color: cyan;">--exclude-resource</span> <span style="color: #66cc66;">&lt;EXCLUDE_RESOURCE&gt;</span>]...
                          [<span style="color: cyan;">--include-path</span> <span style="color: #66cc66;">&lt;INCLUDE_GLOB&gt;</span>]...
                          [<span style="color: cyan;">--exclude-path</span> <span style="color: #66cc66;">&lt;EXCLUDE_GLOB&gt;</span>]...
                          [<span style="color: cyan;">--hot-max-tokens</span> <span style="color: #66cc66;">&lt;N&gt;</span>]
                          [<span style="color: cyan;">--warm-max-decisions</span> <span style="color: #66cc66;">&lt;N_WARM_MAX&gt;</span>]
                          [<span style="color: cyan;">--cold-max-decisions</span> <span style="color: #66cc66;">&lt;N_COLD_MAX&gt;</span>]
                          [<span style="color: cyan;">--query-limit</span> <span style="color: #66cc66;">&lt;N&gt;</span>]
                          [<span style="color: cyan;">--max-file-size</span> <span style="color: #66cc66;">&lt;MAX_FILE_BYTES&gt;</span>]
                          [<span style="color: cyan;">--max-total-size</span> <span style="color: #66cc66;">&lt;MAX_TOTAL_BYTES&gt;</span>]
                          [<span style="color: cyan;">--summarize</span>|<span style="color: cyan;">--no-summarize</span>]
                          [<span style="color: cyan;">--summary-max-tokens</span> <span style="color: #66cc66;">&lt;N&gt;</span>]
                          [<span style="color: cyan;">--strategy</span> <span style="color: #66cc66;">&lt;STRATEGY&gt;</span>]...
                          [<span style="color: cyan;">--default-breadth</span> <span style="color: #66cc66;">&lt;N&gt;</span>]
                          [<span style="color: cyan;">--default-depth</span> (<span style="color: magenta;">SIGNATURE|SUMMARY|STUB|FULL</span>)]
                          [<span style="color: cyan;">--depth-gradient</span> <span style="color: #66cc66;">&lt;HOP:LEVEL&gt;</span>]...
                          [<span style="color: cyan;">--skeleton-ratio</span> <span style="color: #66cc66;">&lt;FLOAT&gt;</span>]
                          [<span style="color: cyan;">--temporal-scope</span> (<span style="color: magenta;">current|recent|all</span>)]
                          [<span style="color: cyan;">--auto-refresh</span>|<span style="color: cyan;">--no-auto-refresh</span>]
                          [<span style="color: cyan;">--clear</span>] <span style="color: #66cc66;">&lt;PROJECT&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> project context show [<span style="color: cyan;">--view</span> (<span style="color: magenta;">strategize|execute|apply|default</span>)]
                            <span style="color: #66cc66;">&lt;PROJECT&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> project context inspect [<span style="color: cyan;">--view</span> (<span style="color: magenta;">strategize|execute|apply|default</span>)]
                               [<span style="color: cyan;">--strategy</span> <span style="color: #66cc66;">&lt;STRATEGY&gt;</span>]
                               [<span style="color: cyan;">--focus</span> <span style="color: #66cc66;">&lt;UKO_URI&gt;</span>]...
                               [<span style="color: cyan;">--breadth</span> <span style="color: #66cc66;">&lt;N&gt;</span>] [<span style="color: cyan;">--depth</span> (<span style="color: magenta;">SIGNATURE|SUMMARY|STUB|FULL</span>)]
                               <span style="color: #66cc66;">&lt;PROJECT&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> project context simulate [<span style="color: cyan;">--view</span> (<span style="color: magenta;">strategize|execute|apply|default</span>)]
                                [<span style="color: cyan;">--budget</span> <span style="color: #66cc66;">&lt;TOKENS&gt;</span>]
                                [<span style="color: cyan;">--focus</span> <span style="color: #66cc66;">&lt;UKO_URI&gt;</span>]...
                                [<span style="color: cyan;">--strategy</span> <span style="color: #66cc66;">&lt;STRATEGY&gt;</span>]...
                                <span style="color: #66cc66;">&lt;PROJECT&gt;</span>

<span style="color: cyan; font-weight: 600;">agents</span> actor run [(<span style="color: magenta;"><span style="color: cyan;">--output</span>|<span style="color: yellow;">-o</span></span>) <span style="color: #66cc66;">&lt;OUTPUT_FILE&gt;</span>]
                 [<span style="color: yellow;">-v</span>...] [<span style="color: cyan;">--unsafe</span>|<span style="color: yellow;">-u</span>] [<span style="color: cyan;">--context</span> <span style="color: #66cc66;">&lt;CONTEXT_NAME&gt;</span>]
                 [<span style="color: cyan;">--context-dir</span> <span style="color: #66cc66;">&lt;CONTEXT_PATH&gt;</span>] [<span style="color: cyan;">--load-context</span> <span style="color: #66cc66;">&lt;LOAD_CONTEXT_NAME&gt;</span>]
                 [(<span style="color: magenta;"><span style="color: cyan;">--temperature</span>|<span style="color: yellow;">-t</span></span>) <span style="color: #66cc66;">&lt;TEMP&gt;</span>] [<span style="color: cyan;">--allow-rxpy-in-run-mode</span>]
                 [<span style="color: cyan;">--skill</span> <span style="color: #66cc66;">&lt;SKILL&gt;</span>]... <span style="color: #66cc66;">&lt;NAME&gt;</span> <span style="color: #66cc66;">&lt;PROMPT&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> actor add (<span style="color: magenta;"><span style="color: cyan;">--config</span>|<span style="color: yellow;">-c</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span> [<span style="color: cyan;">--update</span>]
<span style="color: cyan; font-weight: 600;">agents</span> actor remove <span style="color: #66cc66;">&lt;NAME&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> actor list
<span style="color: cyan; font-weight: 600;">agents</span> actor show <span style="color: #66cc66;">&lt;NAME&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> actor context remove [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] (<span style="color: magenta;"><span style="color: cyan;">--all</span>|<span style="color: yellow;">-a</span>|<span style="color: #66cc66;">&lt;NAME&gt;</span></span>)
<span style="color: cyan; font-weight: 600;">agents</span> actor context list [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]
<span style="color: cyan; font-weight: 600;">agents</span> actor context show <span style="color: #66cc66;">&lt;NAME&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> actor context export (<span style="color: magenta;"><span style="color: cyan;">--output</span>|<span style="color: yellow;">-o</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span> <span style="color: #66cc66;">&lt;NAME&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> actor context import [<span style="color: cyan;">--update</span>] (<span style="color: magenta;"><span style="color: cyan;">--input</span>|<span style="color: yellow;">-i</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span> [<span style="color: #66cc66;">&lt;NAME&gt;</span>]
<span style="color: cyan; font-weight: 600;">agents</span> actor context clear [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] (<span style="color: magenta;"><span style="color: cyan;">--all</span>|<span style="color: yellow;">-a</span>|<span style="color: #66cc66;">&lt;NAME&gt;</span></span>)

<span style="color: cyan; font-weight: 600;">agents</span> skill add (<span style="color: magenta;"><span style="color: cyan;">--config</span>|<span style="color: yellow;">-c</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span> [<span style="color: cyan;">--update</span>]
<span style="color: cyan; font-weight: 600;">agents</span> skill remove [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;NAME&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> skill list [(<span style="color: magenta;"><span style="color: cyan;">--namespace</span>|<span style="color: yellow;">-n</span></span>) <span style="color: #66cc66;">&lt;NS&gt;</span>] [<span style="color: cyan;">--source</span> <span style="color: #66cc66;">&lt;SOURCE&gt;</span>]
<span style="color: cyan; font-weight: 600;">agents</span> skill show  <span style="color: #66cc66;">&lt;NAME&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> skill tools <span style="color: #66cc66;">&lt;NAME&gt;</span>

<span style="color: cyan; font-weight: 600;">agents</span> tool add (<span style="color: magenta;"><span style="color: cyan;">--config</span>|<span style="color: yellow;">-c</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span> [<span style="color: cyan;">--update</span>]
<span style="color: cyan; font-weight: 600;">agents</span> tool remove [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;NAME&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> tool list [(<span style="color: magenta;"><span style="color: cyan;">--namespace</span>|<span style="color: yellow;">-n</span></span>) <span style="color: #66cc66;">&lt;NS&gt;</span>] [<span style="color: cyan;">--source</span> <span style="color: #66cc66;">&lt;SOURCE&gt;</span>] [<span style="color: cyan;">--type</span> (<span style="color: magenta;">tool|validation</span>)] [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]
<span style="color: cyan; font-weight: 600;">agents</span> tool show <span style="color: #66cc66;">&lt;NAME&gt;</span>

<span style="color: cyan; font-weight: 600;">agents</span> resource type add (<span style="color: magenta;"><span style="color: cyan;">--config</span>|<span style="color: yellow;">-c</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span> [<span style="color: cyan;">--update</span>]
<span style="color: cyan; font-weight: 600;">agents</span> resource type remove [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;NAME&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> resource type list [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]
<span style="color: cyan; font-weight: 600;">agents</span> resource type show <span style="color: #66cc66;">&lt;NAME&gt;</span>

<span style="color: cyan; font-weight: 600;">agents</span> resource add [(<span style="color: magenta;"><span style="color: cyan;">--description</span>|<span style="color: yellow;">-d</span></span>) <span style="color: #66cc66;">&lt;DESC&gt;</span>] [<span style="color: cyan;">--update</span>] <span style="color: #66cc66;">&lt;TYPE&gt;</span> <span style="color: #66cc66;">&lt;NAME&gt;</span> [type-specific-flags...]
<span style="color: cyan; font-weight: 600;">agents</span> resource remove [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;NAME&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> resource list [<span style="color: cyan;">--all</span>] [(<span style="color: magenta;"><span style="color: cyan;">--type</span>|<span style="color: yellow;">-t</span></span>) <span style="color: #66cc66;">&lt;TYPE&gt;</span>] 
<span style="color: cyan; font-weight: 600;">agents</span> resource show <span style="color: #66cc66;">&lt;RESOURCE&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> resource inspect [<span style="color: cyan;">--tree</span>] [<span style="color: cyan;">--file</span> <span style="color: #66cc66;">&lt;PATH&gt;</span>] <span style="color: #66cc66;">&lt;RESOURCE&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> resource tree [(<span style="color: magenta;"><span style="color: cyan;">--depth</span>|<span style="color: yellow;">-d</span></span>) <span style="color: #66cc66;">&lt;N&gt;</span>] [(<span style="color: magenta;"><span style="color: cyan;">--type</span>|<span style="color: yellow;">-t</span></span>) <span style="color: #66cc66;">&lt;TYPE&gt;</span>] <span style="color: #66cc66;">&lt;RESOURCE&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> resource link-child <span style="color: #66cc66;">&lt;PARENT&gt;</span> <span style="color: #66cc66;">&lt;CHILD&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> resource unlink-child [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;PARENT&gt;</span> <span style="color: #66cc66;">&lt;CHILD&gt;</span>

<span style="color: cyan; font-weight: 600;">agents</span> plan list [<span style="color: cyan;">--phase</span> <span style="color: #66cc66;">&lt;PHASE&gt;</span>] [<span style="color: cyan;">--state</span> <span style="color: #66cc66;">&lt;STATE&gt;</span>] [<span style="color: cyan;">--project</span> <span style="color: #66cc66;">&lt;PROJECT&gt;</span>]
                [<span style="color: cyan;">--action</span> <span style="color: #66cc66;">&lt;ACTION&gt;</span>] [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]
<span style="color: cyan; font-weight: 600;">agents</span> plan use [<span style="color: cyan;">--automation-profile</span> <span style="color: #66cc66;">&lt;PROFILE&gt;</span>]
                [<span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">&lt;INVARIANT&gt;</span>]...
                [<span style="color: cyan;">--strategy-actor</span> <span style="color: #66cc66;">&lt;STRATEGY_ACTOR&gt;</span>]
                [<span style="color: cyan;">--execution-actor</span> <span style="color: #66cc66;">&lt;EXEC_ACTOR&gt;</span>]
                [<span style="color: cyan;">--estimation-actor</span> <span style="color: #66cc66;">&lt;EST_ACTOR&gt;</span>]
                [<span style="color: cyan;">--invariant-actor</span> <span style="color: #66cc66;">&lt;INV_ACTOR&gt;</span>]
                [<span style="color: cyan;">--arg</span>/<span style="color: yellow;">-a</span> name=value]...
                <span style="color: #66cc66;">&lt;ACTION&gt;</span> <span style="color: #66cc66;">&lt;PROJECT&gt;</span>...
<span style="color: cyan; font-weight: 600;">agents</span> plan execute <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> plan apply [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> plan status <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> plan cancel [(<span style="color: magenta;"><span style="color: cyan;">--reason</span>|<span style="color: yellow;">-r</span></span>) <span style="color: #66cc66;">&lt;REASON&gt;</span>] <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> plan tree [<span style="color: cyan;">--show-superseded</span>] <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> plan explain [<span style="color: cyan;">--show-context</span>] [<span style="color: cyan;">--show-reasoning</span>] <span style="color: #66cc66;">&lt;DECISION_ID&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> plan correct <span style="color: cyan;">--mode</span> (<span style="color: magenta;">revert|append</span>) (<span style="color: magenta;"><span style="color: cyan;">--guidance</span>|<span style="color: yellow;">-g</span></span>) <span style="color: #66cc66;">&lt;GUIDANCE&gt;</span>
                   [<span style="color: cyan;">--dry-run</span>] [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;DECISION_ID&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> plan diff (<span style="color: magenta;"><span style="color: cyan;">--correction</span> <span style="color: #66cc66;">&lt;CORRECTION_ATTEMPT_ID&gt;</span>|<span style="color: #66cc66;">&lt;PLAN_ID&gt;</span></span>)
<span style="color: cyan; font-weight: 600;">agents</span> plan artifacts <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> plan prompt <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span> <span style="color: #66cc66;">&lt;GUIDANCE&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> plan rollback [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span> <span style="color: #66cc66;">&lt;CHECKPOINT_ID&gt;</span>

<span style="color: cyan; font-weight: 600;">agents</span> action create (<span style="color: magenta;"><span style="color: cyan;">--config</span>|<span style="color: yellow;">-c</span></span>) <span style="color: #66cc66;">&lt;CFG_FILE&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> action list [(<span style="color: magenta;"><span style="color: cyan;">--namespace</span>|<span style="color: yellow;">-n</span></span>) <span style="color: #66cc66;">&lt;NS&gt;</span>] [(<span style="color: magenta;"><span style="color: cyan;">--state</span>|<span style="color: yellow;">-s</span></span>) <span style="color: #66cc66;">&lt;STATE&gt;</span>] [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]
<span style="color: cyan; font-weight: 600;">agents</span> action show <span style="color: #66cc66;">&lt;ACTION_NAME&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> action archive <span style="color: #66cc66;">&lt;ACTION_NAME&gt;</span>

<span style="color: cyan; font-weight: 600;">agents</span> automation-profile add (<span style="color: magenta;"><span style="color: cyan;">--config</span>|<span style="color: yellow;">-c</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span> [<span style="color: cyan;">--update</span>]
<span style="color: cyan; font-weight: 600;">agents</span> automation-profile remove [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;NAME&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> automation-profile list [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]
<span style="color: cyan; font-weight: 600;">agents</span> automation-profile show <span style="color: #66cc66;">&lt;NAME&gt;</span>

<span style="color: cyan; font-weight: 600;">agents</span> config set <span style="color: #66cc66;">&lt;key&gt;</span> <span style="color: #66cc66;">&lt;value&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> config get <span style="color: #66cc66;">&lt;key&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> config list [<span style="color: cyan;">--filter-values</span> <span style="color: #66cc66;">&lt;REGEX&gt;</span>] [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]

<span style="color: cyan; font-weight: 600;">agents</span> invariant add [<span style="color: cyan;">--global</span>] [(<span style="color: cyan;">--project</span>|<span style="color: yellow;">-p</span>) PROJECT] [<span style="color: cyan;">--plan</span> PLAN_ID]...
                     [<span style="color: cyan;">--action</span> ACTION]... <span style="color: #66cc66;">&lt;INVARIANT_TEXT&gt;</span>
<span style="color: cyan; font-weight: 600;">agents</span> invariant list [<span style="color: cyan;">--global</span>] [(<span style="color: cyan;">--project</span>|<span style="color: yellow;">-p</span>) PROJECT] [<span style="color: cyan;">--plan</span> PLAN_ID] [<span style="color: cyan;">--action</span> ACTION]
                     [<span style="color: cyan;">--effective</span>] [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]
<span style="color: cyan; font-weight: 600;">agents</span> invariant remove [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;INVARIANT_ID&gt;</span>
</code></pre></div>

### Command Reference

#### Global Options

**Purpose**
Configure global state locations and shell integration for every command.

**Arguments**

- `--data-dir PATH`: Overrides the global data directory (database, caches, sessions, logs). When omitted, the default data location is used.
- `--config-path PATH`: Overrides the global configuration file path. When omitted, the default config path is used.
- `--format rich|color|table|plain|json|yaml`: Set the output rendering format for all subcommands. When omitted, the value is read from the global config key `core.format`. If not set in config either, defaults to `rich`. See **Output Rendering Framework** for full details on each format. The available formats are:
    - `rich` (default): Uses modern rich CLI elements with dynamic effects, animated spinners, progress bars, and generous color. Best for interactive terminal use.
    - `color`: Plain scrolling text with ANSI color codes. Good for terminals that support color but not advanced rendering.
    - `table`: ASCII box-drawing characters to create structured tables and panels with color. Similar to the examples shown throughout this document.
    - `plain`: Plain text with no color codes or non-ASCII characters. Suitable for piping into files, logs, or non-terminal consumers.
    - `json`: Structured JSON output for programmatic consumption. No color except within verbatim text values.
    - `yaml`: Structured YAML output for programmatic consumption. No color except within verbatim text values.
- `--help`, `-h`: Print help for the current command.
- `--version`: Print the version and exit.
- `--install-completion [SHELL]`: Install shell completion for the given shell.
- `--show-completion [SHELL]`: Show the completion script for the given shell.
- `-v`: Increase log verbosity for a single invocation (repeatable). By default (no `-v`), only normal command output is shown on stdout; logging output is suppressed except on fatal errors where the application exits entirely and displays the error. Each additional `-v` raises the verbosity one level: `-v` = ERROR (non-fatal, recoverable errors), `-vv` = WARN (warnings that may indicate a degraded system but are not necessarily errors), `-vvv` = INFO (routine informative messages useful to common users), `-vvvv` = DEBUG (coarse debugging output), `-vvvvv` = TRACE (the most granular logging level available). Increased verbosity writes to both the log file and stderr by default, keeping log output separate from normal program output on stdout. The destination for log output raised by `-v` is configurable: it can be sent to the terminal (stderr by default, or redirected to another stream such as stdin or a device), to the log file only, or to both. See `core.log.terminal`, `core.log.terminal-stream`, and `core.log.file-enabled` configuration keys for details. This flag does not persist — it only affects the current invocation.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--data-dir</span> /srv/cleveragents <span style="color: cyan;">--config-path</span> /srv/cleveragents/config.toml info

╭─ System Snapshot ─────────────────╮
│ <span style="color: cyan; font-weight: 600;">CleverAgents</span> 1.0.0                │
│ <span style="color: #5599ff; font-weight: 600;">Mode:</span> local                       │
│ <span style="color: magenta; font-weight: 600;">Automation:</span> review                │
│ <span style="color: #66cc66; font-weight: 600;">Status:</span> ready                     │
╰───────────────────────────────────╯

╭─ Paths ───────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Data Dir:</span> /srv/cleveragents           │
│ <span style="color: #5599ff; font-weight: 600;">Config:</span> /srv/cleveragents/config.toml │
│ <span style="color: #5599ff; font-weight: 600;">Logs:</span> /srv/cleveragents/logs          │
│ <span style="color: #5599ff; font-weight: 600;">Cache:</span> /srv/cleveragents/cache        │
│ <span style="color: #5599ff; font-weight: 600;">Database:</span> /srv/cleveragents/agents.db │
╰───────────────────────────────────────╯

╭─ Runtime ──────────╮
│ <span style="color: yellow; font-weight: 600;">PID:</span> 4127          │
│ <span style="color: #66cc66; font-weight: 600;">Uptime:</span> 00:14:32   │
│ <span style="color: #5599ff; font-weight: 600;">Python:</span> 3.13.1     │
│ <span style="color: #5599ff; font-weight: 600;">Host:</span> devbox.local │
│ <span style="color: #5599ff; font-weight: 600;">Platform:</span> linux    │
╰────────────────────╯

╭─ Projects & Sessions ─╮
│ <span style="color: #5599ff; font-weight: 600;">Projects:</span> 2           │
│ <span style="color: #5599ff; font-weight: 600;">Sessions:</span> 1 active    │
│ <span style="color: #5599ff; font-weight: 600;">Active Plans:</span> 0       │
│ <span style="color: #5599ff; font-weight: 600;">Actors:</span> 3             │
╰───────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Environment loaded
</code></pre></div>

#### agents version

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> version</code></pre></div>

**Purpose**
Print the current CLI version.

**Arguments**

None.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> version

╭─ CLI Version ────╮
│ <span style="color: cyan; font-weight: 600;">CleverAgents CLI</span> │
│ <span style="color: #5599ff; font-weight: 600;">Version:</span> 1.0.0   │
│ <span style="color: #5599ff; font-weight: 600;">Channel:</span> stable  │
│ <span style="color: #5599ff; font-weight: 600;">Python:</span> 3.13     │
╰──────────────────╯

╭─ Build ────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Build Date:</span> 2026-02-08 │
│ <span style="color: magenta; font-weight: 600;">Commit:</span> a17c3f9        │
│ <span style="color: #5599ff; font-weight: 600;">Schema:</span> v3             │
│ <span style="color: #5599ff; font-weight: 600;">Platform:</span> linux-x86_64 │
╰────────────────────────╯

╭─ Dependencies ─────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">LangGraph:</span> 0.2.60              │
│ <span style="color: #5599ff; font-weight: 600;">LangChain:</span> 0.3.18              │
│ <span style="color: #5599ff; font-weight: 600;">MCP SDK:</span> 1.4.0                 │
│ <span style="color: #5599ff; font-weight: 600;">Pydantic:</span> 2.10.4               │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Version reported
</code></pre></div>

#### agents info

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> info</code></pre></div>

**Purpose**
Show configuration and runtime information useful for debugging or support.

**Arguments**

None.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> info

╭─ Environment ───────────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Data Dir:</span> /home/alex/.cleveragents                          │
│ <span style="color: #5599ff; font-weight: 600;">Config:</span> /home/alex/.cleveragents/config.toml                │
│ <span style="color: #66cc66; font-weight: 600;">Database:</span> sqlite:///home/alex/.cleveragents/cleveragents.db │
│ <span style="color: yellow; font-weight: 600;">Server Mode:</span> disabled                                       │
│ <span style="color: #5599ff; font-weight: 600;">Platform:</span> Linux 6.8.0 (x86_64)                              │
╰─────────────────────────────────────────────────────────────╯

╭─ Runtime ─────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Automation:</span> review                │
│ <span style="color: #5599ff; font-weight: 600;">Providers:</span> 3 configured           │
│ <span style="color: yellow; font-weight: 600;">Sessions:</span> 2 active                │
│ <span style="color: #5599ff; font-weight: 600;">Active Plans:</span> 1                   │
╰───────────────────────────────────╯

╭─ Storage ─────╮
│ <span style="color: #5599ff; font-weight: 600;">Cache:</span> 118 MB │
│ <span style="color: #5599ff; font-weight: 600;">Logs:</span> 42 MB   │
│ <span style="color: yellow; font-weight: 600;">Backups:</span> 3    │
│ <span style="color: #5599ff; font-weight: 600;">DB Size:</span> 8 MB │
╰───────────────╯

╭─ Indexing ─────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Text Index:</span> ready      │
│ <span style="color: #66cc66; font-weight: 600;">Vector Index:</span> ready    │
│ <span style="color: yellow; font-weight: 600;">Graph Store:</span> disabled  │
│ <span style="color: #5599ff; font-weight: 600;">Indexed Files:</span> 1,247   │
╰────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Environment details ready
</code></pre></div>

#### agents diagnostics

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> diagnostics</code></pre></div>

**Purpose**
Run health checks for configuration, providers, and filesystem permissions.

**Arguments**

None.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> diagnostics

╭─ Checks ────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Check</span>            <span style="color: cyan; font-weight: 600;">Status</span>  <span style="color: cyan; font-weight: 600;">Details</span>        │
│ <span style="opacity: 0.7;">───────────────  ──────  ──────────────</span> │
│ Config file      <span style="color: #66cc66; font-weight: 600;">OK</span>      readable       │
│ Database         <span style="color: #66cc66; font-weight: 600;">OK</span>      writable       │
│ OPENAI_API_KEY   <span style="color: yellow; font-weight: 600;">WARN</span>    missing        │
│ Anthropic key    <span style="color: #66cc66; font-weight: 600;">OK</span>      configured     │
│ Disk space       <span style="color: #66cc66; font-weight: 600;">OK</span>      2.1 GB free    │
│ Text index       <span style="color: #66cc66; font-weight: 600;">OK</span>      tantivy 0.22   │
│ Vector index     <span style="color: #66cc66; font-weight: 600;">OK</span>      faiss (CPU)    │
│ Graph store      <span style="color: yellow; font-weight: 600;">WARN</span>    not configured │
│ File permissions <span style="color: #66cc66; font-weight: 600;">OK</span>      data dir r/w   │
│ Git              <span style="color: #66cc66; font-weight: 600;">OK</span>      git 2.43.0     │
╰─────────────────────────────────────────╯

╭─ Summary ─────────╮
│ <span style="color: #5599ff; font-weight: 600;">Checks:</span> 10 total  │
│ <span style="color: yellow; font-weight: 600;">Warnings:</span> 2       │
│ <span style="color: #ff6666; font-weight: 600;">Errors:</span> 0         │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 0.6s    │
╰───────────────────╯

╭─ Recommendations ─────────────────────────────────────────────╮
│ - Set OPENAI_API_KEY to enable OpenAI models                  │
│ - Configure a graph store backend for structural code queries │
│ - Verify provider credentials via config                      │
╰───────────────────────────────────────────────────────────────╯

<span style="color: yellow; font-weight: 600;">⚠ WARN</span> 2 warnings require attention
</code></pre></div>

When critical checks fail, diagnostics reports errors:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> diagnostics

╭─ Checks ────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Check</span>            <span style="color: cyan; font-weight: 600;">Status</span>   <span style="color: cyan; font-weight: 600;">Details</span>                   │
│ <span style="opacity: 0.7;">───────────────  ───────  ────────────────────</span>      │
│ Config file      <span style="color: #66cc66; font-weight: 600;">OK</span>       readable                  │
│ Database         <span style="color: #ff6666; font-weight: 600;">ERROR</span>    locked by another process │
│ OPENAI_API_KEY   <span style="color: #66cc66; font-weight: 600;">OK</span>       configured                │
│ Anthropic key    <span style="color: #ff6666; font-weight: 600;">ERROR</span>    invalid key format        │
│ Disk space       <span style="color: yellow; font-weight: 600;">WARN</span>     312 MB free (low)         │
│ Text index       <span style="color: #66cc66; font-weight: 600;">OK</span>       tantivy 0.22              │
│ Vector index     <span style="color: #ff6666; font-weight: 600;">ERROR</span>    FAISS library not found   │
│ Graph store      <span style="color: #66cc66; font-weight: 600;">OK</span>       neo4j 5.15                │
│ File permissions <span style="color: #66cc66; font-weight: 600;">OK</span>       data dir r/w              │
│ Git              <span style="color: #66cc66; font-weight: 600;">OK</span>       git 2.43.0                │
╰─────────────────────────────────────────────────────╯

╭─ Summary ─────────╮
│ <span style="color: #5599ff; font-weight: 600;">Checks:</span> 10 total  │
│ <span style="color: yellow; font-weight: 600;">Warnings:</span> 1       │
│ <span style="color: #ff6666; font-weight: 600;">Errors:</span> 3         │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 1.2s    │
╰───────────────────╯

╭─ Errors (must fix) ─────────────────────────────────────────────────╮
│ <span style="color: #ff6666; font-weight: 600;">1.</span> Database is locked by PID 12847 — stop the other process or      │
│    delete the lock file at ~/.cleveragents/agents.db-lock           │
│ <span style="color: #ff6666; font-weight: 600;">2.</span> Anthropic key starts with <span style="color: #66cc66;">"pk-"</span> — expected <span style="color: #66cc66;">"sk-ant-"</span> prefix      │
│    Run: agents config set provider.anthropic.api-key <correct-key>               │
│ <span style="color: #ff6666; font-weight: 600;">3.</span> FAISS library not installed — vector search will not work        │
│    Run: pip install faiss-cpu                                       │
╰─────────────────────────────────────────────────────────────────────╯

<span style="color: #ff6666; font-weight: 600;">✗ ERROR</span> 3 errors must be resolved before CleverAgents can operate
</code></pre></div>

#### agents init

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> init [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>]</code></pre></div>

**Purpose**
Initialize or reset the global CleverAgents environment. This wipes any existing data and re-creates the global config and database.

**Arguments**

- `--yes`: Skip the confirmation prompt and proceed with the wipe.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> init

<span style="color: yellow; font-weight: 600;">Warning</span>: This will remove all data in /home/alex/.cleveragents
Continue? [y/N]: y

╭─ Environment Reset ────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Config:</span> /home/alex/.cleveragents/config.toml       │
│ <span style="color: #66cc66; font-weight: 600;">Database:</span> /home/alex/.cleveragents/cleveragents.db │
│ <span style="color: yellow; font-weight: 600;">Backup:</span> /home/alex/.cleveragents.backup-2026-02-08 │
│ <span style="color: #66cc66; font-weight: 600;">Status:</span> ready                                      │
╰────────────────────────────────────────────────────╯

╭─ Defaults ──────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Automation Profile:</span> supervised              │
│ <span style="color: #5599ff; font-weight: 600;">Built-in Profiles:</span> 8 loaded                 │
╰─────────────────────────────────────────────╯

╭─ Created ─────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Config:</span> config.toml       │
│ <span style="color: #66cc66; font-weight: 600;">Database:</span> cleveragents.db │
│ <span style="color: #5599ff; font-weight: 600;">Logs:</span> logs/               │
│ <span style="color: #5599ff; font-weight: 600;">Cache:</span> cache/             │
│ <span style="color: #5599ff; font-weight: 600;">Backups:</span> backups/         │
╰───────────────────────────╯

╭─ Schema ───────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Version:</span> v3                    │
│ <span style="color: #66cc66; font-weight: 600;">Tables:</span> 12 created             │
│ <span style="color: #5599ff; font-weight: 600;">Migrations:</span> up to date         │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Environment initialized
</code></pre></div>

Non-interactive initialization using `--yes` (useful in scripts and CI):

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> init <span style="color: cyan;">--yes</span>

╭─ Initialized ──────────────────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Data Dir:</span> /home/alex/.cleveragents (created)           │
│ <span style="color: #66cc66; font-weight: 600;">Config:</span> /home/alex/.cleveragents/config.toml           │
│ <span style="color: #66cc66; font-weight: 600;">Database:</span> initialized (schema v3)                      │
│ <span style="color: #66cc66; font-weight: 600;">Directories:</span> logs, cache, sessions, contexts           │
╰────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Initialized (non-interactive)
</code></pre></div>

#### agents session

**Purpose**
Manage interactive sessions that hold a conversation history and orchestrator state.

##### agents session create

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> session create [<span style="color: cyan;">--actor</span> <span style="color: #66cc66;">&lt;ACTOR&gt;</span>]</code></pre></div>

**Purpose**
Create a new session for interactive work.

**Arguments**

- `--actor ACTOR`: Orchestrator actor to use for `session tell`.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> session create <span style="color: cyan;">--actor</span> local/orchestrator

╭─ Session ───────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> 01HXM2A6K1P2E9Q9D4GQ7J4S7Z  │
│ <span style="color: magenta; font-weight: 600;">Actor:</span> local/orchestrator       │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-08 12:44       │
│ <span style="color: #5599ff; font-weight: 600;">Namespace:</span> local                │
╰─────────────────────────────────╯

╭─ Settings ─────────────╮
│ <span style="color: magenta; font-weight: 600;">Automation:</span> review     │
│ <span style="color: #5599ff; font-weight: 600;">Streaming:</span> off         │
│ <span style="color: #5599ff; font-weight: 600;">Context:</span> default       │
│ <span style="color: #5599ff; font-weight: 600;">Memory:</span> enabled        │
│ <span style="color: yellow; font-weight: 600;">Max History:</span> 50 turns  │
╰────────────────────────╯

╭─ Actor Details ───────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Provider:</span> anthropic               │
│ <span style="color: magenta; font-weight: 600;">Model:</span> claude-3.5                 │
│ <span style="color: #5599ff; font-weight: 600;">Temperature:</span> 0.7                  │
│ <span style="color: #5599ff; font-weight: 600;">Context Window:</span> 200K tokens       │
╰───────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Session created
</code></pre></div>

##### agents session list

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> session list</code></pre></div>

**Purpose**
List sessions available on the local machine.

**Arguments**

None.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> table session list

╭─ Sessions ───────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>        <span style="color: cyan; font-weight: 600;">Name</span>             <span style="color: cyan; font-weight: 600;">Actor</span>               <span style="color: cyan; font-weight: 600;">Messages</span>  <span style="color: cyan; font-weight: 600;">Updated</span>             │
│ <span style="opacity: 0.7;">────────  ───────────────  ──────────────────  ────────  ────────────────</span>    │
│ 01HXM2A6  weekly-planning  local/orchestrator  6         2026-02-08 12:44    │
│ 01HXM1F2  refactor-sprint  local/orchestrator  14        2026-02-07 18:11    │
╰──────────────────────────────────────────────────────────────────────────────╯

╭─ Summary ────────────────────╮
│ <span style="color: yellow; font-weight: 600;">Total:</span> 2                     │
│ <span style="color: #66cc66; font-weight: 600;">Most Recent:</span> weekly-planning │
│ <span style="color: #5599ff; font-weight: 600;">Oldest:</span> refactor-sprint      │
│ <span style="color: #5599ff; font-weight: 600;">Total Messages:</span> 20           │
│ <span style="color: #5599ff; font-weight: 600;">Storage:</span> 42 KB               │
╰──────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 2 sessions listed
</code></pre></div>

##### agents session show

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> session show <span style="color: #66cc66;">&lt;SESSION_ID&gt;</span></code></pre></div>

**Purpose**
Show details and recent messages for a session.

**Arguments**

- `<SESSION_ID>`: The session identifier.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> session show 01HXM2A6K1P2E9Q9D4GQ7J4S7Z

╭─ Session Summary ───────────────╮
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> 01HXM2A6K1P2E9Q9D4GQ7J4S7Z  │
│ <span style="color: magenta; font-weight: 600;">Actor:</span> local/orchestrator       │
│ <span style="color: yellow; font-weight: 600;">Messages:</span> 6                     │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-08 12:30       │
│ <span style="color: #66cc66; font-weight: 600;">Updated:</span> 2026-02-08 12:44       │
│ <span style="color: #5599ff; font-weight: 600;">Automation:</span> review              │
╰─────────────────────────────────╯

╭─ Recent Messages ──────────────────────────────────╮
│ <span style="opacity: 0.7;">user</span>  Create an action to refresh dependency locks │
│ <span style="opacity: 0.7;">assistant</span>  Plan created, running commands...       │
│ <span style="opacity: 0.7;">assistant</span>  Completed 2 commands                    │
╰────────────────────────────────────────────────────╯

╭─ Linked Plans ────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan ID</span>                     <span style="color: cyan; font-weight: 600;">Phase</span>   <span style="color: cyan; font-weight: 600;">State</span>     │
│ <span style="opacity: 0.7;">──────────────────────────  ──────  ────────</span>  │
│ 01HXM8C2ZK4Q7C2B3F2R4VYV6J  execute  complete │
╰───────────────────────────────────────────────╯

╭─ Token Usage ──────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Input Tokens:</span> 3,420        │
│ <span style="color: #5599ff; font-weight: 600;">Output Tokens:</span> 1,185       │
│ <span style="color: yellow; font-weight: 600;">Estimated Cost:</span> $0.0184    │
╰────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Session details loaded
</code></pre></div>

##### agents session delete

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> session delete [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;SESSION_ID&gt;</span></code></pre></div>

**Purpose**
Delete a session and its stored conversation history.

**Arguments**

- `<SESSION_ID>`: The session identifier.
- `--yes, -y`: Skip the confirmation prompt.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> session delete 01HXM2A6K1P2E9Q9D4GQ7J4S7Z

Delete session 01HXM2A6K1P2E9Q9D4GQ7J4S7Z? [y/N]: y

╭─ Deletion Summary ──────────────────╮
│ <span style="color: cyan; font-weight: 600;">Session:</span> 01HXM2A6K1P2E9Q9D4GQ7J4S7Z │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> 01HXM2A6K1P2E9Q9D4GQ7J4S7Z      │
│ <span style="color: yellow; font-weight: 600;">Messages:</span> 6 removed                 │
│ <span style="color: #5599ff; font-weight: 600;">Storage:</span> 18 KB freed                │
│ <span style="color: #5599ff; font-weight: 600;">Plans Orphaned:</span> 0                   │
╰─────────────────────────────────────╯

╭─ Cleanup ───────────╮
│ <span style="color: #66cc66; font-weight: 600;">Backups:</span> none       │
│ <span style="color: #5599ff; font-weight: 600;">Logs:</span> preserved     │
│ <span style="color: #5599ff; font-weight: 600;">Context:</span> cleared    │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoints:</span> none   │
╰─────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Session deleted
</code></pre></div>

##### agents session export

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> session export [(<span style="color: magenta;"><span style="color: cyan;">--output</span>|<span style="color: yellow;">-o</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span>] <span style="color: #66cc66;">&lt;SESSION_ID&gt;</span></code></pre></div>

**Purpose**
Export a session as a portable JSON file.

**Arguments**

- `<SESSION_ID>`: The session identifier.
- `--output/-o FILE`: Output file path (optional).

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> session export <span style="color: cyan;">--output</span> /tmp/weekly-planning.json 01HXM2A6K1P2E9Q9D4GQ7J4S7Z

╭─ Session Export ────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Session:</span> 01HXM2A6K1P2E9Q9D4GQ7J4S7Z │
│ <span style="color: #5599ff; font-weight: 600;">Output:</span> /tmp/weekly-planning.json   │
│ <span style="color: yellow; font-weight: 600;">Messages:</span> 6                         │
│ <span style="color: #66cc66; font-weight: 600;">Size:</span> 24 KB                         │
│ <span style="color: #5599ff; font-weight: 600;">Format:</span> JSON                        │
╰─────────────────────────────────────╯

╭─ Contents ─────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Messages:</span> 6                │
│ <span style="color: #5599ff; font-weight: 600;">Plan References:</span> 1         │
│ <span style="color: #5599ff; font-weight: 600;">Metadata Keys:</span> 2           │
│ <span style="color: yellow; font-weight: 600;">Actor Config:</span> included     │
│ <span style="color: #5599ff; font-weight: 600;">Schema Version:</span> v3         │
╰────────────────────────────╯

╭─ Integrity ──────────────────╮
│ <span style="color: magenta; font-weight: 600;">Checksum:</span> sha256:7a9b...42c1 │
│ <span style="color: yellow; font-weight: 600;">Encrypted:</span> no                │
╰──────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Export completed
</code></pre></div>

##### agents session import

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> session import (<span style="color: magenta;"><span style="color: cyan;">--input</span>|<span style="color: yellow;">-i</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span></code></pre></div>

**Purpose**
Import a session JSON file.

**Arguments**

- `--input/-i FILE`: Input JSON file.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> session import <span style="color: cyan;">--input</span> /tmp/weekly-planning.json

╭─ Session Import ────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Input:</span> /tmp/weekly-planning.json        │
│ <span style="color: #5599ff; font-weight: 600;">Session ID:</span> 01HXM3D3B2W4CQYQ3P4ZB8A5T1  │
│ <span style="color: yellow; font-weight: 600;">Messages:</span> 6                             │
│ <span style="color: #5599ff; font-weight: 600;">Schema:</span> v3                              │
╰─────────────────────────────────────────╯

╭─ Validation ────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Checksum:</span> verified      │
│ <span style="color: #66cc66; font-weight: 600;">Schema:</span> compatible      │
│ <span style="color: #66cc66; font-weight: 600;">Actor Ref:</span> resolved     │
╰─────────────────────────╯

╭─ Merge ──────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Existing:</span> none       │
│ <span style="color: #5599ff; font-weight: 600;">Strategy:</span> create new │
╰──────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Import completed
</code></pre></div>

##### agents session tell

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> session tell <span style="color: cyan;">--session</span> <span style="color: #66cc66;">&lt;SESSION_ID&gt;</span> [<span style="color: cyan;">--actor</span> <span style="color: #66cc66;">&lt;ACTOR&gt;</span>] [<span style="color: cyan;">--stream</span>] <span style="color: #66cc66;">&lt;PROMPT&gt;</span></code></pre></div>

**Purpose**
Send a natural-language request to the orchestrator. The orchestrator can create actions, plans, or project changes by issuing the necessary CleverAgents commands under the hood.

**Arguments**

- `<PROMPT>`: Instruction text (positional argument).
- `--session SESSION_ID`: Session to use (required).
- `--actor ACTOR`: Override the session actor for this request.
- `--stream`: Stream progress as the orchestrator works.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> session tell <span style="color: #66cc66;">&quot;Create an action to refresh dependency locks and add it to the platform project&quot;</span> \
  <span style="color: cyan;">--session</span> 01HXM2A6K1P2E9Q9D4GQ7J4S7Z

╭─ Plan Request ──────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Actor:</span> local/orchestrator                               │
│ <span style="color: cyan; font-weight: 600;">Session:</span> 01HXM2A6K1P2E9Q9D4GQ7J4S7Z                     │
│ <span style="color: magenta; font-weight: 600;">Automation:</span> review                                      │
│ <span style="color: #5599ff; font-weight: 600;">Prompt:</span> Create an action to refresh dependency locks... │
╰─────────────────────────────────────────────────────────╯

╭─ Commands Executed ─────────────────────────────────────────────────────────────────────────────────────────╮
│ - agents action create <span style="color: cyan;">--config</span> ./actions/refresh-locks.yaml                                              │
│ - agents resource add git-checkout local/platform-repo <span style="color: cyan;">--path</span> /repos/platform                               │
│ - agents project link-resource local/platform local/platform-repo                                           │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Result ──────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Action:</span> local/refresh-locks       │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/platform           │
│ <span style="color: magenta; font-weight: 600;">Resource:</span> local/platform-repo     │
╰───────────────────────────────────╯

╭─ Usage ─────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Input Tokens:</span> 1,842         │
│ <span style="color: #5599ff; font-weight: 600;">Output Tokens:</span> 624          │
│ <span style="color: yellow; font-weight: 600;">Cost:</span> $0.0094               │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 3.2s              │
│ <span style="color: #5599ff; font-weight: 600;">Tool Calls:</span> 3               │
╰─────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Orchestrator completed 3 commands
</code></pre></div>

Using `--stream` to see the response as it is generated (token by token):

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> session tell <span style="color: cyan;">--session</span> 01HXM2A6K1 <span style="color: cyan;">--stream</span> <span style="color: #66cc66;">&quot;What files were changed in the last plan?&quot;</span>

╭─ Session ──────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXM2A6K1P2E9Q9D4GQ7J4S7Z     │
│ <span style="color: #5599ff; font-weight: 600;">Actor:</span> local/orchestrator          │
│ <span style="color: #5599ff; font-weight: 600;">Mode:</span> streaming                    │
╰────────────────────────────────────╯

<span style="color: #66cc66;">▍</span> The last plan (01HXM8C2ZK) modified 6 files in the auth module:

  1. `src/auth/session.py` — refactored session validation
  2. `src/auth/tokens.py` — updated token expiry to 7200s
  3. `src/auth/__init__.py` — updated exports
  4. `tests/test_auth.py` — added 12 new test cases
  5. `tests/test_session.py` — updated session fixtures
  6. `docs/auth.md` — updated API documentation

All changes passed validation (24/24 tests, lint clean).

╭─ Usage ──────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Tokens:</span> 1,240 (stream)   │
│ <span style="color: #5599ff; font-weight: 600;">Duration:</span> 3.1s           │
│ <span style="color: #5599ff; font-weight: 600;">Tool Calls:</span> 2            │
╰──────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Stream complete
</code></pre></div>

#### agents project

**Purpose**
Manage projects and their resources.

##### agents project create

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> project create [(<span style="color: magenta;"><span style="color: cyan;">--description</span>|<span style="color: yellow;">-d</span></span>) <span style="color: #66cc66;">&lt;DESC&gt;</span>] [<span style="color: cyan;">--resource</span> <span style="color: #66cc66;">&lt;RESOURCE&gt;</span>]...
                     [<span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">&lt;INVARIANT&gt;</span>]... [<span style="color: cyan;">--invariant-actor</span> <span style="color: #66cc66;">&lt;ACTOR&gt;</span>] <span style="color: #66cc66;">&lt;NAME&gt;</span></code></pre></div>

**Purpose**
Create a new project record.

**Arguments**

- `<NAME>`: Namespaced project name (positional argument).
- `--description/-d TEXT`: Optional description.
- `--resource RESOURCE`: Resource name or ULID to link to the project at creation time (repeatable).
- `--invariant TEXT`: Invariant to attach to this project (repeatable). These invariants apply to all plans targeting this project.
- `--invariant-actor ACTOR`: Invariant Reconciliation Actor for this project. Used to reconcile project-level invariants against global invariants for all plans targeting this project (unless the plan overrides it).

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project create <span style="color: cyan;">--description</span> <span style="color: #66cc66;">&quot;Backend API&quot;</span> local/api-service

╭─ Project ──────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/api-service        │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Backend API       │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> local                    │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-08 12:46      │
╰────────────────────────────────╯

╭─ Paths ────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Root:</span> /repos/api-service                   │
│ <span style="color: #5599ff; font-weight: 600;">Data Dir:</span> /repos/api-service/.cleveragents │
╰────────────────────────────────────────────╯

╭─ Defaults ──────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Sandbox:</span> git_worktree                   │
│ <span style="color: #66cc66; font-weight: 600;">Validations:</span> 0                          │
│ <span style="color: yellow; font-weight: 600;">Context Filters:</span> none                   │
│ <span style="color: magenta; font-weight: 600;">Automation Profile:</span> (inherits global)   │
╰─────────────────────────────────────────╯

╭─ Resources ──────╮
│ <span style="color: yellow; font-weight: 600;">Total:</span> 0         │
│ <span style="color: #5599ff; font-weight: 600;">Indexed:</span> 0       │
│ <span style="color: #5599ff; font-weight: 600;">Sandboxable:</span> 0   │
╰──────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project created
</code></pre></div>

Creating a project with resources and invariants in one command:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project create <span style="color: cyan;">-d</span> <span style="color: #66cc66;">&quot;Frontend web application&quot;</span> \
  <span style="color: cyan;">--resource</span> local/web-repo <span style="color: cyan;">--resource</span> local/web-db \
  <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">&quot;All components must have unit tests&quot;</span> \
  <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">&quot;CSS must pass stylelint checks&quot;</span> \
  <span style="color: cyan;">--invariant-actor</span> local/invariant-resolver \
  local/web-app

╭─ Project Created ─────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/web-app                   │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Frontend web app         │
│ <span style="color: #5599ff; font-weight: 600;">Remote:</span> no                            │
╰───────────────────────────────────────╯

╭─ Linked Resources ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>               <span style="color: cyan; font-weight: 600;">Type</span>          <span style="color: cyan; font-weight: 600;">Read-Only</span>               │
│ <span style="opacity: 0.7;">─────────────────  ──────────────  ─────────</span>             │
│ local/web-repo     git-checkout    no                   │
│ local/web-db       local/database  no                   │
╰──────────────────────────────────────────────────────────╯

╭─ Invariants ────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">1.</span> All components must have unit tests          │
│ <span style="color: magenta; font-weight: 600;">2.</span> CSS must pass stylelint checks               │
│ <span style="color: #5599ff; font-weight: 600;">Reconciliation Actor:</span> local/invariant-resolver  │
╰─────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project created
</code></pre></div>

##### agents project link-resource

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> project link-resource [<span style="color: cyan;">--read-only</span>] <span style="color: #66cc66;">&lt;PROJECT&gt;</span> <span style="color: #66cc66;">&lt;RESOURCE&gt;</span></code></pre></div>

**Purpose**
Link a registered resource to a project. The resource must already be registered via `agents resource add`. A resource can be linked to multiple projects. Optionally, the resource can be marked as read-only within this project context, and given an alias for convenience.

**Arguments**

- `<PROJECT>`: Project name (positional argument).
- `<RESOURCE>`: Resource name or ULID (positional argument).
- `--read-only`: Mark the resource as read-only within this project (even if the resource itself is writable).

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add git-checkout local/api-repo <span style="color: cyan;">--path</span> /repos/api <span style="color: cyan;">--branch</span> main
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project link-resource local/api-service local/api-repo

╭─ Resource Linked ───────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service              │
│ <span style="color: #5599ff; font-weight: 600;">Resource:</span> local/api-repo                │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> git-checkout                      │
│ <span style="color: #5599ff; font-weight: 600;">Read-Only:</span> no                           │
╰─────────────────────────────────────────╯

╭─ Access ─────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Read:</span> allowed            │
│ <span style="color: yellow; font-weight: 600;">Write:</span> allowed           │
│ <span style="color: #5599ff; font-weight: 600;">Apply:</span> requires approval │
╰──────────────────────────╯

╭─ Indexing ─────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Status:</span> indexing...            │
│ <span style="color: #5599ff; font-weight: 600;">Files Found:</span> 347               │
│ <span style="color: #5599ff; font-weight: 600;">Language:</span> Python (primary)     │
│ <span style="color: #5599ff; font-weight: 600;">Estimated Time:</span> ~20 seconds    │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource linked to project
</code></pre></div>

##### agents project unlink-resource

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> project unlink-resource [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;PROJECT&gt;</span> <span style="color: #66cc66;">&lt;RESOURCE_NAME&gt;</span></code></pre></div>

**Purpose**
Unlink a resource from a project. The resource itself remains registered in the Resource Registry and can still be linked to other projects. Active plans using this resource in this project context will be warned.

**Arguments**

- `<PROJECT>`: Project name (positional argument).
- `<RESOURCE_NAME>`: Resource name (positional argument). Only user-added (named) resources can be unlinked.
- `--yes, -y`: Skip confirmation prompt.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project unlink-resource local/api-service local/api-repo

Unlink local/api-repo from local/api-service? [y/N]: y

╭─ Resource Unlinked ─────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service                          │
│ <span style="color: #5599ff; font-weight: 600;">Resource:</span> local/api-repo                            │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> git-checkout                                  │
╰─────────────────────────────────────────────────────╯

╭─ Index Cleanup ──────────╮
│ <span style="color: yellow; font-weight: 600;">Text Index:</span> 347 removed  │
│ <span style="color: yellow; font-weight: 600;">Vectors:</span> 892 removed     │
│ <span style="color: yellow; font-weight: 600;">Graph Triples:</span> cleared   │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 0.3s           │
╰──────────────────────────╯

╭─ Project Summary ──────────────╮
│ <span style="color: yellow; font-weight: 600;">Linked Resources:</span> 1 remaining  │
│ <span style="color: #66cc66; font-weight: 600;">Last Updated:</span> 2026-02-09 10:30 │
│ <span style="color: #5599ff; font-weight: 600;">Active Plans:</span> 0                │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource unlinked from project
</code></pre></div>

##### agents project list

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> project list [(<span style="color: magenta;"><span style="color: cyan;">--namespace</span>|<span style="color: yellow;">-n</span></span>) NS] [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]</code></pre></div>

**Purpose**
List projects with optional filters.

**Arguments**

- `--namespace/-n NS`: Filter by namespace.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> table project list

╭─ Projects ────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>               <span style="color: cyan; font-weight: 600;">Resources</span>  <span style="color: cyan; font-weight: 600;">Remote</span>  <span style="color: cyan; font-weight: 600;">Active Plans</span>            │
│ <span style="opacity: 0.7;">─────────────────  ─────────  ──────  ────────────</span>            │
│ local/api-service  2          No      1                       │
│ local/docs         1          No      0                       │
╰───────────────────────────────────────────────────────────────╯

╭─ Summary ──────────────────╮
│ <span style="color: yellow; font-weight: 600;">Total:</span> 2                   │
│ <span style="color: #66cc66; font-weight: 600;">With Resources:</span> 2          │
│ <span style="color: #5599ff; font-weight: 600;">Remote:</span> 0                  │
│ <span style="color: #5599ff; font-weight: 600;">Total Resources:</span> 3         │
│ <span style="color: #5599ff; font-weight: 600;">Indexed Files:</span> 1,247       │
│ <span style="color: yellow; font-weight: 600;">Active Plans:</span> 1            │
╰────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 2 projects listed
</code></pre></div>

##### agents project show

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> project show <span style="color: #66cc66;">&lt;PROJECT&gt;</span></code></pre></div>

**Purpose**
Show full project details.

**Arguments**

- `<NAME>`: Project name.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project show local/api-service

╭─ Project Details ──────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/api-service        │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Backend API       │
│ <span style="color: yellow; font-weight: 600;">Resources:</span> 2                   │
│ <span style="color: #66cc66; font-weight: 600;">Remote:</span> no                     │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-08 12:46      │
╰────────────────────────────────╯

╭─ Linked Resources ──────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Resource</span>          <span style="color: cyan; font-weight: 600;">Type</span>            <span style="color: cyan; font-weight: 600;">Sandbox</span>              <span style="color: cyan; font-weight: 600;">Read-Only</span>        │
│ <span style="opacity: 0.7;">────────────────  ──────────────  ────────────────────  ─────────</span>       │
│ local/api-repo   git-checkout    git_worktree         no                │
│ local/staging-db local/database  transaction_rollback yes               │
╰─────────────────────────────────────────────────────────────────────────╯

╭─ Validations (3) ──────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">local/run-tests</span>          Run unit tests with coverage    <span style="color: #66cc66; font-weight: 600;">required</span>                │
│   <span style="opacity: 0.7;">resource: local/api-repo  scope: project  (attachment: 01HXM5A1B2C3D4E5F6G7…)</span>│
│ <span style="color: cyan; font-weight: 600;">local/lint-check</span>         Lint check                     <span style="color: #66cc66; font-weight: 600;">required</span>                │
│   <span style="opacity: 0.7;">resource: local/api-repo  scope: direct (always active)  (attachment: 01HXM5…)</span>│
│ <span style="color: cyan; font-weight: 600;">local/check-bundle-size</span>  Check bundle size (advisory)   <span style="color: yellow; font-weight: 600;">info</span>                    │
│   <span style="opacity: 0.7;">resource: local/api-repo  scope: project  (attachment: 01HXM5D4E5F6G7H8J9…)</span>│
╰───────────────────────────────────────────────────────────────────────────────────╯

╭─ Context ───────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Include:</span> repo               │
│ <span style="color: yellow; font-weight: 600;">Exclude:</span> **/node_modules/** │
│ <span style="color: #5599ff; font-weight: 600;">Max File Size:</span> 1 MB         │
╰─────────────────────────────╯

╭─ Indexing Status ──────────╮
│ <span style="color: #66cc66; font-weight: 600;">Text Index:</span> ready          │
│ <span style="color: #66cc66; font-weight: 600;">Vector Index:</span> ready        │
│ <span style="color: yellow; font-weight: 600;">Graph Store:</span> disabled      │
│ <span style="color: #5599ff; font-weight: 600;">Indexed Files:</span> 347         │
│ <span style="color: #5599ff; font-weight: 600;">Last Indexed:</span> 12:48        │
╰────────────────────────────╯

╭─ Active Plans ──────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan ID</span>   <span style="color: cyan; font-weight: 600;">Action</span>               <span style="color: cyan; font-weight: 600;">Phase</span>    │
│ <span style="opacity: 0.7;">────────  ───────────────────  ───────</span>  │
│ 01HXM7A9  local/code-coverage  execute  │
╰─────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project loaded
</code></pre></div>

##### agents project validations

Note: Validations are managed as a top-level entity via `agents validation` commands (see the **agents validation** section below). A validation is always attached to a resource, but can optionally be scoped to a project via `agents validation attach --project <PROJECT> <RESOURCE> <VALIDATION>`. When scoped to a project, the validation only runs when that resource is accessed through the specified project. The `agents project show` command displays all validations relevant to the project — both directly-attached validations on linked resources and project-scoped validations.

See: [agents validation](#agents-validation) for full details on creating, managing, and attaching validations.

##### agents project delete

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> project delete [<span style="color: cyan;">--force</span>|<span style="color: yellow;">-f</span>] [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;NAME&gt;</span></code></pre></div>

**Purpose**
Delete a project and unlink all associated resources. The resources themselves remain in the Resource Registry.

**Arguments**

- `<NAME>`: Project name.
- `--force/-f`: Delete even if active plans exist.
- `--yes`: Skip confirmation prompt.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project delete local/docs

Delete project local/docs? This cannot be undone. [y/N]: y

╭─ Deletion Summary ──────────────────╮
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/docs                 │
│ <span style="color: yellow; font-weight: 600;">Resources:</span> 1 unlinked               │
│ <span style="color: #5599ff; font-weight: 600;">Data Dir:</span> /repos/docs/.cleveragents │
╰─────────────────────────────────────╯

╭─ Index Cleanup ────────╮
│ <span style="color: yellow; font-weight: 600;">Text Index:</span> cleared    │
│ <span style="color: yellow; font-weight: 600;">Vectors:</span> 240 removed   │
│ <span style="color: yellow; font-weight: 600;">Graph Triples:</span> none    │
│ <span style="color: #5599ff; font-weight: 600;">Storage Freed:</span> 12 MB   │
╰────────────────────────╯

╭─ Backups ────────────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Snapshot:</span> /backups/local-docs-2026-02-08.tgz │
│ <span style="color: yellow; font-weight: 600;">Retention:</span> 7 days                            │
╰──────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project deleted
</code></pre></div>

Attempting to delete a project that has active plans (without `--force`):

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project delete local/api-service

Delete project local/api-service? [y/N]: y

╭─ Delete Blocked ──────────────────────────────────────────╮
│ <span style="color: #ff6666; font-weight: 600;">Cannot delete:</span> project has active plans                   │
│ <span style="color: #5599ff; font-weight: 600;">Active Plans:</span> 2                                           │
│   <span style="opacity: 0.7;">01HXM7A9 — execute/processing (local/code-coverage)</span>     │
│   <span style="opacity: 0.7;">01HXM4J1 — strategize/processing (local/refactor-api)</span>   │
╰───────────────────────────────────────────────────────────╯

╭─ Resolution ──────────────────────────────────────────────────────╮
│ - Cancel or complete active plans first, or                       │
│ - Use <span style="color: cyan;">--force</span> to cancel all active plans and delete the project   │
╰───────────────────────────────────────────────────────────────────╯

<span style="color: #ff6666; font-weight: 600;">✗ ERROR</span> Delete blocked — 2 active plans
</code></pre></div>

Force-deleting a project with active plans:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project delete <span style="color: cyan;">--force</span> <span style="color: cyan;">--yes</span> local/api-service

╭─ Force Delete ─────────────────────────────────────────╮
│ <span style="color: yellow; font-weight: 600;">Cancelling:</span> 2 active plans                             │
│   <span style="opacity: 0.7;">01HXM7A9 — cancelled (was execute/processing)</span>        │
│   <span style="opacity: 0.7;">01HXM4J1 — cancelled (was strategize/processing)</span>     │
╰────────────────────────────────────────────────────────╯

╭─ Deleted ────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service   │
│ <span style="color: #5599ff; font-weight: 600;">Resources Unlinked:</span> 2        │
│ <span style="color: #5599ff; font-weight: 600;">Validations Detached:</span> 3      │
│ <span style="color: #5599ff; font-weight: 600;">Plans Cancelled:</span> 2           │
│ <span style="color: #5599ff; font-weight: 600;">Context Policies:</span> cleared    │
╰──────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project force-deleted
</code></pre></div>

##### agents project context

**Purpose**
Manage ACMS context policies for the hot/warm/cold tiers, per-view context selection, strategy configuration, UKO depth/breadth parameters, and context budget tuning.

###### agents project context set

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> project context set[<span style="color: cyan;">--view</span> (<span style="color: magenta;">strategize|execute|apply|default</span>)]
                          [<span style="color: cyan;">--include-resource</span> <span style="color: #66cc66;">&lt;INCLUDE_RESOURCE&gt;</span>]...
                          [<span style="color: cyan;">--exclude-resource</span> <span style="color: #66cc66;">&lt;EXCLUDE_RESOURCE&gt;</span>]...
                          [<span style="color: cyan;">--include-path</span> <span style="color: #66cc66;">&lt;INCLUDE_GLOB&gt;</span>]...
                          [<span style="color: cyan;">--exclude-path</span> <span style="color: #66cc66;">&lt;EXCLUDE_GLOB&gt;</span>]...
                          [<span style="color: cyan;">--hot-max-tokens</span> <span style="color: #66cc66;">&lt;N&gt;</span>]
                          [<span style="color: cyan;">--warm-max-decisions</span> <span style="color: #66cc66;">&lt;N_WARM_MAX&gt;</span>]
                          [<span style="color: cyan;">--cold-max-decisions</span> <span style="color: #66cc66;">&lt;N_COLD_MAX&gt;</span>]
                          [<span style="color: cyan;">--query-limit</span> <span style="color: #66cc66;">&lt;N&gt;</span>]
                          [<span style="color: cyan;">--max-file-size</span> <span style="color: #66cc66;">&lt;MAX_FILE_BYTES&gt;</span>]
                          [<span style="color: cyan;">--max-total-size</span> <span style="color: #66cc66;">&lt;MAX_TOTAL_BYTES&gt;</span>]
                          [<span style="color: cyan;">--summarize</span>|<span style="color: cyan;">--no-summarize</span>]
                          [<span style="color: cyan;">--summary-max-tokens</span> <span style="color: #66cc66;">&lt;N&gt;</span>]
                          [<span style="color: cyan;">--strategy</span> <span style="color: #66cc66;">&lt;STRATEGY&gt;</span>]...
                          [<span style="color: cyan;">--default-breadth</span> <span style="color: #66cc66;">&lt;N&gt;</span>]
                          [<span style="color: cyan;">--default-depth</span> (<span style="color: magenta;">SIGNATURE|SUMMARY|STUB|FULL</span>)]
                          [<span style="color: cyan;">--depth-gradient</span> <span style="color: #66cc66;">&lt;HOP:LEVEL&gt;</span>]...
                          [<span style="color: cyan;">--skeleton-ratio</span> <span style="color: #66cc66;">&lt;FLOAT&gt;</span>]
                          [<span style="color: cyan;">--temporal-scope</span> (<span style="color: magenta;">current|recent|all</span>)]
                          [<span style="color: cyan;">--auto-refresh</span>|<span style="color: cyan;">--no-auto-refresh</span>]
                          [<span style="color: cyan;">--clear</span>] <span style="color: #66cc66;">&lt;PROJECT&gt;</span></code></pre></div>

**Purpose**
Set the context policy for a project and (optionally) a specific view.

**Arguments**

- `<PROJECT>`: Project name (positional argument, at end of command).
- `--view strategize|execute|apply|default`: Which view this policy applies to.
- `--include-resource NAME`: Resource allowlist (repeatable).
- `--exclude-resource NAME`: Resource denylist (repeatable).
- `--include-path GLOB`: Path allowlist (repeatable).
- `--exclude-path GLOB`: Path denylist (repeatable).
- `--hot-max-tokens N`: Maximum token budget for hot context. This is a soft cap and may be null. The actor/LLM hard limit can be lower; the effective hot context is the lesser of the two.
- `--warm-max-decisions N`: Maximum number of decisions kept in warm context.
- `--cold-max-decisions N`: Maximum number of decisions kept in cold context.
- `--query-limit N`: Max number of retrieval results per query.
- `--max-file-size BYTES`: Max file size included in context.
- `--max-total-size BYTES`: Max total size across included files.
- `--summarize/--no-summarize`: Enable or disable summarization for large context segments.
- `--summary-max-tokens N`: Token limit for generated summaries.
- `--strategy STRATEGY`: ACMS context strategy to enable for this view (repeatable). Overrides the global `context.strategies.enabled` list. Built-in: `simple-keyword`, `semantic-embedding`, `breadth-depth-navigator`, `arce`, `temporal-archaeology`, `plan-decision-context`.
- `--default-breadth N`: Default number of hops from focus nodes in the UKO graph. `0` = focus nodes only. Default: `2`.
- `--default-depth SIGNATURE|SUMMARY|STUB|FULL`: Default detail level for context fragments. Default: `SUMMARY`.
- `--depth-gradient HOP:LEVEL`: Per-hop detail level override (repeatable). Format: `0:FULL`, `1:SUMMARY`, `2:SIGNATURE`. Hops not specified use `--default-depth`.
- `--skeleton-ratio FLOAT`: Fraction of context budget reserved for inherited plan skeleton. Range: 0.0–1.0. Default: `0.15`.
- `--temporal-scope current|recent|all`: Temporal scope for UKO node resolution. Default: `current`.
- `--auto-refresh/--no-auto-refresh`: Enable or disable automatic context re-assembly on budget changes.
- `--clear`: Clear the policy for the selected view.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project context set <span style="color: cyan;">--view</span> strategize \
  <span style="color: cyan;">--include-resource</span> repo <span style="color: cyan;">--exclude-path</span> <span style="color: #66cc66;">&quot;**/node_modules/**&quot;</span> \
  <span style="color: cyan;">--hot-max-tokens</span> 12000 <span style="color: cyan;">--warm-max-decisions</span> 50 <span style="color: cyan;">--cold-max-decisions</span> 200 \
  <span style="color: cyan;">--summarize</span> <span style="color: cyan;">--summary-max-tokens</span> 800 local/api-service

╭─ Context Policy ────────────╮
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service  │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> strategize            │
│ <span style="color: #66cc66; font-weight: 600;">Include:</span> repo               │
│ <span style="color: yellow; font-weight: 600;">Exclude:</span> **/node_modules/** │
╰─────────────────────────────╯

╭─ Limits ─────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Hot Tokens:</span> 12000 (soft cap) │
│ <span style="color: magenta; font-weight: 600;">Warm Decisions:</span> 50           │
│ <span style="color: magenta; font-weight: 600;">Cold Decisions:</span> 200          │
│ <span style="color: #5599ff; font-weight: 600;">Query Limit:</span> 20              │
│ <span style="color: #5599ff; font-weight: 600;">Max File Size:</span> 1 MB          │
│ <span style="color: #5599ff; font-weight: 600;">Max Total Size:</span> 50 MB        │
╰──────────────────────────────╯

╭─ Summarization ─╮
│ <span style="color: #66cc66; font-weight: 600;">Enabled:</span> yes    │
│ <span style="color: #5599ff; font-weight: 600;">Max Tokens:</span> 800 │
╰─────────────────╯

╭─ Other Views ────────╮
│ <span style="color: #5599ff; font-weight: 600;">execute:</span> (default)   │
│ <span style="color: #5599ff; font-weight: 600;">apply:</span> (default)     │
│ <span style="color: #5599ff; font-weight: 600;">default:</span> (unset)     │
╰──────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Context policy updated
</code></pre></div>

###### agents project context show

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> project context show [<span style="color: cyan;">--view</span> (<span style="color: magenta;">strategize|execute|apply|default</span>)]
                            <span style="color: #66cc66;">&lt;PROJECT&gt;</span></code></pre></div>

**Purpose**
Show the active context policy for a project.

**Arguments**

- `<PROJECT>`: Project name (positional argument, at end of command).
- `--view strategize|execute|apply|default`: View to display.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project context show <span style="color: cyan;">--view</span> strategize local/api-service

╭─ Context Policy ────────────╮
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service  │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> strategize            │
│ <span style="color: #66cc66; font-weight: 600;">Include:</span> repo               │
│ <span style="color: yellow; font-weight: 600;">Exclude:</span> **/node_modules/** │
╰─────────────────────────────╯

╭─ Limits ─────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Hot Tokens:</span> 12000 (soft cap) │
│ <span style="color: magenta; font-weight: 600;">Warm Decisions:</span> 50           │
│ <span style="color: magenta; font-weight: 600;">Cold Decisions:</span> 200          │
│ <span style="color: #5599ff; font-weight: 600;">Query Limit:</span> 20              │
│ <span style="color: #5599ff; font-weight: 600;">Max File Size:</span> 1 MB          │
│ <span style="color: #5599ff; font-weight: 600;">Max Total Size:</span> 50 MB        │
╰──────────────────────────────╯

╭─ Summarization ─╮
│ <span style="color: #66cc66; font-weight: 600;">Enabled:</span> yes    │
│ <span style="color: #5599ff; font-weight: 600;">Max Tokens:</span> 800 │
╰─────────────────╯

╭─ Current Usage ──────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Hot Context:</span> 8,420 / 12,000  │
│ <span style="color: #5599ff; font-weight: 600;">Warm Entries:</span> 12 / 50        │
│ <span style="color: #5599ff; font-weight: 600;">Cold Entries:</span> 47 / 200       │
│ <span style="color: #66cc66; font-weight: 600;">Indexed Resources:</span> 1         │
╰──────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Context policy loaded
</code></pre></div>

###### agents project context inspect

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> project context inspect [<span style="color: cyan;">--view</span> (<span style="color: magenta;">strategize|execute|apply|default</span>)]
                               [<span style="color: cyan;">--strategy</span> <span style="color: #66cc66;">&lt;STRATEGY&gt;</span>]
                               [<span style="color: cyan;">--focus</span> <span style="color: #66cc66;">&lt;UKO_URI&gt;</span>]...
                               [<span style="color: cyan;">--breadth</span> <span style="color: #66cc66;">&lt;N&gt;</span>] [<span style="color: cyan;">--depth</span> (<span style="color: magenta;">SIGNATURE|SUMMARY|STUB|FULL</span>)]
                               <span style="color: #66cc66;">&lt;PROJECT&gt;</span></code></pre></div>

**Purpose**
Inspect the current state of the ACMS context assembly for a project. Shows the UKO graph structure, active strategies, indexed resources, context budget usage, and the most recent fusion result. Useful for debugging context quality issues.

**Arguments**

- `<PROJECT>`: Project name (positional argument, at end of command).
- `--view strategize|execute|apply|default`: View to inspect. Default: `default`.
- `--strategy STRATEGY`: Filter to show results from a specific strategy only.
- `--focus UKO_URI`: Show the UKO subgraph rooted at these focus nodes (repeatable). When omitted, shows a summary of the full indexed graph.
- `--breadth N`: Override the breadth (hop count) for the focus node expansion. Default: uses the view's `default_breadth`.
- `--depth SIGNATURE|SUMMARY|STUB|FULL`: Override the depth for the display. Default: uses the view's `default_depth`.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project context inspect <span style="color: cyan;">--view</span> execute <span style="color: cyan;">--focus</span> uko-py:module/src.auth <span style="color: cyan;">--breadth</span> 2 local/api-service

╭─ ACMS Context Inspection ────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service                                      │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> execute                                                   │
│ <span style="color: #66cc66; font-weight: 600;">Focus:</span> uko-py:module/src.auth                                   │
│ <span style="color: magenta; font-weight: 600;">Breadth:</span> 2 hops  │  <span style="color: magenta; font-weight: 600;">Depth:</span> SUMMARY                            │
╰──────────────────────────────────────────────────────────────────╯

╭─ UKO Graph (2-hop neighborhood) ─────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">uko-py:module/src.auth</span> (FULL, 1,240 tokens)                     │
│   ├─ contains → <span style="color: #5599ff;">uko-py:class/AuthHandler</span> (SUMMARY, 320 tokens)  │
│   ├─ contains → <span style="color: #5599ff;">uko-py:class/TokenValidator</span> (SUMMARY, 280 tok)  │
│   ├─ imports  → <span style="color: #5599ff;">uko-py:module/src.db</span> (SIGNATURE, 90 tokens)     │
│   └─ imports  → <span style="color: #5599ff;">uko-py:module/src.config</span> (SIGNATURE, 60 tok)    │
╰──────────────────────────────────────────────────────────────────╯

╭─ Active Strategies ──────────────────────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">breadth-depth-navigator</span>  quality=0.85  budget=45%  4 fragments  │
│ <span style="color: #66cc66; font-weight: 600;">semantic-embedding</span>       quality=0.60  budget=35%  6 fragments  │
│ <span style="color: #66cc66; font-weight: 600;">simple-keyword</span>           quality=0.30  budget=20%  3 fragments  │
╰──────────────────────────────────────────────────────────────────╯

╭─ Budget ─────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Model Window:</span> 128,000 tokens         │
│ <span style="color: #5599ff; font-weight: 600;">Response Reserve:</span> 4,096 tokens       │
│ <span style="color: #5599ff; font-weight: 600;">Tool Definitions:</span> 2,400 tokens       │
│ <span style="color: #5599ff; font-weight: 600;">System Prompt:</span> 1,200 tokens           │
│ <span style="color: #5599ff; font-weight: 600;">Skeleton Reserve:</span> 18,046 (15%)       │
│ <span style="color: magenta; font-weight: 600;">Available Budget:</span> 102,258 tokens     │
│ <span style="color: #66cc66; font-weight: 600;">Used:</span> 1,990 / 102,258 (1.9%)         │
╰──────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Context inspection complete
</code></pre></div>

###### agents project context simulate

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> project context simulate [<span style="color: cyan;">--view</span> (<span style="color: magenta;">strategize|execute|apply|default</span>)]
                                [<span style="color: cyan;">--budget</span> <span style="color: #66cc66;">&lt;TOKENS&gt;</span>]
                                [<span style="color: cyan;">--focus</span> <span style="color: #66cc66;">&lt;UKO_URI&gt;</span>]...
                                [<span style="color: cyan;">--strategy</span> <span style="color: #66cc66;">&lt;STRATEGY&gt;</span>]...
                                <span style="color: #66cc66;">&lt;PROJECT&gt;</span></code></pre></div>

**Purpose**
Simulate a context assembly run without invoking an actor. Produces a dry-run report showing what the Fusion Engine would include in the context payload, which strategies contributed, how the budget was allocated, and what was excluded. Useful for tuning context view configurations before running plans.

**Arguments**

- `<PROJECT>`: Project name (positional argument, at end of command).
- `--view strategize|execute|apply|default`: View to simulate. Default: `default`.
- `--budget TOKENS`: Override the context budget in tokens. When omitted, uses the dynamic budget calculation.
- `--focus UKO_URI`: Focus nodes for the simulation (repeatable). When omitted, uses a default focus derived from recent plan activity.
- `--strategy STRATEGY`: Override which strategies to run (repeatable). When omitted, uses the view's configured strategies.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project context simulate <span style="color: cyan;">--view</span> strategize <span style="color: cyan;">--budget</span> 16000 \
    <span style="color: cyan;">--focus</span> uko-py:module/src.auth <span style="color: cyan;">--focus</span> uko-py:module/src.db \
    local/api-service

╭─ ACMS Simulation ────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service                                      │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> strategize                                                │
│ <span style="color: magenta; font-weight: 600;">Budget:</span> 16,000 tokens (override)                               │
│ <span style="color: #66cc66; font-weight: 600;">Focus:</span> uko-py:module/src.auth, uko-py:module/src.db             │
╰──────────────────────────────────────────────────────────────────╯

╭─ Strategy Results ───────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">breadth-depth-navigator</span>                                        │
│   Confidence: 0.85  │  Budget: 7,200 tokens  │  12 fragments    │
│   Top: src/auth/__init__.py (FULL, 1,240t, score=0.95)          │
│        src/db/models.py (SUMMARY, 480t, score=0.88)             │
│                                                                  │
│ <span style="color: cyan; font-weight: 600;">semantic-embedding</span>                                             │
│   Confidence: 0.60  │  Budget: 5,600 tokens  │  8 fragments     │
│   Top: src/auth/jwt.py (SUMMARY, 380t, score=0.82)              │
│        src/middleware/auth_check.py (SUMMARY, 290t, score=0.79)  │
│                                                                  │
│ <span style="color: cyan; font-weight: 600;">simple-keyword</span>                                                 │
│   Confidence: 0.30  │  Budget: 3,200 tokens  │  5 fragments     │
│   Top: src/auth/utils.py (STUB, 210t, score=0.71)               │
╰──────────────────────────────────────────────────────────────────╯

╭─ Fusion Result ──────────────────────────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Included:</span> 18 fragments (14,820 tokens, 92.6% of budget)         │
│ <span style="color: yellow; font-weight: 600;">Excluded:</span> 7 fragments (3,200 tokens, below budget cutoff)       │
│ <span style="color: #5599ff; font-weight: 600;">Deduplicated:</span> 4 fragments merged                               │
│ <span style="color: #5599ff; font-weight: 600;">Skeleton:</span> 2,400 tokens (15% reserve)                           │
│ <span style="color: magenta; font-weight: 600;">Preamble:</span> 180 tokens                                           │
╰──────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Simulation complete (dry run — no context was assembled)
</code></pre></div>

#### agents actor

**Purpose**
Manage actors and run actor configurations directly.

##### agents actor run

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> actor run [(<span style="color: magenta;"><span style="color: cyan;">--output</span>|<span style="color: yellow;">-o</span></span>) <span style="color: #66cc66;">&lt;OUTPUT_FILE&gt;</span>]
                 [<span style="color: yellow;">-v</span>...] [<span style="color: cyan;">--unsafe</span>|<span style="color: yellow;">-u</span>] [<span style="color: cyan;">--context</span> <span style="color: #66cc66;">&lt;CONTEXT_NAME&gt;</span>]
                 [<span style="color: cyan;">--context-dir</span> <span style="color: #66cc66;">&lt;CONTEXT_PATH&gt;</span>] [<span style="color: cyan;">--load-context</span> <span style="color: #66cc66;">&lt;LOAD_CONTEXT_NAME&gt;</span>]
                 [(<span style="color: magenta;"><span style="color: cyan;">--temperature</span>|<span style="color: yellow;">-t</span></span>) <span style="color: #66cc66;">&lt;TEMP&gt;</span>] [<span style="color: cyan;">--allow-rxpy-in-run-mode</span>]
                 [<span style="color: cyan;">--skill</span> <span style="color: #66cc66;">&lt;SKILL&gt;</span>]... <span style="color: #66cc66;">&lt;NAME&gt;</span> <span style="color: #66cc66;">&lt;PROMPT&gt;</span></code></pre></div>

**Purpose**
Run a named actor in isolation with simple, manual context.

**Arguments**

- `<NAME>`: The name of the actor to run (required).
- `<PROMPT>`: Prompt text (positional argument).
- `--output/-o FILE`: Output file path.
- `--verbose/-v`: Increase log verbosity (repeatable). Same semantics as the global `-v` flag: no `-v` = normal output only, `-v` = ERROR, `-vv` = WARN, `-vvv` = INFO, `-vvvv` = DEBUG, `-vvvvv` = TRACE.
- `--unsafe/-u`: Allow unsafe configs.
- `--context NAME`: Named actor context to attach.
- `--context-dir PATH`: Context storage location.
- `--load-context FILE`: Load context from JSON.
- `--temperature/-t FLOAT`: Override temperature.
- `--skill NAME`: Skill to attach (repeatable).
- `--allow-rxpy-in-run-mode`: Allow RxPy routes in run mode.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor run <span style="color: cyan;">--context</span> docs local/code_reader <span style="color: #66cc66;">&quot;Summarize the README&quot;</span>

╭─ Run Summary ─────────────────╮
│ <span style="color: cyan; font-weight: 600;">Actor:</span> local/code_reader      │
│ <span style="color: #5599ff; font-weight: 600;">Context:</span> docs                 │
│ <span style="color: yellow; font-weight: 600;">Temperature:</span> 0.2              │
│ <span style="color: #5599ff; font-weight: 600;">Provider:</span> anthropic           │
│ <span style="color: #5599ff; font-weight: 600;">Model:</span> claude-3.5             │
╰───────────────────────────────╯

╭─ Inputs ─────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Prompt:</span> Summarize the README │
│ <span style="color: #66cc66; font-weight: 600;">Context Files:</span> 3             │
│ <span style="color: #5599ff; font-weight: 600;">Context Size:</span> 12.4 KB        │
╰──────────────────────────────╯

╭─ Result Metrics ───────╮
│ <span style="color: #66cc66; font-weight: 600;">Output:</span> stdout         │
│ <span style="color: #5599ff; font-weight: 600;">Input Tokens:</span> 1,524    │
│ <span style="color: #5599ff; font-weight: 600;">Output Tokens:</span> 842     │
│ <span style="color: #5599ff; font-weight: 600;">Duration:</span> 1.8s         │
│ <span style="color: yellow; font-weight: 600;">Cost:</span> $0.0021          │
│ <span style="color: #5599ff; font-weight: 600;">Tool Calls:</span> 0          │
╰────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Summary generated
</code></pre></div>

Running an actor with a custom temperature and skill attachment:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor run <span style="color: cyan;">--temperature</span> 0.2 <span style="color: cyan;">--skill</span> local/code-analysis \
  local/reviewer <span style="color: #66cc66;">&quot;Review the auth module for security issues&quot;</span>

╭─ Actor Run ─────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Actor:</span> local/reviewer               │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> agent                         │
│ <span style="color: #5599ff; font-weight: 600;">Temperature:</span> 0.2                    │
│ <span style="color: #5599ff; font-weight: 600;">Skill:</span> local/code-analysis          │
╰─────────────────────────────────────╯

╭─ Response ────────────────────────────────────────────────────────╮
│ I identified 3 potential security concerns in the auth module:    │
│                                                                   │
│ 1. <span style="color: yellow; font-weight: 600;">Token expiry not validated</span> in `validate_session()` at          │
│    src/auth/session.py:42. The JWT expiry claim is decoded but    │
│    not checked against current time.                              │
│                                                                   │
│ 2. <span style="color: yellow; font-weight: 600;">Missing rate limiting</span> on the `/auth/refresh` endpoint.         │
│    An attacker could brute-force refresh tokens.                  │
│                                                                   │
│ 3. <span style="color: #66cc66; font-weight: 600;">Low severity:</span> Password hashing uses bcrypt with cost=10.       │
│    Consider cost=12 for production deployments.                   │
╰───────────────────────────────────────────────────────────────────╯

╭─ Usage ──────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Tokens:</span> 2,840        │
│ <span style="color: #5599ff; font-weight: 600;">Duration:</span> 4.2s       │
│ <span style="color: #5599ff; font-weight: 600;">Cost:</span> $0.009         │
│ <span style="color: #5599ff; font-weight: 600;">Tool Calls:</span> 6        │
╰──────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Actor run completed
</code></pre></div>

Saving actor output to a file:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor run <span style="color: cyan;">--output</span> review.md local/reviewer <span style="color: #66cc66;">&quot;Write a code review report&quot;</span>

╭─ Actor Run ───────────────╮
│ <span style="color: cyan; font-weight: 600;">Actor:</span> local/reviewer     │
│ <span style="color: #5599ff; font-weight: 600;">Output:</span> review.md         │
│ <span style="color: #5599ff; font-weight: 600;">Tokens:</span> 4,120             │
│ <span style="color: #5599ff; font-weight: 600;">Duration:</span> 6.8s            │
╰───────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Output written to review.md (2.4 KB)
</code></pre></div>

##### agents actor add

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> actor add (<span style="color: magenta;"><span style="color: cyan;">--config</span>|<span style="color: yellow;">-c</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span> [<span style="color: cyan;">--update</span>]</code></pre></div>

**Purpose**
Add a new actor configuration, or replace an existing one with `--update`. The actor is fully defined by the YAML configuration file specified with `--config`. If a local actor with the same name already exists, the command fails unless the `--update` flag is provided, which replaces the existing actor.

**Arguments**

- `--config/-c FILE`: Actor config file (required). The file must fully define the actor, including the `name` field which determines the actor's registered name.
- `--update`: Replace an existing local actor with the same name. Without this flag, attempting to add an actor whose name is already registered will fail.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor add <span style="color: cyan;">--config</span> ./actors/reviewer.yaml

╭─ Actor Added ────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/reviewer │
│ <span style="color: #5599ff; font-weight: 600;">Provider:</span> openai     │
│ <span style="color: magenta; font-weight: 600;">Model:</span> gpt-4         │
│ <span style="color: yellow; font-weight: 600;">Default:</span> yes         │
│ <span style="color: #ff6666; font-weight: 600;">Unsafe:</span> no           │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> graph          │
╰──────────────────────╯

╭─ Config ─────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Path:</span> ./actors/reviewer.yaml │
│ <span style="color: magenta; font-weight: 600;">Hash:</span> 8b3f3d2                │
│ <span style="color: #66cc66; font-weight: 600;">Options:</span> 4                   │
│ <span style="color: #5599ff; font-weight: 600;">Nodes:</span> 3                     │
│ <span style="color: #5599ff; font-weight: 600;">Edges:</span> 4                     │
╰──────────────────────────────╯

╭─ Capabilities ───────╮
│ - code review        │
│ - diff summarization │
│ - lint guidance      │
╰──────────────────────╯

╭─ Tools ────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Tool</span>          <span style="color: cyan; font-weight: 600;">Read-Only</span>  <span style="color: cyan; font-weight: 600;">Safe</span>  │
│ <span style="opacity: 0.7;">────────────  ─────────  ────</span>  │
│ read_file     yes        yes   │
│ search_files  yes        yes   │
│ git_diff      yes        yes   │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Actor added
</code></pre></div>

Attempting to register an actor that already exists (without `--update`):

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor add <span style="color: cyan;">--config</span> ./actors/reviewer.yaml

╭─ Error ─────────────────────────────────────────────────╮
│ <span style="color: #ff6666; font-weight: 600;">Actor already exists:</span> local/reviewer                    │
│ <span style="color: #5599ff; font-weight: 600;">Registered:</span> 2026-02-07 14:22                            │
│ <span style="opacity: 0.7;">Use <span style="color: cyan;">--update</span> to replace the existing actor definition.</span>  │
╰─────────────────────────────────────────────────────────╯

<span style="color: #ff6666; font-weight: 600;">✗ ERROR</span> Actor already registered — use --update to replace
</code></pre></div>

Updating an existing actor with `--update`:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor add <span style="color: cyan;">--config</span> ./actors/reviewer.yaml <span style="color: cyan;">--update</span>

╭─ Actor Updated ─────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/reviewer                │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> agent                         │
│ <span style="color: yellow; font-weight: 600;">Status:</span> updated                     │
╰─────────────────────────────────────╯

╭─ Changes ────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Skills:</span> +1 (local/code-analysis)     │
│ <span style="color: #5599ff; font-weight: 600;">Model:</span> unchanged                     │
│ <span style="color: #5599ff; font-weight: 600;">Graph:</span> updated                       │
╰──────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Actor updated
</code></pre></div>

##### agents actor remove

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> actor remove <span style="color: #66cc66;">&lt;NAME&gt;</span></code></pre></div>

**Purpose**
Remove a custom actor.

**Arguments**

- `<NAME>`: Actor name.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor remove local/reviewer

╭─ Actor Removed ──────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/reviewer │
│ <span style="color: #5599ff; font-weight: 600;">Provider:</span> openai     │
│ <span style="color: magenta; font-weight: 600;">Model:</span> gpt-4         │
╰──────────────────────╯

╭─ Impact ───────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Sessions:</span> 0 affected                       │
│ <span style="color: #5599ff; font-weight: 600;">Active Plans:</span> 0 affected                   │
│ <span style="color: #5599ff; font-weight: 600;">Actions Referencing:</span> 0                     │
╰────────────────────────────────────────────╯

╭─ Cleanup ──────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Config:</span> kept on disk   │
│ <span style="color: yellow; font-weight: 600;">Contexts:</span> 1 orphaned   │
╰────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Actor removed
</code></pre></div>

##### agents actor list

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> actor list</code></pre></div>

**Purpose**
List all actors.

**Arguments**

None.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor list

╭─ Actors ──────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>            <span style="color: cyan; font-weight: 600;">Provider</span>   <span style="color: cyan; font-weight: 600;">Model</span>       <span style="color: cyan; font-weight: 600;">Default</span>  <span style="color: cyan; font-weight: 600;">Built-in</span>  <span style="color: cyan; font-weight: 600;">Unsafe</span>      │
│ <span style="opacity: 0.7;">──────────────  ─────────  ──────────  ───────  ────────  ──────</span>      │
│ local/reviewer  openai     gpt-4       ✓                  no          │
│ openai/gpt-4    openai     gpt-4                ✓         no          │
│ anthropic/3.5   anthropic  claude-3.5           ✓         no          │
╰───────────────────────────────────────────────────────────────────────╯

╭─ Summary ──────────────╮
│ <span style="color: yellow; font-weight: 600;">Total:</span> 3               │
│ <span style="color: #66cc66; font-weight: 600;">Built-in:</span> 2            │
│ <span style="color: #5599ff; font-weight: 600;">Custom:</span> 1              │
│ <span style="color: #ff6666; font-weight: 600;">Unsafe:</span> 0              │
│ <span style="color: #5599ff; font-weight: 600;">Providers Used:</span> 2      │
╰────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 3 actors listed
</code></pre></div>

##### agents actor show

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> actor show <span style="color: #66cc66;">&lt;NAME&gt;</span></code></pre></div>

**Purpose**
Show details for a single actor.

**Arguments**

- `<NAME>`: Actor name.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor show local/reviewer

╭─ Actor Details ────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/reviewer               │
│ <span style="color: #5599ff; font-weight: 600;">Provider:</span> openai                   │
│ <span style="color: magenta; font-weight: 600;">Model:</span> gpt-4                       │
│ <span style="color: yellow; font-weight: 600;">Default:</span> yes                       │
│ <span style="color: #66cc66; font-weight: 600;">Built-in:</span> no                       │
│ <span style="color: #ff6666; font-weight: 600;">Unsafe:</span> no                         │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> graph                        │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-08 12:35          │
│ <span style="color: #66cc66; font-weight: 600;">Updated:</span> 2026-02-08 12:40          │
│ <span style="color: #5599ff; font-weight: 600;">Config:</span> ./actors/reviewer.yaml     │
│ <span style="color: magenta; font-weight: 600;">Config Hash:</span> 9c4e2a1               │
╰────────────────────────────────────╯

╭─ Options ──────────╮
│ - temperature: 0.2 │
│ - max_tokens: 2048 │
│ - top_p: 1.0       │
╰────────────────────╯

╭─ Graph Structure ─╮
│ <span style="color: #5599ff; font-weight: 600;">Nodes:</span> 3          │
│ <span style="color: #5599ff; font-weight: 600;">Edges:</span> 4          │
│ <span style="color: #5599ff; font-weight: 600;">Entry:</span> analyze    │
│ <span style="color: #5599ff; font-weight: 600;">Exit:</span> report      │
╰───────────────────╯

╭─ Tools ────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Tool</span>          <span style="color: cyan; font-weight: 600;">Read-Only</span>  <span style="color: cyan; font-weight: 600;">Safe</span>  │
│ <span style="opacity: 0.7;">────────────  ─────────  ────</span>  │
│ read_file     yes        yes   │
│ search_files  yes        yes   │
│ git_diff      yes        yes   │
╰────────────────────────────────╯

╭─ Access ────────────╮
│ <span style="color: #ff6666; font-weight: 600;">Unsafe:</span> no          │
│ <span style="color: #66cc66; font-weight: 600;">Filesystem:</span> allowed │
│ <span style="color: yellow; font-weight: 600;">Network:</span> restricted │
╰─────────────────────╯

╭─ Usage ─────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Referenced by Actions:</span> 1 (local/code-coverage)  │
│ <span style="color: #5599ff; font-weight: 600;">Active in Sessions:</span> 0                           │
│ <span style="color: #5599ff; font-weight: 600;">Total Runs:</span> 14                                  │
│ <span style="color: #5599ff; font-weight: 600;">Avg Cost/Run:</span> $0.0032                           │
╰─────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Actor loaded
</code></pre></div>

##### agents actor context

**Purpose**
Manage manual context for actor runs. These commands mirror the legacy context behavior but are scoped to an actor context name.

###### agents actor context remove

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> actor context remove [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] (<span style="color: magenta;"><span style="color: cyan;">--all</span>|<span style="color: yellow;">-a</span>|<span style="color: #66cc66;">&lt;NAME&gt;</span></span>)</code></pre></div>

**Purpose**
Remove files or directories from an actor context.

**Arguments**

- `<NAME>`: Context name (positional argument). Use --all/-a to target all contexts.
- `--all, -a`: Target all contexts instead of a named one.
- `--yes, -y`: Skip confirmation prompt.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor context remove docs

╭─ Context Removed ───────────╮
│ <span style="color: cyan; font-weight: 600;">Context:</span> docs               │
│ <span style="color: #66cc66; font-weight: 600;">Status:</span> removed             │
╰─────────────────────────────╯

╭─ Stats ───────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Remaining Size:</span> 48 KB     │
│ <span style="color: #66cc66; font-weight: 600;">Updated:</span> 2026-02-08 13:06 │
╰───────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Context updated
</code></pre></div>

###### agents actor context list

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> actor context list [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]</code></pre></div>

**Purpose**
List files stored in an actor context.

**Arguments**

- `[REGEX]`: Optional regex filter for context names.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor context list docs

╭─ Context Files ──────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>              <span style="color: cyan; font-weight: 600;">Type</span>  <span style="color: cyan; font-weight: 600;">Size</span>     <span style="color: cyan; font-weight: 600;">Added</span>       │
│ <span style="opacity: 0.7;">────────────────  ────  ───────  ──────────</span>  │
│ README.md         file  4.2 KB   02-08 12:10 │
│ docs/overview.md  file  12.8 KB  02-08 12:10 │
│ docs/cli.md       file  9.5 KB   02-08 12:10 │
╰──────────────────────────────────────────────╯

╭─ Stats ───────────────────────╮
│ <span style="color: yellow; font-weight: 600;">Total Files:</span> 3                │
│ <span style="color: #66cc66; font-weight: 600;">Total Size:</span> 26.5 KB           │
│ <span style="color: #5599ff; font-weight: 600;">Estimated Tokens:</span> ~6,600      │
│ <span style="color: #5599ff; font-weight: 600;">Languages:</span> Markdown           │
╰───────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 3 files listed
</code></pre></div>

###### agents actor context show

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> actor context show <span style="color: #66cc66;">&lt;NAME&gt;</span></code></pre></div>

**Purpose**
Show content of a file in an actor context.

**Arguments**

- `<NAME>`: Context name (positional argument).

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor context show docs

╭─ Context Summary ───────────╮
│ <span style="color: cyan; font-weight: 600;">Context:</span> docs               │
│ <span style="color: #66cc66; font-weight: 600;">Files:</span> 3                    │
│ <span style="color: yellow; font-weight: 600;">Total Size:</span> 26.5 KB         │
│ <span style="color: #5599ff; font-weight: 600;">Estimated Tokens:</span> ~6,600    │
│ <span style="color: #5599ff; font-weight: 600;">Created:</span> 2026-02-08 12:10   │
╰─────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Context displayed
</code></pre></div>

###### agents actor context export

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> actor context export (<span style="color: magenta;"><span style="color: cyan;">--output</span>|<span style="color: yellow;">-o</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span> <span style="color: #66cc66;">&lt;NAME&gt;</span></code></pre></div>

**Purpose**
Export a context as JSON.

**Arguments**

- `<NAME>`: Context name (positional argument).
- `--output/-o FILE`: Output file path (required).

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor context export <span style="color: cyan;">--output</span> /tmp/docs-context.json docs

╭─ Context Export ───────────────╮
│ <span style="color: cyan; font-weight: 600;">Context:</span> docs                  │
│ <span style="color: #5599ff; font-weight: 600;">Output:</span> /tmp/docs-context.json │
│ <span style="color: yellow; font-weight: 600;">Items:</span> 12                      │
│ <span style="color: #66cc66; font-weight: 600;">Size:</span> 48 KB                    │
╰────────────────────────────────╯

╭─ Integrity ──────────────────╮
│ <span style="color: magenta; font-weight: 600;">Checksum:</span> sha256:19b2...a7d0 │
│ <span style="color: #5599ff; font-weight: 600;">Compressed:</span> no               │
╰──────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Export completed
</code></pre></div>

###### agents actor context import

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> actor context import [<span style="color: cyan;">--update</span>] (<span style="color: magenta;"><span style="color: cyan;">--input</span>|<span style="color: yellow;">-i</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span> [<span style="color: #66cc66;">&lt;NAME&gt;</span>]</code></pre></div>

**Purpose**
Import a context from JSON.

**Arguments**

- `[NAME]`: Context name (optional, inferred from file if omitted).
- `--input/-i FILE`: Input JSON file (required).
- `--update`: Replace an existing context with the same name.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor context import <span style="color: cyan;">--input</span> /tmp/docs-context.json docs

╭─ Context Import ──────────────╮
│ <span style="color: cyan; font-weight: 600;">Context:</span> docs                 │
│ <span style="color: #5599ff; font-weight: 600;">Input:</span> /tmp/docs-context.json │
│ <span style="color: yellow; font-weight: 600;">Items:</span> 12                     │
╰───────────────────────────────╯

╭─ Merge ───────────╮
│ <span style="color: #5599ff; font-weight: 600;">Strategy:</span> replace │
│ <span style="color: yellow; font-weight: 600;">Conflicts:</span> 0      │
╰───────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Import completed
</code></pre></div>

###### agents actor context clear

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> actor context clear [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] (<span style="color: magenta;"><span style="color: cyan;">--all</span>|<span style="color: yellow;">-a</span>|<span style="color: #66cc66;">&lt;NAME&gt;</span></span>)</code></pre></div>

**Purpose**
Clear all files from a context but keep the context itself.

**Arguments**

- `<NAME>`: Context name (positional argument). Use --all/-a to target all contexts.
- `--all, -a`: Target all contexts instead of a named one.
- `--yes, -y`: Skip confirmation.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor context clear docs

Clear context docs? [y/N]: y

╭─ Context Cleared ────╮
│ <span style="color: cyan; font-weight: 600;">Context:</span> docs        │
│ <span style="color: yellow; font-weight: 600;">Items:</span> 12 removed    │
│ <span style="color: #5599ff; font-weight: 600;">Storage:</span> 48 KB freed │
╰──────────────────────╯

╭─ Retention ────────╮
│ <span style="color: #66cc66; font-weight: 600;">Context:</span> preserved │
│ <span style="color: yellow; font-weight: 600;">Files:</span> removed     │
╰────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Context cleared
</code></pre></div>

#### agents skill

**Purpose**
Manage skills — reusable, namespaced collections of tools. Skills are defined in their own YAML configuration files and registered in the system through these commands. Once registered, skills can be referenced by actors.

##### agents skill add

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> skill add (<span style="color: magenta;"><span style="color: cyan;">--config</span>|<span style="color: yellow;">-c</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span> [<span style="color: cyan;">--update</span>]</code></pre></div>

**Purpose**
Register a new skill. The skill is fully defined by the YAML configuration file specified with `--config`. If a skill with the same name already exists, the command fails unless the `--update` flag is provided, which allows overwriting the existing registration with the new configuration.

**Arguments**

- `--config/-c FILE`: Path to the skill YAML configuration file (required). The file must fully define the skill, including the `name` field which determines the skill's registered name.
- `--update`: Allow overwriting an existing skill registration. Without this flag, attempting to add a skill whose name is already registered will fail.

**Examples**

Registering a new skill:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> skill add <span style="color: cyan;">--config</span> ./skills/devops-toolkit.yaml

╭─ Skill Registered ────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/devops-toolkit                │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Full-stack development tools │
│ <span style="color: #66cc66; font-weight: 600;">Config:</span> ./skills/devops-toolkit.yaml      │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-08 13:10                 │
╰───────────────────────────────────────────╯

╭─ Includes ────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">local/file-ops</span> (registered)   │
│ <span style="color: #5599ff; font-weight: 600;">local/git-ops</span> (registered)    │
│ <span style="color: #5599ff; font-weight: 600;">local/github</span> (registered)     │
╰───────────────────────────────╯

╭─ Tool Sources ────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Source</span>         <span style="color: cyan; font-weight: 600;">Count</span>  <span style="color: cyan; font-weight: 600;">Details</span>                 │
│ <span style="opacity: 0.7;">─────────────  ─────  ───────────────────</span>     │
│ builtin        14     file, dir, git, shell   │
│ mcp            6      github (4), linear (2)  │
│ agent_skill    2      deploy, code-review     │
│ custom         1      run_migrations          │
│ <span style="opacity: 0.7;">─────────────  ─────  ───────────────────</span>     │
│ <span style="color: yellow; font-weight: 600;">Total:</span>         23                             │
╰───────────────────────────────────────────────╯

╭─ MCP Servers ────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">linear:</span> validated (2 tools)      │
╰──────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Skill registered with 23 tools
</code></pre></div>

Attempting to add a skill that already exists (without `--update`):

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> skill add <span style="color: cyan;">--config</span> ./skills/devops-toolkit-v2.yaml

<span style="color: #ff6666; font-weight: 600;">✗ Error:</span> Skill 'local/devops-toolkit' is already registered.

To overwrite the existing configuration, re-run with <span style="color: cyan;">--update</span>:

  agents skill add <span style="color: cyan;">--config</span> ./skills/devops-toolkit-v2.yaml <span style="color: cyan;">--update</span>
</code></pre></div>

Updating an existing skill with `--update`:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> skill add <span style="color: cyan;">--config</span> ./skills/devops-toolkit-v2.yaml <span style="color: cyan;">--update</span>

╭─ Skill Updated ───────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/devops-toolkit                │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Full-stack development tools │
│ <span style="color: #66cc66; font-weight: 600;">Updated:</span> 2026-02-08 14:22                 │
╰───────────────────────────────────────────╯

╭─ Changes ─────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Tools Added:</span> 2                │
│ <span style="color: yellow; font-weight: 600;">Tools Removed:</span> 0              │
│ <span style="color: #5599ff; font-weight: 600;">Tools Modified:</span> 1             │
│ <span style="color: #5599ff; font-weight: 600;">Includes Changed:</span> no          │
│ <span style="color: #5599ff; font-weight: 600;">MCP Servers Changed:</span> no       │
╰───────────────────────────────╯

╭─ Affected Actors ─────────────────────────────╮
│ <span style="color: yellow; font-weight: 600;">Warning:</span> 2 actors reference this skill:       │
│ - local/code-assistant                        │
│ - local/full-stack-assistant                  │
│ These actors will pick up changes on next use │
╰───────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Skill updated (23 → 25 tools)
</code></pre></div>

##### agents skill remove

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> skill remove [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;NAME&gt;</span></code></pre></div>

**Purpose**
Remove a registered skill.

**Arguments**

- `<NAME>`: Skill name to remove.
- `--yes`: Skip confirmation prompt.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> skill remove local/devops-toolkit

Remove skill local/devops-toolkit? [y/N]: y

╭─ Skill Removed ──────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/devops-toolkit           │
│ <span style="color: yellow; font-weight: 600;">Tools:</span> 23 removed from registry      │
│ <span style="color: #5599ff; font-weight: 600;">MCP Servers:</span> 1 connection closed     │
╰──────────────────────────────────────╯

╭─ Dependency Check ─────────────────────────────────╮
│ <span style="color: yellow; font-weight: 600;">Warning:</span> 1 skill includes this skill:              │
│ - local/full-stack-dev (will lose devops tools)    │
│ <span style="color: yellow; font-weight: 600;">Warning:</span> 2 actors reference this skill:            │
│ - local/code-assistant                             │
│ - local/full-stack-assistant                       │
╰────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Skill removed
</code></pre></div>

##### agents skill list

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> skill list [(<span style="color: magenta;"><span style="color: cyan;">--namespace</span>|<span style="color: yellow;">-n</span></span>) <span style="color: #66cc66;">&lt;NS&gt;</span>] [<span style="color: cyan;">--source</span> <span style="color: #66cc66;">&lt;SOURCE&gt;</span>]</code></pre></div>

**Purpose**
List registered skills with optional filters.

**Arguments**

- `--namespace/-n NS`: Filter by namespace.
- `--source SOURCE`: Filter by tool source type (mcp, agent_skill, builtin, custom).

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> skill list

╭─ Skills ────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>                    <span style="color: cyan; font-weight: 600;">Tools</span>  <span style="color: cyan; font-weight: 600;">Includes</span>  <span style="color: cyan; font-weight: 600;">Sources</span>                    │
│ <span style="opacity: 0.7;">──────────────────────  ─────  ────────  ──────────────────────</span>     │
│ local/file-ops          9      0         builtin                    │
│ local/git-ops           4      0         builtin                    │
│ local/github            4      0         mcp                        │
│ local/devops-toolkit    23     3         builtin, mcp, custom       │
│ local/full-stack-dev    25     4         builtin, mcp, custom       │
╰─────────────────────────────────────────────────────────────────────╯

╭─ Summary ─────────╮
│ <span style="color: yellow; font-weight: 600;">Total:</span> 5          │
│ <span style="color: #5599ff; font-weight: 600;">Local:</span> 5          │
│ <span style="color: #5599ff; font-weight: 600;">Server:</span> 0         │
│ <span style="color: #5599ff; font-weight: 600;">Total Tools:</span> 28   │
╰───────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 5 skills listed
</code></pre></div>

##### agents skill show

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> skill show  <span style="color: #66cc66;">&lt;NAME&gt;</span></code></pre></div>

**Purpose**
Show full details for a registered skill, including its includes, tool sources, and capability summary.

**Arguments**

- `<NAME>`: Skill name.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> skill show local/devops-toolkit

╭─ Skill Details ──────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/devops-toolkit                   │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Full-stack development tools    │
│ <span style="color: #66cc66; font-weight: 600;">Config:</span> ./skills/devops-toolkit.yaml         │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-08 13:10                    │
│ <span style="color: #66cc66; font-weight: 600;">Updated:</span> 2026-02-08 14:22                    │
╰──────────────────────────────────────────────╯

╭─ Includes (3) ────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">local/file-ops</span>  → 9 tools (builtin)       │
│ <span style="color: #5599ff; font-weight: 600;">local/git-ops</span>   → 4 tools (builtin)       │
│ <span style="color: #5599ff; font-weight: 600;">local/github</span>    → 4 tools (mcp)           │
╰───────────────────────────────────────────╯

╭─ Direct Tools (6) ────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>              <span style="color: cyan; font-weight: 600;">Source</span>       <span style="color: cyan; font-weight: 600;">Writes</span>  <span style="color: cyan; font-weight: 600;">Checkpoint</span>         │
│ <span style="opacity: 0.7;">────────────────  ───────────  ──────  ──────────</span>         │
│ create_issue      mcp:linear   yes     no                 │
│ list_issues       mcp:linear   no      —                  │
│ deploy-to-staging agent_skill  yes     composite          │
│ code-review       agent_skill  no      —                  │
│ run_migrations    custom       yes     transaction        │
│ shell_execute     builtin      yes     snapshot           │
╰───────────────────────────────────────────────────────────╯

╭─ MCP Servers (1) ───────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">linear:</span> stdio, 2 tools, connected   │
╰─────────────────────────────────────╯

╭─ Capability Summary ──────────╮
│ <span style="color: #5599ff; font-weight: 600;">Total Tools:</span> 23               │
│ <span style="color: #66cc66; font-weight: 600;">Read-Only:</span> 10                 │
│ <span style="color: yellow; font-weight: 600;">Writes:</span> 13                    │
│ <span style="color: #66cc66; font-weight: 600;">Checkpointable:</span> 10            │
│ <span style="color: yellow; font-weight: 600;">Has Side Effects:</span> 3           │
│ <span style="color: #5599ff; font-weight: 600;">Requires Approval:</span> 1          │
╰───────────────────────────────╯

╭─ Referenced By ───────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Actors:</span> local/code-assistant      │
│ <span style="color: #5599ff; font-weight: 600;">Skills:</span> local/full-stack-dev      │
╰───────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Skill loaded
</code></pre></div>

##### agents skill tools

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> skill tools <span style="color: #66cc66;">&lt;NAME&gt;</span></code></pre></div>

**Purpose**
List all tools provided by a skill, including those inherited from included skills (the flattened tool set).

**Arguments**

- `<NAME>`: Skill name.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> skill tools local/devops-toolkit

╭─ Tools for local/devops-toolkit ─────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Tool</span>               <span style="color: cyan; font-weight: 600;">Source</span>       <span style="color: cyan; font-weight: 600;">From Skill</span>      <span style="color: cyan; font-weight: 600;">Read-Only</span>  <span style="color: cyan; font-weight: 600;">Writes</span>  <span style="color: cyan; font-weight: 600;">Checkpoint</span>            │
│ <span style="opacity: 0.7;">─────────────────  ───────────  ──────────────  ─────────  ──────  ──────────</span>            │
│ read_file          builtin      local/file-ops  ✓          —       —                     │
│ write_file         builtin      local/file-ops  —          ✓       file                  │
│ edit_file          builtin      local/file-ops  —          ✓       file                  │
│ delete_file        builtin      local/file-ops  —          ✓       file                  │
│ move_file          builtin      local/file-ops  —          ✓       file                  │
│ copy_file          builtin      local/file-ops  —          ✓       file                  │
│ create_directory   builtin      local/file-ops  —          ✓       file                  │
│ list_directory     builtin      local/file-ops  ✓          —       —                     │
│ delete_directory   builtin      local/file-ops  —          ✓       file                  │
│ git_status         builtin      local/git-ops   ✓          —       —                     │
│ git_diff           builtin      local/git-ops   ✓          —       —                     │
│ git_log            builtin      local/git-ops   ✓          —       —                     │
│ git_blame          builtin      local/git-ops   ✓          —       —                     │
│ create_issue       mcp:github   local/github    —          ✓       no                    │
│ create_pr          mcp:github   local/github    —          ✓       no                    │
│ list_repos         mcp:github   local/github    ✓          —       —                     │
│ get_file_contents  mcp:github   local/github    ✓          —       —                     │
│ create_issue       mcp:linear   (direct)        —          ✓       no                    │
│ list_issues        mcp:linear   (direct)        ✓          —       —                     │
│ run_migrations     custom       (direct)        —          ✓       transaction           │
│ deploy-to-staging  agent_skill  (direct)        —          ✓       composite             │
│ code-review        agent_skill  (direct)        ✓          —       —                     │
│ shell_execute      builtin      (direct)        —          ✓       snapshot              │
╰──────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Summary ──────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Total:</span> 23                  │
│ <span style="color: #66cc66; font-weight: 600;">From Includes:</span> 17          │
│ <span style="color: #5599ff; font-weight: 600;">Direct:</span> 6                  │
│ <span style="color: #66cc66; font-weight: 600;">Read-Only:</span> 10              │
│ <span style="color: yellow; font-weight: 600;">Writes:</span> 13                 │
│ <span style="color: #66cc66; font-weight: 600;">Checkpointable:</span> 10         │
╰────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 23 tools listed
</code></pre></div>

#### agents tool

**Purpose**
Manage tools — namespaced, independently registered, callable operations. Tools are defined in their own YAML configuration files and registered in the system through these commands. Once registered, tools can be referenced by name in skills (as part of a tool collection) and in actor graphs (as tool nodes).

##### agents tool add

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> tool add (<span style="color: magenta;"><span style="color: cyan;">--config</span>|<span style="color: yellow;">-c</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span> [<span style="color: cyan;">--update</span>]</code></pre></div>

**Purpose**
Register a new tool. The tool is fully defined by the YAML configuration file specified with `--config`. If a tool with the same name already exists, the command fails unless the `--update` flag is provided, which allows overwriting the existing registration with the new configuration.

**Arguments**

- `--config/-c FILE`: Path to the tool YAML configuration file (required). The file must fully define the tool, including the `name` field which determines the tool's registered name.
- `--update`: Allow overwriting an existing tool registration. Without this flag, attempting to add a tool whose name is already registered will fail.

**Examples**

Registering a new tool:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> tool add <span style="color: cyan;">--config</span> ./tools/run-migrations.yaml

╭─ Tool Registered ────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/run-migrations                   │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Run database migrations         │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> custom                               │
│ <span style="color: #66cc66; font-weight: 600;">Config:</span> ./tools/run-migrations.yaml          │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-09 10:15                    │
╰──────────────────────────────────────────────╯

╭─ Capability ─────────────────────╮
│ <span style="color: yellow; font-weight: 600;">Writes:</span> true                     │
│ <span style="color: #5599ff; font-weight: 600;">Write Scope:</span> database:migrations │
│ <span style="color: #66cc66; font-weight: 600;">Checkpointable:</span> true             │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoint Scope:</span> transaction    │
│ <span style="color: yellow; font-weight: 600;">Side Effects:</span> schema_mutation    │
╰──────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Tool registered
</code></pre></div>

Attempting to add a tool that already exists (without `--update`):

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> tool add <span style="color: cyan;">--config</span> ./tools/run-migrations-v2.yaml

<span style="color: #ff6666; font-weight: 600;">✗ Error:</span> Tool 'local/run-migrations' is already registered.

To overwrite the existing configuration, re-run with <span style="color: cyan;">--update</span>:

  agents tool add <span style="color: cyan;">--config</span> ./tools/run-migrations-v2.yaml <span style="color: cyan;">--update</span>
</code></pre></div>

Updating an existing tool with `--update`:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> tool add <span style="color: cyan;">--config</span> ./tools/db-migrate.yaml <span style="color: cyan;">--update</span>

╭─ Tool Updated ─────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/db-migrate                     │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> custom (Python)                    │
│ <span style="color: yellow; font-weight: 600;">Status:</span> updated (was version 1 → now 2)    │
╰────────────────────────────────────────────╯

╭─ Changes ─────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Input Schema:</span> modified (added batch_size)     │
│ <span style="color: #5599ff; font-weight: 600;">Capabilities:</span> unchanged (writes, checkpoint)  │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> updated                          │
╰───────────────────────────────────────────────╯

╭─ References ──────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Skills:</span> 1 (local/db-tools)    │
│ <span style="color: #5599ff; font-weight: 600;">Actors:</span> 0                     │
│ <span style="opacity: 0.7;">Referencing skills will use</span>   │
│ <span style="opacity: 0.7;">the updated definition.</span>       │
╰───────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Tool updated
</code></pre></div>

##### agents tool remove

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> tool remove [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;NAME&gt;</span></code></pre></div>

**Purpose**
Remove a registered tool. Because Validations are a subtype of Tool and share the same registry, this command also removes validations. When removing a Validation, all attachments are automatically detached before the entry is removed from the registry.

**Arguments**

- `<NAME>`: Tool or validation name to remove.
- `--yes`: Skip confirmation prompt.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> tool remove local/run-migrations

Remove tool local/run-migrations? [y/N]: y

╭─ Tool Removed ────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/run-migrations        │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> custom                    │
╰───────────────────────────────────╯

╭─ References ──────────────────────────────────────╮
│ <span style="color: yellow; font-weight: 600;">Warning:</span> This tool is referenced by:              │
│ - Skill: local/devops-toolkit                     │
│ - Actor graph node: code_executor.run_db_migrate  │
│ These references will break until resolved.       │
╰───────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Tool removed
</code></pre></div>

When removing a validation, attachments are cleaned up automatically:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> tool remove local/check-bundle-size

Remove validation local/check-bundle-size? [y/N]: y

╭─ Validation Removed ─────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/check-bundle-size                    │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Check bundle size (advisory)       │
╰──────────────────────────────────────────────────╯

╭─ Detached From ────────────────────────────────────────────╮
│ <span style="color: yellow; font-weight: 600;">Warning:</span> This validation had 2 attachments:               │
│ - local/api-repo (scope: project local/api-service)       │
│ - local/api-repo (direct)                                 │
│ These attachments have been removed.                      │
╰───────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation removed
</code></pre></div>

##### agents tool list

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> tool list [(<span style="color: magenta;"><span style="color: cyan;">--namespace</span>|<span style="color: yellow;">-n</span></span>) <span style="color: #66cc66;">&lt;NS&gt;</span>] [<span style="color: cyan;">--source</span> <span style="color: #66cc66;">&lt;SOURCE&gt;</span>] [<span style="color: cyan;">--type</span> (<span style="color: magenta;">tool|validation</span>)] [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]</code></pre></div>

**Purpose**
List registered tools with optional filters. Because Validations are a subtype of Tool and share the same registry, this command lists both plain tools and validations. Use `--type validation` to show only validations, or `--type tool` to show only plain tools. When `--type` is omitted, both are listed with a `Type` column distinguishing them.

**Arguments**

- `--namespace/-n NS`: Filter by namespace.
- `--source SOURCE`: Filter by tool source type (mcp, agent_skill, builtin, custom).
- `--type TYPE`: Filter by entry type: `tool` (plain tools only) or `validation` (validations only). When omitted, both are listed.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> tool list <span style="color: cyan;">--namespace</span> local

╭─ Tools ─────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>                       <span style="color: cyan; font-weight: 600;">Type</span>        <span style="color: cyan; font-weight: 600;">Source</span>   <span style="color: cyan; font-weight: 600;">Read-Only</span>  <span style="color: cyan; font-weight: 600;">Writes</span>    │
│ <span style="opacity: 0.7;">─────────────────────────  ──────────  ───────  ─────────  ──────</span>    │
│ local/run-migrations       tool        custom   —          ✓         │
│ local/validate-api-compat  tool        custom   —          ✓         │
│ local/create-subplan       tool        custom   —          ✓         │
│ local/deploy-staging       tool        agent    —          ✓         │
│ local/run-tests            validation  custom   ✓          —         │
│ local/lint-check           validation  custom   ✓          —         │
│ local/check-bundle-size    validation  custom   ✓          —         │
│ local/type-check           validation  custom   ✓          —         │
╰─────────────────────────────────────────────────────────────────────────╯

╭─ Summary ────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Total:</span> 8                 │
│ <span style="color: #5599ff; font-weight: 600;">Tools:</span> 4                 │
│ <span style="color: #5599ff; font-weight: 600;">Validations:</span> 4           │
│ <span style="color: #66cc66; font-weight: 600;">Read-Only:</span> 4             │
│ <span style="color: yellow; font-weight: 600;">Writes:</span> 4                │
╰──────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 8 tools listed
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> tool list <span style="color: cyan;">--type</span> validation <span style="color: cyan;">--namespace</span> local

╭─ Validations ────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>                       <span style="color: cyan; font-weight: 600;">Source</span>   <span style="color: cyan; font-weight: 600;">Mode</span>          <span style="color: cyan; font-weight: 600;">Attachments</span>                │
│ <span style="opacity: 0.7;">─────────────────────────  ───────  ────────────  ────────────────────────</span>   │
│ local/run-tests            custom   required      2 (1 direct, 1 project)    │
│ local/lint-check           custom   required      1 (1 direct)               │
│ local/check-bundle-size    custom   informational 1 (1 project)              │
│ local/type-check           custom   required      2 (2 project)              │
╰──────────────────────────────────────────────────────────────────────────────────╯

╭─ Summary ──────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Total:</span> 4               │
│ <span style="color: #66cc66; font-weight: 600;">Required:</span> 3            │
│ <span style="color: yellow; font-weight: 600;">Informational:</span> 1       │
╰────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 4 validations listed
</code></pre></div>

##### agents tool show

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> tool show <span style="color: #66cc66;">&lt;NAME&gt;</span></code></pre></div>

**Purpose**
Show full details for a registered tool, including its schema, capability metadata, and where it is referenced. Because Validations are a subtype of Tool and share the same registry, this command also shows validation details. When showing a Validation, additional validation-specific fields are displayed: `Mode` (required/informational) and `Attached To` (listing each resource attachment with its scope — direct, project-scoped, or plan-scoped).

**Arguments**

- `<NAME>`: Tool or validation name.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> tool show local/run-migrations

╭─ Tool Details ───────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/run-migrations                   │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Run database migrations         │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> custom                               │
│ <span style="color: #66cc66; font-weight: 600;">Config:</span> ./tools/run-migrations.yaml          │
│ <span style="color: #66cc66; font-weight: 600;">Registered:</span> 2026-02-09 10:15                 │
╰──────────────────────────────────────────────╯

╭─ Input Schema ─────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">direction</span>: string (required) enum: [up, down]  │
│ <span style="color: #5599ff; font-weight: 600;">count</span>: integer (default: 1)                    │
╰────────────────────────────────────────────────╯

╭─ Capability ──────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Read-Only:</span> false                  │
│ <span style="color: yellow; font-weight: 600;">Writes:</span> true                      │
│ <span style="color: #5599ff; font-weight: 600;">Write Scope:</span> database:migrations  │
│ <span style="color: #66cc66; font-weight: 600;">Checkpointable:</span> true              │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoint Scope:</span> transaction     │
│ <span style="color: yellow; font-weight: 600;">Side Effects:</span> schema_mutation     │
│ <span style="color: #5599ff; font-weight: 600;">Idempotent:</span> false                 │
╰───────────────────────────────────╯

╭─ Referenced By ───────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Skills:</span>                               │
│   - local/devops-toolkit              │
│ <span style="color: #5599ff; font-weight: 600;">Actor Graph Nodes:</span>                    │
│   - code_executor.run_db_migrate      │
╰───────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Tool details loaded
</code></pre></div>

When showing a Validation, the output includes validation-specific sections:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> tool show local/run-tests

╭─ Validation Details ──────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/run-tests                             │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> validation                                  │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Run unit tests with coverage          │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> custom                                    │
│ <span style="color: #66cc66; font-weight: 600;">Mode:</span> required                                    │
│ <span style="color: #66cc66; font-weight: 600;">Config:</span> ./validations/run-tests.yaml              │
│ <span style="color: #66cc66; font-weight: 600;">Registered:</span> 2026-02-09 10:15                      │
╰───────────────────────────────────────────────────╯

╭─ Input Schema ─────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">coverage_threshold</span>: integer (default: 80)          │
╰────────────────────────────────────────────────────╯

╭─ Output Schema (Validation Return Format) ─────────╮
│ <span style="color: #66cc66; font-weight: 600;">passed</span>: boolean (required)                         │
│ <span style="color: #5599ff; font-weight: 600;">message</span>: string (optional)                         │
│ <span style="color: #5599ff; font-weight: 600;">data</span>: object (optional, arbitrary structure)        │
╰────────────────────────────────────────────────────╯

╭─ Capability ──────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Read-Only:</span> true (enforced)         │
│ <span style="color: #66cc66; font-weight: 600;">Checkpointable:</span> false (enforced)   │
│ <span style="color: yellow; font-weight: 600;">Timeout:</span> 600s                      │
╰───────────────────────────────────╯

╭─ Attached To ─────────────────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">local/api-repo</span> (direct, always active)                           │
│   <span style="opacity: 0.7;">(attachment: 01HXM5B2C3D4E5F6G7H8J9K0L1)</span>                      │
│ <span style="color: #5599ff; font-weight: 600;">local/api-repo</span> (scope: project local/api-service)                │
│   <span style="opacity: 0.7;">(attachment: 01HXM5A1B2C3D4E5F6G7H8J9K0)</span>                      │
╰──────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation details loaded
</code></pre></div>

#### agents validation

**Purpose**
Register and attach validations — a specialized subtype of Tool that extends the Tool class with pass/fail semantics and attachment scoping. A Validation inherits all base Tool properties (name, source, input_schema, capability, resource bindings, lifecycle hooks, etc.) and adds: a `mode` field (`required` or `informational`), and a structured JSON return format with a mandatory `passed` boolean, an optional `message` string, and an optional `data` object for arbitrary informational output. Since Validation extends Tool, it shares the same backing sources (custom, MCP, agent_skill, builtin) plus the additional `wrapped` source type for Validations that wrap an existing Tool via the `wraps` field. It uses the same YAML configuration format (with an additional `validation` block and optional `wraps`/`transform` fields), and the same registries and resolution mechanisms. Validations are always read-only (`writes` is always `false`, `checkpointable` is always `false`).

Because Validations are a subtype of Tool and share the same Tool Registry and naming namespace, only validation-specific operations have dedicated subcommands here: `add` (registration with validation-specific fields like `mode`), `attach`, and `detach`. General tool operations — listing, inspection, and removal — are handled through the `agents tool` commands:

- **List validations**: `agents tool list --type validation`
- **Show validation details**: `agents tool show <NAME>` (displays validation-specific fields when the entry is a Validation)
- **Remove a validation**: `agents tool remove <NAME>` (automatically removes all attachments)

A validation is always attached to a resource. The optional `--project` or `--plan` flag controls the scope of the attachment:
- **Direct attachment** (no scope flag): The validation is always active for that resource, regardless of which plan or project accesses it. Use `agents validation attach <RESOURCE> <VALIDATION> [args...]`.
- **Project-scoped attachment** (`--project`): The validation only runs for that resource when it is being interacted with through the specified project. Use `agents validation attach --project <PROJECT> <RESOURCE> <VALIDATION> [args...]`.
- **Plan-scoped attachment** (`--plan`): The validation only runs for that resource when it is being interacted with through the specified plan. Use `agents validation attach --plan <PLAN_ID> <RESOURCE> <VALIDATION> [args...]`.

The same validation can be attached to the same resource multiple times — directly, through different projects, and through different plans — and since validations accept arguments, attaching the same validation to the same resource multiple times with different arguments is a common and useful configuration pattern (e.g., running the same test suite with different coverage thresholds for different projects).

Each `attach` invocation returns a system-assigned **attachment ULID** uniquely identifying that attachment. Use this ULID with `agents validation detach <ATTACHMENT_ID>` to remove a specific attachment.

When multiple attachment scopes apply, the union of all applicable validations is used. A resource with a directly-attached validation will always have that validation run, plus any additional validations attached through the active project or plan.

##### agents validation add

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> validation add (<span style="color: magenta;"><span style="color: cyan;">--config</span>|<span style="color: yellow;">-c</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span> [<span style="color: cyan;">--update</span>]</code></pre></div>

**Purpose**
Register a new validation. The validation is fully defined by the YAML configuration file specified with `--config`. The validation is registered in the shared Tool Registry under the name specified in the config file; the name must not conflict with any existing tool or validation. If a validation with the same name already exists, the command fails unless `--update` is provided. The validation YAML may use `wraps` to reference an existing Tool, reusing its implementation and interpreting its output through a `transform` function (see Tool Wrapping under Core Concepts > Validation). When `wraps` is used, the wrapped Tool must already be registered.

**Arguments**

- `--config/-c FILE`: Path to the validation YAML configuration file (required). The file must fully define the validation, including the `name` field which determines the validation's registered name, the `validation.mode` field (`required` or `informational`), and either inline implementation (`source` + `code`) or wrapping (`wraps` + `transform`).
- `--update`: Allow overwriting an existing validation registration.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation add <span style="color: cyan;">--config</span> ./validations/run-tests.yaml

╭─ Validation Registered ────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/run-tests                                  │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Run unit tests with coverage               │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> custom                                         │
│ <span style="color: #66cc66; font-weight: 600;">Mode:</span> required                                         │
│ <span style="color: #66cc66; font-weight: 600;">Config:</span> ./validations/run-tests.yaml                   │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-09 10:15                              │
╰────────────────────────────────────────────────────────╯

╭─ Capability ────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Read-Only:</span> true (enforced)         │
│ <span style="color: #66cc66; font-weight: 600;">Checkpointable:</span> false (enforced)   │
│ <span style="color: yellow; font-weight: 600;">Timeout:</span> 600s                      │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation registered
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation add <span style="color: cyan;">--config</span> ./validations/lint-check.yaml

╭─ Validation Registered ──────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/lint-check               │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Lint check              │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> custom                       │
│ <span style="color: #66cc66; font-weight: 600;">Mode:</span> required                       │
│ <span style="color: yellow; font-weight: 600;">Timeout:</span> 300s                        │
╰───────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation registered
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation add <span style="color: cyan;">--config</span> ./validations/check-bundle-size.yaml

╭─ Validation Registered ───────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/check-bundle-size                     │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Check bundle size (advisory)        │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> custom                                    │
│ <span style="color: yellow; font-weight: 600;">Mode:</span> informational                              │
│ <span style="color: yellow; font-weight: 600;">Timeout:</span> 300s                                    │
╰───────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation registered
</code></pre></div>

##### agents validation attach

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> validation attach [<span style="color: cyan;">--project</span> <span style="color: #66cc66;">&lt;PROJECT&gt;</span>|<span style="color: cyan;">--plan</span> <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span>]
                         <span style="color: #66cc66;">&lt;RESOURCE&gt;</span> <span style="color: #66cc66;">&lt;VALIDATION&gt;</span> [<span style="color: #66cc66;">&lt;ARGS&gt;</span>...]</code></pre></div>

**Purpose**
Attach a registered validation to a resource, with an optional project or plan scope. A resource is always required — validations are fundamentally resource-centric. The optional `--project` or `--plan` flag narrows when the validation is active: without either flag, the validation runs whenever any plan or project accesses the resource; with `--project`, it only runs when the resource is accessed through that project; with `--plan`, it only runs when the resource is accessed through that plan. At most one scope flag may be provided per invocation.

The command returns a system-assigned **attachment ULID** that uniquely identifies this specific attachment association. This ULID is used to detach the validation later via `agents validation detach <ATTACHMENT_ID>`. The same validation can be attached to the same resource multiple times — directly, through different projects, through different plans, and even to the same resource and scope multiple times with different arguments.

**Arguments**

- `<RESOURCE>`: Resource name or ULID to attach the validation to (positional argument, required).
- `<VALIDATION>`: Validation name (positional argument, required).
- `--project PROJECT`: Scope the attachment to a specific project. The validation only runs for this resource when it is accessed through the specified project.
- `--plan PLAN_ID`: Scope the attachment to a specific plan. The validation only runs for this resource when it is accessed through the specified plan.
- `<ARGS>...`: Optional validation-specific arguments (passed through to the validation tool's `input_schema` at execution time).

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> local/api-service local/api-repo local/run-tests

╭─ Validation Attached ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Attachment ID:</span> 01HXM5A1B2C3D4E5F6G7H8J9K0       │
│ <span style="color: cyan; font-weight: 600;">Validation:</span> local/run-tests                              │
│ <span style="color: #5599ff; font-weight: 600;">Mode:</span> required                                          │
│ <span style="color: #66cc66; font-weight: 600;">Resource:</span> local/api-repo                                │
│ <span style="color: #66cc66; font-weight: 600;">Scope:</span> project local/api-service                        │
╰────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach local/api-repo local/lint-check

╭─ Validation Attached ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Attachment ID:</span> 01HXM5B2C3D4E5F6G7H8J9K0L1       │
│ <span style="color: cyan; font-weight: 600;">Validation:</span> local/lint-check                             │
│ <span style="color: #5599ff; font-weight: 600;">Mode:</span> required                                          │
│ <span style="color: #66cc66; font-weight: 600;">Resource:</span> local/api-repo                                │
│ <span style="color: #66cc66; font-weight: 600;">Scope:</span> direct (always active)                           │
│ <span style="opacity: 0.7;">This validation will run for ALL plans/projects</span>           │
│ <span style="opacity: 0.7;">that access this resource.</span>                               │
╰────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached
</code></pre></div>

Attaching with validation-specific arguments:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> local/api-service local/api-repo local/run-tests <span style="color: cyan;">--coverage-threshold</span> 90

╭─ Validation Attached ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Attachment ID:</span> 01HXM5C3D4E5F6G7H8J9K0L1M2       │
│ <span style="color: cyan; font-weight: 600;">Validation:</span> local/run-tests                              │
│ <span style="color: #5599ff; font-weight: 600;">Mode:</span> required                                          │
│ <span style="color: #66cc66; font-weight: 600;">Resource:</span> local/api-repo                                │
│ <span style="color: #66cc66; font-weight: 600;">Scope:</span> project local/api-service                        │
│ <span style="color: #5599ff; font-weight: 600;">Args:</span> coverage_threshold=90                              │
╰────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached
</code></pre></div>

##### agents validation detach

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> validation detach [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;ATTACHMENT_ID&gt;</span></code></pre></div>

**Purpose**
Detach a validation by its attachment ULID. The attachment ULID is returned by `agents validation attach` when the attachment is created and is also displayed by `agents tool show <VALIDATION>` in the "Attached To" section. Because a validation may be attached to the same resource multiple times — directly, through different projects, through different plans, or even to the same resource and scope with different arguments — the ULID uniquely identifies the specific attachment to remove. The validation itself remains registered in the Tool Registry; only the attachment association is removed.

**Arguments**

- `<ATTACHMENT_ID>`: The ULID of the attachment to remove (returned by `agents validation attach`).
- `--yes, -y`: Skip confirmation prompt.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation detach 01HXM5A1B2C3D4E5F6G7H8J9K0

Detach validation local/run-tests from resource local/api-repo (scope: project local/api-service)? [y/N]: y

╭─ Validation Detached ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Attachment ID:</span> 01HXM5A1B2C3D4E5F6G7H8J9K0        │
│ <span style="color: cyan; font-weight: 600;">Validation:</span> local/run-tests                               │
│ <span style="color: #5599ff; font-weight: 600;">Resource:</span> local/api-repo                                  │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> project local/api-service                          │
╰─────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation detached
</code></pre></div>

#### agents resource type

**Purpose**
Manage resource type definitions. Resource types are schema-level definitions that constrain categories of resources — they define what CLI arguments `agents resource add <type>` accepts, whether instances are physical or virtual, allowed parent/child types, auto-discovery behavior, sandbox strategy, and handler implementation. Built-in types (`git-checkout`, `git`, `fs-mount`, `fs-directory`, and their child types) are hardcoded. Custom types are defined in YAML configuration files and extend the system with new `agents resource add` subcommands.

##### agents resource type add

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> resource type add (<span style="color: magenta;"><span style="color: cyan;">--config</span>|<span style="color: yellow;">-c</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span> [<span style="color: cyan;">--update</span>]</code></pre></div>

**Purpose**
Register a new custom resource type. The resource type is fully defined by the YAML configuration file specified with `--config`.

**Arguments**

- `--config/-c FILE`: Path to the resource type YAML configuration file (required). The file must fully define the resource type, including the `name` field which determines the type's registered name.
- `--update`: If the type name already exists, overwrite it. Without this flag, adding a duplicate name fails with an error.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource type add <span style="color: cyan;">--config</span> ./resource-types/svn.yaml

╭─ Resource Type ────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/svn                    │
│ <span style="color: #5599ff; font-weight: 600;">Physical/Virtual:</span> physical         │
│ <span style="color: #5599ff; font-weight: 600;">User Addable:</span> yes                  │
│ <span style="color: #66cc66; font-weight: 600;">Registered:</span> 2026-02-09 10:15       │
╰────────────────────────────────────╯

╭─ CLI Arguments ────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Argument</span>      <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>    │
│ <span style="opacity: 0.7;">────────────  ────────  ─────────────</span>  │
│ <span style="color: cyan;">--url</span>         yes       Repository URL │
│ <span style="color: cyan;">--checkout</span>    no        Local checkout │
╰────────────────────────────────────────╯

╭─ Child Types ──────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Auto-discover:</span> svn-revision, svn-file  │
│ <span style="color: #5599ff; font-weight: 600;">Manual link:</span> fs-mount                  │
╰────────────────────────────────────────╯

╭─ Sandbox ──────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Strategy:</span> copy_on_write        │
│ <span style="color: #5599ff; font-weight: 600;">Handler:</span> SVNHandler (custom)   │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource type registered
<span style="color: cyan; font-weight: 600;">ℹ</span> New subcommand available: agents resource add local/svn
</code></pre></div>

##### agents resource type remove

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> resource type remove [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;NAME&gt;</span></code></pre></div>

**Purpose**
Remove a custom resource type. Built-in types cannot be removed. Fails if any registered resources use this type.

**Arguments**

- `<NAME>`: Resource type name.
- `--yes`: Skip confirmation prompt.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource type remove local/svn

Remove resource type local/svn? [y/N]: y

╭─ Resource Type Removed ───────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/svn               │
│ <span style="color: yellow; font-weight: 600;">Resources Using:</span> 0            │
│ <span style="color: #5599ff; font-weight: 600;">Subcommand Removed:</span> yes       │
╰───────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource type removed
</code></pre></div>

##### agents resource type list

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> resource type list [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]</code></pre></div>

**Purpose**
List all registered resource types (built-in and custom).

**Arguments**

None (use the global `--format` option to control output format).

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource type list

╭─ Resource Types ──────────────────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>                 <span style="color: cyan; font-weight: 600;">Source</span>    <span style="color: cyan; font-weight: 600;">Phys/Virt</span>  <span style="color: cyan; font-weight: 600;">Addable</span>  <span style="color: cyan; font-weight: 600;">Auto-children</span>                                  │
│ <span style="opacity: 0.7;">───────────────────  ────────  ─────────  ───────  ──────────────────────────────────────</span>         │
│ git-checkout        built-in  physical   yes      git, fs-directory                               │
│ git                 built-in  physical   yes      git-remote, git-branch, git-tag,                │
│                                                    git-commit, git-stash, git-submodule           │
│ git-remote          built-in  physical   no       (none)                                          │
│ git-branch          built-in  physical   no       git-commit                                      │
│ git-tag             built-in  physical   no       (none)                                          │
│ git-commit          built-in  physical   no       git-tree                                        │
│ git-tree            built-in  physical   no       git-tree-entry                                  │
│ git-tree-entry      built-in  physical   no       (none)                                          │
│ git-stash           built-in  physical   no       (none)                                          │
│ git-submodule       built-in  physical   no       (none)                                          │
│ fs-mount            built-in  physical   yes      fs-directory                                    │
│ fs-directory        built-in  physical   yes      fs-file, fs-directory,                          │
│                                                    fs-symlink, fs-hardlink                        │
│ fs-file             built-in  physical   no       (none)                                          │
│ fs-symlink          built-in  physical   no       (none)                                          │
│ fs-hardlink         built-in  physical   no       (none)                                          │
│ file                built-in  virtual    no       (none)                                          │
│ directory           built-in  virtual    no       (none)                                          │
│ symlink             built-in  virtual    no       (none)                                          │
│ commit              built-in  virtual    no       (none)                                          │
│ branch              built-in  virtual    no       (none)                                          │
│ tag                 built-in  virtual    no       (none)                                          │
│ remote              built-in  virtual    no       (none)                                          │
│ submodule           built-in  virtual    no       (none)                                          │
│ tree                built-in  virtual    no       (none)                                          │
│ local/svn           custom    physical   yes      svn-revision, svn-file                          │
╰───────────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Summary ─────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Built-in:</span> 24              │
│ <span style="color: #5599ff; font-weight: 600;">Custom:</span> 1                 │
│ <span style="color: #66cc66; font-weight: 600;">User Addable:</span> 4           │
╰───────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 25 resource types listed
</code></pre></div>

##### agents resource type show

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> resource type show <span style="color: #66cc66;">&lt;NAME&gt;</span></code></pre></div>

**Purpose**
Show detailed information about a resource type, including its full schema.

**Arguments**

- `<NAME>`: Resource type name.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource type show git-checkout

╭─ Resource Type ──────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> git-checkout                                                   │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> built-in                                                     │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> A locally checked-out git repository with worktree      │
│ <span style="color: #5599ff; font-weight: 600;">Physical/Virtual:</span> physical                                           │
│ <span style="color: #66cc66; font-weight: 600;">User Addable:</span> yes                                                    │
╰──────────────────────────────────────────────────────────────────────╯

╭─ CLI Arguments (agents resource add git-checkout) ─────────────────╮
│ <span style="color: cyan; font-weight: 600;">Argument</span>    <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Type</span>    <span style="color: cyan; font-weight: 600;">Description</span>                          │
│ <span style="opacity: 0.7;">──────────  ────────  ──────  ──────────────────────────────</span>       │
│ <span style="color: cyan;">--path</span>      yes       path    Local checkout directory             │
│ <span style="color: cyan;">--branch</span>    no        string  Default branch (default: main)       │
╰────────────────────────────────────────────────────────────────────╯

╭─ Parent Types ───────────────╮
│ Allowed: (any, top-level OK) │
╰──────────────────────────────╯

╭─ Child Types ────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Type</span>           <span style="color: cyan; font-weight: 600;">Auto</span>  <span style="color: cyan; font-weight: 600;">Manual Link</span>  <span style="color: cyan; font-weight: 600;">Description</span>                    │
│ <span style="opacity: 0.7;">─────────────  ────  ───────────  ──────────────────────────</span>     │
│ git            yes   no           Repo object DB and history     │
│ fs-directory   yes   no           Worktree root directory        │
╰──────────────────────────────────────────────────────────────────╯

╭─ Sandbox ──────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Strategy:</span> git_worktree         │
│ <span style="color: #5599ff; font-weight: 600;">Checkpointable:</span> yes            │
│ <span style="color: #5599ff; font-weight: 600;">Handler:</span> GitCheckoutHandler    │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource type details loaded
</code></pre></div>

#### agents resource

**Purpose**
Manage independently registered resources. Resources represent anything that can be read, written, or queried — git repositories, filesystems, databases, APIs, and more. Resources are registered independently of projects and linked to one or more projects via `agents project link-resource`. Resources form a directed acyclic graph (DAG) with parent/child relationships, and child resources are often auto-discovered when a parent resource is registered.

##### agents resource add

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> resource add [(<span style="color: magenta;"><span style="color: cyan;">--description</span>|<span style="color: yellow;">-d</span></span>) <span style="color: #66cc66;">&lt;DESC&gt;</span>] [<span style="color: cyan;">--update</span>] <span style="color: #66cc66;">&lt;TYPE&gt;</span> <span style="color: #66cc66;">&lt;NAME&gt;</span> [type-specific-flags...]</code></pre></div>

**Purpose**
Register a new resource. Every resource receives a system-assigned ULID. User-added resources also require a namespaced name (`[[server:]namespace/]name`) specified at creation time. The `add` command uses type-specific subcommands — each registered resource type (built-in or custom) provides its own subcommand with type-appropriate arguments. On success, the command returns both the name and the ULID assigned to the newly created resource.

**Arguments**

- `<TYPE>`: Resource type name (e.g., `git-checkout`, `git`, `fs-mount`, `fs-directory`, `local/svn`). Determines type-specific flags.
- `<NAME>`: Namespaced resource name (positional, required). Must be globally unique following the standard `[[server:]namespace/]name` format.
- `--description/-d TEXT`: Optional resource description.

Type-specific flags depend on the resource type. See `agents resource type show <TYPE>` for available arguments.

The command returns the name and ULID of the newly created resource. Auto-discovered child resources are created automatically with ULIDs only (no names).

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add git-checkout local/api-repo <span style="color: cyan;">--path</span> /home/user/projects/api-service <span style="color: cyan;">--branch</span> main

╭─ Resource ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/api-repo                            │
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXR1A1B2C3D4E5F6G7H8J9K0                  │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> git-checkout                              │
│ <span style="color: #5599ff; font-weight: 600;">Physical/Virtual:</span> physical                      │
│ <span style="color: #66cc66; font-weight: 600;">Path:</span> /home/user/projects/api-service           │
│ <span style="color: #5599ff; font-weight: 600;">Branch:</span> main                                    │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-09 10:20                       │
╰─────────────────────────────────────────────────╯

╭─ Auto-discovered Children ─────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>               <span style="color: cyan; font-weight: 600;">Type</span>            <span style="color: cyan; font-weight: 600;">Status</span>                            │
│ <span style="opacity: 0.7;">───────────────  ──────────────  ─────────────────</span>                 │
│ 01HXR1A1B2C3…   git             <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│ 01HXR1A1B2C4…   git-remote      <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│ 01HXR1A1B2C5…   git-branch      <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│ 01HXR1A1B2C6…   git-branch      <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│ 01HXR1A1B2C7…   fs-directory    <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│   + 47 git-commit resources                                        │
│   + 312 git-tree-entry resources                                   │
│   + 3 fs-directory + 28 fs-file                                    │
╰────────────────────────────────────────────────────────────────────╯

╭─ Capabilities ─────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Readable:</span> yes                  │
│ <span style="color: yellow; font-weight: 600;">Writable:</span> yes                  │
│ <span style="color: #66cc66; font-weight: 600;">Sandboxable:</span> yes               │
│ <span style="color: #66cc66; font-weight: 600;">Checkpointable:</span> yes            │
│ <span style="color: #5599ff; font-weight: 600;">Sandbox Strategy:</span> git_worktree │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource registered (395 child resources discovered)
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add fs-mount local/docs <span style="color: cyan;">--mount-path</span> /docs/api-reference

╭─ Resource ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/docs                                │
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXR2B3C4D5E6F7G8H9J0K1L2                  │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> fs-mount                                  │
│ <span style="color: #5599ff; font-weight: 600;">Physical/Virtual:</span> physical                      │
│ <span style="color: #66cc66; font-weight: 600;">Mount Path:</span> /docs/api-reference                 │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-09 10:22                       │
╰─────────────────────────────────────────────────╯

╭─ Auto-discovered Children ────────────────────╮
│   + 1 fs-directory (root)                     │
│   + 3 fs-directory resources                  │
│   + 28 fs-file resources                      │
╰───────────────────────────────────────────────╯

╭─ Capabilities ──────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Readable:</span> yes                       │
│ <span style="color: yellow; font-weight: 600;">Writable:</span> yes                       │
│ <span style="color: #66cc66; font-weight: 600;">Sandboxable:</span> yes                    │
│ <span style="color: #66cc66; font-weight: 600;">Checkpointable:</span> yes                 │
│ <span style="color: #5599ff; font-weight: 600;">Sandbox Strategy:</span> copy_on_write     │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource registered (31 child resources discovered)
</code></pre></div>

##### agents resource remove

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> resource remove [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;NAME&gt;</span></code></pre></div>

**Purpose**
Remove a registered resource and all its auto-discovered child resources. Only user-added (named) resources can be removed. Fails if the resource is linked to any project (unlink first).

**Arguments**

- `<NAME>`: Resource name (only user-added resources can be removed).
- `--yes`: Skip confirmation prompt.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource remove local/api-repo

Remove resource local/api-repo and 395 child resources? [y/N]: y

╭─ Resource Removed ──────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/api-repo                                │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> git-checkout                                  │
│ <span style="color: yellow; font-weight: 600;">Children Removed:</span> 395                               │
│ <span style="color: #5599ff; font-weight: 600;">Projects Unlinked:</span> 0                                │
╰─────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource removed
</code></pre></div>

##### agents resource list

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> resource list [<span style="color: cyan;">--all</span>] [(<span style="color: magenta;"><span style="color: cyan;">--type</span>|<span style="color: yellow;">-t</span></span>) <span style="color: #66cc66;">&lt;TYPE&gt;</span>] </code></pre></div>

**Purpose**
List registered resources with optional filters. By default, lists only user-added (named) resources. Use `--all` to include auto-discovered child resources.

**Arguments**

- `--type/-t TYPE`: Filter by resource type (accepts a regex).
- `--all`: Include auto-discovered child resources (by default only user-added resources are shown).

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource list

╭─ Resources ──────────────────────────────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>               <span style="color: cyan; font-weight: 600;">ID</span>                            <span style="color: cyan; font-weight: 600;">Type</span>         <span style="color: cyan; font-weight: 600;">Phys/Virt</span>  <span style="color: cyan; font-weight: 600;">Children</span>  <span style="color: cyan; font-weight: 600;">Projects</span>                 │
│ <span style="opacity: 0.7;">─────────────────  ────────────────────────────  ───────────  ─────────  ────────  ────────────────</span>         │
│ local/api-repo     01HXR1A1B2C3D4E5F6G7H8J9K0  git-checkout physical   395       local/api-service          │
│ local/docs         01HXR2B2C3D4E5F6G7H8J9K0L1  fs-mount     physical   32        local/api-service          │
│ local/staging-db   01HXR3C3D4E5F6G7H8J9K0L1M2  database     physical   12        local/api-service,         │
│                                                                                   local/staging            │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Summary ───────────╮
│ <span style="color: #5599ff; font-weight: 600;">Total:</span> 3            │
│ <span style="color: #5599ff; font-weight: 600;">Physical:</span> 3         │
│ <span style="color: #5599ff; font-weight: 600;">Virtual:</span> 0          │
│ <span style="color: #5599ff; font-weight: 600;">Total Children:</span> 405 │
╰─────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 3 resources listed
</code></pre></div>

##### agents resource show

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> resource show <span style="color: #66cc66;">&lt;RESOURCE&gt;</span></code></pre></div>

**Purpose**
Show detailed information about a registered resource including its type, capabilities, parent/child relationships, and linked projects.

**Arguments**

- `<RESOURCE>`: Resource name or ULID.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource show local/api-repo

╭─ Resource ─────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/api-repo                               │
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXR1A1B2C3D4E5F6G7H8J9K0                     │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> git-checkout                                 │
│ <span style="color: #5599ff; font-weight: 600;">Physical/Virtual:</span> physical                         │
│ <span style="color: #66cc66; font-weight: 600;">Path:</span> /home/user/projects/api-service              │
│ <span style="color: #5599ff; font-weight: 600;">Branch:</span> main                                       │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-09 10:20                          │
╰────────────────────────────────────────────────────╯

╭─ Capabilities ────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Readable:</span> yes                     │
│ <span style="color: yellow; font-weight: 600;">Writable:</span> yes                     │
│ <span style="color: #66cc66; font-weight: 600;">Sandboxable:</span> yes                  │
│ <span style="color: #66cc66; font-weight: 600;">Checkpointable:</span> yes               │
│ <span style="color: #5599ff; font-weight: 600;">Sandbox Strategy:</span> git_worktree    │
╰───────────────────────────────────╯

╭─ Parents ────╮
│ (top-level)  │
╰──────────────╯

╭─ Direct Children ──────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>                            <span style="color: cyan; font-weight: 600;">Type</span>          <span style="color: cyan; font-weight: 600;">Auto</span>  <span style="color: cyan; font-weight: 600;">Children</span>             │
│ <span style="opacity: 0.7;">────────────────────────────  ────────────  ────  ────────</span>             │
│ 01HXR4D4E5F6G7H8J9K0L1M2N3  git           yes   363                    │
│ 01HXR5E5F6G7H8J9K0L1M2N3P4  fs-directory  yes   32                     │
╰────────────────────────────────────────────────────────────────────────╯

╭─ Linked Projects ─────────────╮
│ - local/api-service (r/w)     │
╰───────────────────────────────╯

╭─ Tool Bindings ────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Tool</span>                      <span style="color: cyan; font-weight: 600;">Slot</span>   <span style="color: cyan; font-weight: 600;">Access</span>        │
│ <span style="opacity: 0.7;">────────────────────────  ─────  ───────────</span>   │
│ (builtin) git_status     repo   read_only      │
│ (builtin) git_diff       repo   read_only      │
│ (builtin) git_log        repo   read_only      │
│ local/run-migrations     db     (not bound)    │
╰────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource details loaded
</code></pre></div>

##### agents resource inspect

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> resource inspect [<span style="color: cyan;">--tree</span>] [<span style="color: cyan;">--file</span> <span style="color: #66cc66;">&lt;PATH&gt;</span>] <span style="color: #66cc66;">&lt;RESOURCE&gt;</span></code></pre></div>

**Purpose**
Inspect a resource's contents. For file-based resources (git checkouts, filesystem mounts, directories), displays the file tree or the contents of a specific file. Works with any resource — user-added or auto-discovered — via name or ULID.

**Arguments**

- `<RESOURCE>`: Resource name or ULID.
- `--tree`: Show the resource's file/content tree.
- `--file PATH`: Show contents of a specific file within the resource.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource inspect local/api-repo <span style="color: cyan;">--tree</span>

╭─ Resource Tree: local/api-repo ──────────────────────────────────────╮
│                                                                     │
│ <span style="color: cyan; font-weight: 600;">/home/user/projects/api-service</span>                                     │
│ ├── <span style="color: #5599ff; font-weight: 600;">src/</span>                                                           │
│ │   ├── <span style="color: #5599ff; font-weight: 600;">api/</span>                                                       │
│ │   │   ├── __init__.py                                             │
│ │   │   ├── <span style="color: #5599ff; font-weight: 600;">auth/</span>                                                   │
│ │   │   │   ├── auth_middleware.py                                   │
│ │   │   │   ├── token_service.py                                     │
│ │   │   │   └── rbac.py                                              │
│ │   │   ├── <span style="color: #5599ff; font-weight: 600;">routes/</span>                                                 │
│ │   │   └── <span style="color: #5599ff; font-weight: 600;">models/</span>                                                 │
│ │   └── <span style="color: #5599ff; font-weight: 600;">utils/</span>                                                     │
│ ├── <span style="color: #5599ff; font-weight: 600;">tests/</span>                                                         │
│ ├── README.md                                                       │
│ └── pyproject.toml                                                   │
│                                                                     │
╰─────────────────────────────────────────────────────────────────────╯

╭─ Summary ──────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Directories:</span> 8         │
│ <span style="color: #5599ff; font-weight: 600;">Files:</span> 41               │
│ <span style="color: #5599ff; font-weight: 600;">Total Size:</span> 284 KB      │
╰────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource tree displayed
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource inspect local/api-repo <span style="color: cyan;">--file</span> src/api/auth/auth_middleware.py

╭─ File: src/api/auth/auth_middleware.py ──────────────────╮
│ <span style="color: cyan; font-weight: 600;">Resource:</span> local/api-repo                                │
│ <span style="color: #5599ff; font-weight: 600;">Size:</span> 2.4 KB                                            │
│ <span style="color: #5599ff; font-weight: 600;">Language:</span> Python                                         │
│ <span style="color: #5599ff; font-weight: 600;">Last Modified:</span> 2026-02-10 14:32                          │
╰──────────────────────────────────────────────────────────╯

<span style="opacity: 0.7;">  1</span> │ <span style="color: cyan;">from</span> fastapi <span style="color: cyan;">import</span> Request, HTTPException
<span style="opacity: 0.7;">  2</span> │ <span style="color: cyan;">from</span> .token_service <span style="color: cyan;">import</span> validate_token
<span style="opacity: 0.7;">  3</span> │
<span style="opacity: 0.7;">  4</span> │ <span style="color: cyan;">async def</span> <span style="color: #66cc66;">auth_middleware</span>(request: Request):
<span style="opacity: 0.7;">  5</span> │     token = request.headers.get(<span style="color: #66cc66;">"Authorization"</span>)
<span style="opacity: 0.7;">  6</span> │     <span style="color: cyan;">if not</span> token:
<span style="opacity: 0.7;">  7</span> │         <span style="color: cyan;">raise</span> HTTPException(status_code=<span style="color: yellow;">401</span>)
<span style="opacity: 0.7;">  8</span> │     user = <span style="color: cyan;">await</span> validate_token(token)
<span style="opacity: 0.7;">  9</span> │     request.state.user = user
<span style="opacity: 0.7;"> 10</span> │     <span style="color: cyan;">return</span> user
<span style="opacity: 0.7;">   </span> │ <span style="opacity: 0.5;">... (24 more lines)</span>

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> File displayed
</code></pre></div>

##### agents resource tree

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> resource tree [(<span style="color: magenta;"><span style="color: cyan;">--depth</span>|<span style="color: yellow;">-d</span></span>) <span style="color: #66cc66;">&lt;N&gt;</span>] [(<span style="color: magenta;"><span style="color: cyan;">--type</span>|<span style="color: yellow;">-t</span></span>) <span style="color: #66cc66;">&lt;TYPE&gt;</span>] <span style="color: #66cc66;">&lt;RESOURCE&gt;</span></code></pre></div>

**Purpose**
Display the resource DAG as a tree starting from a given resource, showing parent/child relationships.

**Arguments**

- `<RESOURCE>`: Resource name or ULID.
- `--depth/-d N`: Maximum depth to display (default: 3).
- `--type/-t TYPE`: Filter to only show children of a specific type.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource tree local/api-repo <span style="color: cyan;">--depth</span> 2

╭─ Resource Tree: local/api-repo ──────────────────────────────────────╮
│                                                                     │
│ <span style="color: cyan; font-weight: 600;">git-checkout 01HXR1A1..J9K0</span> (physical)                              │
│ ├── <span style="color: #5599ff; font-weight: 600;">git 01HXR4D4..M2N3</span> (physical)                                   │
│ │   ├── <span style="color: #5599ff; font-weight: 600;">git-remote 01HXR6F6..P4Q5</span>                                   │
│ │   ├── <span style="color: magenta; font-weight: 600;">git-branch 01HXR7G7..Q5R6</span>                                   │
│ │   │   ├── <span style="color: #66cc66; font-weight: 600;">git-commit 01HXR8H8..R6S7</span>                               │
│ │   │   └── <span style="opacity: 0.7;">... 22 more git-commit resources</span>                        │
│ │   └── <span style="color: magenta; font-weight: 600;">git-branch 01HXR9J9..S7T8</span>                                   │
│ │       └── <span style="opacity: 0.7;">... 26 git-commit resources</span>                             │
│ └── <span style="color: #5599ff; font-weight: 600;">fs-directory 01HXR5E5..N3P4</span> (physical)                          │
│     ├── <span style="color: #66cc66; font-weight: 600;">fs-directory 01HXRAK1..T8U9</span>                                 │
│     ├── <span style="color: #66cc66; font-weight: 600;">fs-directory 01HXRBL2..U9V0</span>                                 │
│     └── <span style="opacity: 0.7;">... 28 more fs-file resources</span>                               │
│                                                                     │
╰─────────────────────────────────────────────────────────────────────╯

╭─ Summary ──────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Total shown:</span> 14        │
│ <span style="color: #5599ff; font-weight: 600;">Total in subtree:</span> 395  │
│ <span style="color: #5599ff; font-weight: 600;">Max depth:</span> 2           │
╰────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource tree displayed
</code></pre></div>

##### agents resource link-child

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> resource link-child <span style="color: #66cc66;">&lt;PARENT&gt;</span> <span style="color: #66cc66;">&lt;CHILD&gt;</span></code></pre></div>

**Purpose**
Manually link one resource as a child of another. The child resource must already be registered. The resource types must be compatible (the parent type must allow the child type). A resource can have multiple parents.

**Arguments**

- `<PARENT>`: Parent resource name or ULID.
- `<CHILD>`: Child resource name or ULID.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource link-child local/api-repo 01HXR2B2C3D4E5F6G7H8J9K0L1

╭─ Child Linked ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Parent:</span> local/api-repo                              │
│ <span style="color: #5599ff; font-weight: 600;">Child:</span> 01HXR2B2C3D4E5F6G7H8J9K0L1                   │
│ <span style="color: #5599ff; font-weight: 600;">Child Type:</span> fs-mount                                │
│ <span style="color: #66cc66; font-weight: 600;">Status:</span> linked                                      │
╰─────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Child resource linked
</code></pre></div>

##### agents resource unlink-child

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> resource unlink-child [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;PARENT&gt;</span> <span style="color: #66cc66;">&lt;CHILD&gt;</span></code></pre></div>

**Purpose**
Remove a manual parent/child link between two resources. Auto-discovered links cannot be manually unlinked.

**Arguments**

- `<PARENT>`: Parent resource name or ULID.
- `<CHILD>`: Child resource name or ULID.
- `--yes`: Skip confirmation prompt.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource unlink-child local/api-repo 01HXR2B2C3D4E5F6G7H8J9K0L1

Unlink 01HXR2B2C3D4E5F6G7H8J9K0L1 from parent local/api-repo? [y/N]: y

╭─ Child Unlinked ────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Parent:</span> local/api-repo                              │
│ <span style="color: #5599ff; font-weight: 600;">Child:</span> 01HXR2B2C3D4E5F6G7H8J9K0L1                   │
│ <span style="color: #66cc66; font-weight: 600;">Status:</span> unlinked                                    │
╰─────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Child resource unlinked
</code></pre></div>

#### agents plan

**Purpose**
Manage plans through the Strategize -> Execute -> Apply lifecycle (instantiated from Action templates).

##### agents plan list

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> plan list [<span style="color: cyan;">--phase</span> <span style="color: #66cc66;">&lt;PHASE&gt;</span>] [<span style="color: cyan;">--state</span> <span style="color: #66cc66;">&lt;STATE&gt;</span>] [<span style="color: cyan;">--project</span> <span style="color: #66cc66;">&lt;PROJECT&gt;</span>]
                [<span style="color: cyan;">--action</span> <span style="color: #66cc66;">&lt;ACTION&gt;</span>] [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]</code></pre></div>

**Purpose**
List plans with optional filtering.

**Arguments**

- `--phase PHASE`: Filter by phase.
- `--state STATE`: Filter by processing state.
- `--project PROJECT`: Filter by project.
- `--action ACTION`: Filter by action name.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> table plan list <span style="color: cyan;">--phase</span> execute

╭─ Plans ──────────────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>        <span style="color: cyan; font-weight: 600;">Phase</span>    <span style="color: cyan; font-weight: 600;">State</span>       <span style="color: cyan; font-weight: 600;">Action</span>               <span style="color: cyan; font-weight: 600;">Project</span>            <span style="color: cyan; font-weight: 600;">Elapsed</span>       │
│ <span style="opacity: 0.7;">────────  ───────  ──────────  ───────────────────  ─────────────────  ─────────</span>     │
│ 01HXM7A9  execute  processing  local/code-coverage  local/api-service  00:01:12      │
╰──────────────────────────────────────────────────────────────────────────────────────╯

╭─ Filters ──────╮
│ <span style="color: yellow; font-weight: 600;">Phase:</span> execute │
│ <span style="color: magenta; font-weight: 600;">State:</span> (any)   │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> (any) │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> (any)  │
╰────────────────╯

╭─ Summary ─────────╮
│ <span style="color: yellow; font-weight: 600;">Total:</span> 1          │
│ <span style="color: cyan; font-weight: 600;">Processing:</span> 1     │
│ <span style="color: #66cc66; font-weight: 600;">Completed:</span> 0      │
│ <span style="color: #ff6666; font-weight: 600;">Errored:</span> 0        │
╰───────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 1 plan listed
</code></pre></div>

Listing all plans without filters shows plans across all phases and states:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan list

╭─ Plans ──────────────────────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>        <span style="color: cyan; font-weight: 600;">Phase</span>       <span style="color: cyan; font-weight: 600;">State</span>       <span style="color: cyan; font-weight: 600;">Action</span>               <span style="color: cyan; font-weight: 600;">Project</span>            <span style="color: cyan; font-weight: 600;">Elapsed</span>            │
│ <span style="opacity: 0.7;">────────  ──────────  ──────────  ───────────────────  ─────────────────  ─────────</span>          │
│ 01HXM7A9  execute     processing  local/code-coverage  local/api-service  00:01:12           │
│ 01HXM6R3  <span style="color: #66cc66; font-weight: 600;">applied</span>     <span style="color: #66cc66; font-weight: 600;">complete</span>    local/add-auth       local/api-service  00:07:14           │
│ 01HXM5K2  <span style="color: #ff6666; font-weight: 600;">execute</span>     <span style="color: #ff6666; font-weight: 600;">errored</span>     local/migrate-db     local/api-service  00:04:33           │
│ 01HXM4J1  strategize  processing  local/refactor-api   local/web-app      00:00:45           │
│ 01HXM3H8  <span style="opacity: 0.5;">cancelled</span>   <span style="opacity: 0.5;">cancelled</span>   local/add-logging    local/api-service  00:02:10           │
╰──────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Summary ─────────────╮
│ <span style="color: yellow;">Total:</span> 5              │
│ <span style="color: cyan; font-weight: 600;">Processing:</span> 2         │
│ <span style="color: #66cc66; font-weight: 600;">Completed:</span> 1          │
│ <span style="color: #ff6666; font-weight: 600;">Errored:</span> 1            │
│ <span style="opacity: 0.5;">Cancelled:</span> 1          │
╰───────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 5 plans listed
</code></pre></div>

Filtering by project with `--project`:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan list <span style="color: cyan;">--project</span> local/web-app

╭─ Plans ──────────────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>        <span style="color: cyan; font-weight: 600;">Phase</span>       <span style="color: cyan; font-weight: 600;">State</span>       <span style="color: cyan; font-weight: 600;">Action</span>               <span style="color: cyan; font-weight: 600;">Project</span>        <span style="color: cyan; font-weight: 600;">Elapsed</span>        │
│ <span style="opacity: 0.7;">────────  ──────────  ──────────  ───────────────────  ─────────────  ─────────</span>      │
│ 01HXM4J1  strategize  processing  local/refactor-api   local/web-app  00:00:45       │
╰──────────────────────────────────────────────────────────────────────────────────────╯

╭─ Filters ─────────────────╮
│ <span style="color: yellow;">Phase:</span> (any)              │
│ <span style="color: magenta; font-weight: 600;">State:</span> (any)              │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/web-app    │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> (any)             │
╰───────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 1 plan listed
</code></pre></div>

##### agents plan use

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> plan use [<span style="color: cyan;">--automation-profile</span> <span style="color: #66cc66;">&lt;PROFILE&gt;</span>]
                [<span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">&lt;INVARIANT&gt;</span>]...
                [<span style="color: cyan;">--strategy-actor</span> <span style="color: #66cc66;">&lt;STRATEGY_ACTOR&gt;</span>]
                [<span style="color: cyan;">--execution-actor</span> <span style="color: #66cc66;">&lt;EXEC_ACTOR&gt;</span>]
                [<span style="color: cyan;">--estimation-actor</span> <span style="color: #66cc66;">&lt;EST_ACTOR&gt;</span>]
                [<span style="color: cyan;">--invariant-actor</span> <span style="color: #66cc66;">&lt;INV_ACTOR&gt;</span>]
                [<span style="color: cyan;">--arg</span>/<span style="color: yellow;">-a</span> name=value]...
                <span style="color: #66cc66;">&lt;ACTION&gt;</span> <span style="color: #66cc66;">&lt;PROJECT&gt;</span>...</code></pre></div>

**Purpose**
Apply an action to one or more projects and start the Strategize phase.

**Arguments**

- `<ACTION_NAME>`: Action name.
- `<PROJECT>`: One or more project names (positional arguments, repeatable).
- `--arg/-a name=value`: Action argument (repeatable).
- `--automation-profile PROFILE`: Automation profile name (e.g., `trusted`, `auto`, `local/careful-auto`). Overrides the profile inherited from the action, project, or global config.
- `--strategy-actor ACTOR`: Override the action's strategy actor for this plan.
- `--execution-actor ACTOR`: Override the action's execution actor for this plan.
- `--estimation-actor ACTOR`: Override the action's estimation actor for this plan.
- `--invariant-actor ACTOR`: Override the action's Invariant Reconciliation Actor for this plan.
- `--invariant TEXT`: Invariant to attach to the created plan (repeatable). These are added as plan-level invariants in addition to any invariants inherited from the action, project, or global scope.

All actor arguments (`--strategy-actor`, `--execution-actor`, `--estimation-actor`, `--invariant-actor`) are optional overrides. When provided, they replace whatever was set when creating the action. When omitted, the action's configured actors are used.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan use local/code-coverage local/api-service \
  <span style="color: cyan;">--arg</span> target_coverage_percent=85 <span style="color: cyan;">--automation-profile</span> trusted

╭─ Plan Created ──────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan ID:</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> strategize                   │
│ <span style="color: magenta; font-weight: 600;">Action:</span> local/code-coverage         │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/api-service          │
│ <span style="color: #66cc66; font-weight: 600;">Automation:</span> trusted                 │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                          │
╰─────────────────────────────────────╯

╭─ Inputs ──────────────────────╮
│ - target_coverage_percent=85  │
│ - automation_profile=trusted  │
╰───────────────────────────────╯

╭─ Actors ────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Strategy:</span> local/strategist      │
│ <span style="color: magenta; font-weight: 600;">Execution:</span> local/executor       │
│ <span style="color: #5599ff; font-weight: 600;">Estimation:</span> (none)              │
╰─────────────────────────────────╯

╭─ Automation ─────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> trusted                     │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> CLI flag                     │
│ <span style="color: #5599ff; font-weight: 600;">Read-Only:</span> no                        │
╰──────────────────────────────────────╯

╭─ Context ───────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Resources:</span> 2 (repo, db)         │
│ <span style="color: #5599ff; font-weight: 600;">Indexed Files:</span> 347              │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> strategize                │
│ <span style="color: #5599ff; font-weight: 600;">Hot Token Budget:</span> 12,000        │
╰─────────────────────────────────╯

╭─ Next Steps ─────────────────────────────────────╮
│ - agents plan execute 01HXM8C2ZK4Q7C2B3F2R4VYV6J │
│ - agents plan status 01HXM8C2ZK4Q7C2B3F2R4VYV6J  │
│ - agents plan tree 01HXM8C2ZK4Q7C2B3F2R4VYV6J    │
╰──────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan created
</code></pre></div>

Applying an action to multiple projects simultaneously, with plan-level invariants:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan use local/security-audit local/api-service local/web-app \
  <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">&quot;Never modify production database schemas&quot;</span> \
  <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">&quot;All changes must include test coverage&quot;</span> \
  <span style="color: cyan;">--automation-profile</span> supervised

╭─ Plan Created ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM9D2ZK4Q7C2B3F2R4VYV6J                    │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/security-audit                        │
│ <span style="color: yellow;">Phase:</span> strategize (running)                         │
│ <span style="color: magenta; font-weight: 600;">Automation:</span> supervised                              │
╰─────────────────────────────────────────────────────╯

╭─ Target Projects ───────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">1.</span> local/api-service (3 resources)  │
│ <span style="color: #66cc66; font-weight: 600;">2.</span> local/web-app (2 resources)      │
╰─────────────────────────────────────╯

╭─ Plan Invariants ──────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Scope</span>     <span style="color: magenta; font-weight: 600;">Source</span>   <span style="color: magenta; font-weight: 600;">Invariant</span>                               │
│ <span style="opacity: 0.7;">────────  ───────  ──────────────────────────────────</span>      │
│ plan      CLI      Never modify production DB schemas      │
│ plan      CLI      All changes must include test coverage  │
│ project   config   API responses must be backward-compat   │
│ global    config   Follow Python PEP 8 style guide         │
╰────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan created — strategize in progress
</code></pre></div>

Using an action with custom actor overrides:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan use local/code-coverage local/api-service \
  <span style="color: cyan;">--strategy-actor</span> local/senior-planner \
  <span style="color: cyan;">--execution-actor</span> local/fast-executor \
  <span style="color: cyan;">--arg</span> target_coverage_percent=95

╭─ Plan Created ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM9E3ZK4Q7C2B3F2R4VYV6J                    │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/code-coverage                         │
│ <span style="color: yellow;">Phase:</span> strategize (running)                         │
│ <span style="color: magenta; font-weight: 600;">Automation:</span> trusted                                 │
╰─────────────────────────────────────────────────────╯

╭─ Actor Overrides ────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Strategy:</span> local/senior-planner       │
│ <span style="color: #5599ff; font-weight: 600;">Execution:</span> local/fast-executor       │
│ <span style="opacity: 0.7;">(Estimation: action default)</span>         │
╰──────────────────────────────────────╯

╭─ Arguments ─────────────────╮
│ <span style="color: cyan; font-weight: 600;">target_coverage_percent:</span> 95 │
╰─────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan created — strategize in progress
</code></pre></div>

##### agents plan execute

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> plan execute <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span></code></pre></div>

**Purpose**
Start or resume execution for a plan.

**Arguments**

- `<PLAN_ID>`: Plan ID (required).

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan execute 01HXM8C2ZK4Q7C2B3F2R4VYV6J

╭─ Execution ──────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> execute                   │
│ <span style="color: magenta; font-weight: 600;">Sandbox:</span> git_worktree            │
│ <span style="color: #5599ff; font-weight: 600;">Worker:</span> local/executor           │
│ <span style="color: #66cc66; font-weight: 600;">Started:</span> 12:58:10                │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                       │
╰──────────────────────────────────╯

╭─ Sandbox ──────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Strategy:</span> git_worktree                     │
│ <span style="color: #5599ff; font-weight: 600;">Path:</span> /repos/api/.worktrees/plan-01HXM8    │
│ <span style="color: #5599ff; font-weight: 600;">Branch:</span> cleveragents/plan-01HXM8C2         │
│ <span style="color: #66cc66; font-weight: 600;">Status:</span> active                             │
╰────────────────────────────────────────────╯

╭─ Strategy Summary ─────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Decisions:</span> 8                           │
│ <span style="color: magenta; font-weight: 600;">Invariants:</span> 2                          │
│ <span style="color: #5599ff; font-weight: 600;">Planned Child Plans:</span> 2+                │
│ <span style="color: #5599ff; font-weight: 600;">Estimated Files:</span> ~12                   │
│ <span style="color: #5599ff; font-weight: 600;">Risk:</span> low                              │
╰────────────────────────────────────────╯

╭─ Progress ────────╮
│ <span style="color: cyan; font-weight: 600;">⏳</span> Collect context │
│ <span style="color: yellow; font-weight: 600;">•</span> Run tools       │
│ <span style="color: yellow; font-weight: 600;">•</span> Build changeset │
│ <span style="color: yellow; font-weight: 600;">•</span> Validate        │
╰───────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Execution started
</code></pre></div>

Resuming execution of a plan that was previously paused or errored:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan execute 01HXM7K2ZK4Q7C2B3F2R4VYV6J

╭─ Execution Resumed ─────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM7K2ZK4Q7C2B3F2R4VYV6J    │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> execute (resumed)            │
│ <span style="color: magenta; font-weight: 600;">Sandbox:</span> git_worktree               │
│ <span style="color: #5599ff; font-weight: 600;">Worker:</span> local/executor              │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoint:</span> cp_01HXM8C2 (loaded)    │
│ <span style="color: #5599ff; font-weight: 600;">Resumed From:</span> step 4 of 6           │
╰─────────────────────────────────────╯

╭─ Previous Progress ──────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Step 1: Collect context (0.8s)         │
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Step 2: Analyze codebase (4.2s)        │
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Step 3: Generate migrations (6.1s)     │
│ <span style="color: #ff6666; font-weight: 600;">✗</span> Step 4: Apply migrations (errored)     │
│ <span style="opacity: 0.5;">○</span> Step 5: Update models (pending)        │
│ <span style="opacity: 0.5;">○</span> Step 6: Run validations (pending)      │
╰──────────────────────────────────────────╯

╭─ Guidance Applied ──────────────────────────────────────────────╮
│ <span style="opacity: 0.7;"><span style="color: #66cc66;">"Use smaller batch sizes for the migration to avoid timeouts"</span></span>   │
╰─────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Execution resumed from checkpoint cp_01HXM8C2
</code></pre></div>

##### agents plan apply

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> plan apply [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span></code></pre></div>

**Purpose**
Apply sandboxed changes to real resources.

**Arguments**

- `<PLAN_ID>`: Plan ID.
- `--yes`: Skip confirmation.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply 01HXM8C2ZK4Q7C2B3F2R4VYV6J

Apply changes for plan 01HXM8C2ZK4Q7C2B3F2R4VYV6J? [y/N]: y

╭─ Apply Summary ─────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J    │
│ <span style="color: #5599ff; font-weight: 600;">Artifacts:</span> 6 files updated          │
│ <span style="color: yellow; font-weight: 600;">Changes:</span> 42 insertions, 9 deletions │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/api-service          │
│ <span style="color: #66cc66; font-weight: 600;">Applied At:</span> 2026-02-08 13:04        │
╰─────────────────────────────────────╯

╭─ Validation (from Execute) ────╮
│ <span style="color: #66cc66; font-weight: 600;">Tests:</span> passed (24/24)          │
│ <span style="color: #66cc66; font-weight: 600;">Lint:</span> passed (0 warnings)      │
│ <span style="color: #66cc66; font-weight: 600;">Type Check:</span> passed (0 errors)  │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 12.4s                │
╰────────────────────────────────╯

╭─ Sandbox Cleanup ─────────╮
│ <span style="color: #66cc66; font-weight: 600;">Worktree:</span> removed         │
│ <span style="color: #66cc66; font-weight: 600;">Branch:</span> merged to main    │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoint:</span> archived      │
╰───────────────────────────╯

╭─ Plan Lifecycle ────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Phase:</span> applied                          │
│ <span style="color: #66cc66; font-weight: 600;">State:</span> complete                         │
│ <span style="color: #5599ff; font-weight: 600;">Total Duration:</span> 00:06:14                │
│ <span style="color: yellow; font-weight: 600;">Total Cost:</span> $0.0847                     │
│ <span style="color: #5599ff; font-weight: 600;">Decisions Made:</span> 8                       │
│ <span style="color: #5599ff; font-weight: 600;">Child Plans:</span> 2 (completed)              │
╰─────────────────────────────────────────╯

╭─ Next Steps ──────╮
│ - Review git diff │
│ - Commit changes  │
╰───────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied
</code></pre></div>

When Execute-phase validations failed and were not resolved (e.g., the execution actor exhausted its retry limit or failed outright), the plan cannot be applied. Apply checks the validation record and refuses to proceed:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J

╭─ Apply Summary ─────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J    │
│ <span style="color: #5599ff; font-weight: 600;">Artifacts:</span> 6 files updated          │
│ <span style="color: yellow;">Changes:</span> 42 insertions, 9 deletions │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/api-service          │
╰─────────────────────────────────────╯

╭─ Validation ───────────────────────────────────────────────╮
│ <span style="color: #ff6666; font-weight: 600;">✗</span> Tests: <span style="color: #ff6666; font-weight: 600;">FAILED</span> (22/24 passed, 2 failed)                   │
│   <span style="opacity: 0.7;">FAIL test_auth.py::test_session_refresh — AssertionError</span> │
│   <span style="opacity: 0.7;">FAIL test_auth.py::test_token_expiry — TimeoutError</span>      │
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Lint: passed (0 warnings)                                │
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Type Check: passed (0 errors)                            │
│ <span style="color: #5599ff; font-weight: 600;">Duration:</span> 14.8s                                            │
╰────────────────────────────────────────────────────────────╯

╭─ Sandbox Status ─────────────────────────────────────────────╮
│ <span style="color: yellow; font-weight: 600;">Worktree:</span> preserved (changes NOT committed)                  │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoint:</span> cp_01HXM8C2 (pre-apply state available)          │
│ <span style="opacity: 0.7;">The sandbox is preserved for correction or manual review.</span>    │
╰──────────────────────────────────────────────────────────────╯

╭─ Recovery Options ──────────────────────────────────────────────────╮
│ - <span style="color: cyan;">agents plan prompt</span> <span style="opacity: 0.7;">— provide guidance to fix test failures</span>        │
│ - <span style="color: cyan;">agents plan correct</span> <span style="opacity: 0.7;">— revert and re-execute with guidance</span>         │
│ - <span style="color: cyan;">agents plan rollback</span> <span style="opacity: 0.7;">— restore to a previous checkpoint</span>           │
│ - <span style="color: cyan;">agents plan cancel</span> <span style="opacity: 0.7;">— abort the plan entirely</span>                      │
╰─────────────────────────────────────────────────────────────────────╯

<span style="color: #ff6666; font-weight: 600;">✗ ERROR</span> Apply refused — 2 required Execute-phase validations did not pass
</code></pre></div>

##### agents plan status

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> plan status <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span></code></pre></div>

**Purpose**
Show detailed status for a plan.

**Arguments**

- `<PLAN_ID>`: Plan ID (required).

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan status 01HXM8C2ZK4Q7C2B3F2R4VYV6J

╭─ Plan Status ────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> execute                   │
│ <span style="color: magenta; font-weight: 600;">State:</span> processing                │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/code-coverage      │
│ <span style="color: #66cc66; font-weight: 600;">Project:</span> local/api-service       │
│ <span style="color: #5599ff; font-weight: 600;">Automation:</span> review               │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                       │
╰──────────────────────────────────╯

╭─ Progress ───────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Strategize     │
│ <span style="color: cyan; font-weight: 600;">⏳</span> Execute        │
│ <span style="color: yellow; font-weight: 600;">•</span> Apply (queued) │
╰──────────────────╯

╭─ Timing ──────────╮
│ <span style="color: #66cc66; font-weight: 600;">Started:</span> 12:57:01 │
│ <span style="color: yellow; font-weight: 600;">Elapsed:</span> 00:01:12 │
│ <span style="color: #66cc66; font-weight: 600;">ETA:</span> 00:03:45     │
╰───────────────────╯

╭─ Execution Detail ──────────╮
│ <span style="color: #5599ff; font-weight: 600;">Sandbox:</span> git_worktree       │
│ <span style="color: #5599ff; font-weight: 600;">Tool Calls:</span> 8               │
│ <span style="color: #5599ff; font-weight: 600;">Files Modified:</span> 3           │
│ <span style="color: #5599ff; font-weight: 600;">Child Plans:</span> 1/2 complete   │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoints:</span> 2 created      │
╰─────────────────────────────╯

╭─ Cost ───────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Tokens Used:</span> 12,420  │
│ <span style="color: yellow; font-weight: 600;">Cost So Far:</span> $0.041  │
│ <span style="color: #5599ff; font-weight: 600;">Estimated:</span> $0.085    │
╰──────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Status refreshed
</code></pre></div>

Status of a plan that has completed successfully:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan status 01HXM6R3ZK4Q7C2B3F2R4VYV6J

╭─ Plan Status ─────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM6R3ZK4Q7C2B3F2R4VYV6J  │
│ <span style="color: #66cc66; font-weight: 600;">Phase:</span> applied                    │
│ <span style="color: #66cc66; font-weight: 600;">State:</span> complete                   │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/add-auth            │
│ <span style="color: #66cc66; font-weight: 600;">Project:</span> local/api-service        │
│ <span style="color: #5599ff; font-weight: 600;">Automation:</span> trusted               │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                        │
╰───────────────────────────────────╯

╭─ Progress ───────────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Strategize         │
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Execute            │
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Apply (committed)  │
╰──────────────────────╯

╭─ Timing ─────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Started:</span> 2026-02-08 12:57:01     │
│ <span style="color: #66cc66; font-weight: 600;">Finished:</span> 2026-02-08 13:04:15    │
│ <span style="color: #5599ff; font-weight: 600;">Total Duration:</span> 00:07:14         │
╰──────────────────────────────────╯

╭─ Result ────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Decisions Made:</span> 8                   │
│ <span style="color: #5599ff; font-weight: 600;">Child Plans:</span> 2/2 complete           │
│ <span style="color: #66cc66; font-weight: 600;">Artifacts:</span> 6 files updated          │
│ <span style="color: #66cc66; font-weight: 600;">Validations:</span> 3/3 passed             │
│ <span style="color: yellow;">Total Cost:</span> $0.085                  │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan completed successfully
</code></pre></div>

Status of a plan in the strategize phase:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan status 01HXM9F2ZK4Q7C2B3F2R4VYV6J

╭─ Plan Status ────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM9F2ZK4Q7C2B3F2R4VYV6J │
│ <span style="color: yellow;">Phase:</span> strategize                │
│ <span style="color: magenta; font-weight: 600;">State:</span> processing                │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/refactor-auth      │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/api-service       │
│ <span style="color: #5599ff; font-weight: 600;">Automation:</span> supervised           │
╰──────────────────────────────────╯

╭─ Progress ───────────────╮
│ <span style="color: cyan; font-weight: 600;">⏳</span> Strategize (running)   │
│ <span style="opacity: 0.5;">○</span> Execute (waiting)      │
│ <span style="opacity: 0.5;">○</span> Apply (waiting)        │
╰──────────────────────────╯

╭─ Strategy Progress ────────╮
│ <span style="color: #5599ff; font-weight: 600;">Decisions Made:</span> 4          │
│ <span style="color: #5599ff; font-weight: 600;">Invariants Enforced:</span> 2     │
│ <span style="color: #5599ff; font-weight: 600;">Child Plans Planned:</span> 3     │
│ <span style="color: yellow;">Elapsed:</span> 00:00:28          │
╰────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Strategize in progress
</code></pre></div>

Status of a plan that encountered an error:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan status 01HXM7K2ZK4Q7C2B3F2R4VYV6J

╭─ Plan Status ────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM7K2ZK4Q7C2B3F2R4VYV6J │
│ <span style="color: #ff6666; font-weight: 600;">Phase:</span> execute                   │
│ <span style="color: #ff6666; font-weight: 600;">State:</span> errored                   │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/migrate-db         │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/api-service       │
│ <span style="color: #5599ff; font-weight: 600;">Automation:</span> supervised           │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                       │
╰──────────────────────────────────╯

╭─ Progress ───────────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Strategize         │
│ <span style="color: #ff6666; font-weight: 600;">✗</span> Execute            │
│ <span style="opacity: 0.5;">○</span> Apply (skipped)    │
╰──────────────────────╯

╭─ Error Detail ──────────────────────────────────────────────────╮
│ <span style="color: #ff6666; font-weight: 600;">Error:</span> Tool invocation failed: connection refused               │
│ <span style="color: #5599ff; font-weight: 600;">Tool:</span> local/db-migrate                                          │
│ <span style="color: #5599ff; font-weight: 600;">Step:</span> 4 of 6                                                    │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoint:</span> cp_01HXM8C2 (sandbox state preserved)               │
│ <span style="opacity: 0.7;">Recoverable: yes — use <span style="color: #66cc66;">"agents plan prompt"</span> to provide guidance</span> │
╰─────────────────────────────────────────────────────────────────╯

╭─ Cost ───────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Tokens Used:</span> 8,340   │
│ <span style="color: yellow;">Cost So Far:</span> $0.028  │
╰──────────────────────╯

<span style="color: #ff6666; font-weight: 600;">✗ ERROR</span> Plan errored — use `agents plan prompt` to resume or `agents plan cancel` to abort
</code></pre></div>

##### agents plan cancel

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> plan cancel [(<span style="color: magenta;"><span style="color: cyan;">--reason</span>|<span style="color: yellow;">-r</span></span>) <span style="color: #66cc66;">&lt;REASON&gt;</span>] <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span></code></pre></div>

**Purpose**
Cancel a plan that is not terminal.

**Arguments**

- `<PLAN_ID>`: Plan ID.
- `--reason/-r TEXT`: Optional reason.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan cancel 01HXM8C2ZK4Q7C2B3F2R4VYV6J <span style="color: cyan;">--reason</span> <span style="color: #66cc66;">&quot;blocked on credentials&quot;</span>

╭─ Plan Cancelled ─────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> execute                   │
│ <span style="color: magenta; font-weight: 600;">Reason:</span> blocked on credentials   │
│ <span style="color: #5599ff; font-weight: 600;">State:</span> cancelled                 │
│ <span style="color: #5599ff; font-weight: 600;">Cancelled At:</span> 13:02:15           │
╰──────────────────────────────────╯

╭─ Sandbox ────────────────╮
│ <span style="color: yellow; font-weight: 600;">Status:</span> preserved        │
│ <span style="color: #5599ff; font-weight: 600;">Files Modified:</span> 3        │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoints:</span> 2           │
╰──────────────────────────╯

╭─ Child Plans ─────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Completed:</span> 1              │
│ <span style="color: yellow; font-weight: 600;">Cancelled:</span> 1              │
│ <span style="color: #5599ff; font-weight: 600;">Artifacts Preserved:</span> yes  │
╰───────────────────────────╯

╭─ Recovery ───────────────────────────────────────────╮
│ - Resolve credentials                                │
│ - Run agents plan execute 01HXM8C2ZK4Q7C2B3F2R4VYV6J │
╰──────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan cancelled
</code></pre></div>

##### agents plan tree

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> plan tree [<span style="color: cyan;">--show-superseded</span>] <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span></code></pre></div>

**Purpose**
Render the decision tree for a plan.

**Arguments**

- `<PLAN_ID>`: Plan ID (required).
- `--show-superseded`: Include superseded decisions.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan tree 01HXM8C2ZK4Q7C2B3F2R4VYV6J

╭─ Decision Tree ──────────────────────────────────────────────────────────────────────────╮
│ Plan: 01HXM8C2ZK4Q7C2B3F2R4VYV6J                                                         │
│ ├─ <span style="color: white;">[prompt_definition]</span> <span style="color: #66cc66;">"Increase test coverage to 85%"</span>                                   │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">"Prioritize financial transaction and user mgmt code"</span>            │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">"All API calls over TCP must be mocked"</span>                          │
│ ├─ <span style="color: #5599ff;">[strategy_choice]</span> <span style="color: #66cc66;">"Prioritize auth and payments"</span> <span style="opacity: 0.7;">(confidence: 0.82)</span>                   │
│ ├─ <span style="color: #66cc66;">[subplan_parallel_spawn]</span> "Implement auth and payment modules, in parallel"            │
│ │  ├─ <span style="color: #66cc66;">[subplan_spawn]</span> "Write auth tests" → Plan: 01HXM9F1A                               │
│ │  └─ <span style="color: #66cc66;">[subplan_spawn]</span> "Write payment tests" → Plan: 01HXM9F2B                            │
│ └─ <span style="color: #66cc66;">[subplan_parallel_spawn]</span> "Write tests for remaining modules"                          │
│    └─ ...                                                                                │
╰──────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Tree Summary ─────────────╮
│ <span style="color: yellow; font-weight: 600;">Nodes:</span> 9                   │
│ <span style="color: #5599ff; font-weight: 600;">Depth:</span> 3                   │
│ <span style="color: #66cc66; font-weight: 600;">Child Plans:</span> 2+            │
│ <span style="color: magenta; font-weight: 600;">Invariants:</span> 2              │
│ <span style="color: #5599ff; font-weight: 600;">Superseded:</span> 0 (hidden)     │
╰────────────────────────────╯

╭─ Child Plans ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>          <span style="color: cyan; font-weight: 600;">Name</span>           <span style="color: cyan; font-weight: 600;">Phase</span>    <span style="color: cyan; font-weight: 600;">State</span>          │
│ <span style="opacity: 0.7;">──────────  ─────────────  ───────  ─────────</span>      │
│ 01HXM9F1A   auth-tests     execute  processing     │
│ 01HXM9F2B   payment-tests  execute  queued         │
╰────────────────────────────────────────────────────╯

╭─ Decision IDs (for correction) ──────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Root:</span> 01HXM9A0B1Q2W3R5G8Z0P4Q1X8                 │
│ <span style="color: magenta; font-weight: 600;">Invariant 1:</span> 01HXM9A0C1R3X4S6G9Z1P5Q2Y9          │
│ <span style="color: magenta; font-weight: 600;">Invariant 2:</span> 01HXM9A0D2S4Y5T7H0Z2P6Q3Z0          │
│ <span style="color: #5599ff; font-weight: 600;">Strategy:</span> 01HXM9A1C2Q7W3R5G8Z0P4Q1X9             │
│ <span style="color: #66cc66; font-weight: 600;">Parallel 1:</span> 01HXM9A1D3R8X5S7H1Z2P5Q2Y0           │
│ <span style="color: #66cc66; font-weight: 600;">Spawn Auth:</span> 01HXM9A2D3Q8W4R6H9Z1P5Q2X0           │
│ <span style="color: #66cc66; font-weight: 600;">Spawn Payment:</span> 01HXM9A3E4Q9W5R7I0Z2P6Q3X1        │
│ <span style="color: #66cc66; font-weight: 600;">Parallel 2:</span> 01HXM9A4F5Q0W6R8J1Z3P7Q4X2           │
╰──────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Decision tree rendered
</code></pre></div>

##### agents plan explain

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> plan explain [<span style="color: cyan;">--show-context</span>] [<span style="color: cyan;">--show-reasoning</span>] <span style="color: #66cc66;">&lt;DECISION_ID&gt;</span></code></pre></div>

**Purpose**
Show a detailed explanation for a decision.

**Arguments**

- `<DECISION_ID>`: Decision ID.
- `--show-context`: Include the context snapshot.
- `--show-reasoning`: Include raw model reasoning if available.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan explain 01HXM9A1C2Q7W3R5G8Z0P4Q1X9 <span style="color: cyan;">--show-context</span>

╭─ Decision ─────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXM9A1C2Q7W3R5G8Z0P4Q1X9                 │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> strategy_choice                          │
│ <span style="color: magenta; font-weight: 600;">Question:</span> Which modules should be prioritized? │
│ <span style="color: #66cc66; font-weight: 600;">Chosen:</span> Auth and payments                      │
│ <span style="color: yellow; font-weight: 600;">Confidence:</span> 0.82                               │
│ <span style="color: #5599ff; font-weight: 600;">Plan:</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J               │
│ <span style="color: #5599ff; font-weight: 600;">Sequence:</span> 2 of 5                               │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-08 12:58                      │
╰────────────────────────────────────────────────╯

╭─ Alternatives Considered ──────────────────────╮
│ 1. Auth and payments <span style="color: #66cc66; font-weight: 600;">(chosen)</span>                  │
│ 2. User module first (coverage 71%, med risk)  │
│ 3. All modules equally (spread thin)           │
╰────────────────────────────────────────────────╯

╭─ Impact ──────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Downstream Decisions:</span> 3       │
│ <span style="color: #5599ff; font-weight: 600;">Downstream Child Plans:</span> 2     │
│ <span style="color: #66cc66; font-weight: 600;">Artifacts Produced:</span> 5         │
│ <span style="color: yellow; font-weight: 600;">Correction Impact:</span> medium     │
╰───────────────────────────────╯

╭─ Context Snapshot ───────────────╮
│ - Coverage < 70% in auth         │
│ - Payments failures last release │
│ - Auth: 12 files, 45% coverage   │
│ - Payments: 8 files, 52% cover.  │
│ <span style="color: #5599ff; font-weight: 600;">Hot Context Hash:</span> sha256:4b2e... │
╰──────────────────────────────────╯

╭─ Rationale ───────────────────────────────────────╮
│ Auth and payment modules have the lowest coverage │
│ and highest business risk. Auth handles security  │
│ tokens, payments handles money. Both had bugs in  │
│ the last release traceable to missing tests.      │
╰───────────────────────────────────────────────────╯

╭─ Correction ──────────────────────────────────────────────╮
│ agents plan correct 01HXM9A1C2Q7W3R5G8Z0P4Q1X9            │
│   <span style="color: cyan;">--mode</span> revert <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">"Prioritize payments first..."</span> │
╰───────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Decision explained
</code></pre></div>

Including the raw model reasoning with `--show-reasoning`:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan explain <span style="color: cyan;">--show-reasoning</span> 01HXM9A1C2Q7W3R5G8Z0P4Q1X9

╭─ Decision ──────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXM9A1C2Q7W3R5G8Z0P4Q1X9          │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> strategy_choice                   │
│ <span style="color: magenta; font-weight: 600;">Choice:</span> Convert to async/await          │
│ <span style="color: #5599ff; font-weight: 600;">Alternatives:</span> 3                         │
╰─────────────────────────────────────────╯

╭─ Alternatives Considered ────────────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">1. Convert to async/await patterns</span> (chosen)                  │
│ <span style="opacity: 0.7;">   2. Keep synchronous with thread pool</span>                      │
│ <span style="opacity: 0.7;">   3. Use callback-based approach</span>                            │
╰──────────────────────────────────────────────────────────────╯

╭─ Rationale ──────────────────────────────────────────────────╮
│ Async/await is the modern Python standard for I/O-bound      │
│ operations. The project already uses asyncio in 3 modules.   │
│ Thread pools would add complexity without native support.    │
╰──────────────────────────────────────────────────────────────╯

╭─ Model Reasoning (raw) ───────────────────────────────────────╮
│ <span style="opacity: 0.7;">I need to decide on the concurrency pattern for the payment</span>   │
│ <span style="opacity: 0.7;">processing module. Let me analyze the current codebase:</span>       │
│ <span style="opacity: 0.7;"></span>                                                              │
│ <span style="opacity: 0.7;">1. src/payments/api.py uses synchronous requests.</span>             │
│ <span style="opacity: 0.7;">2. src/core/scheduler.py already uses asyncio.</span>                │
│ <span style="opacity: 0.7;">3. The database driver (asyncpg) supports async natively.</span>     │
│ <span style="opacity: 0.7;">4. Project invariant says <span style="color: #66cc66;">"prefer modern Python patterns"</span>.</span>    │
│ <span style="opacity: 0.7;"></span>                                                              │
│ <span style="opacity: 0.7;">Given that 3/5 core modules already use asyncio, and the</span>      │
│ <span style="opacity: 0.7;">database driver supports it, converting to async/await is</span>     │
│ <span style="opacity: 0.7;">the most consistent choice. Thread pools would work but</span>       │
│ <span style="opacity: 0.7;">add unnecessary complexity and don't integrate well with</span>      │
│ <span style="opacity: 0.7;">the existing asyncio event loop in scheduler.py.</span>              │
╰───────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Decision explained
</code></pre></div>

##### agents plan correct

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> plan correct <span style="color: cyan;">--mode</span> (<span style="color: magenta;">revert|append</span>) (<span style="color: magenta;"><span style="color: cyan;">--guidance</span>|<span style="color: yellow;">-g</span></span>) <span style="color: #66cc66;">&lt;GUIDANCE&gt;</span>
                   [<span style="color: cyan;">--dry-run</span>] [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;DECISION_ID&gt;</span></code></pre></div>

**Purpose**
Correct a decision either by reverting and re-executing or by appending a fix.

**Arguments**

- `<DECISION_ID>`: Decision ID.
- `--mode revert|append`: Correction mode.
- `--guidance/-g TEXT`: Guidance text.
- `--dry-run`: Show impact without executing.
- `--yes`: Skip confirmation for revert mode.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan correct 01HXM9A1C2Q7W3R5G8Z0P4Q1X9 <span style="color: cyan;">--mode</span> revert \
  <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">&quot;Prioritize payments first&quot;</span> <span style="color: cyan;">--yes</span>

╭─ Correction ────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Mode:</span> revert                                        │
│ <span style="color: yellow; font-weight: 600;">Impact:</span> 3 decisions, 2 child plans, 5 artifacts     │
│ <span style="color: #66cc66; font-weight: 600;">New Decision:</span> 01HXM9B7Z3Q1Q8K2E9H7K3W2M8            │
│ <span style="color: magenta; font-weight: 600;">Corrects:</span> 01HXM9A1C2Q7W3R5G8Z0P4Q1X9                │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 2                                          │
╰─────────────────────────────────────────────────────╯

╭─ Affected Subtree ──────────────╮
│ <span style="color: yellow; font-weight: 600;">Decisions Invalidated:</span> 3        │
│ <span style="color: yellow; font-weight: 600;">Child Plans Rolled Back:</span> 2      │
│ <span style="color: yellow; font-weight: 600;">Artifacts Archived:</span> 5           │
│ <span style="color: #5599ff; font-weight: 600;">Unaffected Decisions:</span> 2         │
╰─────────────────────────────────╯

╭─ Sandbox Rollback ─────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Checkpoint:</span> cp_01HXM8C2        │
│ <span style="color: #5599ff; font-weight: 600;">Files Reverted:</span> 5              │
│ <span style="color: #66cc66; font-weight: 600;">Status:</span> restored               │
╰────────────────────────────────╯

╭─ Recompute ──────────────╮
│ <span style="color: yellow; font-weight: 600;">Queued:</span> 2 child plans    │
│ <span style="color: #66cc66; font-weight: 600;">ETA:</span> 4m                  │
╰──────────────────────────╯

╭─ History ───────────────────────────────────────────╮
│ - Original decision superseded                      │
│ - Prior artifacts archived for comparison           │
│ - agents plan diff <span style="color: cyan;">--correction</span> 01HXM9B7Z3Q1Q8K2..  │
╰─────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Correction applied
</code></pre></div>

Using `--mode append` to add a corrective decision without reverting existing work (useful when the original decision was partially correct):

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan correct 01HXM9A1C2Q7W3R5G8Z0P4Q1X9 <span style="color: cyan;">--mode</span> append \
  <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">&quot;Also add rate limiting to the auth endpoints&quot;</span>

╭─ Correction ─────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Mode:</span> append                                     │
│ <span style="color: #66cc66; font-weight: 600;">Impact:</span> adds to existing subtree, no rollback    │
│ <span style="color: #66cc66; font-weight: 600;">New Decision:</span> 01HXM9C3Z5T2Q8K2E9H7K3W2M8         │
│ <span style="color: #5599ff; font-weight: 600;">Appended After:</span> 01HXM9A1C2Q7W3R5G8Z0P4Q1X9       │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 2                                       │
╰──────────────────────────────────────────────────╯

╭─ Append Detail ─────────────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Original decision preserved:</span> yes                                │
│ <span style="color: #5599ff; font-weight: 600;">Existing artifacts kept:</span> yes                                    │
│ <span style="color: #66cc66; font-weight: 600;">Additional work:</span> appended as new child plan                     │
│ <span style="opacity: 0.7;">The original 5 artifacts remain; a new child plan will add</span>      │
│ <span style="opacity: 0.7;">rate-limiting code on top of the existing auth changes.</span>         │
╰─────────────────────────────────────────────────────────────────╯

╭─ Queued ──────────╮
│ <span style="color: yellow;">New child:</span> 1      │
│ <span style="color: #66cc66; font-weight: 600;">ETA:</span> 2m           │
╰───────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Append correction queued
</code></pre></div>

Using `--dry-run` to preview the impact of a correction before committing to it:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan correct 01HXM9A1C2Q7W3R5G8Z0P4Q1X9 <span style="color: cyan;">--mode</span> revert \
  <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">&quot;Use async/await pattern instead&quot;</span> <span style="color: cyan;">--dry-run</span>

╭─ Dry Run — Correction Preview ─────────────────────────────────────╮
│ <span style="color: yellow; font-weight: 600;">⚠  This is a preview only. No changes will be made.</span>                │
╰────────────────────────────────────────────────────────────────────╯

╭─ Would Revert ───────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Decisions to invalidate:</span> 3                           │
│   <span style="opacity: 0.7;">01HXM9A1..  strategy_choice    <span style="color: #66cc66;">"sync pattern"</span></span>      │
│   <span style="opacity: 0.7;">01HXM9A2..  implementation_choice  <span style="color: #66cc66;">"requests"</span></span>      │
│   <span style="opacity: 0.7;">01HXM9A3..  tool_invocation    write_file ×4</span>       │
│ <span style="color: #5599ff; font-weight: 600;">Child plans to roll back:</span> 2                          │
│ <span style="color: #5599ff; font-weight: 600;">Artifacts to archive:</span> 5 files                        │
│ <span style="color: #5599ff; font-weight: 600;">Unaffected decisions:</span> 2 (will be kept)               │
╰──────────────────────────────────────────────────────╯

╭─ Estimated Cost ──────────╮
│ <span style="color: #5599ff; font-weight: 600;">Re-strategize:</span> ~$0.012    │
│ <span style="color: #5599ff; font-weight: 600;">Re-execute:</span> ~$0.035       │
│ <span style="color: #5599ff; font-weight: 600;">Total:</span> ~$0.047            │
│ <span style="color: #5599ff; font-weight: 600;">ETA:</span> ~4 minutes           │
╰───────────────────────────╯

<span style="opacity: 0.7;">To execute this correction, remove --dry-run and add --yes</span>
</code></pre></div>

##### agents plan diff

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> plan diff (<span style="color: magenta;"><span style="color: cyan;">--correction</span> <span style="color: #66cc66;">&lt;CORRECTION_ATTEMPT_ID&gt;</span>|<span style="color: #66cc66;">&lt;PLAN_ID&gt;</span></span>)</code></pre></div>

**Purpose**
Show diffs for a plan or a correction attempt.

**Arguments**

- `<PLAN_ID>`: Show diff for a plan (positional argument). Mutually exclusive with --correction.
- `--correction CORRECTION_ATTEMPT_ID`: Show diff for a correction attempt instead.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan diff 01HXM8C2ZK4Q7C2B3F2R4VYV6J

╭─ Diff Summary ─────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J               │
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service                     │
│ <span style="color: yellow; font-weight: 600;">Files Changed:</span> 2                               │
│ <span style="color: #66cc66; font-weight: 600;">Insertions:</span> 12                                 │
│ <span style="color: #ff6666; font-weight: 600;">Deletions:</span> 4                                   │
│ <span style="color: #5599ff; font-weight: 600;">Net Change:</span> +8 lines                           │
╰────────────────────────────────────────────────╯

╭─ Files ───────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Path</span>                 <span style="color: cyan; font-weight: 600;">Change</span>  <span style="color: cyan; font-weight: 600;">Status</span>   │
│ <span style="opacity: 0.7;">───────────────────  ──────  ────────</span> │
│ src/auth/session.py  <span style="color: #66cc66; font-weight: 600;">+8 -2</span>   modified │
│ src/auth/tokens.py   <span style="color: #66cc66; font-weight: 600;">+4 -2</span>   modified │
╰───────────────────────────────────────╯

╭─ Patch Preview ──────────────────────────╮
│ <span style="opacity: 0.7;">--- a/src/auth/session.py</span>                │
│ <span style="opacity: 0.7;">+++ b/src/auth/session.py</span>                │
│ <span style="color: cyan;">@@ -12,4 +12,10 @@</span>                       │
│ <span style="color: #ff6666;">- import jwt</span>                             │
│ <span style="color: #66cc66;">+ import sessionlib</span>                      │
│ <span style="color: #ff6666;">- def validate_token(...)</span>                │
│ <span style="color: #66cc66;">+ def validate_session(...)</span>              │
│ <span style="opacity: 0.7;">--- a/src/auth/tokens.py</span>                 │
│ <span style="opacity: 0.7;">+++ b/src/auth/tokens.py</span>                 │
│ <span style="color: cyan;">@@ -5,3 +5,7 @@</span>                          │
│ <span style="color: #ff6666;">- TOKEN_EXPIRY = 3600</span>                    │
│ <span style="color: #66cc66;">+ TOKEN_EXPIRY = 7200</span>                    │
╰──────────────────────────────────────────╯

╭─ Risk Assessment ────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">API Compatibility:</span> preserved     │
│ <span style="color: #66cc66; font-weight: 600;">Test Coverage:</span> maintained        │
│ <span style="color: yellow; font-weight: 600;">Breaking Changes:</span> none detected  │
╰──────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Diff generated
</code></pre></div>

Showing the diff for a specific correction attempt, comparing what changed between the original and corrected execution:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan diff <span style="color: cyan;">--correction</span> 01HXM9B7Z3Q1Q8K2E9H7K3W2M8

╭─ Correction Diff ───────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Correction:</span> 01HXM9B7Z3Q1Q8K2E9H7K3W2M8          │
│ <span style="color: #5599ff; font-weight: 600;">Original Decision:</span> 01HXM9A1C2Q7W3R5..           │
│ <span style="color: #5599ff; font-weight: 600;">Mode:</span> revert                                    │
│ <span style="color: yellow;">Files Changed:</span> 3                                │
│ <span style="color: #66cc66;">New Insertions:</span> 18                              │
│ <span style="color: #ff6666;">New Deletions:</span> 6                                │
╰─────────────────────────────────────────────────╯

╭─ Comparison ─────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">File</span>                  <span style="color: cyan; font-weight: 600;">Before (original)</span>  <span style="color: cyan; font-weight: 600;">After (corrected)</span>       │
│ <span style="opacity: 0.7;">────────────────────  ────────────────  ────────────────────</span>     │
│ src/payments/api.py   +12 -4            +18 -6 (expanded)        │
│ src/auth/tokens.py    +8 -2             (unchanged)              │
│ tests/test_payments.py  (new file)      (new file, larger)       │
╰──────────────────────────────────────────────────────────────────╯

╭─ Patch Preview (corrected vs original) ───────────╮
│ <span style="opacity: 0.7;">--- a/src/payments/api.py (original)</span>              │
│ <span style="opacity: 0.7;">+++ b/src/payments/api.py (corrected)</span>             │
│ <span style="color: cyan;">@@ -1,12 +1,18 @@</span>                                 │
│ <span style="color: #ff6666;">- # sync payment processing</span>                       │
│ <span style="color: #66cc66;">+ # async payment processing (corrected)</span>          │
│ <span style="color: #66cc66;">+ import asyncio</span>                                  │
│ <span style="color: #66cc66;">+ from aiohttp import ClientSession</span>               │
│   <span style="opacity: 0.7;">...</span>                                             │
╰───────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Correction diff generated
</code></pre></div>

##### agents plan artifacts

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> plan artifacts <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span></code></pre></div>

**Purpose**
List artifacts produced by a plan.

**Arguments**

- `<PLAN_ID>`: Plan ID.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan artifacts 01HXM8C2ZK4Q7C2B3F2R4VYV6J

╭─ Artifacts ─────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Path</span>                   <span style="color: cyan; font-weight: 600;">Type</span>   <span style="color: cyan; font-weight: 600;">Size</span>    <span style="color: cyan; font-weight: 600;">Change</span>     <span style="color: cyan; font-weight: 600;">Child Plan</span> │
│ <span style="opacity: 0.7;">─────────────────────  ─────  ──────  ─────────  ───────</span>    │
│ src/auth/session.py    write  2.1 KB  <span style="color: #66cc66; font-weight: 600;">+8 -2</span>      root       │
│ tests/test_session.py  write  4.7 KB  <span style="color: #66cc66; font-weight: 600;">+47 -0</span>     root       │
│ src/auth/tokens.py     edit   1.8 KB  <span style="color: #66cc66; font-weight: 600;">+4 -2</span>      root       │
│ tests/test_tokens.py   write  3.2 KB  <span style="color: #66cc66; font-weight: 600;">+32 -0</span>     auth       │
╰─────────────────────────────────────────────────────────────╯

╭─ Summary ───────────╮
│ <span style="color: yellow; font-weight: 600;">Total:</span> 4            │
│ <span style="color: #66cc66; font-weight: 600;">Writes:</span> 2 (new)     │
│ <span style="color: #5599ff; font-weight: 600;">Edits:</span> 2 (modified) │
│ <span style="color: #ff6666; font-weight: 600;">Deletes:</span> 0          │
│ <span style="color: #5599ff; font-weight: 600;">Total Size:</span> 11.8 KB │
╰─────────────────────╯

╭─ By Plan ─────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Root Plan:</span> 3 artifacts    │
│ <span style="color: #5599ff; font-weight: 600;">auth-tests:</span> 1 artifact    │
│ <span style="color: #5599ff; font-weight: 600;">payment-tests:</span> (pending)  │
╰───────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 4 artifacts listed
</code></pre></div>

##### agents plan prompt

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> plan prompt <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span> <span style="color: #66cc66;">&lt;GUIDANCE&gt;</span></code></pre></div>

**Purpose**
Provide additional guidance to a plan, typically when it is errored or awaiting input.

**Arguments**

- `<PLAN_ID>`: Plan ID.
- `"<GUIDANCE>"`: Guidance text.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan prompt 01HXM8C2ZK4Q7C2B3F2R4VYV6J <span style="color: #66cc66;">&quot;Use mocks for database tests&quot;</span>

╭─ Guidance Added ────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J        │
│ <span style="color: magenta; font-weight: 600;">Guidance:</span> Use mocks for database tests  │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> next execution step              │
│ <span style="color: #5599ff; font-weight: 600;">Phase:</span> execute                          │
│ <span style="color: #5599ff; font-weight: 600;">State:</span> errored → processing             │
╰─────────────────────────────────────────╯

╭─ Decision Created ────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> user_intervention                   │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> 01HXM9C5G7R2X8S3K4Z5Q8R6Y3            │
│ <span style="color: #5599ff; font-weight: 600;">Parent:</span> 01HXM9A1C2Q7W3R5G8Z0P4Q1X9        │
╰───────────────────────────────────────────╯

╭─ Queue ────╮
│ <span style="color: yellow; font-weight: 600;">Pending:</span> 1 │
│ <span style="color: #66cc66; font-weight: 600;">Applied:</span> 0 │
╰────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Guidance queued
</code></pre></div>

##### agents plan rollback

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> plan rollback [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;PLAN_ID&gt;</span> <span style="color: #66cc66;">&lt;CHECKPOINT_ID&gt;</span></code></pre></div>

**Purpose**
Rollback a plan sandbox to a checkpoint.

**Arguments**

- `<PLAN_ID>`: Plan ID.
- `<CHECKPOINT_ID>`: Checkpoint ID.
- `--yes`: Skip confirmation.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan rollback 01HXM8C2ZK4Q7C2B3F2R4VYV6J cp_01HXM8C2

Rollback plan 01HXM8C2ZK4Q7C2B3F2R4VYV6J to cp_01HXM8C2? [y/N]: y

╭─ Rollback Summary ───────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J │
│ <span style="color: magenta; font-weight: 600;">Checkpoint:</span> cp_01HXM8C2          │
│ <span style="color: yellow; font-weight: 600;">Label:</span> before auth refactor      │
│ <span style="color: yellow; font-weight: 600;">Files:</span> 6 reverted                │
╰──────────────────────────────────╯

╭─ Changes Reverted ──────────────────╮
│ <span style="color: yellow; font-weight: 600;">File</span>                    <span style="color: yellow; font-weight: 600;">Action</span>      │
│ <span style="opacity: 0.7;">──────────────────────  ──────────</span>  │
│ src/auth/session.py     restored    │
│ src/auth/tokens.py      restored    │
│ tests/test_session.py   removed     │
│ tests/test_tokens.py    removed     │
│ src/auth/fixtures.py    restored    │
│ src/auth/__init__.py    restored    │
╰─────────────────────────────────────╯

╭─ Impact ──────────────────────────────╮
│ <span style="color: yellow; font-weight: 600;">Child Plans Invalidated:</span> 2            │
│ <span style="color: #5599ff; font-weight: 600;">Sandbox:</span> restored to cp_01HXM8C2      │
│ <span style="color: #5599ff; font-weight: 600;">Decisions After CP:</span> 2 discarded       │
│ <span style="color: #5599ff; font-weight: 600;">Tool Calls After CP:</span> 5 undone         │
╰───────────────────────────────────────╯

╭─ Post-Rollback State ──────────╮
│ <span style="color: yellow; font-weight: 600;">Phase:</span> execute                 │
│ <span style="color: #5599ff; font-weight: 600;">State:</span> queued (awaiting input) │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoints Remaining:</span> 2       │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Rollback complete
</code></pre></div>

#### agents action

**Purpose**
Manage reusable actions.

##### agents action create

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> action create (<span style="color: magenta;"><span style="color: cyan;">--config</span>|<span style="color: yellow;">-c</span></span>) <span style="color: #66cc66;">&lt;CFG_FILE&gt;</span></code></pre></div>

**Purpose**
Create a new action template from a YAML configuration file. The `--config` file is required and must fully define the action.

**Arguments**

- `--config/-c FILE`: YAML configuration file defining the action (required). The file must fully define the action, including the `name` field, `strategy-actor`, `execution-actor`, and `definition-of-done`.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action create <span style="color: cyan;">--config</span> ./actions/code-coverage.yaml

╭─ Action Created ────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/code-coverage               │
│ <span style="color: yellow; font-weight: 600;">State:</span> available                        │
│ <span style="color: magenta; font-weight: 600;">Strategy Actor:</span> local/strategist        │
│ <span style="color: magenta; font-weight: 600;">Execution Actor:</span> local/executor         │
│ <span style="color: #66cc66; font-weight: 600;">Reusable:</span> yes                           │
│ <span style="color: #5599ff; font-weight: 600;">Read Only:</span> no                           │
│ <span style="color: #66cc66; font-weight: 600;">Config:</span> ./actions/code-coverage.yaml    │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-08 12:20               │
╰─────────────────────────────────────────╯

╭─ Definition of Done ─╮
│ Coverage reaches 85% │
╰──────────────────────╯

╭─ Arguments ──────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>                     <span style="color: cyan; font-weight: 600;">Type</span>    <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>           │
│ <span style="opacity: 0.7;">───────────────────────  ──────  ────────  ─────────────────────</span> │
│ target_coverage_percent  int     yes       Target coverage %     │
│ test_command             string  no        Test framework to use │
╰──────────────────────────────────────────────────────────────────╯

╭─ Automation ──────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> supervised                   │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> default                       │
╰───────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Action created
</code></pre></div>

##### agents action list

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> action list [(<span style="color: magenta;"><span style="color: cyan;">--namespace</span>|<span style="color: yellow;">-n</span></span>) <span style="color: #66cc66;">&lt;NS&gt;</span>] [(<span style="color: magenta;"><span style="color: cyan;">--state</span>|<span style="color: yellow;">-s</span></span>) <span style="color: #66cc66;">&lt;STATE&gt;</span>] [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]</code></pre></div>

**Purpose**
List actions with optional filters.

**Arguments**

- `--namespace/-n NS`: Filter by namespace.
- `--state/-s STATE`: Filter by state.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action list

╭─ Actions ──────────────────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>                 <span style="color: cyan; font-weight: 600;">State</span>      <span style="color: cyan; font-weight: 600;">Strategy Actor</span>    <span style="color: cyan; font-weight: 600;">Execution Actor</span>  <span style="color: cyan; font-weight: 600;">Reusable</span>  <span style="color: cyan; font-weight: 600;">Plans</span>         │
│ <span style="opacity: 0.7;">───────────────────  ─────────  ────────────────  ───────────────  ────────  ─────</span>         │
│ local/code-coverage  available  local/strategist  local/executor   ✓         3             │
╰────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Filters ────────╮
│ <span style="color: yellow; font-weight: 600;">State:</span> available │
│ <span style="color: #5599ff; font-weight: 600;">Namespace:</span> (any) │
╰──────────────────╯

╭─ Summary ──────────────╮
│ <span style="color: yellow; font-weight: 600;">Total:</span> 1               │
│ <span style="color: #66cc66; font-weight: 600;">Available:</span> 1           │
│ <span style="color: yellow; font-weight: 600;">Archived:</span> 0            │
│ <span style="color: #5599ff; font-weight: 600;">Total Plans Created:</span> 3 │
╰────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 1 action listed
</code></pre></div>

##### agents action show

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> action show <span style="color: #66cc66;">&lt;ACTION_NAME&gt;</span></code></pre></div>

**Purpose**
Show details for an action.

**Arguments**

- `<ACTION_NAME>`: Action name.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action show local/code-coverage

╭─ Action Details ──────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/code-coverage             │
│ <span style="color: yellow; font-weight: 600;">State:</span> available                      │
│ <span style="color: magenta; font-weight: 600;">Strategy Actor:</span> local/strategist      │
│ <span style="color: magenta; font-weight: 600;">Execution Actor:</span> local/executor       │
│ <span style="color: #66cc66; font-weight: 600;">Reusable:</span> yes                         │
│ <span style="color: #5599ff; font-weight: 600;">Read Only:</span> no                         │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-08 12:20             │
╰───────────────────────────────────────╯

╭─ Definition of Done ─╮
│ Coverage reaches 85% │
╰──────────────────────╯

╭─ Arguments ──────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>                     <span style="color: cyan; font-weight: 600;">Type</span>    <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>           │
│ <span style="opacity: 0.7;">───────────────────────  ──────  ────────  ─────────────────────</span> │
│ target_coverage_percent  int     yes       Target coverage %     │
│ test_command             string  no        Test framework to use │
╰──────────────────────────────────────────────────────────────────╯

╭─ Automation ──────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> supervised                   │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> default                       │
╰───────────────────────────────────────╯

╭─ History ────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Plans Created:</span> 3             │
│ <span style="color: #66cc66; font-weight: 600;">Plans Completed:</span> 2           │
│ <span style="color: #ff6666; font-weight: 600;">Plans Failed:</span> 0              │
│ <span style="color: yellow; font-weight: 600;">Avg Duration:</span> 00:04:30       │
│ <span style="color: #5599ff; font-weight: 600;">Avg Cost:</span> $0.072             │
╰──────────────────────────────╯

╭─ Usage ───────────────────────────────────────────────────────────╮
│ - agents plan use local/code-coverage local/api-service           │
│     <span style="color: cyan;">--arg</span> target_coverage_percent=85                              │
╰───────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Action loaded
</code></pre></div>

##### agents action archive

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> action archive <span style="color: #66cc66;">&lt;ACTION_NAME&gt;</span></code></pre></div>

**Purpose**
Archive an action.

**Arguments**

- `<ACTION_NAME>`: Action name.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action archive local/old-action

╭─ Action Archived ───────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/old-action      │
│ <span style="color: yellow; font-weight: 600;">State:</span> available → archived │
│ <span style="color: #66cc66; font-weight: 600;">Archived:</span> 2026-02-08 12:22  │
╰─────────────────────────────╯

╭─ Impact ───────────────────────╮
│ <span style="color: yellow; font-weight: 600;">Availability:</span> hidden from list │
│ <span style="color: #5599ff; font-weight: 600;">Existing Plans:</span> unchanged      │
│ <span style="color: #5599ff; font-weight: 600;">Active Plans:</span> 0 affected       │
╰────────────────────────────────╯

╭─ History ─────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Total Plans:</span> 5            │
│ <span style="color: #66cc66; font-weight: 600;">Completed:</span> 4              │
│ <span style="color: #ff6666; font-weight: 600;">Failed:</span> 1                 │
│ <span style="color: #5599ff; font-weight: 600;">Last Used:</span> 2026-02-06     │
╰───────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Action archived
</code></pre></div>

#### agents automation-profile

**Purpose**
Manage automation profiles — named collections of confidence thresholds (floating-point values from 0.0 to 1.0) that control which tasks are automated vs. require human approval. Each threshold specifies the minimum confidence level at which the system proceeds automatically; below the threshold, the system drops to manual mode. A threshold of 0.0 means "always automatic" and 1.0 means "always manual." Built-in profiles (`manual`, `review`, `supervised`, `cautious`, `trusted`, `auto`, `ci`, `full-auto`) are always available. Custom profiles follow the same `<namespace>/<name>` naming convention as other entities.

##### agents automation-profile add

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> automation-profile add (<span style="color: magenta;"><span style="color: cyan;">--config</span>|<span style="color: yellow;">-c</span></span>) <span style="color: #66cc66;">&lt;FILE&gt;</span> [<span style="color: cyan;">--update</span>]</code></pre></div>

**Purpose**
Register a new custom automation profile from a YAML configuration file. The profile is fully defined by the config file. If a profile with the same name already exists, the command fails unless the `--update` flag is provided.

**Arguments**

- `--config/-c FILE`: YAML configuration file defining the profile (required). The file must fully define the profile, including the `name` field which determines the profile's registered name.
- `--update`: Replace an existing profile with the same name.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> automation-profile add <span style="color: cyan;">--config</span> ./profiles/careful-auto.yaml

╭─ Profile Registered ─────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/careful-auto                                         │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Autonomous execution with mandatory sandbox         │
│              and manual apply                                    │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-08 14:30                                        │
╰──────────────────────────────────────────────────────────────────╯

╭─ Confidence Thresholds ────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">auto_strategize:</span> 0.0                   │
│ <span style="color: #66cc66; font-weight: 600;">auto_execute:</span> 0.0                      │
│ <span style="color: #ff6666; font-weight: 600;">auto_apply:</span> 1.0                        │
│ <span style="color: #66cc66; font-weight: 600;">auto_decisions_strategize:</span> 0.0         │
│ <span style="color: #66cc66; font-weight: 600;">auto_decisions_execute:</span> 0.0            │
│ <span style="color: #66cc66; font-weight: 600;">auto_validation_fix:</span> 0.0               │
│ <span style="color: #ff6666; font-weight: 600;">auto_strategy_revision:</span> 1.0            │
│ <span style="color: #66cc66; font-weight: 600;">auto_child_plans:</span> 0.0                  │
│ <span style="color: #66cc66; font-weight: 600;">auto_retry_transient:</span> 0.0              │
│ <span style="color: #66cc66; font-weight: 600;">auto_checkpoint_restore:</span> 0.0           │
│ <span style="color: #66cc66; font-weight: 600;">require_sandbox:</span> true                  │
│ <span style="color: #66cc66; font-weight: 600;">require_checkpoints:</span> true              │
│ <span style="color: #ff6666; font-weight: 600;">allow_unsafe_tools:</span> false              │
╰────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Profile registered
</code></pre></div>

##### agents automation-profile remove

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> automation-profile remove [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;NAME&gt;</span></code></pre></div>

**Purpose**
Remove a custom automation profile. Built-in profiles cannot be removed.

**Arguments**

- `<NAME>`: Profile name.
- `--yes, -y`: Skip confirmation prompt.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> automation-profile remove local/careful-auto

Remove automation profile local/careful-auto? [y/N]: y

╭─ Profile Removed ──────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/careful-auto   │
╰────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Profile removed
</code></pre></div>

##### agents automation-profile list

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> automation-profile list [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]</code></pre></div>

**Purpose**
List all available automation profiles (built-in and custom).

**Arguments**

- `[REGEX]`: Optional filter pattern.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> automation-profile list

╭─ Automation Profiles ──────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>                <span style="color: cyan; font-weight: 600;">Source</span>    <span style="color: cyan; font-weight: 600;">Auto-Apply</span>  <span style="color: cyan; font-weight: 600;">Sandbox</span>  <span style="color: cyan; font-weight: 600;">Description</span>                 │
│ <span style="opacity: 0.7;">──────────────────  ────────  ──────────  ───────  ────────────────────────</span>    │
│ manual             built-in  1.0         yes      Human-driven (default)       │
│ review             built-in  1.0         yes      Auto-phase, manual decisions │
│ supervised         built-in  1.0         yes      Auto-plan, manual exec       │
│ cautious           built-in  1.0         yes      Confidence-gated automation  │
│ trusted            built-in  1.0         yes      Auto-exec, manual apply      │
│ auto               built-in  1.0         yes      Full auto except apply       │
│ ci                 built-in  0.0         yes      Full auto, safe CI/CD        │
│ full-auto          built-in  0.0         no       Complete automation          │
│ local/careful-auto custom    0.8         yes      Custom careful profile       │
╰────────────────────────────────────────────────────────────────────────────────╯

╭─ Summary ───────────╮
│ <span style="color: #5599ff; font-weight: 600;">Built-in:</span> 8         │
│ <span style="color: #5599ff; font-weight: 600;">Custom:</span> 1           │
│ <span style="color: #5599ff; font-weight: 600;">Total:</span> 9            │
╰─────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 9 profiles listed
</code></pre></div>

##### agents automation-profile show

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> automation-profile show <span style="color: #66cc66;">&lt;NAME&gt;</span></code></pre></div>

**Purpose**
Show full details for an automation profile, including all flag values.

**Arguments**

- `<NAME>`: Profile name.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> automation-profile show trusted

╭─ Automation Profile ───────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> trusted                                                  │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> built-in                                               │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Auto-exec, manual apply. Day-to-day development   │
╰────────────────────────────────────────────────────────────────╯

╭─ Phase Transitions (thresholds) ─────╮
│ <span style="color: #66cc66; font-weight: 600;">auto_strategize:</span> 0.0                 │
│ <span style="color: #66cc66; font-weight: 600;">auto_execute:</span> 0.0                    │
│ <span style="color: #ff6666; font-weight: 600;">auto_apply:</span> 1.0                      │
╰──────────────────────────────────────╯

╭─ Decision Automation (thresholds) ───╮
│ <span style="color: #66cc66; font-weight: 600;">auto_decisions_strategize:</span> 0.0       │
│ <span style="color: #66cc66; font-weight: 600;">auto_decisions_execute:</span> 0.0          │
╰──────────────────────────────────────╯

╭─ Self-Repair (thresholds) ───────────╮
│ <span style="color: #66cc66; font-weight: 600;">auto_validation_fix:</span> 0.0             │
│ <span style="color: #ff6666; font-weight: 600;">auto_strategy_revision:</span> 1.0          │
│ <span style="color: #66cc66; font-weight: 600;">auto_retry_transient:</span> 0.0            │
│ <span style="color: #ff6666; font-weight: 600;">auto_checkpoint_restore:</span> 1.0         │
╰──────────────────────────────────────╯

╭─ Execution Controls (thresholds) ────╮
│ <span style="color: #66cc66; font-weight: 600;">auto_child_plans:</span> 0.0                │
│ <span style="color: #66cc66; font-weight: 600;">require_sandbox:</span> true                │
│ <span style="color: #66cc66; font-weight: 600;">require_checkpoints:</span> true            │
│ <span style="color: #ff6666; font-weight: 600;">allow_unsafe_tools:</span> false            │
╰──────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Profile loaded
</code></pre></div>

#### agents config

**Purpose**
Manage global configuration values.

##### agents config set

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> config set <span style="color: #66cc66;">&lt;key&gt;</span> <span style="color: #66cc66;">&lt;value&gt;</span></code></pre></div>

**Purpose**
Set a configuration key.

**Arguments**

- `<key>`: Hierarchical dot-path key name (e.g., `core.automation-profile`, `core.log.level`, `actor.default.invariant`, `core.format`). See **Global Configuration Keys** for the complete reference.
- `<value>`: Value to set.

The `actor.default.invariant` key sets the default Invariant Reconciliation Actor used globally. This actor is used to reconcile invariant conflicts when neither the plan nor the project specifies one.

The `core.format` key sets the default output rendering format used by all commands. Accepted values are `rich`, `color`, `table`, `plain`, `json`, `yaml`. When set, this value is used unless overridden by the `--format` CLI flag. See **Output Rendering Framework** for details.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set core.automation-profile trusted

╭─ Config Updated ──────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Key:</span> core.automation-profile          │
│ <span style="color: #66cc66; font-weight: 600;">Value:</span> trusted                        │
│ <span style="color: yellow; font-weight: 600;">Previous:</span> manual                      │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> config                        │
│ <span style="color: yellow; font-weight: 600;">Scope:</span> global                         │
╰───────────────────────────────────────╯

╭─ Effective ────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Sessions:</span> new sessions             │
│ <span style="color: yellow; font-weight: 600;">Plans:</span> future plans (unless set)   │
│ <span style="color: #5599ff; font-weight: 600;">Existing:</span> unchanged                │
╰────────────────────────────────────╯

╭─ Saved To ──────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">File:</span> ~/.cleveragents/config.toml   │
│ <span style="color: #5599ff; font-weight: 600;">Line:</span> 8                             │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Config updated
</code></pre></div>

Setting the default output format:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set core.format table

╭─ Config Updated ─────────────────╮
│ <span style="color: cyan; font-weight: 600;">Key:</span> core.format                 │
│ <span style="color: #5599ff; font-weight: 600;">Previous:</span> rich                   │
│ <span style="color: #66cc66; font-weight: 600;">New Value:</span> table                 │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> user (~/.cleveragents)    │
╰──────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Set core.format = table
</code></pre></div>

Setting a global invariant actor:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set actor.default.invariant local/invariant-resolver

╭─ Config Updated ──────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Key:</span> actor.default.invariant                      │
│ <span style="color: #5599ff; font-weight: 600;">Previous:</span> (not set)                               │
│ <span style="color: #66cc66; font-weight: 600;">New Value:</span> local/invariant-resolver               │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> user (~/.cleveragents)                     │
╰───────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Set actor.default.invariant = local/invariant-resolver
</code></pre></div>

##### agents config get

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> config get <span style="color: #66cc66;">&lt;key&gt;</span></code></pre></div>

**Purpose**
Get a configuration value.

**Arguments**

- `<key>`: Key to read.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config get core.automation-profile

╭─ Config ──────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Key:</span> core.automation-profile      │
│ <span style="color: #66cc66; font-weight: 600;">Value:</span> trusted                    │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> config                    │
│ <span style="color: yellow; font-weight: 600;">Overridden:</span> no                    │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> string                      │
╰───────────────────────────────────╯

╭─ Origin ──────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">File:</span> ~/.cleveragents/config.toml │
│ <span style="color: #66cc66; font-weight: 600;">Line:</span> 8                           │
│ <span style="color: #5599ff; font-weight: 600;">Default:</span> supervised               │
╰───────────────────────────────────╯

╭─ Resolution Chain ──────────────╮
│ 1. CLI flag: (not set)          │
│ 2. Env var: (not set)           │
│ 3. Config file: trusted         │
│ 4. Default: supervised          │
│ <span style="color: #66cc66; font-weight: 600;">Winner:</span> config file (level 3)   │
╰─────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Config read
</code></pre></div>

##### agents config list

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> config list [<span style="color: cyan;">--filter-values</span> <span style="color: #66cc66;">&lt;REGEX&gt;</span>] [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]</code></pre></div>

**Purpose**
List all configuration values.

**Arguments**

None.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config list

╭─ Config ───────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Key</span>               <span style="color: cyan; font-weight: 600;">Value</span>               <span style="color: cyan; font-weight: 600;">Source</span>   <span style="color: cyan; font-weight: 600;">Modified</span>    │
│ <span style="opacity: 0.7;">────────────────  ──────────────────  ───────  ────────</span>    │
│ core.automation-profile  trusted             config   yes  │
│ actor.default.invariant local/reconciler    config   yes   │
│ core.log.level          FATAL               default  no    │
╰────────────────────────────────────────────────────────────╯

╭─ Overrides ─────╮
│ <span style="color: yellow; font-weight: 600;">Env:</span> none       │
│ <span style="color: #5599ff; font-weight: 600;">CLI Flags:</span> none │
╰─────────────────╯

╭─ Config File ───────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Path:</span> ~/.cleveragents/config.toml   │
│ <span style="color: #5599ff; font-weight: 600;">Size:</span> 284 bytes                     │
│ <span style="color: #66cc66; font-weight: 600;">Valid:</span> yes                          │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 6 settings listed
</code></pre></div>

#### agents invariant

**Purpose**
Manage invariants — named constraints that guide and constrain plan execution. Invariants can be attached to any scope: global (all plans), project (all plans targeting that project), plan (a specific plan and its child plans), or action (carried forward when the action is used). Exactly one scope flag is required for `add` and `list`.

##### agents invariant add

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> invariant add [<span style="color: cyan;">--global</span>] [(<span style="color: cyan;">--project</span>|<span style="color: yellow;">-p</span>) PROJECT] [<span style="color: cyan;">--plan</span> PLAN_ID]...
                     [<span style="color: cyan;">--action</span> ACTION]... <span style="color: #66cc66;">&lt;INVARIANT_TEXT&gt;</span></code></pre></div>

**Purpose**
Add an invariant at the specified scope.

**Arguments**

- `<INVARIANT_TEXT>`: The invariant text (positional argument at end of command).
- `--global`: Attach as a global invariant (applies to all plans).
- `--project/-p PROJECT`: Attach to a project (applies to all plans targeting this project).
- `--plan PLAN_ID`: Attach to a plan (plan-level invariant). Repeatable.
- `--action ACTION`: Attach to an action (action-level invariant). Repeatable.

At least one scope flag (`--global`, `--project`, `--plan`, or `--action`) must be provided. `--plan` and `--action` can be repeated to attach the same invariant to multiple plans or actions.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> invariant add <span style="color: cyan;">--global</span> <span style="color: #66cc66;">&quot;All public APIs must maintain backward compatibility&quot;</span>

╭─ Invariant Added ──────────────────────────────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Invariant:</span> All public APIs must maintain backward compatibility        │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> global                                                          │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> inv_01HXM9A1B                                                      │
╰────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Invariant added

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> invariant add <span style="color: cyan;">--project</span> local/api-service <span style="color: #66cc66;">&quot;All endpoints must validate auth tokens&quot;</span>

╭─ Invariant Added ──────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service                                     │
│ <span style="color: #66cc66; font-weight: 600;">Invariant:</span> All endpoints must validate auth tokens             │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> project                                                 │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> inv_01HXM9A2C                                              │
╰────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Invariant added

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> invariant add <span style="color: cyan;">--plan</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J <span style="color: #66cc66;">&quot;All database queries must use parameterized statements&quot;</span>

╭─ Invariant Added ─────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J                                      │
│ <span style="color: #66cc66; font-weight: 600;">Invariant:</span> All database queries must use parameterized statements     │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> plan                                                           │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> inv_01HXM9G3A                                                     │
╰───────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Invariant added

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> invariant add <span style="color: cyan;">--action</span> local/code-coverage <span style="color: #66cc66;">&quot;Test files must not import production secrets&quot;</span>

╭─ Invariant Added ──────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Action:</span> local/code-coverage                                            │
│ <span style="color: #66cc66; font-weight: 600;">Invariant:</span> Test files must not import production secrets               │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> action                                                          │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> inv_01HXM9H4B                                                      │
╰────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Invariant added
</code></pre></div>

##### agents invariant list

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> invariant list [<span style="color: cyan;">--global</span>] [(<span style="color: cyan;">--project</span>|<span style="color: yellow;">-p</span>) PROJECT] [<span style="color: cyan;">--plan</span> PLAN_ID] [<span style="color: cyan;">--action</span> ACTION]
                     [<span style="color: cyan;">--effective</span>] [<span style="color: #66cc66;">&lt;REGEX&gt;</span>]</code></pre></div>

**Purpose**
List invariants at a given scope. Use `--effective` with `--plan` to show the final reconciled view of invariants (after precedence resolution) rather than just the invariants directly attached at that scope.

**Arguments**

- `--global`: List global invariants.
- `--project/-p PROJECT`: List invariants attached to a project.
- `--plan PLAN_ID`: List invariants attached to a plan.
- `--action ACTION`: List invariants attached to an action.
- `--effective`: (Only with `--plan`) Show the reconciled invariant view after precedence resolution across all scopes.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> invariant list <span style="color: cyan;">--global</span>

╭─ Global Invariants ──────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>              <span style="color: cyan; font-weight: 600;">Text</span>                                                     │
│ <span style="opacity: 0.7;">──────────────  ────────────────────────────────────────────────────</span>     │
│ inv_01HXM9A1B  All public APIs must maintain backward compatibility      │
│ inv_01HXM9A1C  Payment processing must be idempotent                     │
╰──────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 2 invariants

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> invariant list <span style="color: cyan;">--plan</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J <span style="color: cyan;">--effective</span>

╭─ Effective Invariants (Plan 01HXM8C2ZK4Q7C2B3F2R4VYV6J) ──────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>              <span style="color: cyan; font-weight: 600;">Source</span>   <span style="color: cyan; font-weight: 600;">Text</span>                                                             │
│ <span style="opacity: 0.7;">──────────────  ───────  ──────────────────────────────────────────────────────</span>           │
│ inv_01HXM9A1B  global   All public APIs must maintain backward compatibility              │
│ inv_01HXM9A2C  project  All endpoints must validate auth tokens                           │
│ inv_01HXM9G3A  plan     All database queries must use parameterized statements            │
╰───────────────────────────────────────────────────────────────────────────────────────────╯

│ <span style="color: yellow; font-weight: 600;">Conflicts Resolved:</span> 1                                                              │
│ <span style="opacity: 0.7;">  Global <span style="color: #66cc66;">"Use shared DB pool"</span> overridden by plan "All database queries must use    │
│   parameterized statements"</span>                                                         │

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 3 effective invariants (1 global, 1 project, 1 plan; 1 conflict resolved)
</code></pre></div>

##### agents invariant remove

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">agents</span> invariant remove [<span style="color: cyan;">--yes</span>|<span style="color: yellow;">-y</span>] <span style="color: #66cc66;">&lt;INVARIANT_ID&gt;</span></code></pre></div>

**Purpose**
Remove an invariant by ID. The invariant is removed from whichever scope it was originally attached to.

**Arguments**

- `<INVARIANT_ID>`: Invariant ID to remove.
- `--yes`: Skip confirmation.

**Examples**

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> invariant remove inv_01HXM9A1C

Remove invariant inv_01HXM9A1C (<span style="color: #66cc66;">"Payment processing must be idempotent"</span>, scope: global)? [y/N]: y

╭─ Invariant Removed ──────────────────────────────────────────────╮
│ <span style="color: yellow; font-weight: 600;">Removed:</span> Payment processing must be idempotent                   │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> global                                                    │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> inv_01HXM9A1C                                                │
╰──────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Invariant removed
</code></pre></div>

## Core Concepts

### Plan

A **plan** is the fundamental unit of orchestration and traceability.

#### Plan Lifecycle Phases

A plan always moves through the following phases, in order:

**Strategize → Execute → Apply → Applied (terminal)**

In this spec:

* **Strategize** is the phase name (the output is a **strategy**).
* **Execute** is the phase name (the output is a **changeset**).
* **Apply** is the phase name (the output is an **applied change**).
* **Applied** is the resulting terminal state after Apply succeeds.

This four-stage model is explicitly called out as the new architecture replacing a prior linear pipeline.

#### Phase Transition Verbs (CLI / UX Contract)

 Verbs that trigger phase transitions. CleverAgents should standardize these verbs as the **public API** (CLI, TUI, web):

| Current Phase | Command Verb | Next Phase |
| ------------- | ------------ | ---------- |
| (none)        | `create`     | Action     |
| Action        | `use`        | Strategize |
| Strategize    | `execute`    | Execute    |
| Execute       | `apply`      | Applied    |

**Important behavioral rule:**
CleverAgents uses **automation profiles** to control which of these phase transitions happen automatically. The profile determines whether each transition requires explicit user action or proceeds autonomously, but the verbs remain the conceptual contract.

#### Plan States (Per Phase)

A plan's phase indicates "what step of the lifecycle it is in." Separately, the plan has a **processing state** indicating "what is happening right now."

Recommended state model:

* **Action phase states**

  * `available` (action exists and can be used)
  * `archived` (soft-deleted or hidden, optional)

* **Strategize / Execute / Apply phase states**

  * `queued` (waiting for compute/worker)
  * `processing` (currently running)
  * `errored` (failed; includes error metadata)
  * `complete` (finished successfully)
  * `cancelled` (user/system cancelled; safe terminal for that phase)

#### Plan Identity and Traceability

Every plan should have:

* **plan_id**: Unique, immutable ID (UUID or ULID).
* **parent_plan_id**: Nullable; present for child plans.
* **root_plan_id**: The top-most plan in the tree.
* **attempt**: An integer attempt counter that increments when re-running a phase (e.g., re-executing after a fix).
* **created_at / updated_at / completed_at** timestamps.
* **created_by** (user identity / session identity).

#### Plan Hierarchy and Parallelism

A single plan should usually represent the smallest "complete" unit of work (similar to what would fit in one git commit). However:

* **Plans are hierarchical.** A child plan is simply a Plan with a parent — it follows the same lifecycle, has the same data model, and is functionally identical to a root plan except that it has a `parent_plan_id`.
* **Decisions about child plans are made during Strategize** (as `subplan_spawn` decision types). Multiple child plans that should execute concurrently are grouped under a `subplan_parallel_spawn` decision.
* **Child plans are actually spawned during Execute** (based on those decisions).
* Child plans can run **in parallel** (via `subplan_parallel_spawn`) or **sequentially** (via individual `subplan_spawn` decisions). Without a `subplan_parallel_spawn` wrapper, each `subplan_spawn` decision results in sequential execution.
* **Applicable invariants are enforced** during Strategize by adding `invariant_enforced` decisions to the tree, which constrain downstream decisions and child plans.
* The parent plan is responsible for **merging results**.

This is core to the long-term objective: tackling large tasks while only recomputing parts of the decision tree when corrected.

##### Hierarchical Decomposition for Scale

When handling massive tasks (e.g., converting Firefox to Rust), the system uses hierarchical decomposition. Each level spawns child plans (which are themselves full Plans with their own decision trees):

1. **Root Plan**: High-level architectural decisions and invariants
   - "Convert Firefox Renderer to Rust"
   - Invariant: "Maintain API compatibility with existing C++ callers"
   - Decision: "Start with leaf modules, work inward"
   - Context: Module dependency graph (2,847 modules)

2. **Subsystem-Level Plans**: Major component decisions (spawned via `subplan_parallel_spawn` for independent subsystems)
   - "Phase 1: Convert utility libraries (no external deps)"
   - Each subsystem plan gets its own bounded context and inherits parent invariants
    
3. **Module-Level Plans**: Individual module conversions
   - "Convert string_utils module"
   - Context: Only the 47 functions and 12 dependent files
   - Decision: "Use Rust's String type"

4. **File-Level Plans**: Specific file changes
   - Actual code transformations
   - Minimal context needed

At each level, only the relevant context is loaded. The persistent decision graph means we can always reconstruct why we're converting a particular module and what constraints (including inherited invariants) apply from higher-level decisions.

##### Child Plan Spawning Mechanism

In the actor definition for the execution actor, tool nodes can directly invoke registered tools to trigger child plans. The `local/create-subplan` tool is independently registered and referenced by name in the actor graph node. During execution, `subplan_spawn` decisions are realized as actual child plans, and `subplan_parallel_spawn` groups trigger concurrent spawning of all enclosed child plans.

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Example: Execution actor with subplan spawning capability.</span>
<span style="opacity: 0.7;"># The graph uses a tool node referencing a named registered tool.</span>
<span style="color: cyan; font-weight: 600;">actors</span>:
  <span style="color: cyan; font-weight: 600;">code_executor</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: graph
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">actor</span>: anthropic/claude-3-opus
    <span style="color: cyan; font-weight: 600;">skills</span>:
      - local/plan-tools          # Skill containing create_subplan for LLM tool-calling
      - local/file-ops
    <span style="color: cyan; font-weight: 600;">routes</span>:
      <span style="color: cyan; font-weight: 600;">execute_workflow</span>:
        <span style="color: cyan; font-weight: 600;">nodes</span>:
          - <span style="color: cyan;">name</span>: spawn_test_subplan
            <span style="color: cyan; font-weight: 600;">type</span>: tool
            <span style="color: cyan; font-weight: 600;">tool</span>: local/create-subplan <span style="opacity: 0.7;"># Named tool from Tool Registry</span>
</code></pre></div>

The `local/create-subplan` tool is independently registered via its own YAML configuration file:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># File: tools/create-subplan.yaml</span>
<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">&quot;3.0&quot;</span>

<span style="color: cyan; font-weight: 600;">tool</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/create-subplan
  <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Spawn a subplan for a given action&quot;</span>
  <span style="color: cyan; font-weight: 600;">source</span>: custom

  <span style="color: cyan; font-weight: 600;">input_schema</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: object
    <span style="color: cyan; font-weight: 600;">properties</span>:
      <span style="color: cyan; font-weight: 600;">action</span>: { type: string }
      <span style="color: cyan; font-weight: 600;">target_files</span>: { type: array, items: { type: string } }
    <span style="color: cyan; font-weight: 600;">required</span>: [action]

  <span style="color: cyan; font-weight: 600;">capability</span>:
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">side_effects</span>: [spawn_subplan]

  <span style="color: cyan; font-weight: 600;">code</span>: <span style="color: #66cc66;">|</span>
    subplan = ctx.spawn_subplan(
        action=params[&quot;action&quot;],
        target_files=params.get(&quot;target_files&quot;, [])
    )
    return {&quot;subplan_id&quot;: subplan.id}
</code></pre></div>

The `local/plan-tools` skill references this tool (and others) by name:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># File: skills/plan-tools.yaml</span>
<span style="color: cyan; font-weight: 600;">skill</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/plan-tools
  <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Tools for spawning and managing subplans&quot;</span>
  <span style="color: cyan; font-weight: 600;">tools</span>:
    - local/create-subplan
</code></pre></div>

##### Child Plan Execution Modes

* **Sequential**: Individual `subplan_spawn` decisions without a `subplan_parallel_spawn` wrapper execute one after another. If one fails, subsequent child plans are not started.
* **Parallel**: Multiple `subplan_spawn` decisions grouped under a `subplan_parallel_spawn` decision execute concurrently. If one fails, others can continue. The `subplan_parallel_spawn` decision acts as a container that signals the system to spawn all enclosed child plans simultaneously.

##### Child Plan Failure Handling

* **Parallel execution** (via `subplan_parallel_spawn`): Other parallel child plans continue even if one fails.
* **Sequential execution**: Subsequent child plans are not started if a prior one fails.
* **Note**: An "error" only occurs if an exception is thrown by the application (a bug). Plan failures (e.g., tests don't pass) are handled within the plan's logic, not as application errors.

##### Child Plan Result Merging

The way child plan results are merged depends on the resource type:

* **Git-compatible resources** (source code, text files): Git-style merge
* **Databases**: Transaction coordination or sequential application
* **Other resources**: Pluggable merge strategies based on resource type
* **Non-mergeable resources**: May require sequential execution only

#### The Plan "Decision Tree" and Visualization

CleverAgents intends to record enough information to render:

* an **ASCII tree** in the TUI, and
* optionally a GUI tree via visualization tools (D3/Cytoscape) once the data exists.

This implies each plan should persist:

* decisions made,
* the rationale (or at least the prompt/context snapshot that produced it),
* dependencies ("this decision influenced these child plans").

This is required for "correcting plans" (see Behavior section).


#### Decision Data Model

##### Relationship Between Plan Description and Decisions

Each plan has a **description field** (inherited from the action's description, potentially with argument substitutions). This description acts as the **primary component of the prompt** fed to the strategy actor during the Strategize phase.

**Decisions are choices that are NOT explicitly defined by the plan description.** They represent the gaps, ambiguities, or implementation details that must be resolved to execute the plan.

For example:
- **Plan description**: "Increase test coverage to 85%"
- **Decisions that emerge**: 
  - "Which modules should be prioritized?" (not specified in description)
  - "Should we use mocks or integration tests for the database layer?" (not specified)
  - "Should we refactor the auth module to make it more testable, or write tests around it as-is?" (not specified)

##### Decision Making Based on Autonomy Level

Who makes decisions depends on the plan's **automation profile**:

| Profile Flag | Who Makes Decisions |
|-------------|---------------------|
| `auto_decisions_strategize = 1.0` (always manual) | User is prompted for each decision point during Strategize |
| `auto_decisions_strategize = 0.0` (always automatic) | Strategy actor makes decisions autonomously, records reasoning |
| `auto_decisions_execute = 1.0` (always manual) | User is prompted for each decision point during Execute |
| `auto_decisions_execute = 0.0` (always automatic) | Execution actor makes decisions autonomously |

Intermediate thresholds (e.g., `auto_decisions_strategize = 0.7`) cause the system to auto-decide only when the Semantic Escalation confidence score meets or exceeds the threshold; otherwise the user is prompted.

When **automation allows automatic decisions**, the strategy actor uses its best judgment based on context, and records its reasoning in the decision's `rationale` field.

When **user input is required**, the system pauses and prompts the user:

<div class="highlight"><pre><code>
Decision required: Which modules should be prioritized for test coverage?

Options identified by the strategy actor:
  1. auth module (currently 45% coverage, high risk)
  2. payment module (currently 52% coverage, high risk)  
  3. user module (currently 71% coverage, medium risk)

Your choice (or provide custom guidance): _
</code></pre></div>

##### The Prompt as the Root Decision

**The prompt passed to the strategize actor is itself a decision node** in the decision tree—specifically, it's the **root decision** of type `prompt_definition`.

This is important because:

1. **Every plan has its own prompt**: The root plan's prompt comes from the action description + user arguments. Child plan prompts are created by parent plans during their execution.

2. **Parent plans create child plan prompts**: When a parent plan spawns a child plan, it decides what prompt to give that child plan. This is recorded as a `prompt_definition` decision in the parent's tree, and becomes the root decision of the child plan's tree.

3. **Invariants flow into the decision tree**: During Strategize, applicable invariants (from global, project, action, and plan scopes) are reconciled via the **Invariant Reconciliation Actor** and recorded as `invariant_enforced` decisions, making them explicit constraints that influence downstream decisions and child plans.

4. **Unified correction mechanism**: Since the prompt, invariants, and all other decisions are part of the same tree, correcting any of them uses the same `agents plan correct` command.

<div class="highlight"><pre><code>
Plan: 01KH29QDEE6DZTXKWNKCV8VP0F
├── [<span style="color: magenta;">prompt_definition</span>] &quot;Increase test coverage to 85% for the whole project.&quot;
├── [<span style="color: magenta;">invariant_enforced</span>] &quot;Prioritize all functionality related to financial transactions and user management&quot;
├── [<span style="color: magenta;">invariant_enforced</span>] &quot;All API calls over TCP must be mocked&quot;
├── [<span style="color: magenta;">strategy_choice</span>] &quot;Prioritize auth and payment modules, implement them in parallel before the rest&quot;
├── [<span style="color: magenta;">subplan_parallel_spawn</span>] &quot;Implement auth and payment modules, in parallel&quot;
│   ├── [<span style="color: magenta;">subplan_spawn</span>] &quot;Write tests for auth module&quot;
│   │   └── Plan: 01KH29R8WPKPBHRY7Q0NA9XW86
│   │       ├── [<span style="color: magenta;">prompt_definition</span>] &quot;Write unit tests for auth module using mocks for the remote API calls&quot;
│   │       ├── [<span style="color: magenta;">implementation_choice</span>] &quot;Test login flow first&quot;
│   │       └── ...
│   └── [<span style="color: magenta;">subplan_spawn</span>] &quot;Write tests for payment module&quot;
│       └── Plan: 01KH29RN2YKSXMTBDG82AKRHRA
│           ├── [<span style="color: magenta;">prompt_definition</span>] &quot;Write unit tests for payment module using&quot;
│           └── ...
└── [<span style="color: magenta;">subplan_parallel_spawn</span>] &quot;Write tests for all modules except the auth and payment modules&quot;
    └──  ...
</code></pre></div>

##### Correcting Decisions (Including Prompts)

All corrections use the same unified command:

<div class="highlight"><pre><code>
agents plan correct &lt;decision_id&gt; <span style="color: cyan;">--mode</span>=&lt;mode&gt; <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">&quot;&lt;corrected decision text&gt;&quot;</span>
</code></pre></div>

**Parameters:**
* `<decision_id>`: The ULID of the decision to correct
* `--mode`: Either `revert` (rollback and re-run) or `append` (add fix at end)
* `--guidance`: Free-form text specifying what the correct decision should be

**Examples:**

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Correct a strategy choice</span>
agents plan correct 01ARZ3NDEKTSV4RRFFQ69G5FAV <span style="color: cyan;">--mode</span>=revert <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">&quot;Prioritize the payment module first, not auth, due to upcoming deadline&quot;</span>

<span style="opacity: 0.7;"># Correct the root prompt to be more specific</span>
agents plan tree &lt;plan_id&gt;
<span style="opacity: 0.7;"># Shows: [prompt_definition] id=01ARZ3NDEKTSV4RRFFQ69G5FAV &quot;Increase test coverage to 85%&quot;</span>

agents plan correct 01ARZ3NDEKTSV4RRFFQ69G5FAV <span style="color: cyan;">--mode</span>=revert <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">&quot;Increase test coverage to 85%, prioritizing auth and payment modules. Use mocks for database tests, not integration tests.&quot;</span>

<span style="opacity: 0.7;"># Correct a subplan&#x27;s prompt (originally created by parent plan)</span>
agents plan correct 01BRZ4PDFLUTW5SSGR70H6GBW <span style="color: cyan;">--mode</span>=revert <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">&quot;Write unit tests for auth module, focusing on edge cases for token expiration&quot;</span>

<span style="opacity: 0.7;"># Append a fix rather than rewriting history</span>
agents plan correct 01ARZ3NDEKTSV4RRFFQ69G5FAV <span style="color: cyan;">--mode</span>=append <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">&quot;The previous approach missed error handling tests - add comprehensive error path coverage&quot;</span>

<span style="opacity: 0.7;"># Remove an invariant that shouldn&#x27;t apply</span>
agents plan correct 01CRZ5QEHMVUX6TTHR81I7HCX <span style="color: cyan;">--mode</span>=revert <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">&quot;Remove this invariant - TCP mocking is not needed for this module since it has no network calls&quot;</span>

<span style="opacity: 0.7;"># Add a missing invariant to the plan</span>
agents invariant add <span style="color: cyan;">--plan</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J <span style="color: #66cc66;">&quot;All database queries must use parameterized statements&quot;</span>
</code></pre></div>

**Note:** CLI commands should not require interactive input. The `--guidance` parameter provides the correction inline.

**When to correct the prompt vs. a specific decision:**

| Situation | Correction Approach |
|-----------|---------------------|
| Original request was too vague | Correct the `prompt_definition` decision |
| Strategy actor made a bad choice on a specific question | Correct that specific decision |
| Parent plan gave a child plan a bad prompt | Correct the child plan's `prompt_definition` |
| An invariant should not apply to this plan | Correct (remove) the `invariant_enforced` decision |
| A missing constraint should be added | Add a new `invariant_enforced` decision via `agents invariant add --plan` or correct the plan's strategy |
| Sequential child plans should run in parallel | Correct the relevant decisions to use a `subplan_parallel_spawn` grouping |

Because the prompt is part of the decision tree, the system automatically knows that correcting it invalidates all downstream decisions in that plan (and its child plans).

**Decisions are only created during the Strategize phase.** The decision tree captures what choices were made and why, enabling correction and replay.

##### Decision Record Structure

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">Decision</span>:
<span style="opacity: 0.7;">  # Identity</span>
  <span style="color: cyan; font-weight: 600;">decision_id</span>: ULID <span style="opacity: 0.7;"># Unique identifier</span>
  <span style="color: cyan; font-weight: 600;">plan_id</span>: ULID <span style="opacity: 0.7;"># Parent plan this decision belongs to</span>
  <span style="color: cyan; font-weight: 600;">parent_decision_id</span>: ULID | null <span style="opacity: 0.7;"># Parent decision (for tree structure)</span>
  <span style="color: cyan; font-weight: 600;">sequence_number</span>: int <span style="opacity: 0.7;"># Order within the plan&#x27;s decisions</span>
  
<span style="opacity: 0.7;">  # Classification</span>
  <span style="color: cyan; font-weight: 600;">decision_type</span>: enum
    - prompt_definition         # The prompt/description for this plan (root decision)
    - invariant_enforced        # An invariant (from global, project, action, or plan scope) applicable to this plan, added as a constraint
    - strategy_choice           # High-level approach decision during Strategize
    - implementation_choice     # How to implement a specific task
    - resource_selection        # Which resources to read/modify
    - subplan_spawn             # Decision to create a child plan (spawned later in Execute)
    - subplan_parallel_spawn    # Decision to spawn a group of child plans in parallel (contains subplan_spawn children)
    - tool_invocation           # Which skill/tool to use
    - error_recovery            # How to handle a failure
    - validation_response       # Response to validation failure
    - user_intervention         # User provided guidance/correction
  
<span style="opacity: 0.7;">  # The Decision Itself</span>
  <span style="color: cyan; font-weight: 600;">question</span>: str <span style="opacity: 0.7;"># What question was being answered</span>
  <span style="color: cyan; font-weight: 600;">chosen_option</span>: str <span style="opacity: 0.7;"># What was decided</span>
  <span style="color: cyan; font-weight: 600;">alternatives_considered</span>: list[str] <span style="opacity: 0.7;"># Other options that were evaluated</span>
  <span style="color: cyan; font-weight: 600;">confidence_score</span>: float | null <span style="opacity: 0.7;"># 0.0-1.0 if the actor provided confidence</span>
  
<span style="opacity: 0.7;">  # Context Snapshot (for replay)</span>
  <span style="color: cyan; font-weight: 600;">context_snapshot</span>:
    <span style="color: cyan; font-weight: 600;">hot_context_hash</span>: str <span style="opacity: 0.7;"># Cryptographic hash of the exact context</span>
    <span style="color: cyan; font-weight: 600;">hot_context_ref</span>: str <span style="opacity: 0.7;"># Pointer to the full stored snapshot</span>
    <span style="color: cyan; font-weight: 600;">relevant_resources</span>: list[ResourceRef] <span style="opacity: 0.7;"># Every file/symbol that influenced this decision</span>
    <span style="color: cyan; font-weight: 600;">actor_state_ref</span>: str <span style="opacity: 0.7;"># Complete LangGraph checkpoint</span>
    
<span style="opacity: 0.7;">  # When the system decides &quot;refactor the authentication module to use async patterns,&quot; </span>
<span style="opacity: 0.7;">  # it permanently records:</span>
<span style="opacity: 0.7;">  # - Which files were examined to make that decision</span>
<span style="opacity: 0.7;">  # - What symbols and dependencies were traced</span>
<span style="opacity: 0.7;">  # - The exact code state that was analyzed</span>
<span style="opacity: 0.7;">  # - The reasoning chain that led to this choice</span>
<span style="opacity: 0.7;">  # - Alternative approaches that were considered but rejected</span>
  
<span style="opacity: 0.7;">  # Rationale</span>
  <span style="color: cyan; font-weight: 600;">rationale</span>: str <span style="opacity: 0.7;"># Why this option was chosen</span>
  <span style="color: cyan; font-weight: 600;">actor_reasoning</span>: str | null <span style="opacity: 0.7;"># Raw LLM reasoning if available</span>
  
<span style="opacity: 0.7;">  # Downstream Impact (populated during Execute phase)</span>
  <span style="color: cyan; font-weight: 600;">downstream_decision_ids</span>: list[ULID] <span style="opacity: 0.7;"># Decisions that depend on this one</span>
  <span style="color: cyan; font-weight: 600;">downstream_plan_ids</span>: list[ULID] <span style="opacity: 0.7;"># Child plans spawned because of this decision</span>
  <span style="color: cyan; font-weight: 600;">artifacts_produced</span>: list[ArtifactRef] <span style="opacity: 0.7;"># Files/outputs created under this decision</span>
  
<span style="opacity: 0.7;">  # Timestamps</span>
  <span style="color: cyan; font-weight: 600;">created_at</span>: datetime
  
<span style="opacity: 0.7;">  # Correction Metadata</span>
  <span style="color: cyan; font-weight: 600;">is_correction</span>: bool <span style="opacity: 0.7;"># Was this decision a correction of another?</span>
  <span style="color: cyan; font-weight: 600;">corrects_decision_id</span>: ULID | null <span style="opacity: 0.7;"># If correction, which decision was replaced</span>
  <span style="color: cyan; font-weight: 600;">correction_reason</span>: str | null <span style="opacity: 0.7;"># Why the correction was made</span>
  <span style="color: cyan; font-weight: 600;">superseded_by</span>: ULID | null <span style="opacity: 0.7;"># If this decision was later corrected</span>
</code></pre></div>

##### Decision Timing

| Phase | Decision Activity |
|-------|-------------------|
| **Strategize** | Decisions are **created**, including `invariant_enforced` decisions for applicable invariants, `subplan_spawn` decisions, and `subplan_parallel_spawn` decisions grouping parallel child plans. `downstream_plan_ids` is empty. |
| **Execute** | Child plans are **spawned**. `downstream_plan_ids` is **populated** when child plans are created based on `subplan_spawn` decisions (both standalone and those within `subplan_parallel_spawn` groups). |
| **Apply** | No new decisions. History can be flagged for cleanup after successful apply. |

##### Decision Tree Storage Schema

<div class="highlight"><pre><code>
<span style="opacity: 0.7;">-- Core decision table</span>
<span style="color: #5599ff; font-weight: 600;">CREATE</span> <span style="color: #5599ff; font-weight: 600;">TABLE</span> decisions (
    decision_id <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">PRIMARY</span> <span style="color: #5599ff; font-weight: 600;">KEY</span>,      -- ULID
    plan_id <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,
    parent_decision_id <span style="color: #5599ff; font-weight: 600;">TEXT</span>,
    sequence_number <span style="color: #5599ff; font-weight: 600;">INTEGER</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,
    decision_type <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,        -- prompt_definition, invariant_enforced, strategy_choice,
<span style="opacity: 0.7;">                                       -- implementation_choice, resource_selection, subplan_spawn,</span>
<span style="opacity: 0.7;">                                       -- subplan_parallel_spawn, tool_invocation, error_recovery,</span>
<span style="opacity: 0.7;">                                       -- validation_response, user_intervention</span>
    question <span style="color: #5599ff; font-weight: 600;">TEXT</span>,
    chosen_option <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,
    alternatives_considered <span style="color: #5599ff; font-weight: 600;">TEXT</span>,      -- JSON array
    confidence_score <span style="color: #5599ff; font-weight: 600;">REAL</span>,
    rationale <span style="color: #5599ff; font-weight: 600;">TEXT</span>,
    actor_reasoning <span style="color: #5599ff; font-weight: 600;">TEXT</span>,
    context_snapshot <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,    -- JSON blob
    is_correction <span style="color: #5599ff; font-weight: 600;">BOOLEAN</span> <span style="color: #5599ff; font-weight: 600;">DEFAULT</span> <span style="color: #5599ff; font-weight: 600;">FALSE</span>,
    corrects_decision_id <span style="color: #5599ff; font-weight: 600;">TEXT</span>,
    correction_reason <span style="color: #5599ff; font-weight: 600;">TEXT</span>,
    superseded_by <span style="color: #5599ff; font-weight: 600;">TEXT</span>,
    created_at <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,
    
    <span style="color: #5599ff; font-weight: 600;">FOREIGN</span> <span style="color: #5599ff; font-weight: 600;">KEY</span> (plan_id) <span style="color: #5599ff; font-weight: 600;">REFERENCES</span> plans(plan_id),
    <span style="color: #5599ff; font-weight: 600;">FOREIGN</span> <span style="color: #5599ff; font-weight: 600;">KEY</span> (parent_decision_id) <span style="color: #5599ff; font-weight: 600;">REFERENCES</span> decisions(decision_id),
    <span style="color: #5599ff; font-weight: 600;">FOREIGN</span> <span style="color: #5599ff; font-weight: 600;">KEY</span> (corrects_decision_id) <span style="color: #5599ff; font-weight: 600;">REFERENCES</span> decisions(decision_id),
    <span style="color: #5599ff; font-weight: 600;">FOREIGN</span> <span style="color: #5599ff; font-weight: 600;">KEY</span> (superseded_by) <span style="color: #5599ff; font-weight: 600;">REFERENCES</span> decisions(decision_id)
);

<span style="opacity: 0.7;">-- Downstream relationships (many-to-many for DAG)</span>
<span style="color: #5599ff; font-weight: 600;">CREATE</span> <span style="color: #5599ff; font-weight: 600;">TABLE</span> decision_dependencies (
    upstream_decision_id <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,
    downstream_decision_id <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,
    dependency_type <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,     -- <span style="color: #66cc66;">&#x27;decision&#x27;</span>, <span style="color: #66cc66;">&#x27;plan&#x27;</span>, <span style="color: #66cc66;">&#x27;artifact&#x27;</span>
    downstream_ref <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,      -- The actual ID of decision/plan/artifact
    
    <span style="color: #5599ff; font-weight: 600;">PRIMARY</span> <span style="color: #5599ff; font-weight: 600;">KEY</span> (upstream_decision_id, downstream_decision_id, downstream_ref),
    <span style="color: #5599ff; font-weight: 600;">FOREIGN</span> <span style="color: #5599ff; font-weight: 600;">KEY</span> (upstream_decision_id) <span style="color: #5599ff; font-weight: 600;">REFERENCES</span> decisions(decision_id)
);

<span style="opacity: 0.7;">-- Correction history</span>
<span style="color: #5599ff; font-weight: 600;">CREATE</span> <span style="color: #5599ff; font-weight: 600;">TABLE</span> correction_attempts (
    attempt_id <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">PRIMARY</span> <span style="color: #5599ff; font-weight: 600;">KEY</span>,       -- ULID
    plan_id <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,
    original_decision_id <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,
    new_decision_id <span style="color: #5599ff; font-weight: 600;">TEXT</span>,
    original_subtree_snapshot <span style="color: #5599ff; font-weight: 600;">TEXT</span>,    -- Reference to archived state
    correction_reason <span style="color: #5599ff; font-weight: 600;">TEXT</span>,
    status <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,              -- <span style="color: #66cc66;">&#x27;pending&#x27;</span>, <span style="color: #66cc66;">&#x27;executing&#x27;</span>, <span style="color: #66cc66;">&#x27;completed&#x27;</span>, <span style="color: #66cc66;">&#x27;failed&#x27;</span>
    created_at <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,
    completed_at <span style="color: #5599ff; font-weight: 600;">TEXT</span>,
    
    <span style="color: #5599ff; font-weight: 600;">FOREIGN</span> <span style="color: #5599ff; font-weight: 600;">KEY</span> (plan_id) <span style="color: #5599ff; font-weight: 600;">REFERENCES</span> plans(plan_id),
    <span style="color: #5599ff; font-weight: 600;">FOREIGN</span> <span style="color: #5599ff; font-weight: 600;">KEY</span> (original_decision_id) <span style="color: #5599ff; font-weight: 600;">REFERENCES</span> decisions(decision_id),
    <span style="color: #5599ff; font-weight: 600;">FOREIGN</span> <span style="color: #5599ff; font-weight: 600;">KEY</span> (new_decision_id) <span style="color: #5599ff; font-weight: 600;">REFERENCES</span> decisions(decision_id)
);
</code></pre></div>

### Action

#### What an Action Is

An **action** is a reusable plan template that is not associated with any projects yet.

**Actions are created via CLI commands with a required `--config` YAML file** that fully defines the action. Any CLI options supplied alongside the config file act as optional overrides for values in the YAML.

Examples:

* "Increase test coverage to 80%"
* "Refactor module X to be async-safe"
* "Write an RFC for feature Y"
* "Provision an infra cluster and validate access" (non-code)

Actions are **intentionally project-agnostic** so they can be reused across projects.

An action is the first stage of a plan — before it is used. Because of this, **invariants can be attached to actions**. When an action is used (via `agents plan use`), any invariants attached to the action are carried forward as plan-level invariants on the resulting plan. This allows teams to bake constraints directly into reusable templates. Invariants can also be added to a plan after the action is used, via `agents invariant add --plan` or `--invariant` flags on `agents plan use`.

#### Action Creation (CLI)

Actions are created using the CLI. The action is fully defined by the YAML configuration file:

<div class="highlight"><pre><code>
agents action create <span style="color: cyan;">--config</span> ./actions/code-coverage.yaml
</code></pre></div>

The YAML file provides the complete action definition, including the name, strategy-actor, execution-actor, definition-of-done, arguments, invariants, and all other properties.

**Required parameters:**
* `--config`: YAML configuration file that fully defines the action (name, strategy-actor, execution-actor, definition-of-done, etc.)

Arguments defined in the YAML's `args` section are values that will be:
* Injected into the description and/or definition of done (via templating)
* Passed into the context of the actors
* Required when using the action on projects

#### Action Data Model (Expanded)

A plan in the Action phase has:

##### 1) `name` (namespaced)

Format:

* `[server:][namespace/]<name>`

Rules:

* If server is omitted, default server is assumed unless namespace is `local`.
* If namespace is omitted, default is `local`.
* Names should be stable identifiers (kebab-case recommended).

Examples:

* `local/code-coverage`
* `myusername/code-coverage`
* `myorgname/code-coverage`
* `prod:myorgname/code-coverage` (server-qualified)

##### 2) `short_description`

Optional at creation; auto-filled if blank.

##### 3) `long_description`

Optional but recommended for reusable actions.

##### 4) `definition_of_done` (DoD)

Required. Must be explicit and testable. 

##### 5) `actors`

Two actors minimum, two optional:

* **strategy_actor** (planner/architect) — required
* **execution_actor** (builder/implementer) — required
* **estimation_actor** (cost/risk estimator) — optional
* **invariant_actor** (Invariant Reconciliation Actor) — optional; resolves invariant conflicts when the plan enters Strategize. Lookup falls back to project, then global config.

Actors can be:

* an LLM agent (built-in),
* a graph (custom yaml, or built-in),

Note: graphs are hierarchical allowing them to reference other actors as nodes.

Actor abstraction is central: an actor may be a single agent or an entire graph.

##### 6) `reusable` (boolean)

* Default: `true`.
* If `true`: using the action creates a *new* plan in Strategize while leaving the action available.
* If `false`: action self-deletes (or auto-archives) after first use.

##### 7) `read_only` (boolean)

* Default: `false`.
* If `true`: the plan must only use read-only tools (tools with `read_only: true` in their capability metadata) and must never modify resources (even in sandbox).
* Read-only actions are still useful for "investigation reports," architecture reviews, or dry-run planning.

##### 8) `inputs_schema` (recommended addition)

To make actions genuinely reusable, actions should declare their inputs:

* required args (e.g., target coverage percent),
* optional args (e.g., test framework),
* validation rules (types, bounds).

Example:

* `target_coverage_percent`: integer 0–100

##### 9) `automation_profile`

The resolved automation profile name for this plan (e.g., `trusted`, `auto`, `local/careful-auto`). Determined at `plan use` time using the profile precedence rules (plan > action > project > global). Once set, it is locked to the plan.

### Strategy (Strategize Phase)

#### Using an Action (Transition to Strategize)

The `use` command transitions an Action into the Strategize phase by applying it to one or more projects:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Basic usage</span>
agents plan use local/code-coverage my-api-service

<span style="opacity: 0.7;"># Multiple projects</span>
agents plan use local/schema-update <span style="opacity: 0.7;">\</span>
  api-service <span style="opacity: 0.7;">\</span>
  web-frontend <span style="opacity: 0.7;">\</span>
  mobile-app

<span style="opacity: 0.7;"># With action arguments</span>
agents plan use local/code-coverage <span style="opacity: 0.7;">\</span>
  my-api-service <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--arg</span> target_coverage_percent=85 <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--arg</span> test_framework=pytest

<span style="opacity: 0.7;"># With explicit automation profile</span>
agents plan use local/deploy-action <span style="opacity: 0.7;">\</span>
  staging-env <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--automation-profile</span> manual

<span style="opacity: 0.7;"># With invariants attached at use time</span>
agents plan use local/code-coverage <span style="opacity: 0.7;">\</span>
  my-api-service <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--arg</span> target_coverage_percent=85 <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">&quot;All API calls over TCP must be mocked&quot;</span> <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">&quot;Do not modify the payments module&quot;</span>
</code></pre></div>

**Parameters:**
* `<PROJECT>`: Project to apply the action to (positional, can be repeated for multi-project plans)
* `--arg`: Action argument values (format: `name=value`)
* `--automation-profile`: Override automation profile for this plan
* `--invariant`: Invariant to attach to the created plan (can be repeated). These are added as plan-level invariants in addition to any inherited from the action, project, or global scope.

When the action is used:
1. A new plan is created with a unique ULID
2. The plan's automation profile is resolved (plan > action > project > global precedence)
3. Any invariants from the action are carried forward as plan-level invariants, combined with any `--invariant` flags provided
4. The plan enters the **Strategize** phase
5. The **Invariant Reconciliation Actor** computes the effective invariant view (resolving conflicts using plan > project > global precedence)
6. The `strategy_actor` begins analyzing the project(s)

#### What Strategize Does

When an action is **used** on projects, it becomes a **plan in Strategize**.

Strategize is:

* **read-only**, producing a plan of attack,
* responsible for gathering context from project resources,
* responsible for collecting applicable invariants (from global, project, action, and plan scopes), computing the effective invariant view via the **Invariant Reconciliation Actor** (applying plan > project > global precedence), and recording them as `invariant_enforced` decisions,
* responsible for generating a strategy and child plan blueprint (using `subplan_spawn` and `subplan_parallel_spawn` decisions),
* not allowed to execute child plans or modify resources.

This "architect vs coder" separation is explicitly described as a core motivation.

**Resource-aware dependency analysis**:
During the Strategize phase, the strategy actor employs specialized mechanisms to compute precise dependency closures:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Pseudocode of what happens inside a strategy actor</span>
<span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">compute_closure_for_refactoring</span>(target_module):
    closure = ResourceClosure()
    
    <span style="opacity: 0.7;"># Direct file dependencies</span>
    closure.add_files(find_imports(target_module))
    closure.add_files(find_includes(target_module))
    
    <span style="opacity: 0.7;"># Symbol dependencies</span>
    <span style="color: magenta; font-weight: 600;">for</span> symbol <span style="color: magenta; font-weight: 600;">in</span> extract_exported_symbols(target_module):
        closure.add_files(find_symbol_usage(symbol, scope=<span style="color: #66cc66;">&#x27;project&#x27;</span>))
    
    <span style="opacity: 0.7;"># Test dependencies</span>
    closure.add_files(find_tests_for_module(target_module))
    
    <span style="opacity: 0.7;"># Build system dependencies</span>
    closure.add_files(find_build_references(target_module))
    
    <span style="color: magenta; font-weight: 600;">return</span> closure
</code></pre></div>

The system leverages several key insights:
- **Modular boundaries exist**: Even in legacy codebases, there are natural boundaries
- **Changes are incremental**: We don't convert 50,000 files atomically
- **Dependencies are sparse**: Most modules depend on a small fraction of the codebase
- **Interfaces are narrow**: Public APIs are much smaller than implementations

#### Strategize Data Model

A plan in Strategize contains all Action fields plus:

##### 1) `projects`

A list of projects the plan is used on.

Important: A strategy plan may target **multiple projects**. Multi-project work in one "window" is considered a major usability advantage over tools that require being run from a single directory.

##### 2) `strategy_context`

A structured object describing:

* what resources were considered,
* how they were retrieved,
* what filtering/limits were applied,
* what the actor saw.

This matters because a plan must be debuggable and correctable later.

Recommended fields:

* `resource_refs`: IDs of resources used
* `queries`: search queries performed
* `selected_chunks`: chunk IDs + sources + reasons
* `constraints`: context window limits, file ignore patterns
* `generated_summaries`: if summarization occurred

##### 3) `strategy`

The output plan:

* steps (ordered and/or DAG),
* conditions/branches ("if tests fail, do X"),
* child plans to spawn (including which action templates to use, and whether they should run in parallel via `subplan_parallel_spawn`),
* evaluation criteria (how to know success),
* risk assessment.

##### 4) `execution_blueprint` (recommended addition)

Strategize should output not only narrative text but also a machine-usable blueprint:

* list of tasks,
* required skills,
* expected outputs,
* dependencies between tasks.

This blueprint becomes the input to Execute.

##### 5) `cost_estimate` and `risk_estimate` (optional)

**Cost and risk estimation is optional** but recommended for production use.

When enabled, a specialized **estimation actor** analyzes:

* The initial prompt/request
* The strategy produced by the Strategize phase
* Historical data from similar plans (if available)

And produces estimates for:

* LLM tokens/cost range
* Number of steps/child plans expected
* Expected risk of rollbacks
* Estimated execution time

**Implementation**: Similar to how there's a `strategy_actor` and `execution_actor` for each action, there can be an optional `estimation_actor` whose entire job is cost/risk estimation. This actor runs after Strategize completes (before Execute) and its output is informational only.

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Example: Action with estimation actor (defined in the YAML config file)</span>
agents action create <span style="color: cyan;">--config</span> ./actions/expensive-refactor.yaml
</code></pre></div>

This becomes critical in server/multi-user usage and cost controls.

### Execution (Execute Phase)

#### What Execute Does

Execute is where the plan actually performs work, but **in a sandboxed environment** that can later be reviewed and applied.

Key properties:

1. **Work happens in a sandbox**
   All file modifications, generated artifacts, and intermediate outputs live in an isolated "execution workspace" until Apply.

2. **Execute may spawn child plans**
   Child plan spawning is a first-class behavior of Execute: a parent plan can distribute work to child plans (sequentially via `subplan_spawn` or concurrently via `subplan_parallel_spawn`) and merge results.

3. **Execute must support checkpointing / rollback (when enabled)**
   Checkpointable tools allow rolling back to a checkpoint ID to recover from partial failure or wrong turns.

4. **Execute produces a "reviewable diff"**
   Diff review sandbox is described as a differentiating feature: users can inspect changes before applying.

#### Execution Workspace / Sandbox Model (Detailed)

A sandbox isolates plan execution from the real project resources until Apply.

##### Key Sandbox Principles

1. **Lazy Sandboxing**: Resources are sandboxed **only when accessed**, not upfront.
   - A project may have many resources (git repo + 10 databases + cloud accounts)
   - A plan may only modify one resource
   - Only accessed resources are sandboxed
   - Efficient for large projects

2. **Per-Plan Sandboxes**: Each plan and child plan has its own sandbox containing only the resources it edits.

3. **Resource-Defined Strategy**: The sandbox strategy is defined on each **resource**, not by skills or globally.

4. **Cleanup Behavior**:
   - Sandboxes are cleaned up before application exit when possible
   - Abandoned sandboxes (from crashes, etc.) are cleaned up on next application run
   - Completed plan sandboxes are cleaned or archived based on retention policy

##### Sandbox Implementation Strategies

Different resource types require different sandbox strategies:

| Resource Type | Strategy | Rollback Mechanism |
|--------------|----------|-------------------|
| `git-checkout` | `git_worktree` | Git reset/checkout |
| `git` | `none` | N/A (represents a repo instance — not directly sandboxable) |
| `fs-mount` | `copy_on_write` or `overlay` | Restore from snapshot |
| `fs-directory` | `copy_on_write` | Restore from snapshot |
| Custom database types | `transaction_rollback` | Transaction rollback |
| Custom API types | `none` | Often not sandboxable |

**1. Git worktree / branch sandbox (preferred for code)**

* Create a worktree or temporary branch
* All modifications are commits or staged changes
* Apply merges/cherry-picks

Pros: natural rollback, diff support, efficient
Cons: requires git

**2. Filesystem copy sandbox**

* Copy project directory to a sandbox directory
* Execute modifies sandbox copy
* Apply syncs diff back

Pros: simple
Cons: expensive for huge repos

**3. Overlay filesystem sandbox**

* Use overlayfs-style "copy-on-write" to avoid full copies

Pros: efficient
Cons: more complex, OS-dependent

**4. Transaction-based sandbox (for databases)**

* Begin transaction at sandbox creation
* All operations within transaction
* Rollback on failure, commit on apply

Pros: native to databases
Cons: long-running transactions can cause issues

**5. No sandbox (for non-sandboxable resources)**

* Some resources cannot be sandboxed (certain APIs, cloud services)
* User proceeds at their own risk
* Plan should warn about non-sandboxable resources

##### Multi-Resource Sandboxing

When a plan accesses multiple resources:

* Each resource gets its own sandbox (based on its defined strategy)
* Sandboxes are independent
* Apply commits each sandbox separately
* If any sandbox Apply fails, others may still succeed (partial apply)

**Complete isolation during execution prevents compound errors**:
Each plan executes in its own sandbox, which means:
<div class="highlight"><pre><code>
Plan A (refactoring auth module):
- Sandbox A1: Contains only auth/*.cpp, auth_tests/*.cpp
- Cannot see Plan B&#x27;s intermediate states
- Cannot accidentally depend on Plan B&#x27;s half-done work

Plan B (updating API endpoints):
- Sandbox B1: Contains only api/*.cpp, api_tests/*.cpp  
- Makes changes assuming current auth interface
- Protected from Plan A&#x27;s intermediate refactoring
</code></pre></div>

**Hierarchical merge resolution**:
When child plans complete, the parent plan performs intelligent merging:
<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">merge_subplan_results</span>(subplan_results):
    <span style="opacity: 0.7;"># Group by resource type</span>
    by_resource = group_by_resource_type(subplan_results)
    
    <span style="opacity: 0.7;"># Apply resource-specific merge strategies</span>
    <span style="color: magenta; font-weight: 600;">for</span> resource_type, changes <span style="color: magenta; font-weight: 600;">in</span> by_resource:
        <span style="color: magenta; font-weight: 600;">if</span> resource_type == <span style="color: #66cc66;">&#x27;git-checkout&#x27;</span>:
            merge_git_changes(changes)  <span style="opacity: 0.7;"># Three-way merge</span>
        <span style="color: magenta; font-weight: 600;">elif</span> resource_type == <span style="color: #66cc66;">&#x27;fs-mount&#x27;</span>:
            merge_fs_changes(changes)   <span style="opacity: 0.7;"># Copy-on-write reconciliation</span>
        <span style="color: magenta; font-weight: 600;">elif</span> resource_type.startswith(<span style="color: #66cc66;">&#x27;database&#x27;</span>):
            merge_db_changes(changes)   <span style="opacity: 0.7;"># Sequential application</span>
    
    <span style="opacity: 0.7;"># Validate merged state</span>
    run_integration_tests()
</code></pre></div>

#### Execution Data Model

A plan in Execute contains:

##### 1) `execution_context`

The context used for execution (often smaller/more tactical than strategy context).

##### 2) `execution_log`

Structured timeline of:

* tool calls (with parent skill noted),
* actor calls,
* outputs,
* errors and retries,
* checkpoints created.

This log is essential for debugging.

##### 3) `artifacts`

Outputs produced:

* changed files,
* generated files,
* reports,
* diagrams,
* test outputs,
* diffs.

##### 4) `sandbox_ref`

Pointer to the sandbox location/state:

* path, branch name, workspace ID, container ID, etc.

##### 5) `checkpoint_graph` (if enabled)

A record of checkpoints:

* checkpoint ID
* timestamp
* tool responsible (and its parent skill)
* resources affected
* rollback instructions / metadata

#### Checkpointing in Execute (Core Safety Mechanism)

The intended user-level behavior is:

* "Give me a checkpoint ID."
* Perform additional operations.
* "Roll back to checkpoint X."

Not all tools can support this; checkpointing must be declared per tool (in its capability metadata).

##### Tool-level checkpointability

Each tool declares (via its capability metadata):

* `checkpointable: true|false`
* `checkpoint_scope`: what granularity of rollback is supported (file, transaction, commit, snapshot)
* `rollback_mechanism`: how rollback occurs

Examples:

* File tools (from a file-ops skill): snapshot file states pre-modification
* Git tools (from a git-ops skill): create commit or stash; rollback is reset/checkout
* Shell/CLI tools (running inside a container): rollback by restoring filesystem snapshot or reloading base image state

It should be noted that checkpointing is easier when tool scope is constrained (e.g., "only files within a docker image + git").

##### Plan-level rollback policy

Plans should have an option:

* `rollback_enabled: true|false`

If disabled, the plan may use more generic/unsafe tools with fewer restrictions (useful for low-stakes tasks).

#### Execution as Transactions (Recommended)

Execution should be treated like a transactional pipeline:

* Each step either:

  * commits a checkpoint on success, or
  * rolls back to the previous checkpoint on failure.

This is explicitly motivated by "partial failure leaves codebase inconsistent" and the need for transaction rollback. 

#### Tool-Based Resource Modification (Modern Architecture)

**IMPORTANT: CleverAgents does NOT parse LLM output to extract code.** Instead, it uses the modern tool-based approach pioneered by Claude Code, Cursor, and Aider where:

1. **LLMs call tools directly** (`edit_file()`, `write_file()`, `delete_file()`, etc.) — tools provided by referenced skills
2. **Tools operate on the sandbox** - each tool invocation modifies sandbox state directly
3. **ChangeSet is built from tool invocations** - not by parsing LLM text output
4. **Validation runs on sandbox state** - after tools execute, not on parsed output

This architecture provides:

* **Atomic operations**: Each tool call is a discrete, trackable change
* **No parsing ambiguity**: Tools have structured parameters (path, content, etc.)
* **Resource-agnostic**: Same pattern works for files, databases, APIs, any resource type
* **Safety by design**: Tools run in sandbox with defined capabilities and restrictions
* **MCP compatibility**: Tools from MCP-based skills map directly to MCP tools for external integrations

##### How It Works

```kroki-mermaid
sequenceDiagram
    participant LLM as LLM Agent
    participant Router as Tool Router
    participant Sandbox as Sandbox
    participant CS as ChangeSet
    participant Val as Validator

    LLM->>Router: Tool call (with parameters)
    Router->>Router: Validate parameters
    Router->>Router: Enforce capability restrictions
    Router->>Sandbox: Execute tool in sandbox
    Sandbox->>Sandbox: Operate on sandboxed state
    Sandbox->>Sandbox: Record invocation
    Sandbox->>Sandbox: Create checkpoint (if needed)
    Sandbox->>CS: Emit Change record
    CS->>CS: Accumulate into ChangeSet
    CS->>Val: Submit for validation
    Val->>Val: Run validators on sandbox state
    Val->>Val: Generate diff from ChangeSet
    Val-->>LLM: Present for review before Apply
```

##### Built-in Resource Tools

CleverAgents provides these core tools (via built-in skills) for resource manipulation:

| Tool | Description | Creates Change? |
|-------|-------------|-----------------|
| `read_file(path)` | Read file contents | No |
| `write_file(path, content)` | Create/overwrite file | Yes |
| `edit_file(path, changes)` | Apply targeted edits | Yes |
| `delete_file(path)` | Remove file | Yes |
| `move_file(src, dst)` | Rename/move file | Yes |
| `create_directory(path)` | Create directory | Yes |
| `list_files(pattern)` | List files matching glob | No |
| `search_files(pattern, content)` | Search file contents | No |
| `get_file_info(path)` | Get file metadata | No |

Each built-in tool automatically:
* Operates within sandbox boundaries
* Records changes to the ChangeSet
* Validates parameters against project configuration
* Enforces deny-list patterns (`.git/`, `node_modules/`, etc.)

##### Why Not Parse LLM Output?

The obsolete approach of parsing markdown code fences has fundamental problems:

1. **Ambiguity**: Is text explanation or code? Where does one file end and another begin?
2. **Fragility**: Models output varying formats; regex parsing is brittle
3. **Loss of semantics**: You lose the intent (create vs modify vs delete)
4. **No atomicity**: Can't rollback individual operations
5. **Resource-limited**: Only works for files, not databases or other resources

The tool-based approach solves all of these by making each operation explicit, typed, and trackable.

### Semantic Error Prevention

CleverAgents provides multiple layers of proactive error prevention that catch semantic errors before they can propagate through the system.

#### Layer 1: Decision-time Validation During Strategize

Every decision includes semantic validation:
<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">Decision</span>: Refactor payment module to async
<span style="color: cyan; font-weight: 600;">alternatives_considered</span>:
  - &quot;Convert to async/await patterns&quot; (chosen)
  - &quot;Use thread pool with channels&quot; (rejected: doesn&#x27;t integrate with async ecosystem)
  - &quot;Keep synchronous with timeout&quot; (rejected: doesn&#x27;t solve core latency issue)
<span style="color: cyan; font-weight: 600;">confidence_score</span>: <span style="color: yellow;">0.85</span>
<span style="color: cyan; font-weight: 600;">validation_performed</span>:
  - Checked all payment API consumers can handle async
  - Verified database driver supports async operations
  - Confirmed no regulatory requirement for sync processing
</code></pre></div>

#### Layer 2: Execution-time Semantic Guards

The execution actor uses a tool node that references the independently registered `local/validate-api-compat` tool:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Actor graph uses a named tool node for semantic validation</span>
<span style="color: cyan; font-weight: 600;">actors</span>:
  <span style="color: cyan; font-weight: 600;">code_executor</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: graph
    <span style="color: cyan; font-weight: 600;">skills</span>:
      - local/semantic-validators    # Skill containing validation tools for LLM tool-calling
    <span style="color: cyan; font-weight: 600;">nodes</span>:
      - <span style="color: cyan;">name</span>: semantic_validator
        <span style="color: cyan; font-weight: 600;">type</span>: tool
        <span style="color: cyan; font-weight: 600;">tool</span>: local/validate-api-compat <span style="opacity: 0.7;"># Named tool from Tool Registry</span>
</code></pre></div>

The `local/validate-api-compat` tool is independently registered via its own YAML:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># File: tools/validate-api-compat.yaml</span>
<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">&quot;3.0&quot;</span>

<span style="color: cyan; font-weight: 600;">tool</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/validate-api-compat
  <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Check for breaking API changes and attempt auto-migration&quot;</span>
  <span style="color: cyan; font-weight: 600;">source</span>: custom

  <span style="color: cyan; font-weight: 600;">capability</span>:
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">true</span>

  <span style="color: cyan; font-weight: 600;">code</span>: <span style="color: #66cc66;">|</span>
<span style="opacity: 0.7;">    # Not just syntax checking - semantic validation</span>
    old_api = extract_api_signature(previous_version)
    new_api = extract_api_signature(current_version)
    
    breaking_changes = find_breaking_changes(old_api, new_api)
    if breaking_changes:
        affected_consumers = find_api_consumers(breaking_changes)
        migration_plan = generate_migration(breaking_changes)
        
        if can_auto_migrate(affected_consumers, migration_plan):
            apply_migration(migration_plan)
        <span style="color: cyan; font-weight: 600;">else</span>:
            raise SemanticError(
                &quot;Breaking API changes require manual review&quot;,
                changes=breaking_changes,
                affected=affected_consumers
            )
</code></pre></div>

The `local/semantic-validators` skill references this tool by name:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># File: skills/semantic-validators.yaml</span>
<span style="color: cyan; font-weight: 600;">skill</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/semantic-validators
  <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Semantic validation tools for API compatibility and code invariants&quot;</span>
  <span style="color: cyan; font-weight: 600;">tools</span>:
    - local/validate-api-compat
</code></pre></div>

#### Layer 3: Invariant Enforcement

Invariants are named constraints that guide and constrain plan execution. They can be attached at four scopes, all managed through the unified `agents invariant` command:

* **Global invariants**: Apply to all plans across all projects. Added via `agents invariant add --global`.
* **Project invariants**: Apply to all plans targeting a specific project. Added via `agents invariant add --project`. Can also be attached at creation time via `agents project create --invariant`.
* **Action invariants**: Attached to an action and carried forward as plan-level invariants when the action is used. Added via `agents invariant add --action`. Can also be attached at creation time via `agents action create --invariant`.
* **Plan invariants**: Apply to a specific plan and its child plans. Added via `agents invariant add --plan`. Can also be attached at creation time via `agents plan use --invariant`.

**Precedence and conflict resolution**: When invariants from different scopes conflict, narrower scopes override broader scopes:

* **Plan-level** invariants override **project-level** and **global-level** invariants.
* **Project-level** invariants override **global-level** invariants.

Note: Action invariants are carried forward as plan-level invariants when the action is used (see **Action invariants** above), so they participate in precedence at the plan tier — there is no separate action tier in the precedence chain.

Conflict resolution is performed by the **Invariant Reconciliation Actor** — a dedicated actor responsible for comparing invariants across scopes, identifying conflicts, and producing the final **effective invariant view** for a plan. The Invariant Reconciliation Actor is set at three levels via `--invariant-actor`:

1. **Global config**: Set via `agents config set actor.default.invariant <ACTOR>`. Defines the default Invariant Reconciliation Actor used when neither the project nor the plan specifies one.
2. **Project-level**: Set via `--invariant-actor` on `agents project create`. If a project defines an Invariant Reconciliation Actor, it is used to reconcile that project's invariants against global invariants.
3. **Plan-level**: Set via `--invariant-actor` on `agents action create` (carried forward when the action is used) or `agents plan use` (which overrides whatever was set on the action). If a plan has an Invariant Reconciliation Actor, it reconciles invariants from all scopes (plan, project, and global) and produces the final effective view for that plan.

The lookup order is: plan → project → global config. The first Invariant Reconciliation Actor found is used.

**Invariant view calculation**: When an action is used and a plan enters the Strategize phase, the Invariant Reconciliation Actor computes the effective invariant view by:

1. Collecting all invariants from global, project, plan, and action scopes.
2. Identifying conflicts (invariants from different scopes that contradict each other).
3. Applying precedence rules (plan > project > global) to resolve conflicts.
4. Producing the final set of effective invariants.

Each effective invariant is then recorded as an `invariant_enforced` decision in the plan's decision tree. This makes invariants visible, auditable, and correctable through the standard decision correction mechanism.

**Child plan inheritance**: When a top-level plan spawns child plans, the parent's effective invariant view (already reconciled) is passed down to each child plan. Child plans do not re-run reconciliation — they inherit the parent's resolved view.

**Correcting invariants**: The correction mechanism for `invariant_enforced` decisions supports two operations:
* **Remove**: Remove an existing invariant from the plan's decision tree (the invariant remains defined at its scope but is no longer enforced for this plan).
* **Add**: Add a new invariant to the plan. When adding, the user can select from invariants already accessible to the plan (those defined at the plan, action, project, or global scope), or provide free-form text to create a new ad-hoc invariant.

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Add invariants at different scopes</span>
agents invariant add <span style="color: cyan;">--global</span> <span style="color: #66cc66;">&quot;All public APIs must maintain backward compatibility&quot;</span>
agents invariant add <span style="color: cyan;">--global</span> <span style="color: #66cc66;">&quot;Payment processing must be idempotent&quot;</span>
agents invariant add <span style="color: cyan;">--project</span> local/api-service <span style="opacity: 0.7;">\</span>
  <span style="color: #66cc66;">&quot;Database transactions must complete within 5 seconds&quot;</span>
agents invariant add <span style="color: cyan;">--project</span> local/api-service <span style="opacity: 0.7;">\</span>
  <span style="color: #66cc66;">&quot;Authentication must always use OAuth2&quot;</span>
agents invariant add <span style="color: cyan;">--plan</span> &lt;PLAN_ID&gt; <span style="color: #66cc66;">&quot;All API calls over TCP must be mocked&quot;</span>
agents invariant add <span style="color: cyan;">--action</span> local/code-coverage <span style="color: #66cc66;">&quot;Test files must not import production secrets&quot;</span>

<span style="opacity: 0.7;"># List invariants</span>
agents invariant list <span style="color: cyan;">--global</span>
agents invariant list <span style="color: cyan;">--project</span> local/api-service
agents invariant list <span style="color: cyan;">--plan</span> &lt;PLAN_ID&gt; <span style="color: cyan;">--effective</span>   # Shows reconciled view

<span style="opacity: 0.7;"># Remove an invariant</span>
agents invariant remove &lt;INVARIANT_ID&gt;

<span style="opacity: 0.7;"># Attach invariants at creation time (convenience)</span>
agents project create <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">&quot;All endpoints must validate auth tokens&quot;</span> local/api-service
agents action create <span style="color: cyan;">--config</span> ./actions/code-coverage.yaml
agents plan use local/code-coverage local/api-service <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">&quot;Mock all network calls&quot;</span>

<span style="opacity: 0.7;"># Correct an invariant decision (remove or replace via standard correction)</span>
agents plan correct &lt;DECISION_ID&gt; <span style="color: cyan;">--mode</span>=revert <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">&quot;Remove this invariant - it does not apply to this module&quot;</span>
</code></pre></div>

The system collects, reconciles, and checks invariants:
<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">InvariantEnforcer</span>:
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">compute_effective_invariants</span>(self, plan):
        <span style="color: #66cc66;">&quot;&quot;&quot;Compute the effective invariant view for a plan using the Invariant Reconciliation Actor.&quot;&quot;&quot;</span>
        <span style="opacity: 0.7;"># 1. Collect raw invariants from all scopes</span>
        raw = self.collect_all_invariants(plan)
        
        <span style="opacity: 0.7;"># 2. Find the Invariant Reconciliation Actor (plan -&gt; project -&gt; global config)</span>
        reconciler = (
            self.get_plan_invariant_actor(plan)
            <span style="color: magenta; font-weight: 600;">or</span> self.get_project_invariant_actor(plan)
            <span style="color: magenta; font-weight: 600;">or</span> self.get_global_invariant_actor()
        )
        
        <span style="opacity: 0.7;"># 3. Reconcile: apply precedence (plan &gt; project &gt; global), resolve conflicts</span>
        effective = reconciler.reconcile(raw, precedence=[<span style="color: #66cc66;">&#x27;plan&#x27;</span>, <span style="color: #66cc66;">&#x27;project&#x27;</span>, <span style="color: #66cc66;">&#x27;global&#x27;</span>])
        <span style="color: magenta; font-weight: 600;">return</span> effective
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">collect_all_invariants</span>(self, plan):
        <span style="color: #66cc66;">&quot;&quot;&quot;Collect invariants from all scopes accessible to this plan.&quot;&quot;&quot;</span>
        invariants = []
        invariants.extend(self.get_global_invariants())
        <span style="color: magenta; font-weight: 600;">for</span> project <span style="color: magenta; font-weight: 600;">in</span> plan.projects:
            invariants.extend(self.get_project_invariants(project))
        invariants.extend(self.get_action_invariants(plan.action))
        invariants.extend(self.get_plan_invariants(plan))
        <span style="color: magenta; font-weight: 600;">return</span> invariants
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">check_invariant_preservation</span>(self, changes, enforced_invariants):
        <span style="color: #66cc66;">&quot;&quot;&quot;Check that changes respect all enforced invariants.&quot;&quot;&quot;</span>
        <span style="color: magenta; font-weight: 600;">for</span> invariant <span style="color: magenta; font-weight: 600;">in</span> enforced_invariants:
            <span style="color: magenta; font-weight: 600;">if</span> <span style="color: magenta; font-weight: 600;">not</span> self.verify_invariant(invariant, changes):
                <span style="color: magenta; font-weight: 600;">return</span> InvariantViolation(invariant, changes)
        <span style="color: magenta; font-weight: 600;">return</span> Success()
</code></pre></div>

#### Layer 4: Predictive Error Prevention

The system learns from past failures:
<div class="highlight"><pre><code>
Error Pattern Database:
  - <span style="color: cyan;">pattern</span>: <span style="color: #66cc66;">&quot;Async conversion in payment module&quot;</span>
    <span style="color: cyan; font-weight: 600;">historical_failures</span>:
      - &quot;Race condition in payment confirmation&quot;
      - &quot;Timeout handling breaks idempotency&quot;
    <span style="color: cyan; font-weight: 600;">preventive_checks</span>:
      - &quot;Add explicit transaction boundaries&quot;
      - &quot;Verify idempotency keys are preserved&quot;
      - &quot;Check distributed lock acquisition&quot;
</code></pre></div>

### Applied (Apply Phase)

#### What Apply Does

Apply takes the sandboxed work product and makes it "real" in the project.

Core properties:

1. **Apply is a controlled commit step**
   Apply exists specifically to separate "generated work" from "committed work," enabling review and safer automation.

2. **Apply is often the highest-risk step**
   It changes real systems. This is where approvals and checks matter most.

3. **Apply produces a terminal 'applied' plan**
   After successful apply, the plan becomes Applied.

#### Apply Responsibilities (Recommended Checklist)

Apply should perform (configurable) validations before committing:

* **Diff review gate**

  * If the `auto_apply` threshold is not met (i.e., confidence < threshold, or threshold is `1.0`) in the automation profile, show:

    * changed files summary,
    * full diff,
    * risk warnings.
* **Conflict resolution**

  * If applying to a git repo, handle rebase/merge conflicts safely.
* **Audit log**

  * Record who applied, what changed, when, and why.

#### Validation in Apply

Validation runs during **Execute**, not during Apply. By the time a plan reaches the Apply phase, all required validations have already passed. Apply commits the sandbox changes to the real resources and does not re-run validations.

For full details on validation — including the Validation type system, modes, attachment scoping, failure handling, fix-then-revalidate loops, and data model — see the **Validation** section under Core Concepts.

#### Apply Data Model

A plan in Apply includes:

* `apply_summary`
* `applied_artifacts` (final commit hash, merged PR link, file list)
* `final_validation_results` (per-validation tool invocation results: `passed`, `message`, and `data` for each)
* `approval_record` (if human approvals are required)
* `deployment_record` (optional, if apply triggers deploy)

#### "Applied" Terminal State

When Apply succeeds:

* plan.phase = `applied`
* plan.state = `complete`
* the sandbox may be cleaned up or archived depending on retention policy

When Apply fails:

* plan.phase remains Apply
* plan.state = `errored`
* sandbox remains intact for inspection/retry

### Project

A **project** is the boundary that answers:

* "Where is the work happening?"
* "What can this plan read and write?"
* "What skills (and their tools) can this plan use?"
* "What context is available?"

A project is a **collection of linked resources and configuration**. Projects link to independently registered resources from the **Resource Registry** — they do not define resources inline. A resource can be linked to multiple projects, enabling shared resources across teams and workflows.

**Important: Projects are created via CLI commands, NOT YAML configuration files.**

#### Project Types: Local vs Remote

Projects are classified based on their resources:

| Type | Definition | Where Plans Can Execute |
|------|------------|------------------------|
| **Local** | Contains at least one local-only resource | Client only |
| **Remote** | All resources are remotely accessible | Client or Server |

This distinction matters for server mode: the server can only execute plans on **remote** projects because it needs network access to all resources.

#### Project Creation (CLI)

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Step 1: Register resources independently</span>
agents resource add git-checkout local/api-repo <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--path</span> /repos/api-service <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--branch</span> main

agents resource add local/database local/staging-db <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--connection-string</span> <span style="color: #66cc66;">&quot;postgresql://staging.example.com/mydb&quot;</span> <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--read-only</span>

<span style="opacity: 0.7;"># Step 2: Create the project</span>
agents project create <span style="color: #66cc66;">&quot;my-api-service&quot;</span>

<span style="opacity: 0.7;"># Step 3: Link resources to the project</span>
agents project link-resource <span style="color: #66cc66;">&quot;my-api-service&quot;</span> local/api-repo

agents project link-resource <span style="color: #66cc66;">&quot;my-api-service&quot;</span> local/staging-db <span style="color: cyan;">--read-only</span>
</code></pre></div>

Resources are registered once and can be linked to multiple projects. The resource's type, sandbox strategy, and capabilities are defined by its resource type in the Resource Registry — not by the project.

#### Project Data Model

A project includes:

##### 1) Identity

* `name` — the namespaced project name (e.g., `local/api-service`). This serves as the project's globally unique identifier; no separate ULID or ID is generated. The namespacing scheme (`[[server:]namespace/]name`) ensures global uniqueness across systems.
* `namespace` (follows same rules as actors: `local/`, `<username>/`, `<orgname>/`)
* `is_remote` (boolean, derived from resources)

##### 2) Linked Resources

Resources are the "things you can act on." Projects **link** to independently registered resources from the Resource Registry rather than defining them inline. This means:

* A resource can be linked to multiple projects (shared resources).
* The resource's type, capabilities, sandbox strategy, and DAG relationships are defined by the resource itself — not by the project.
* Projects can apply project-level overrides when linking (e.g., marking a writable resource as read-only within a specific project context).

Each linked resource reference has:

* `resource_id` (ULID reference to a Resource Registry entry). Resources can be referenced by name or ULID in CLI commands; name is resolved to `resource_id` at command time.
* `project_read_only` (boolean — project-level read-only override)
* `alias` (optional short name for referencing within the project)

The full resource details (type, location, sandbox strategy, capabilities, parent/child DAG, etc.) are stored in the Resource Registry. See the **Resources** section for details.

##### 3) Context configuration

Project-level defaults:

* ignore patterns (like `.gitignore` semantics)
* max file size
* indexing strategy
* preferred chunking/summarization policy (even if evolving)
* context retention policy

#### Multi-Project Operations

A single plan may target multiple projects (e.g., updating shared schemas across services). This is considered a key UX advantage over "run in one directory" systems. Because resources are independently registered and can be linked to multiple projects, shared resources across projects are a natural part of the architecture.

In multi-project execution:

* Strategize must clarify which steps affect which projects.
* Execution must isolate sandboxes per project OR define a composite sandbox. When multiple projects share the same resource, a single sandbox for that resource is used.
* Apply must commit changes to each project separately, with separate approval records if necessary.
* Tool resource bindings are resolved per-project — the same tool may bind to different resources depending on which project context it runs in.

### Namespaces

Namespaces define **ownership, scoping, and discoverability** of actors, tools, skills, resources, resource types, actions, projects, and plans.

**All named entities use the format `<namespace>/<name>`.**

#### Namespace Types

| Namespace | Scope | Storage | Examples |
|-----------|-------|---------|----------|
| `local/` | Current machine only | Local database | `local/my-reviewer`, `local/test-action` |
| `<username>/` | Personal server namespace | Server database | `freemo/code-analyzer`, `jsmith/deploy-script` |
| `<orgname>/` | Organization namespace | Server database | `cleverthis/standard-review`, `acme/deploy-action` |
| `openai/`, `anthropic/`, etc. | Built-in LLM actors | N/A (built-in) | `openai/gpt-4`, `anthropic/claude-3-opus` |

#### Namespace Rules

* **`local/`**

  * Reserved namespace for local-only items
  * Exists only on the current machine
  * Stored in local database
  * Fast iteration, no sharing
  * Default namespace when none specified

* **`<username>/`** (e.g., `freemo/`, `jsmith/`)

  * Personal namespace on the server
  * Created when user registers an account
  * Stored on server, synced when connected
  * Used for reusable entities (actions, actors, tools, skills, resources) a user wants across machines
  * Only the owning user can create/modify items

* **`<orgname>/`** (e.g., `cleverthis/`, `acme/`)

  * Organization namespace on the server
  * Created when organization is registered
  * Shared across team members
  * All namespaced entities (actions, actors, tools, skills, resources, projects) can be centrally managed

* **Built-in Provider Namespaces** (`openai/`, `anthropic/`, `google/`, etc.)

  * Reserved for built-in LLM actors
  * Automatically available when API keys are configured
  * In server mode: available if logged in and server has keys
  * In local mode: requires environment variables or app configuration
  * Cannot be used for custom actors

#### Server-qualified Names

To disambiguate between servers (when connected to multiple):

* `dev:freemo/code-coverage` (personal namespace on dev server)
* `prod:cleverthis/deploy-action` (org namespace on prod server)

This enables a pattern where:

* local machine runs a lightweight client
* server stores canonical definitions
* multiple servers can coexist

### Actor

#### What an Actor Is

An **actor** is the abstraction that generalizes "agent" into "anything conversational."

* It can be as small as a single LLM agent.
* It can also be an entire graph that itself calls other actors/tools.
* Actors can be nested/hierarchical, enabling "orchestrator of orchestrators."

**Every custom actor IS a graph** (a LangGraph defined via YAML configuration). Even a simple actor wrapping a single LLM is technically a graph with one node.

#### Actor Naming

Actors are **always named using `<namespace>/<name>` format**:

* `local/my-reviewer` - Local actor
* `freemo/code-analyzer` - Personal server actor
* `cleverthis/deploy-specialist` - Organization actor
* `openai/gpt-4` - Built-in LLM actor

#### Actor Definition (YAML Configuration)

Actors are defined via **YAML configuration files**. Tools and skills are also defined via their own YAML configuration files. YAML configuration is used for actors, tools, and skills (not for actions or projects).

Example actor configuration (see `examples/` directory for full examples):

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">name</span>: local/my-workflow

<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">&quot;3.0&quot;</span>
  <span style="color: cyan; font-weight: 600;">default_actor</span>: workflow_controller

<span style="color: cyan; font-weight: 600;">actors</span>:
<span style="opacity: 0.7;">  # Simple LLM actor with skills referenced by name</span>
  <span style="color: cyan; font-weight: 600;">my_assistant</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">actor</span>: openai/gpt-4 <span style="opacity: 0.7;"># Reference to built-in actor</span>
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.7</span>
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: <span style="color: #66cc66;">|</span>
        You are a helpful assistant.
        Current task: {{ context.task_description }}
    <span style="color: cyan; font-weight: 600;">skills</span>:
      - local/file-ops               # Grants access to all tools in this skill
      - local/git-ops

<span style="opacity: 0.7;">  # LLM actor with a composite skill (includes many sub-skills)</span>
  <span style="color: cyan; font-weight: 600;">data_processor</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">actor</span>: anthropic/claude-3-opus
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: <span style="color: #66cc66;">|</span>
        You are a data processing assistant.
    <span style="color: cyan; font-weight: 600;">skills</span>:
      - local/data-toolkit           # A skill containing analysis + transformation tools

<span style="opacity: 0.7;">  # Actor referencing another actor</span>
  <span style="color: cyan; font-weight: 600;">reviewer</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">actor</span>: local/code-reviewer <span style="opacity: 0.7;"># Reference to another custom actor</span>
      <span style="color: cyan; font-weight: 600;">memory_enabled</span>: <span style="color: magenta; font-weight: 600;">true</span>
      <span style="color: cyan; font-weight: 600;">max_history</span>: <span style="color: yellow;">20</span>
    <span style="color: cyan; font-weight: 600;">skills</span>:
      - local/file-ops
      - local/git-ops

<span style="color: cyan; font-weight: 600;">routes</span>:
  <span style="color: cyan; font-weight: 600;">main_workflow</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: graph
    <span style="color: cyan; font-weight: 600;">entry_point</span>: start
    <span style="color: cyan; font-weight: 600;">nodes</span>:
      - <span style="color: cyan;">name</span>: analyze
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: my_assistant
      - <span style="color: cyan;">name</span>: process
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: data_processor
    <span style="color: cyan; font-weight: 600;">edges</span>:
      - <span style="color: cyan;">source</span>: start
        <span style="color: cyan; font-weight: 600;">target</span>: analyze
      - <span style="color: cyan;">source</span>: analyze
        <span style="color: cyan; font-weight: 600;">target</span>: process
      - <span style="color: cyan;">source</span>: process
        <span style="color: cyan; font-weight: 600;">target</span>: end

<span style="color: cyan; font-weight: 600;">context</span>:
  <span style="color: cyan; font-weight: 600;">global</span>:
    <span style="color: cyan; font-weight: 600;">task_description</span>: <span style="color: #66cc66;">&quot;Default task&quot;</span>
</code></pre></div>

#### Actor Arguments

**All actors can receive arguments when invoked**, including built-in actors. Arguments are passed when:

1. An action is used on projects (arguments flow to strategy/execution actors)
2. An actor is directly invoked

Arguments are injected into the actor's context and can be used in Jinja2 templates within prompts.

For built-in actors (like `openai/gpt-4`), common arguments include:
* `temperature`
* `max_tokens`
* `system_prompt`

#### Actor Composition (Hierarchical References)

Actors can reference other actors **by name**:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">actors</span>:
  <span style="color: cyan; font-weight: 600;">complex_workflow</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">actor</span>: local/base-analyzer <span style="opacity: 0.7;"># References another actor</span>
</code></pre></div>

**Load order matters**: Referenced actors must be loaded/defined before actors that depend on them.

This enables hierarchical composition where:
* Actor A's graph can include nodes that call Actor B (by name)
* Actor B itself is a graph that might call Actor C
* And so on...

#### Actor vs Agent (Relationship)

* **Agent**: an actor that is specifically an LLM with tools and reasoning behaviors.
* **Actor**: may be an agent, but may also be:

  * a composite workflow,
  * a multi-step graph,
  * a wrapper around a third-party system (as long as it's "text in → text out" conversationally).

#### Actor Definition Fields (From Notes + Extended)

A robust actor schema should include:

* `name` (namespaced, **required** in the YAML config file — defines the actor's registered identity)
* `provider` (LLM provider or runtime target)
* `model`
* `system_prompt` (or prompt template)
* `skill_access_policy` (which skill categories/names are allowed or denied)
* `graph_descriptor` (for composite actors)
* `memory_policy` (per-plan/per-actor—see memory section)
* `context_view_policy` (what context this actor sees — includes ACMS settings: `preferred_strategies`, `default_breadth`, `default_depth`, `depth_gradient`, `skeleton_budget_ratio`, `temporal_scope`, `auto_refresh`, `refresh_threshold`)
* `limits` (token limits, tool call limits, retries)
* `cost_policy` (caps, budgets)
* `metadata` (use cases, version)

#### Actor Composition and Graphs

Actors can reference:

* other actors (by namespaced name)
* skills (by namespaced name — all tools from referenced skills become available)
* subgraphs

This is central to enabling both:

* multi-agent orchestration, and
* modular reuse of workflows.

#### Nodes in the Graph: Actors and Tools

Graph nodes can be any of:

* an **actor** (another LLM agent or composite workflow, referenced by name),
* a **tool node** — a deterministic, non-LLM step that directly invokes a tool. Tool nodes can:
  * **Reference a named registered tool** by its fully-qualified name (e.g., `tool: local/run-migrations`). The tool must be registered in the Tool Registry via `agents tool add`. Metadata can optionally be overridden at the point of use.
  * **Define an anonymous inline tool** using the same format as a tool YAML body (with `anonymous: true`). This is useful for one-off, workflow-specific operations that don't warrant separate registration.

This is a powerful simplification: actors provide intelligence, tools provide capability (both as graph nodes and through skills for LLM tool-calling), and skills organize tools into reusable collections. Everything participates in the same graph.

**Tool node with named tool reference:**

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">nodes</span>:
  - <span style="color: cyan;">name</span>: run_db_migrate
    <span style="color: cyan; font-weight: 600;">type</span>: tool
    <span style="color: cyan; font-weight: 600;">tool</span>: local/run-migrations <span style="opacity: 0.7;"># Named tool from Tool Registry</span>
    <span style="color: cyan; font-weight: 600;">override</span>:                           # Optional metadata override
      <span style="color: cyan; font-weight: 600;">capability</span>:
        <span style="color: cyan; font-weight: 600;">human_approval_required</span>: <span style="color: magenta; font-weight: 600;">true</span>

  - <span style="color: cyan;">name</span>: spawn_tests
    <span style="color: cyan; font-weight: 600;">type</span>: tool
    <span style="color: cyan; font-weight: 600;">tool</span>: local/create-subplan <span style="opacity: 0.7;"># Another named tool</span>
</code></pre></div>

**Tool node with anonymous inline tool:**

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">nodes</span>:
  - <span style="color: cyan;">name</span>: custom_validation
    <span style="color: cyan; font-weight: 600;">type</span>: tool
    <span style="color: cyan; font-weight: 600;">anonymous</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Validate output format before proceeding&quot;</span>
    <span style="color: cyan; font-weight: 600;">input_schema</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: object
      <span style="color: cyan; font-weight: 600;">properties</span>:
        <span style="color: cyan; font-weight: 600;">data</span>: { type: object }
    <span style="color: cyan; font-weight: 600;">capability</span>:
      <span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">code</span>: <span style="color: #66cc66;">|</span>
<span style="opacity: 0.7;">      # Inline Python — same format as a named tool YAML body</span>
      if not params[&quot;data&quot;].get(&quot;status&quot;):
          raise ValueError(&quot;Missing status field&quot;)
      return {&quot;valid&quot;: True}
</code></pre></div>

### Agent

#### Agent Definition

In CleverAgents, an **agent** is a specialized actor with:

* a conversational interface,
* tool-calling capability,
* potentially memory, planning heuristics, and role identity.

Examples of agent roles:

* planner/architect (strategy actor)
* coder/implementer (execution actor)
* reviewer/qa agent
* release/apply agent

The transcript explicitly discusses role separation like planner/coder/reviewer in context views/memory proposals.

#### Agent Behavior Configuration

Agents should be configurable without code changes:

* prompt templates
* tool sets
* safety constraints
* style constraints (verbosity, code style)
* reliability controls (self-checks, validations)

A design goal is user empowerment: "users customize LLM behavior without modifying core code."

### Tools

#### What a Tool Is

A **tool** is a namespaced, independently registered, callable operation. It is the **atomic unit of execution** in CleverAgents — the smallest piece of functionality that can read, write, or transform resources. Tools are defined in their own YAML configuration files, managed through the `agents tool` CLI commands, and registered in the **Tool Registry**.

Tools follow the same `<namespace>/<name>` naming convention as actors, skills, and other entities (e.g., `local/run-migrations`, `cleverthis/validate-api`, `local/create-subplan`). They support optional server-qualified prefixes for multi-server disambiguation (e.g., `dev:freemo/custom-analysis`).

**Validation as a Tool subtype**: A **Validation** is a specialized subtype of Tool that extends the Tool class with validation-specific metadata (`mode`: required/informational) and a structured JSON return format (`{ "passed": bool, "message": string, "data": object }`). Because Validation extends Tool via standard class inheritance, it inherits all base properties and behaviors — registration, resource bindings, lifecycle hooks, capability metadata, source types (custom, MCP, agent_skill, builtin, and the validation-specific `wrapped` source for Validations that delegate to an existing Tool), and the ability to exist as a tool node in an actor graph. A Validation can also **wrap** an existing plain Tool via the `wraps` field, reusing the Tool's implementation and interpreting its output through a `transform` function — see the **Tool Wrapping** subsection under Core Concepts > Validation for details.

Key constraints on Validations:

- **Always read-only**: Validations observe and report but never modify resources. `writes` is always `false` and `checkpointable` is always `false` (read-only operations need no checkpointing). The `agents validation add` command does not accept `--writes`/`--no-writes` or `--checkpointable`/`--no-checkpointable` flags.
- **Shared namespace**: Validations and plain Tools share the same naming namespace in the Tool Registry. A Validation and a plain Tool cannot have the same name — attempting to register a Validation with a name already taken by a Tool (or vice versa) results in a conflict error.
- **Superset/subset semantics**: A Validation can be used anywhere a Tool is expected (since it IS a Tool), but a plain Tool cannot be used where a Validation is specifically required (e.g., attached to a resource as a validation).
- **Unified management**: Since Validations live in the Tool Registry, they are listed via `agents tool list` (with `--type validation` to filter), inspected via `agents tool show`, and removed via `agents tool remove`. Only registration (`agents validation add`), attachment (`agents validation attach`), and detachment (`agents validation detach`) have validation-specific CLI commands.

Validations can be attached to resources directly, or to resources through projects or plans. The same mechanisms used to determine what tools can operate on what resources carry over to determining what validations apply to a particular resource. See the **Validation** section (immediately following this Tools section) for full details on the Validation type system, modes, attachment scoping, failure handling, and data model.

#### The Dual Role of Tools

Tools serve two distinct roles in CleverAgents:

1. **As components of a Skill**: A skill references tools by name to assemble a reusable capability collection. When an actor references a skill, all of that skill's tools (including those from included child skills) become available to the actor's LLM agent for tool-calling.

2. **As tool nodes in an Actor graph**: An actor's graph definition can include `type: tool` nodes that directly invoke a specific tool. This is used for deterministic, non-LLM steps in a workflow — e.g., spawning a child plan, running validation, or executing a migration. The tool node either references a named registered tool or defines an anonymous inline tool.

```kroki-mermaid
block-beta
    columns 3
    space:3
    block:header:3
        A["Tool: Dual Role"]
    end
    space:3
    block:role1:1
        B["Role 1: In a Skill"]
        C["Skill: local/devops"]
        D["tools:"]
        E["  - local/run-migrations"]
        F["  - local/validate-schema"]
        G["(tool-calling by LLM)"]
    end
    space:1
    block:role2:1
        H["Role 2: In an Actor Graph"]
        I["Actor Graph node:"]
        J["  name: run_db"]
        K["  type: tool"]
        L["  tool: local/run-migrations"]
        M["(deterministic invoke)"]
    end
```

#### Tool Configuration (YAML)

Tools are defined in their own YAML configuration files, separate from skills and actors. A tool YAML file declares the tool's identity, schema, capability metadata, and implementation:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># File: tools/run-migrations.yaml</span>
<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">&quot;3.0&quot;</span>

<span style="color: cyan; font-weight: 600;">tool</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/run-migrations
  <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Run database migrations for the API service&quot;</span>

  <span style="color: cyan; font-weight: 600;">source</span>: custom <span style="opacity: 0.7;"># mcp | agent_skill | builtin | custom</span>

<span style="opacity: 0.7;">  # Resource bindings — what resources this tool needs access to</span>
  <span style="color: cyan; font-weight: 600;">resources</span>:
    <span style="color: cyan; font-weight: 600;">db</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: local/database
      <span style="color: cyan; font-weight: 600;">access</span>: read_write
      <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">true</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Target database for migrations&quot;</span>

  <span style="color: cyan; font-weight: 600;">input_schema</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: object
    <span style="color: cyan; font-weight: 600;">properties</span>:
      <span style="color: cyan; font-weight: 600;">direction</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: string
        <span style="color: cyan; font-weight: 600;">enum</span>: [up, down]
      <span style="color: cyan; font-weight: 600;">count</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: integer
        <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: yellow;">1</span>
    <span style="color: cyan; font-weight: 600;">required</span>: [direction]

  <span style="color: cyan; font-weight: 600;">capability</span>:
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">write_scope</span>:
      <span style="color: cyan; font-weight: 600;">resource_slots</span>: [db] <span style="opacity: 0.7;"># References the &quot;db&quot; resource slot</span>
    <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">checkpoint_scope</span>: transaction
    <span style="color: cyan; font-weight: 600;">side_effects</span>: [schema_mutation]

  <span style="color: cyan; font-weight: 600;">code</span>: <span style="color: #66cc66;">|</span>
    import subprocess
    direction = params[&quot;direction&quot;]
    count = params.get(&quot;count&quot;, 1)
    db = ctx.resources[&quot;db&quot;]          # Access the bound database resource
    result = subprocess.run(
        [&quot;alembic&quot;, direction, str(count)],
        capture_output=True, text=True, cwd=db.sandbox.root
    )
    return {&quot;stdout&quot;: result.stdout, &quot;returncode&quot;: result.returncode}
</code></pre></div>

Another example — a tool that wraps an MCP server endpoint:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># File: tools/create-github-issue.yaml</span>
<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">&quot;3.0&quot;</span>

<span style="color: cyan; font-weight: 600;">tool</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/create-github-issue
  <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Create a GitHub issue via MCP&quot;</span>

  <span style="color: cyan; font-weight: 600;">source</span>: mcp
  <span style="color: cyan; font-weight: 600;">mcp_server</span>:
    <span style="color: cyan; font-weight: 600;">command</span>: <span style="color: #66cc66;">&quot;npx @anthropic/mcp-github&quot;</span>
    <span style="color: cyan; font-weight: 600;">env</span>:
      <span style="color: cyan; font-weight: 600;">GITHUB_TOKEN</span>: <span style="color: #66cc66;">&quot;${GITHUB_TOKEN}&quot;</span>
    <span style="color: cyan; font-weight: 600;">tool_name</span>: create_issue <span style="opacity: 0.7;"># The tool name as exposed by the MCP server</span>

  <span style="color: cyan; font-weight: 600;">capability</span>:
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">write_scope</span>: [github:issues]
    <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">false</span>
</code></pre></div>

And an Agent Skill tool:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># File: tools/deploy-staging.yaml</span>
<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">&quot;3.0&quot;</span>

<span style="color: cyan; font-weight: 600;">tool</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/deploy-staging
  <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Deploy the current branch to the staging environment&quot;</span>

  <span style="color: cyan; font-weight: 600;">source</span>: agent_skill
  <span style="color: cyan; font-weight: 600;">agent_skill</span>:
    <span style="color: cyan; font-weight: 600;">path</span>: ./skills/deploy-to-staging
    <span style="color: cyan; font-weight: 600;">sandbox_policy</span>: container
    <span style="color: cyan; font-weight: 600;">allowed_tools</span>: [&quot;Bash(docker:*)&quot;, &quot;Bash(kubectl:*)&quot;, &quot;Read&quot;]

  <span style="color: cyan; font-weight: 600;">capability</span>:
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">side_effects</span>: [deploy, infrastructure]
</code></pre></div>

#### Tool Registration and Management

Tools are managed through the `agents tool` CLI commands:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Register a new tool from its YAML configuration</span>
agents tool add <span style="color: cyan;">--config</span> ./tools/run-migrations.yaml

<span style="opacity: 0.7;"># Update an existing tool (re-reads the config file, overwrites registration)</span>
agents tool add <span style="color: cyan;">--config</span> ./tools/run-migrations.yaml <span style="color: cyan;">--update</span>

<span style="opacity: 0.7;"># List all registered tools</span>
agents tool list

<span style="opacity: 0.7;"># Show details for a tool (schema, capability, references)</span>
agents tool show local/run-migrations

<span style="opacity: 0.7;"># Remove a tool</span>
agents tool remove local/run-migrations
</code></pre></div>

Once registered, a tool is available to be referenced by skills (in their `tools` list) and by actor graphs (as `type: tool` nodes). Tools persist in the database (local or server) and follow the same namespace rules as actors and skills.

#### Anonymous Tools

An **anonymous tool** is an inline tool definition that appears directly in a skill YAML or an actor graph node. Anonymous tools use the **same format** as a named tool's YAML definition (same `input_schema`, `capability`, and `code` fields) but lack a namespaced name. They are:

* **Not registered** in the Tool Registry
* **Not reusable** — they exist only within the YAML file where they are defined
* **Useful for one-off operations** that are too specific to warrant separate registration

Anonymous tools in a skill YAML:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">skill</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/my-skill
  <span style="color: cyan; font-weight: 600;">tools</span>:
    - local/run-migrations          # Named tool reference
    - local/validate-api-compat     # Named tool reference

  <span style="color: cyan; font-weight: 600;">anonymous_tools</span>:                  # Inline definitions, same format as tool YAML
    - <span style="color: cyan;">description</span>: <span style="color: #66cc66;">&quot;One-off data cleanup for this project&quot;</span>
      <span style="color: cyan; font-weight: 600;">input_schema</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: object
        <span style="color: cyan; font-weight: 600;">properties</span>:
          <span style="color: cyan; font-weight: 600;">table</span>: { type: string }
      <span style="color: cyan; font-weight: 600;">capability</span>:
        <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">true</span>
        <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">true</span>
      <span style="color: cyan; font-weight: 600;">code</span>: <span style="color: #66cc66;">|</span>
<span style="opacity: 0.7;">        # ... Python code ...</span>
        return {&quot;cleaned&quot;: count}
</code></pre></div>

Anonymous tools in an actor graph node:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">nodes</span>:
  - <span style="color: cyan;">name</span>: custom_step
    <span style="color: cyan; font-weight: 600;">type</span>: tool
    <span style="color: cyan; font-weight: 600;">anonymous</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Inline validation specific to this workflow&quot;</span>
    <span style="color: cyan; font-weight: 600;">input_schema</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: object
      <span style="color: cyan; font-weight: 600;">properties</span>:
        <span style="color: cyan; font-weight: 600;">data</span>: { type: object }
    <span style="color: cyan; font-weight: 600;">capability</span>:
      <span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">code</span>: <span style="color: #66cc66;">|</span>
<span style="opacity: 0.7;">      # ... Python code ...</span>
      return {&quot;valid&quot;: True}
</code></pre></div>

The anonymous tool format is intentionally identical to the body of a named tool YAML — this means promoting an anonymous tool to a named, registered tool is a simple copy-paste into its own YAML file and `agents tool add`.

#### Metadata Overrides

When referencing a named tool in a skill or actor graph, its registered metadata can optionally be **overridden** at the point of use. This allows context-specific adjustments without modifying the tool's global registration.

**Overriding tool metadata in a skill:**

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">skill</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/strict-devops
  <span style="color: cyan; font-weight: 600;">tools</span>:
    - <span style="color: cyan;">name</span>: local/run-migrations
      <span style="color: cyan; font-weight: 600;">override</span>:
        <span style="color: cyan; font-weight: 600;">capability</span>:
          <span style="color: cyan; font-weight: 600;">human_approval_required</span>: <span style="color: magenta; font-weight: 600;">true</span> <span style="opacity: 0.7;"># Override: require approval in this skill</span>
          <span style="color: cyan; font-weight: 600;">write_scope</span>: [database:staging] <span style="opacity: 0.7;"># Override: restrict scope for this context</span>

    - local/validate-api-compat            # No overrides, use as registered
</code></pre></div>

**Overriding tool metadata in an actor graph node:**

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">nodes</span>:
  - <span style="color: cyan;">name</span>: safe_migrate
    <span style="color: cyan; font-weight: 600;">type</span>: tool
    <span style="color: cyan; font-weight: 600;">tool</span>: local/run-migrations
    <span style="color: cyan; font-weight: 600;">override</span>:
      <span style="color: cyan; font-weight: 600;">capability</span>:
        <span style="color: cyan; font-weight: 600;">human_approval_required</span>: <span style="color: magenta; font-weight: 600;">true</span>
</code></pre></div>

**Overriding tool metadata when including a sub-skill:**

When a skill includes another skill (importing all its tools), individual tools from the included skill can have their metadata overridden:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">skill</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/production-ops
  <span style="color: cyan; font-weight: 600;">includes</span>:
    - <span style="color: cyan;">name</span>: local/devops-toolkit
      <span style="color: cyan; font-weight: 600;">tool_overrides</span>:
        - <span style="color: cyan;">tool</span>: local/run-migrations
          <span style="color: cyan; font-weight: 600;">override</span>:
            <span style="color: cyan; font-weight: 600;">capability</span>:
              <span style="color: cyan; font-weight: 600;">human_approval_required</span>: <span style="color: magenta; font-weight: 600;">true</span> <span style="opacity: 0.7;"># In this context, require human approval</span>
              <span style="color: cyan; font-weight: 600;">write_scope</span>: [database:production]

        - <span style="color: cyan;">tool</span>: local/create-github-issue
          <span style="color: cyan; font-weight: 600;">override</span>:
            <span style="color: cyan; font-weight: 600;">capability</span>:
              <span style="color: cyan; font-weight: 600;">human_approval_required</span>: <span style="color: magenta; font-weight: 600;">true</span> <span style="opacity: 0.7;"># Require approval in this context</span>
</code></pre></div>

Override rules:
1. Overrides are **shallow-merged** — only the specified fields are replaced; unspecified fields retain their registered values.
2. Overrides **never persist** back to the Tool Registry — they apply only at the point of use.
3. Built-in tool metadata **cannot be overridden** (it is authoritative from the implementation).
4. The override scope is limited to `capability` and `description` fields. Schema (`input_schema`, `output_schema`) cannot be overridden because it would break callers' expectations.

#### Resource Bindings

Tools operate on **resources** — git repositories, filesystems, databases, and more. The **resource binding** system declares and resolves the relationship between a tool and the resources it needs access to.

##### Resource Slots

A tool declares one or more **resource slots** in its YAML configuration. Each slot is a typed placeholder that specifies:

* **Slot name**: A logical name used to reference the resource within the tool's code and parameters.
* **Resource type**: The resource type required (e.g., `git`, `fs-mount`, `local/database`). The bound resource must be of this type (or a compatible subtype).
* **Access mode**: `read_only`, `write_only`, or `read_write`.
* **Description**: Human-readable explanation of what the tool uses this resource for.
* **Required/optional**: Whether the slot must be bound for the tool to function.

Example tool YAML with resource slots:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">tool</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/run-migrations
  <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Run database migrations&quot;</span>
  <span style="color: cyan; font-weight: 600;">source</span>: custom

  <span style="color: cyan; font-weight: 600;">resources</span>:
    <span style="color: cyan; font-weight: 600;">db</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: local/database
      <span style="color: cyan; font-weight: 600;">access</span>: read_write
      <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">true</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Target database for migrations&quot;</span>

  <span style="color: cyan; font-weight: 600;">capability</span>:
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">write_scope</span>: [db:migrations] <span style="opacity: 0.7;"># References the &quot;db&quot; slot</span>
    <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">true</span>

  <span style="color: cyan; font-weight: 600;">code</span>: <span style="color: #66cc66;">|</span>
    direction = params[&quot;direction&quot;]
    db_resource = ctx.resources[&quot;db&quot;]   # Access the bound resource
    result = db_resource.handler.execute_migration(direction, db_resource.sandbox)
    return {&quot;status&quot;: &quot;ok&quot;}
</code></pre></div>

A tool that works with multiple resources:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">tool</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/cross-repo-diff
  <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Compare files across two git repositories&quot;</span>
  <span style="color: cyan; font-weight: 600;">source</span>: custom

  <span style="color: cyan; font-weight: 600;">resources</span>:
    <span style="color: cyan; font-weight: 600;">source_repo</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: git-checkout
      <span style="color: cyan; font-weight: 600;">access</span>: read_only
      <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">true</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Source repository to compare from&quot;</span>
    <span style="color: cyan; font-weight: 600;">target_repo</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: git-checkout
      <span style="color: cyan; font-weight: 600;">access</span>: read_only
      <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">true</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Target repository to compare against&quot;</span>

  <span style="color: cyan; font-weight: 600;">capability</span>:
    <span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">true</span>

  <span style="color: cyan; font-weight: 600;">code</span>: <span style="color: #66cc66;">|</span>
    source = ctx.resources[&quot;source_repo&quot;]
    target = ctx.resources[&quot;target_repo&quot;]
<span style="opacity: 0.7;">    # ... compare files across repos ...</span>
</code></pre></div>

##### Three Binding Modes

Resource slots are resolved to actual resources through one of three binding modes:

**1. Contextual Binding (default)**

The slot declares a resource type requirement, and the system resolves it from the plan's project context at activation time. This is the most common mode — the tool says "I need a git-checkout resource" and the system finds one among the project's linked resources.

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">resources</span>:
  <span style="color: cyan; font-weight: 600;">repo</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: git-checkout
    <span style="color: cyan; font-weight: 600;">access</span>: read_write
<span style="opacity: 0.7;">    # No `bind` field → contextual binding</span>
</code></pre></div>

Resolution rules for contextual binding:
* The system searches the plan's project for linked resources matching the slot's type.
* If exactly one resource of the right type exists, it is automatically bound.
* If multiple resources match, the system uses the slot name as a hint (e.g., a slot named `repo` prefers a resource with alias `repo`). If ambiguous, the plan execution raises an error requiring explicit binding.
* If no resource matches, the tool cannot be activated for this plan (a validation error is raised during plan creation).

**2. Static Binding**

The slot is hardcoded to a specific registered resource by name. This is useful for tools that always operate on the same resource, regardless of project context.

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">resources</span>:
  <span style="color: cyan; font-weight: 600;">docs</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: fs-mount
    <span style="color: cyan; font-weight: 600;">access</span>: read_only
    <span style="color: cyan; font-weight: 600;">bind</span>: local/company-docs <span style="opacity: 0.7;"># Static: always this resource</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Company documentation corpus&quot;</span>
</code></pre></div>

Static bindings are resolved at registration time and validated — the named resource must exist and be of the correct type.

**3. Parameter Binding**

The resource reference is passed as a tool argument at invocation time. This is useful for tools that operate on user-specified resources.

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">resources</span>:
  <span style="color: cyan; font-weight: 600;">target</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: git-checkout
    <span style="color: cyan; font-weight: 600;">access</span>: read_only
    <span style="color: cyan; font-weight: 600;">from_param</span>: repository <span style="opacity: 0.7;"># Bound from the &quot;repository&quot; input parameter</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Repository to analyze&quot;</span>

<span style="color: cyan; font-weight: 600;">input_schema</span>:
  <span style="color: cyan; font-weight: 600;">type</span>: object
  <span style="color: cyan; font-weight: 600;">properties</span>:
    <span style="color: cyan; font-weight: 600;">repository</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Name of the registered resource to analyze&quot;</span>
  <span style="color: cyan; font-weight: 600;">required</span>: [repository]
</code></pre></div>

The `from_param` field links a resource slot to an input parameter. At invocation time, the system resolves the parameter value as a resource name from the Resource Registry and validates type compatibility.

##### Binding Resolution Flow

```kroki-mermaid
stateDiagram-v2
    [*] --> ToolActivation: Actor references skill or tool node

    state "For Each Resource Slot" as ForEach {
        state binding_check <<choice>>
        [*] --> binding_check: Check binding type

        binding_check --> StaticBinding: has bind field
        binding_check --> ContextualBinding: no bind, no from_param
        binding_check --> ParameterBinding: has from_param

        state "Static Binding" as StaticBinding {
            [*] --> ResolveByName: Resolve from Resource Registry
            ResolveByName --> ValidateType: Validate type compatibility
        }

        state "Contextual Binding" as ContextualBinding {
            [*] --> SearchProject: Search plan's project resources
            SearchProject --> FilterByType: Filter by resource type
            state match_check <<choice>>
            FilterByType --> match_check
            match_check --> AutoBind: One match
            match_check --> TryAlias: Multiple matches
            match_check --> ValidationError: No matches
            TryAlias --> AliasMatch: Try alias/name match
            AliasMatch --> AutoBind: Match found
            AliasMatch --> ValidationError: No match
        }

        state "Parameter Binding" as ParameterBinding {
            [*] --> DeferBinding: Defer to invocation time
        }

        StaticBinding --> StoreBindings
        AutoBind --> StoreBindings
        ParameterBinding --> StoreBindings
        state "Store in ToolActivationContext" as StoreBindings
    }

    state "Tool Invocation" as Invocation {
        [*] --> ResolveParams: Resolve parameter-bound slots\nfrom invocation params
        [*] --> ValidateAccess: Ensure sandbox exists\nValidate access mode
        ResolveParams --> Execute
        ValidateAccess --> Execute
        state "Execute tool with bound resources" as Execute
    }

    ForEach --> Invocation
    Invocation --> [*]
```

##### Built-in Tool Resource Bindings

Built-in tools have **implicit resource slots** that do not need to be declared in YAML (they are hardcoded in the implementation):

| Built-in Tool Group | Implicit Slot | Slot Type | Access |
|---------------------|--------------|-----------|--------|
| `file_operations` (read_file, write_file, edit_file, etc.) | `directory` | `fs-directory` or `git-checkout` | `read_write` |
| `directory_operations` (create_directory, list_directory, etc.) | `directory` | `fs-directory` or `git-checkout` | `read_write` |
| `search_operations` (search_files, find_definition, etc.) | `directory` | `fs-directory` or `git-checkout` | `read_only` |
| `git_operations` (git_status, git_diff, git_log, etc.) | `repo` | `git-checkout` | `read_only` |

Built-in tools accept both `fs-directory` and `git-checkout` types for file operations because a `git-checkout` resource's worktree root is an `fs-directory`. When binding to a `git-checkout`, the resource router automatically resolves to the worktree root `fs-directory` child for file operations. A standalone `fs-mount` resource also works — the router resolves through the `fs-mount` → root `fs-directory` chain.

##### Resource Discovery via Bindings

The binding system enables powerful resource discovery queries:

* **"What tools can modify this resource?"** → Find all tools with resource slots matching the resource's type and `access: read_write` or `access: write_only`.
* **"What tools can read this virtual file?"** → Find the virtual file's physical children, then find tools with slots matching each physical resource's type.
* **"What resources does this tool need?"** → Inspect the tool's declared resource slots.
* **"Is this tool compatible with this project?"** → Check if the project's linked resources can satisfy all of the tool's required resource slots.

#### Tool Registry

CleverAgents maintains a **Tool Registry** — a persistent catalog of all independently registered tools:

```kroki-plantuml
@startuml
skinparam classAttributeIconSize 0
skinparam classFontSize 13
skinparam noteFontSize 11
skinparam defaultFontSize 12

class ToolRegistry {
  - toolIndex : Map<String, ToolRecord>
  --
  + add(config_path) : ToolRecord
  + update(name, config_path) : ToolRecord
  + remove(name) : void
  + lookup(name) : ToolRecord
  + list(filters) : ToolRecord[]
}

class ToolRecord {
  + name : String
  + description : String
  + source : String {mcp|agent_skill|builtin|custom}
  + config_path : String
  + input_schema : JSONSchema
  + output_schema : JSONSchema
  + capability_metadata : CapabilityMetadata
  + resource_slots : List<ResourceSlot>
  + code : String
}

ToolRegistry "1" *-- "0..*" ToolRecord : indexes >

note right of ToolRegistry
  **Populated by:**
  - agents tool add CLI command
  - Dynamic refresh on MCP notifications

  **Consumed by:**
  - Skill registration
  - Actor graph construction
  - Resource binding resolution
  - Plan validation
end note
@enduml
```

The Tool Registry works alongside the Skill Registry (described in the Skills section). Skills reference tools by name from the Tool Registry; the Skill Registry's flattened tool sets are composed from Tool Registry entries plus any anonymous inline tools.

#### Tool Interface and Architecture

Each individual tool — whether independently registered or defined as an anonymous inline tool — conforms to a uniform interface regardless of its source:

```kroki-plantuml
@startuml
skinparam classAttributeIconSize 0
skinparam classFontSize 13
skinparam defaultFontSize 12
skinparam linetype ortho

class Tool {
}

class Identity {
  + name : String
  + qualified_name : String
  + source : ToolSource
}

class Schema {
  + input_schema : JSONSchema
  + output_schema : JSONSchema
}

class CapabilityMetadata {
  + read_only : Boolean
  + writes : Boolean
  + write_scope : String
  + idempotent : Boolean
  + checkpointable : Boolean
  + side_effects : List<String>
  + cost_profile : String
  + human_approval_required : Boolean
}

class ResourceBindings {
  + slots : Map<String, ResourceSlot>
}

class ResourceSlot {
  + type : String
  + access : String
  + required : Boolean
  + bind : String
  + from_param : String
  + description : String
}

interface Lifecycle <<interface>> {
  + discover() : ToolDescriptor
  + activate() : void
  + execute(params, ctx) : Result
  + deactivate() : void
}

class ExecutionContext {
  + sandbox : Sandbox
  + plan : Plan
  + changes : List<Change>
  + resources : Map<String, BoundResource>
}

enum ToolSource {
  mcp
  agent_skill
  builtin
  custom
}

Tool *-- Identity
Tool *-- Schema
Tool *-- CapabilityMetadata
Tool *-- ResourceBindings
Tool *-- Lifecycle
Tool o-- ExecutionContext : uses at runtime >
ResourceBindings *-- "0..*" ResourceSlot
Identity --> ToolSource
@enduml
```

Every tool implements the same four lifecycle methods. The **tool adapter layer** is responsible for translating source-specific behavior into these methods.

#### Tool Adapter Layer

Each tool source has a corresponding **adapter** that translates source-specific protocols into the uniform tool interface:

```kroki-plantuml
@startuml
skinparam classAttributeIconSize 0
skinparam classFontSize 13
skinparam defaultFontSize 12

interface "ToolInterface" as UTI <<interface>> {
  + discover() : ToolDescriptor
  + activate() : void
  + execute(params, ctx) : Result
  + deactivate() : void
}

class MCPToolAdapter {
  + discover() : ToolDescriptor
  .. tools/list RPC → descriptors ..
  + activate() : void
  .. spawn server, init JSON-RPC ..
  + execute(params, ctx) : Result
  .. tools/call RPC → result ..
  + deactivate() : void
  .. shutdown server ..
}

class AgentSkillAdapter {
  + discover() : ToolDescriptor
  .. parse SKILL.md frontmatter ..
  + activate() : void
  .. load SKILL.md body into agent context ..
  + execute(params, ctx) : Result
  .. agent follows instructions, runs scripts ..
  + deactivate() : void
  .. remove from context ..
}

class BuiltinAdapter {
  + discover() : ToolDescriptor
  .. return hardcoded descriptors ..
  + activate() : void
  .. no-op ..
  + execute(params, ctx) : Result
  .. call native Python impl ..
  + deactivate() : void
  .. no-op ..
}

MCPToolAdapter .up.|> UTI
AgentSkillAdapter .up.|> UTI
BuiltinAdapter .up.|> UTI
@enduml
```

##### MCPToolAdapter

Bridges external MCP servers into the tool model:

1. **discover()**: Spawns the MCP server process (or connects to a remote Streamable HTTP endpoint), performs the MCP `initialize` handshake, negotiates capabilities, then calls `tools/list` to enumerate available tools. Each MCP tool becomes a separate `ToolDescriptor` with its `inputSchema` and inferred capability metadata.

2. **activate()**: Ensures the MCP server process is running and the JSON-RPC connection is healthy. For remote servers, validates the authentication token. Registers for `notifications/tools/list_changed` so CleverAgents can dynamically update available tools.

3. **execute()**: Translates a `Tool.execute(params, ctx)` call into an MCP `tools/call` JSON-RPC request. Before dispatching:
   - Rewrites file paths to sandbox-relative paths
   - Validates params against `inputSchema`
    - Checks capability metadata against plan access policy
   - Creates a checkpoint if the tool is marked checkpointable
   
   After the MCP tool returns its `content[]` response, the adapter:
   - Parses the result into the CleverAgents `Result` format
   - Records any resource mutations as `Change` objects in the plan's `ChangeSet`

4. **deactivate()**: Sends a clean shutdown to the MCP server process and closes the JSON-RPC connection.

**Capability inference**: MCP tools expose limited metadata (name, description, inputSchema). The adapter infers extended capability metadata using heuristics:
- Tools whose names contain `read`, `get`, `list`, `search`, `find` → `read_only: true`
- Tools whose names contain `write`, `create`, `update`, `delete`, `set` → `writes: true`
- All inferences can be overridden via the `overrides` block in tool or skill YAML

##### AgentSkillAdapter

Bridges Agent Skills Standard (`SKILL.md` folders) into the tool model. Agent Skills are fundamentally different from MCP tools — they are **instruction-driven** rather than **schema-driven**. An Agent Skill is not a single function call; it is a bundle of procedural knowledge that an LLM agent loads into its context and follows.

1. **discover()**: Scans the configured skill directory for a `SKILL.md` file. Parses only the YAML frontmatter (`name`, `description`, optional `compatibility`, `metadata`, `allowed-tools`) to produce a lightweight `ToolDescriptor`. This metadata is injected into the agent's system prompt in a structured format so the LLM can decide when the skill is relevant:

   <div class="highlight"><pre><code>
   &lt;<span <span style="color: yellow;">style</span>="color: cyan; font-weight: 600;">available_agent_skills</span>&gt;
     &lt;<span <span style="color: yellow;">style</span>="color: cyan; font-weight: 600;">agent_skill</span>&gt;
       &lt;<span <span style="color: yellow;">style</span>="color: cyan; font-weight: 600;">name</span>&gt;deploy-to-staging&lt;/<span <span style="color: yellow;">style</span>="color: cyan; font-weight: 600;">name</span>&gt;
       &lt;<span <span style="color: yellow;">style</span>="color: cyan; font-weight: 600;">description</span>&gt;Deploy the current branch to the staging environment.&lt;/<span <span style="color: yellow;">style</span>="color: cyan; font-weight: 600;">description</span>&gt;
       &lt;<span <span style="color: yellow;">style</span>="color: cyan; font-weight: 600;">tool</span>&gt;local/deploy-staging&lt;/<span <span style="color: yellow;">style</span>="color: cyan; font-weight: 600;">tool</span>&gt;
     &lt;/<span <span style="color: yellow;">style</span>="color: cyan; font-weight: 600;">agent_skill</span>&gt;
   &lt;/<span <span style="color: yellow;">style</span>="color: cyan; font-weight: 600;">available_agent_skills</span>&gt;
   </code></pre></div>

   Discovery is **low-cost** — only ~50–100 tokens per Agent Skill for metadata. The full instructions are not loaded until activation.

2. **activate()**: When the LLM agent determines (or is instructed) that a task matches the skill's description, the adapter loads the full `SKILL.md` Markdown body into the agent's active context. This injects step-by-step instructions, examples, edge cases, and references to bundled scripts. The tool is now "active" — the agent has the procedural knowledge to execute it.

   If the skill references additional files (`references/*.md`, `scripts/*.py`, `assets/*`), these are made available on demand — the agent can read them as needed, following the Agent Skills Standard's **progressive disclosure** model.

3. **execute()**: Unlike MCP tools (which are single RPC calls), Agent Skill execution is **agent-mediated**. The LLM agent follows the loaded instructions, potentially:
   - Running bundled scripts via shell execution (sandboxed)
   - Reading reference files for additional context
   - Using other available tools (e.g., built-in file operations) as part of the procedure
   - Making multiple tool calls in sequence to accomplish the workflow
   
   The adapter wraps this execution in a tool execution context so that all mutations are tracked, sandboxed, and checkpointable. Script execution respects the `allowed_tools` and `sandbox_policy` declared in the tool's YAML.

4. **deactivate()**: Removes the skill's instructions from the agent's active context to free up token budget. The skill's metadata remains available for re-activation.

**Key design principle**: Agent Skills extend the agent's *knowledge*, not just its *toolset*. An Agent Skill can teach an agent a multi-step workflow that involves calling multiple other tools, making decisions based on intermediate results, and following domain-specific best practices — something a single MCP tool call cannot express.

##### BuiltinToolAdapter

Wraps CleverAgents' native resource operations as tools:

1. **discover()**: Returns hardcoded `ToolDescriptor` objects for each built-in operation. These descriptors have fully specified capability metadata since the implementation is first-party.

2. **activate()**: No-op. Built-in tools are always available.

3. **execute()**: Calls the native Python implementation directly. Built-in tools operate through the resource abstraction layer, automatically integrating with sandbox path mapping, change tracking, and checkpointing.

4. **deactivate()**: No-op.

**Built-in tool groups:**

**File Operations (`file_operations`):**
<div class="highlight"><pre><code>
read_file(path: <span style="color: cyan;">str</span>) -&gt; <span style="color: cyan;">str</span>
write_file(path: <span style="color: cyan;">str</span>, content: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>
edit_file(path: <span style="color: cyan;">str</span>, edits: <span style="color: cyan;">list</span>[Edit]) -&gt; <span style="color: magenta; font-weight: 600;">None</span>
delete_file(path: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>
move_file(source: <span style="color: cyan;">str</span>, destination: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>
copy_file(source: <span style="color: cyan;">str</span>, destination: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>
</code></pre></div>

**Directory Operations (`directory_operations`):**
<div class="highlight"><pre><code>
create_directory(path: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>
list_directory(path: <span style="color: cyan;">str</span>, pattern: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;*&quot;</span>) -&gt; <span style="color: cyan;">list</span>[<span style="color: cyan;">str</span>]
delete_directory(path: <span style="color: cyan;">str</span>, recursive: <span style="color: cyan;">bool</span> = <span style="color: magenta; font-weight: 600;">False</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>
</code></pre></div>

**Search Operations (`search_operations`):**
<div class="highlight"><pre><code>
search_files(pattern: <span style="color: cyan;">str</span>, content_pattern: <span style="color: cyan;">str</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: cyan;">list</span>[Match]
find_definition(symbol: <span style="color: cyan;">str</span>) -&gt; <span style="color: cyan;">list</span>[Location]
find_references(symbol: <span style="color: cyan;">str</span>) -&gt; <span style="color: cyan;">list</span>[Location]
</code></pre></div>

**Git Operations (`git_operations`, when resource is a git repository):**
<div class="highlight"><pre><code>
git_status() -&gt; GitStatus
git_diff(path: <span style="color: cyan;">str</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: cyan;">str</span>
git_log(count: <span style="color: cyan;">int</span> = 10) -&gt; <span style="color: cyan;">list</span>[Commit]
git_blame(path: <span style="color: cyan;">str</span>) -&gt; <span style="color: cyan;">list</span>[BlameLine]
</code></pre></div>

Each built-in tool:
* Has fully defined capability metadata
* Operates through the resource abstraction layer
* Automatically tracks changes to the ChangeSet
* Respects sandbox boundaries and deny-lists

#### Tool Capability Metadata (Critical for Safety)

MCP's metadata is not sufficient (read-only/idempotent is not enough; write scope is unclear). CleverAgents extends every tool — regardless of source — with a uniform capability metadata schema:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">capability</span>:
  <span style="color: cyan; font-weight: 600;">read_only</span>: bool <span style="opacity: 0.7;"># Whether tool only performs read operations</span>
  <span style="color: cyan; font-weight: 600;">writes</span>: bool <span style="opacity: 0.7;"># Whether tool can modify resources</span>
  <span style="color: cyan; font-weight: 600;">write_scope</span>:             # What the tool is allowed to mutate
    - <span style="color: cyan;">file_paths</span>: [&quot;src/**&quot;, &quot;tests/**&quot;]     # Path patterns within bound resources
    - <span style="color: cyan;">resource_slots</span>: [&quot;repo&quot;, &quot;db&quot;]         # Resource slot names (from resource bindings)
    - <span style="color: cyan;">environment</span>: container | host
  <span style="color: cyan; font-weight: 600;">idempotent</span>: bool <span style="opacity: 0.7;"># Whether repeated calls produce same result</span>
  <span style="color: cyan; font-weight: 600;">checkpointable</span>: bool <span style="opacity: 0.7;"># Whether tool supports checkpoint/rollback</span>
  <span style="color: cyan; font-weight: 600;">checkpoint_scope</span>: str <span style="opacity: 0.7;"># What can be rolled back (file, transaction, commit, snapshot)</span>
  <span style="color: cyan; font-weight: 600;">side_effects</span>:            # Non-reversible effects
    - install_packages
    - mutate_infra
    - send_email
  <span style="color: cyan; font-weight: 600;">cost_profile</span>:            # Usage constraints
    <span style="color: cyan; font-weight: 600;">rate_limit</span>: <span style="color: #66cc66;">&quot;10/min&quot;</span>
    <span style="color: cyan; font-weight: 600;">estimated_cost</span>: <span style="color: #66cc66;">&quot;$0.01/call&quot;</span>
  <span style="color: cyan; font-weight: 600;">human_approval_required</span>: bool <span style="opacity: 0.7;"># Whether a human must approve invocation</span>
</code></pre></div>

**Where metadata comes from per source:**

| Source | Metadata origin | Override mechanism |
|--------|-----------------|--------------------|
| Built-in | Hardcoded in implementation | Not overridable (authoritative) |
| MCP | Inferred from tool name/description + MCP annotations | `overrides` block in tool or skill YAML; `override` at skill/actor reference point |
| Agent Skill | Declared in SKILL.md frontmatter `metadata` + inferred from `allowed-tools` | Tool YAML `capability` block; `override` at skill/actor reference point |
| Custom | Manually declared in tool YAML `capability` block | `override` at skill/actor reference point (author is the source of truth for registered values) |

#### Read-Only Actions and Tool Access Control

When an action is marked `read_only: true`, it can **only use tools that have `read_only: true`** in their capability metadata. This is enforced at runtime by the tool execution context — any attempt to invoke a tool with `writes: true` from a read-only plan raises a `AccessDeniedError`.

#### Tool Execution Flow

When an LLM agent decides to use a tool (regardless of source), the following flow occurs through the unified execution pipeline:

<div class="highlight"><pre><code>
1. LLM generates tool call
   e.g., edit_file(path=&quot;src/main.py&quot;, changes=[...])
   or:   local/github.create_issue(title=&quot;Bug fix&quot;, body=&quot;...&quot;)
   or:   (activates Agent Skill &quot;deploy-to-staging&quot; via instructions)
                                ↓
2. Tool Router receives call
   - Resolves tool by name from the Tool Registry or actor&#x27;s skill tool sets
   - Validates parameters against inputSchema
    - Checks capability metadata against plan&#x27;s access policy:
     • Is this tool in allowed skill categories?
     • Does the plan allow writes?
     • Is human approval required?
   - If denied → return AccessDeniedError to LLM
                                ↓
3. Resource Binding Resolution &amp; Sandbox Context
   - Resolve resource bindings for this tool:
     • Static bindings: already resolved at registration
     • Contextual bindings: resolve from plan&#x27;s project resources
     • Parameter bindings: resolve from invocation arguments
   - Validate resource type compatibility for each slot
   - Validate access mode (e.g., read_write tool on read_only resource → error)
   - Ensure sandbox exists for each bound resource (lazy sandboxing)
   - Maps logical paths to sandbox-relative paths via bound resource handlers
   - Inject bound resources into ctx.resources[slot_name]
   - If tool is checkpointable → create pre-execution checkpoint
                                ↓
4. Adapter-Specific Execution
   - MCP: sends tools/call JSON-RPC to server process
   - Agent Skill: agent follows loaded SKILL.md instructions,
     running scripts and tools in sandboxed shell
   - Built-in: calls native Python implementation directly
   - Custom: executes inline code with sandboxed context
                                ↓
5. Change Recording
   - If tool modified resources → create Change record(s)
   - Append Change(s) to plan&#x27;s ChangeSet
   - Update sandbox state
   - If checkpointable → record checkpoint for rollback
                                ↓
6. Result Return
   - Normalize result to uniform Result type
   - Return to LLM agent for continued reasoning
</code></pre></div>

#### Change Tracking from Tool Invocations

**Critical Architecture Point:** The ChangeSet is NOT built by parsing LLM output. It is built by recording the effects of tool invocations:

<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">ToolExecutionContext</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;Context provided to every tool execution, regardless of source.&quot;&quot;&quot;</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">__init__</span>(self, plan: Plan, sandbox: Sandbox,
                 resources: <span style="color: cyan;">dict</span>[<span style="color: cyan;">str</span>, BoundResource]):
        self.plan = plan
        self.sandbox = sandbox
        self.resources = resources    <span style="opacity: 0.7;"># slot_name → BoundResource</span>
        self.changes: <span style="color: cyan;">list</span>[Change] = []
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">record_change</span>(self, change: Change) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Record a change made by a tool.&quot;&quot;&quot;</span>
        self.changes.append(change)
        self.plan.changeset.add_change(change)


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">WriteFileTool</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;Example: built-in tool for writing files.&quot;&quot;&quot;</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">execute</span>(self, path: <span style="color: cyan;">str</span>, content: <span style="color: cyan;">str</span>, ctx: ToolExecutionContext) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        handler = ctx.sandbox.get_handler(path)
        change = handler.write(path, content, ctx.sandbox)
        ctx.record_change(change)
</code></pre></div>

This approach means:
* Every resource modification is explicit and tracked
* The ChangeSet accurately reflects what was done, not what was said
* Rollback is precise (replay inverse of recorded changes)
* Audit logs show exactly which tool invocation produced each change

#### MCP Integration Details

##### MCP Concepts Mapping

| MCP Concept | CleverAgents Equivalent | Extension |
|------------|------------------------|-----------|
| Tool | Independently registered Tool (source: mcp), referenced by skills | Extended capability metadata (write_scope, checkpointable, side_effects) |
| Resource | Resource | Extended to support both read AND write operations |
| Prompt | Action template | Full plan lifecycle (Strategize → Execute → Apply) |
| Server | MCP Server connection (declared in tool or skill YAML) | Managed by MCPToolAdapter with lifecycle and reconnection |
| JSON-RPC | Internal adapter protocol | Abstracted behind Tool.execute() |

##### MCP Server Lifecycle Management

CleverAgents manages MCP server processes as part of the tool/skill/actor lifecycle:

```kroki-mermaid
sequenceDiagram
    participant CLI as CLI
    participant Reg as Registry
    participant ActorRT as Actor Runtime
    participant Adapter as MCPToolAdapter
    participant MCP as MCP Server

    note over CLI,Reg: Phase 1 - Registration
    CLI->>Reg: agents tool add or skill add
    Reg->>Reg: Validate server command or endpoint
    Reg->>Reg: Store server config in record

    note over ActorRT,MCP: Phase 2 - Actor Activation
    ActorRT->>Adapter: Activate (for each MCP server)
    Adapter->>MCP: Spawn process (stdio) or connect (HTTP)
    Adapter->>MCP: MCP initialize handshake
    MCP-->>Adapter: Capabilities
    Adapter->>MCP: tools list
    MCP-->>Adapter: Tool descriptors
    Adapter->>MCP: Subscribe notifications tools list_changed

    note over ActorRT,MCP: Phase 3 - Execution
    ActorRT->>Adapter: LLM generates tool call
    Adapter->>MCP: tools call (JSON-RPC)
    MCP-->>Adapter: Result
    Adapter->>ActorRT: Result + Change tracking

    note over ActorRT,MCP: Phase 4 - Deactivation
    ActorRT->>Adapter: Deactivate
    Adapter->>MCP: Clean shutdown
```

##### Sandbox Path Rewriting for MCP Tools

MCP servers operate on real filesystem paths, but CleverAgents executes plans in sandboxes. The MCPToolAdapter transparently rewrites paths:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Before sending to MCP server:</span>
<span style="opacity: 0.7;"># Logical path: &quot;src/main.py&quot;</span>
<span style="opacity: 0.7;"># Sandbox path: &quot;/tmp/sandbox-01HXM/worktree/src/main.py&quot;</span>
<span style="opacity: 0.7;"># The adapter rewrites the tool arguments so the MCP server</span>
<span style="opacity: 0.7;"># operates on sandboxed state without knowing about the sandbox.</span>
</code></pre></div>

This ensures MCP tools respect sandbox boundaries even though they have no awareness of the CleverAgents sandbox model.

#### Agent Skills Integration Details

##### Discovery and Progressive Disclosure

Agent Skills follow a three-tier progressive disclosure model that maps directly to the tool lifecycle:

| Tier | What loads | When | Token cost |
|------|-----------|------|------------|
| **Metadata** | `name` + `description` from SKILL.md frontmatter | Tool registration / actor activation | ~50–100 tokens per Agent Skill |
| **Instructions** | Full SKILL.md Markdown body | When LLM determines task matches the skill (activate phase) | Recommended < 5000 tokens |
| **Resources** | `scripts/`, `references/`, `assets/` | On demand during execution | Variable |

This means an actor can have dozens of Agent Skill tools available but only pay the token cost for their metadata at startup. Full instructions load only when relevant.

##### Agent Skills vs. MCP Tools: When to Use Which

| Dimension | MCP Tools | Agent Skills |
|-----------|-----------|--------------|
| **Interaction model** | Single function call with JSON params/result | Multi-step procedure with instructions the agent follows |
| **Knowledge type** | "Here is a function you can call" | "Here is how to accomplish a complex task" |
| **Statefulness** | Stateless per-call | Stateful across multiple tool calls within a procedure |
| **Authoring** | Implement an MCP server (code) | Write a SKILL.md file (prose + optional scripts) |
| **Portability** | Any MCP-compatible host | Any Agent Skills-compatible agent |
| **Best for** | Atomic operations (CRUD, queries, API calls) | Complex workflows (code review processes, deployment procedures, data analysis pipelines) |

Both can coexist in the same skill. A common pattern is an Agent Skill tool that teaches the agent a workflow which involves calling multiple MCP tools:

<div class="highlight"><pre><code>
Agent Skill Tool: &quot;local/deploy-staging&quot;
  SKILL.md instructions:
    1. Run tests using the built-in shell tool
    2. Create a PR using the GitHub MCP tool (create_pull_request)
    3. Wait for CI using the GitHub MCP tool (get_check_runs)
    4. Deploy using the AWS MCP tool (ecs_update_service)
    5. Verify deployment using the HTTP MCP tool (fetch_url)
</code></pre></div>

#### Tool-Level Checkpointability

Each tool declares whether it supports checkpoint/rollback via its capability metadata. Checkpointing behavior varies by source:

| Source | Checkpoint mechanism |
|--------|---------------------|
| **Built-in file ops** | Snapshot file state pre-modification; rollback restores file content |
| **Built-in git ops** | Create commit or stash; rollback via `git reset` / `git checkout` |
| **MCP tools** | Adapter-created checkpoints of affected resources; rollback replays inverse operations where possible |
| **Agent Skills** | Composite — each sub-tool-call within the skill's execution is individually checkpointed |
| **Custom (containerized)** | Filesystem snapshot or container image layer; rollback restores snapshot |

Checkpointing is easier when tool scope is constrained (e.g., "only files within a sandbox worktree + git"). The capability metadata's `checkpoint_scope` field communicates what granularity of rollback is supported.

When `require_checkpoints` is enabled on a plan, the plan may **only** use tools that have `checkpointable: true`. If disabled, the plan may use more generic/unsafe tools with fewer restrictions (useful for low-stakes tasks).

### Validation

#### What a Validation Is

A **Validation** is a specialized subtype of Tool designed to verify that work performed during plan execution meets specified quality, correctness, or compliance criteria. A Validation observes the current state of resources, evaluates a condition, and returns a structured pass/fail result. It never modifies resources — it only reads and reports.

Because Validation extends Tool via standard class inheritance, it is not a separate concept bolted onto the system — it *is* a tool, with additional constraints and metadata. This means validation benefits from the entire tool infrastructure: source types, resource bindings, lifecycle hooks, input/output schemas, registry management, skill composition, and actor graph integration. No parallel system is required.

#### Relationship to Tool

A Validation inherits **all** base Tool properties:

| Inherited from Tool | Additional in Validation |
|---------------------|--------------------------|
| `name` (namespaced) | `mode` (`required` or `informational`) |
| `description` | Structured return format enforcement |
| `source` (custom, mcp, agent_skill, builtin, wrapped) | Read-only enforcement (`writes: false`, `checkpointable: false`) |
| `input_schema` (JSON Schema) | Attachment scoping (resource-centric, with optional project/plan scope) |
| `output_schema` (JSON Schema) | Attachment ULID (system-assigned per attachment) |
| `capability` metadata | `wraps` (optional reference to an existing Tool) |
| `resource_slots` (resource bindings) | `transform` (Python function to convert wrapped Tool output to validation format) |
| `lifecycle` hooks (discover/activate/execute/deactivate) | |
| `code` (inline implementation) | |
| `mcp_server` / `mcp_tool_name` (MCP source) | |
| `timeout` | |
| `idempotent` | |

**Shared namespace**: Validations and plain Tools share the same naming namespace in the Tool Registry. A name like `local/run-tests` can refer to either a Tool or a Validation — but never both simultaneously. Attempting to register a Validation with a name already taken by a plain Tool (or vice versa) results in a conflict error. This shared namespace enables unified management: `agents tool list` shows both types, `agents tool show` works for both, and `agents tool remove` removes either type.

**Superset/subset semantics**: Because Validation extends Tool, a Validation can be used anywhere a Tool is expected — it can appear in a skill's tool list, serve as a tool node in an actor graph, or be invoked directly by an LLM agent. However, a plain Tool **cannot** be used where a Validation is specifically required. For example, `agents validation attach` rejects a name that resolves to a plain Tool rather than a Validation. This distinction is enforced by the `type` discriminator stored in the Tool Registry: each entry is tagged as either `tool` or `validation`.

#### Read-Only Enforcement

Validations are **always read-only**. This is a hard constraint, not a convention:

- `writes` is always `false`. A Validation must never modify, create, or delete resources. It reads the current state and reports findings.
- `checkpointable` is always `false`. Since a Validation produces no state changes, there is nothing to checkpoint or roll back.
- `read_only` is always `true` (implicit). This is the inverse of `writes` and is always set for validations.

This constraint is enforced at multiple levels:

1. **Registration time**: The `agents validation add` command does not accept `--writes`/`--no-writes` or `--checkpointable`/`--no-checkpointable` flags. Any `writes` or `checkpointable` values in the validation YAML configuration file are silently overridden to `false`.
2. **Runtime enforcement**: The execution runtime treats validation invocations as read-only operations. Resource bindings for validations are resolved with `access: read_only` semantics — the validation receives a read-only view of the resource, not a writable handle. If a validation's implementation attempts to write (e.g., a custom Python validation calling a write API), the sandbox enforces the read-only constraint and the invocation fails.
3. **Sandbox interaction**: When a validation executes within a plan's sandbox, it reads the sandbox state (e.g., the modified files in a git worktree) but cannot modify it. This allows validations to verify the work-in-progress without risk of corrupting it.

The read-only guarantee has an important architectural consequence: validations are **always safe to run**. They cannot cause side effects, corrupt state, or require rollback. This enables aggressive parallelization, speculative validation (running validations before all work is complete to provide early feedback), and retry without concern for accumulated state changes.

#### Validation Mode

Each Validation has a `mode` that determines how the system responds to failure:

**Required** (`mode: required`):
- The validation **must** pass for execution to proceed to the Apply phase.
- When a required validation fails, the execution actor attempts to fix the underlying issue (e.g., fix failing tests, correct lint errors) within the bounds of the current strategy, then re-runs the validation.
- This fix-then-revalidate loop continues up to the configured retry limit.
- If self-fix is exhausted, the actor may request a strategy revision (re-running the Strategize phase for the affected subtree) or escalate to the user, depending on the automation profile.
- Required validations act as hard gates — they define "definition of done" for a plan.

**Informational** (`mode: informational`):
- The validation's result is **recorded** but does not block execution.
- When an informational validation fails, the result (including `message` and `data`) is included in the plan's validation summary for human review, but the plan continues normally.
- Informational validations are useful for advisory checks: bundle size reports, code complexity metrics, deprecation warnings, performance benchmarks, or any check where failure is noteworthy but not blocking.
- The distinction between required and informational allows teams to introduce new validations gradually — start as informational to measure impact, then promote to required once the codebase is clean.

The mode is set at registration time (in the validation YAML or via `--required`/`--informational` on `agents validation add`) and applies globally to that validation. The mode cannot be overridden per-attachment — if different scopes need different enforcement levels for the same check, register separate validations with different names and modes.

#### Structured Return Format

Every Validation must return a JSON object conforming to this structure:

```json
{
  "passed": true,
  "message": "All 247 tests passed, 94% coverage",
  "data": {
    "tests_run": 247,
    "tests_passed": 247,
    "tests_failed": 0,
    "coverage_percent": 94.2,
    "coverage_threshold": 80,
    "duration_seconds": 12.4
  }
}
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `passed` | boolean | **Yes** | Whether the validation passed (`true`) or failed (`false`). This is the only field that drives system behavior (gating for required, recording for informational). |
| `message` | string | No | Human-readable summary of the result. Displayed in CLI output, plan summaries, and used by the execution actor to understand failures. Should be concise but actionable (e.g., "3 lint errors in src/api/handler.py" rather than just "failed"). |
| `data` | object | No | Arbitrary structured data in any format the validation chooses. This is the validation's primary output channel for rich, machine-readable results. Examples: test coverage reports, lint error lists with file/line/column, security vulnerability details, performance measurement data. The `data` field has no required schema — each validation defines its own structure. |

**Return format enforcement**: If a validation returns output that is not valid JSON, or valid JSON that lacks the `passed` boolean field, the system treats the invocation as an error (distinct from a validation failure). The validation result is recorded as `"passed": false` with a system-generated `message` indicating the malformed return, and the original output is preserved in `data.raw_output` for debugging.

The structured return format serves multiple consumers:
- **The execution actor** reads `message` and `data` to understand failures and attempt fixes. A well-structured `data` field (e.g., with file paths and line numbers) enables more targeted fix attempts.
- **The plan summary** records all validation results for human review and auditing.
- **Downstream automation** (CI scripts, dashboards) can parse `data` programmatically via `agents --format json plan show`.

#### Attachment Scoping

Validations are not globally active — they must be explicitly **attached** to one or more scopes to take effect. This attachment model provides fine-grained control over which validations run for which work.

##### Attachment Model

A validation is always attached to a resource. The optional `--project` or `--plan` flag controls the scope under which the validation is active for that resource:

1. **Direct attachment** (`agents validation attach <RESOURCE> <VALIDATION> [args...]`)

   The validation is always active when that resource is accessed by any plan, regardless of which project or plan is involved. This scope is for invariants that must hold for a resource in all contexts — e.g., a lint check that must pass for a repository no matter what project is using it.

   Use cases:
   - Repository-wide lint/format checks
   - Schema validation on database resources
   - Security scanning on any codebase resource
   - License compliance checks

2. **Project-scoped attachment** (`agents validation attach --project <PROJECT> <RESOURCE> <VALIDATION> [args...]`)

   The validation is active only for that resource when it is being interacted with through the specified project. Different projects using the same resource can have different validation requirements. This is the most common attachment scope.

   Use cases:
   - Unit test suites specific to a project
   - Type checking for a TypeScript project (not relevant for a Python project using the same repo)
   - API compatibility checks for a microservice project
   - Bundle size checks for a frontend project

3. **Plan-scoped attachment** (`agents validation attach --plan <PLAN_ID> <RESOURCE> <VALIDATION> [args...]`)

   The validation is active only for that resource when it is being interacted with through the specified plan. This is the most targeted scope, useful for one-off or experimental validations.

   Use cases:
   - Temporary extra checks during a risky migration
   - One-time regression validation for a specific bug fix
   - Experimental validations being tested before promoting to project scope
   - User-added ad hoc checks during an interactive session

Since validations accept arguments, the same validation can be attached to the same resource multiple times with different arguments. For example, `local/run-tests` might be attached to `local/api-repo` through project `local/api-service` with `--coverage-threshold 90` and also through project `local/staging` with `--coverage-threshold 70`.

##### Attachment Resolution

When a plan executes, the system collects all applicable validations for each resource the plan accesses. The resolution algorithm:

1. **Collect direct validations**: For every resource the plan accesses, collect all validations directly attached to that resource (no scope flag).
2. **Collect project-scoped validations**: For every resource the plan accesses, collect all validations attached to that resource with a `--project` scope matching the plan's target project.
3. **Collect plan-scoped validations**: For every resource the plan accesses, collect all validations attached to that resource with a `--plan` scope matching the plan itself.
4. **Union**: Take the union of all collected validations per resource. If the same validation name appears from multiple scopes for the same resource (e.g., attached both directly and through a project), each attachment is treated as a distinct invocation — they may have different arguments and thus produce different results. When the same validation name appears from multiple scopes with identical arguments, the most specific scope wins (plan > project > direct) and the validation runs once.
5. **Child plan inheritance**: Child plans (spawned via `subplan_spawn` or `subplan_parallel_spawn`) inherit their parent plan's project-scoped and plan-scoped resource/validation associations by default. Direct validations are collected independently based on which resources the child plan accesses (which may differ from the parent).

##### Attachment Identity

Each attachment is identified by a system-assigned **ULID**. This ULID is:
- Returned by `agents validation attach` when the attachment is created.
- Displayed by `agents tool show <VALIDATION>` in the "Attached To" section and by `agents project show` in the validations list.
- Required by `agents validation detach <ATTACHMENT_ID>` to remove a specific attachment.

The ULID is necessary because the same validation can be attached to the same resource multiple times — directly, through different projects, through different plans, and even to the same resource and scope with different arguments. The ULID uniquely identifies which specific attachment to remove.

##### Attachment Arguments

When attaching a validation, optional arguments can be provided after the validation name:

```
agents validation attach --project local/api-service local/api-repo local/run-tests --coverage-threshold 90
agents validation attach --project local/staging-api local/api-repo local/run-tests --coverage-threshold 70
```

These arguments are stored with the attachment and passed to the validation tool's `input_schema` at execution time. This enables a single validation definition to be reused across scopes with different thresholds or configurations. If no arguments are provided, the validation uses its `input_schema` defaults.

#### Validation Lifecycle in Plan Execution

Validation participates in the plan lifecycle at well-defined points:

##### During Strategize

Validations are **not executed** during Strategize. However, the strategy actor is aware of which validations are attached (via the attachment resolution described above) and factors them into the strategy:
- The strategy may allocate time/tokens for validation fix-up loops.
- The strategy may note that certain validations are informational and thus non-blocking.
- The decision tree may include `validation_checkpoint` decisions that mark points where validation should be run.

##### During Execute

Validation is the **final step** of the Execute phase. The execution actor's workflow proceeds as follows:

1. **Perform work**: The actor executes the strategy — writing code, modifying resources, running tools — all within the sandbox.
2. **Collect applicable validations**: The system resolves all validations from the resource-direct, project, and plan scopes (as described in Attachment Resolution above).
3. **Execute validations**: Each applicable validation is invoked as a standard tool call. The validation reads the sandbox state and returns its structured result. Validations may be run in parallel since they are read-only and cannot interfere with each other.
4. **Process results**:
   - **All required validations pass**: Execution is complete. The plan transitions to the review/Apply phase.
   - **Any required validation fails**: The execution actor enters the fix-then-revalidate loop (see Validation Failure Handling below).
   - **Informational validations fail**: Results are recorded in the plan's validation summary. No fix attempts are made.

##### Validation is Not Run During Apply

Validation runs during Execute, **not** during Apply. By the time a plan reaches Apply, all required validations have already passed. Apply commits the sandbox changes to the real resources. If the user wants post-apply verification (e.g., integration tests against the real system), that should be implemented as a separate plan or an external CI pipeline — not as a validation attachment.

The rationale: Apply is a controlled commit step. Introducing validation during Apply would create a situation where committed changes might need to be rolled back, defeating the purpose of the sandbox model. The Execute phase is where all verification occurs, and Apply is the point of no return.

#### Validation Failure Handling

Because validations are tools, their execution follows the standard tool invocation flow. Each validation returns a structured JSON result with `{ "passed": true/false, "message": "...", "data": {...} }`. The execution actor interprets these results based on the validation's `mode`.

##### Required Validation Failure

When a **required** validation returns `"passed": false` during Execute:

1. **Diagnosis**: The execution actor examines the validation's `message` and `data` fields to understand the nature of the failure. A well-structured `data` field (e.g., with specific file paths, line numbers, error messages) enables more targeted fix attempts.

2. **Self-fix attempt**: The execution actor attempts to fix the issue within the bounds of the current strategy. For example:
   - A failing test: the actor reads the test output, identifies the broken assertion, and fixes the code.
   - A lint error: the actor reads the lint report and corrects the formatting or style violation.
   - A type error: the actor reads the type checker output and fixes the type mismatch.

3. **Re-validation**: After each fix attempt, the actor re-invokes the failing validation. If it passes, the loop ends. If it still fails, the actor examines the new `message` and `data` for the updated failure state.

4. **Retry limit**: The fix-then-revalidate loop runs up to the configured retry limit (default: 3 attempts, configurable per plan or in the automation profile). After the limit is reached, self-fix stops.

5. **Strategy revision**: If the actor determines that the failure cannot be resolved within the current strategy's constraints (e.g., the strategy says "modify only `handler.py`" but the test failure requires changes to `model.py`), it may request a **strategy revision**. This triggers a re-run of the Strategize phase for the affected subtree of the decision tree. Whether this happens automatically or requires user approval depends on the automation profile's `auto_strategy_revision` flag.

6. **Escalation**: If strategy revision also fails, or if the automation profile requires human approval for strategy changes, the plan pauses and requests user guidance via `agents plan prompt`:

   <div class="highlight"><pre><code>
   agents plan prompt &lt;plan_id&gt; <span style="color: #66cc66;">&quot;Try using mock objects for the database tests&quot;</span>
   </code></pre></div>

7. **Terminal failure**: If the user does not intervene (or explicitly cancels), the plan fails with `state: failed`. The sandbox is preserved for inspection.

The flow can be summarized as:

```
validate → fail → fix → re-validate → fail → fix → re-validate → ... → retry limit
  → request strategy revision → re-strategize → re-execute → validate
  → still failing → escalate to user → user provides guidance → resume
  → still failing → plan fails
```

##### Informational Validation Failure

When an **informational** validation returns `"passed": false`:

1. The result (including `message` and `data`) is recorded in the plan's `validation_summary`.
2. Execution continues normally — no fix attempts, no blocking, no escalation.
3. The informational failure is visible in `agents plan show`, plan summaries, and any rendering format.
4. Informational failures may trigger notifications (if configured) but never block plan progression.

##### Validation Error vs. Validation Failure

An important distinction:

- **Validation failure** (`passed: false`): The validation ran successfully and determined the condition was not met. This is normal and handled by the mode-specific logic above.
- **Validation error**: The validation itself failed to execute — a runtime exception, timeout, malformed return, or infrastructure failure. Validation errors are treated as required validation failures regardless of the validation's mode, because a validation that cannot run provides no assurance.

When a validation error occurs:
- The result is recorded with `passed: false`, a system-generated `message` describing the error, and the raw error details in `data`.
- If the validation is required, the fix-then-revalidate loop attempts to resolve the error (e.g., by fixing a broken test configuration).
- If the validation is informational, the error is still recorded but does not block.
- Repeated validation errors (e.g., the validation tool itself is misconfigured) are surfaced prominently in the plan summary.

#### Validation in Actor Graphs

Because Validations are Tools, they can appear as **tool nodes** in actor graphs. This enables explicit, deterministic validation steps within workflows:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Actor graph with explicit validation nodes</span>
<span style="color: cyan; font-weight: 600;">graph</span>:
  <span style="color: cyan; font-weight: 600;">nodes</span>:
    - <span style="color: cyan; font-weight: 600;">name</span>: implement
      <span style="color: cyan; font-weight: 600;">type</span>: agent
      <span style="color: cyan; font-weight: 600;">actor</span>: local/code-writer
    - <span style="color: cyan; font-weight: 600;">name</span>: run_tests
      <span style="color: cyan; font-weight: 600;">type</span>: tool
      <span style="color: cyan; font-weight: 600;">tool</span>: local/run-tests       <span style="opacity: 0.7;"># This is a Validation (subtype of Tool)</span>
    - <span style="color: cyan; font-weight: 600;">name</span>: lint_check
      <span style="color: cyan; font-weight: 600;">type</span>: tool
      <span style="color: cyan; font-weight: 600;">tool</span>: local/lint-check      <span style="opacity: 0.7;"># Also a Validation</span>
    - <span style="color: cyan; font-weight: 600;">name</span>: fix_issues
      <span style="color: cyan; font-weight: 600;">type</span>: agent
      <span style="color: cyan; font-weight: 600;">actor</span>: local/code-fixer
  <span style="color: cyan; font-weight: 600;">edges</span>:
    - [implement, run_tests]
    - [implement, lint_check]
    - <span style="color: cyan; font-weight: 600;">condition</span>: <span style="color: #66cc66;">&quot;not run_tests.passed or not lint_check.passed&quot;</span>
      <span style="color: cyan; font-weight: 600;">from</span>: [run_tests, lint_check]
      <span style="color: cyan; font-weight: 600;">to</span>: fix_issues
    - [fix_issues, run_tests]    <span style="opacity: 0.7;"># Retry loop</span>
    - [fix_issues, lint_check]
</code></pre></div>

When a Validation appears as a tool node, its return value is available to downstream nodes via the standard graph data flow. The `passed`, `message`, and `data` fields can be used in edge conditions, passed as input to subsequent nodes, or logged for the plan summary.

This graph-based approach complements the attachment model: attached validations run automatically at the end of Execute (the system handles collection and invocation), while graph-embedded validations run at explicitly defined points in the workflow (the actor author controls placement). Both approaches can coexist — a plan may have attached validations that run at the end plus graph-embedded validations that run at intermediate checkpoints.

#### Validation and Skills

Validations can be **included in skills** just like any other tool. Since a Validation is a Tool, a skill YAML can reference it by name:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Skill: local/python-quality</span>
<span style="color: cyan; font-weight: 600;">skill</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/python-quality
  <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Python code quality tools and validations&quot;</span>
  <span style="color: cyan; font-weight: 600;">tools</span>:
    - local/run-tests         <span style="opacity: 0.7;"># Validation (required)</span>
    - local/lint-check        <span style="opacity: 0.7;"># Validation (required)</span>
    - local/type-check        <span style="opacity: 0.7;"># Validation (required)</span>
    - local/format-code       <span style="opacity: 0.7;"># Plain Tool (writes)</span>
    - local/run-benchmarks    <span style="opacity: 0.7;"># Validation (informational)</span>
</code></pre></div>

When an actor references this skill, the Validations are available as tools that the LLM agent can call. This is distinct from validation attachment — being included in a skill makes the validation *callable* by the actor's LLM, but does not make it a *required gate*. Attachment determines gating; skill inclusion determines availability.

A common pattern: a team's skill includes their validations for on-demand use by the LLM (the actor can run tests proactively during development), while the same validations are also attached to the project (ensuring they run as a mandatory gate at the end of Execute even if the LLM forgot to run them).

#### Tool Wrapping

A Validation can **wrap an existing Tool**, reusing its implementation without duplicating code. This is the recommended approach when a plain Tool already performs the work a Validation needs (e.g., running tests, generating a report, scanning for vulnerabilities) and the Validation only needs to interpret the Tool's output as pass/fail.

##### The Problem

Consider a team that already has a registered Tool called `local/run-tests` — it runs the test suite and returns a structured report (test counts, coverage data, output logs). Now they want a Validation that gates execution on all tests passing. Without wrapping, they would need to duplicate the entire test-running implementation inside a new Validation YAML, differing only in the final pass/fail interpretation. This duplication creates maintenance burden: if the test runner configuration changes, both the Tool and the Validation must be updated.

##### The Solution: `wraps` + `transform`

A Validation YAML can declare a `wraps` field that references an existing registered Tool by name. At execution time, the system invokes the wrapped Tool, captures its output, and passes that output through a `transform` function that produces the Validation's structured return format (`{ "passed", "message", "data" }`).

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># validations/tests-pass.yaml</span>
<span style="opacity: 0.7;"># Wraps the existing local/run-tests tool — no test logic duplicated</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/tests-pass</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Validate that all unit tests pass (wraps local/run-tests)&quot;</span>

<span style="color: cyan; font-weight: 600;">wraps</span>: local/run-tests

<span style="color: cyan; font-weight: 600;">transform</span>: |
  def transform(tool_output):
      passed = tool_output.get(&quot;returncode&quot;) == 0
      return {
          &quot;passed&quot;: passed,
          &quot;message&quot;: &quot;All tests passed&quot; if passed else f&quot;Tests failed (exit {tool_output.get('returncode')})&quot;,
          &quot;data&quot;: tool_output
      }

<span style="color: cyan; font-weight: 600;">validation</span>:
  <span style="color: cyan; font-weight: 600;">mode</span>: required

<span style="color: cyan; font-weight: 600;">timeout</span>: <span style="color: yellow;">600</span>
</code></pre></div>

When `local/tests-pass` is invoked (either by attachment or direct call):
1. The system resolves `wraps: local/run-tests` to the registered Tool.
2. The Validation's input arguments are mapped to the wrapped Tool's input arguments using the `argument_mapping` (see below). If no `argument_mapping` is defined, the Validation's input arguments are passed through to the wrapped Tool as-is.
3. The wrapped Tool is invoked with the mapped arguments.
4. The wrapped Tool's output is captured (whatever it returns — JSON, text, etc.).
5. The `transform` function is called with the captured output.
6. The `transform` function returns the Validation's structured result (`{ "passed", "message", "data" }`).

This is opaque to the consumer — the caller sees only a standard Validation with its structured return format. The wrapping is an implementation detail.

##### What Gets Inherited

When a Validation uses `wraps`, the following properties are **inherited from the wrapped Tool** unless explicitly overridden in the Validation YAML:

| Property | Inherited? | Override behavior |
|----------|-----------|-------------------|
| `input_schema` | Yes | If the Validation YAML defines `input_schema`, it replaces the wrapped Tool's schema entirely. If omitted, the Validation accepts the same inputs as the wrapped Tool. When a custom `input_schema` is defined, an `argument_mapping` should also be provided to map the Validation's inputs to the wrapped Tool's expected inputs. |
| `argument_mapping` | No | Not inherited. When present, maps the Validation's input arguments to the wrapped Tool's input arguments. When absent, input arguments are passed through unchanged. See the Argument Mapping section. |
| `resource_slots` | Yes | If the Validation YAML defines `resource_slots`, they replace the wrapped Tool's slots. If omitted, the Validation inherits the same resource bindings. |
| `timeout` | Yes | If the Validation YAML specifies `timeout`, it overrides. If omitted, the wrapped Tool's timeout is used. |
| `description` | No | The Validation must provide its own description (it serves a different purpose than the wrapped Tool). |
| `source` | No | Ignored — the source is implicitly `wrapped`. The Validation does not declare `source` or `code`. |
| `capability` | No | Overridden — `writes` and `checkpointable` are forced to `false` regardless of the wrapped Tool's values. |

##### The `transform` Function

The `transform` field contains a Python function that converts the wrapped Tool's output to the Validation's return format. The function signature is:

```python
def transform(tool_output) -> dict:
    """
    Args:
        tool_output: The wrapped Tool's return value. The type depends on the
                     Tool's implementation — typically a dict (for JSON-returning
                     tools) but may be a string or other type.
    Returns:
        A dict with at minimum {"passed": bool}. May also include
        "message" (str) and "data" (any).
    """
```

The `transform` function runs in a sandboxed Python environment with no write access to the filesystem or network. It is a pure data transformation — it receives the Tool's output and produces the Validation's result. If the `transform` function raises an exception, the Validation is treated as an error (see Validation Error vs. Validation Failure).

If `transform` is omitted, the system applies a **default transform** that expects the wrapped Tool's output to already contain a `passed` field:
- If the output is a dict with a `passed` boolean, it is used as-is (pass-through).
- If the output is a dict without `passed`, the validation errors with a message indicating the wrapped tool's output is not in validation format and a `transform` function is required.
- If the output is not a dict, the validation errors similarly.

##### Argument Mapping (`argument_mapping`)

When a Validation wraps a Tool, the Validation may accept different input arguments than the wrapped Tool. The `argument_mapping` field specifies how the Validation's input arguments map to the wrapped Tool's expected input arguments. This is necessary when:

- The Validation's `input_schema` defines different field names than the wrapped Tool's `input_schema`.
- The Validation accepts a subset of the wrapped Tool's arguments and wants to provide fixed values for the rest.
- The Validation renames arguments for clarity in the validation context.

The `argument_mapping` is a dictionary where keys are the wrapped Tool's input parameter names and values are either:
- A string referencing a Validation input parameter name (forwarded as-is).
- A fixed literal value (string, number, boolean) that is always passed to the wrapped Tool regardless of the Validation's inputs.

```yaml
# Example: Validation wraps local/run-tests but renames arguments
name: local/tests-pass
wraps: local/run-tests

argument_mapping:
  test_directory: source_dir        # Forward Validation's "source_dir" → Tool's "test_directory"
  coverage_enabled: true            # Always pass true for coverage_enabled
  verbose: false                    # Always pass false for verbose

transform: |
  def transform(tool_output):
      return {"passed": tool_output.get("returncode") == 0, "message": "Tests completed"}

validation:
  mode: required
```

When `argument_mapping` is **omitted**, the Validation's input arguments are passed through to the wrapped Tool unchanged. This is the common case when the Validation inherits the wrapped Tool's `input_schema` without modification (i.e., the Validation YAML does not define its own `input_schema`).

When `argument_mapping` is **present**, only the mapped arguments are forwarded to the wrapped Tool. Any Validation input arguments not referenced in the mapping are not passed to the wrapped Tool. Any wrapped Tool arguments not listed as keys in the mapping receive no value (and must either be optional in the Tool's schema or have defaults).

##### Read-Only Semantics for Wrapped Tools

Validations are always read-only, but the wrapped Tool may not be. The wrapping enforces read-only semantics:

- The wrapped Tool is invoked within the Validation's read-only execution context. Resource bindings are resolved with `access: read_only` regardless of what the wrapped Tool's `resource_slots` specify.
- If the wrapped Tool's implementation attempts to write (e.g., mutate files, insert database rows), the sandbox enforces the read-only constraint and the invocation fails as a validation error.
- At registration time, if the wrapped Tool has `writes: true`, the system emits a **warning** (not an error) advising the user that the wrapped Tool is marked as writing and may fail at runtime under read-only enforcement. This allows wrapping tools that are conservatively marked `writes: true` but whose actual behavior for the given inputs is read-only.

This design means wrapping is always safe from the Validation perspective — the worst case is a runtime error, never an unintended write.

##### Multiple Validations Wrapping the Same Tool

The same Tool can be wrapped by multiple Validations with different `transform` functions and different modes. This is a common pattern:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># The base tool runs tests and produces a comprehensive report</span>
<span style="opacity: 0.7;"># Tool: local/run-tests (already registered)</span>

<span style="opacity: 0.7;"># Validation 1: All tests must pass (required)</span>
<span style="opacity: 0.7;"># validations/tests-pass.yaml</span>
<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/tests-pass</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;All unit tests must pass&quot;</span>
<span style="color: cyan; font-weight: 600;">wraps</span>: local/run-tests
<span style="color: cyan; font-weight: 600;">transform</span>: |
  def transform(tool_output):
      return {
          &quot;passed&quot;: tool_output.get(&quot;returncode&quot;) == 0,
          &quot;message&quot;: f&quot;{tool_output.get('tests_passed', 0)}/{tool_output.get('tests_run', 0)} tests passed&quot;,
          &quot;data&quot;: tool_output
      }
<span style="color: cyan; font-weight: 600;">validation</span>:
  <span style="color: cyan; font-weight: 600;">mode</span>: required
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Validation 2: Coverage must exceed threshold (informational for now)</span>
<span style="opacity: 0.7;"># validations/coverage-check.yaml</span>
<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/coverage-check</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Coverage must exceed threshold (advisory)&quot;</span>
<span style="color: cyan; font-weight: 600;">wraps</span>: local/run-tests
<span style="color: cyan; font-weight: 600;">transform</span>: |
  def transform(tool_output):
      coverage = tool_output.get(&quot;coverage_percent&quot;, 0)
      threshold = 80
      return {
          &quot;passed&quot;: coverage >= threshold,
          &quot;message&quot;: f&quot;Coverage: {coverage}% (threshold: {threshold}%)&quot;,
          &quot;data&quot;: {&quot;coverage_percent&quot;: coverage, &quot;threshold&quot;: threshold}
      }
<span style="color: cyan; font-weight: 600;">validation</span>:
  <span style="color: cyan; font-weight: 600;">mode</span>: informational
</code></pre></div>

Both validations wrap the same `local/run-tests` tool but extract different signals. When both are attached to the same project, each Validation independently invokes the wrapped Tool and applies its own `transform` function. A future optimization may deduplicate these invocations when the forwarded arguments are identical (see Validation Ordering and Parallelism).

##### When to Wrap vs. When to Write From Scratch

| Scenario | Approach |
|----------|----------|
| An existing Tool already does the work; you just need pass/fail | **Wrap it** — use `wraps` + `transform` |
| Multiple Validations need different interpretations of the same Tool's output | **Wrap it** multiple times with different transforms |
| The validation logic is simple and self-contained (e.g., run a shell command, check exit code) | **Write from scratch** — use `source: custom` with inline `code` |
| The validation needs logic that the existing Tool doesn't provide (different inputs, different execution) | **Write from scratch** — the Tool's implementation isn't relevant |
| The existing Tool has side effects that are incompatible with read-only enforcement | **Write from scratch** — wrapping would fail at runtime |

#### Validation Data Model

The validation-related fields stored in the plan data model:

| Field | Location | Description |
|-------|----------|-------------|
| `validation_summary` | `plan.execution` | Array of validation results collected during Execute. Each entry includes the validation name, mode, `passed`, `message`, `data`, execution duration, and attempt number. |
| `final_validation_results` | `plan.apply` | Snapshot of the final validation state at the time execution completed (all required validations passing). Identical to the last state of `validation_summary` but stored separately for quick reference. |
| `validation_attempts` | `plan.execution` | Total number of validation invocations across all fix-then-revalidate loops. Useful for understanding how much effort was spent on validation remediation. |
| `validation_fix_history` | `plan.execution` | Per-validation log of fix attempts. Each entry records: the validation that failed, the fix the actor applied, and whether the subsequent re-validation passed. Enables auditing of the fix-then-revalidate process. |

A validation result entry in `validation_summary`:

```json
{
  "validation": "local/run-tests",
  "mode": "required",
  "passed": true,
  "message": "All 247 tests passed, 94% coverage",
  "data": {
    "tests_run": 247,
    "tests_passed": 247,
    "coverage_percent": 94.2
  },
  "duration_ms": 12400,
  "attempt": 2,
  "attachment_id": "01HXM5A1B2C3D4E5F6G7H8J9K0",
  "attachment_resource": "local/api-repo",
  "attachment_scope": "project",
  "attachment_scope_target": "local/api-service"
}
```

#### Validation Ordering and Parallelism

Since validations are read-only, they are inherently safe to run in parallel. The execution runtime may parallelize validation invocations subject to:

- **Resource constraints**: Validations that require significant compute (e.g., full test suites) may be serialized to avoid resource exhaustion.
- **Timeout budgets**: Each validation has its own `timeout` (from the tool configuration). The total validation phase has an implicit budget derived from the sum of individual timeouts, but the runtime may use parallelism to finish faster.
- **Dependency hints**: A future extension may allow declaring ordering dependencies between validations (e.g., "run lint before tests" to fail fast on formatting issues). Currently, all validations run independently.

**Wrapped Tool deduplication (deferred)**: When multiple Validations wrap the same Tool (via `wraps`), a future optimization could invoke the wrapped Tool once and fan out its output to each Validation's `transform` function. However, deduplication is only valid when multiple Validations wrap the same Tool **and** receive the exact same forwarded arguments (after `argument_mapping` resolution) **and** are evaluated in the same calling chain. This complexity — particularly around argument equivalence and cache invalidation during fix-then-revalidate loops — means deduplication is **deferred for future design**. The current implementation invokes the wrapped Tool separately for each Validation that wraps it.

The recommended execution strategy is:
1. Run all validations in parallel (each Validation independently invokes its wrapped Tool if applicable).
2. Collect results.
3. If any required validation fails, fix and re-run only the failing validations (not all of them).
4. Repeat until all pass or retry limit is reached.

#### Registering and Managing Validations

Validations are **registered** via `agents validation add` and **attached** via `agents validation attach`. These are the only validation-specific CLI commands. All other management operations use the standard `agents tool` commands:

| Operation | Command | Notes |
|-----------|---------|-------|
| **Register** | `agents validation add --config <FILE>` | Validation-specific. Config file defines all properties including mode (`required`/`informational`). |
| **Update** | `agents validation add --config <FILE> --update` | Uses the `--update` flag to overwrite existing registration. |
| **Attach** | `agents validation attach [--project\|--plan] <RESOURCE> <VALIDATION> [args...]` | Returns an attachment ULID. Resource is always required; project/plan scope is optional. |
| **Detach** | `agents validation detach [--yes] <ATTACHMENT_ID>` | Uses the attachment ULID, not the validation name. |
| **List** | `agents tool list --type validation` | Shared with tools. Use `--type validation` to filter. |
| **Show** | `agents tool show <NAME>` | Shows validation-specific fields when the entry is a Validation. |
| **Remove** | `agents tool remove <NAME>` | Shared with tools. Automatically detaches from all scopes. |

See the **agents validation** and **agents tool** CLI Reference sections for full command details and examples.

#### Typical Validation Workflow

A typical workflow for setting up validations on a project:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># 1. Define validation YAML files</span>
<span style="opacity: 0.7;"># (see Configuration > Validation Configuration Files for schema and examples)</span>

<span style="opacity: 0.7;"># 2. Register validations</span>
agents validation add <span style="color: cyan;">--config</span> ./validations/run-tests.yaml
agents validation add <span style="color: cyan;">--config</span> ./validations/lint-check.yaml
agents validation add <span style="color: cyan;">--config</span> ./validations/type-check.yaml
agents validation add <span style="color: cyan;">--config</span> ./validations/check-bundle-size.yaml

<span style="opacity: 0.7;"># 3. Attach to resource through a project (active only when this resource is accessed through this project)</span>
agents validation attach <span style="color: cyan;">--project</span> local/api-service local/api-repo local/run-tests
agents validation attach <span style="color: cyan;">--project</span> local/api-service local/api-repo local/type-check
agents validation attach <span style="color: cyan;">--project</span> local/api-service local/api-repo local/check-bundle-size

<span style="opacity: 0.7;"># 4. Attach directly to a resource (always active for any plan accessing this resource)</span>
agents validation attach local/api-repo local/lint-check

<span style="opacity: 0.7;"># 5. Verify setup</span>
agents tool list <span style="color: cyan;">--type</span> validation <span style="color: cyan;">--namespace</span> local
agents tool show local/run-tests

<span style="opacity: 0.7;"># 6. Run a plan — validations execute automatically at end of Execute phase</span>
agents plan create <span style="color: cyan;">--project</span> local/api-service <span style="color: cyan;">--action</span> local/implement-feature <span style="color: #66cc66;">&quot;Add user authentication&quot;</span>
</code></pre></div>

#### Design Rationale

**Why Validation extends Tool rather than being a separate concept**:
- Reuses the entire tool infrastructure (registry, bindings, lifecycle, sources, schemas) without duplication.
- Validations can be composed into skills, used in actor graphs, and invoked by LLM agents — all for free.
- A single namespace and registry avoids the complexity of managing two parallel systems.
- Tool-aware features (resource bindings, MCP integration, Agent Skills) apply to validations automatically.

**Why read-only is enforced rather than advisory**:
- Validations that modify state defeat the purpose of the sandbox model.
- Read-only guarantees enable safe parallelization and retry without side effects.
- It makes validations categorically safe — no risk analysis needed for running a validation.

**Why attachments use ULIDs rather than name+scope pairs**:
- A validation may be attached to the same scope multiple times with different arguments.
- ULIDs provide an unambiguous handle for removal without complex composite keys.
- Consistent with the ULID-based identity model used for plans, resources, and decisions.

**Why validation runs during Execute, not Apply**:
- Apply is a controlled commit step. Validation failures during Apply would require rolling back committed changes.
- The sandbox model ensures all verification occurs before the point of no return.
- Post-apply verification (integration tests, smoke tests) is a separate concern best handled by external CI or follow-up plans.

### Skills

#### What a Skill Is

A **skill** is a namespaced, reusable **collection of tools** that is registered in the system via its own YAML configuration file and managed through `agents skill` CLI commands. Skills are the unit of capability composition in CleverAgents — they define *what an actor can do* by assembling tools into coherent, reusable bundles.

A skill is **not** a single tool. It is a **container** that references one or more tools (by name from the Tool Registry) and/or defines anonymous inline tools, along with metadata describing the collection's purpose, capabilities, and safety characteristics. Tools are independently registered, callable operations (see the **Tools** section above). Skills organize them into reusable groups.

**Key properties of a skill:**

* **Named and namespaced**: Skills follow the same `<namespace>/<name>` naming convention as actors, tools, actions, and plans (e.g., `local/github-ops`, `cleverthis/file-management`, `local/deploy-tools`).
* **Defined in their own YAML files**: Skills are NOT defined inline in actor configurations. They have their own configuration files and are managed as independent, reusable entities.
* **A collection of tools**: Each skill references named tools from the Tool Registry and/or defines anonymous inline tools. Skills can also expose tools from MCP servers, Agent Skills Standard folders, and built-in tool groups.
* **Hierarchically composable**: A skill can include other skills by reference, inheriting all of their tools. This enables layered composition — a "full-stack" skill might include a "file-ops" skill, a "git-ops" skill, and a "github" skill. When including a sub-skill, individual tool metadata can optionally be overridden.
* **Referenced by actors**: Actors reference skills by fully-qualified name. The actor's graph gains access to all tools within the referenced skills.

#### The Skill / Tool Distinction

```kroki-plantuml
@startuml
skinparam packageStyle rectangle
skinparam defaultFontSize 12
skinparam componentFontSize 12

package "Skill: local/devops-toolkit" as Skill {
  package "builtin: file_operations" as FileOps {
    component [read_file()] as T1
    component [write_file()] as T2
    component [edit_file()] as T3
  }

  package "builtin: git_operations" as GitOps {
    component [git_status()] as T4
    component [git_diff()] as T5
  }

  package "mcp: github-server" as GH {
    component [create_issue()] as T6
    component [create_pr()] as T7
    component [list_repos()] as T8
  }

  package "custom" as Custom {
    component [run_migrations()] as T9
  }

  package "Included Skills" as Includes {
    component [local/pdf-processing\n(adds pdf tools)] as I1
    component [local/data-analysis\n(adds analysis tools)] as I2
  }
}
@enduml
```

**Tools** are independently registered, atomic units of execution (see the **Tools** section above for full details). Each tool has:
* A namespaced name, description, and JSON Schema for inputs/outputs
* Its own YAML configuration file, registered via `agents tool add`
* A source type (mcp, agent_skill, builtin, custom)
* Capability metadata (read_only, writes, checkpointable, etc.)
* A lifecycle: `discover()`, `activate()`, `execute(params, ctx)`, `deactivate()`

**Skills** are the organizational units. Each skill has:
* A namespaced name
* A YAML configuration file defining its tool composition
* Zero or more **named tool references** (pointing to independently registered tools in the Tool Registry)
* Zero or more **anonymous inline tools** (one-off tools defined directly in the skill YAML)
* Zero or more included child skills (whose tools are merged in, with optional per-tool metadata overrides)
* Tool sources: MCP servers, Agent Skills folders, built-in tool groups
* Metadata (description, capability summary)

When an actor references a skill, it gains access to the **flattened set of all tools** — named tool references, anonymous tools, tools from MCP/Agent Skills/builtins, and those inherited from included child skills.

#### Skill Configuration (YAML)

Skills are defined in their own YAML configuration files, separate from tool and actor configurations. A skill YAML file declares which registered tools it includes (by name), which other skills it includes, and optionally defines anonymous inline tools:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># File: skills/devops-toolkit.yaml</span>
<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">&quot;3.0&quot;</span>

<span style="color: cyan; font-weight: 600;">skill</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/devops-toolkit
  <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Full-stack development tools for file ops, git, GitHub, and deployment&quot;</span>

<span style="opacity: 0.7;">  # ── Named Tool References ───────────────────────────────</span>
<span style="opacity: 0.7;">  # Reference independently registered tools by name.</span>
<span style="opacity: 0.7;">  # These tools must already be registered via `agents tool add`.</span>
<span style="opacity: 0.7;">  # Optional metadata overrides can be applied per tool.</span>
  <span style="color: cyan; font-weight: 600;">tools</span>:
    - local/run-migrations                  # Simple reference, use as registered
    - <span style="color: cyan;">name</span>: local/deploy-staging            # Reference with metadata override
      <span style="color: cyan; font-weight: 600;">override</span>:
        <span style="color: cyan; font-weight: 600;">capability</span>:
          <span style="color: cyan; font-weight: 600;">human_approval_required</span>: <span style="color: magenta; font-weight: 600;">true</span> <span style="opacity: 0.7;"># Require approval in this skill context</span>

<span style="opacity: 0.7;">  # ── Include other skills ─────────────────────────────────</span>
<span style="opacity: 0.7;">  # All tools from included skills become part of this skill.</span>
<span style="opacity: 0.7;">  # Included skills must already be registered in the system.</span>
<span style="opacity: 0.7;">  # Individual tools from included skills can have metadata overridden.</span>
  <span style="color: cyan; font-weight: 600;">includes</span>:
    - local/file-ops           # built-in file + directory + search tools
    - local/git-ops            # built-in git tools
    - <span style="color: cyan;">name</span>: local/github       # MCP-based GitHub tools, with per-tool overrides
      <span style="color: cyan; font-weight: 600;">tool_overrides</span>:
        - <span style="color: cyan;">tool</span>: local/create-github-issue
          <span style="color: cyan; font-weight: 600;">override</span>:
            <span style="color: cyan; font-weight: 600;">capability</span>:
              <span style="color: cyan; font-weight: 600;">write_scope</span>: [github:issues:org-only]

<span style="opacity: 0.7;">  # ── MCP Server Tools ─────────────────────────────────────</span>
<span style="opacity: 0.7;">  # Connect to MCP servers and expose their tools.</span>
<span style="opacity: 0.7;">  # Tools discovered from MCP servers are auto-registered in the</span>
<span style="opacity: 0.7;">  # Tool Registry if not already present.</span>
  <span style="color: cyan; font-weight: 600;">mcp_servers</span>:
    - <span style="color: cyan;">name</span>: linear
      <span style="color: cyan; font-weight: 600;">command</span>: <span style="color: #66cc66;">&quot;npx @anthropic/mcp-linear&quot;</span>
      <span style="color: cyan; font-weight: 600;">env</span>:
        <span style="color: cyan; font-weight: 600;">LINEAR_API_KEY</span>: <span style="color: #66cc66;">&quot;${LINEAR_API_KEY}&quot;</span>
<span style="opacity: 0.7;">      # Optional: override inferred capability metadata per tool</span>
      <span style="color: cyan; font-weight: 600;">overrides</span>:
        - <span style="color: cyan;">tool</span>: create_issue
          <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">true</span>
          <span style="color: cyan; font-weight: 600;">write_scope</span>: [linear:issues]
        - <span style="color: cyan;">tool</span>: list_issues
          <span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">true</span>

<span style="opacity: 0.7;">  # ── Agent Skills (SKILL.md folders) ──────────────────────</span>
<span style="opacity: 0.7;">  # Each Agent Skill folder is loaded as a composite tool.</span>
<span style="opacity: 0.7;">  # The agent discovers it via metadata, activates it by</span>
<span style="opacity: 0.7;">  # loading SKILL.md instructions, and follows them.</span>
  <span style="color: cyan; font-weight: 600;">agent_skills</span>:
    - <span style="color: cyan;">path</span>: ./skills/code-review-checklist
      <span style="color: cyan; font-weight: 600;">sandbox_policy</span>: <span style="color: magenta; font-weight: 600;">none</span>

<span style="opacity: 0.7;">  # ── Built-in Tool Groups ─────────────────────────────────</span>
<span style="opacity: 0.7;">  # Opt-in to built-in tool groups provided by CleverAgents.</span>
  <span style="color: cyan; font-weight: 600;">builtins</span>:
    - <span style="color: cyan;">group</span>: shell_operations

<span style="opacity: 0.7;">  # ── Anonymous Tools ──────────────────────────────────────</span>
<span style="opacity: 0.7;">  # Inline tool definitions for one-off, skill-specific operations.</span>
<span style="opacity: 0.7;">  # Same format as a named tool YAML body but without a name.</span>
<span style="opacity: 0.7;">  # These are NOT registered in the Tool Registry and are NOT reusable.</span>
  <span style="color: cyan; font-weight: 600;">anonymous_tools</span>:
    - <span style="color: cyan;">description</span>: <span style="color: #66cc66;">&quot;One-off cleanup for legacy migration artifacts&quot;</span>
      <span style="color: cyan; font-weight: 600;">input_schema</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: object
        <span style="color: cyan; font-weight: 600;">properties</span>:
          <span style="color: cyan; font-weight: 600;">directory</span>: { type: string }
      <span style="color: cyan; font-weight: 600;">capability</span>:
        <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">true</span>
        <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">true</span>
        <span style="color: cyan; font-weight: 600;">checkpoint_scope</span>: file
      <span style="color: cyan; font-weight: 600;">code</span>: <span style="color: #66cc66;">|</span>
        import os, glob
        directory = params[&quot;directory&quot;]
        removed = []
        for f in glob.glob(os.path.join(ctx.sandbox.root, directory, &quot;*.legacy&quot;)):
            os.remove(f)
            removed.append(f)
        return {&quot;removed&quot;: removed, &quot;count&quot;: len(removed)}
</code></pre></div>

Here is an example of a simpler skill that wraps only built-in tools, suitable for common reuse:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># File: skills/file-ops.yaml</span>
<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">&quot;3.0&quot;</span>

<span style="color: cyan; font-weight: 600;">skill</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/file-ops
  <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;File and directory operations&quot;</span>

  <span style="color: cyan; font-weight: 600;">builtins</span>:
    - <span style="color: cyan;">group</span>: file_operations      # read, write, edit, delete, move, copy
    - <span style="color: cyan;">group</span>: directory_operations  # create, list, delete dirs
</code></pre></div>

And an example of a skill that is purely MCP-based:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># File: skills/github.yaml</span>
<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">&quot;3.0&quot;</span>

<span style="color: cyan; font-weight: 600;">skill</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/github
  <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;GitHub operations via MCP&quot;</span>

  <span style="color: cyan; font-weight: 600;">mcp_servers</span>:
    - <span style="color: cyan;">name</span>: github
      <span style="color: cyan; font-weight: 600;">command</span>: <span style="color: #66cc66;">&quot;npx @anthropic/mcp-github&quot;</span>
      <span style="color: cyan; font-weight: 600;">env</span>:
        <span style="color: cyan; font-weight: 600;">GITHUB_TOKEN</span>: <span style="color: #66cc66;">&quot;${GITHUB_TOKEN}&quot;</span>
      <span style="color: cyan; font-weight: 600;">overrides</span>:
        - <span style="color: cyan;">tool</span>: create_issue
          <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">true</span>
          <span style="color: cyan; font-weight: 600;">write_scope</span>: [github:issues]
          <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">false</span>
        - <span style="color: cyan;">tool</span>: create_pull_request
          <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">true</span>
          <span style="color: cyan; font-weight: 600;">write_scope</span>: [github:pulls]
          <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">false</span>
        - <span style="color: cyan;">tool</span>: list_repos
          <span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">true</span>
        - <span style="color: cyan;">tool</span>: get_file_contents
          <span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">true</span>
</code></pre></div>

#### Skill Hierarchy and Composition

Skills can include other skills via the `includes` field. When a skill includes another, all tools from the child skill (and transitively, all tools from any skills *it* includes) become part of the parent skill's flattened tool set.

<div class="highlight"><pre><code>
local/full-stack-dev
  ├── includes: local/file-ops
  │     └── builtins: file_operations, directory_operations
  ├── includes: local/git-ops
  │     └── builtins: git_operations
  ├── includes: local/github
  │     └── mcp_servers: github (create_issue, create_pr, list_repos, ...)
  ├── agent_skills: code-review-checklist
  └── tools: local/run-migrations, local/deploy-staging  (named tool refs)

  Flattened tool set available to actors referencing local/full-stack-dev:
    read_file, write_file, edit_file, delete_file, move_file, copy_file,
    create_directory, list_directory, delete_directory,
    git_status, git_diff, git_log, git_blame,
    create_issue, create_pr, list_repos, get_file_contents,
    code-review-checklist (agent skill),
    local/run-migrations, local/deploy-staging (named tools)
</code></pre></div>

**Rules for skill composition:**

1. **Circular includes are forbidden.** The system validates the include graph at registration time and rejects cycles.
2. **Tool name conflicts**: If two included skills provide tools with the same name, the conflict is resolved by qualification — the tool must be referenced as `<skill_name>.<tool_name>` (e.g., `local/github.create_issue` vs `local/linear.create_issue`). Direct tools (defined in the skill itself) take precedence over included tools.
3. **Included skills must be registered** before the including skill can be added. The `agents skill add` command validates this.
4. **Depth is unlimited** but the flattened tool set is computed at registration time and cached. Deep hierarchies do not incur runtime overhead.

#### Skill Registration and Management

Skills are managed through the `agents skill` CLI commands. Named tools referenced by skills must first be registered via `agents tool add` (see the **Tools** section):

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># First, register any named tools the skill will reference</span>
agents tool add <span style="color: cyan;">--config</span> ./tools/run-migrations.yaml
agents tool add <span style="color: cyan;">--config</span> ./tools/deploy-staging.yaml

<span style="opacity: 0.7;"># Then register the skill (which references those tools by name)</span>
agents skill add <span style="color: cyan;">--config</span> ./skills/devops-toolkit.yaml local/devops-toolkit

<span style="opacity: 0.7;"># Update an existing skill (re-reads the config file, overwrites registration)</span>
agents skill add <span style="color: cyan;">--config</span> ./skills/devops-toolkit.yaml <span style="color: cyan;">--update</span> local/devops-toolkit

<span style="opacity: 0.7;"># List all registered skills</span>
agents skill list

<span style="opacity: 0.7;"># Show details for a skill (tools, includes, metadata)</span>
agents skill show local/devops-toolkit

<span style="opacity: 0.7;"># List all tools provided by a skill (flattened, including from child skills)</span>
agents skill tools local/devops-toolkit

<span style="opacity: 0.7;"># Remove a skill</span>
agents skill remove local/devops-toolkit
</code></pre></div>

Once registered, a skill is available to be referenced by any actor configuration. Skills persist in the database (local or server) and follow the same namespace rules as actors, tools, and actions.

#### Actor References to Skills and Tools

Actors reference skills **by name** to make collections of tools available for LLM tool-calling. Additionally, actor graphs can include **tool nodes** that directly reference named tools or define anonymous inline tools (see **Nodes in the Graph** in the Actor section).

The actor's configuration lists which skills it should have access to:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># File: actors/code-assistant.yaml</span>
<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">&quot;3.0&quot;</span>
  <span style="color: cyan; font-weight: 600;">default_actor</span>: code_assistant

<span style="color: cyan; font-weight: 600;">actors</span>:
  <span style="color: cyan; font-weight: 600;">code_assistant</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">actor</span>: anthropic/claude-3-opus
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.3</span>
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: <span style="color: #66cc66;">|</span>
        You are a code assistant with access to file, git, and GitHub tools.
        Current task: {{ context.task_description }}

<span style="opacity: 0.7;">    # Reference skills by fully-qualified name.</span>
<span style="opacity: 0.7;">    # All tools from these skills become available to this actor.</span>
    <span style="color: cyan; font-weight: 600;">skills</span>:
      - local/file-ops
      - local/git-ops
      - local/github

<span style="opacity: 0.7;">  # Or reference a single composite skill that includes all of the above</span>
  <span style="color: cyan; font-weight: 600;">full_stack_assistant</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">actor</span>: anthropic/claude-3-opus
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: <span style="color: #66cc66;">|</span>
        You are a full-stack development assistant.

    <span style="color: cyan; font-weight: 600;">skills</span>:
      - local/full-stack-dev    # includes file-ops, git-ops, github, etc.
</code></pre></div>

**Server-qualified skill references**: When connected to multiple servers, skills can be disambiguated with a server prefix, same as actors:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">skills</span>:
  - <span style="color: cyan;">dev</span>:freemo/custom-analysis     # from dev server, personal namespace
  - <span style="color: cyan;">prod</span>:cleverthis/deploy-tools   # from prod server, org namespace
  - local/file-ops                 # local skill
</code></pre></div>

#### Skill Registry

To enable plan validation and discovery at scale, CleverAgents maintains two registries that work together:

1. **Tool Registry** — a persistent catalog of all independently registered tools (described in the **Tools** section above). Managed via `agents tool add/remove/list/show`.

2. **Skill Registry** — a persistent catalog of all registered skills and their flattened tool sets. The Skill Registry composes its tool sets by resolving named tool references from the Tool Registry, incorporating anonymous inline tools, and merging tools from included child skills.

```kroki-plantuml
@startuml
skinparam classAttributeIconSize 0
skinparam classFontSize 13
skinparam defaultFontSize 12

class SkillRegistry {
  - skillIndex : Map<String, SkillRecord>
  --
  + add(config_path) : SkillRecord
  + update(name, config_path) : SkillRecord
  + remove(name) : void
  + lookup(name) : SkillRecord
  + list(filters) : SkillRecord[]
  + tools(name) : ToolDescriptor[]
  + validate_plan(plan) : ValidationResult
  + refresh(name) : void
}

class SkillRecord {
  + name : String
  + description : String
  + config_path : String
  + includes : List<String>
  + tool_refs : List<String>
  + anonymous_tools : List<ToolDef>
  + flattened_tools : List<ToolDescriptor>
  + overrides : Map<String, Object>
  + capability_summary : CapabilitySummary
}

SkillRegistry "1" *-- "0..*" SkillRecord : indexes >

note right of SkillRegistry
  **Populated by:**
  - agents skill add CLI command
  - Dynamic refresh on MCP notifications

  **Depends on:**
  - Tool Registry (resolve named tool references)

  **Consumed by:**
  - Actor activation
  - Plan validation
  - Agent context injection
end note
@enduml
```

Both registries persist in the database (local SQLite or server). MCP server tools are refreshed dynamically when `notifications/tools/list_changed` events are received.

### Session

#### What a Session Is

A **session** is a user's interactive thread with CleverAgents across time.

A session should:

* maintain conversational continuity,
* store plan references,
* persist memory (if enabled),
* provide a UI anchor (CLI invocation, TUI workspace, web session).

#### Session and Memory Persistence

The notes include a known issue: conversation history can be lost between CLI invocations depending on connection string configuration, implying the system needs a stable memory service backend.

Therefore, CleverAgents should specify:

* sessions have stable IDs
* sessions can be resumed
* session storage backend is configured explicitly
* if session persistence is disabled, the UX should be explicit about it (no silent history loss)

### Server

#### What a Server Is

A server is an optional mode that enables:

* multi-user access
* shared org namespaces (`<username>/` and `<orgname>/`)
* persistent plan records
* remote plan execution
* governance

**Single-user local mode is the default** (so setup is easy), but the architecture anticipates server mode for shared skills and org-level actions.

#### Client-Only vs Server Mode

| Mode | Description | Plan Execution |
|------|-------------|----------------|
| **Client-only** | No server connection. All data in local database. | Always local |
| **Server mode** | Connected to a CleverAgents server. Namespaced items sync. | Local or server |

**It is possible to run a client with no server at all.** Server is optional.

#### Plan Execution Location

Where a plan executes depends on the project type:

| Project Type | Client Execution | Server Execution |
|--------------|-----------------|------------------|
| **Local** (has local-only resources) | ✅ Yes | ❌ No (server can't access local resources) |
| **Remote** (all resources remotely accessible) | ✅ Yes | ✅ Yes |

When acting on **local projects**, the client must be running because only the client can access local resources.

**Remote projects** can execute on either:
- The client (if user prefers local execution)
- The server (for long-running plans, since client may be transient)

#### Server Execution Benefits

Server execution is useful when:

* Plans take a long time to execute
* Client may disconnect (laptop closes, network issues)
* Multiple team members need to monitor plan progress
* Centralized logging and auditing required

#### No Plan Queuing

**Plans are not queued.** When a plan is used on projects and executed, it runs immediately. There is no worker queue or delayed execution model.

#### Multi-user Risks and Prompt Injection

Prompt injection isn't critical in single-user mode but becomes important for multi-user server environments.

Server mode must include:

* access boundaries
* prompt sanitization / safe templating
* resource access controls
* auditing

### Resources

A **resource** is an independently registered entity representing anything that a plan can reason about or manipulate — git repositories, filesystems, databases, APIs, documents, and more. Resources are **first-class citizens** in CleverAgents, managed through the `agents resource` CLI commands and stored in the **Resource Registry**.

**CleverAgents extends the MCP resource concept** to support both read AND write operations (MCP resources are read-only). Unlike MCP's flat resource model, CleverAgents resources form a **directed acyclic graph (DAG)** with parent/child relationships, support **physical vs virtual** distinction for content identity tracking, and are governed by a **resource type system** that constrains their structure and behavior.

Resources are registered independently of projects. Projects **link** to resources from the Resource Registry — a resource can be linked to multiple projects, enabling shared resources across teams and workflows.

#### What a Resource Is

A resource has:

* **Name and namespace**: User-added resources follow the same `<namespace>/<name>` naming convention as actors, tools, skills, and other entities (e.g., `local/api-repo`, `cleverthis/staging-db`). Auto-discovered child resources do not have names — they are identified by ULID only. Every resource (whether user-added or auto-discovered) always has a system-assigned ULID.
* **Resource type**: Every resource has a type (e.g., `git`, `fs-mount`, `git-branch`, `fs-file`) that determines its properties, CLI arguments, allowed parent/child relationships, sandbox strategy, and handler implementation.
* **Physical or virtual nature**: Resources are either **physical** (a specific, concrete manifestation) or **virtual** (an abstract identity linking equivalent physical resources). This is determined by the resource type.
* **Value/properties**: Type-specific properties (a file path, a URL, a connection string, a commit hash, etc.).
* **Parent/child relationships**: Resources form a DAG. A resource can have multiple parents and multiple children, subject to type constraints.
* **Capabilities**: Whether the resource is readable, writable, sandboxable, and checkpointable.

#### Resource Types

A **resource type** is a schema-level definition that constrains a category of resources. Resource types define:

* **CLI arguments**: What arguments `agents resource add <type>` accepts (for user-addable types), including which are required vs optional and validation rules.
* **Physical or virtual**: Whether instances of this type are physical or virtual resources.
* **Allowed parent types**: What resource types are valid parents.
* **Allowed child types**: What resource types are valid children, and whether they are auto-discovered or manually linkable.
* **Auto-discovery behavior**: What child resources are automatically created when an instance of this type is registered (e.g., registering a `git-checkout` resource auto-discovers a `git` child and an `fs-directory` child for the worktree root; the `git` child in turn auto-discovers remotes, branches, commits, and tree entries).
* **User addable**: Whether users can create instances of this type directly via `agents resource add <type>`. Types with `user_addable: false` are only generated as auto-discovered children of other resources.
* **Sandbox strategy**: The default sandboxing approach for instances of this type.
* **Handler**: The resource handler implementation that provides read/write/sandbox/checkpoint operations.

##### Built-in Resource Types

Built-in types are organized into three layers: **git** (version control structure), **git-checkout** (a composition that bridges git metadata with a local directory), and **filesystem** (physical files on disk). Virtual types link equivalent physical resources across these layers through content/identity matching. There are 24 built-in types total (15 physical + 9 virtual), of which 4 are user-addable (`git-checkout`, `git`, `fs-mount`, `fs-directory`).

Each table below includes the full parent/child relationship constraints. **Allowed Parents** lists what types may be a parent of this type, with cardinality (how many parents of that type are allowed) and whether the relationship is required or optional. **Allowed Children** lists what types may be children, with cardinality and whether they are required or optional. `0..*` means zero or more, `1` means exactly one (required), `0..1` means zero or one (optional).

**Physical types — Git layer** (version control structure — every instance is a concrete manifestation in a specific repository):

| Type | User Addable | Sandbox | Allowed Parents | Allowed Children | Description |
|------|-------------|---------|-----------------|------------------|-------------|
| `git` | yes | `none` | `git-checkout` (0..1, optional) | `git-remote` (0..*, optional), `git-branch` (0..*, optional), `git-tag` (0..*, optional), `git-commit` (0..*, optional), `git-stash` (0..*, optional), `git-submodule` (0..*, optional) | A git repository — the object database, refs, and full history. Accessible via a local `.git` directory path or a remote URL. Every `git` resource is a specific, concrete repo instance (local or hosted on a remote server). |
| `git-remote` | no | `none` | `git` (1, required) | (none) | A remote URL configured on a git repo (e.g., `origin → https://github.com/org/repo`). Auto-discovered child of `git`. Optionally linked as a child of a `remote` virtual resource when the same URL appears in multiple repos. |
| `git-branch` | no | (inherits) | `git` (1, required) | `git-commit` (0..*, optional) | A named branch ref (e.g., `main`, `feature/auth`). Auto-discovered child of `git`. Optionally linked as a child of a `branch` virtual resource when the same branch name + HEAD exists in multiple repos. |
| `git-tag` | no | (inherits) | `git` (1, required) | (none) | A tag ref — lightweight or annotated (e.g., `v1.0.0`). Auto-discovered child of `git`. Optionally linked as a child of a `tag` virtual resource when the same tag name + target exists in multiple repos. |
| `git-commit` | no | (inherits) | `git-branch` (1..*, required), `git` (1, required) | `git-tree` (1, required) | A specific commit object. Auto-discovered child of `git-branch` (a commit can belong to multiple branches). Each commit contains exactly one root `git-tree`. Also a direct child of `git` for ancestry traversal. Optionally linked as a child of a `commit` virtual resource when the same commit hash exists in multiple repos (e.g., shared history between fork and upstream). |
| `git-tree` | no | (inherits) | `git-commit` (1..*, required) | `git-tree-entry` (0..*, optional), `git-tree` (0..*, optional) | A tree object — a directory listing at a specific commit. Each tree contains entries (blobs and subtrees). Auto-discovered child of `git-commit`. Trees are recursive: a tree can contain subtrees as children. Optionally linked as a child of a `tree` virtual resource when the same tree hash exists across commits/repos. |
| `git-tree-entry` | no | (inherits) | `git-tree` (1, required) | (none) | A blob entry in a tree — a specific file's content at a specific path and mode. Auto-discovered child of `git-tree`. Represents the leaf of git's content-addressable storage. Optionally linked as a child of a `file` virtual resource when byte-identical content with the same name and permissions exists in the filesystem layer. |
| `git-stash` | no | (inherits) | `git` (1, required) | (none) | A stash entry (e.g., `stash@{0}`). Auto-discovered child of `git`. Represents work-in-progress saved via `git stash`. |
| `git-submodule` | no | (inherits) | `git` (1, required) | (none) | A submodule reference — a pointer to another git repository at a specific commit and path. Auto-discovered child of `git`. Optionally linked as a child of a `submodule` virtual resource when the same submodule URL + path exists in multiple repos. |

**Physical types — Git checkout** (composition: git metadata + local worktree directory):

| Type | User Addable | Sandbox | Allowed Parents | Allowed Children | Description |
|------|-------------|---------|-----------------|------------------|-------------|
| `git-checkout` | yes | `git_worktree` | (none — always a top-level resource) | `git` (1, required), `fs-directory` (1, required) | A locally checked-out git repository. The **composition type** — auto-discovers a `git` child (the repo's object database, branches, tags, commits, trees, and remotes) and an `fs-directory` child (the worktree root directory, e.g., `/home/user/projects/my-app`). Most users register this type. The worktree root IS a directory, not a mount point, so git-checkout composes with `fs-directory` directly. |

**Physical types — Filesystem layer** (files on disk, used by git checkouts and standalone directories alike):

| Type | User Addable | Sandbox | Allowed Parents | Allowed Children | Description |
|------|-------------|---------|-----------------|------------------|-------------|
| `fs-mount` | yes | `copy_on_write` | (none — always a top-level resource) | `fs-directory` (1, required) | A physical mount point on the local system (e.g., `/mnt/data`, `/home`). Represents the mount itself — the filesystem type (ext4, btrfs, etc.) is a property. The root directory is a required auto-discovered `fs-directory` child. Used for registering entire mount points or storage volumes. |
| `fs-directory` | yes | `copy_on_write` | `git-checkout` (0..1, optional), `fs-mount` (0..1, optional), `fs-directory` (0..1, optional) | `fs-directory` (0..*, optional), `fs-file` (0..*, optional), `fs-symlink` (0..*, optional), `fs-hardlink` (0..*, optional) | A directory on the filesystem. Can be the root child of `fs-mount` (mount point root), the worktree root child of `git-checkout`, a subdirectory child of another `fs-directory`, or a standalone user-registered directory. Optionally linked as a child of a `directory` virtual resource when equivalent directory content exists elsewhere. When user-addable, accepts `--path` flag. |
| `fs-file` | no | (inherits) | `fs-directory` (1, required) | (none) | A regular file on the local filesystem. Auto-discovered child of `fs-directory`. Optionally linked as a child of a `file` virtual resource when byte-identical content with the same name and permissions exists elsewhere (in another `fs-file` or a `git-tree-entry`). |
| `fs-symlink` | no | (inherits) | `fs-directory` (1, required) | (none) | A symbolic link on the local filesystem. Auto-discovered child of `fs-directory`. Optionally linked as a child of a `symlink` virtual resource when a symlink with the same name and target exists elsewhere. |
| `fs-hardlink` | no | (inherits) | `fs-directory` (1, required) | (none) | A hard link on the local filesystem — a file with link count > 1. Auto-discovered child of `fs-directory`. The system tracks hard link relationships by inode to avoid treating the same underlying data as distinct resources. |

**Virtual types** (abstract identity types that link equivalent physical resources — never user-addable, no sandbox):

Virtual types use simple names that mirror their physical counterparts. A virtual resource answers the question: "where else does this same thing exist?" Two physical resources share a virtual parent when they are equivalent by the virtual type's criteria (same content, same name, same permissions, same hash, etc.).

| Type | Allowed Children | Description |
|------|-----------------|-------------|
| `file` | `fs-file` (0..*, optional), `git-tree-entry` (0..*, optional) | Cross-layer file identity. Links physical `fs-file` and `git-tree-entry` resources that represent the same file — identical content bytes, filename, and permissions. Answers: "this file in the working tree and this blob in git's tree are the same file." |
| `directory` | `fs-directory` (0..*, optional), `git-tree` (0..*, optional) | Cross-layer directory identity. Links physical `fs-directory` and `git-tree` resources whose recursive contents are equivalent. Answers: "this directory on disk matches this tree object in git." |
| `symlink` | `fs-symlink` (0..*, optional), `git-tree-entry` (0..*, optional) | Cross-layer symlink identity. Links physical `fs-symlink` and `git-tree-entry` (mode 120000) resources with the same name and target. |
| `commit` | `git-commit` (0..*, optional) | Cross-repo commit identity. Links `git-commit` resources across different repos that share the same commit hash — typically a fork and its upstream. Answers: "this commit exists in both repos." |
| `branch` | `git-branch` (0..*, optional) | Cross-repo branch identity. Links `git-branch` resources across different repos with the same branch name and HEAD commit hash. |
| `tag` | `git-tag` (0..*, optional) | Cross-repo tag identity. Links `git-tag` resources across different repos with the same tag name and target object. |
| `remote` | `git-remote` (0..*, optional) | Cross-repo remote identity. Links `git-remote` resources across different repos that point to the same URL. Answers: "these repos share the same upstream." |
| `submodule` | `git-submodule` (0..*, optional) | Cross-repo submodule identity. Links `git-submodule` resources across different repos with the same submodule URL and path. |
| `tree` | `git-tree` (0..*, optional) | Cross-repo/cross-commit tree identity. Links `git-tree` resources across different commits or repos that have the same tree hash — identical directory structure and contents. |

**Key design notes:**

* Virtual types are **never user-addable** — they are created and maintained automatically by the system when equivalent physical resources are detected.
* Virtual types have **no sandbox strategy** because they represent abstract identities, not concrete locations. Tools always operate on the physical children.
* **Physical types list virtual parents in their Allowed Parents column** (via the "optionally linked" descriptions). For example, an `fs-file` can be linked as a child of a `file` virtual resource when its content matches a `git-tree-entry`. This is how the DAG connects physical and virtual layers.
* `git` represents a specific git repository instance — whether hosted remotely (e.g., on GitHub's servers) or locally (a `.git` directory on disk). It is **physical** because it is a concrete manifestation that exists somewhere, not an abstract identity. A `git` resource can be created from a remote URL alone (accessing the object database via the git protocol) or from a local `.git` directory.
* `git-checkout` is the type most users register for repos they've cloned. It composes a `git` child (repo metadata) and an `fs-directory` child (the worktree root directory). The worktree root is a directory on an existing filesystem — NOT a separate mount point — so `git-checkout` links directly to `fs-directory`, not `fs-mount`. This means the worktree's files use the **same `fs-directory` and `fs-file` types** regardless of how they were created.
* `git-commit` has a `git-tree` child (the root tree object), which in turn has `git-tree-entry` and nested `git-tree` children. This properly models git's internal object structure: commits point to trees, trees contain entries (blobs) and subtrees.
* `fs-mount` represents a physical mount point, not a directory. The filesystem type (ext4, btrfs, etc.) is a property on the mount. The root directory is an auto-discovered `fs-directory` child. Use `fs-mount` for registering mount points and storage volumes. Use `fs-directory` (user-addable) for registering arbitrary directories.
* `fs-directory` is user-addable, allowing users to register standalone directories (e.g., a build output folder, a config directory) without wrapping them in an `fs-mount`. An `fs-directory` registered standalone or as a child of `fs-mount`/`git-checkout` uses the same type and auto-discovers the same `fs-file`, `fs-symlink`, `fs-hardlink`, and nested `fs-directory` children.
* `git-tree-entry` represents a blob in git's tree — a specific file's content at a specific path and mode. The corresponding file on disk (if checked out) is an `fs-file`. The `file` virtual type bridges these two when their content, name, and permissions are identical.
* **4 user-addable types**: `git-checkout` (local repo), `git` (remote or local metadata-only), `fs-mount` (mount point), `fs-directory` (arbitrary directory).

##### Built-in Type Hierarchy

The parent-child relationships between built-in resource types form three layers — git structure, git checkout (composition), and filesystem — bridged by virtual identity types:

```kroki-plantuml
@startuml
skinparam defaultFontSize 11
skinparam objectFontSize 11
skinparam packageStyle rectangle

package "GIT-CHECKOUT (composition)" as GC #LightBlue {
  object "git-checkout" as gc {
    /home/user/projects/myapp
  }
}

package "GIT STRUCTURE" as GS #LightYellow {
  object "git" as git {
    repo object DB
  }
  object "git-remote" as remote {
    origin
  }
  object "git-tag" as tag {
    v1.0.0
  }
  object "git-submodule" as submod {
    lib/shared
  }
  object "git-branch" as branch {
    main
  }
  object "git-stash" as stash {
    stash@0
  }
  object "git-commit" as commit {
    a1b2c3d
  }
  object "git-tree" as tree {
    e8f1... root
  }
  object "git-tree-entry" as entry1 {
    README.md
  }
  object "git-tree" as subtree {
    src/ subtree
  }
  object "git-tree-entry" as entry2 {
    src/app.ts
  }
  object "git-tree-entry" as entry3 {
    src/main.ts
  }
}

package "FILESYSTEM (worktree)" as FS #LightGreen {
  object "fs-directory" as fsroot {
    worktree root
  }
  object "fs-directory" as srcdir {
    src/
  }
  object "fs-file" as readme {
    README.md
  }
  object "fs-file" as app {
    app.ts
  }
  object "fs-file" as main {
    main.ts
  }
}

package "STANDALONE FS-DIRECTORY" as SFS #Wheat {
  object "fs-directory" as sfs {
    /opt/deploy/myapp
  }
  object "fs-directory" as ssrcdir {
    src/
  }
  object "fs-file" as sreadme {
    README.md
  }
  object "fs-file" as sapp {
    app.ts
  }
  object "fs-file" as smain {
    main.ts
  }
  object "fs-symlink" as symlink {
    link.txt
  }
}

package "STANDALONE FS-MOUNT" as SM #LightCoral {
  object "fs-mount" as mount {
    /mnt/data
  }
  object "fs-directory" as mountroot {
    root: /
  }
}

package "VIRTUAL LAYER (abstract identities)" as VL #Lavender {
  object "file" as vfile {
    app.ts @ sha256:9f8e...
  }
  object "directory" as vdir {
    src/ @ merkle:3d4f...
  }
  object "commit" as vcommit {
    a1b2c3d
  }
  object "branch" as vbranch {
    main @ a1b2c3d
  }
  object "remote" as vremote {
    github.com/org/repo
  }
  object "tree" as vtree {
    e8f1...9d2a
  }
}

gc --> git
gc --> fsroot

mount --> mountroot

git --> remote
git --> tag
git --> submod
git --> branch
git --> stash

branch --> commit
commit --> tree
tree --> entry1
tree --> subtree
subtree --> entry2
subtree --> entry3

fsroot --> srcdir
fsroot --> readme
srcdir --> app
srcdir --> main

sfs --> ssrcdir
sfs --> sreadme
sfs --> symlink
ssrcdir --> sapp
ssrcdir --> smain

app ..> vfile : equivalent
sapp ..> vfile : equivalent
entry2 ..> vfile : equivalent
srcdir ..> vdir : equivalent
ssrcdir ..> vdir : equivalent
subtree ..> vdir : equivalent
commit ..> vcommit : equivalent
branch ..> vbranch : equivalent
remote ..> vremote : equivalent
tree ..> vtree : equivalent
@enduml
```

**Reading the diagram:**

* **Top left**: A `git-checkout` resource decomposes into a `git` child (left — the repository's full structure) and an `fs-directory` child (center — the worktree root directory at `/home/user/projects/myapp`). The worktree root is a directory, not a mount point.
* **Git structure** (left column): The `git` child contains `git-remote` (origin), `git-tag` (v1.0.0), `git-submodule` (lib/shared), `git-stash` (stash@{0}), and `git-branch` (main). The branch contains `git-commit` objects, each commit contains a root `git-tree`, and trees contain `git-tree-entry` (blobs) and nested `git-tree` (subtrees). This properly models git's internal object structure.
* **Filesystem** (center/right): The worktree's `fs-directory` contains `src/` (an `fs-directory`), `README.md` (an `fs-file`), and files including `fs-symlink` resources. A standalone `fs-directory` (`/opt/deploy/myapp`) with the same structure. A standalone `fs-mount` (`/mnt/data`) with a root `fs-directory` child.
* **Virtual layer** (boxed area): Shows how virtual types link equivalent physical resources:
  - A `file` virtual resource links `fs-file` and `git-tree-entry` resources that have the same content, filename, and permissions — bridging the filesystem and git layers.
  - A `directory` virtual resource links `fs-directory` and `git-tree` resources with the same recursive content.
  - A `commit` virtual resource links `git-commit` resources across repos with the same commit hash.
  - A `branch` virtual resource links `git-branch` resources across repos with the same name and HEAD.
  - A `remote` virtual resource links `git-remote` resources across repos with the same URL.
  - A `tree` virtual resource links `git-tree` resources across repos/commits with the same tree hash.

**Key separations:**

* **`git` vs `git-checkout`**: A `git` resource represents a specific repository instance (local or remote). It can exist without any local directory (created from a remote URL — the repo exists on the remote server). A `git-checkout` always has both a `git` child and an `fs-directory` child — it represents a locally cloned repo with files on disk.
* **`git-tree-entry` vs `fs-file`**: A `git-tree-entry` is a blob entry in git's tree (path + content hash + mode). An `fs-file` is a physical file on disk. When a repo is checked out, both exist and typically have matching content — the `file` virtual type links them when content, name, and permissions match.
* **`git-tree` vs `fs-directory`**: A `git-tree` is a tree object in git's object database (a directory listing at a commit). An `fs-directory` is a physical directory on disk. The `directory` virtual type links them when their recursive contents match.
* **`git-commit` → `git-tree` → `git-tree-entry`**: This chain properly models git internals. Commits point to a root tree, trees contain entries (blobs) and subtrees. The old design skipped the tree level; the current design preserves it.
* **`fs-mount` vs `fs-directory`**: An `fs-mount` is a mount point (e.g., `/mnt/data`). The filesystem type (ext4, btrfs, etc.) is a property. The root directory is an `fs-directory` child. An `fs-directory` is a directory — it can be a child of `fs-mount`, `git-checkout`, or another `fs-directory`, or it can be registered standalone by the user.
* **`git-checkout` composes with `fs-directory`, not `fs-mount`**: A git checkout's worktree is a directory on an existing filesystem, not a separate mount point. This is why `git-checkout`'s required child is `fs-directory` (the worktree root), not `fs-mount`.
* **Virtual types bridge physical equivalents**: `file` bridges `fs-file` + `git-tree-entry` (cross-layer). `directory` bridges `fs-directory` + `git-tree` (cross-layer). `commit`, `branch`, `tag`, `remote`, `submodule`, and `tree` link the same git structural element across different repos.

##### Concrete Example: A Made-Up Project

Consider a web application called "Acme Dashboard" with three registered resources:

1. **`local/acme-app`** — a checked-out git repo at `/home/alice/projects/acme-dashboard` (type: `git-checkout`)
2. **`local/acme-upstream`** — a git repo accessed via remote URL, not cloned (type: `git`)
3. **`local/acme-deploy`** — a standalone directory at `/opt/deploy/acme-dashboard` containing a production build snapshot (type: `fs-directory`)

**Registration:**

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># 1) Checked-out git repo (has local files on disk)</span>
agents resource add git-checkout local/acme-app <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--path</span> /home/alice/projects/acme-dashboard <span style="color: cyan;">--branch</span> main

<span style="opacity: 0.7;"># 2) Git repo via remote URL (no local checkout — metadata only)</span>
agents resource add git local/acme-upstream <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--url</span> git@github.com:acmecorp/dashboard.git

<span style="opacity: 0.7;"># 3) Standalone directory (not a git repo — just files on disk)</span>
agents resource add fs-directory local/acme-deploy <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--path</span> /opt/deploy/acme-dashboard
</code></pre></div>

**What gets auto-discovered for each:**

**`local/acme-app`** (type: `git-checkout`) discovers two children — a `git` and an `fs-directory` (the worktree root):

```kroki-plantuml
@startwbs
* local/acme-app\n(git-checkout / physical)
** local/acme-app:repo\n(git / physical)
*** acme-app:repo:origin\n(git-remote)\ngit@github.com:acmecorp/dashboard.git
*** acme-app:repo:v1.0.0\n(git-tag)
*** acme-app:repo:lib/shared\n(git-submodule @ c4d5e6f)
*** acme-app:repo:stash@0\n(git-stash)
*** acme-app:repo:main\n(git-branch)
**** main:a7f3e21\n(git-commit)
***** main:a7f3e21:tree\n(git-tree / root)
****** a7f3e21:README.md\n(git-tree-entry)
****** a7f3e21:package.json\n(git-tree-entry)
****** a7f3e21:src/\n(git-tree / subtree)
******* a7f3e21:src/app.ts\n(git-tree-entry)
******* a7f3e21:src/api.ts\n(git-tree-entry)
******* a7f3e21:src/utils.ts\n(git-tree-entry)
*** acme-app:repo:develop\n(git-branch)
**** develop:b2c4d8e\n(git-commit)
***** develop:b2c4d8e:tree\n(git-tree)
****** b2c4d8e:src/\n(git-tree)
******* b2c4d8e:src/app.ts\n(git-tree-entry)
******* b2c4d8e:src/api.ts\n(git-tree-entry / modified)
** local/acme-app:worktree\n(fs-directory / physical)\n/home/alice/projects/acme-dashboard/
*** worktree:src/\n(fs-directory)
**** worktree:src/app.ts\n(fs-file)
**** worktree:src/api.ts\n(fs-file)
**** worktree:src/utils.ts\n(fs-file)
*** worktree:package.json\n(fs-file)
*** worktree:README.md\n(fs-file)
*** worktree:docs -> ../docs\n(fs-symlink)
@endwbs
```

The `git-checkout` cleanly separates two concerns: the `git` child contains version control structure (remotes, branches, tags, stashes, submodules, commits, trees, and tree entries — git's full object model), while the `fs-directory` child is the worktree root directory containing the actual files on disk. Note how git's internal structure is fully modeled: `git-commit` → `git-tree` (root tree object) → `git-tree-entry` (blobs) and nested `git-tree` (subtrees). The worktree root is a directory (`fs-directory`), not a mount point — `git-checkout` does not own an `fs-mount` resource because a git checkout's worktree is just a directory on an existing filesystem. When content matches (as it does for a clean checkout), virtual types link the `fs-file` and `git-tree-entry` resources.

**`local/acme-upstream`** (type: `git`, remote URL — NOT checked out) discovers:

```kroki-plantuml
@startwbs
* local/acme-upstream\n(git / physical)\ngit@github.com:acmecorp/dashboard.git
** acme-upstream:origin\n(git-remote)
** acme-upstream:v1.0.0\n(git-tag)
** acme-upstream:main\n(git-branch)
*** main:a7f3e21\n(git-commit)
**** main:a7f3e21:tree\n(git-tree)
***** a7f3e21:src/\n(git-tree)
****** a7f3e21:src/app.ts\n(git-tree-entry)
****** a7f3e21:src/api.ts\n(git-tree-entry)
** acme-upstream:develop\n(git-branch)
*** ...\n(remaining structure)
@endwbs
```

A standalone `git` resource has **full access to branches, tags, commits, trees, and tree entries** — everything in the git object database — but **no `fs-directory` child** and **no `fs-file` resources**. There are no files on the local disk (the repo exists on GitHub's servers). Tools that need local file access cannot bind to it.

This is the key difference from `git-checkout`: a `git` resource represents a specific repo instance. Plans can reason about history, diffs between branches, remote relationships — without a local clone. A `git-checkout` adds the local worktree directory on top.

**`local/acme-deploy`** (type: `fs-directory`, standalone) discovers:

```kroki-plantuml
@startwbs
* local/acme-deploy\n(fs-directory / physical)\n/opt/deploy/acme-dashboard/
** acme-deploy:src/\n(fs-directory)
*** acme-deploy:src/app.ts\n(fs-file)
*** acme-deploy:src/api.ts\n(fs-file)
*** acme-deploy:src/utils.ts\n(fs-file)
** acme-deploy:package.json\n(fs-file)
** acme-deploy:README.md\n(fs-file)
@endwbs
```

A standalone `fs-directory` — no git metadata, no branches, no commits, no tree entries. Just a directory containing files and subdirectories. Uses the **same `fs-directory` and `fs-file` types** as the git checkout's worktree root.

**Virtual resource linking across all three:**

After all three resources are registered, the system detects equivalent physical resources and creates virtual parents to link them:

```kroki-plantuml
@startuml
skinparam defaultFontSize 10
skinparam objectFontSize 10
skinparam packageStyle rectangle
left to right direction

package "PHYSICAL: local/acme-app" as P1 #LightBlue {
  object "fs-directory" as acmeWtSrc {
    worktree:src/
  }
  object "fs-file" as acmeWtApp {
    worktree:src/app.ts
  }
  object "fs-file" as acmeWtUtils {
    worktree:src/utils.ts
  }
  object "fs-file" as acmeWtApi {
    worktree:src/api.ts
  }
  object "git-tree" as acmeGitSrc {
    main:a7f3e21:src/
  }
  object "git-tree-entry" as acmeGitApp {
    main:src/app.ts
  }
  object "git-tree-entry" as acmeGitUtils {
    main:src/utils.ts
  }
  object "git-tree-entry" as acmeGitApi {
    main:src/api.ts
  }
  object "git-commit" as acmeCommit {
    main:a7f3e21
  }
  object "git-branch" as acmeBranch {
    main
  }
  object "git-tag" as acmeTag {
    v1.0.0
  }
  object "git-remote" as acmeRemote {
    origin
  }
  object "git-tree" as acmeTree {
    main:a7f3e21:tree
  }
  object "git-submodule" as acmeSubmod {
    lib/shared
  }
}

package "PHYSICAL: local/acme-deploy" as P2 #LightGreen {
  object "fs-directory" as deploySrc {
    src/
  }
  object "fs-file" as deployApp {
    src/app.ts
  }
  object "fs-file" as deployUtils {
    src/utils.ts
  }
  object "fs-file" as deployApi {
    src/api.ts
  }
}

package "PHYSICAL: local/acme-upstream" as P3 #LightYellow {
  object "git-tree" as upstreamSrc {
    main:a7f3e21:src/
  }
  object "git-tree-entry" as upstreamApp {
    main:src/app.ts
  }
  object "git-tree-entry" as upstreamUtils {
    main:src/utils.ts
  }
  object "git-tree-entry" as upstreamApi {
    main:src/api.ts
  }
  object "git-commit" as upstreamCommit {
    main:a7f3e21
  }
  object "git-branch" as upstreamBranch {
    main
  }
  object "git-tag" as upstreamTag {
    v1.0.0
  }
  object "git-remote" as upstreamRemote {
    origin
  }
  object "git-tree" as upstreamTree {
    main:a7f3e21:tree
  }
}

package "VIRTUAL LAYER\n(auto-created by equivalence)" as VL #Lavender {
  object "directory" as vDir {
    src/ (merkle:3d4f...)
  }
  object "file" as vAppTs {
    app.ts (sha256:9f8e...)
  }
  object "file" as vUtilsTs {
    utils.ts (sha256:a2b1...)
  }
  object "file" as vApiTs {
    api.ts (sha256:e1d3...)
  }
  object "commit" as vCommit {
    a7f3e21
  }
  object "branch" as vBranch {
    main @ a7f3e21
  }
  object "tag" as vTag {
    v1.0.0
  }
  object "remote" as vRemote {
    github.com:acmecorp/dashboard.git
  }
  object "tree" as vTree {
    e8f1...9d2a
  }
  object "submodule" as vSubmod {
    lib/shared
  }
}

acmeWtSrc ..> vDir
deploySrc ..> vDir
acmeGitSrc ..> vDir
upstreamSrc ..> vDir

acmeWtApp ..> vAppTs
deployApp ..> vAppTs
acmeGitApp ..> vAppTs
upstreamApp ..> vAppTs

acmeWtUtils ..> vUtilsTs
deployUtils ..> vUtilsTs
acmeGitUtils ..> vUtilsTs
upstreamUtils ..> vUtilsTs

acmeWtApi ..> vApiTs
deployApi ..> vApiTs
acmeGitApi ..> vApiTs
upstreamApi ..> vApiTs

note "NOT linked: develop:b2c4d8e:src/api.ts\n(different content on develop branch)" as N1

acmeCommit ..> vCommit
upstreamCommit ..> vCommit

acmeBranch ..> vBranch
upstreamBranch ..> vBranch

acmeTag ..> vTag
upstreamTag ..> vTag

acmeRemote ..> vRemote
upstreamRemote ..> vRemote

acmeTree ..> vTree
upstreamTree ..> vTree

acmeSubmod ..> vSubmod
@enduml
```

**How the `directory` virtual type works:**

The `directory` virtual resource for `src/` exists because the `src/` directory has identical recursive content across multiple physical locations. Its children include both `fs-directory` resources (physical directories on disk) and `git-tree` resources (tree objects in git's object database). The system detects directory equivalence by computing a Merkle hash over the sorted child content hashes. If someone adds a file to the deploy directory but not the git checkout's worktree, the Merkle hashes diverge, and `local/acme-deploy:src/` is unlinked from the `directory` virtual parent.

**How the `file` virtual type works:**

The `file` virtual type links physical resources that represent the same file — identical content bytes, filename, and permissions. It bridges across layers: an `fs-file` on disk and a `git-tree-entry` in git's tree are linked when they have matching content. This is the primary cross-layer bridge. When content diverges (e.g., an uncommitted edit), the virtual link is broken.

**How `commit` works across repos:**

When two `git` resources share history (e.g., a fork and its upstream), the same commit hash will appear in both repos' branches. The `commit` virtual type links these — the commit object `a7f3e21` in the local repo and `a7f3e21` in the upstream repo are the same commit, and the virtual parent captures this identity.

**Divergence scenario:**

If a developer edits `src/api.ts` in the deploy directory (`/opt/deploy/acme-dashboard/src/api.ts`), the system detects the content hash change and:

1. Unlinks `local/acme-deploy:src/api.ts` from `file: api.ts (sha256:e1d3...8a9b)` (content no longer matches).
2. Unlinks `local/acme-deploy:src/` from `directory: src/ (merkle:3d4f...a2b1)` (directory contents no longer identical — the Merkle hash has changed).
3. The git checkout's worktree files and git-tree-entry resources remain linked (their content hasn't changed).
4. If the edit makes the deploy file match some *other* known content hash, a new virtual link may be created.

Additional resource types (databases, APIs, cloud infrastructure, etc.) can be added as **custom resource types** via `agents resource type add`.

##### Custom Resource Types

Custom resource types are defined in YAML configuration files and registered via `agents resource type add`. Once registered, a custom type automatically becomes available as a new subcommand under `agents resource add`.

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># File: resource-types/database.yaml</span>
<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">&quot;3.0&quot;</span>

<span style="color: cyan; font-weight: 600;">resource_type</span>:
  <span style="color: cyan; font-weight: 600;">name</span>: local/database
  <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;A SQL database (PostgreSQL, MySQL, SQLite, etc.)&quot;</span>
  <span style="color: cyan; font-weight: 600;">physical_or_virtual</span>: physical
  <span style="color: cyan; font-weight: 600;">user_addable</span>: <span style="color: magenta; font-weight: 600;">true</span>

<span style="opacity: 0.7;">  # CLI arguments for `agents resource add local/database`</span>
  <span style="color: cyan; font-weight: 600;">cli_arguments</span>:
    - <span style="color: cyan;">name</span>: connection-string
      <span style="color: cyan; font-weight: 600;">type</span>: string
      <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">true</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Database connection string (e.g., postgresql://host/dbname)&quot;</span>
      <span style="color: cyan; font-weight: 600;">validation</span>:
        <span style="color: cyan; font-weight: 600;">pattern</span>: <span style="color: #66cc66;">&quot;^(postgresql|mysql|sqlite)://&quot;</span>
    - <span style="color: cyan;">name</span>: schema
      <span style="color: cyan; font-weight: 600;">type</span>: string
      <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Default schema to use&quot;</span>
    - <span style="color: cyan;">name</span>: read-only
      <span style="color: cyan; font-weight: 600;">type</span>: boolean
      <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
      <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: magenta; font-weight: 600;">false</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Whether the database should be treated as read-only&quot;</span>

<span style="opacity: 0.7;">  # Sandbox and handler</span>
  <span style="color: cyan; font-weight: 600;">sandbox_strategy</span>: transaction_rollback
  <span style="color: cyan; font-weight: 600;">handler</span>: DatabaseHandler
  <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">true</span>

<span style="opacity: 0.7;">  # Allowed parent types (empty means can be top-level)</span>
  <span style="color: cyan; font-weight: 600;">allowed_parent_types</span>: []

<span style="opacity: 0.7;">  # Child types</span>
  <span style="color: cyan; font-weight: 600;">child_types</span>:
    - <span style="color: cyan;">type</span>: local/db-schema
      <span style="color: cyan; font-weight: 600;">auto_discover</span>: <span style="color: magenta; font-weight: 600;">true</span>
      <span style="color: cyan; font-weight: 600;">manual_link</span>: <span style="color: magenta; font-weight: 600;">false</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Discovered database schemas&quot;</span>
    - <span style="color: cyan;">type</span>: local/db-table
      <span style="color: cyan; font-weight: 600;">auto_discover</span>: <span style="color: magenta; font-weight: 600;">true</span>
      <span style="color: cyan; font-weight: 600;">manual_link</span>: <span style="color: magenta; font-weight: 600;">false</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Discovered tables within schemas&quot;</span>

<span style="opacity: 0.7;">  # Capabilities</span>
  <span style="color: cyan; font-weight: 600;">capabilities</span>:
    <span style="color: cyan; font-weight: 600;">readable</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">writable</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">sandboxable</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">true</span>
</code></pre></div>

When this type is registered:
<div class="highlight"><pre><code>
agents resource type add <span style="color: cyan;">--config</span> ./resource-types/database.yaml
<span style="opacity: 0.7;"># Now available: agents resource add local/database &lt;NAME&gt; --connection-string CONN [--schema SCHEMA] [--read-only]</span>
</code></pre></div>

The `user_addable` field determines whether the type appears as a subcommand. Types with `user_addable: false` are only auto-generated as children — for example, `git-remote`, `git-branch`, `git-commit`, and `git-tree-entry` are never created directly by users but are discovered when a `git` (or `git-checkout`) resource is registered.

#### The Resource DAG

Resources form a **directed acyclic graph** (DAG), not a simple tree. A resource can have **multiple parents** and **multiple children**, subject to type constraints. The diagram below shows how a `git-checkout`, a standalone `git` repo (remote), a standalone `fs-directory`, and virtual resources interconnect:

```kroki-plantuml
@startuml
skinparam defaultFontSize 10
skinparam objectFontSize 10
skinparam packageStyle rectangle

package "GIT-CHECKOUT: local/app" as GCO #LightBlue {
  object "git-checkout" as gco {
    local/app
  }
  object "git" as gcoGit {
    local/app:repo
  }
  object "git-remote" as gcoRemote {
    origin
  }
  object "git-tag" as gcoTag {
    v1.0.0
  }
  object "git-branch" as gcoBranch {
    main
  }
  object "git-commit" as gcoCommit {
    a1b2c3d
  }
  object "git-tree" as gcoTree {
    e8f1... root
  }
  object "git-tree-entry" as gcoEntry1 {
    README.md
  }
  object "git-tree" as gcoSubtree {
    src/
  }
  object "git-tree-entry" as gcoEntry2 {
    src/app.ts
  }
  object "git-tree-entry" as gcoEntry3 {
    src/main.ts
  }
  object "fs-directory" as gcoFs {
    local/app:worktree
  }
  object "fs-directory" as gcoSrcDir {
    src/
  }
  object "fs-file" as gcoReadme {
    README.md
  }
  object "fs-file" as gcoApp {
    app.ts
  }
  object "fs-file" as gcoMain {
    main.ts
  }
}

package "GIT (remote): local/upstream" as GR #LightYellow {
  object "git" as gr {
    local/upstream
  }
  object "git-remote" as grRemote {
    origin
  }
  object "git-tag" as grTag {
    v1.0.0
  }
  object "git-branch" as grBranch {
    main
  }
  object "git-commit" as grCommit {
    a1b2c3d
  }
  object "git-tree" as grTree {
    e8f1... root
  }
  object "git-tree-entry" as grEntry1 {
    README.md
  }
  object "git-tree" as grSubtree {
    src/
  }
  object "git-tree-entry" as grEntry2 {
    src/app.ts
  }
  object "git-tree-entry" as grEntry3 {
    src/main.ts
  }
}

package "STANDALONE FS-DIRECTORY: local/deploy" as SFD #LightGreen {
  object "fs-directory" as sfd {
    /opt/deploy/myapp
  }
  object "fs-directory" as sfdSrcDir {
    src/
  }
  object "fs-file" as sfdReadme {
    README.md
  }
  object "fs-file" as sfdApp {
    app.ts
  }
  object "fs-file" as sfdMain {
    main.ts
  }
}

package "VIRTUAL LAYER" as VL #Lavender {
  object "file" as vFile {
    app.ts@v1
  }
  object "directory" as vDir {
    src/@v1
  }
  object "commit" as vCommit {
    a1b2c3d
  }
  object "branch" as vBranch {
    main@a1b...
  }
  object "tag" as vTag {
    v1.0.0
  }
  object "remote" as vRemote {
    github.com/org/repo
  }
  object "tree" as vTree {
    e8f1...9d2a
  }
}

' Physical hierarchy
gco --> gcoGit
gco --> gcoFs
gcoGit --> gcoRemote
gcoGit --> gcoTag
gcoGit --> gcoBranch
gcoBranch --> gcoCommit
gcoCommit --> gcoTree
gcoTree --> gcoEntry1
gcoTree --> gcoSubtree
gcoSubtree --> gcoEntry2
gcoSubtree --> gcoEntry3
gcoFs --> gcoSrcDir
gcoFs --> gcoReadme
gcoSrcDir --> gcoApp
gcoSrcDir --> gcoMain

gr --> grRemote
gr --> grTag
gr --> grBranch
grBranch --> grCommit
grCommit --> grTree
grTree --> grEntry1
grTree --> grSubtree
grSubtree --> grEntry2
grSubtree --> grEntry3

sfd --> sfdSrcDir
sfd --> sfdReadme
sfdSrcDir --> sfdApp
sfdSrcDir --> sfdMain

' Virtual equivalence links
gcoApp ..> vFile
sfdApp ..> vFile
gcoEntry2 ..> vFile
grEntry2 ..> vFile
gcoSrcDir ..> vDir
sfdSrcDir ..> vDir
gcoSubtree ..> vDir
grSubtree ..> vDir
gcoCommit ..> vCommit
grCommit ..> vCommit
gcoBranch ..> vBranch
grBranch ..> vBranch
gcoTag ..> vTag
grTag ..> vTag
gcoRemote ..> vRemote
grRemote ..> vRemote
gcoTree ..> vTree
grTree ..> vTree
@enduml
```

**Key properties of the DAG:**

1. **Multiple parents**: A `git-tree-entry` has a `git-tree` parent (git structure) and potentially a `file` virtual parent (content identity). An `fs-file` has an `fs-directory` parent (filesystem hierarchy) and potentially a `file` virtual parent. An `fs-directory` can be a child of `git-checkout` (as its worktree root), a child of `fs-mount` (as the mount root), a child of another `fs-directory` (as a subdirectory), a child of a `directory` virtual (identity), or a standalone user-registered resource.
2. **Multiple children**: A `git-checkout` has a `git` child and an `fs-directory` child. A `git` resource has `git-remote`, `git-branch`, `git-tag`, `git-stash`, `git-submodule`, and `git-commit` children. A `git-commit` has a `git-tree` child. A `git-tree` has `git-tree-entry` and nested `git-tree` children.
3. **Cycles are forbidden**: The graph is always a DAG. The system validates this when links are created.
4. **Type constraints**: Not any resource can be a child of any other — the parent's resource type defines which child types are allowed (see the Allowed Parents / Allowed Children columns in the built-in types tables).
5. **Cross-layer bridge**: Virtual resources link equivalent physical resources from different layers (git structure, filesystem, different repos). The `file` virtual type bridges `fs-file` + `git-tree-entry`. The `directory` virtual type bridges `fs-directory` + `git-tree`. The `commit`, `branch`, `tag`, `remote`, `submodule`, and `tree` virtual types link the same git structural element across different repositories.

#### Physical vs Virtual Resources

Resources are either **physical** or **virtual**, a distinction determined by their resource type.

**Physical resources** are specific, concrete manifestations. Each physical resource is a particular instance that exists somewhere — a file at a particular path on a particular machine, a git repository at a particular URL on a particular server, a commit in a particular repo. Physical resources can be directly read and written by tools. Most resources are physical.

**Virtual resources** represent an abstract identity that links equivalent physical resources. They answer the question: "where else does this same thing exist?" A `file` virtual resource links all the physical `fs-file` and `git-tree-entry` resources that have the same content, filename, and permissions. A `commit` virtual resource links `git-commit` resources across repos that share the same commit hash. Virtual resources have no location of their own and cannot be directly read or written.

**Rules for the physical/virtual boundary:**

1. The **children of a virtual resource** can be physical resources, other virtual resources, or a combination of both.
2. A **physical resource's parents** can be either physical or virtual resources.
3. **Not all physical resources need a virtual parent**. Virtual resource linking is optional and only applies when equivalence tracking is meaningful.

**Equivalence linking:**

Two physical resources share a virtual parent when they are equivalent by the virtual type's criteria. Each virtual type has its own equivalence semantics:

* **`file`**: Physical files (`fs-file` or `git-tree-entry`) share a `file` parent when they have the same content bytes (SHA-256), the same filename, and the same permissions. This is the primary cross-layer bridge — it links filesystem files with git blob entries. Example: `local/app:worktree:src/main.py` (an `fs-file`) and `local/app:repo:main:a1b...:src/main.py` (a `git-tree-entry`) both have the same content in a clean checkout, so they share a `file` virtual parent.

* **`directory`**: Physical directories (`fs-directory`) and git trees (`git-tree`) share a `directory` parent when their full recursive contents are equivalent. This bridges the filesystem and git layers — the `src/` directory on disk and the `src/` subtree in git's tree object can be linked when their contents match.

* **`symlink`**: Physical symlinks (`fs-symlink`) and git tree entries with symlink mode (`git-tree-entry` mode 120000) share a `symlink` parent when they have the same name and target.

* **`commit`**: Physical commits (`git-commit`) in different repos share a `commit` parent when they have the same commit hash. This is common when repos share history (e.g., a fork and its upstream).

* **`branch`**: Physical branches (`git-branch`) in different repos share a `branch` parent when they have the same name and the same HEAD commit hash. A push or local commit on one repo causes divergence.

* **`tag`**: Physical tags (`git-tag`) in different repos share a `tag` parent when they have the same tag name and target object.

* **`remote`**: Physical remotes (`git-remote`) in different repos share a `remote` parent when they point to the same URL. Answers: "these repos share the same upstream."

* **`submodule`**: Physical submodules (`git-submodule`) in different repos share a `submodule` parent when they have the same submodule URL and path.

* **`tree`**: Physical tree objects (`git-tree`) in different commits or repos share a `tree` parent when they have the same tree hash — identical directory structure and contents.

**Divergence detection:**

When a physical resource's content changes (e.g., a file is edited, a directory gains a new file, a branch advances), the system detects that it may no longer match its virtual parent's identity. At that point:

* If the edit causes the physical resource to diverge from all other physical siblings under the same virtual parent, the physical resource is unlinked from that virtual parent.
* If the edit makes it match a *different* virtual resource's identity, it may be re-linked.
* Content equivalence is tracked via content hashing: SHA-256 for files, Merkle hashes for directories, tree hashes for git trees, commit hashes for commits, HEAD+name for branches, name+target for tags, URL for remotes.
* **Cascading divergence**: When a `file` link breaks, the parent `directory` virtual resource is also re-evaluated (since its identity depends on all child identities).

This enables powerful queries like:

* "What physical locations exist for this file content?" → Find all physical resources sharing the `file` virtual parent.
* "What tools can edit this file?" → Find all tools with resource bindings compatible with the physical resource types.
* "Has this file been modified in any location?" → Check if all physical siblings still share the same `file` virtual parent.
* "Are these two repos in sync?" → Check if their branches share a `branch` virtual parent.
* "Which directories are identical across deployments?" → Find `directory` virtual resources with multiple physical children.
* "What submodules are shared across projects?" → Find `submodule` virtual resources with multiple physical children.

#### Resource Registration (CLI)

Resources are created via `agents resource add <type>` with type-specific arguments. Auto-discovered children are created automatically:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Register a checked-out git repository (most common)</span>
agents resource add git-checkout local/api-repo <span style="color: cyan;">--path</span> /home/user/projects/api-service <span style="color: cyan;">--branch</span> main
<span style="opacity: 0.7;"># Auto-discovers: git child (repo metadata, remotes, branches, commits, tree entries)</span>
<span style="opacity: 0.7;">#                 + fs-directory child (worktree root directory, subdirectories, files)</span>

<span style="opacity: 0.7;"># Register a git repo via remote URL (no local checkout — exists on remote server)</span>
agents resource add git local/upstream <span style="color: cyan;">--url</span> git@github.com:org/upstream.git
<span style="opacity: 0.7;"># Auto-discovers: remotes, branches, tags, commits, trees, tree entries, stashes, submodules</span>
<span style="opacity: 0.7;">#                 (no fs-directory — not checked out locally)</span>

<span style="opacity: 0.7;"># Register a standalone directory (not a git repo — just files on disk)</span>
agents resource add fs-directory local/docs <span style="color: cyan;">--path</span> /opt/docs/api-reference
<span style="opacity: 0.7;"># Auto-discovers: subdirectories, files, symlinks, hardlinks</span>

<span style="opacity: 0.7;"># Register a standalone filesystem mount (entire volume)</span>
agents resource add fs-mount local/data-volume <span style="color: cyan;">--mount-path</span> /mnt/data
<span style="opacity: 0.7;"># Auto-discovers: root fs-directory, subdirectories, files, symlinks, hardlinks</span>

<span style="opacity: 0.7;"># Link resources to projects (resources must be registered first)</span>
agents project link-resource local/api-service local/api-repo
agents project link-resource local/api-service local/docs <span style="color: cyan;">--read-only</span>
</code></pre></div>

#### Auto-Discovery

When a resource is registered, its resource type's handler **auto-discovers child resources**. This process:

1. **Scans** the resource to identify children (e.g., a `git-checkout` handler creates a `git` child and an `fs-directory` child for the worktree root; a `git` handler lists remotes, branches, tags, commits, stashes, and submodules; a `git-commit` handler creates a root `git-tree` child; a `git-tree` handler lists tree entries and subtrees; an `fs-mount` handler creates a root `fs-directory` and discovers its contents; an `fs-directory` handler discovers subdirectories, files, symlinks, and hardlinks).
2. **Creates** child resource records in the Resource Registry identified by auto-generated ULIDs. Auto-discovered children do not receive names — they are identified by ULID only, even if their resource type is user-addable.
3. **Reuses existing resources**: If a discovered child matches an already-registered resource (same type + same value/location), the existing resource is **linked** as a child rather than creating a duplicate. For example, if `local/docs` (an `fs-directory` resource at `/home/user/projects/api-service`) is already registered and the `git-checkout` handler discovers its worktree root at the same path, it links to the existing `local/docs` resource instead of creating a new one.
4. **Links virtual resources**: When auto-discovery detects that a physical resource's content matches an existing virtual resource (via content hashing), it links the physical resource as a child of the virtual resource.

Auto-discovered children are marked as `auto: true` in the DAG, distinguishing them from manually linked children. Auto-discovered links cannot be manually unlinked (they are managed by the handler), while manually created links can be freely managed.

Auto-discovery runs:
* At registration time (`agents resource add`)
* On refresh (when the system detects changes, e.g., new commits, new files)
* On demand (when a tool accesses the resource and the handler detects staleness)

#### Resource Capabilities

Each resource declares its capabilities, derived from its resource type:

| Capability | Description |
|-----------|-------------|
| `readable` | Whether the resource can be read |
| `writable` | Whether the resource can be modified |
| `sandboxable` | Whether the resource supports sandbox isolation |
| `checkpointable` | Whether the resource supports checkpoint/rollback |

These capabilities are used by the **tool execution flow** to validate that a tool's resource binding is compatible — a tool declaring `access: read_write` on a resource slot cannot be bound to a read-only resource.

#### Resource Registry

CleverAgents maintains a **Resource Registry** — a persistent catalog of all registered resources and their DAG relationships:

```kroki-plantuml
@startuml
skinparam classAttributeIconSize 0
skinparam classFontSize 13
skinparam defaultFontSize 12

class ResourceRegistry {
  - resourceIndex : Map<String, ResourceRecord>
  - typeIndex : Map<String, ResourceTypeRecord>
  --
  + add(type, name, properties) : ResourceRecord
  + update(name, properties) : ResourceRecord
  + remove(name) : void
  + lookup(name) : ResourceRecord
  + list(filters) : ResourceRecord[]
  + tree(name, depth) : DAG_subtree
  + link_child(parent, child) : void
  + unlink_child(parent, child) : void
  + refresh(name) : void
  + find_by_content(hash) : ResourceRecord[]
  + find_virtual_parent(resource) : ResourceRecord
}

class ResourceRecord {
  + name : String
  + type : String
  + physical_or_virtual : PhysVirt
  + properties : Map<String, Object>
  + capabilities : Capabilities
  + parents : List<ResourceRecord>
  + children : List<ResourceRecord>
  + content_hash : String
  + linked_projects : List<String>
  + created_at : DateTime
  + updated_at : DateTime
}

class ResourceTypeRecord {
  + name : String
  + description : String
  + source : String
  + physical_or_virtual : PhysVirt
  + user_addable : Boolean
  + cli_arguments : List<CLIArgument>
  + allowed_parent_types : List<String>
  + child_types : Map<String, ChildTypeConfig>
  + sandbox_strategy : String
  + handler : String
  + capabilities : Capabilities
  + config_path : String
}

enum PhysVirt {
  physical
  virtual
}

ResourceRegistry "1" *-- "0..*" ResourceRecord : indexes resources >
ResourceRegistry "1" *-- "0..*" ResourceTypeRecord : indexes types >
ResourceRecord --> PhysVirt
ResourceTypeRecord --> PhysVirt

note right of ResourceRegistry
  **Populated by:**
  - agents resource add CLI
  - Auto-discovery during registration
  - Content-identity linking

  **Consumed by:**
  - Tool binding resolution
  - Sandbox creation
  - Change tracking
  - Project linking
  - Plan validation
end note
@enduml
```

The Resource Registry persists in the database (local SQLite or server). It works alongside the Tool Registry and Skill Registry.

#### Resource Sandbox Strategy

**Each resource defines its own sandbox strategy**, determined by its resource type. This is critical because:

1. The same resource may be accessed through different tools and skills
2. Different resource types require different sandboxing approaches
3. Some resources cannot be sandboxed at all

| Resource Type | Sandbox Strategy | Rollback Mechanism |
|--------------|------------------|-------------------|
| `git-checkout` | `git_worktree` | Git reset/checkout |
| `git` | `none` | N/A (represents a repo instance — not directly sandboxable) |
| `fs-mount` | `copy_on_write` or `overlay` | Restore from snapshot |
| `fs-directory` | `copy_on_write` | Restore from snapshot |
| Custom database types | `transaction_rollback` | Transaction rollback |
| Custom API types | `none` (often not sandboxable) | N/A |

The sandbox strategy is inherited by child resources from their parent unless the child type defines its own. For example, `git-branch`, `git-commit`, `git-tree`, and `git-tree-entry` all inherit from their `git` ancestor. `fs-file`, `fs-symlink`, and `fs-hardlink` inherit from their `fs-directory` parent.

#### Lazy Sandboxing

Resources are **sandboxed lazily when accessed**, not upfront. This is different from indexing — resources are indexed immediately when registered, but sandboxes are only created when execution needs to modify a resource:

1. A project may link many resources (e.g., git repo + databases + cloud accounts)
2. A plan may only need to modify one resource
3. Only the accessed resources are sandboxed
4. Each plan/child plan has its own sandbox containing only edited resources

This is efficient for large projects where most resources remain untouched.

#### Resource Access Tracking

The system tracks **which tools access which resources** through the tool-resource binding system. This tracking happens at multiple levels:

1. **Declaration-time**: Tool YAML declares resource slots with type and access mode (see **Resource Bindings** in the Tools section).
2. **Activation-time**: When a tool is activated for a plan, its resource slots are bound to specific resources. The system records these bindings.
3. **Execution-time**: Every tool invocation logs which bound resources were actually accessed, what operations were performed (read/write/delete), and what paths or objects were touched.

This enables:

* **Accurate sandbox scoping**: Only sandbox resources that will actually be modified.
* **Rollback feasibility analysis**: Know exactly which resources were modified and whether they support rollback.
* **Security auditing**: Complete record of which tools accessed which resources and how.
* **Cross-resource impact analysis**: Determine if changes to a resource affect tools bound to sibling or child resources.
* **Virtual resource consistency**: Detect when a physical resource diverges from its virtual parent.

#### Unified Resource Abstraction Layer

CleverAgents provides a unified abstraction that allows tools to work with any resource type through a consistent interface. This enables:

1. **Resource-agnostic tools**: A tool like `read_content(path)` works whether the path refers to a file, database record, or API endpoint.
2. **Consistent sandbox semantics**: All resources support the same sandbox lifecycle (create, read, write, checkpoint, rollback).
3. **Pluggable resource handlers**: New resource types can be added by registering custom resource types without modifying existing tools.
4. **Unified change tracking**: All resource modifications flow into the same ChangeSet model.

##### Resource Handler Interface

Every resource type provides a handler that implements this interface:

<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">ResourceHandler</span>(<span style="color: cyan;">Protocol</span>):
    <span style="color: #66cc66;">&quot;&quot;&quot;Handler for a specific resource type.&quot;&quot;&quot;</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">read</span>(self, path: <span style="color: cyan;">str</span>, sandbox: Sandbox) -&gt; Content:
        <span style="color: #66cc66;">&quot;&quot;&quot;Read content from the sandboxed resource.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">write</span>(self, path: <span style="color: cyan;">str</span>, content: Content, sandbox: Sandbox) -&gt; Change:
        <span style="color: #66cc66;">&quot;&quot;&quot;Write content and return the Change record.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">delete</span>(self, path: <span style="color: cyan;">str</span>, sandbox: Sandbox) -&gt; Change:
        <span style="color: #66cc66;">&quot;&quot;&quot;Delete resource and return the Change record.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;"><span style="color: cyan;">list</span></span>(self, pattern: <span style="color: cyan;">str</span>, sandbox: Sandbox) -&gt; <span style="color: cyan;">list</span>[<span style="color: cyan;">str</span>]:
        <span style="color: #66cc66;">&quot;&quot;&quot;List paths matching pattern.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">diff</span>(self, path: <span style="color: cyan;">str</span>, sandbox: Sandbox) -&gt; <span style="color: cyan;">str</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Generate diff between sandbox and original state.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">supports_operation</span>(self, operation: OperationType) -&gt; <span style="color: cyan;">bool</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Check if this resource supports the given operation.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">discover_children</span>(self, resource: ResourceRecord) -&gt; <span style="color: cyan;">list</span>[ResourceRecord]:
        <span style="color: #66cc66;">&quot;&quot;&quot;Auto-discover child resources (called at registration and refresh).&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">content_hash</span>(self, path: <span style="color: cyan;">str</span>, sandbox: Sandbox) -&gt; <span style="color: cyan;">str</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Compute content hash for identity tracking.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">create_sandbox</span>(self, resource: ResourceRecord) -&gt; Sandbox:
        <span style="color: #66cc66;">&quot;&quot;&quot;Create a sandbox for this resource using its type&#x27;s strategy.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">create_checkpoint</span>(self, sandbox: Sandbox) -&gt; Checkpoint:
        <span style="color: #66cc66;">&quot;&quot;&quot;Create a checkpoint within the sandbox.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">rollback_to</span>(self, sandbox: Sandbox, checkpoint: Checkpoint) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Roll back sandbox state to a checkpoint.&quot;&quot;&quot;</span>
        ...
</code></pre></div>

##### Built-in Resource Handlers

| Resource Type | Handler | Read | Write | Delete | Sandbox Strategy |
|--------------|---------|------|-------|--------|------------------|
| `git-checkout` | `GitCheckoutHandler` | ✓ | ✓ | ✓ | `git_worktree` |
| `git` | `GitHandler` | ✓ | ✗ | ✗ | `none` |
| `git-commit`, `git-tree`, `git-tree-entry` | `GitObjectHandler` | ✓ | ✗ | ✗ | (inherits) |
| `git-branch`, `git-tag`, `git-stash` | `GitRefHandler` | ✓ | ✓ | ✓ | (inherits) |
| `git-remote`, `git-submodule` | `GitConfigHandler` | ✓ | ✗ | ✗ | (inherits) |
| `fs-mount` | `FilesystemHandler` | ✓ | ✓ | ✓ | `copy_on_write` |
| `fs-directory` | `FilesystemHandler` | ✓ | ✓ | ✓ | `copy_on_write` |
| `fs-file`, `fs-symlink`, `fs-hardlink` | `FilesystemHandler` | ✓ | ✓ | ✓ | (inherits) |

Additional handlers are provided by custom resource types when they are registered.

##### Resource Path Resolution

Paths in tool invocations are resolved through a resource routing system that uses tool-resource bindings to determine the target resource:

```kroki-mermaid
sequenceDiagram
    participant Tool as Tool Invocation
    participant Router as Resource Router
    participant Handler as GitCheckoutHandler

    Tool->>Router: edit_file(path='src/main.py', ...)
    Router->>Router: Check tool's resource bindings
    Note right of Router: slot 'repo' bound to<br/>local/api-repo (git-checkout)
    Router->>Router: Resolve path within bound resource
    Note right of Router: local/api-repo:worktree:src/main.py
    Router->>Handler: Route to resource handler
    Handler->>Handler: Resolve path to sandbox worktree
    Handler->>Handler: Operate on sandboxed state
    Handler-->>Tool: Return Change record
```

When a tool has multiple resource slots bound, the path scheme or slot name disambiguates:

<div class="highlight"><pre><code>
# Explicit slot reference
path://repo/src/main.py      → routes to the &quot;repo&quot; slot&#x27;s bound resource
path://docs/api/readme.md    → routes to the &quot;docs&quot; slot&#x27;s bound resource

# Default: unqualified paths route to the tool&#x27;s primary resource slot
src/main.py                  → routes to the first (or only) resource slot
</code></pre></div>



### Context

The Advanced Context Management System (ACMS) is CleverAgents' fully pluggable, strategy-driven framework for assembling context for actors. It replaces and subsumes the basic context tier system with a comprehensive architecture built around three core innovations:

1. **A Universal Knowledge Ontology (UKO)** -- an inheritance-based RDF ontology hierarchy that represents *any* resource (source code, documents, databases, infrastructure) at multiple levels of abstraction, with full provenance back to the originating resource and temporal versioning across revisions.

2. **A Context Request Protocol (CRP)** -- a structured vocabulary through which actors (via skills) declare what information they need, at what level of detail, and with what scope, while they are reasoning. This replaces static "context view" approaches with a dynamic, demand-driven model.

3. **A Pluggable Strategy Framework** with a **Fusion Coordinator** -- multiple independent context strategies can be registered, each working with different data backends and different abstraction levels of the UKO. A coordinator merges their contributions into a single, budget-respecting, deduplicated context payload.

The system is designed around the hierarchical nature of plans: parent plans see wide, shallow context (breadth); child plans see narrow, deep context (depth). Context inheritance flows parent-to-child with progressive focusing, and every context assembly respects a dynamically-changing token budget.

**Critical Design Decision**: All indexing happens immediately when resources are added to projects or when code changes. There is no "on-demand" indexing during agent execution. This ensures that agents always have instant access to search capabilities without any indexing delays. The computational cost is paid once upfront, not repeatedly during agent operations.

> The full architectural design of the ACMS -- including the UKO ontology hierarchy, backend abstraction layer, strategy coordinator internals, fusion engine, index synchronization, performance characteristics, and plugin architecture -- is specified in the **Architecture > ACMS Architecture** section.

#### Core Data Types

The ACMS defines several data types that are used throughout the system by actors, skills, strategies, and the plan lifecycle.

##### DetailLevel

```python
class DetailLevel(Enum):
    """How much content to include for each item in context."""
    SIGNATURE = "signature"   # Declarations only (name, type, parameters)
    SUMMARY   = "summary"     # LLM-generated or docstring condensation
    STUB      = "stub"        # Signatures + key logic (control flow, returns)
    FULL      = "full"        # Complete source content
```

##### ContextRequest

A structured request for context, issued by an actor or skill via the CRP.

```python
@dataclass
class ContextRequest:
    """A structured request for context, issued by an actor or skill."""

    # === What to find ===
    query: str | None = None          # Natural language query
    entities: list[str] = field(default_factory=list)  # Named entities to focus on
    uko_types: list[str] = field(default_factory=list)  # UKO types to filter

    # === Scope control ===
    focus: list[str] = field(default_factory=list)
    # URIs or identifiers of specific items to focus on

    breadth: int = 2
    # How many hops outward in the dependency/reference graph.

    depth: DetailLevel = DetailLevel.SUMMARY
    # How much detail to include for each item found.

    # === Focus depth gradient ===
    depth_gradient: bool = True
    # When True, items closer to the focus get more detail.

    # === Temporal scope ===
    temporal: TemporalScope = TemporalScope.CURRENT

    # === Budget ===
    max_tokens: int | None = None

    # === Strategy hints ===
    preferred_strategies: list[str] = field(default_factory=list)
    required_backends: list[str] = field(default_factory=list)

    # === Priority and purpose ===
    priority: float = 0.5           # 0.0 = background, 1.0 = critical
    purpose: str = ""               # Why is this context needed?
```

##### ContextFragment

The atomic unit of context returned by strategies and consumed by the Fusion Engine.

```python
@dataclass
class ContextFragment:
    """A single piece of context assembled by a strategy."""
    uko_node: str                     # UKO URI of the source node
    content: str                      # Rendered text content
    detail_level: DetailLevel         # Level of detail in this fragment
    token_count: int                  # Token count of content
    relevance_score: float            # 0.0-1.0 relevance to the request
    provenance: FragmentProvenance     # Trace back to resource + location
    metadata: dict = field(default_factory=dict)
```

##### AssembledContext

The output of a context assembly cycle -- the final, budget-respecting payload delivered to an actor.

```python
@dataclass
class AssembledContext:
    """The fused, budget-respecting context payload."""
    fragments: list[ContextFragment]   # Ordered context fragments
    total_tokens: int                  # Total token count
    budget_used: float                 # Fraction of budget consumed (0.0-1.0)
    strategies_used: list[str]         # Which strategies contributed
    context_hash: str                  # Cryptographic hash for snapshot
    preamble: str | None               # Optional structure summary
    provenance_map: dict               # Fragment -> resource/location mapping
```

#### Context Request Protocol (CRP)

Instead of static context views, actors (through their skills) **actively request** context as they reason. The CRP defines a structured vocabulary for these requests.

This is fundamentally different from existing approaches where context is assembled once before the actor runs. With CRP:

1. The actor starts with an **initial context** (assembled from the plan's context view, parent context inheritance, and strategy defaults).
2. As the actor reasons, skills can issue **refinement requests** to pull in additional context dynamically.
3. Each request triggers a new context assembly cycle with the remaining token budget.

##### The `builtin/context` Skill

Actors issue context requests through a **context skill** that is automatically injected into every actor's skill set:

```yaml
# Built-in skill, always available
skill:
  name: builtin/context
  description: "Request additional context during reasoning"

  anonymous_tools:
    - name: request_context
      description: "Request specific context to be added to the conversation"
      input_schema:
        type: object
        properties:
          query: { type: string, description: "What information do you need?" }
          focus: { type: array, items: { type: string },
                   description: "Specific files, classes, or functions to focus on" }
          breadth: { type: integer, default: 2,
                     description: "How many dependency hops outward (0-5)" }
          depth: { type: string, enum: ["signature", "summary", "stub", "full"],
                   default: "summary",
                   description: "How much detail for each item" }
          purpose: { type: string, description: "Why do you need this context?" }
        required: [purpose]

    - name: query_history
      description: "Query historical context about past decisions and changes"
      input_schema:
        type: object
        properties:
          query: { type: string }
          scope: { type: string, enum: ["current_plan", "plan_tree", "all_plans"],
                   default: "plan_tree" }
        required: [query]

    - name: get_context_budget
      description: "Check remaining context token budget"
      input_schema:
        type: object
        properties: {}
```

#### Context Strategy Protocol

Every context strategy implements this protocol. Strategies are pluggable -- built-in strategies ship with CleverAgents, and custom strategies can be registered via configuration.

```python
@runtime_checkable
class ContextStrategy(Protocol):
    """A pluggable context assembly strategy."""

    @property
    def name(self) -> str: ...

    @property
    def capabilities(self) -> StrategyCapabilities: ...

    def can_handle(self, request: ContextRequest,
                   backends: BackendSet) -> float:
        """Returns 0.0-1.0 confidence that this strategy can usefully
        contribute to this request."""
        ...

    def assemble(self, request: ContextRequest,
                 backends: BackendSet,
                 budget: int,
                 plan_context: PlanContext) -> list[ContextFragment]:
        """Execute the strategy. Must respect the budget."""
        ...

    def explain(self) -> str: ...
```

```python
@dataclass
class StrategyCapabilities:
    """Declares what a strategy is capable of."""
    uses_text: bool = False
    uses_vector: bool = False
    uses_graph: bool = False
    uses_temporal: bool = False
    uko_levels: list[str] = field(default_factory=list)
    resource_types: list[str] = field(default_factory=list)
    supports_depth_breadth: bool = False
    supports_plan_hierarchy: bool = False
    supports_temporal: bool = False
    quality_score: float = 0.5
```

##### Built-in Strategies

| Strategy | Quality | Backends Required | Description |
|----------|---------|------------------|-------------|
| `simple-keyword` | 0.3 | Text only | Basic keyword/regex text search. Universal fallback. |
| `semantic-embedding` | 0.6 | Vector | Vector similarity search for semantically related content. |
| `breadth-depth-navigator` | 0.85 | Graph | Graph-aware UKO traversal with depth/breadth projection. Primary strategy for code-aware context. |
| `arce` | 0.95 | All | Multi-modal pipeline combining text, vector, and graph with intent analysis. Highest quality. |
| `temporal-archaeology` | 0.5 | Graph + Cold tier | Historical pattern discovery from past decisions and archived context. |
| `plan-decision-context` | 0.7 | Warm/Cold tiers | Retrieves context from parent/ancestor plan decisions. |

##### Strategy Registration

Strategies are registered through configuration:

```toml
[context.strategies]
enabled = ["simple-keyword", "semantic-embedding", "arce", "breadth-depth-navigator"]

[context.strategies.custom]
"my-domain-strategy" = "my_package.strategies.DomainStrategy"
```

#### Hierarchical Plan Context

In a plan hierarchy, each level sees a different slice of the codebase. Context inheritance flows parent-to-child with progressive focusing:

| Level | Breadth | Depth | Example Content |
|-------|---------|-------|-----------------|
| Root | Entire project | SIGNATURE | Module names, class headers, dependency map |
| Subplan A | `src/auth/` module + direct deps | SUMMARY | Function signatures with descriptions, key type definitions |
| Sub-subplan A1 | `AuthManager` class + 2-hop deps | FULL | Complete function bodies, all parameters, all call sites |

The **skeleton** is a compact, SIGNATURE-level representation of the parent's context window that is passed to every child. This ensures children always have the "big picture" available, even though they focus on a narrow area. The skeleton typically consumes 5-15% of the child's token budget (controlled by `skeleton_ratio`).

#### Depth/Breadth Projection

The depth/breadth projection system allows fine-grained control over how much of the knowledge graph is materialized into context. It operates on the UKO graph structure.

- **Breadth** (integer, 0-N): How many hops in the `uko:references` / `uko:dependsOn` / `uko:contains^-1` graph to traverse from the focus items.
- **Depth** (DetailLevel): How much content to include for each item found.
- **Depth gradient**: When enabled, detail decreases with distance from focus.

```
Request: focus=["class://AuthManager"], breadth=2, depth=FULL, gradient=True

Result (token costs approximate):

Distance 0 (FULL detail):
  class AuthManager:                               # 800 tokens
      """Manages user authentication..."""
      def authenticate(self, username, password):
          ...full body...
      def validate_token(self, token):
          ...full body...

Distance 1 (STUB detail):
  class BaseManager:                               # 120 tokens
      def connect(self) -> Connection: ...
      def disconnect(self) -> None: ...
  class CryptoUtils:                               # 80 tokens
      def hash_password(pwd: str) -> str: ...
      def verify_hash(pwd: str, hash: str) -> bool: ...
  class UserDB:                                    # 100 tokens
      def find_user(username: str) -> User | None: ...
      def create_user(user: User) -> None: ...

Distance 2 (SIGNATURE detail):
  class Connection                                 # 20 tokens
  class User                                       # 15 tokens
  class DatabasePool                               # 15 tokens

Total: ~1,150 tokens (vs ~15,000 if everything were FULL)
```

#### Integration with Plan Lifecycle

```
Plan Lifecycle                        ACMS Actions
─────────────────                     ────────────────────────────
Plan created (agents plan use)        ResourceScope resolved.
                                      ScopedBackendViews created.

Strategize phase begins               InitialContextAssembler runs:
                                        - Inherits parent context (if subplan)
                                        - Runs StrategyCoordinator
                                        - Produces AssembledContext
                                        - Injects into actor's system prompt

Strategy actor reasons                 Actor may issue ContextRequests via
                                       builtin/context skill.
                                       Each request triggers re-assembly
                                       with remaining budget.

Strategy actor produces decisions      Each Decision's context_snapshot
                                       captures AssembledContext hash +
                                       provenance map.

Execute phase begins                   New InitialContextAssembler run
                                       with execute-phase view.
                                       Decisions from Strategize are in
                                       warm tier.

Execution actor works                  Dynamic ContextRequests as needed.

Subplan spawned                        PlanContextInheritance computes
                                       child context from parent.
                                       Skeleton propagation.
                                       New ResourceScope (possibly narrower).

Apply phase                            Minimal context assembly
                                       (validation results, diff summary).

Plan completes                         Hot context archived to warm.
                                       Warm context ages to cold based
                                       on retention policy.
```

### Output Rendering Framework

#### Overview

CleverAgents uses a unified **Output Rendering Framework** to decouple command output data from its visual presentation. Every CLI command produces structured output through a common abstraction layer, and the active **format** determines how that output is rendered to the terminal (or piped to external consumers). The format is set via the global `--format` flag, the `format` config key, or defaults to `rich`.

The framework is **reactive-first**: commands do not build a static data structure and hand it to a renderer. Instead, commands open an **output session**, create **element handles** for each piece of output (a panel, a table, a progress indicator), and write data to those handles — potentially from multiple concurrent producers. The session coordinates with a **materialization strategy** selected by the active format, which decides *when* and *how* each element's content reaches the terminal. A `rich` session renders updates in-place as they arrive; a `plain` session buffers each element and flushes sequentially; a `json` session accumulates everything and serializes once at the end. **Producer code is format-agnostic** — it writes to handles without knowing which format is active.

This architecture is designed for modularity, extensibility, and future-proofing — the same session-based output can be consumed by the CLI, a future TUI, a web frontend, or programmatic integrations. The design uses a pipeline of composable stages: **session lifecycle management**, **typed element handles**, **event-driven materialization**, and **format-specific element rendering**.

#### Architecture

##### Rendering Pipeline

All CLI output flows through a five-stage reactive pipeline:

<div class="highlight"><pre><code>
Command Logic ──► OutputSession ──► ElementHandles ──► MaterializationStrategy ──► Terminal/Pipe
                  (lifecycle)       (typed producers)   (format-driven policy)      (stdout/stderr)
</code></pre></div>

1. **Command Logic** opens an `OutputSession` and creates typed **element handles** — `PanelHandle`, `TableHandle`, `ProgressHandle`, etc. — for each piece of output the command will produce. Handles are created in **declaration order**, which determines the canonical order in which elements appear in sequential formats.

2. **OutputSession** is the central coordinator. It owns the set of active handles, tracks their lifecycle (open → writing → closed), emits `ElementEvent` objects to the active materialization strategy, and provides a `snapshot()` method that returns a static `StructuredOutput` representing the accumulated state at any point in time.

3. **ElementHandles** are the producer-facing API. Each handle is typed for a specific element kind (panel, table, tree, etc.) and exposes write methods appropriate to that kind (`add_row()`, `set_entry()`, `set_step_status()`, etc.). Handles are **thread-safe** — multiple concurrent coroutines or threads can write to different handles simultaneously. Handles are **format-agnostic** — the producer never knows or cares which format is active.

4. **MaterializationStrategy** is a polymorphic observer selected by the active format. It receives `ElementEvent` notifications from the session and decides *when* and *how* to render content. Each strategy delegates the actual visual rendering of an element's accumulated state to a paired **ElementRenderer**.

5. **Terminal/Pipe** receives the final byte stream. The framework auto-detects whether stdout is a TTY and degrades gracefully (e.g., `rich` falls back to `table` when piped to a non-TTY unless `--format rich` was explicitly set).

##### OutputSession

The `OutputSession` is the core abstraction that replaces direct construction of static output objects. Commands receive a session (typically injected by the CLI framework) and interact with it throughout their execution:

<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">OutputSession</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;A live output document that coordinates element production and materialization.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    The session manages the lifecycle of all output elements for a single command</span>
<span style="color: #66cc66;">    invocation. It is the bridge between format-agnostic producer code and the</span>
<span style="color: #66cc66;">    format-specific materialization strategy.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Thread Safety:</span>
<span style="color: #66cc66;">        The session is thread-safe. Multiple producers may create and write to</span>
<span style="color: #66cc66;">        handles concurrently. The session serializes event delivery to the</span>
<span style="color: #66cc66;">        materialization strategy using an internal event queue.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Lifecycle:</span>
<span style="color: #66cc66;">        session = OutputSession.open(command, strategy)</span>
<span style="color: #66cc66;">        handle_a = session.panel(&quot;Title&quot;)       # create handles</span>
<span style="color: #66cc66;">        handle_b = session.table(&quot;Results&quot;, ...) </span>
<span style="color: #66cc66;">        handle_a.set_entry(...)                  # write to handles (concurrent OK)</span>
<span style="color: #66cc66;">        handle_b.add_row(...)</span>
<span style="color: #66cc66;">        handle_a.close()                         # close handles when done</span>
<span style="color: #66cc66;">        handle_b.close()</span>
<span style="color: #66cc66;">        session.close()                          # finalize the session</span>
<span style="color: #66cc66;">    &quot;&quot;&quot;</span>
    
    <span style="opacity: 0.7;"># --- Session lifecycle ---</span>
    
    command: <span style="color: cyan;">str</span>                                  <span style="opacity: 0.7;"># The command that owns this session</span>
    session_id: <span style="color: cyan;">str</span>                               <span style="opacity: 0.7;"># Unique session identifier (ULID)</span>
    created_at: <span style="color: cyan;">datetime</span>                          <span style="opacity: 0.7;"># Session creation timestamp</span>
    
    _strategy: MaterializationStrategy            <span style="opacity: 0.7;"># The active materialization strategy</span>
    _handles: <span style="color: cyan;">OrderedDict</span>[<span style="color: cyan;">str</span>, ElementHandle]     <span style="opacity: 0.7;"># handle_id → handle, in declaration order</span>
    _event_queue: asyncio.Queue[ElementEvent]     <span style="opacity: 0.7;"># Internal event queue for serialization</span>
    _state: SessionState                          <span style="opacity: 0.7;"># &quot;open&quot; | &quot;closing&quot; | &quot;closed&quot;</span>
    _lock: threading.Lock                         <span style="opacity: 0.7;"># Protects handle creation/removal</span>
    
    <span style="color: yellow;">@classmethod</span>
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">open</span>(cls, command: <span style="color: cyan;">str</span>, strategy: MaterializationStrategy,
             metadata: <span style="color: cyan;">dict</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: #66cc66;">&quot;OutputSession&quot;</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Open a new output session.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Called by the CLI framework before command execution. The strategy is</span>
<span style="color: #66cc66;">        selected based on the resolved format (see Format Resolution).</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Args:</span>
<span style="color: #66cc66;">            command: The command string (e.g., &quot;project show&quot;).</span>
<span style="color: #66cc66;">            strategy: The materialization strategy for the active format.</span>
<span style="color: #66cc66;">            metadata: Optional command metadata (user, timestamp, etc.).</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Returns:</span>
<span style="color: #66cc66;">            A new OutputSession ready for element creation.</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        ...
    
    <span style="opacity: 0.7;"># --- Element handle factories ---</span>
    <span style="opacity: 0.7;"># Each factory creates a typed handle, registers it with the session in</span>
    <span style="opacity: 0.7;"># declaration order, and emits an ElementCreated event to the strategy.</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">panel</span>(self, title: <span style="color: cyan;">str</span>, *,
              border_style: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;rounded&quot;</span>,
              priority: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;normal&quot;</span>,
              collapse_hint: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;auto&quot;</span>,
              metadata: <span style="color: cyan;">dict</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: #66cc66;">&quot;PanelHandle&quot;</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Create a panel element handle for key-value pair output.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">table</span>(self, title: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span>, *,
              columns: <span style="color: cyan;">list</span>[<span style="color: #66cc66;">&quot;ColumnDef&quot;</span>],
              summary: <span style="color: cyan;">dict</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>,
              max_rows_hint: <span style="color: cyan;">int</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>,
              sort_key: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>,
              priority: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;normal&quot;</span>,
              collapse_hint: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;auto&quot;</span>,
              metadata: <span style="color: cyan;">dict</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: #66cc66;">&quot;TableHandle&quot;</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Create a table element handle for tabular data.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">tree</span>(self, root_label: <span style="color: cyan;">str</span>, *,
             root_style: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>,
             max_depth_hint: <span style="color: cyan;">int</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>,
             show_guides: <span style="color: cyan;">bool</span> = <span style="color: magenta; font-weight: 600;">True</span>,
             priority: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;normal&quot;</span>,
             collapse_hint: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;auto&quot;</span>,
             metadata: <span style="color: cyan;">dict</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: #66cc66;">&quot;TreeHandle&quot;</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Create a tree element handle for hierarchical data.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">progress</span>(self, label: <span style="color: cyan;">str</span>, *,
                 total: <span style="color: cyan;">int</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>,
                 indeterminate: <span style="color: cyan;">bool</span> = <span style="color: magenta; font-weight: 600;">False</span>,
                 steps: <span style="color: cyan;">list</span>[<span style="color: cyan;">str</span>] | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>,
                 priority: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;normal&quot;</span>,
                 metadata: <span style="color: cyan;">dict</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: #66cc66;">&quot;ProgressHandle&quot;</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Create a progress indicator handle.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Args:</span>
<span style="color: #66cc66;">            label: Display label for the progress indicator.</span>
<span style="color: #66cc66;">            total: Total units of work (None for indeterminate).</span>
<span style="color: #66cc66;">            indeterminate: If True, show a spinner instead of a progress bar.</span>
<span style="color: #66cc66;">            steps: Named steps to track (creates ProgressStep objects with</span>
<span style="color: #66cc66;">                   initial status &quot;pending&quot;).</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">status</span>(self, message: <span style="color: cyan;">str</span>, *,
               level: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;info&quot;</span>,
               detail: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>,
               priority: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;normal&quot;</span>,
               metadata: <span style="color: cyan;">dict</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: #66cc66;">&quot;StatusHandle&quot;</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Create a status message handle.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">text</span>(self, content: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;&quot;</span>, *,
             wrap: <span style="color: cyan;">bool</span> = <span style="color: magenta; font-weight: 600;">True</span>,
             indent: <span style="color: cyan;">int</span> = 0,
             priority: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;normal&quot;</span>,
             metadata: <span style="color: cyan;">dict</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: #66cc66;">&quot;TextHandle&quot;</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Create a text block handle.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">code</span>(self, content: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;&quot;</span>, *,
             language: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>,
             line_numbers: <span style="color: cyan;">bool</span> = <span style="color: magenta; font-weight: 600;">False</span>,
             highlight_lines: <span style="color: cyan;">list</span>[<span style="color: cyan;">int</span>] | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>,
             priority: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;normal&quot;</span>,
             metadata: <span style="color: cyan;">dict</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: #66cc66;">&quot;CodeHandle&quot;</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Create a code block handle.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">diff</span>(self, *,
             file_a: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>,
             file_b: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>,
             priority: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;normal&quot;</span>,
             metadata: <span style="color: cyan;">dict</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: #66cc66;">&quot;DiffHandle&quot;</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Create a diff block handle.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">separator</span>(self, style: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;line&quot;</span>) -&gt; <span style="color: #66cc66;">&quot;SeparatorHandle&quot;</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Create a visual separator. Separators are auto-closed on creation.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">action_hint</span>(self, commands: <span style="color: cyan;">list</span>[<span style="color: cyan;">str</span>],
                    description: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: #66cc66;">&quot;ActionHintHandle&quot;</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Create an action hint. Action hints are auto-closed on creation.&quot;&quot;&quot;</span>
        ...
    
    <span style="opacity: 0.7;"># --- Session operations ---</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">snapshot</span>(self) -&gt; <span style="color: #66cc66;">&quot;StructuredOutput&quot;</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Return a static snapshot of all elements accumulated so far.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        The snapshot captures the current state of every handle (open or closed)</span>
<span style="color: #66cc66;">        as a StructuredOutput object. This is used by accumulate-mode strategies</span>
<span style="color: #66cc66;">        (json/yaml) at session end, and is available at any time for logging,</span>
<span style="color: #66cc66;">        debugging, or programmatic inspection.</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">close</span>(self, *, exit_code: <span style="color: cyan;">int</span> = 0) -&gt; <span style="color: #66cc66;">&quot;StructuredOutput&quot;</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Close the session and finalize all output.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Any handles still open are force-closed (with a warning logged).</span>
<span style="color: #66cc66;">        Emits a SessionEnd event to the strategy. Returns the final</span>
<span style="color: #66cc66;">        StructuredOutput snapshot.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Args:</span>
<span style="color: #66cc66;">            exit_code: The command&#x27;s exit code (included in the snapshot).</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Returns:</span>
<span style="color: #66cc66;">            The final StructuredOutput snapshot.</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        ...
    
    <span style="opacity: 0.7;"># --- Context manager support ---</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">__enter__</span>(self) -&gt; <span style="color: #66cc66;">&quot;OutputSession&quot;</span>:
        <span style="color: magenta; font-weight: 600;">return</span> self
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">__exit__</span>(self, exc_type, exc_val, exc_tb) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Auto-close session on context exit.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        If exiting due to an exception, sets exit_code to 1 and emits an</span>
<span style="color: #66cc66;">        error status element before closing.</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        ...
</code></pre></div>

##### Element Handles

Element handles are the producer-facing API. Each handle type wraps a specific element kind and provides methods appropriate to that kind. All handles share a common base:

<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">ElementHandle</span>(<span style="color: cyan;">Generic</span>[E]):
    <span style="color: #66cc66;">&quot;&quot;&quot;Base class for all element handles.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    An element handle is a write-only view of an output element. Producers use</span>
<span style="color: #66cc66;">    handles to incrementally build element content without knowledge of the</span>
<span style="color: #66cc66;">    active format or materialization strategy.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Type Parameter:</span>
<span style="color: #66cc66;">        E: The OutputElement subclass this handle wraps (e.g., Panel, Table).</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Thread Safety:</span>
<span style="color: #66cc66;">        Individual handle methods are thread-safe. Multiple threads may call</span>
<span style="color: #66cc66;">        methods on *different* handles concurrently. Concurrent writes to the</span>
<span style="color: #66cc66;">        *same* handle are serialized via an internal lock.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Lifecycle:</span>
<span style="color: #66cc66;">        handle = session.table(...)    # Created by session factory</span>
<span style="color: #66cc66;">        handle.add_row(...)            # Write operations (zero or more)</span>
<span style="color: #66cc66;">        handle.close()                 # Finalize (required unless auto-closed)</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Closed Handle Behavior:</span>
<span style="color: #66cc66;">        Calling any write method on a closed handle raises ElementClosedError.</span>
<span style="color: #66cc66;">    &quot;&quot;&quot;</span>
    
    handle_id: <span style="color: cyan;">str</span>                       <span style="opacity: 0.7;"># Unique handle identifier (ULID)</span>
    element_type: <span style="color: cyan;">str</span>                    <span style="opacity: 0.7;"># Semantic type (&quot;panel&quot;, &quot;table&quot;, etc.)</span>
    declaration_index: <span style="color: cyan;">int</span>               <span style="opacity: 0.7;"># Position in session&#x27;s declaration order</span>
    
    _session: OutputSession              <span style="opacity: 0.7;"># Owning session (for event emission)</span>
    _element: E                          <span style="opacity: 0.7;"># The accumulated element state</span>
    _state: HandleState                  <span style="opacity: 0.7;"># &quot;open&quot; | &quot;closed&quot;</span>
    _lock: threading.Lock                <span style="opacity: 0.7;"># Serializes writes to this handle</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">close</span>(self) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Close this handle, signaling that no more data will be written.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Emits an ElementClosed event to the materialization strategy.</span>
<span style="color: #66cc66;">        For buffered strategies, this triggers rendering of the element.</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        ...
    
    <span style="color: yellow;">@property</span>
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">is_open</span>(self) -&gt; <span style="color: cyan;">bool</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Whether this handle is still accepting writes.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: yellow;">@property</span>
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">element</span>(self) -&gt; E:
        <span style="color: #66cc66;">&quot;&quot;&quot;The accumulated element state (read-only snapshot).&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">__enter__</span>(self) -&gt; <span style="color: cyan;">Self</span>:
        <span style="color: magenta; font-weight: 600;">return</span> self
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">__exit__</span>(self, exc_type, exc_val, exc_tb) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Auto-close handle on context exit.&quot;&quot;&quot;</span>
        <span style="color: magenta; font-weight: 600;">if</span> self.is_open:
            self.close()


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">PanelHandle</span>(ElementHandle[Panel]):
    <span style="color: #66cc66;">&quot;&quot;&quot;Handle for building a Panel element incrementally.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Panels are titled groups of key-value pairs. Entries can be added,</span>
<span style="color: #66cc66;">    updated, or removed after creation.</span>
<span style="color: #66cc66;">    &quot;&quot;&quot;</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">set_entry</span>(self, key: <span style="color: cyan;">str</span>, value: <span style="color: cyan;">str</span>, *,
                  style_hint: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>,
                  icon: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Set or update a key-value entry in the panel.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        If an entry with the given key already exists, it is updated.</span>
<span style="color: #66cc66;">        Otherwise, a new entry is appended.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Emits an ElementUpdated event.</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">set_entries</span>(self, entries: <span style="color: cyan;">dict</span>[<span style="color: cyan;">str</span>, <span style="color: cyan;">str</span>], *,
                    style_hints: <span style="color: cyan;">dict</span>[<span style="color: cyan;">str</span>, <span style="color: cyan;">str</span>] | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Set multiple entries at once (batch update). Emits a single event.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">remove_entry</span>(self, key: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Remove an entry by key. Emits an ElementUpdated event.&quot;&quot;&quot;</span>
        ...


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">TableHandle</span>(ElementHandle[Table]):
    <span style="color: #66cc66;">&quot;&quot;&quot;Handle for building a Table element incrementally.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Tables are the primary element for streamed data. Rows can be added</span>
<span style="color: #66cc66;">    one at a time or in batches as data becomes available from queries,</span>
<span style="color: #66cc66;">    API calls, or concurrent operations.</span>
<span style="color: #66cc66;">    &quot;&quot;&quot;</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">add_row</span>(self, row: <span style="color: cyan;">dict</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Append a single row to the table.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        The row dict maps column names to cell values. Missing columns</span>
<span style="color: #66cc66;">        are filled with None. Extra columns not in the schema are ignored.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Emits an ElementUpdated event (type=row_added).</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">add_rows</span>(self, rows: <span style="color: cyan;">list</span>[<span style="color: cyan;">dict</span>]) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Append multiple rows in a batch. Emits a single ElementUpdated event.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">set_summary</span>(self, summary: <span style="color: cyan;">dict</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Set or update the summary/aggregation row. Emits an ElementUpdated event.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">set_sort_key</span>(self, column: <span style="color: cyan;">str</span>, *, descending: <span style="color: cyan;">bool</span> = <span style="color: magenta; font-weight: 600;">False</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Change the sort key. Emits an ElementUpdated event.&quot;&quot;&quot;</span>
        ...


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">TreeHandle</span>(ElementHandle[Tree]):
    <span style="color: #66cc66;">&quot;&quot;&quot;Handle for building a Tree element incrementally.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Trees are built by adding child nodes to existing nodes. The root node</span>
<span style="color: #66cc66;">    is created with the handle. Subtrees can be constructed incrementally</span>
<span style="color: #66cc66;">    as hierarchical data is discovered.</span>
<span style="color: #66cc66;">    &quot;&quot;&quot;</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">add_child</span>(self, parent_path: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span>, label: <span style="color: cyan;">str</span>, *,
                  style_hint: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>,
                  collapsed: <span style="color: cyan;">bool</span> = <span style="color: magenta; font-weight: 600;">False</span>,
                  metadata: <span style="color: cyan;">dict</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: cyan;">str</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Add a child node to the tree.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Args:</span>
<span style="color: #66cc66;">            parent_path: Slash-separated path to the parent node (None = root).</span>
<span style="color: #66cc66;">            label: Display label for the new node.</span>
<span style="color: #66cc66;">            style_hint: Optional color/style hint.</span>
<span style="color: #66cc66;">            collapsed: Whether this node starts collapsed in interactive renderers.</span>
<span style="color: #66cc66;">            metadata: Arbitrary data attached to the node.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Returns:</span>
<span style="color: #66cc66;">            The full path to the newly created node (for use as parent_path</span>
<span style="color: #66cc66;">            in subsequent add_child calls).</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Emits an ElementUpdated event.</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">set_node_style</span>(self, path: <span style="color: cyan;">str</span>, style_hint: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Update the style of an existing node. Emits an ElementUpdated event.&quot;&quot;&quot;</span>
        ...


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">ProgressHandle</span>(ElementHandle[ProgressIndicator]):
    <span style="color: #66cc66;">&quot;&quot;&quot;Handle for updating a ProgressIndicator element.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Progress handles are unique in that they are expected to receive many</span>
<span style="color: #66cc66;">    rapid updates. The materialization strategy may throttle update events</span>
<span style="color: #66cc66;">    to avoid overwhelming the terminal (e.g., limiting redraws to 10/sec).</span>
<span style="color: #66cc66;">    &quot;&quot;&quot;</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">set_progress</span>(self, current: <span style="color: cyan;">int</span>, total: <span style="color: cyan;">int</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Update the progress counter.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Args:</span>
<span style="color: #66cc66;">            current: Current progress value.</span>
<span style="color: #66cc66;">            total: Total value (can change, e.g., when total is discovered late).</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Emits an ElementUpdated event (may be throttled by the strategy).</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">set_step_status</span>(self, step_label: <span style="color: cyan;">str</span>, status: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Update the status of a named step.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Args:</span>
<span style="color: #66cc66;">            step_label: The label of the step to update.</span>
<span style="color: #66cc66;">            status: New status — &quot;pending&quot; | &quot;active&quot; | &quot;done&quot; | &quot;error&quot; | &quot;skipped&quot;.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Emits an ElementUpdated event.</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">set_label</span>(self, label: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Update the progress label text. Emits an ElementUpdated event.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">increment</span>(self, delta: <span style="color: cyan;">int</span> = 1) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Increment progress by delta. Convenience wrapper around set_progress.&quot;&quot;&quot;</span>
        ...


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">StatusHandle</span>(ElementHandle[StatusMessage]):
    <span style="color: #66cc66;">&quot;&quot;&quot;Handle for a status message.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Status handles are typically created and immediately closed (fire-and-forget</span>
<span style="color: #66cc66;">    messages). However, they can be kept open for messages that may be revised</span>
<span style="color: #66cc66;">    (e.g., a &quot;Working...&quot; status that becomes &quot;Done&quot; or &quot;Failed&quot;).</span>
<span style="color: #66cc66;">    &quot;&quot;&quot;</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">set_message</span>(self, message: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Update the status message text. Emits an ElementUpdated event.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">set_level</span>(self, level: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Change the status level. Emits an ElementUpdated event.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">set_detail</span>(self, detail: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Set or clear the detail text. Emits an ElementUpdated event.&quot;&quot;&quot;</span>
        ...


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">TextHandle</span>(ElementHandle[TextBlock]):
    <span style="color: #66cc66;">&quot;&quot;&quot;Handle for a text block. Supports appending text incrementally.&quot;&quot;&quot;</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">append</span>(self, text: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Append text to the block. Emits an ElementUpdated event.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">set_content</span>(self, content: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Replace the entire content. Emits an ElementUpdated event.&quot;&quot;&quot;</span>
        ...


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">CodeHandle</span>(ElementHandle[CodeBlock]):
    <span style="color: #66cc66;">&quot;&quot;&quot;Handle for a code block.&quot;&quot;&quot;</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">set_content</span>(self, content: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Set the code content. Emits an ElementUpdated event.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">set_language</span>(self, language: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Set the language for syntax highlighting. Emits an ElementUpdated event.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">set_highlight_lines</span>(self, lines: <span style="color: cyan;">list</span>[<span style="color: cyan;">int</span>]) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Set lines to highlight. Emits an ElementUpdated event.&quot;&quot;&quot;</span>
        ...


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">DiffHandle</span>(ElementHandle[DiffBlock]):
    <span style="color: #66cc66;">&quot;&quot;&quot;Handle for a diff block. Hunks can be added incrementally.&quot;&quot;&quot;</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">add_hunk</span>(self, header: <span style="color: cyan;">str</span>, lines: <span style="color: cyan;">list</span>[<span style="color: #66cc66;">&quot;DiffLine&quot;</span>]) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Add a diff hunk. Emits an ElementUpdated event.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">set_stats</span>(self, insertions: <span style="color: cyan;">int</span>, deletions: <span style="color: cyan;">int</span>, **extra: <span style="color: cyan;">int</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Set diff statistics. Emits an ElementUpdated event.&quot;&quot;&quot;</span>
        ...
</code></pre></div>

##### Element Events

Element handles communicate with the materialization strategy through a typed event system. Events are the sole interface between production (handles) and consumption (strategy) — this indirection is what enables format-agnostic producer code:

<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">ElementEvent</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;Base class for all events emitted by element handles.&quot;&quot;&quot;</span>
    event_type: <span style="color: cyan;">str</span>                      <span style="opacity: 0.7;"># &quot;created&quot; | &quot;updated&quot; | &quot;closed&quot;</span>
    handle_id: <span style="color: cyan;">str</span>                       <span style="opacity: 0.7;"># The handle that emitted this event</span>
    element_type: <span style="color: cyan;">str</span>                    <span style="opacity: 0.7;"># The element kind (&quot;panel&quot;, &quot;table&quot;, etc.)</span>
    timestamp: <span style="color: cyan;">datetime</span>                  <span style="opacity: 0.7;"># When the event occurred</span>
    session_id: <span style="color: cyan;">str</span>                      <span style="opacity: 0.7;"># The owning session</span>


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">ElementCreated</span>(ElementEvent):
    <span style="color: #66cc66;">&quot;&quot;&quot;Emitted when a new element handle is created via a session factory.&quot;&quot;&quot;</span>
    event_type = <span style="color: #66cc66;">&quot;created&quot;</span>
    declaration_index: <span style="color: cyan;">int</span>               <span style="opacity: 0.7;"># Position in session declaration order</span>
    initial_state: OutputElement         <span style="opacity: 0.7;"># The element&#x27;s initial state</span>


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">ElementUpdated</span>(ElementEvent):
    <span style="color: #66cc66;">&quot;&quot;&quot;Emitted when data is written to an element handle.&quot;&quot;&quot;</span>
    event_type = <span style="color: #66cc66;">&quot;updated&quot;</span>
    update_type: <span style="color: cyan;">str</span>                     <span style="opacity: 0.7;"># Kind-specific: &quot;entry_set&quot;, &quot;row_added&quot;,</span>
                                         <span style="opacity: 0.7;">#   &quot;progress_changed&quot;, &quot;step_status_changed&quot;, etc.</span>
    delta: <span style="color: cyan;">dict</span>                          <span style="opacity: 0.7;"># The change payload (what was added/modified)</span>
    element_snapshot: OutputElement      <span style="opacity: 0.7;"># The full element state after this update</span>


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">ElementClosed</span>(ElementEvent):
    <span style="color: #66cc66;">&quot;&quot;&quot;Emitted when an element handle is closed (no more data will arrive).&quot;&quot;&quot;</span>
    event_type = <span style="color: #66cc66;">&quot;closed&quot;</span>
    final_state: OutputElement           <span style="opacity: 0.7;"># The element&#x27;s final accumulated state</span>


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">SessionEnd</span>(ElementEvent):
    <span style="color: #66cc66;">&quot;&quot;&quot;Emitted when the session itself is closed.&quot;&quot;&quot;</span>
    event_type = <span style="color: #66cc66;">&quot;session_end&quot;</span>
    exit_code: <span style="color: cyan;">int</span>
    snapshot: <span style="color: #66cc66;">&quot;StructuredOutput&quot;</span>         <span style="opacity: 0.7;"># The complete accumulated output</span>
</code></pre></div>

##### Element Data Model (Snapshot Types)

Each element handle accumulates state into a typed **snapshot object**. These are the data classes that represent a fully-built element — they are what the `ElementRenderer` receives when it is time to paint. They are also the building blocks of the `StructuredOutput` returned by `session.snapshot()`:

<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">OutputElement</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;Base class for all output element snapshot types.&quot;&quot;&quot;</span>
    element_type: <span style="color: cyan;">str</span>                    <span style="opacity: 0.7;"># Semantic type identifier</span>
    metadata: <span style="color: cyan;">dict</span>                       <span style="opacity: 0.7;"># Arbitrary metadata (timestamps, IDs, etc.)</span>
    priority: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;normal&quot;</span>             <span style="opacity: 0.7;"># &quot;critical&quot; | &quot;normal&quot; | &quot;supplementary&quot;</span>
    collapse_hint: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;auto&quot;</span>          <span style="opacity: 0.7;"># &quot;always&quot; | &quot;auto&quot; | &quot;never&quot; — guidance for renderers</span>
                                         <span style="opacity: 0.7;">#   on whether this element can be collapsed/hidden</span>

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">Panel</span>(OutputElement):
    <span style="color: #66cc66;">&quot;&quot;&quot;A titled group of key-value pairs.&quot;&quot;&quot;</span>
    element_type = <span style="color: #66cc66;">&quot;panel&quot;</span>
    title: <span style="color: cyan;">str</span>
    entries: <span style="color: cyan;">list</span>[PanelEntry]            <span style="opacity: 0.7;"># Each entry: key, value, style_hint (color, icon, etc.)</span>
    border_style: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;rounded&quot;</span>        <span style="opacity: 0.7;"># &quot;rounded&quot; | &quot;square&quot; | &quot;heavy&quot; | &quot;none&quot;</span>

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">PanelEntry</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;A single key-value pair within a Panel.&quot;&quot;&quot;</span>
    key: <span style="color: cyan;">str</span>
    value: <span style="color: cyan;">str</span>
    style_hint: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>        <span style="opacity: 0.7;"># Color/style for the value (e.g., &quot;success&quot;, &quot;warning&quot;)</span>
    icon: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>              <span style="opacity: 0.7;"># Optional icon/prefix character</span>

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">Table</span>(OutputElement):
    <span style="color: #66cc66;">&quot;&quot;&quot;A tabular data set with typed columns.&quot;&quot;&quot;</span>
    element_type = <span style="color: #66cc66;">&quot;table&quot;</span>
    title: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span>
    columns: <span style="color: cyan;">list</span>[ColumnDef]             <span style="opacity: 0.7;"># name, type, alignment, width_hint, sortable</span>
    rows: <span style="color: cyan;">list</span>[<span style="color: cyan;">dict</span>]                     <span style="opacity: 0.7;"># Column name → cell value</span>
    summary: <span style="color: cyan;">dict</span> | <span style="color: magenta; font-weight: 600;">None</span>                 <span style="opacity: 0.7;"># Optional aggregation row (totals, counts)</span>
    max_rows_hint: <span style="color: cyan;">int</span> | <span style="color: magenta; font-weight: 600;">None</span>            <span style="opacity: 0.7;"># Suggest truncation for large datasets</span>
    sort_key: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span>                 <span style="opacity: 0.7;"># Default sort column</span>

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">ColumnDef</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;Schema for a single table column.&quot;&quot;&quot;</span>
    name: <span style="color: cyan;">str</span>                            <span style="opacity: 0.7;"># Column display name</span>
    type: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;string&quot;</span>                 <span style="opacity: 0.7;"># &quot;string&quot; | &quot;number&quot; | &quot;boolean&quot; | &quot;datetime&quot; | &quot;id&quot;</span>
    alignment: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;left&quot;</span>              <span style="opacity: 0.7;"># &quot;left&quot; | &quot;right&quot; | &quot;center&quot;</span>
    width_hint: <span style="color: cyan;">int</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>        <span style="opacity: 0.7;"># Suggested character width (None = auto)</span>
    sortable: <span style="color: cyan;">bool</span> = <span style="color: magenta; font-weight: 600;">False</span>               <span style="opacity: 0.7;"># Whether this column can be sorted</span>
    style_hint: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>        <span style="opacity: 0.7;"># Default style for cells in this column</span>

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">Tree</span>(OutputElement):
    <span style="color: #66cc66;">&quot;&quot;&quot;A hierarchical tree structure.&quot;&quot;&quot;</span>
    element_type = <span style="color: #66cc66;">&quot;tree&quot;</span>
    root: TreeNode                       <span style="opacity: 0.7;"># Recursive node structure</span>
    max_depth_hint: <span style="color: cyan;">int</span> | <span style="color: magenta; font-weight: 600;">None</span>           <span style="opacity: 0.7;"># Suggest depth truncation</span>
    show_guides: <span style="color: cyan;">bool</span> = <span style="color: magenta; font-weight: 600;">True</span>             <span style="opacity: 0.7;"># Whether to show tree guide lines</span>

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">TreeNode</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;A node in a tree structure.&quot;&quot;&quot;</span>
    label: <span style="color: cyan;">str</span>
    style_hint: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span>               <span style="opacity: 0.7;"># Color/style for this node</span>
    children: <span style="color: cyan;">list</span>[<span style="color: #66cc66;">&quot;TreeNode&quot;</span>]
    collapsed: <span style="color: cyan;">bool</span> = <span style="color: magenta; font-weight: 600;">False</span>              <span style="opacity: 0.7;"># Hint: start collapsed in interactive renderers</span>
    metadata: <span style="color: cyan;">dict</span>                       <span style="opacity: 0.7;"># Arbitrary data attached to the node</span>

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">StatusMessage</span>(OutputElement):
    <span style="color: #66cc66;">&quot;&quot;&quot;A status line (success, warning, error, info).&quot;&quot;&quot;</span>
    element_type = <span style="color: #66cc66;">&quot;status&quot;</span>
    level: <span style="color: cyan;">str</span>                           <span style="opacity: 0.7;"># &quot;ok&quot; | &quot;warn&quot; | &quot;error&quot; | &quot;info&quot;</span>
    message: <span style="color: cyan;">str</span>
    detail: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span>                   <span style="opacity: 0.7;"># Optional detail text</span>

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">ProgressIndicator</span>(OutputElement):
    <span style="color: #66cc66;">&quot;&quot;&quot;A progress bar or spinner for long-running operations.&quot;&quot;&quot;</span>
    element_type = <span style="color: #66cc66;">&quot;progress&quot;</span>
    label: <span style="color: cyan;">str</span>
    current: <span style="color: cyan;">int</span> | <span style="color: magenta; font-weight: 600;">None</span>
    total: <span style="color: cyan;">int</span> | <span style="color: magenta; font-weight: 600;">None</span>
    indeterminate: <span style="color: cyan;">bool</span> = <span style="color: magenta; font-weight: 600;">False</span>          <span style="opacity: 0.7;"># Spinner mode vs. progress bar mode</span>
    steps: <span style="color: cyan;">list</span>[ProgressStep] | <span style="color: magenta; font-weight: 600;">None</span>     <span style="opacity: 0.7;"># Named steps with status (pending/active/done)</span>

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">ProgressStep</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;A named step within a progress indicator.&quot;&quot;&quot;</span>
    label: <span style="color: cyan;">str</span>
    status: <span style="color: cyan;">str</span>                          <span style="opacity: 0.7;"># &quot;pending&quot; | &quot;active&quot; | &quot;done&quot; | &quot;error&quot; | &quot;skipped&quot;</span>

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">CodeBlock</span>(OutputElement):
    <span style="color: #66cc66;">&quot;&quot;&quot;A block of source code with optional syntax highlighting.&quot;&quot;&quot;</span>
    element_type = <span style="color: #66cc66;">&quot;code&quot;</span>
    content: <span style="color: cyan;">str</span>
    language: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span>                 <span style="opacity: 0.7;"># For syntax highlighting</span>
    line_numbers: <span style="color: cyan;">bool</span> = <span style="color: magenta; font-weight: 600;">False</span>
    highlight_lines: <span style="color: cyan;">list</span>[<span style="color: cyan;">int</span>] | <span style="color: magenta; font-weight: 600;">None</span>    <span style="opacity: 0.7;"># Lines to emphasize</span>

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">DiffBlock</span>(OutputElement):
    <span style="color: #66cc66;">&quot;&quot;&quot;A unified diff display.&quot;&quot;&quot;</span>
    element_type = <span style="color: #66cc66;">&quot;diff&quot;</span>
    hunks: <span style="color: cyan;">list</span>[DiffHunk]
    file_a: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span>
    file_b: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span>
    stats: <span style="color: cyan;">dict</span> | <span style="color: magenta; font-weight: 600;">None</span>                   <span style="opacity: 0.7;"># insertions, deletions, etc.</span>

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">DiffHunk</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;A single hunk within a diff.&quot;&quot;&quot;</span>
    header: <span style="color: cyan;">str</span>                          <span style="opacity: 0.7;"># @@ line range @@</span>
    lines: <span style="color: cyan;">list</span>[DiffLine]

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">DiffLine</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;A single line in a diff hunk.&quot;&quot;&quot;</span>
    type: <span style="color: cyan;">str</span>                            <span style="opacity: 0.7;"># &quot;context&quot; | &quot;add&quot; | &quot;remove&quot;</span>
    content: <span style="color: cyan;">str</span>
    line_number_old: <span style="color: cyan;">int</span> | <span style="color: magenta; font-weight: 600;">None</span>
    line_number_new: <span style="color: cyan;">int</span> | <span style="color: magenta; font-weight: 600;">None</span>

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">TextBlock</span>(OutputElement):
    <span style="color: #66cc66;">&quot;&quot;&quot;A free-form text block (descriptions, rationale, etc.).&quot;&quot;&quot;</span>
    element_type = <span style="color: #66cc66;">&quot;text&quot;</span>
    content: <span style="color: cyan;">str</span>
    wrap: <span style="color: cyan;">bool</span> = <span style="color: magenta; font-weight: 600;">True</span>
    indent: <span style="color: cyan;">int</span> = 0

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">Separator</span>(OutputElement):
    <span style="color: #66cc66;">&quot;&quot;&quot;A visual separator between logical groups.&quot;&quot;&quot;</span>
    element_type = <span style="color: #66cc66;">&quot;separator&quot;</span>
    style: <span style="color: cyan;">str</span> = <span style="color: #66cc66;">&quot;line&quot;</span>                  <span style="opacity: 0.7;"># &quot;line&quot; | &quot;blank&quot; | &quot;double&quot;</span>

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">ActionHint</span>(OutputElement):
    <span style="color: #66cc66;">&quot;&quot;&quot;A suggested next-step action for the user.&quot;&quot;&quot;</span>
    element_type = <span style="color: #66cc66;">&quot;action_hint&quot;</span>
    commands: <span style="color: cyan;">list</span>[<span style="color: cyan;">str</span>]                  <span style="opacity: 0.7;"># Suggested CLI commands</span>
    description: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span>

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">StructuredOutput</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;Static snapshot of a complete command output.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    This is the accumulated state of all elements at a point in time.</span>
<span style="color: #66cc66;">    It is produced by OutputSession.snapshot() and OutputSession.close().</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Uses:</span>
<span style="color: #66cc66;">    - Final serialization for json/yaml formats</span>
<span style="color: #66cc66;">    - Logging and audit trails</span>
<span style="color: #66cc66;">    - Programmatic inspection and testing</span>
<span style="color: #66cc66;">    - TUI widget data binding (initial state)</span>
<span style="color: #66cc66;">    &quot;&quot;&quot;</span>
    command: <span style="color: cyan;">str</span>                         <span style="opacity: 0.7;"># The command that produced this output</span>
    session_id: <span style="color: cyan;">str</span>                      <span style="opacity: 0.7;"># The session that produced this output</span>
    elements: <span style="color: cyan;">list</span>[OutputElement]        <span style="opacity: 0.7;"># Ordered list of element snapshots</span>
    exit_code: <span style="color: cyan;">int</span> = 0
    timing: <span style="color: cyan;">dict</span> | <span style="color: magenta; font-weight: 600;">None</span>                  <span style="opacity: 0.7;"># start_time, end_time, duration</span>
    metadata: <span style="color: cyan;">dict</span>                       <span style="opacity: 0.7;"># command-specific metadata</span>
</code></pre></div>

##### Materialization Strategies

The materialization strategy is the format-side counterpart to the output session. It receives element events and decides *when* and *how* to render content. Each strategy is paired with an `ElementRenderer` that handles the actual visual formatting of individual elements.

The strategy pattern creates a clean separation between **timing/ordering policy** (when to render) and **visual formatting** (how to render). This means the same `PlainElementRenderer` can be used whether elements arrive all-at-once or are streamed concurrently — the strategy handles the coordination.

<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">MaterializationStrategy</span>(<span style="color: cyan;">Protocol</span>):
    <span style="color: #66cc66;">&quot;&quot;&quot;Interface for format-driven output materialization.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    A materialization strategy receives element lifecycle events from the</span>
<span style="color: #66cc66;">    OutputSession and decides when to render element content to the output</span>
<span style="color: #66cc66;">    stream. Strategies do not render elements themselves — they delegate</span>
<span style="color: #66cc66;">    to a paired ElementRenderer at the appropriate time.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    The strategy is the mechanism by which format-agnostic producer code</span>
<span style="color: #66cc66;">    produces correct output regardless of format. The producer writes to</span>
<span style="color: #66cc66;">    handles; the strategy decides what reaches the terminal and when.</span>
<span style="color: #66cc66;">    &quot;&quot;&quot;</span>
    
    strategy_name: <span style="color: cyan;">str</span>                   <span style="opacity: 0.7;"># &quot;live&quot; | &quot;sequential_buffer&quot; | &quot;accumulate&quot;</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">bind</span>(self, renderer: <span style="color: #66cc66;">&quot;ElementRenderer&quot;</span>,
             terminal_caps: <span style="color: #66cc66;">&quot;TerminalCapabilities&quot;</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Bind this strategy to a renderer and terminal capabilities.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Called once during format resolution, before the session opens.</span>
<span style="color: #66cc66;">        The strategy retains a reference to the renderer for use during</span>
<span style="color: #66cc66;">        event handling. The output stream is provided separately via</span>
<span style="color: #66cc66;">        on_session_begin, since the session owns the stream.</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">on_session_begin</span>(self, session: OutputSession, stream: <span style="color: cyan;">IO</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Called when the session opens. The strategy receives the output</span>
<span style="color: #66cc66;">        stream and may write preamble (e.g., opening JSON bracket).&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">on_element_created</span>(self, event: ElementCreated) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Called when a new element handle is created.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">on_element_updated</span>(self, event: ElementUpdated) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Called when data is written to an element handle.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">on_element_closed</span>(self, event: ElementClosed) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Called when an element handle is closed.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">on_session_end</span>(self, event: SessionEnd) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Called when the session closes. The strategy may write epilogue.&quot;&quot;&quot;</span>
        ...


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">LiveMaterializer</span>(MaterializationStrategy):
    <span style="color: #66cc66;">&quot;&quot;&quot;Materialization strategy for the `rich` format.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Renders element updates in real-time using terminal cursor movement.</span>
<span style="color: #66cc66;">    Multiple elements can be visually active and updating simultaneously.</span>
<span style="color: #66cc66;">    The terminal display is a live document that is rewritten in place.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Behavior:</span>
<span style="color: #66cc66;">    - on_element_created: Allocates screen region for the element, renders</span>
<span style="color: #66cc66;">      initial (possibly empty) visual state.</span>
<span style="color: #66cc66;">    - on_element_updated: Re-renders the element in place using cursor</span>
<span style="color: #66cc66;">      movement. For progress indicators, updates may be throttled to a</span>
<span style="color: #66cc66;">      maximum refresh rate (default: 15 fps) to avoid terminal flooding.</span>
<span style="color: #66cc66;">    - on_element_closed: Renders the final state and freezes the screen</span>
<span style="color: #66cc66;">      region (no further updates). May apply a visual transition (e.g.,</span>
<span style="color: #66cc66;">      spinner resolves to a checkmark).</span>
<span style="color: #66cc66;">    - on_session_end: Finalizes the display, moves cursor to end, and</span>
<span style="color: #66cc66;">      restores normal terminal scrolling.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Screen Layout:</span>
<span style="color: #66cc66;">    Elements are arranged vertically in declaration order. Each element</span>
<span style="color: #66cc66;">    occupies a contiguous block of terminal lines. The materializer tracks</span>
<span style="color: #66cc66;">    the line offset and height of each element&#x27;s region. When an element&#x27;s</span>
<span style="color: #66cc66;">    height changes (e.g., a table gains rows), subsequent elements are</span>
<span style="color: #66cc66;">    shifted down.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Concurrent Updates:</span>
<span style="color: #66cc66;">    Updates from multiple handles are coalesced into a single frame refresh</span>
<span style="color: #66cc66;">    at the target frame rate. The materializer maintains a dirty-element set</span>
<span style="color: #66cc66;">    and redraws all dirty elements in a single pass per frame.</span>
<span style="color: #66cc66;">    &quot;&quot;&quot;</span>
    strategy_name = <span style="color: #66cc66;">&quot;live&quot;</span>
    
    _frame_rate: <span style="color: cyan;">float</span> = 15.0            <span style="opacity: 0.7;"># Maximum redraws per second</span>
    _element_regions: <span style="color: cyan;">OrderedDict</span>[<span style="color: cyan;">str</span>, ScreenRegion]  <span style="opacity: 0.7;"># handle_id → screen region</span>
    _dirty_set: <span style="color: cyan;">set</span>[<span style="color: cyan;">str</span>]                 <span style="opacity: 0.7;"># handle_ids that need redraw</span>
    _frame_timer: asyncio.TimerHandle    <span style="opacity: 0.7;"># Coalescing timer for frame redraws</span>


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">SequentialBufferMaterializer</span>(MaterializationStrategy):
    <span style="color: #66cc66;">&quot;&quot;&quot;Materialization strategy for `plain`, `color`, and `table` formats.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Buffers element content and renders elements sequentially in declaration</span>
<span style="color: #66cc66;">    order. An element&#x27;s content is rendered to the output stream only when</span>
<span style="color: #66cc66;">    its handle is closed. If handles are closed out of declaration order,</span>
<span style="color: #66cc66;">    the out-of-order element&#x27;s rendered content is held in a buffer until</span>
<span style="color: #66cc66;">    all preceding elements have been rendered.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    This strategy ensures that static, scrolling output formats produce</span>
<span style="color: #66cc66;">    coherent sequential output even when producers write to handles</span>
<span style="color: #66cc66;">    concurrently and close them in arbitrary order.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Behavior:</span>
<span style="color: #66cc66;">    - on_element_created: Records the element&#x27;s declaration index. No output.</span>
<span style="color: #66cc66;">    - on_element_updated: Buffers the update internally. No output.</span>
<span style="color: #66cc66;">    - on_element_closed: If this element is the next in declaration order,</span>
<span style="color: #66cc66;">      renders it immediately (and any buffered subsequent elements that are</span>
<span style="color: #66cc66;">      also closed). Otherwise, buffers the rendered content.</span>
<span style="color: #66cc66;">    - on_session_end: Force-renders any remaining buffered elements (handles</span>
<span style="color: #66cc66;">      that were never closed, in declaration order).</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Example (two tables populated concurrently):</span>
<span style="color: #66cc66;">    1. Handle A (index 0) created — table &quot;Resources&quot;</span>
<span style="color: #66cc66;">    2. Handle B (index 1) created — table &quot;Validations&quot;</span>
<span style="color: #66cc66;">    3. Handle B receives rows, Handle A receives rows (interleaved)</span>
<span style="color: #66cc66;">    4. Handle B closes (index 1) — rendered content buffered (waiting for A)</span>
<span style="color: #66cc66;">    5. Handle A closes (index 0) — A is rendered to stream, then buffered B</span>
<span style="color: #66cc66;">       is rendered to stream</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Result: Output shows table A followed by table B, regardless of the</span>
<span style="color: #66cc66;">    order in which data arrived or handles closed.</span>
<span style="color: #66cc66;">    &quot;&quot;&quot;</span>
    strategy_name = <span style="color: #66cc66;">&quot;sequential_buffer&quot;</span>
    
    _next_render_index: <span style="color: cyan;">int</span> = 0          <span style="opacity: 0.7;"># The declaration index to render next</span>
    _rendered_buffers: <span style="color: cyan;">dict</span>[<span style="color: cyan;">int</span>, <span style="color: cyan;">str</span>]     <span style="opacity: 0.7;"># index → pre-rendered content (waiting)</span>
    _closed_set: <span style="color: cyan;">set</span>[<span style="color: cyan;">int</span>]                <span style="opacity: 0.7;"># Declaration indices of closed elements</span>


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">AccumulateMaterializer</span>(MaterializationStrategy):
    <span style="color: #66cc66;">&quot;&quot;&quot;Materialization strategy for `json` and `yaml` formats.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Accumulates all element data silently until the session ends, then</span>
<span style="color: #66cc66;">    serializes the complete StructuredOutput as a single JSON or YAML</span>
<span style="color: #66cc66;">    document.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Behavior:</span>
<span style="color: #66cc66;">    - on_element_created: No output.</span>
<span style="color: #66cc66;">    - on_element_updated: No output.</span>
<span style="color: #66cc66;">    - on_element_closed: No output.</span>
<span style="color: #66cc66;">    - on_session_end: Calls session.snapshot() to get the final</span>
<span style="color: #66cc66;">      StructuredOutput, then delegates to the ElementRenderer&#x27;s</span>
<span style="color: #66cc66;">      serialize() method for complete document serialization.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    This strategy is the simplest — it ignores all intermediate events and</span>
<span style="color: #66cc66;">    only acts on session_end. It exists as a distinct strategy (rather than</span>
<span style="color: #66cc66;">    a special case) to maintain the uniform strategy interface.</span>
<span style="color: #66cc66;">    &quot;&quot;&quot;</span>
    strategy_name = <span style="color: #66cc66;">&quot;accumulate&quot;</span>
</code></pre></div>

##### ElementRenderer Protocol

While the `MaterializationStrategy` controls *when* elements are rendered, the `ElementRenderer` controls *how* each element type is visually formatted. Each format has a paired `ElementRenderer` implementation:

<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">ElementRenderer</span>(<span style="color: cyan;">Protocol</span>):
    <span style="color: #66cc66;">&quot;&quot;&quot;Interface for format-specific element rendering.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    An ElementRenderer knows how to paint each element type for a specific</span>
<span style="color: #66cc66;">    output format. It is called by the MaterializationStrategy when it is</span>
<span style="color: #66cc66;">    time to render an element.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Implementations:</span>
<span style="color: #66cc66;">    - PlainElementRenderer: ASCII text, no escapes</span>
<span style="color: #66cc66;">    - ColorElementRenderer: ANSI-colored text, same layout as plain</span>
<span style="color: #66cc66;">    - TableElementRenderer: Unicode box-drawing with color</span>
<span style="color: #66cc66;">    - RichElementRenderer: Advanced terminal features (cursor, animation)</span>
<span style="color: #66cc66;">    - JsonElementRenderer: JSON serialization</span>
<span style="color: #66cc66;">    - YamlElementRenderer: YAML serialization</span>
<span style="color: #66cc66;">    &quot;&quot;&quot;</span>
    
    format_name: <span style="color: cyan;">str</span>                     <span style="opacity: 0.7;"># &quot;plain&quot;, &quot;color&quot;, &quot;table&quot;, &quot;rich&quot;, &quot;json&quot;, &quot;yaml&quot;</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">render_panel</span>(self, panel: Panel, stream: <span style="color: cyan;">IO</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Render a panel element to the stream.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">render_table</span>(self, table: Table, stream: <span style="color: cyan;">IO</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Render a table element to the stream.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">render_tree</span>(self, tree: Tree, stream: <span style="color: cyan;">IO</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Render a tree element to the stream.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">render_status</span>(self, status: StatusMessage, stream: <span style="color: cyan;">IO</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Render a status message to the stream.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">render_progress</span>(self, progress: ProgressIndicator, stream: <span style="color: cyan;">IO</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Render a progress indicator to the stream.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">render_code</span>(self, code: CodeBlock, stream: <span style="color: cyan;">IO</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Render a code block to the stream.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">render_diff</span>(self, diff: DiffBlock, stream: <span style="color: cyan;">IO</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Render a diff block to the stream.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">render_text</span>(self, text: TextBlock, stream: <span style="color: cyan;">IO</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Render a text block to the stream.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">render_separator</span>(self, separator: Separator, stream: <span style="color: cyan;">IO</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Render a visual separator to the stream.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">render_action_hint</span>(self, hint: ActionHint, stream: <span style="color: cyan;">IO</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Render an action hint to the stream.&quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">render_element</span>(self, element: OutputElement, stream: <span style="color: cyan;">IO</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Dispatch to the appropriate render method based on element type.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        This is the primary entry point used by materialization strategies.</span>
<span style="color: #66cc66;">        It uses a dispatch table to route to the correct typed method.</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        dispatch = {
            <span style="color: #66cc66;">&quot;panel&quot;</span>: self.render_panel,
            <span style="color: #66cc66;">&quot;table&quot;</span>: self.render_table,
            <span style="color: #66cc66;">&quot;tree&quot;</span>: self.render_tree,
            <span style="color: #66cc66;">&quot;status&quot;</span>: self.render_status,
            <span style="color: #66cc66;">&quot;progress&quot;</span>: self.render_progress,
            <span style="color: #66cc66;">&quot;code&quot;</span>: self.render_code,
            <span style="color: #66cc66;">&quot;diff&quot;</span>: self.render_diff,
            <span style="color: #66cc66;">&quot;text&quot;</span>: self.render_text,
            <span style="color: #66cc66;">&quot;separator&quot;</span>: self.render_separator,
            <span style="color: #66cc66;">&quot;action_hint&quot;</span>: self.render_action_hint,
        }
        handler = dispatch.get(element.element_type)
        <span style="color: magenta; font-weight: 600;">if</span> handler:
            handler(element, stream)
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">serialize</span>(self, output: StructuredOutput, stream: <span style="color: cyan;">IO</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Serialize a complete StructuredOutput to the stream.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Used by AccumulateMaterializer for json/yaml formats. For visual</span>
<span style="color: #66cc66;">        formats (plain/color/table/rich), this method iterates over</span>
<span style="color: #66cc66;">        output.elements and calls render_element for each.</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        ...
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">can_render</span>(self, terminal_caps: <span style="color: #66cc66;">&quot;TerminalCapabilities&quot;</span>) -&gt; <span style="color: cyan;">bool</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Whether this renderer can operate in the given terminal environment.&quot;&quot;&quot;</span>
        ...
</code></pre></div>

##### Format Resolution

The active format is resolved using a precedence chain:

1. **CLI flag**: `--format <value>` on the command line (highest priority).
2. **Environment variable**: `CLEVERAGENTS_FORMAT=<value>`.
3. **Config file**: The `core.format` key in the global config (`agents config set core.format <value>`).
4. **TTY detection**: If stdout is not a TTY and no explicit format was set, fall back to `plain` (not `rich`), since non-TTY consumers cannot interpret ANSI codes or cursor movement.
5. **Default**: `rich`.

Once the format is resolved, the CLI framework selects the corresponding `(MaterializationStrategy, ElementRenderer)` pair from the `RendererRegistry`, opens an `OutputSession` bound to that strategy, and passes the session to the command implementation.

#### Format Specifications

##### `plain` — Plain Text

**Philosophy**: Maximum portability. Output is pure ASCII text with no escape codes, no box-drawing characters, and no color. Suitable for piping to files, logs, grep, awk, or any non-terminal consumer.

**Rendering rules**:

- **Panels**: Rendered as indented key-value pairs with a header line.
- **Tables**: Rendered as aligned columns separated by whitespace (no box drawing). Column headers are separated from data by a dashed line.
- **Trees**: Rendered with ASCII indentation using `+--` and `|` characters.
- **Status messages**: Prefixed with `[OK]`, `[WARN]`, `[ERROR]`, `[INFO]`.
- **Progress**: Rendered as static status lines (no animation). Steps shown as `[x]` (done), `[ ]` (pending), `[>]` (active).
- **Diffs**: Standard unified diff format.
- **Code blocks**: Raw text with optional line numbers.
- **No ANSI escape codes** of any kind.
- **No Unicode characters** beyond basic ASCII (no box drawing, no checkmarks, no arrows).

**Example** (`agents --format plain project show local/api-service`):

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> plain project show local/api-service

Project Details
  Name: local/api-service
  Description: Backend API
  Resources: 2
  Remote: no
  Created: 2026-02-08 12:46

Linked Resources
  Resource          Type            Sandbox              Read-Only
  ----------------  --------------  --------------------  ---------
  local/api-repo    git-checkout    git_worktree          no
  local/staging-db  local/database  transaction_rollback  yes

Validations (3)
  local/run-tests    pytest <span style="color: cyan;">--cov</span>=src <span style="color: cyan;">--cov-fail-under</span>=80  required
  local/lint-check   ruff check .                          required
  local/check-bundle-size  node scripts/check-bundle-size.js     info

Context
  Include: repo
  Exclude: **/node_modules/**
  Max File Size: 1 MB

Indexing Status
  Text Index: ready
  Vector Index: ready
  Graph Store: disabled
  Indexed Files: 347
  Last Indexed: 12:48

Active Plans
  Plan ID   <span style="color: yellow; font-weight: 600;">Action</span>               Phase
  --------  -------------------  -------
  01HXM7A9  local/code-coverage  execute

<span style="color: #66cc66; font-weight: 600;">[OK]</span> Project loaded
</code></pre></div>

**Example** (`agents --format plain plan list`):

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> plain plan list <span style="color: cyan;">--phase</span> execute

Plans
  ID        Phase    State       <span style="color: yellow; font-weight: 600;">Action</span>               Project            Elapsed
  --------  -------  ----------  -------------------  -----------------  ---------
  01HXM7A9  execute  processing  local/code-coverage  local/api-service  00:01:12

Filters
  Phase: execute
  State: (any)
  Project: (any)
  <span style="color: yellow; font-weight: 600;">Action</span>: (any)

Summary
  Total: 1
  Processing: 1
  Completed: 0
  Errored: 0

<span style="color: #66cc66; font-weight: 600;">[OK]</span> 1 plan listed
</code></pre></div>

##### `color` — Colored Plain Text

**Philosophy**: Same structural layout as `plain`, but with ANSI color codes applied to improve readability. No box-drawing characters, no cursor movement, no animation.

**Rendering rules**:

- **Identical layout to `plain`**, but with color applied:
  - **Headers/titles**: Bold cyan.
  - **Keys**: Bold blue.
  - **Values**: Default color, with semantic coloring:
    - Success/positive: Green.
    - Warnings/attention: Yellow.
    - Errors/failures: Red.
    - Identifiers/names: Cyan.
    - Counts/numbers: Default (white).
  - **Table headers**: Bold cyan with underlines rendered as dim dashes.
  - **Status prefixes**: `[OK]` in green, `[WARN]` in yellow, `[ERROR]` in red, `[INFO]` in blue.
  - **Diff lines**: `+` lines green, `-` lines red, `@@` headers cyan.
- **No box-drawing characters** — uses the same whitespace/dash layout as `plain`.
- **No cursor movement or animation** — pure scrolling output.
- **Respects `NO_COLOR` environment variable**: If `NO_COLOR` is set, `color` format falls back to `plain`.

**Example** (`agents --format color project show local/api-service`):

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> color project show local/api-service

<span style="color: cyan; font-weight: 600;">Project Details</span>
  <span style="color: #5599ff; font-weight: 600;">Name:</span> <span style="color: cyan;">local/api-service</span>
  <span style="color: #5599ff; font-weight: 600;">Description:</span> Backend API
  <span style="color: #5599ff; font-weight: 600;">Resources:</span> <span style="color: yellow;">2</span>
  <span style="color: #5599ff; font-weight: 600;">Remote:</span> <span style="color: #66cc66;">no</span>
  <span style="color: #5599ff; font-weight: 600;">Created:</span> <span style="color: #66cc66;">2026-02-08 12:46</span>

<span style="color: cyan; font-weight: 600;">Linked Resources</span>
  <span style="color: cyan; font-weight: 600;">Resource</span>          <span style="color: cyan; font-weight: 600;">Type</span>            <span style="color: cyan; font-weight: 600;">Sandbox</span>              <span style="color: cyan; font-weight: 600;">Read-Only</span>
  <span style="opacity: 0.7;">----------------  --------------  --------------------  ---------</span>
  local/api-repo    git-checkout    git_worktree          no
  local/staging-db  local/database  transaction_rollback  yes

<span style="color: cyan; font-weight: 600;">Validations (3)</span>
  <span style="color: cyan;">local/run-tests</span>    pytest --cov=src --cov-fail-under=80  <span style="color: #66cc66;">required</span>
  <span style="color: cyan;">local/lint-check</span>   ruff check .                          <span style="color: #66cc66;">required</span>
  <span style="color: cyan;">local/check-bundle-size</span>  node scripts/check-bundle-size.js     <span style="color: yellow;">info</span>

<span style="color: cyan; font-weight: 600;">Context</span>
  <span style="color: #5599ff; font-weight: 600;">Include:</span> <span style="color: #66cc66;">repo</span>
  <span style="color: #5599ff; font-weight: 600;">Exclude:</span> <span style="color: yellow;">**/node_modules/**</span>
  <span style="color: #5599ff; font-weight: 600;">Max File Size:</span> 1 MB

<span style="color: cyan; font-weight: 600;">Indexing Status</span>
  <span style="color: #5599ff; font-weight: 600;">Text Index:</span> <span style="color: #66cc66;">ready</span>
  <span style="color: #5599ff; font-weight: 600;">Vector Index:</span> <span style="color: #66cc66;">ready</span>
  <span style="color: #5599ff; font-weight: 600;">Graph Store:</span> <span style="color: yellow;">disabled</span>
  <span style="color: #5599ff; font-weight: 600;">Indexed Files:</span> 347
  <span style="color: #5599ff; font-weight: 600;">Last Indexed:</span> 12:48

<span style="color: cyan; font-weight: 600;">Active Plans</span>
  <span style="color: cyan; font-weight: 600;">Plan ID</span>   <span style="color: cyan; font-weight: 600;">Action</span>               <span style="color: cyan; font-weight: 600;">Phase</span>
  <span style="opacity: 0.7;">--------  -------------------  -------</span>
  01HXM7A9  local/code-coverage  execute

<span style="color: #66cc66; font-weight: 600;">[OK]</span> Project loaded
</code></pre></div>

##### `table` — ASCII Box-Drawing Tables

**Philosophy**: Structured, visually distinct panels and tables using Unicode box-drawing characters (╭──────────────────╮╰╯│─). Uses color. This is the style shown in the existing CLI examples throughout this document.

**Rendering rules**:

- **Panels**: Rendered as bordered boxes with title in the top border. Uses `╭─╮│╰──────────────────╯` characters for rounded corners.
- **Tables**: Rendered inside bordered boxes with column-aligned headers and separator lines using `─` and `│`.
- **Trees**: Rendered inside a bordered box using `├──`, `└──`, `│` tree guide characters.
- **Status messages**: Use Unicode indicators: `✓` (green) for OK, `⚠` (yellow) for WARN, `✗` (red) for ERROR, `ℹ` (blue) for INFO.
- **Progress**: Rendered as a step list inside a panel with `✓`, `⏳`, `•` markers.
- **Color scheme**: Same semantic coloring as `color` format, applied within box structures.
- **No animation or cursor movement** — the boxes are static, scrolling output.

**Distinction from `rich`**: The `table` format uses the same box-drawing panels and color as `rich` for static content, but it does **not** use any dynamic or interactive terminal features. There are no animated spinners, no live-updating progress bars, no cursor movement, and no in-place redraws. All output is static and scrolls sequentially. Where `rich` would show a spinning `⠋` and a live progress bar, `table` renders a static snapshot using fixed markers (`✓`, `⏳`, `•`). This makes `table` suitable for terminals without advanced capabilities, and for output that will be reviewed after the fact (e.g., scrollback buffers).

**Example** (`agents --format table project show local/api-service`):

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> table project show local/api-service

╭─ Project Details ──────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/api-service        │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Backend API       │
│ <span style="color: yellow; font-weight: 600;">Resources:</span> 2                   │
│ <span style="color: #66cc66; font-weight: 600;">Remote:</span> no                     │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-08 12:46      │
╰────────────────────────────────╯

╭─ Linked Resources ──────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Resource</span>          <span style="color: cyan; font-weight: 600;">Type</span>            <span style="color: cyan; font-weight: 600;">Sandbox</span>              <span style="color: cyan; font-weight: 600;">Read-Only</span>        │
│ <span style="opacity: 0.7;">────────────────  ──────────────  ────────────────────  ─────────</span>       │
│ local/api-repo   git-checkout    git_worktree         no                │
│ local/staging-db local/database  transaction_rollback yes               │
╰─────────────────────────────────────────────────────────────────────────╯

╭─ Validations (3) ────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">local/run-tests</span>    pytest <span style="color: cyan;">--cov</span>=src <span style="color: cyan;">--cov-fail-under</span>=80  <span style="color: #66cc66; font-weight: 600;">required</span> │
│ <span style="color: cyan; font-weight: 600;">local/lint-check</span>   ruff check .                          <span style="color: #66cc66; font-weight: 600;">required</span> │
│ <span style="color: cyan; font-weight: 600;">local/check-bundle-size</span>  node scripts/check-bundle-size.js     <span style="color: yellow; font-weight: 600;">info</span>     │
╰──────────────────────────────────────────────────────────────────────╯

╭─ Context ───────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Include:</span> repo               │
│ <span style="color: yellow; font-weight: 600;">Exclude:</span> **/node_modules/** │
│ <span style="color: #5599ff; font-weight: 600;">Max File Size:</span> 1 MB         │
╰─────────────────────────────╯

╭─ Indexing Status ──────────╮
│ <span style="color: #66cc66; font-weight: 600;">Text Index:</span> ready          │
│ <span style="color: #66cc66; font-weight: 600;">Vector Index:</span> ready        │
│ <span style="color: yellow; font-weight: 600;">Graph Store:</span> disabled      │
│ <span style="color: #5599ff; font-weight: 600;">Indexed Files:</span> 347         │
│ <span style="color: #5599ff; font-weight: 600;">Last Indexed:</span> 12:48        │
╰────────────────────────────╯

╭─ Active Plans ──────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan ID</span>   <span style="color: cyan; font-weight: 600;">Action</span>               <span style="color: cyan; font-weight: 600;">Phase</span>    │
│ <span style="opacity: 0.7;">────────  ───────────────────  ───────</span>  │
│ 01HXM7A9  local/code-coverage  execute  │
╰─────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project loaded
</code></pre></div>

**Example** (`agents --format table plan execute 01HXM8C2ZK`):

Unlike `rich` mode which would show animated spinners and a live progress bar, the `table` format renders a static snapshot of execution state:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> table plan execute 01HXM8C2ZK

╭─ Execution ──────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> execute                   │
│ <span style="color: magenta; font-weight: 600;">Sandbox:</span> git_worktree            │
│ <span style="color: #5599ff; font-weight: 600;">Worker:</span> local/executor           │
│ <span style="color: #66cc66; font-weight: 600;">Started:</span> 12:58:10                │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                       │
╰──────────────────────────────────╯

╭─ Strategy Summary ─────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Decisions:</span> 8                           │
│ <span style="color: magenta; font-weight: 600;">Invariants:</span> 2                          │
│ <span style="color: #5599ff; font-weight: 600;">Planned Child Plans:</span> 2+                │
│ <span style="color: #5599ff; font-weight: 600;">Estimated Files:</span> ~12                   │
│ <span style="color: #5599ff; font-weight: 600;">Risk:</span> low                              │
╰────────────────────────────────────────╯

╭─ Progress ────────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Collect context │
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Run tools       │
│ <span style="color: cyan; font-weight: 600;">⏳</span> Build changeset │
│ <span style="color: yellow; font-weight: 600;">•</span> Validate        │
╰───────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Execution started
</code></pre></div>

##### `rich` — Modern Rich CLI Elements

**Philosophy**: The premium interactive terminal experience. Uses advanced terminal capabilities: cursor movement, inline updates, animated spinners, live-updating progress bars, collapsible sections, syntax highlighting, and dynamic layout. This is the default format.

**Rendering rules**:

- **Panels**: Rich bordered panels with rounded corners, title bars, and optional collapse/expand behavior. Panels may animate into view.
- **Tables**: Full-featured tables with automatic column sizing, truncation with ellipsis, sortable column indicators, alternating row shading, and horizontal scrolling for wide tables.
- **Trees**: Interactive collapsible trees. Nodes expand/collapse with visual animation. Color-coded by node type. Depth guides use dotted lines.
- **Status messages**: Use animated checkmarks/spinners that resolve to final state. Success messages may briefly flash or highlight.
- **Progress**: Live-updating progress bars with:
  - Animated spinners (Braille, dots, or bars depending on terminal capability).
  - Elapsed time and ETA.
  - Per-step status with animated transitions (pending → active → done).
  - Multi-line progress for parallel operations.
- **Diffs**: Syntax-highlighted side-by-side or unified diffs with line numbers, change highlighting at the character level (not just line level), and navigable hunks.
- **Code blocks**: Full syntax highlighting using terminal colors (256-color or truecolor when available). Line numbers in dim color. Highlighted lines with background color.
- **Dynamic layout**: Adapts to terminal width. Narrow terminals get a stacked layout; wide terminals get side-by-side panels.
- **Live updates**: Long-running commands (plan execute, plan status) use live-updating displays that redraw in place rather than scrolling.
- **Graceful degradation**: If the terminal does not support required capabilities (e.g., no truecolor, no cursor movement), the renderer automatically falls back to `table` rendering for those elements.

**Example** (`agents --format rich plan execute 01HXM8C2ZK`):

The `rich` format produces output that cannot be fully represented in static documentation — animated spinners cycle in place, progress bars fill smoothly, and elements update without scrolling. The rendering below is a static snapshot of what the terminal would display at a given moment:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> rich plan execute 01HXM8C2ZK

╭─ Execution ──────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> execute                   │
│ <span style="color: magenta; font-weight: 600;">Sandbox:</span> git_worktree            │
│ <span style="color: #5599ff; font-weight: 600;">Worker:</span> local/executor           │
│ <span style="color: #66cc66; font-weight: 600;">Started:</span> 12:58:10                │
╰──────────────────────────────────╯

<span style="color: cyan; font-weight: 600;">⠋</span> Collecting context...                      <span style="opacity: 0.5;">(⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏ animates in place)</span>
  ├── repo: local/api-repo <span style="color: #66cc66; font-weight: 600;">✓</span>
  └── db: local/staging-db <span style="color: #66cc66; font-weight: 600;">✓</span>

╭─ Strategy Summary ──────────────────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">8</span> decisions │ <span style="color: magenta; font-weight: 600;">2</span> invariants │ <span style="color: #5599ff; font-weight: 600;">2+</span> child plans │ <span style="color: #5599ff; font-weight: 600;">~12</span> files │ risk: <span style="color: #66cc66; font-weight: 600;">low</span>     │
╰─────────────────────────────────────────────────────────────────────────╯

<span style="color: cyan; font-weight: 600;">Progress</span> <span style="color: #66cc66;">━━━━━━━━━━━━━━━━</span><span style="opacity: 0.3;">━━━━━━━━━━━━━━━━━━━</span>  <span style="color: cyan; font-weight: 600;">42%</span>  <span style="opacity: 0.7;">elapsed 0:01:12  ETA 0:01:40</span>
  <span style="color: #66cc66; font-weight: 600;">✓</span> Collect context <span style="opacity: 0.5;">..................</span> <span style="color: #66cc66;">0.8s</span>
  <span style="color: #66cc66; font-weight: 600;">✓</span> Run tools (8 calls) <span style="opacity: 0.5;">.............</span> <span style="color: #66cc66;">12.4s</span>
  <span style="color: cyan; font-weight: 600;">⠙</span> Build changeset <span style="opacity: 0.5;">.................</span> <span style="color: yellow;">(running)</span>     <span style="opacity: 0.5;">(animates in place)</span>
  <span style="opacity: 0.5;">○</span> Validate <span style="opacity: 0.5;">........................</span> <span style="opacity: 0.5;">(pending)</span>

╭─ Live Tool Calls ───────────────────────────────────────╮
│ <span style="opacity: 0.7;">#6</span> read_file   <span style="color: #5599ff;">src/auth/__init__.py</span>   <span style="color: #66cc66; font-weight: 600;">✓</span>  <span style="opacity: 0.7;">0.1s</span>           │
│ <span style="opacity: 0.7;">#7</span> write_file  <span style="color: #5599ff;">tests/test_auth.py</span>     <span style="color: #66cc66; font-weight: 600;">✓</span>  <span style="opacity: 0.7;">0.2s</span>           │
│ <span style="opacity: 0.7;">#8</span> edit_file   <span style="color: #5599ff;">src/auth/session.py</span>    <span style="color: cyan; font-weight: 600;">⠙</span>  <span style="color: yellow;">...</span>            │
╰─────────────────────────────────────────────────────────╯
</code></pre></div>

In `rich` mode:
- The Braille spinner characters (`⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏`) animate in real-time, cycling in place without scrolling.
- The progress bar (`━━━`) fills smoothly as work completes.
- Completed steps appear with a green `✓` via in-place line update (the line rewrites, it does not scroll).
- The "Live Tool Calls" panel scrolls its content internally, showing only the most recent N calls.
- The terminal is not flooded with scrolling text — elements update in place using cursor movement.

**Example** (`agents --format rich version`):

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> rich version

╭─────────────────────────────────────╮
│  <span style="color: cyan; font-weight: 600;">CleverAgents CLI</span>  <span style="color: #5599ff; font-weight: 600;">v1.0.0</span>           │
│  <span style="opacity: 0.5;">channel: stable</span>                    │
╰─────────────────────────────────────╯

╭─ Build ─────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Build Date:</span> 2026-02-08              │
│ <span style="color: magenta; font-weight: 600;">Commit:</span> a17c3f9                     │
│ <span style="color: #5599ff; font-weight: 600;">Schema:</span> v3                          │
│ <span style="color: #5599ff; font-weight: 600;">Platform:</span> linux-x86_64              │
│ <span style="color: #5599ff; font-weight: 600;">Python:</span> 3.13.1                      │
╰─────────────────────────────────────╯

╭─ Dependencies ─────────────────────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">LangGraph</span> 0.2.60 │ <span style="color: #5599ff; font-weight: 600;">LangChain</span> 0.3.18 │ <span style="color: #5599ff; font-weight: 600;">MCP SDK</span> 1.4.0 │ <span style="color: #5599ff; font-weight: 600;">Pydantic</span> 2.10.4  │
╰────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Version reported
</code></pre></div>

In `rich` mode, the version card may use background colors, bold gradients, or subtle box shadows (depending on terminal truecolor support). Elements may animate into view with a brief slide or fade transition.

##### `json` — JSON Data Structure

**Philosophy**: Machine-readable output for programmatic consumption. Every command produces a well-defined JSON object. No ANSI color codes in the structural data. Color codes may appear only **within** text values that represent verbatim content (such as code blocks or diff output where the original text contained ANSI sequences), but all structural keys, labels, and metadata are plain strings.

**Rendering rules**:

- **Top-level structure**: Always a JSON object with a standard envelope:
  <div class="highlight"><pre><code>
  {
    <span style="color: cyan; font-weight: 600;">&quot;command&quot;</span>: <span style="color: #66cc66;">&quot;project show&quot;</span>,
    <span style="color: cyan; font-weight: 600;">&quot;status&quot;</span>: <span style="color: #66cc66;">&quot;ok&quot;</span>,
    <span style="color: cyan; font-weight: 600;">&quot;exit_code&quot;</span>: <span style="color: yellow;">0</span>,
    <span style="color: cyan; font-weight: 600;">&quot;data&quot;</span>: { ... },
    <span style="color: cyan; font-weight: 600;">&quot;timing&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;duration_ms&quot;</span>: <span style="color: yellow;">42</span> },
    <span style="color: cyan; font-weight: 600;">&quot;metadata&quot;</span>: { ... }
  }
  </code></pre></div>
- **Panels**: Rendered as nested objects within `data`.
- **Tables**: Rendered as arrays of objects within `data`.
- **Trees**: Rendered as nested objects with `children` arrays.
- **Status messages**: Included in a `messages` array within the envelope.
- **Progress**: Not rendered (JSON output is non-interactive; progress is omitted).
- **Diffs**: Rendered as structured objects with `hunks` arrays.
- **No ANSI codes** in any structural element. Raw ANSI codes are preserved only in string values that represent verbatim terminal output.
- **Pretty-printed** by default (indented). Compact mode available via `<span style="color: cyan;">--json-compact</span>` (future option).
- **Consistent schema per command**: Each command's JSON schema is stable and documented, enabling reliable programmatic parsing.

**Example** (`agents <span style="color: cyan;">--format</span> json project show local/api-service`):

<div class="highlight"><pre><code>
{
  <span style="color: cyan; font-weight: 600;">&quot;command&quot;</span>: <span style="color: #66cc66;">&quot;project show&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;status&quot;</span>: <span style="color: #66cc66;">&quot;ok&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;exit_code&quot;</span>: <span style="color: yellow;">0</span>,
  <span style="color: cyan; font-weight: 600;">&quot;data&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;project&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: <span style="color: #66cc66;">&quot;local/api-service&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Backend API&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;local&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;remote&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
      <span style="color: cyan; font-weight: 600;">&quot;created_at&quot;</span>: <span style="color: #66cc66;">&quot;2026-02-08T12:46:00Z&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;linked_resources&quot;</span>: [
      {
        <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: <span style="color: #66cc66;">&quot;local/api-repo&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;git-checkout&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;sandbox_strategy&quot;</span>: <span style="color: #66cc66;">&quot;git_worktree&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;read_only&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
      },
      {
        <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: <span style="color: #66cc66;">&quot;local/staging-db&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;local/database&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;sandbox_strategy&quot;</span>: <span style="color: #66cc66;">&quot;transaction_rollback&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;read_only&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>
      }
    ],
    <span style="color: cyan; font-weight: 600;">&quot;validations&quot;</span>: [
      {
        <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: <span style="color: #66cc66;">&quot;local/run-tests&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;command&quot;</span>: <span style="color: #66cc66;">&quot;pytest --cov=src --cov-fail-under=80&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;mode&quot;</span>: <span style="color: #66cc66;">&quot;required&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;timeout&quot;</span>: <span style="color: yellow;">600</span>,
        <span style="color: cyan; font-weight: 600;">&quot;resource&quot;</span>: <span style="color: #66cc66;">&quot;repo&quot;</span>
      },
      {
        <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: <span style="color: #66cc66;">&quot;local/lint-check&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;command&quot;</span>: <span style="color: #66cc66;">&quot;ruff check .&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;mode&quot;</span>: <span style="color: #66cc66;">&quot;required&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;timeout&quot;</span>: <span style="color: yellow;">300</span>,
        <span style="color: cyan; font-weight: 600;">&quot;resource&quot;</span>: <span style="color: magenta; font-weight: 600;">null</span>
      },
      {
        <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: <span style="color: #66cc66;">&quot;local/check-bundle-size&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;command&quot;</span>: <span style="color: #66cc66;">&quot;node scripts/check-bundle-size.js&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;mode&quot;</span>: <span style="color: #66cc66;">&quot;informational&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;timeout&quot;</span>: <span style="color: yellow;">300</span>,
        <span style="color: cyan; font-weight: 600;">&quot;resource&quot;</span>: <span style="color: magenta; font-weight: 600;">null</span>
      }
    ],
    <span style="color: cyan; font-weight: 600;">&quot;context&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;include_resources&quot;</span>: [<span style="color: #66cc66;">&quot;repo&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;exclude_paths&quot;</span>: [<span style="color: #66cc66;">&quot;**/node_modules/**&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;max_file_size_bytes&quot;</span>: <span style="color: yellow;">1048576</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;indexing&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;text_index&quot;</span>: <span style="color: #66cc66;">&quot;ready&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;vector_index&quot;</span>: <span style="color: #66cc66;">&quot;ready&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;graph_store&quot;</span>: <span style="color: #66cc66;">&quot;disabled&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;indexed_files&quot;</span>: <span style="color: yellow;">347</span>,
      <span style="color: cyan; font-weight: 600;">&quot;last_indexed_at&quot;</span>: <span style="color: #66cc66;">&quot;2026-02-08T12:48:00Z&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;active_plans&quot;</span>: [
      {
        <span style="color: cyan; font-weight: 600;">&quot;plan_id&quot;</span>: <span style="color: #66cc66;">&quot;01HXM7A9&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;action&quot;</span>: <span style="color: #66cc66;">&quot;local/code-coverage&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;phase&quot;</span>: <span style="color: #66cc66;">&quot;execute&quot;</span>
      }
    ]
  },
  <span style="color: cyan; font-weight: 600;">&quot;timing&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;duration_ms&quot;</span>: <span style="color: yellow;">42</span>
  },
  <span style="color: cyan; font-weight: 600;">&quot;messages&quot;</span>: [
    { <span style="color: cyan; font-weight: 600;">&quot;level&quot;</span>: <span style="color: #66cc66;">&quot;ok&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;text&quot;</span>: <span style="color: #66cc66;">&quot;Project loaded&quot;</span> }
  ]
}
</code></pre></div>

**Example** (`agents --format json plan list --phase execute`):

<div class="highlight"><pre><code>
{
  <span style="color: cyan; font-weight: 600;">&quot;command&quot;</span>: <span style="color: #66cc66;">&quot;plan list&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;status&quot;</span>: <span style="color: #66cc66;">&quot;ok&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;exit_code&quot;</span>: <span style="color: yellow;">0</span>,
  <span style="color: cyan; font-weight: 600;">&quot;data&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;plans&quot;</span>: [
      {
        <span style="color: cyan; font-weight: 600;">&quot;id&quot;</span>: <span style="color: #66cc66;">&quot;01HXM7A9&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;phase&quot;</span>: <span style="color: #66cc66;">&quot;execute&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;state&quot;</span>: <span style="color: #66cc66;">&quot;processing&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;action&quot;</span>: <span style="color: #66cc66;">&quot;local/code-coverage&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;project&quot;</span>: <span style="color: #66cc66;">&quot;local/api-service&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;elapsed&quot;</span>: <span style="color: #66cc66;">&quot;00:01:12&quot;</span>
      }
    ],
    <span style="color: cyan; font-weight: 600;">&quot;filters&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;phase&quot;</span>: <span style="color: #66cc66;">&quot;execute&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;state&quot;</span>: <span style="color: magenta; font-weight: 600;">null</span>,
      <span style="color: cyan; font-weight: 600;">&quot;project&quot;</span>: <span style="color: magenta; font-weight: 600;">null</span>,
      <span style="color: cyan; font-weight: 600;">&quot;action&quot;</span>: <span style="color: magenta; font-weight: 600;">null</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;summary&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;total&quot;</span>: <span style="color: yellow;">1</span>,
      <span style="color: cyan; font-weight: 600;">&quot;processing&quot;</span>: <span style="color: yellow;">1</span>,
      <span style="color: cyan; font-weight: 600;">&quot;completed&quot;</span>: <span style="color: yellow;">0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;errored&quot;</span>: <span style="color: yellow;">0</span>
    }
  },
  <span style="color: cyan; font-weight: 600;">&quot;timing&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;duration_ms&quot;</span>: <span style="color: yellow;">18</span>
  },
  <span style="color: cyan; font-weight: 600;">&quot;messages&quot;</span>: [
    { <span style="color: cyan; font-weight: 600;">&quot;level&quot;</span>: <span style="color: #66cc66;">&quot;ok&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;text&quot;</span>: <span style="color: #66cc66;">&quot;1 plan listed&quot;</span> }
  ]
}
</code></pre></div>

##### `yaml` — YAML Data Structure

**Philosophy**: Same data as `json` but in YAML format. Preferred by users who find YAML more readable for configuration and scripting workflows. Follows the same structural conventions as `json`.

**Rendering rules**:

- **Same data envelope** as JSON (`command`, `status`, `exit_code`, `data`, `timing`, `messages`).
- **YAML 1.2 compliant** output.
- **Multi-line strings** use YAML block scalars (`|` for literal, `>` for folded) when appropriate.
- **No ANSI codes** in structural elements (same rule as JSON).
- **Sorted keys** for deterministic output.

**Example** (`agents --format yaml project show local/api-service`):

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">command</span>: project show
<span style="color: cyan; font-weight: 600;">status</span>: ok
<span style="color: cyan; font-weight: 600;">exit_code</span>: <span style="color: yellow;">0</span>
<span style="color: cyan; font-weight: 600;">data</span>:
  <span style="color: cyan; font-weight: 600;">project</span>:
    <span style="color: cyan; font-weight: 600;">name</span>: local/api-service
    <span style="color: cyan; font-weight: 600;">description</span>: Backend API
    <span style="color: cyan; font-weight: 600;">type</span>: local
    <span style="color: cyan; font-weight: 600;">remote</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">created_at</span>: <span style="color: #66cc66;">&quot;2026-02-08T12:46:00Z&quot;</span>
  <span style="color: cyan; font-weight: 600;">linked_resources</span>:
    - <span style="color: cyan;">name</span>: local/api-repo
      <span style="color: cyan; font-weight: 600;">type</span>: git-checkout
      <span style="color: cyan; font-weight: 600;">sandbox_strategy</span>: git_worktree
      <span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">false</span>
    - <span style="color: cyan;">name</span>: local/staging-db
      <span style="color: cyan; font-weight: 600;">type</span>: local/database
      <span style="color: cyan; font-weight: 600;">sandbox_strategy</span>: transaction_rollback
      <span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">true</span>
  <span style="color: cyan; font-weight: 600;">validations</span>:
    - <span style="color: cyan;">name</span>: local/run-tests
      <span style="color: cyan; font-weight: 600;">command</span>: <span style="color: #66cc66;">&quot;pytest --cov=src --cov-fail-under=80&quot;</span>
      <span style="color: cyan; font-weight: 600;">mode</span>: required
      <span style="color: cyan; font-weight: 600;">timeout</span>: <span style="color: yellow;">600</span>
      <span style="color: cyan; font-weight: 600;">resource</span>: repo
    - <span style="color: cyan;">name</span>: local/lint-check
      <span style="color: cyan; font-weight: 600;">command</span>: <span style="color: #66cc66;">&quot;ruff check .&quot;</span>
      <span style="color: cyan; font-weight: 600;">mode</span>: required
      <span style="color: cyan; font-weight: 600;">timeout</span>: <span style="color: yellow;">300</span>
      <span style="color: cyan; font-weight: 600;">resource</span>: <span style="color: magenta; font-weight: 600;">null</span>
    - <span style="color: cyan;">name</span>: local/check-bundle-size
      <span style="color: cyan; font-weight: 600;">command</span>: <span style="color: #66cc66;">&quot;node scripts/check-bundle-size.js&quot;</span>
      <span style="color: cyan; font-weight: 600;">mode</span>: informational
      <span style="color: cyan; font-weight: 600;">timeout</span>: <span style="color: yellow;">300</span>
      <span style="color: cyan; font-weight: 600;">resource</span>: <span style="color: magenta; font-weight: 600;">null</span>
  <span style="color: cyan; font-weight: 600;">context</span>:
    <span style="color: cyan; font-weight: 600;">include_resources</span>:
      - repo
    <span style="color: cyan; font-weight: 600;">exclude_paths</span>:
      - &quot;**/node_modules/**&quot;
    <span style="color: cyan; font-weight: 600;">max_file_size_bytes</span>: <span style="color: yellow;">1048576</span>
  <span style="color: cyan; font-weight: 600;">indexing</span>:
    <span style="color: cyan; font-weight: 600;">text_index</span>: ready
    <span style="color: cyan; font-weight: 600;">vector_index</span>: ready
    <span style="color: cyan; font-weight: 600;">graph_store</span>: disabled
    <span style="color: cyan; font-weight: 600;">indexed_files</span>: <span style="color: yellow;">347</span>
    <span style="color: cyan; font-weight: 600;">last_indexed_at</span>: <span style="color: #66cc66;">&quot;2026-02-08T12:48:00Z&quot;</span>
  <span style="color: cyan; font-weight: 600;">active_plans</span>:
    - <span style="color: cyan;">plan_id</span>: 01HXM7A9
      <span style="color: cyan; font-weight: 600;">action</span>: local/code-coverage
      <span style="color: cyan; font-weight: 600;">phase</span>: execute
<span style="color: cyan; font-weight: 600;">timing</span>:
  <span style="color: cyan; font-weight: 600;">duration_ms</span>: <span style="color: yellow;">42</span>
<span style="color: cyan; font-weight: 600;">messages</span>:
  - <span style="color: cyan;">level</span>: ok
    <span style="color: cyan; font-weight: 600;">text</span>: Project loaded
</code></pre></div>

#### Format Comparison Matrix

| Capability | `plain` | `color` | `table` | `rich` | `json` | `yaml` |
|---|---|---|---|---|---|---|
| Color codes | No | Yes | Yes | Yes | No | No |
| Box drawing | No | No | Yes | Yes | No | No |
| Animation/spinners | No | No | No | Yes | No | No |
| Live updates | No | No | No | Yes | No | No |
| Cursor movement | No | No | No | Yes | No | No |
| Syntax highlighting | No | No | No | Yes | No | No |
| Collapsible sections | No | No | No | Yes | No | No |
| Machine-parseable | Partially | Partially | No | No | Yes | Yes |
| Pipe-safe | Yes | No* | No | No | Yes | Yes |
| Unicode required | No | No | Yes | Yes | No | No |
| TTY required | No | No | No | Yes** | No | No |

\* `color` output can be piped if the consumer understands ANSI codes (e.g., `less -R`).
\** `rich` gracefully degrades to `table` when stdout is not a TTY.

#### Renderer Registration and Extension

The framework uses a **registry pattern** for format renderers, enabling third-party or plugin renderers. Each format is registered as a `(MaterializationStrategy, ElementRenderer)` pair — the strategy controls timing/ordering, and the renderer controls visual formatting:

<div class="highlight"><pre><code>
<span style="color: yellow;">@dataclass</span>
<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">FormatRegistration</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;A registered format: its strategy factory, renderer factory, and fallback.&quot;&quot;&quot;</span>
    strategy_factory: <span style="color: cyan;">Callable</span>[[TerminalCapabilities], MaterializationStrategy]
    renderer_factory: <span style="color: cyan;">Callable</span>[[TerminalCapabilities], ElementRenderer]
    fallback: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span>                 <span style="opacity: 0.7;"># Format name to fall back to, or None</span>


<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">RendererRegistry</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;Central registry for format (strategy, renderer) pairs.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Formats are registered by name and resolved at runtime based on the</span>
<span style="color: #66cc66;">    active format and terminal capabilities. The registry supports dynamic</span>
<span style="color: #66cc66;">    registration, enabling plugins to add custom formats (e.g., &#x27;html&#x27;,</span>
<span style="color: #66cc66;">    &#x27;csv&#x27;, &#x27;markdown&#x27;).</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    Built-in registrations:</span>
<span style="color: #66cc66;">        &quot;rich&quot;  → (LiveMaterializer, RichElementRenderer), fallback=&quot;table&quot;</span>
<span style="color: #66cc66;">        &quot;table&quot; → (SequentialBufferMaterializer, TableElementRenderer), fallback=&quot;color&quot;</span>
<span style="color: #66cc66;">        &quot;color&quot; → (SequentialBufferMaterializer, ColorElementRenderer), fallback=&quot;plain&quot;</span>
<span style="color: #66cc66;">        &quot;plain&quot; → (SequentialBufferMaterializer, PlainElementRenderer), fallback=None</span>
<span style="color: #66cc66;">        &quot;json&quot;  → (AccumulateMaterializer, JsonElementRenderer), fallback=None</span>
<span style="color: #66cc66;">        &quot;yaml&quot;  → (AccumulateMaterializer, YamlElementRenderer), fallback=None</span>
<span style="color: #66cc66;">    &quot;&quot;&quot;</span>
    
    _formats: <span style="color: cyan;">dict</span>[<span style="color: cyan;">str</span>, FormatRegistration] = {}
    
    <span style="color: yellow;">@classmethod</span>
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">register</span>(cls, format_name: <span style="color: cyan;">str</span>,
                 strategy_factory: <span style="color: cyan;">Callable</span>[[TerminalCapabilities], MaterializationStrategy],
                 renderer_factory: <span style="color: cyan;">Callable</span>[[TerminalCapabilities], ElementRenderer],
                 fallback: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span> = <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Register a format.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Args:</span>
<span style="color: #66cc66;">            format_name: The format identifier (e.g., &#x27;rich&#x27;, &#x27;json&#x27;).</span>
<span style="color: #66cc66;">            strategy_factory: Callable that creates a MaterializationStrategy,</span>
<span style="color: #66cc66;">                given terminal capabilities.</span>
<span style="color: #66cc66;">            renderer_factory: Callable that creates an ElementRenderer,</span>
<span style="color: #66cc66;">                given terminal capabilities.</span>
<span style="color: #66cc66;">            fallback: Optional fallback format name if this format cannot</span>
<span style="color: #66cc66;">                operate in the current terminal environment.</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        cls._formats[format_name] = FormatRegistration(
            strategy_factory=strategy_factory,
            renderer_factory=renderer_factory,
            fallback=fallback,
        )
    
    <span style="color: yellow;">@classmethod</span>
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">resolve</span>(cls, format_name: <span style="color: cyan;">str</span>,
                terminal_caps: TerminalCapabilities
                ) -&gt; <span style="color: cyan;">tuple</span>[MaterializationStrategy, ElementRenderer]:
        <span style="color: #66cc66;">&quot;&quot;&quot;Resolve the best (strategy, renderer) pair for the given format.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Walks the fallback chain if the requested format&#x27;s renderer cannot</span>
<span style="color: #66cc66;">        operate in the current terminal environment. Returns the first pair</span>
<span style="color: #66cc66;">        where the renderer reports can_render(terminal_caps) == True.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Raises:</span>
<span style="color: #66cc66;">            ValueError: If no usable format is found (should never happen</span>
<span style="color: #66cc66;">                since &#x27;plain&#x27; has no fallback and always works).</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        current = format_name
        visited: <span style="color: cyan;">set</span>[<span style="color: cyan;">str</span>] = <span style="color: cyan;">set</span>()
        
        <span style="color: magenta; font-weight: 600;">while</span> current <span style="color: magenta; font-weight: 600;">and</span> current <span style="color: magenta; font-weight: 600;">not</span> <span style="color: magenta; font-weight: 600;">in</span> visited:
            visited.add(current)
            registration = cls._formats.get(current)
            <span style="color: magenta; font-weight: 600;">if</span> registration <span style="color: magenta; font-weight: 600;">is</span> <span style="color: magenta; font-weight: 600;">None</span>:
                <span style="color: magenta; font-weight: 600;">break</span>
            
            renderer = registration.renderer_factory(terminal_caps)
            <span style="color: magenta; font-weight: 600;">if</span> renderer.can_render(terminal_caps):
                strategy = registration.strategy_factory(terminal_caps)
                strategy.bind(renderer, terminal_caps=terminal_caps)
                <span style="color: magenta; font-weight: 600;">return</span> strategy, renderer
            
            current = registration.fallback
        
        <span style="opacity: 0.7;"># Ultimate fallback is always plain</span>
        plain = cls._formats[<span style="color: #66cc66;">&quot;plain&quot;</span>]
        renderer = plain.renderer_factory(terminal_caps)
        strategy = plain.strategy_factory(terminal_caps)
        strategy.bind(renderer, terminal_caps=terminal_caps)
        <span style="color: magenta; font-weight: 600;">return</span> strategy, renderer
    
    <span style="color: yellow;">@classmethod</span>
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">available_formats</span>(cls) -&gt; <span style="color: cyan;">list</span>[<span style="color: cyan;">str</span>]:
        <span style="color: #66cc66;">&quot;&quot;&quot;Return all registered format names.&quot;&quot;&quot;</span>
        <span style="color: magenta; font-weight: 600;">return</span> sorted(cls._formats.keys())
    
    <span style="color: yellow;">@classmethod</span>
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">is_registered</span>(cls, format_name: <span style="color: cyan;">str</span>) -&gt; <span style="color: cyan;">bool</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Check if a format is registered.&quot;&quot;&quot;</span>
        <span style="color: magenta; font-weight: 600;">return</span> format_name <span style="color: magenta; font-weight: 600;">in</span> cls._formats
</code></pre></div>

##### Terminal Capability Detection

The framework detects terminal capabilities to guide format resolution, strategy selection, and renderer fallback:

<div class="highlight"><pre><code>
<span style="color: yellow;">@dataclass</span>
<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">TerminalCapabilities</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;Detected capabilities of the output terminal.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    This dataclass is populated once at CLI startup and passed to the</span>
<span style="color: #66cc66;">    RendererRegistry for format resolution. It is also available to</span>
<span style="color: #66cc66;">    individual strategies and renderers for fine-grained adaptation</span>
<span style="color: #66cc66;">    (e.g., adjusting column widths to terminal width, choosing between</span>
<span style="color: #66cc66;">    256-color and truecolor palettes).</span>
<span style="color: #66cc66;">    &quot;&quot;&quot;</span>
    is_tty: <span style="color: cyan;">bool</span>                         <span style="opacity: 0.7;"># Is stdout a TTY?</span>
    width: <span style="color: cyan;">int</span>                           <span style="opacity: 0.7;"># Terminal width in columns</span>
    height: <span style="color: cyan;">int</span>                          <span style="opacity: 0.7;"># Terminal height in rows</span>
    supports_ansi: <span style="color: cyan;">bool</span>                  <span style="opacity: 0.7;"># Supports basic ANSI escape codes?</span>
    supports_256_color: <span style="color: cyan;">bool</span>             <span style="opacity: 0.7;"># Supports 256-color palette?</span>
    supports_truecolor: <span style="color: cyan;">bool</span>             <span style="opacity: 0.7;"># Supports 24-bit truecolor?</span>
    supports_unicode: <span style="color: cyan;">bool</span>               <span style="opacity: 0.7;"># Supports Unicode (box-drawing, etc.)?</span>
    supports_cursor_movement: <span style="color: cyan;">bool</span>       <span style="opacity: 0.7;"># Supports cursor repositioning?</span>
    supports_alternate_screen: <span style="color: cyan;">bool</span>      <span style="opacity: 0.7;"># Supports alternate screen buffer?</span>
    no_color: <span style="color: cyan;">bool</span>                       <span style="opacity: 0.7;"># Is NO_COLOR environment variable set?</span>
    term_program: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span>             <span style="opacity: 0.7;"># TERM_PROGRAM value (e.g., &quot;iTerm2&quot;, &quot;vscode&quot;)</span>
    
    <span style="color: yellow;">@classmethod</span>
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">detect</span>(cls) -&gt; <span style="color: #66cc66;">&quot;TerminalCapabilities&quot;</span>:
        <span style="color: #66cc66;">&quot;&quot;&quot;Auto-detect terminal capabilities from the environment.</span>
<span style="color: #66cc66;">        </span>
<span style="color: #66cc66;">        Detection logic:</span>
<span style="color: #66cc66;">        - is_tty: os.isatty(sys.stdout.fileno())</span>
<span style="color: #66cc66;">        - width/height: os.get_terminal_size() with fallback to (80, 24)</span>
<span style="color: #66cc66;">        - supports_ansi: True if is_tty and not Windows legacy console</span>
<span style="color: #66cc66;">        - supports_256_color: True if TERM contains &quot;256color&quot; or COLORTERM is set</span>
<span style="color: #66cc66;">        - supports_truecolor: True if COLORTERM is &quot;truecolor&quot; or &quot;24bit&quot;</span>
<span style="color: #66cc66;">        - supports_unicode: True if locale encoding is UTF-8</span>
<span style="color: #66cc66;">        - supports_cursor_movement: True if is_tty and TERM is not &quot;dumb&quot;</span>
<span style="color: #66cc66;">        - supports_alternate_screen: True if supports_cursor_movement</span>
<span style="color: #66cc66;">        - no_color: True if NO_COLOR environment variable is set (any value)</span>
<span style="color: #66cc66;">        - term_program: Value of TERM_PROGRAM environment variable</span>
<span style="color: #66cc66;">        &quot;&quot;&quot;</span>
        ...
</code></pre></div>

##### Plugin Format Registration

Third-party plugins can register custom formats using the registry:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Example: Registering a custom &#x27;csv&#x27; format plugin</span>
<span style="color: magenta; font-weight: 600;">from</span> cleveragents.output <span style="color: magenta; font-weight: 600;">import</span> RendererRegistry, SequentialBufferMaterializer

<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">CsvElementRenderer</span>(ElementRenderer):
    <span style="color: #66cc66;">&quot;&quot;&quot;Renders tables as CSV, other elements as plain text.&quot;&quot;&quot;</span>
    format_name = <span style="color: #66cc66;">&quot;csv&quot;</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">render_table</span>(self, table: Table, stream: <span style="color: cyan;">IO</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
        writer = csv.writer(stream)
        writer.writerow([col.name <span style="color: magenta; font-weight: 600;">for</span> col <span style="color: magenta; font-weight: 600;">in</span> table.columns])
        <span style="color: magenta; font-weight: 600;">for</span> row <span style="color: magenta; font-weight: 600;">in</span> table.rows:
            writer.writerow([row.get(col.name, <span style="color: #66cc66;">&quot;&quot;</span>) <span style="color: magenta; font-weight: 600;">for</span> col <span style="color: magenta; font-weight: 600;">in</span> table.columns])
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">can_render</span>(self, terminal_caps: TerminalCapabilities) -&gt; <span style="color: cyan;">bool</span>:
        <span style="color: magenta; font-weight: 600;">return</span> <span style="color: magenta; font-weight: 600;">True</span>  <span style="opacity: 0.7;"># CSV works everywhere</span>

<span style="opacity: 0.7;"># Register at plugin load time</span>
RendererRegistry.register(
    format_name=<span style="color: #66cc66;">&quot;csv&quot;</span>,
    strategy_factory=<span style="color: magenta; font-weight: 600;">lambda</span> caps: SequentialBufferMaterializer(),
    renderer_factory=<span style="color: magenta; font-weight: 600;">lambda</span> caps: CsvElementRenderer(),
    fallback=<span style="color: #66cc66;">&quot;plain&quot;</span>,
)
</code></pre></div>

#### Edge Cases and Special Behaviors

##### Error Output

Errors are rendered through the same framework. When a command raises an exception or signals an error, the session's context manager (`__exit__`) catches the exception, creates a `StatusMessage` with `level="error"` and an optional `TextBlock` with details, and closes the session with `exit_code=1`. In `json`/`yaml` formats, errors produce:

<div class="highlight"><pre><code>
{
  <span style="color: cyan; font-weight: 600;">&quot;command&quot;</span>: <span style="color: #66cc66;">&quot;project show&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;status&quot;</span>: <span style="color: #66cc66;">&quot;error&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;exit_code&quot;</span>: <span style="color: yellow;">1</span>,
  <span style="color: cyan; font-weight: 600;">&quot;error&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;code&quot;</span>: <span style="color: #66cc66;">&quot;NOT_FOUND&quot;</span>,
    <span style="color: cyan; font-weight: 600;">&quot;message&quot;</span>: <span style="color: #66cc66;">&quot;Project &#x27;local/nonexistent&#x27; not found&quot;</span>,
    <span style="color: cyan; font-weight: 600;">&quot;detail&quot;</span>: <span style="color: #66cc66;">&quot;No project with name &#x27;local/nonexistent&#x27; exists. Run &#x27;agents project list&#x27; to see available projects.&quot;</span>,
    <span style="color: cyan; font-weight: 600;">&quot;suggestions&quot;</span>: [
      <span style="color: #66cc66;">&quot;agents project list&quot;</span>,
      <span style="color: #66cc66;">&quot;agents project create local/nonexistent&quot;</span>
    ]
  },
  <span style="color: cyan; font-weight: 600;">&quot;timing&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;duration_ms&quot;</span>: <span style="color: yellow;">5</span> }
}
</code></pre></div>

##### Empty Results

When a list command returns no results, all formats handle it gracefully:

- **plain/color**: Prints a message like `No projects found.`
- **table**: Renders an empty table with headers and a `(empty)` message.
- **rich**: Renders a dimmed panel with an empty-state message and suggested actions.
- **json/yaml**: Returns an empty array in the appropriate data field.

##### Large Data Sets

For commands that may return large result sets (e.g., `resource list` with thousands of resources):

- **plain/color/table** (SequentialBufferMaterializer): The table handle accumulates rows as the producer adds them. Since the buffer is in-memory, very large result sets benefit from the `max_rows_hint` — the renderer truncates display at N rows with a `(... and N more rows)` indicator. The full data is still available in the snapshot for json/yaml.
- **rich** (LiveMaterializer): Uses a virtual-scrolling table that renders only visible rows. Shows a count indicator (e.g., "Showing 1-50 of 2,847"). New rows animate into view as they are added.
- **json/yaml** (AccumulateMaterializer): Accumulates and emits a complete array at session end. Streaming JSON lines (one JSON object per row) for very large sets is a future consideration.

##### Nested/Recursive Structures

Tree-like data (resource trees, decision trees, plan hierarchies) may be arbitrarily deep. Renderers respect `max_depth_hint`:

- **plain/color**: Truncate at depth N with a `... (N more levels)` indicator.
- **table**: Same truncation, rendered inside a box.
- **rich**: Collapsible tree nodes — deep levels start collapsed. User can expand interactively if the terminal supports it.
- **json/yaml**: Full depth — no truncation (programmatic consumers need complete data).

##### Mixed Content

Some commands produce mixed output (e.g., `plan status` has panels, tables, progress bars, and status messages). Each element is created via its own handle on the session, and the materialization strategy renders them in declaration order. The `ElementRenderer` is responsible for visual spacing and grouping between heterogeneous elements (e.g., inserting blank lines between a panel and a table in `plain` format, or adding visual margins in `rich` format).

##### Producer Error Mid-Stream

When a producer encounters an error while writing to a handle (e.g., an API call fails while populating a table), the framework handles it as follows:

1. **The handle is closed with partial data** — the producer catches its exception, optionally calls `handle.close()` (or lets the context manager close it), and then creates a `StatusMessage` handle with `level="error"` to report the failure.

2. **The materialization strategy renders whatever was accumulated** — a table with 3 of an expected 10 rows is rendered with those 3 rows, followed by the error message. This is better than rendering nothing.

3. **The session's exit code is set to 1** — indicating partial failure.

4. **For `json`/`yaml` formats**, the accumulated snapshot includes both the partial data and the error message in the `messages` array, giving programmatic consumers full visibility.

Example of producer error handling:

<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">async</span> <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">list_resources</span>(session: OutputSession, client: ApiClient) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
    table = session.table(<span style="color: #66cc66;">&quot;Resources&quot;</span>, columns=[
        ColumnDef(name=<span style="color: #66cc66;">&quot;Name&quot;</span>), ColumnDef(name=<span style="color: #66cc66;">&quot;Type&quot;</span>), ColumnDef(name=<span style="color: #66cc66;">&quot;Status&quot;</span>),
    ])
    
    <span style="color: magenta; font-weight: 600;">try</span>:
        <span style="color: magenta; font-weight: 600;">async</span> <span style="color: magenta; font-weight: 600;">for</span> resource <span style="color: magenta; font-weight: 600;">in</span> client.list_resources():
            table.add_row({
                <span style="color: #66cc66;">&quot;Name&quot;</span>: resource.name,
                <span style="color: #66cc66;">&quot;Type&quot;</span>: resource.type,
                <span style="color: #66cc66;">&quot;Status&quot;</span>: resource.status,
            })
    <span style="color: magenta; font-weight: 600;">except</span> ApiError <span style="color: magenta; font-weight: 600;">as</span> e:
        table.close()  <span style="opacity: 0.7;"># Close with partial data</span>
        session.status(<span style="color: #66cc66;">f&quot;Error fetching resources: {e}&quot;</span>, level=<span style="color: #66cc66;">&quot;error&quot;</span>)
        <span style="color: magenta; font-weight: 600;">return</span>
    
    table.close()
    session.status(<span style="color: #66cc66;">f&quot;{table.element.row_count} resources listed&quot;</span>, level=<span style="color: #66cc66;">&quot;ok&quot;</span>)
</code></pre></div>

##### Abandoned Handles

If a handle is never explicitly closed and the session ends (either normally via `session.close()` or via the context manager's `__exit__`), the session force-closes all remaining open handles:

1. A warning is logged (not rendered to the user): `"Handle {handle_id} ({element_type}) was not explicitly closed; force-closing at session end."`
2. The handle is closed with its current accumulated state.
3. The materialization strategy processes the `ElementClosed` event normally.

This ensures that no data is silently lost, even if producer code forgets to close a handle due to an unhandled code path.

##### Back-Pressure and Throttling

The `LiveMaterializer` (used by `rich` format) limits terminal redraws to its configured frame rate (default 15 fps). When handles emit updates faster than the frame rate:

1. Updates are coalesced — the materializer tracks a **dirty set** of handle IDs that have been updated since the last frame.
2. On each frame tick, all dirty elements are redrawn in a single pass, and the dirty set is cleared.
3. The event queue between session and strategy uses bounded capacity. If the queue fills (producer is vastly faster than rendering), the session's `_emit_event` method drops `ElementUpdated` events for handles that are already in the dirty set (since the next frame will redraw them anyway). `ElementCreated` and `ElementClosed` events are never dropped.

For `SequentialBufferMaterializer` and `AccumulateMaterializer`, there is no back-pressure concern — updates are buffered in memory and never rendered incrementally.

##### Cancellation Semantics

When a command is cancelled (e.g., user presses Ctrl+C):

1. The session receives a cancellation signal and enters the `"closing"` state.
2. All open handles are force-closed with their current state.
3. A `StatusMessage` with `level="warn"` and message `"Operation cancelled"` is emitted.
4. The session closes with `exit_code=130` (standard SIGINT exit code).
5. **For `rich` format**: The `LiveMaterializer` freezes the display, resolves any active spinners to a cancellation indicator (e.g., yellow `⚠`), and moves the cursor to the end of the output.
6. **For buffered formats**: Any elements that have been rendered stay on screen. Pending buffered elements are flushed in order, followed by the cancellation message.
7. **For `json`/`yaml`**: The accumulated snapshot is serialized with `"status": "cancelled"` and the appropriate exit code.

##### Interleaved Status Messages During Concurrent Production

When multiple producers are running concurrently (e.g., populating two tables), status messages may be created at any time by any producer. The materialization strategy handles these based on format:

- **`rich`** (LiveMaterializer): Status messages are rendered immediately in a dedicated status region at the bottom of the display (below all element regions). Multiple concurrent status messages stack vertically.
- **`plain`/`color`/`table`** (SequentialBufferMaterializer): Status messages created during concurrent production are treated as elements in declaration order, just like tables and panels. A status message created between two table creations will be rendered between those tables. Status messages created *after* all tables will render after all tables are flushed.
- **`json`/`yaml`** (AccumulateMaterializer): All status messages are collected in the `messages` array of the final snapshot, ordered by timestamp.

#### Integration with Future TUI

The reactive `OutputSession` architecture is intentionally designed to serve as the data layer for a future TUI (text user interface). The session's event-driven model maps directly to TUI widget patterns:

1. **Element handles become observable data sources.** A TUI `MaterializationStrategy` (e.g., `TuiMaterializer`) would subscribe to element events and route them to TUI widgets. The producer code (command logic) is completely unaware of whether it is driving a CLI, TUI, or web frontend — it writes to handles identically in all cases.

2. **Element types map to TUI widgets:**
   - `PanelHandle` → info pane or detail card widget
   - `TableHandle` → sortable, filterable data grid widget (rows arrive incrementally via `add_row` events)
   - `TreeHandle` → collapsible tree view widget (nodes arrive incrementally via `add_child` events)
   - `ProgressHandle` → animated progress bar or step-list widget
   - `StatusHandle` → toast notification or status bar message
   - `CodeHandle` → syntax-highlighted code viewer widget
   - `DiffHandle` → side-by-side diff viewer widget

3. **Interactive features are additive.** The TUI can offer features that the CLI cannot — sorting table columns, filtering rows, collapsing/expanding tree nodes, searching within code blocks — without any changes to producer code. These features are implemented in the TUI's `ElementRenderer` and widget layer.

4. **Concurrent updates are native.** Because the session already supports multiple concurrent producers writing to different handles, the TUI naturally displays multiple simultaneously-updating widgets (e.g., two tables being populated in parallel by concurrent operations). The `TuiMaterializer` routes events to widgets, and each widget redraws independently using the TUI framework's event loop.

5. **The `StructuredOutput` snapshot** provides the initial state when navigating to a completed session in the TUI (e.g., reviewing a past command's output), while live sessions use the event stream.

The separation between production (element handles), timing (materialization strategy), and presentation (element renderer) ensures that the same command logic supports CLI, TUI, and web frontends without modification — only the `(MaterializationStrategy, ElementRenderer)` pair changes.

#### Programmatic Usage Examples

This section demonstrates how command implementations use the Output Rendering Framework through the `OutputSession` API, and how the same producer code produces correct output across all formats.

##### Example 1: Simple Static Command Output

The simplest usage — a command that creates elements, populates them synchronously, and closes them. No concurrency, no streaming.

**Producer code** (`agents project show`):

<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">async</span> <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">cmd_project_show</span>(session: OutputSession, project_name: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;Implementation of &#x27;agents project show &lt;project&gt;&#x27;.&quot;&quot;&quot;</span>
    project = <span style="color: magenta; font-weight: 600;">await</span> api.get_project(project_name)
    resources = <span style="color: magenta; font-weight: 600;">await</span> api.list_project_resources(project.name)
    validations = <span style="color: magenta; font-weight: 600;">await</span> api.list_project_validations(project.name)
    
    <span style="opacity: 0.7;"># --- Build output elements ---</span>
    
    <span style="opacity: 0.7;"># Panel: Project details</span>
    <span style="color: magenta; font-weight: 600;">with</span> session.panel(<span style="color: #66cc66;">&quot;Project Details&quot;</span>) <span style="color: magenta; font-weight: 600;">as</span> panel:
        panel.set_entries({
            <span style="color: #66cc66;">&quot;Name&quot;</span>: project.name,
            <span style="color: #66cc66;">&quot;Description&quot;</span>: project.description,
            <span style="color: #66cc66;">&quot;Resources&quot;</span>: <span style="color: cyan;">str</span>(len(resources)),
            <span style="color: #66cc66;">&quot;Remote&quot;</span>: <span style="color: #66cc66;">&quot;yes&quot;</span> <span style="color: magenta; font-weight: 600;">if</span> project.remote <span style="color: magenta; font-weight: 600;">else</span> <span style="color: #66cc66;">&quot;no&quot;</span>,
            <span style="color: #66cc66;">&quot;Created&quot;</span>: project.created_at.strftime(<span style="color: #66cc66;">&quot;%Y-%m-%d %H:%M&quot;</span>),
        }, style_hints={
            <span style="color: #66cc66;">&quot;Name&quot;</span>: <span style="color: #66cc66;">&quot;identifier&quot;</span>,
            <span style="color: #66cc66;">&quot;Resources&quot;</span>: <span style="color: #66cc66;">&quot;number&quot;</span>,
            <span style="color: #66cc66;">&quot;Remote&quot;</span>: <span style="color: #66cc66;">&quot;success&quot;</span> <span style="color: magenta; font-weight: 600;">if</span> <span style="color: magenta; font-weight: 600;">not</span> project.remote <span style="color: magenta; font-weight: 600;">else</span> <span style="color: #66cc66;">&quot;info&quot;</span>,
            <span style="color: #66cc66;">&quot;Created&quot;</span>: <span style="color: #66cc66;">&quot;success&quot;</span>,
        })
    
    <span style="opacity: 0.7;"># Table: Linked resources</span>
    <span style="color: magenta; font-weight: 600;">with</span> session.table(<span style="color: #66cc66;">&quot;Linked Resources&quot;</span>, columns=[
        ColumnDef(name=<span style="color: #66cc66;">&quot;Resource&quot;</span>, type=<span style="color: #66cc66;">&quot;string&quot;</span>, style_hint=<span style="color: #66cc66;">&quot;identifier&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Type&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Sandbox&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Read-Only&quot;</span>),
    ]) <span style="color: magenta; font-weight: 600;">as</span> table:
        <span style="color: magenta; font-weight: 600;">for</span> r <span style="color: magenta; font-weight: 600;">in</span> resources:
            table.add_row({
                <span style="color: #66cc66;">&quot;Resource&quot;</span>: r.name,
                <span style="color: #66cc66;">&quot;Type&quot;</span>: r.type,
                <span style="color: #66cc66;">&quot;Sandbox&quot;</span>: r.sandbox_strategy,
                <span style="color: #66cc66;">&quot;Read-Only&quot;</span>: <span style="color: #66cc66;">&quot;yes&quot;</span> <span style="color: magenta; font-weight: 600;">if</span> r.read_only <span style="color: magenta; font-weight: 600;">else</span> <span style="color: #66cc66;">&quot;no&quot;</span>,
            })
    
    <span style="opacity: 0.7;"># Table: Validations</span>
    <span style="color: magenta; font-weight: 600;">with</span> session.table(<span style="color: #66cc66;">f&quot;Validations ({len(validations)})&quot;</span>, columns=[
        ColumnDef(name=<span style="color: #66cc66;">&quot;ID&quot;</span>, type=<span style="color: #66cc66;">&quot;id&quot;</span>, style_hint=<span style="color: #66cc66;">&quot;identifier&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Command&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Mode&quot;</span>),
    ]) <span style="color: magenta; font-weight: 600;">as</span> table:
        <span style="color: magenta; font-weight: 600;">for</span> v <span style="color: magenta; font-weight: 600;">in</span> validations:
            table.add_row({
                <span style="color: #66cc66;">&quot;ID&quot;</span>: v.id,
                <span style="color: #66cc66;">&quot;Command&quot;</span>: v.command,
                <span style="color: #66cc66;">&quot;Mode&quot;</span>: v.mode,
            })
    
    <span style="opacity: 0.7;"># Status: Final message</span>
    session.status(<span style="color: #66cc66;">&quot;Project loaded&quot;</span>, level=<span style="color: #66cc66;">&quot;ok&quot;</span>)
</code></pre></div>

**What this produces in `plain` format:**

<div class="highlight"><pre><code>
Project Details
  Name: local/api-service
  Description: Backend API
  Resources: 2
  Remote: no
  Created: 2026-02-08 12:46

Linked Resources
  Resource          Type            Sandbox              Read-Only
  ----------------  --------------  --------------------  ---------
  local/api-repo    git-checkout    git_worktree          no
  local/staging-db  local/database  transaction_rollback  yes

Validations (3)
  Name                     Command                                Mode
  -----------------------  -------------------------------------  -----------
  local/run-tests          pytest <span style="color: cyan;">--cov</span>=src <span style="color: cyan;">--cov-fail-under</span>=80   required
  local/lint-check         ruff check .                           required
  local/check-bundle-size  node scripts/check-bundle-size.js      informational

<span style="color: #66cc66; font-weight: 600;">[OK]</span> Project loaded
</code></pre></div>

**What this produces in `rich` format:**

<div class="highlight"><pre><code>
╭─ Project Details ──────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/api-service        │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Backend API       │
│ <span style="color: yellow; font-weight: 600;">Resources:</span> 2                   │
│ <span style="color: #66cc66; font-weight: 600;">Remote:</span> no                     │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-08 12:46      │
╰────────────────────────────────╯

╭─ Linked Resources ──────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Resource</span>          <span style="color: cyan; font-weight: 600;">Type</span>            <span style="color: cyan; font-weight: 600;">Sandbox</span>              <span style="color: cyan; font-weight: 600;">Read-Only</span>        │
│ <span style="opacity: 0.7;">────────────────  ──────────────  ────────────────────  ─────────</span>       │
│ local/api-repo   git-checkout    git_worktree         no                │
│ local/staging-db local/database  transaction_rollback yes               │
╰─────────────────────────────────────────────────────────────────────────╯

╭─ Validations (3) ──────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>                     <span style="color: cyan; font-weight: 600;">Command</span>                                <span style="color: cyan; font-weight: 600;">Mode</span>            │
│ <span style="opacity: 0.7;">───────────────────────  ─────────────────────────────────────  ───────────</span>     │
│ <span style="color: cyan;">local/run-tests</span>          pytest <span style="color: cyan;">--cov</span>=src <span style="color: cyan;">--cov-fail-under</span>=80   <span style="color: #66cc66;">required</span>        │
│ <span style="color: cyan;">local/lint-check</span>         ruff check .                           <span style="color: #66cc66;">required</span>        │
│ <span style="color: cyan;">local/check-bundle-size</span>  node scripts/check-bundle-size.js      <span style="color: yellow;">informational</span>   │
╰────────────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project loaded
</code></pre></div>

**What this produces in `json` format:**

<div class="highlight"><pre><code>
{
  <span style="color: cyan; font-weight: 600;">&quot;command&quot;</span>: <span style="color: #66cc66;">&quot;project show&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;status&quot;</span>: <span style="color: #66cc66;">&quot;ok&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;exit_code&quot;</span>: <span style="color: yellow;">0</span>,
  <span style="color: cyan; font-weight: 600;">&quot;data&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;project_details&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;Name&quot;</span>: <span style="color: #66cc66;">&quot;local/api-service&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;Description&quot;</span>: <span style="color: #66cc66;">&quot;Backend API&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;Resources&quot;</span>: <span style="color: #66cc66;">&quot;2&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;Remote&quot;</span>: <span style="color: #66cc66;">&quot;no&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;Created&quot;</span>: <span style="color: #66cc66;">&quot;2026-02-08 12:46&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;linked_resources&quot;</span>: [
      {
        <span style="color: cyan; font-weight: 600;">&quot;Resource&quot;</span>: <span style="color: #66cc66;">&quot;local/api-repo&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;Type&quot;</span>: <span style="color: #66cc66;">&quot;git-checkout&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;Sandbox&quot;</span>: <span style="color: #66cc66;">&quot;git_worktree&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;Read-Only&quot;</span>: <span style="color: #66cc66;">&quot;no&quot;</span>
      },
      {
        <span style="color: cyan; font-weight: 600;">&quot;Resource&quot;</span>: <span style="color: #66cc66;">&quot;local/staging-db&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;Type&quot;</span>: <span style="color: #66cc66;">&quot;local/database&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;Sandbox&quot;</span>: <span style="color: #66cc66;">&quot;transaction_rollback&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;Read-Only&quot;</span>: <span style="color: #66cc66;">&quot;yes&quot;</span>
      }
    ],
    <span style="color: cyan; font-weight: 600;">&quot;validations&quot;</span>: [
      {
        <span style="color: cyan; font-weight: 600;">&quot;Name&quot;</span>: <span style="color: #66cc66;">&quot;local/run-tests&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;Command&quot;</span>: <span style="color: #66cc66;">&quot;pytest --cov=src --cov-fail-under=80&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;Mode&quot;</span>: <span style="color: #66cc66;">&quot;required&quot;</span>
      },
      {
        <span style="color: cyan; font-weight: 600;">&quot;Name&quot;</span>: <span style="color: #66cc66;">&quot;local/lint-check&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;Command&quot;</span>: <span style="color: #66cc66;">&quot;ruff check .&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;Mode&quot;</span>: <span style="color: #66cc66;">&quot;required&quot;</span>
      },
      {
        <span style="color: cyan; font-weight: 600;">&quot;Name&quot;</span>: <span style="color: #66cc66;">&quot;local/check-bundle-size&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;Command&quot;</span>: <span style="color: #66cc66;">&quot;node scripts/check-bundle-size.js&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;Mode&quot;</span>: <span style="color: #66cc66;">&quot;informational&quot;</span>
      }
    ]
  },
  <span style="color: cyan; font-weight: 600;">&quot;timing&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;duration_ms&quot;</span>: <span style="color: yellow;">42</span> },
  <span style="color: cyan; font-weight: 600;">&quot;messages&quot;</span>: [
    { <span style="color: cyan; font-weight: 600;">&quot;level&quot;</span>: <span style="color: #66cc66;">&quot;ok&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;text&quot;</span>: <span style="color: #66cc66;">&quot;Project loaded&quot;</span> }
  ]
}
</code></pre></div>

In all three formats, the producer code is **identical**. The `OutputSession` and its materialization strategy handle the differences transparently.

##### Example 2: Streaming Rows into a Table

A command that streams rows into a table as results arrive from a paginated API. The table handle stays open while the producer fetches pages.

**Producer code** (`agents resource list`):

<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">async</span> <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">cmd_resource_list</span>(session: OutputSession, project: <span style="color: cyan;">str</span> | <span style="color: magenta; font-weight: 600;">None</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;Implementation of &#x27;agents resource list&#x27;.&quot;&quot;&quot;</span>
    
    <span style="opacity: 0.7;"># Create the table handle — it will accumulate rows as we stream them</span>
    table = session.table(<span style="color: #66cc66;">&quot;Resources&quot;</span>, columns=[
        ColumnDef(name=<span style="color: #66cc66;">&quot;Name&quot;</span>, type=<span style="color: #66cc66;">&quot;string&quot;</span>, style_hint=<span style="color: #66cc66;">&quot;identifier&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Type&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Project&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Sandbox&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Status&quot;</span>),
    ], sort_key=<span style="color: #66cc66;">&quot;Name&quot;</span>)
    
    <span style="opacity: 0.7;"># Create a progress indicator for the fetch operation</span>
    progress = session.progress(<span style="color: #66cc66;">&quot;Fetching resources...&quot;</span>, indeterminate=<span style="color: magenta; font-weight: 600;">True</span>)
    
    <span style="opacity: 0.7;"># Stream pages from the API</span>
    count = 0
    <span style="color: magenta; font-weight: 600;">async</span> <span style="color: magenta; font-weight: 600;">for</span> page <span style="color: magenta; font-weight: 600;">in</span> api.list_resources_paginated(project=project):
        <span style="color: magenta; font-weight: 600;">for</span> resource <span style="color: magenta; font-weight: 600;">in</span> page.items:
            table.add_row({
                <span style="color: #66cc66;">&quot;Name&quot;</span>: resource.name,
                <span style="color: #66cc66;">&quot;Type&quot;</span>: resource.type,
                <span style="color: #66cc66;">&quot;Project&quot;</span>: resource.project,
                <span style="color: #66cc66;">&quot;Sandbox&quot;</span>: resource.sandbox_strategy,
                <span style="color: #66cc66;">&quot;Status&quot;</span>: resource.status,
            })
            count += 1
        
        <span style="opacity: 0.7;"># Update progress label with count so far</span>
        progress.set_label(<span style="color: #66cc66;">f&quot;Fetching resources... ({count} found)&quot;</span>)
    
    <span style="opacity: 0.7;"># Close the progress indicator (it has served its purpose)</span>
    progress.close()
    
    <span style="opacity: 0.7;"># Set summary and close the table</span>
    table.set_summary({<span style="color: #66cc66;">&quot;total&quot;</span>: count})
    table.close()
    
    <span style="opacity: 0.7;"># Final status</span>
    session.status(<span style="color: #66cc66;">f&quot;{count} resources listed&quot;</span>, level=<span style="color: #66cc66;">&quot;ok&quot;</span>)
</code></pre></div>

**What this looks like in `plain` format** (SequentialBufferMaterializer):

The progress indicator is rendered as a static line. The table is buffered until `table.close()` is called, then rendered in full. The user sees nothing until the fetch is complete — then the entire result appears at once:

<div class="highlight"><pre><code>
Fetching resources... (47 found) [done]

Resources
  Name                  Type            Project            Sandbox              Status
  --------------------  --------------  -----------------  --------------------  --------
  local/api-repo        git-checkout    local/api-service  git_worktree          active
  local/staging-db      local/database  local/api-service  transaction_rollback  active
  local/docs-repo       git-checkout    local/docs-site    git_worktree          active
  ... (44 more rows)

  Total: 47

<span style="color: #66cc66; font-weight: 600;">[OK]</span> 47 resources listed
</code></pre></div>

**What this looks like in `rich` format** (LiveMaterializer):

The progress spinner animates in real-time. The table updates in-place as rows arrive — each new row appears at the bottom of the table, the row count updates, and the terminal display is rewritten without scrolling. This is a static snapshot of the live display mid-fetch:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">⠙</span> Fetching resources... (<span style="color: yellow;">23</span> found)

╭─ Resources ────────────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>                  <span style="color: cyan; font-weight: 600;">Type</span>            <span style="color: cyan; font-weight: 600;">Project</span>            <span style="color: cyan; font-weight: 600;">Sandbox</span>              <span style="color: cyan; font-weight: 600;">Status</span>   │
│ <span style="opacity: 0.7;">────────────────────  ──────────────  ─────────────────  ────────────────────  ──────</span>  │
│ <span style="color: cyan;">local/api-repo</span>        git-checkout    local/api-service  git_worktree          <span style="color: #66cc66;">active</span>  │
│ <span style="color: cyan;">local/staging-db</span>      local/database  local/api-service  transaction_rollback  <span style="color: #66cc66;">active</span>  │
│ <span style="color: cyan;">local/docs-repo</span>       git-checkout    local/docs-site    git_worktree          <span style="color: #66cc66;">active</span>  │
│ <span style="opacity: 0.5;">  ...</span>                                                                                  │
│ <span style="color: cyan;">local/test-fixtures</span>   git-checkout    local/api-service  git_worktree          <span style="color: #66cc66;">active</span>  │
│                                                                                        │
│ <span style="opacity: 0.7;">Showing 1-23 of 23 (fetching...)</span>                                                       │
╰────────────────────────────────────────────────────────────────────────────────────────╯
</code></pre></div>

In `rich` mode, the spinner animates, the table grows as rows arrive, and the row count updates — all in-place without scrolling. When the fetch completes, the spinner resolves to `✓`, and the table shows its final state.

##### Example 3: Concurrent Parallel Operations (Two Tables Simultaneously)

This is the key motivating example for the reactive architecture. Two tables are populated simultaneously by parallel workers, and the producer code is completely format-agnostic.

**Producer code** (`agents plan status` — showing resources and active tool calls concurrently):

<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">async</span> <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">cmd_plan_status</span>(session: OutputSession, plan_id: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;Implementation of &#x27;agents plan status &lt;plan_id&gt;&#x27;.</span>
<span style="color: #66cc66;">    </span>
<span style="color: #66cc66;">    This command fetches plan metadata, then concurrently streams two data</span>
<span style="color: #66cc66;">    sources: resource statuses and active tool call logs. Both data sources</span>
<span style="color: #66cc66;">    are long-running — they produce results over several seconds as the</span>
<span style="color: #66cc66;">    backend resolves each item.</span>
<span style="color: #66cc66;">    &quot;&quot;&quot;</span>
    plan = <span style="color: magenta; font-weight: 600;">await</span> api.get_plan(plan_id)
    
    <span style="opacity: 0.7;"># Panel: Plan metadata (created and closed synchronously)</span>
    <span style="color: magenta; font-weight: 600;">with</span> session.panel(<span style="color: #66cc66;">&quot;Plan&quot;</span>) <span style="color: magenta; font-weight: 600;">as</span> panel:
        panel.set_entries({
            <span style="color: #66cc66;">&quot;Plan ID&quot;</span>: plan.id,
            <span style="color: #66cc66;">&quot;Phase&quot;</span>: plan.phase,
            <span style="color: #66cc66;">&quot;State&quot;</span>: plan.state,
            <span style="color: #66cc66;">&quot;Action&quot;</span>: plan.action,
            <span style="color: #66cc66;">&quot;Project&quot;</span>: plan.project,
            <span style="color: #66cc66;">&quot;Started&quot;</span>: plan.started_at.strftime(<span style="color: #66cc66;">&quot;%H:%M:%S&quot;</span>),
        }, style_hints={
            <span style="color: #66cc66;">&quot;Plan ID&quot;</span>: <span style="color: #66cc66;">&quot;identifier&quot;</span>,
            <span style="color: #66cc66;">&quot;Phase&quot;</span>: <span style="color: #66cc66;">&quot;info&quot;</span>,
            <span style="color: #66cc66;">&quot;State&quot;</span>: <span style="color: #66cc66;">&quot;warning&quot;</span> <span style="color: magenta; font-weight: 600;">if</span> plan.state == <span style="color: #66cc66;">&quot;processing&quot;</span> <span style="color: magenta; font-weight: 600;">else</span> <span style="color: #66cc66;">&quot;success&quot;</span>,
        })
    
    <span style="opacity: 0.7;"># Create both table handles BEFORE starting concurrent producers.</span>
    <span style="opacity: 0.7;"># Declaration order determines rendering order in sequential formats.</span>
    resource_table = session.table(<span style="color: #66cc66;">&quot;Resource Status&quot;</span>, columns=[
        ColumnDef(name=<span style="color: #66cc66;">&quot;Resource&quot;</span>, style_hint=<span style="color: #66cc66;">&quot;identifier&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Type&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Status&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Latency&quot;</span>, type=<span style="color: #66cc66;">&quot;string&quot;</span>, alignment=<span style="color: #66cc66;">&quot;right&quot;</span>),
    ])
    
    tool_table = session.table(<span style="color: #66cc66;">&quot;Tool Call Log&quot;</span>, columns=[
        ColumnDef(name=<span style="color: #66cc66;">&quot;#&quot;</span>, type=<span style="color: #66cc66;">&quot;number&quot;</span>, alignment=<span style="color: #66cc66;">&quot;right&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Tool&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Target&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Result&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Duration&quot;</span>, type=<span style="color: #66cc66;">&quot;string&quot;</span>, alignment=<span style="color: #66cc66;">&quot;right&quot;</span>),
    ])
    
    <span style="opacity: 0.7;"># --- Run two producers concurrently ---</span>
    <span style="opacity: 0.7;"># Each producer writes to its own handle. Neither producer knows</span>
    <span style="opacity: 0.7;"># which format is active. The materialization strategy handles</span>
    <span style="opacity: 0.7;"># the coordination.</span>
    
    <span style="color: magenta; font-weight: 600;">async</span> <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">stream_resources</span>():
        <span style="color: #66cc66;">&quot;&quot;&quot;Producer A: streams resource status checks.&quot;&quot;&quot;</span>
        <span style="color: magenta; font-weight: 600;">async</span> <span style="color: magenta; font-weight: 600;">for</span> status <span style="color: magenta; font-weight: 600;">in</span> api.stream_resource_statuses(plan.id):
            resource_table.add_row({
                <span style="color: #66cc66;">&quot;Resource&quot;</span>: status.resource_name,
                <span style="color: #66cc66;">&quot;Type&quot;</span>: status.resource_type,
                <span style="color: #66cc66;">&quot;Status&quot;</span>: status.status,
                <span style="color: #66cc66;">&quot;Latency&quot;</span>: <span style="color: #66cc66;">f&quot;{status.latency_ms}ms&quot;</span>,
            })
        resource_table.close()
    
    <span style="color: magenta; font-weight: 600;">async</span> <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">stream_tool_calls</span>():
        <span style="color: #66cc66;">&quot;&quot;&quot;Producer B: streams tool call results.&quot;&quot;&quot;</span>
        <span style="color: magenta; font-weight: 600;">async</span> <span style="color: magenta; font-weight: 600;">for</span> call <span style="color: magenta; font-weight: 600;">in</span> api.stream_tool_calls(plan.id):
            tool_table.add_row({
                <span style="color: #66cc66;">&quot;#&quot;</span>: call.sequence_number,
                <span style="color: #66cc66;">&quot;Tool&quot;</span>: call.tool_name,
                <span style="color: #66cc66;">&quot;Target&quot;</span>: call.target,
                <span style="color: #66cc66;">&quot;Result&quot;</span>: call.result_summary,
                <span style="color: #66cc66;">&quot;Duration&quot;</span>: <span style="color: #66cc66;">f&quot;{call.duration_ms}ms&quot;</span>,
            })
        tool_table.close()
    
    <span style="opacity: 0.7;"># Launch both producers concurrently</span>
    <span style="color: magenta; font-weight: 600;">await</span> asyncio.gather(stream_resources(), stream_tool_calls())
    
    <span style="opacity: 0.7;"># Final status</span>
    session.status(<span style="color: #66cc66;">f&quot;Plan {plan_id} status retrieved&quot;</span>, level=<span style="color: #66cc66;">&quot;ok&quot;</span>)
</code></pre></div>

**What this produces in `plain` format** (SequentialBufferMaterializer):

Both tables are populated concurrently, but the materializer buffers each one and renders them in **declaration order** when their handles close. The user sees nothing until the first-declared table (Resource Status) closes, then it prints. Then when the second table (Tool Call Log) closes, it prints. Data may have arrived interleaved across both tables, but the output is perfectly sequential:

<div class="highlight"><pre><code>
Plan
  Plan ID: 01HXM7A9
  Phase: execute
  State: processing
  <span style="color: yellow; font-weight: 600;">Action</span>: local/code-coverage
  Project: local/api-service
  Started: 12:58:10

Resource Status
  Resource          Type            Status   Latency
  ----------------  --------------  -------  -------
  local/api-repo    git-checkout    ready    42ms
  local/staging-db  local/database  ready    128ms

Tool Call Log
  #   Tool        Target                  Result         Duration
  --  ----------  ----------------------  -------------  --------
   1  read_file   src/auth/__init__.py    200 lines      0.1s
   2  read_file   src/auth/session.py     340 lines      0.1s
   3  write_file  tests/test_auth.py      created        0.2s
   4  edit_file   src/auth/session.py     12 lines +/-   0.3s
   5  run_tests   pytest tests/test_auth  3 passed       2.1s

<span style="color: #66cc66; font-weight: 600;">[OK]</span> Plan 01HXM7A9 status retrieved
</code></pre></div>

**What this produces in `rich` format** (LiveMaterializer):

Both tables are visible simultaneously and update in-place as data arrives. This snapshot shows the display mid-stream — the resource table has two rows and the tool call table has three so far:

<div class="highlight"><pre><code>
╭─ Plan ──────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan ID:</span> 01HXM7A9                   │
│ <span style="color: #5599ff; font-weight: 600;">Phase:</span> execute                      │
│ <span style="color: yellow; font-weight: 600;">State:</span> processing                   │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/code-coverage         │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/api-service          │
│ <span style="color: #66cc66; font-weight: 600;">Started:</span> 12:58:10                   │
╰─────────────────────────────────────╯

╭─ Resource Status <span style="color: cyan; font-weight: 600;">⠙</span> ───────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Resource</span>          <span style="color: cyan; font-weight: 600;">Type</span>            <span style="color: cyan; font-weight: 600;">Status</span>   <span style="color: cyan; font-weight: 600;">Latency</span>            │
│ <span style="opacity: 0.7;">────────────────  ──────────────  ───────  ───────</span>            │
│ <span style="color: cyan;">local/api-repo</span>    git-checkout    <span style="color: #66cc66;">ready</span>    <span style="opacity: 0.7;">42ms</span>               │
│ <span style="color: cyan;">local/staging-db</span>  local/database  <span style="color: #66cc66;">ready</span>    <span style="opacity: 0.7;">128ms</span>              │
│                                                               │
│ <span style="opacity: 0.5;">2 resources (streaming...)</span>                                    │
╰───────────────────────────────────────────────────────────────╯

╭─ Tool Call Log <span style="color: cyan; font-weight: 600;">⠙</span> ────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">#</span>   <span style="color: cyan; font-weight: 600;">Tool</span>        <span style="color: cyan; font-weight: 600;">Target</span>                  <span style="color: cyan; font-weight: 600;">Result</span>         <span style="color: cyan; font-weight: 600;">Duration</span>      │
│ <span style="opacity: 0.7;">──  ──────────  ──────────────────────  ─────────────  ────────</span>      │
│  <span style="opacity: 0.7;">1</span>  read_file   <span style="color: #5599ff;">src/auth/__init__.py</span>    <span style="color: #66cc66;">200 lines</span>      <span style="opacity: 0.7;">0.1s</span>          │
│  <span style="opacity: 0.7;">2</span>  read_file   <span style="color: #5599ff;">src/auth/session.py</span>     <span style="color: #66cc66;">340 lines</span>      <span style="opacity: 0.7;">0.1s</span>          │
│  <span style="opacity: 0.7;">3</span>  write_file  <span style="color: #5599ff;">tests/test_auth.py</span>      <span style="color: #66cc66;">created</span>        <span style="opacity: 0.7;">0.2s</span>          │
│                                                                      │
│ <span style="opacity: 0.5;">3 calls (streaming...)</span>                                               │
╰──────────────────────────────────────────────────────────────────────╯
</code></pre></div>

In `rich` mode, both tables have animated spinners in their titles indicating active streaming. As new rows arrive from either producer, the corresponding table's display is updated in-place. When a producer finishes and closes its handle, the spinner resolves to a `✓` and the "(streaming...)" indicator is removed. The other table continues updating independently.

**What this produces in `json` format** (AccumulateMaterializer):

Nothing is printed until the session closes. Then the complete accumulated state is serialized:

<div class="highlight"><pre><code>
{
  <span style="color: cyan; font-weight: 600;">&quot;command&quot;</span>: <span style="color: #66cc66;">&quot;plan status&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;status&quot;</span>: <span style="color: #66cc66;">&quot;ok&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;exit_code&quot;</span>: <span style="color: yellow;">0</span>,
  <span style="color: cyan; font-weight: 600;">&quot;data&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;plan&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;Plan ID&quot;</span>: <span style="color: #66cc66;">&quot;01HXM7A9&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;Phase&quot;</span>: <span style="color: #66cc66;">&quot;execute&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;State&quot;</span>: <span style="color: #66cc66;">&quot;processing&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;Action&quot;</span>: <span style="color: #66cc66;">&quot;local/code-coverage&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;Project&quot;</span>: <span style="color: #66cc66;">&quot;local/api-service&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;Started&quot;</span>: <span style="color: #66cc66;">&quot;12:58:10&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;resource_status&quot;</span>: [
      { <span style="color: cyan; font-weight: 600;">&quot;Resource&quot;</span>: <span style="color: #66cc66;">&quot;local/api-repo&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Type&quot;</span>: <span style="color: #66cc66;">&quot;git-checkout&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Status&quot;</span>: <span style="color: #66cc66;">&quot;ready&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Latency&quot;</span>: <span style="color: #66cc66;">&quot;42ms&quot;</span> },
      { <span style="color: cyan; font-weight: 600;">&quot;Resource&quot;</span>: <span style="color: #66cc66;">&quot;local/staging-db&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Type&quot;</span>: <span style="color: #66cc66;">&quot;local/database&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Status&quot;</span>: <span style="color: #66cc66;">&quot;ready&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Latency&quot;</span>: <span style="color: #66cc66;">&quot;128ms&quot;</span> }
    ],
    <span style="color: cyan; font-weight: 600;">&quot;tool_call_log&quot;</span>: [
      { <span style="color: cyan; font-weight: 600;">&quot;#&quot;</span>: <span style="color: yellow;">1</span>, <span style="color: cyan; font-weight: 600;">&quot;Tool&quot;</span>: <span style="color: #66cc66;">&quot;read_file&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Target&quot;</span>: <span style="color: #66cc66;">&quot;src/auth/__init__.py&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Result&quot;</span>: <span style="color: #66cc66;">&quot;200 lines&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Duration&quot;</span>: <span style="color: #66cc66;">&quot;0.1s&quot;</span> },
      { <span style="color: cyan; font-weight: 600;">&quot;#&quot;</span>: <span style="color: yellow;">2</span>, <span style="color: cyan; font-weight: 600;">&quot;Tool&quot;</span>: <span style="color: #66cc66;">&quot;read_file&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Target&quot;</span>: <span style="color: #66cc66;">&quot;src/auth/session.py&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Result&quot;</span>: <span style="color: #66cc66;">&quot;340 lines&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Duration&quot;</span>: <span style="color: #66cc66;">&quot;0.1s&quot;</span> },
      { <span style="color: cyan; font-weight: 600;">&quot;#&quot;</span>: <span style="color: yellow;">3</span>, <span style="color: cyan; font-weight: 600;">&quot;Tool&quot;</span>: <span style="color: #66cc66;">&quot;write_file&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Target&quot;</span>: <span style="color: #66cc66;">&quot;tests/test_auth.py&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Result&quot;</span>: <span style="color: #66cc66;">&quot;created&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Duration&quot;</span>: <span style="color: #66cc66;">&quot;0.2s&quot;</span> },
      { <span style="color: cyan; font-weight: 600;">&quot;#&quot;</span>: <span style="color: yellow;">4</span>, <span style="color: cyan; font-weight: 600;">&quot;Tool&quot;</span>: <span style="color: #66cc66;">&quot;edit_file&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Target&quot;</span>: <span style="color: #66cc66;">&quot;src/auth/session.py&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Result&quot;</span>: <span style="color: #66cc66;">&quot;12 lines +/-&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Duration&quot;</span>: <span style="color: #66cc66;">&quot;0.3s&quot;</span> },
      { <span style="color: cyan; font-weight: 600;">&quot;#&quot;</span>: <span style="color: yellow;">5</span>, <span style="color: cyan; font-weight: 600;">&quot;Tool&quot;</span>: <span style="color: #66cc66;">&quot;run_tests&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Target&quot;</span>: <span style="color: #66cc66;">&quot;pytest tests/test_auth&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Result&quot;</span>: <span style="color: #66cc66;">&quot;3 passed&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;Duration&quot;</span>: <span style="color: #66cc66;">&quot;2.1s&quot;</span> }
    ]
  },
  <span style="color: cyan; font-weight: 600;">&quot;timing&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;duration_ms&quot;</span>: <span style="color: yellow;">3200</span> },
  <span style="color: cyan; font-weight: 600;">&quot;messages&quot;</span>: [
    { <span style="color: cyan; font-weight: 600;">&quot;level&quot;</span>: <span style="color: #66cc66;">&quot;ok&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;text&quot;</span>: <span style="color: #66cc66;">&quot;Plan 01HXM7A9 status retrieved&quot;</span> }
  ]
}
</code></pre></div>

The critical point: **the producer code in all three formats is exactly the same**. The `asyncio.gather` call runs both producers concurrently regardless of format. The materialization strategy — `LiveMaterializer`, `SequentialBufferMaterializer`, or `AccumulateMaterializer` — transparently decides how that concurrent data reaches the user.

##### Example 4: Progress with Concurrent Sub-Operations

A command that executes a multi-step process with a progress indicator, where some steps involve parallel sub-operations.

**Producer code** (`agents plan execute`):

<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">async</span> <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">cmd_plan_execute</span>(session: OutputSession, plan_id: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;Implementation of &#x27;agents plan execute &lt;plan_id&gt;&#x27;.&quot;&quot;&quot;</span>
    plan = <span style="color: magenta; font-weight: 600;">await</span> api.get_plan(plan_id)
    
    <span style="opacity: 0.7;"># Panel: Execution metadata</span>
    <span style="color: magenta; font-weight: 600;">with</span> session.panel(<span style="color: #66cc66;">&quot;Execution&quot;</span>) <span style="color: magenta; font-weight: 600;">as</span> panel:
        panel.set_entries({
            <span style="color: #66cc66;">&quot;Plan&quot;</span>: plan.id,
            <span style="color: #66cc66;">&quot;Phase&quot;</span>: <span style="color: #66cc66;">&quot;execute&quot;</span>,
            <span style="color: #66cc66;">&quot;Sandbox&quot;</span>: plan.sandbox_strategy,
            <span style="color: #66cc66;">&quot;Worker&quot;</span>: plan.worker,
            <span style="color: #66cc66;">&quot;Started&quot;</span>: <span style="color: cyan;">datetime</span>.now().strftime(<span style="color: #66cc66;">&quot;%H:%M:%S&quot;</span>),
        })
    
    <span style="opacity: 0.7;"># Progress indicator with named steps</span>
    progress = session.progress(<span style="color: #66cc66;">&quot;Executing plan&quot;</span>, total=4, steps=[
        <span style="color: #66cc66;">&quot;Collect context&quot;</span>,
        <span style="color: #66cc66;">&quot;Run tools&quot;</span>,
        <span style="color: #66cc66;">&quot;Build changeset&quot;</span>,
        <span style="color: #66cc66;">&quot;Validate&quot;</span>,
    ])
    
    <span style="opacity: 0.7;"># Step 1: Collect context</span>
    progress.set_step_status(<span style="color: #66cc66;">&quot;Collect context&quot;</span>, <span style="color: #66cc66;">&quot;active&quot;</span>)
    context = <span style="color: magenta; font-weight: 600;">await</span> api.collect_context(plan.id)
    progress.set_step_status(<span style="color: #66cc66;">&quot;Collect context&quot;</span>, <span style="color: #66cc66;">&quot;done&quot;</span>)
    progress.set_progress(1, 4)
    
    <span style="opacity: 0.7;"># Step 2: Run tools (parallel sub-operations)</span>
    progress.set_step_status(<span style="color: #66cc66;">&quot;Run tools&quot;</span>, <span style="color: #66cc66;">&quot;active&quot;</span>)
    tool_results = <span style="color: magenta; font-weight: 600;">await</span> api.run_tools(plan.id, context)
    progress.set_step_status(<span style="color: #66cc66;">&quot;Run tools&quot;</span>, <span style="color: #66cc66;">&quot;done&quot;</span>)
    progress.set_progress(2, 4)
    
    <span style="opacity: 0.7;"># Step 3: Build changeset</span>
    progress.set_step_status(<span style="color: #66cc66;">&quot;Build changeset&quot;</span>, <span style="color: #66cc66;">&quot;active&quot;</span>)
    changeset = <span style="color: magenta; font-weight: 600;">await</span> api.build_changeset(plan.id, tool_results)
    progress.set_step_status(<span style="color: #66cc66;">&quot;Build changeset&quot;</span>, <span style="color: #66cc66;">&quot;done&quot;</span>)
    progress.set_progress(3, 4)
    
    <span style="opacity: 0.7;"># Step 4: Validate</span>
    progress.set_step_status(<span style="color: #66cc66;">&quot;Validate&quot;</span>, <span style="color: #66cc66;">&quot;active&quot;</span>)
    validation = <span style="color: magenta; font-weight: 600;">await</span> api.validate_changeset(plan.id, changeset)
    progress.set_step_status(<span style="color: #66cc66;">&quot;Validate&quot;</span>, <span style="color: #66cc66;">&quot;done&quot;</span>)
    progress.set_progress(4, 4)
    
    progress.close()
    
    <span style="opacity: 0.7;"># Summary panel</span>
    <span style="color: magenta; font-weight: 600;">with</span> session.panel(<span style="color: #66cc66;">&quot;Strategy Summary&quot;</span>) <span style="color: magenta; font-weight: 600;">as</span> panel:
        panel.set_entries({
            <span style="color: #66cc66;">&quot;Decisions&quot;</span>: <span style="color: cyan;">str</span>(changeset.decision_count),
            <span style="color: #66cc66;">&quot;Invariants&quot;</span>: <span style="color: cyan;">str</span>(changeset.invariant_count),
            <span style="color: #66cc66;">&quot;Planned Child Plans&quot;</span>: <span style="color: #66cc66;">f&quot;{changeset.child_plan_count}+&quot;</span>,
            <span style="color: #66cc66;">&quot;Estimated Files&quot;</span>: <span style="color: #66cc66;">f&quot;~{changeset.file_count}&quot;</span>,
            <span style="color: #66cc66;">&quot;Risk&quot;</span>: changeset.risk_level,
        })
    
    <span style="opacity: 0.7;"># Final status</span>
    <span style="color: magenta; font-weight: 600;">if</span> validation.passed:
        session.status(<span style="color: #66cc66;">&quot;Execution complete — all validations passed&quot;</span>, level=<span style="color: #66cc66;">&quot;ok&quot;</span>)
    <span style="color: magenta; font-weight: 600;">else</span>:
        session.status(
            <span style="color: #66cc66;">f&quot;Execution complete — {validation.failure_count} validation(s) failed&quot;</span>,
            level=<span style="color: #66cc66;">&quot;warn&quot;</span>,
            detail=validation.summary,
        )
</code></pre></div>

**What this looks like in `plain` format:**

The progress indicator renders as a static step list. Since `SequentialBufferMaterializer` buffers each element until its handle closes, the progress indicator is not visible during execution — it appears as a completed snapshot after the fact:

<div class="highlight"><pre><code>
Execution
  Plan: 01HXM8C2ZK4Q7C2B3F2R4VYV6J
  Phase: execute
  Sandbox: git_worktree
  Worker: local/executor
  Started: 12:58:10

Executing plan  [4/4]
  [x] Collect context
  [x] Run tools
  [x] Build changeset
  [x] Validate

Strategy Summary
  Decisions: 8
  Invariants: 2
  Planned Child Plans: 2+
  Estimated Files: ~12
  Risk: low

<span style="color: #66cc66; font-weight: 600;">[OK]</span> Execution complete — all validations passed
</code></pre></div>

**What this looks like in `rich` format:**

The progress indicator is live — the spinner animates, the progress bar fills, and steps transition from pending to active to done in real-time. This snapshot shows the display mid-execution (step 3 active):

<div class="highlight"><pre><code>
╭─ Execution ──────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXM8C2ZK4Q7C2B3F2R4VYV6J │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> execute                   │
│ <span style="color: magenta; font-weight: 600;">Sandbox:</span> git_worktree            │
│ <span style="color: #5599ff; font-weight: 600;">Worker:</span> local/executor           │
│ <span style="color: #66cc66; font-weight: 600;">Started:</span> 12:58:10                │
╰──────────────────────────────────╯

<span style="color: cyan; font-weight: 600;">Executing plan</span> <span style="color: #66cc66;">━━━━━━━━━━━━━━━━</span><span style="opacity: 0.3;">━━━━━━━━━━━━━━━━━━━</span>  <span style="color: cyan; font-weight: 600;">50%</span>  <span style="opacity: 0.7;">elapsed 0:00:13</span>
  <span style="color: #66cc66; font-weight: 600;">✓</span> Collect context <span style="opacity: 0.5;">..................</span> <span style="color: #66cc66;">0.8s</span>
  <span style="color: #66cc66; font-weight: 600;">✓</span> Run tools <span style="opacity: 0.5;">......................</span> <span style="color: #66cc66;">12.4s</span>
  <span style="color: cyan; font-weight: 600;">⠙</span> Build changeset <span style="opacity: 0.5;">.................</span> <span style="color: yellow;">(running)</span>
  <span style="opacity: 0.5;">○</span> Validate <span style="opacity: 0.5;">........................</span> <span style="opacity: 0.5;">(pending)</span>
</code></pre></div>

When execution completes, the progress indicator resolves to its final state (all steps `✓`), the Strategy Summary panel appears below it, and the final status message is displayed.

##### Example 5: Error Mid-Stream with Partial Output

A command where one of multiple concurrent producers fails, demonstrating graceful partial output.

**Producer code** (hypothetical `agents resource verify`):

<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">async</span> <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">cmd_resource_verify</span>(session: OutputSession, project: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>:
    <span style="color: #66cc66;">&quot;&quot;&quot;Verify all resources in a project. Some verifications may fail.&quot;&quot;&quot;</span>
    resources = <span style="color: magenta; font-weight: 600;">await</span> api.list_project_resources(project)
    
    <span style="opacity: 0.7;"># Create a table that will be populated concurrently</span>
    results_table = session.table(<span style="color: #66cc66;">&quot;Verification Results&quot;</span>, columns=[
        ColumnDef(name=<span style="color: #66cc66;">&quot;Resource&quot;</span>, style_hint=<span style="color: #66cc66;">&quot;identifier&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Type&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Check&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Status&quot;</span>),
        ColumnDef(name=<span style="color: #66cc66;">&quot;Detail&quot;</span>),
    ])
    
    <span style="opacity: 0.7;"># Progress indicator</span>
    progress = session.progress(
        <span style="color: #66cc66;">&quot;Verifying resources&quot;</span>,
        total=len(resources),
        steps=[r.name <span style="color: magenta; font-weight: 600;">for</span> r <span style="color: magenta; font-weight: 600;">in</span> resources],
    )
    
    <span style="opacity: 0.7;"># Verify each resource concurrently</span>
    <span style="color: magenta; font-weight: 600;">async</span> <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">verify_one</span>(resource):
        progress.set_step_status(resource.name, <span style="color: #66cc66;">&quot;active&quot;</span>)
        <span style="color: magenta; font-weight: 600;">try</span>:
            result = <span style="color: magenta; font-weight: 600;">await</span> api.verify_resource(resource.id)
            results_table.add_row({
                <span style="color: #66cc66;">&quot;Resource&quot;</span>: resource.name,
                <span style="color: #66cc66;">&quot;Type&quot;</span>: resource.type,
                <span style="color: #66cc66;">&quot;Check&quot;</span>: result.check_name,
                <span style="color: #66cc66;">&quot;Status&quot;</span>: <span style="color: #66cc66;">&quot;pass&quot;</span> <span style="color: magenta; font-weight: 600;">if</span> result.passed <span style="color: magenta; font-weight: 600;">else</span> <span style="color: #66cc66;">&quot;fail&quot;</span>,
                <span style="color: #66cc66;">&quot;Detail&quot;</span>: result.detail,
            })
            progress.set_step_status(
                resource.name,
                <span style="color: #66cc66;">&quot;done&quot;</span> <span style="color: magenta; font-weight: 600;">if</span> result.passed <span style="color: magenta; font-weight: 600;">else</span> <span style="color: #66cc66;">&quot;error&quot;</span>,
            )
        <span style="color: magenta; font-weight: 600;">except</span> ApiError <span style="color: magenta; font-weight: 600;">as</span> e:
            results_table.add_row({
                <span style="color: #66cc66;">&quot;Resource&quot;</span>: resource.name,
                <span style="color: #66cc66;">&quot;Type&quot;</span>: resource.type,
                <span style="color: #66cc66;">&quot;Check&quot;</span>: <span style="color: #66cc66;">&quot;connection&quot;</span>,
                <span style="color: #66cc66;">&quot;Status&quot;</span>: <span style="color: #66cc66;">&quot;error&quot;</span>,
                <span style="color: #66cc66;">&quot;Detail&quot;</span>: <span style="color: cyan;">str</span>(e),
            })
            progress.set_step_status(resource.name, <span style="color: #66cc66;">&quot;error&quot;</span>)
        progress.increment()
    
    <span style="opacity: 0.7;"># Launch all verifications concurrently</span>
    <span style="color: magenta; font-weight: 600;">await</span> asyncio.gather(
        *[verify_one(r) <span style="color: magenta; font-weight: 600;">for</span> r <span style="color: magenta; font-weight: 600;">in</span> resources],
        return_exceptions=<span style="color: magenta; font-weight: 600;">True</span>,  <span style="opacity: 0.7;"># Don&#x27;t fail fast — collect all results</span>
    )
    
    progress.close()
    results_table.close()
    
    <span style="opacity: 0.7;"># Summarize</span>
    snapshot = results_table.element
    pass_count = sum(1 <span style="color: magenta; font-weight: 600;">for</span> r <span style="color: magenta; font-weight: 600;">in</span> snapshot.rows <span style="color: magenta; font-weight: 600;">if</span> r[<span style="color: #66cc66;">&quot;Status&quot;</span>] == <span style="color: #66cc66;">&quot;pass&quot;</span>)
    fail_count = sum(1 <span style="color: magenta; font-weight: 600;">for</span> r <span style="color: magenta; font-weight: 600;">in</span> snapshot.rows <span style="color: magenta; font-weight: 600;">if</span> r[<span style="color: #66cc66;">&quot;Status&quot;</span>] <span style="color: magenta; font-weight: 600;">in</span> (<span style="color: #66cc66;">&quot;fail&quot;</span>, <span style="color: #66cc66;">&quot;error&quot;</span>))
    
    <span style="color: magenta; font-weight: 600;">if</span> fail_count == 0:
        session.status(<span style="color: #66cc66;">f&quot;All {pass_count} resources verified&quot;</span>, level=<span style="color: #66cc66;">&quot;ok&quot;</span>)
    <span style="color: magenta; font-weight: 600;">else</span>:
        session.status(
            <span style="color: #66cc66;">f&quot;{fail_count} of {pass_count + fail_count} resources failed verification&quot;</span>,
            level=<span style="color: #66cc66;">&quot;error&quot;</span>,
        )
</code></pre></div>

**What this produces in `plain` format** (after all concurrent verifications complete):

<div class="highlight"><pre><code>
Verifying resources  [3/3]
  [x] local/api-repo
  [!] local/staging-db
  [x] local/docs-repo

Verification Results
  Resource          Type            Check       Status  Detail
  ----------------  --------------  ----------  ------  ----------------------------------
  local/api-repo    git-checkout    integrity   pass    All refs valid
  local/staging-db  local/database  connection  error   Connection refused (port 5432)
  local/docs-repo   git-checkout    integrity   pass    All refs valid

<span style="color: #ff6666; font-weight: 600;">[ERROR]</span> 1 of 3 resources failed verification
</code></pre></div>

**What this produces in `color` format:**

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">Verifying resources</span>  [3/3]
  <span style="color: #66cc66;">[x]</span> local/api-repo
  <span style="color: #ff6666;">[!]</span> local/staging-db
  <span style="color: #66cc66;">[x]</span> local/docs-repo

<span style="color: cyan; font-weight: 600;">Verification Results</span>
  <span style="color: cyan; font-weight: 600;">Resource</span>          <span style="color: cyan; font-weight: 600;">Type</span>            <span style="color: cyan; font-weight: 600;">Check</span>       <span style="color: cyan; font-weight: 600;">Status</span>  <span style="color: cyan; font-weight: 600;">Detail</span>
  <span style="opacity: 0.7;">----------------  --------------  ----------  ------  ----------------------------------</span>
  <span style="color: cyan;">local/api-repo</span>    git-checkout    integrity   <span style="color: #66cc66;">pass</span>    All refs valid
  <span style="color: cyan;">local/staging-db</span>  local/database  connection  <span style="color: #ff6666;">error</span>   <span style="color: #ff6666;">Connection refused (port 5432)</span>
  <span style="color: cyan;">local/docs-repo</span>   git-checkout    integrity   <span style="color: #66cc66;">pass</span>    All refs valid

<span style="color: #ff6666; font-weight: 600;">[ERROR]</span> 1 of 3 resources failed verification
</code></pre></div>

**What this produces in `yaml` format:**

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">command</span>: resource verify
<span style="color: cyan; font-weight: 600;">status</span>: error
<span style="color: cyan; font-weight: 600;">exit_code</span>: <span style="color: yellow;">1</span>
<span style="color: cyan; font-weight: 600;">data</span>:
  <span style="color: cyan; font-weight: 600;">verification_results</span>:
    - <span style="color: cyan;">Resource</span>: local/api-repo
      <span style="color: cyan; font-weight: 600;">Type</span>: git-checkout
      <span style="color: cyan; font-weight: 600;">Check</span>: integrity
      <span style="color: cyan; font-weight: 600;">Status</span>: pass
      <span style="color: cyan; font-weight: 600;">Detail</span>: All refs valid
    - <span style="color: cyan;">Resource</span>: local/staging-db
      <span style="color: cyan; font-weight: 600;">Type</span>: local/database
      <span style="color: cyan; font-weight: 600;">Check</span>: connection
      <span style="color: cyan; font-weight: 600;">Status</span>: error
      <span style="color: cyan; font-weight: 600;">Detail</span>: <span style="color: #66cc66;">&quot;Connection refused (port 5432)&quot;</span>
    - <span style="color: cyan;">Resource</span>: local/docs-repo
      <span style="color: cyan; font-weight: 600;">Type</span>: git-checkout
      <span style="color: cyan; font-weight: 600;">Check</span>: integrity
      <span style="color: cyan; font-weight: 600;">Status</span>: pass
      <span style="color: cyan; font-weight: 600;">Detail</span>: All refs valid
<span style="color: cyan; font-weight: 600;">timing</span>:
  <span style="color: cyan; font-weight: 600;">duration_ms</span>: <span style="color: yellow;">2840</span>
<span style="color: cyan; font-weight: 600;">messages</span>:
  - <span style="color: cyan;">level</span>: error
    <span style="color: cyan; font-weight: 600;">text</span>: <span style="color: #66cc66;">&quot;1 of 3 resources failed verification&quot;</span>
</code></pre></div>

In all formats, the concurrent verification produces a complete result set with partial failures clearly visible. The producer code uses `return_exceptions=True` on `asyncio.gather` to ensure all verifications complete even if some fail, and the error handling within each `verify_one` coroutine ensures that failures are recorded as table rows rather than causing the entire command to abort.

## Behavior

### Automation Profiles

Automation profiles determine which phase transitions happen automatically and which require human approval.

#### Overview

An **automation profile** is a named collection of **confidence thresholds** — floating-point values from 0.0 to 1.0 inclusive — that controls which tasks are automated vs. require human approval. Each threshold specifies the minimum confidence score (as computed by the Semantic Escalation system) at which the system proceeds automatically. When the computed confidence for a given operation falls below the profile's threshold for that flag, the system drops to manual mode and requests human input. A threshold of **0.0** means "always automatic" (proceed regardless of confidence), while **1.0** means "always manual" (always require human approval). Profiles follow the same `<namespace>/<name>` naming convention as actors, tools, skills, and other entities. Profiles are managed via the `agents automation-profile` CLI commands.

#### Automatable Tasks

Each automation profile specifies a **confidence threshold** (a floating-point value from 0.0 to 1.0 inclusive) for each of the following automatable tasks. The threshold determines the minimum confidence level at which the system proceeds automatically. When the computed confidence (from Semantic Escalation) falls below the threshold, the system drops to manual mode for that task. Setting a threshold to **0.0** makes the task always automatic; setting it to **1.0** makes it always manual.

The three safety flags (`require_sandbox`, `require_checkpoints`, `allow_unsafe_tools`) remain boolean since they are binary constraints rather than confidence-dependent behaviors.

| Flag | Type | Description | Behavior |
|------|------|-------------|----------|
| `auto_strategize` | float (0.0–1.0) | Automatically enter Strategize after `plan use` | When confidence >= threshold, Strategize begins immediately. Below threshold, system pauses; user must run `agents plan execute` to start Strategize. |
| `auto_execute` | float (0.0–1.0) | Automatically proceed from Strategize to Execute | When confidence >= threshold, Execute begins when Strategize completes. Below threshold, system pauses for user review. |
| `auto_apply` | float (0.0–1.0) | Automatically proceed from Execute to Apply | When confidence >= threshold, Apply begins when Execute completes. Below threshold, system pauses for user diff review. |
| `auto_decisions_strategize` | float (0.0–1.0) | Automatically make decisions during Strategize | When confidence >= threshold, the strategy actor makes the decision autonomously. Below threshold, system pauses at the decision point for user input. |
| `auto_decisions_execute` | float (0.0–1.0) | Automatically make decisions during Execute | When confidence >= threshold, the execution actor makes the decision autonomously. Below threshold, system pauses at the decision point for user input. |
| `auto_validation_fix` | float (0.0–1.0) | Automatically attempt to fix validation failures | When confidence >= threshold, execution actor self-fixes failing validations. Below threshold, system pauses for user guidance. |
| `auto_strategy_revision` | float (0.0–1.0) | Automatically revise strategy when Execute hits constraints | When confidence >= threshold, system re-runs Strategize for affected subtree. Below threshold, system pauses and asks user. |
| `auto_child_plans` | float (0.0–1.0) | Automatically spawn and execute child plans | When confidence >= threshold, child plans are created and executed without pausing. Below threshold, each spawn requires approval. |
| `auto_retry_transient` | float (0.0–1.0) | Automatically retry on transient failures (network, timeout, rate-limit) | When confidence >= threshold, system retries with backoff. Below threshold, system pauses and asks user. |
| `auto_checkpoint_restore` | float (0.0–1.0) | Automatically restore from checkpoint on failure | When confidence >= threshold, system rolls back and retries. Below threshold, user decides whether to restore. |
| `require_sandbox` | boolean | Require sandbox isolation for Execute phase | When `true`, Execute must run in a sandbox. When `false`, sandbox is optional. |
| `require_checkpoints` | boolean | Require checkpointing during Execute | When `true`, tools must create checkpoints before writes. When `false`, checkpointing is optional. |
| `allow_unsafe_tools` | boolean | Allow execution of tools marked as unsafe | When `true`, unsafe tools can be invoked. When `false`, unsafe tools are blocked. |

#### Built-in Automation Profiles

CleverAgents ships with eight built-in automation profiles. Built-in profiles use no namespace prefix.

Threshold values are shown for each flag. A value of **0.0** means always automatic, **1.0** means always manual, and intermediate values (e.g., 0.5, 0.7) mean "automatic when confidence is at or above that level."

| Flag | `manual` | `review` | `supervised` | `cautious` | `trusted` | `auto` | `ci` | `full-auto` |
|------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| `auto_strategize` | 1.0 | 0.0 | 0.0 | 0.7 | 0.0 | 0.0 | 0.0 | 0.0 |
| `auto_execute` | 1.0 | 0.0 | 1.0 | 0.7 | 0.0 | 0.0 | 0.0 | 0.0 |
| `auto_apply` | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 |
| `auto_decisions_strategize` | 1.0 | 1.0 | 0.0 | 0.6 | 0.0 | 0.0 | 0.0 | 0.0 |
| `auto_decisions_execute` | 1.0 | 1.0 | 1.0 | 0.8 | 0.0 | 0.0 | 0.0 | 0.0 |
| `auto_validation_fix` | 1.0 | 1.0 | 1.0 | 0.7 | 0.0 | 0.0 | 0.0 | 0.0 |
| `auto_strategy_revision` | 1.0 | 1.0 | 1.0 | 0.8 | 1.0 | 0.0 | 0.0 | 0.0 |
| `auto_child_plans` | 1.0 | 0.0 | 1.0 | 0.7 | 0.0 | 0.0 | 0.0 | 0.0 |
| `auto_retry_transient` | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| `auto_checkpoint_restore` | 1.0 | 1.0 | 1.0 | 0.6 | 1.0 | 0.0 | 0.0 | 0.0 |
| `require_sandbox` | true | true | true | true | true | true | true | false |
| `require_checkpoints` | true | true | true | true | true | true | true | false |
| `allow_unsafe_tools` | false | false | false | false | false | false | false | true |

**`manual`**: Maximum human control. All thresholds set to 1.0 — every phase transition, every decision, every child plan requires explicit human approval regardless of confidence. Sandbox and checkpoints are mandatory. Unsafe tools are blocked. This is the default starting point. Use for: new users learning the system, critical production systems, first-time exploration of an unfamiliar codebase, sensitive projects, regulatory environments.

**`review`**: Phases run automatically (Strategize and Execute proceed without pausing), but all decisions within those phases require human approval (thresholds set to 1.0). Apply is manual. Transient retries and child plan spawning are automatic. The system does the work but consults you on every choice point. Use for: teams that want to stay in the decision loop without manually triggering each phase, code reviews where architectural choices matter more than execution mechanics.

**`supervised`**: Strategize thresholds set to 0.0 (always automatic), but Execute and Apply thresholds set to 1.0 (always manual). The system plans autonomously and retries transient failures automatically, but pauses before Execute for human review of the strategy. Use for: projects where you trust the planning but want to review before execution begins.

**`cautious`**: Uses intermediate confidence thresholds (0.6–0.8) instead of binary 0.0/1.0 values. The system proceeds automatically only when the Semantic Escalation system reports high confidence, and escalates to the user when uncertain. Apply is always manual (1.0). Higher thresholds (0.8) are applied to riskier operations like strategy revision and execution decisions, while lower thresholds (0.6) are used for safer operations like checkpoint restores and strategy decisions. Transient retries are always automatic. Use for: teams adopting automation gradually, projects with mixed complexity where some tasks are routine but others need oversight, situations where you want the system to self-assess rather than follow rigid rules.

**`trusted`**: Strategize and Execute thresholds set to 0.0 (always automatic). Validation fixes and child plan spawning proceed automatically. The system pauses only before Apply (threshold 1.0) for human review of the final diffs. Use for: day-to-day feature development, routine refactoring, test generation.

**`auto`**: All thresholds set to 0.0 except Apply (1.0). The system can revise its own strategy, restore from checkpoints, and handle all decisions automatically. Only Apply requires human approval. Use for: well-understood projects, batch operations, tasks with strong invariant coverage.

**`ci`**: All thresholds set to 0.0 — complete end-to-end automation including Apply — but sandbox and checkpoints remain mandatory and unsafe tools are blocked. Designed for non-interactive environments where full automation is needed but safety nets must be preserved. Use for: CI/CD pipelines, automated testing workflows, scheduled batch jobs, any headless execution where rollback capability is essential.

**`full-auto`**: All thresholds set to 0.0 — complete end-to-end automation including Apply. No sandbox or checkpoint requirements. Unsafe tools are allowed. Use for: low-risk routine tasks (dependency updates, documentation generation, formatting), trusted batch operations with rollback capabilities, environments where external safety mechanisms exist.

#### Profile Precedence

Automation profiles are determined using this precedence (highest to lowest):

1. **Plan-level**: Explicitly set via `--automation-profile` on `agents plan use`
2. **Action-level**: Set on the action via `--automation-profile` on `agents action create`
3. **Project-level**: Set via `agents config set core.automation-profile <PROFILE> --project <PROJECT>`
4. **Global-level**: Set via `agents config set core.automation-profile <PROFILE>`

The **effective profile** for a plan is resolved at the moment of `agents plan use`. Once resolved, the profile is **locked to that plan** — subsequent changes to project or global profiles do not affect running plans.

#### Child Plan Profile Inheritance

Child plans inherit the parent plan's effective automation profile. If the parent's profile is changed explicitly after creation, new child plans use the new profile while already-running child plans retain their original profile.

#### Custom Automation Profiles

Custom profiles are created via YAML configuration files and registered with `agents automation-profile add`. Each automatable task flag takes a confidence threshold (0.0–1.0) instead of a boolean. A threshold of 0.0 means "always automatic" and 1.0 means "always manual." Intermediate values (e.g., 0.5, 0.7) enable fine-grained control where the system proceeds automatically only when the Semantic Escalation confidence score meets or exceeds the threshold:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># File: profiles/careful-auto.yaml</span>
<span style="color: cyan; font-weight: 600;">name</span>: local/careful-auto
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Autonomous execution with mandatory sandbox and manual apply&quot;</span>

<span style="opacity: 0.7;"># Confidence thresholds (0.0 = always auto, 1.0 = always manual)</span>
<span style="color: cyan; font-weight: 600;">auto_strategize</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_execute</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_apply</span>: <span style="color: yellow;">1.0</span>
<span style="color: cyan; font-weight: 600;">auto_decisions_strategize</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_decisions_execute</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_validation_fix</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_strategy_revision</span>: <span style="color: yellow;">1.0</span>
<span style="color: cyan; font-weight: 600;">auto_child_plans</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_retry_transient</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_checkpoint_restore</span>: <span style="color: yellow;">0.0</span>

<span style="opacity: 0.7;"># Safety flags (boolean)</span>
<span style="color: cyan; font-weight: 600;">require_sandbox</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">require_checkpoints</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">allow_unsafe_tools</span>: <span style="color: magenta; font-weight: 600;">false</span>
</code></pre></div>

A profile with intermediate thresholds provides nuanced control. For example, `auto_decisions_execute: 0.7` means decisions during Execute proceed automatically when confidence >= 0.7, but drop to manual review when confidence is below 0.7:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># File: profiles/nuanced-auto.yaml</span>
<span style="color: cyan; font-weight: 600;">name</span>: local/nuanced-auto
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Nuanced automation with graduated confidence thresholds&quot;</span>

<span style="color: cyan; font-weight: 600;">auto_strategize</span>: <span style="color: yellow;">0.0</span><span style="opacity: 0.7;">              # Always auto-strategize</span>
<span style="color: cyan; font-weight: 600;">auto_execute</span>: <span style="color: yellow;">0.5</span><span style="opacity: 0.7;">                 # Auto-execute when confidence >= 0.5</span>
<span style="color: cyan; font-weight: 600;">auto_apply</span>: <span style="color: yellow;">1.0</span><span style="opacity: 0.7;">                   # Always require manual apply</span>
<span style="color: cyan; font-weight: 600;">auto_decisions_strategize</span>: <span style="color: yellow;">0.3</span><span style="opacity: 0.7;">   # Low bar for strategy decisions</span>
<span style="color: cyan; font-weight: 600;">auto_decisions_execute</span>: <span style="color: yellow;">0.7</span><span style="opacity: 0.7;">      # Higher bar for execution decisions</span>
<span style="color: cyan; font-weight: 600;">auto_validation_fix</span>: <span style="color: yellow;">0.5</span><span style="opacity: 0.7;">        # Auto-fix when reasonably confident</span>
<span style="color: cyan; font-weight: 600;">auto_strategy_revision</span>: <span style="color: yellow;">0.8</span><span style="opacity: 0.7;">     # High confidence needed for auto-revision</span>
<span style="color: cyan; font-weight: 600;">auto_child_plans</span>: <span style="color: yellow;">0.5</span><span style="opacity: 0.7;">           # Auto-spawn when moderately confident</span>
<span style="color: cyan; font-weight: 600;">auto_retry_transient</span>: <span style="color: yellow;">0.0</span><span style="opacity: 0.7;">       # Always auto-retry transient errors</span>
<span style="color: cyan; font-weight: 600;">auto_checkpoint_restore</span>: <span style="color: yellow;">0.6</span><span style="opacity: 0.7;">    # Auto-restore when fairly confident</span>

<span style="color: cyan; font-weight: 600;">require_sandbox</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">require_checkpoints</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">allow_unsafe_tools</span>: <span style="color: magenta; font-weight: 600;">false</span>
</code></pre></div>

<div class="highlight"><pre><code>
agents automation-profile add <span style="color: cyan;">--config</span> ./profiles/careful-auto.yaml
</code></pre></div>

#### Semantic Escalation

Semantic Escalation is the system that computes a **confidence score** (0.0–1.0) for each operation, and it is the mechanism through which automation profile thresholds take effect. The confidence score reflects the system's assessment of how likely an autonomous action is to succeed without human guidance. This score is then compared against the profile's threshold for the relevant flag to determine whether to proceed automatically or escalate to the user.

The confidence score is computed from multiple factors:

<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">AutonomyController</span>:
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">should_proceed_automatically</span>(self, decision, context, profile):
        <span style="color: #66cc66;">&quot;&quot;&quot;Determine whether to proceed automatically or escalate to user.&quot;&quot;&quot;</span>
        factors = {
            <span style="color: #66cc66;">&#x27;past_success_rate&#x27;</span>: self.get_historical_success(decision.type),
            <span style="color: #66cc66;">&#x27;codebase_familiarity&#x27;</span>: self.get_familiarity_score(context.project),
            <span style="color: #66cc66;">&#x27;risk_assessment&#x27;</span>: self.evaluate_risk(decision),
            <span style="color: #66cc66;">&#x27;invariant_complexity&#x27;</span>: self.analyze_invariants(decision)
        }
        
        confidence = self.compute_confidence(factors)  <span style="opacity: 0.7;"># Returns 0.0–1.0</span>
        threshold = profile.get_threshold(decision.flag)  <span style="opacity: 0.7;"># e.g., auto_decisions_execute</span>
        
        <span style="color: magenta; font-weight: 600;">if</span> confidence &gt;= threshold:
            <span style="opacity: 0.7;"># Confidence meets or exceeds the profile threshold — proceed</span>
            <span style="color: magenta; font-weight: 600;">return</span> ProceedAutonomously(decision, confidence)
        <span style="color: magenta; font-weight: 600;">else</span>:
            <span style="opacity: 0.7;"># Confidence below threshold — escalate to human</span>
            <span style="color: magenta; font-weight: 600;">return</span> RequestHumanGuidance(decision, confidence, threshold, factors)
</code></pre></div>

**How thresholds and confidence interact**: A profile with `auto_decisions_execute: 0.7` means the system will make execution decisions automatically when confidence >= 0.7, but will pause for human input when confidence < 0.7. This is more nuanced than a binary on/off: a profile can set a high bar (0.9) for risky operations while being permissive (0.2) for low-risk ones.

**Special cases**: A threshold of **0.0** means "always automatic" — even zero confidence passes the threshold. A threshold of **1.0** means "always manual" — no confidence level (which tops out below 1.0 in practice) is high enough to pass. This means the old boolean behavior is a strict subset: `true` maps to `0.0` and `false` maps to `1.0`.

#### Progressive Trust Building

New users typically follow this progression:

1. Start with `manual` to understand system behavior
1. Move to `review` to let phases run automatically while staying in the decision loop
1. Adopt `supervised` as confidence in the planning phase builds
1. Try `cautious` for confidence-gated automation that escalates only when uncertain
1. Adopt `trusted` for routine development tasks
1. Enable `auto` for well-understood projects with strong invariant coverage
1. Use `ci` for headless CI/CD pipelines with safety nets intact
1. Use `full-auto` for low-risk batch operations where external safety mechanisms exist

### Guardrails

System-level guardrails are pre-flight checks and runtime limits that prevent plans from executing in invalid or unsafe conditions. These are distinct from **Validations** (the Tool subtype described in Core Concepts > Validation) — guardrails operate at the system/infrastructure level before and during plan execution, whereas Validations verify the *quality of the work produced* by a plan at the end of the Execute phase.

#### Plan Generation Guardrails

Before a plan begins execution, the system performs pre-flight validation to ensure the plan is well-formed and its dependencies are satisfiable. These checks must be implemented:

* **Action schema validation**: Verify the action referenced by the plan exists, is well-formed, and its configuration conforms to the expected schema.
* **Actor availability**: Confirm that all actors required by the plan (strategy actor, execution actor, estimation actor, invariant reconciliation actor) are registered and reachable. For remote actors, verify network connectivity.
* **Skill and tool existence**: Verify that all skills and tools referenced by the action's actor configuration exist in the registry. This includes both named tools and tools referenced via skills (transitively resolved).
* **Automation policy**: Verify that the automation profile allows the requested level of autonomy for the target project, resources, and actions.
* **Rollback feasibility**: If `require_checkpoints` is enabled on the plan, verify that all tools in the actor's skill set have `checkpointable: true`. Reject plans that would use non-checkpointable tools under a checkpoint-required policy.
* **Resource accessibility**: Verify that the project's linked resources are accessible — git repos are cloneable, databases are connectable, file system paths exist, etc. This is a shallow connectivity check, not a full resource health assessment.
* **Validation attachment resolution**: Pre-resolve the validations that will apply to this plan (from resource-direct, project, and plan attachment scopes) and verify they are all registered and their tool definitions are valid. This ensures validation failures during Execute are due to the work product, not misconfigured validations.

These pre-flight checks prevent "plan runs with fake providers," missing tool errors mid-execution, and other surprises that waste compute and user time. If any pre-flight check fails, the plan is rejected before entering the Strategize phase, with a clear error message identifying the failing check.

#### Cost and Rate Limits

Runtime guardrails to prevent runaway resource consumption:

* **Per-plan budgets**: Maximum API token spend, maximum wall-clock time, maximum number of tool invocations per plan. When a budget is exceeded, the plan pauses and requests user approval to continue or is terminated.
* **Per-session budgets**: Aggregate limits across all plans in a session. Prevents a single interactive session from consuming excessive resources.
* **Per-org budgets**: Server-enforced limits for multi-user deployments. Administrators set organization-wide spend caps that cannot be overridden by individual users.
* **Per-actor limits**: Maximum tool calls per actor invocation, maximum retries per tool failure, maximum tokens per LLM call. Prevents individual actors from looping indefinitely.
* **Validation retry limits**: Maximum number of fix-then-revalidate iterations when a required Validation fails during Execute. This is a specific application of per-actor limits — the default is 3 attempts, configurable per plan or in the automation profile.

Cost and rate limits are future concerns that require integration with LLM provider billing APIs and internal metering. The system should define configuration surfaces for these limits but may initially implement only the per-plan and per-actor limits, with per-session, per-org, and billing integration added later.

### Correcting Plans (Core Feature)

Correcting plans is where CleverAgents becomes more than "a fancy prompt runner."

#### The Goal

When a plan makes a wrong decision early, we want to:

* correct the decision,
* recompute only the affected subtree,
* preserve unaffected work.

This is explicitly described: "redo everything below that decision, not the entire code base."

#### Decision Tree Representation

Every plan records (see Decision Data Model section):

* decisions (choice points) - created during Strategize, including `invariant_enforced`, `subplan_spawn`, and `subplan_parallel_spawn` decisions
* dependencies (which later work depended on that decision)
* child plans spawned because of that decision - populated during Execute
* artifacts generated under that branch

This makes plan runs auditable and correctable.

#### Two Correction Modes

1. **Revert-from-history correction (`--mode=revert`)**

* Find the decision point in the tree
* Roll back all changes (code and non-code) to that point
* Re-run from that decision point forward
* Keep old execution artifacts for comparison
* Potentially expensive if high up in the tree

2. **Add-at-end correction (`--mode=append`)**

* Leave history intact
* Append a new plan at the end that fixes the outcome
* Cheaper and safer sometimes
* Does not rewrite history

#### Correction Flow (Revert Mode)

When user requests correction at Decision B:

1. **Mark for Correction**
   <div class="highlight"><pre><code>
   Decision B.superseded_by = new_decision_id
   </code></pre></div>

2. **Identify Downstream Impact**
   - Recursively collect all decisions that depend on Decision B (including `invariant_enforced`, `subplan_spawn`, and `subplan_parallel_spawn` decisions)
   - Collect all child plans spawned from those decisions
   - These form the "affected subtree"

3. **Rollback Resources**
   - For each affected decision's `artifacts_produced`:
     - Rollback to the checkpoint before that artifact was created
   - For affected child plans:
     - Rollback their sandboxes entirely

4. **Preserve for Comparison**
   - Archive the original subtree's artifacts
   - Create a `CorrectionAttempt` record linking old and new

5. **Re-execute from Decision Point**
   - Restore context to `Decision B.context_snapshot`
   - User provides new guidance/correction
   - Re-run execution from that point
   - New decisions get `is_correction: true, corrects_decision_id: B`

6. **Apply as Normal**
   - The corrected plan goes through normal Apply gating
   - Diff shows changes from the correction

#### History Cleanup

**History can only be flagged for cleanup after a plan is Applied.**

Once a plan is applied:
- It can no longer be rolled back
- Old correction artifacts can be archived or deleted based on retention policy
- The decision tree is preserved for audit purposes

#### CLI Commands for Correction

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># View decision tree</span>
agents plan tree &lt;plan_id&gt;
agents <span style="color: cyan;">--format</span>=json plan tree &lt;plan_id&gt;  # For visualization tools

<span style="opacity: 0.7;"># Inspect a specific decision</span>
agents plan explain &lt;decision_id&gt;
<span style="opacity: 0.7;"># Shows: question, chosen option, alternatives, rationale, downstream impact</span>

<span style="opacity: 0.7;"># Correct via revert-and-replay</span>
agents plan correct &lt;decision_id&gt; <span style="color: cyan;">--mode</span>=revert <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">&quot;&lt;what the decision should be&gt;&quot;</span>
<span style="opacity: 0.7;"># Re-executes from that point with the new guidance</span>

<span style="opacity: 0.7;"># Correct via append (add fix at end)  </span>
agents plan correct &lt;decision_id&gt; <span style="color: cyan;">--mode</span>=append <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">&quot;&lt;description of the fix&gt;&quot;</span>
<span style="opacity: 0.7;"># Creates a new child plan to fix the outcome without rewriting history</span>

<span style="opacity: 0.7;"># Compare old vs new after correction</span>
agents plan diff <span style="color: cyan;">--correction</span> &lt;correction_attempt_id&gt;
</code></pre></div>

#### Correction Safety

Corrections always:

* Create a new attempt revision (increment `plan.attempt`)
* Preserve old artifacts for diff/compare
* Run execute in sandbox again
* Require apply gating again
* Never modify already-applied changes

This keeps history reproducible and prevents accidental destructive edits.

### Human-in-the-Loop Collaboration

Even though the direction is "more autonomous," the transcript explicitly recognizes that real workflows require engineers to collaborate with the system, editing code while it works, and using better UX integration (TUI/web/IDE).

So CleverAgents should aim for:

* visibility: what is it doing now?
* interruptibility: pause/cancel/retry
* editability: allow user to modify strategy before execute
* reconciliation: detect if user changed sandbox files mid-run and handle it

### UI / Interaction Model

#### CLI-first + TUI + Web App + IDE

The system intends to be CLI-first, with:

* a TUI built using Textual,
* which can generate a web app "for free,"
* and later an IDE plugin that embeds the TUI in the IDE.

This implies a "single UI codebase" model:

* same underlying view logic,
* multiple frontends.

#### Plan Tree Visualization

The TUI should show:

* plan list
* plan details
* plan tree (ASCII)
* diff view
* approvals

And should later allow exporting the tree as image (PNG) or JSON for other visualization tools.

## Configuration

This section provides a complete reference for the YAML configuration files used to define the major configurable objects in CleverAgents: **Actors**, **Skills**, **Tools**, **Actions**, **Resource Types**, **Context Views**, and **Automation Profiles**. Projects are created via CLI commands rather than standalone configuration files, but their context views are configured through YAML and are documented here as well. It also documents the global configuration keys that control system-wide behavior.

### Global Configuration Keys

Global configuration keys control system-wide defaults and behavior. They are stored in the global configuration file (default: `~/.cleveragents/config.toml`) and managed via the `agents config set`, `agents config get`, and `agents config list` commands.

#### Hierarchical Key Structure

Configuration keys use **dot-separated hierarchical names**, similar to `git config`. Each dot introduces a level of nesting, grouping related keys under a common parent. For example:

<div class="highlight"><pre><code>
core.format              <span style="opacity: 0.7;"># top-level "core" group, "format" key</span>
core.log.level           <span style="opacity: 0.7;"># "core" group, "log" subgroup, "level" key</span>
index.text.backend       <span style="opacity: 0.7;"># "index" group, "text" subgroup, "backend" key</span>
</code></pre></div>

The key `plan.concurrency` is **not** the same as a top-level key `concurrency` — the dot path is the full identity of the key. This means you can have `plan.concurrency` and `session.concurrency` as distinct keys without conflict.

On the CLI, the full dot path is always used:

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set core.format table
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config get plan.budget.per-plan
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config list plan.*
</code></pre></div>

The `agents config list` command accepts an optional glob pattern to filter keys by subtree. For example, `agents config list index.*` lists all keys under the `index` group, and `agents config list provider.*` lists all provider credential keys.

In the TOML configuration file, the hierarchy maps directly to TOML's native table structure. The dot-path key `index.text.backend` can be expressed equivalently as:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Inline dot notation (convenient for single keys)</span>
<span style="color: cyan; font-weight: 600;">index.text.backend</span> = <span style="color: #66cc66;">"tantivy"</span>

<span style="opacity: 0.7;"># Or as nested TOML tables (better for groups)</span>
[<span style="color: cyan; font-weight: 600;">index.text</span>]
<span style="color: cyan;">backend</span> = <span style="color: #66cc66;">"tantivy"</span>

[<span style="color: cyan; font-weight: 600;">index.vector</span>]
<span style="color: cyan;">backend</span> = <span style="color: #66cc66;">"faiss"</span>
</code></pre></div>

Both forms are valid and can be mixed. The TOML parser normalizes them to the same internal representation.

Every key follows a resolution chain: CLI flag > environment variable > project-scoped config > global config file > built-in default.

#### Key Reference

Keys are organized by their top-level group. Within each group, the full dot-path, type, default, corresponding environment variable, and description are provided.

##### `core.*` — Core System Settings

| Key | Type | Default | Env Variable | Description |
|-----|------|---------|-------------|-------------|
| `core.data-dir` | string | `~/.cleveragents` | `CLEVERAGENTS_DATA_DIR` | Root directory for all CleverAgents persistent state: database, logs, cache, sessions, checkpoints, and backups. All other paths are derived relative to this directory unless individually overridden. Overridden per-invocation by the `--data-dir` CLI flag. |
| `core.config-path` | string | `<core.data-dir>/config.toml` | `CLEVERAGENTS_CONFIG_PATH` | Path to the global configuration file itself. Typically only set via environment variable or CLI flag to bootstrap an alternate configuration. Overridden per-invocation by the `--config-path` CLI flag. |
| `core.format` | string | `rich` | `CLEVERAGENTS_FORMAT` | Default output rendering format for all CLI commands. Accepted values: `rich`, `color`, `table`, `plain`, `json`, `yaml`. Overridden per-invocation by the `--format` CLI flag. |
| `core.namespace` | string | `local` | `CLEVERAGENTS_NAMESPACE` | The default namespace prefix applied when creating entities without an explicit namespace. For local-only usage, this is `local`. In server mode, typically the user's username or organization name. |
| `core.automation-profile` | string | `supervised` | `CLEVERAGENTS_AUTOMATION_PROFILE` | The default automation profile applied to new plans when no profile is specified at the plan, action, or project level. Accepts any built-in profile name (`manual`, `review`, `supervised`, `cautious`, `trusted`, `auto`, `ci`, `full-auto`) or a custom profile name in `<namespace>/<name>` format. **Project-scopable.** |
| `core.log.level` | string | `FATAL` | `CLEVERAGENTS_LOG_LEVEL` | Base logging verbosity level. Accepted values (from least to most verbose): `FATAL`, `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`. The default `FATAL` means only fatal errors (where the application exits) produce log output; all other log messages are suppressed. The `-v` CLI flag can be repeated (`-v` through `-vvvvv`) to raise the effective level for a single invocation: `-v` = ERROR, `-vv` = WARN, `-vvv` = INFO, `-vvvv` = DEBUG, `-vvvvv` = TRACE. The effective level applies to both log file output and terminal log output (subject to `core.log.terminal` and `core.log.file-enabled` settings). |
| `core.log.dir` | string | `<core.data-dir>/logs` | `CLEVERAGENTS_LOG_DIR` | Directory where log files are written. Can be set to an alternative path to redirect log storage. |
| `core.log.file-enabled` | boolean | `true` | `CLEVERAGENTS_LOG_FILE_ENABLED` | Whether log output is written to log files. When `true`, log messages at or above the effective verbosity level are written to the log directory. When `false`, log file output is suppressed entirely (useful when log output should only go to the terminal). |
| `core.log.terminal` | string | `auto` | `CLEVERAGENTS_LOG_TERMINAL` | Controls whether log output raised by `-v` is also displayed on the terminal. Accepted values: `auto` (show on terminal when `-v` is used, suppress otherwise), `always` (always show log output on terminal at the effective level), `never` (suppress terminal log output entirely — log only to file). This keeps log output separate from normal program output, which goes to stdout. |
| `core.log.terminal-stream` | string | `stderr` | `CLEVERAGENTS_LOG_TERMINAL_STREAM` | The stream used for terminal log output. Accepted values: `stderr` (default, keeps logs separate from normal stdout output), `stdout` (merge with normal output), or a file path / device path (e.g., `/dev/null`, `/dev/pts/1`, or a file path) to redirect terminal log output to an alternative destination. |
| `core.log.retention-days` | integer | `30` | `CLEVERAGENTS_LOG_RETENTION_DAYS` | Number of days to retain log files before automatic cleanup. |
| `core.backup.dir` | string | `<core.data-dir>/backups` | `CLEVERAGENTS_BACKUP_DIR` | Directory where backup snapshots are stored. |
| `core.backup.retention-days` | integer | `7` | `CLEVERAGENTS_BACKUP_RETENTION_DAYS` | Number of days to retain backup snapshots created during project deletion, `agents init` resets, and plan correction history cleanup. Backups older than this are automatically purged. |
| `core.cache.dir` | string | `<core.data-dir>/cache` | `CLEVERAGENTS_CACHE_DIR` | Directory for transient caches (downloaded models, tool artifacts, temporary files). |

##### `server.*` — Server Mode

| Key | Type | Default | Env Variable | Description |
|-----|------|---------|-------------|-------------|
| `server.url` | string | *(not set)* | `CLEVERAGENTS_SERVER_URL` | URL of the CleverAgents server for multi-user collaborative mode. When set, the CLI operates in server mode, syncing namespaced entities (actors, actions, skills, projects) with the remote server. When unset, the CLI operates in local-only mode. |
| `server.token` | string | *(not set)* | `CLEVERAGENTS_SERVER_TOKEN` | Authentication token for server mode. Required when `server.url` is set. Obtained via server registration or team invite flow. Prefer the environment variable for CI environments. |
| `server.sync.auto` | boolean | `true` | `CLEVERAGENTS_SERVER_SYNC_AUTO` | Whether to automatically sync entity definitions (actors, actions, skills) with the server on startup and after registration changes. When `false`, sync must be triggered manually. |
| `server.sync.interval` | integer | `300` | `CLEVERAGENTS_SERVER_SYNC_INTERVAL` | Interval in seconds between automatic background syncs with the server. Only applies when `server.sync.auto` is `true`. |

##### `actor.*` — Actor Defaults

| Key | Type | Default | Env Variable | Description |
|-----|------|---------|-------------|-------------|
| `actor.default.strategy` | string | *(not set)* | `CLEVERAGENTS_DEFAULT_STRATEGY_ACTOR` | Default strategy actor used for plans when not specified on the action or `plan use` invocation. Must reference a registered actor in `<namespace>/<name>` format. When unset, the action's `strategy_actor` field is required. |
| `actor.default.execution` | string | *(not set)* | `CLEVERAGENTS_DEFAULT_EXECUTION_ACTOR` | Default execution actor used for plans when not specified on the action or `plan use` invocation. Must reference a registered actor. When unset, the action's `execution_actor` field is required. |
| `actor.default.estimation` | string | *(not set)* | `CLEVERAGENTS_DEFAULT_ESTIMATION_ACTOR` | Default estimation actor used for cost and effort estimation. Estimation is optional; when unset, plans skip the estimation step. |
| `actor.default.invariant` | string | *(not set)* | `CLEVERAGENTS_DEFAULT_INVARIANT_ACTOR` | Default Invariant Reconciliation Actor used globally. When a plan enters Strategize and neither the plan, action, nor project specifies an invariant actor, this actor reconciles invariant conflicts across scopes. Must reference a registered actor. |
| `actor.default.orchestrator` | string | *(not set)* | `CLEVERAGENTS_DEFAULT_ORCHESTRATOR` | Default orchestrator actor for new sessions created without an explicit `--actor` flag. |

##### `plan.*` — Plan Execution

| Key | Type | Default | Env Variable | Description |
|-----|------|---------|-------------|-------------|
| `plan.concurrency` | integer | `4` | `CLEVERAGENTS_PLAN_CONCURRENCY` | Maximum number of plans that can execute concurrently. When this limit is reached, new `plan execute` commands queue until a slot opens. Child plans count toward the parent's concurrency allocation, not toward the global limit. **Project-scopable.** |
| `plan.max-child-depth` | integer | `5` | `CLEVERAGENTS_PLAN_MAX_CHILD_DEPTH` | Maximum nesting depth for child plan spawning. Prevents runaway recursive plan decomposition. A value of 1 means no child plans; 5 means up to 5 levels of parent-child nesting. **Project-scopable.** |
| `plan.budget.per-plan` | float | *(not set)* | `CLEVERAGENTS_PLAN_BUDGET` | Maximum estimated API cost (in USD) allowed per plan. When the running cost estimate exceeds this budget, the plan pauses and requests human approval to continue. When unset, no per-plan cost limit is enforced. **Project-scopable.** |
| `plan.budget.per-session` | float | *(not set)* | `CLEVERAGENTS_SESSION_BUDGET` | Maximum estimated API cost (in USD) allowed per session. When cumulative session cost exceeds this budget, all plan operations in the session pause. When unset, no per-session cost limit is enforced. |
| `plan.budget.warn-threshold` | float | `0.8` | `CLEVERAGENTS_PLAN_BUDGET_WARN` | Fraction of the per-plan budget at which a warning is emitted. For example, `0.8` means a warning fires at 80% of the budget. Only effective when `plan.budget.per-plan` is set. |
| `plan.tool.max-calls-per-step` | integer | `25` | `CLEVERAGENTS_TOOL_MAX_CALLS` | Maximum number of tool invocations allowed in a single actor step (one LLM turn). Prevents runaway tool loops. When the limit is reached, the actor step is interrupted and the plan pauses for human review. |
| `plan.tool.max-retries` | integer | `3` | `CLEVERAGENTS_TOOL_MAX_RETRIES` | Maximum number of retry attempts for a single failing tool invocation before escalating. Applies to transient errors (network timeouts, rate limits). Non-transient errors fail immediately. |
| `plan.tool.retry-backoff` | string | `exponential` | `CLEVERAGENTS_TOOL_RETRY_BACKOFF` | Retry backoff strategy for transient tool failures. Accepted values: `exponential` (doubling delay starting at 1s), `linear` (fixed 2s delay), `none` (immediate retry). |

##### `sandbox.*` — Sandbox and Checkpointing

| Key | Type | Default | Env Variable | Description |
|-----|------|---------|-------------|-------------|
| `sandbox.strategy` | string | `git_worktree` | `CLEVERAGENTS_SANDBOX_STRATEGY` | Default sandbox isolation strategy for the Execute phase. Accepted values: `git_worktree` (create a git worktree for isolation), `filesystem_copy` (copy the project directory), `transaction_rollback` (for database resources), `none` (no isolation — requires `require_sandbox: false` in the automation profile). Per-resource-type strategies override this default. **Project-scopable.** |
| `sandbox.cleanup` | string | `on_apply` | `CLEVERAGENTS_SANDBOX_CLEANUP` | When to clean up sandbox working directories. Accepted values: `on_apply` (clean up after successful apply), `on_terminal` (clean up when plan reaches any terminal state — applied, cancelled, or failed), `manual` (never auto-clean; user must delete). |
| `sandbox.checkpoint.enabled` | boolean | `true` | `CLEVERAGENTS_CHECKPOINT_ENABLED` | Whether checkpointing is enabled globally. When `true`, the Execute phase creates checkpoints before write operations, enabling rollback. When `false`, checkpointing is skipped (requires `require_checkpoints: false` in the automation profile). **Project-scopable.** |
| `sandbox.checkpoint.dir` | string | `<core.data-dir>/checkpoints` | `CLEVERAGENTS_CHECKPOINT_DIR` | Directory where plan execution checkpoints are stored. Each plan gets a subdirectory named by its ULID. |
| `sandbox.checkpoint.max-per-plan` | integer | `50` | `CLEVERAGENTS_CHECKPOINT_MAX` | Maximum number of checkpoints retained per plan. When exceeded, the oldest checkpoints are pruned (keeping the first and most recent). |

##### `index.*` — Code Intelligence and Indexing

| Key | Type | Default | Env Variable | Description |
|-----|------|---------|-------------|-------------|
| `index.text.backend` | string | `tantivy` | `CLEVERAGENTS_INDEX_TEXT_BACKEND` | Backend for full-text search indexing of project resources. Accepted values: `tantivy` (recommended, high-performance Rust-based engine), `sqlite_fts` (built-in SQLite FTS5, no additional dependencies). |
| `index.text.dir` | string | `<core.data-dir>/index/text` | `CLEVERAGENTS_INDEX_TEXT_DIR` | Directory where the full-text search index is stored. |
| `index.vector.backend` | string | `faiss` | `CLEVERAGENTS_INDEX_VECTOR_BACKEND` | Backend for vector similarity search (semantic code search). Accepted values: `faiss` (Facebook AI Similarity Search, CPU or GPU), `qdrant` (requires a running Qdrant server), `none` (disable vector search). |
| `index.vector.dir` | string | `<core.data-dir>/index/vector` | `CLEVERAGENTS_INDEX_VECTOR_DIR` | Directory where the vector index is stored (for local backends). |
| `index.vector.qdrant-url` | string | *(not set)* | `CLEVERAGENTS_QDRANT_URL` | URL of the Qdrant server. Required when `index.vector.backend` is `qdrant`. |
| `index.graph.backend` | string | `none` | `CLEVERAGENTS_INDEX_GRAPH_BACKEND` | Backend for the knowledge graph store (structural code relationships, RDF triples). Accepted values: `neo4j` (requires a running Neo4j server), `rdflib` (in-process Python RDF library), `none` (disable graph queries). |
| `index.graph.neo4j-url` | string | *(not set)* | `CLEVERAGENTS_NEO4J_URL` | URL of the Neo4j server. Required when `index.graph.backend` is `neo4j`. |
| `index.graph.neo4j-auth` | string | *(not set)* | `CLEVERAGENTS_NEO4J_AUTH` | Authentication for Neo4j in `user:password` format. Required when `index.graph.backend` is `neo4j`. |
| `index.embedding.provider` | string | `openai` | `CLEVERAGENTS_EMBEDDING_PROVIDER` | Provider used for generating vector embeddings. Accepted values: `openai`, `anthropic`, `local` (uses a local sentence-transformers model). When `local`, no API key is required for embedding generation. |
| `index.embedding.model` | string | `text-embedding-3-small` | `CLEVERAGENTS_EMBEDDING_MODEL` | Model identifier used for generating vector embeddings when indexing project resources. Must be a valid model for the configured `index.embedding.provider`. |
| `index.embedding.dimensions` | integer | *(provider default)* | `CLEVERAGENTS_EMBEDDING_DIMENSIONS` | Number of dimensions for generated embeddings. When unset, the provider's default dimensionality for the chosen model is used. Can be reduced for faster search at the cost of accuracy. |
| `index.auto-reindex` | boolean | `true` | `CLEVERAGENTS_AUTO_REINDEX` | Whether to automatically re-index project resources when files change on disk. When `true`, indexes are updated on resource add and before each Strategize phase. When `false`, re-indexing must be triggered manually. |

##### `context.*` — Context Tier Defaults

These keys set the default context policy for all projects. Project-level context policies (set via `agents project context set`) override these defaults. All keys in this group are **project-scopable**.

| Key | Type | Default | Env Variable | Description |
|-----|------|---------|-------------|-------------|
| `context.hot.max-tokens` | integer | `16000` | `CLEVERAGENTS_CTX_HOT_TOKENS` | Default maximum token budget for hot context (the current working set loaded into the LLM context window). This is a soft cap; the actor's model context window is the hard limit. |
| `context.warm.max-decisions` | integer | `100` | `CLEVERAGENTS_CTX_WARM_DECISIONS` | Default maximum number of recent decisions retained in warm context (available for retrieval but not loaded by default). |
| `context.cold.max-decisions` | integer | `500` | `CLEVERAGENTS_CTX_COLD_DECISIONS` | Default maximum number of historical decisions retained in cold context (archived for audit and correction). |
| `context.query.limit` | integer | `20` | `CLEVERAGENTS_CTX_QUERY_LIMIT` | Default maximum number of retrieval results returned per context query during Strategize and Execute. |
| `context.query.min-relevance` | float | `0.3` | `CLEVERAGENTS_CTX_QUERY_MIN_RELEVANCE` | Minimum relevance score (0.0–1.0) for retrieval results to be included in context. Results below this threshold are discarded even if the query limit is not reached. |
| `context.file.max-size` | integer | `1048576` | `CLEVERAGENTS_CTX_MAX_FILE_SIZE` | Default maximum file size (in bytes) for files included in context. Files exceeding this size are summarized or excluded. Default is 1 MB (1,048,576 bytes). |
| `context.file.max-total-size` | integer | `52428800` | `CLEVERAGENTS_CTX_MAX_TOTAL_SIZE` | Default maximum total size (in bytes) across all files included in context. Default is 50 MB. |
| `context.summarize.enabled` | boolean | `true` | `CLEVERAGENTS_CTX_SUMMARIZE` | Whether to summarize large context segments that exceed token limits rather than truncating them. When `true`, an LLM summarization pass produces a condensed version. When `false`, content is hard-truncated. |
| `context.summarize.max-tokens` | integer | `1000` | `CLEVERAGENTS_CTX_SUMMARY_TOKENS` | Maximum number of tokens in a generated context summary. Controls the verbosity of summaries produced when `context.summarize.enabled` is `true`. |
| `context.summarize.model` | string | *(uses actor's model)* | `CLEVERAGENTS_CTX_SUMMARY_MODEL` | Model to use for context summarization. When unset, the active actor's own model is used. Set this to a faster/cheaper model (e.g., a smaller variant) to reduce summarization cost. |
| `context.strategies.enabled` | list | `["simple-keyword", "semantic-embedding", "breadth-depth-navigator"]` | `CLEVERAGENTS_CTX_STRATEGIES` | Ordered list of ACMS context strategies enabled globally. Strategies are run in parallel and their results fused by the Fusion Engine. |
| `context.strategies.custom.*` | object | *(none)* | — | Registration block for custom context strategies. Each key under `custom` names a strategy; the value specifies its `module`, `class`, `max_quality`, and optional `config`. |
| `context.strategies.arce.model` | string | *(uses actor's model)* | `CLEVERAGENTS_CTX_ARCE_MODEL` | Model used by the ARCE (Autonomous Reasoning Context Extraction) strategy for its internal reasoning loop. |
| `context.strategies.arce.max-rounds` | integer | `3` | `CLEVERAGENTS_CTX_ARCE_ROUNDS` | Maximum number of search-refine rounds the ARCE strategy performs before returning results. |
| `context.strategies.breadth-depth-navigator.max-hops` | integer | `4` | `CLEVERAGENTS_CTX_BDN_HOPS` | Maximum graph traversal depth for the breadth-depth-navigator strategy. |
| `context.budget.response-reserve-tokens` | integer | `4096` | `CLEVERAGENTS_CTX_RESPONSE_RESERVE` | Number of tokens reserved from the model's context window for the response. Subtracted before computing the context budget. |
| `context.budget.tool-definition-estimate` | integer | *(auto-computed)* | `CLEVERAGENTS_CTX_TOOL_ESTIMATE` | Estimated tokens consumed by tool definitions in the prompt. When unset, computed from the active skill set. |
| `context.budget.skeleton-ratio` | float | `0.15` | `CLEVERAGENTS_CTX_SKELETON_RATIO` | Default fraction of the context budget reserved for inherited plan skeleton context. |
| `context.budget.refresh-threshold` | float | `0.30` | `CLEVERAGENTS_CTX_REFRESH_THRESHOLD` | Fractional change in available budget that triggers automatic context re-assembly. E.g., `0.30` means re-assemble when budget changes by more than 30%. |
| `context.budget.min-useful-budget` | integer | `500` | `CLEVERAGENTS_CTX_MIN_BUDGET` | Minimum useful context budget in tokens. If the computed budget falls below this, context assembly is skipped and a warning is emitted. |
| `context.tiers.warm.retention-hours` | integer | `24` | `CLEVERAGENTS_CTX_WARM_HOURS` | Number of hours warm-tier context entries are retained before demotion to cold tier. |
| `context.tiers.cold.retention-days` | integer | `90` | `CLEVERAGENTS_CTX_COLD_DAYS` | Number of days cold-tier context entries are retained before archival/expiry. |
| `context.uko.default-analyzers` | list | `["python", "typescript", "rust", "java", "markdown", "json-schema"]` | `CLEVERAGENTS_CTX_UKO_ANALYZERS` | List of UKO analyzers enabled by default for resource indexing. Each analyzer extracts language-specific UKO nodes from resources. |
| `context.uko.analyzers.custom.*` | object | *(none)* | — | Registration block for custom UKO analyzers. Each key under `custom` names an analyzer; the value specifies its `module`, `class`, `languages`, and optional `config`. |
| `context.fusion.dedup-strategy` | string | `content-hash` | `CLEVERAGENTS_CTX_FUSION_DEDUP` | Deduplication strategy used by the Fusion Engine: `content-hash` (hash-based), `uko-identity` (same UKO node), or `semantic` (embedding similarity). |
| `context.fusion.ordering` | string | `relevance-coherence` | `CLEVERAGENTS_CTX_FUSION_ORDER` | Ordering strategy for the final context payload: `relevance` (by score), `topological` (by dependency), `relevance-coherence` (relevance with coherence grouping). |
| `context.fusion.preamble-enabled` | boolean | `true` | `CLEVERAGENTS_CTX_FUSION_PREAMBLE` | Whether the Fusion Engine prepends a structured preamble (listing included files, strategies used, and budget usage) to the assembled context. |
| `context.fusion.preamble-max-tokens` | integer | `200` | `CLEVERAGENTS_CTX_FUSION_PREAMBLE_TOKENS` | Maximum tokens allocated to the context preamble. |

##### `provider.*` — LLM Provider Credentials

Provider credential keys follow the pattern `provider.<name>.<field>`. Each provider has an `api-key` field and may have additional fields for endpoint configuration. Environment variables for provider keys use standard naming conventions compatible with existing tooling (e.g., `OPENAI_API_KEY`).

| Key | Type | Default | Env Variable | Description |
|-----|------|---------|-------------|-------------|
| `provider.openai.api-key` | string | *(not set)* | `OPENAI_API_KEY` | API key for OpenAI models. Required when using OpenAI-based actors or the default embedding provider. The standard `OPENAI_API_KEY` environment variable is checked for compatibility with existing tooling. |
| `provider.openai.org-id` | string | *(not set)* | `OPENAI_ORG_ID` | OpenAI organization ID. Optional; used when the API key belongs to multiple organizations. |
| `provider.openai.base-url` | string | *(not set)* | `OPENAI_BASE_URL` | Custom base URL for OpenAI-compatible APIs (e.g., a local proxy or alternative provider). When unset, the official OpenAI API URL is used. |
| `provider.anthropic.api-key` | string | *(not set)* | `ANTHROPIC_API_KEY` | API key for Anthropic models. Required when using Anthropic-based actors. |
| `provider.google.api-key` | string | *(not set)* | `GOOGLE_API_KEY` | API key for Google AI models. Required when using Google-based actors. |
| `provider.azure.endpoint` | string | *(not set)* | `AZURE_OPENAI_ENDPOINT` | Azure OpenAI endpoint URL. Required when using Azure-hosted OpenAI models. |
| `provider.azure.api-key` | string | *(not set)* | `AZURE_OPENAI_API_KEY` | API key for Azure OpenAI. Required alongside `provider.azure.endpoint`. |
| `provider.azure.api-version` | string | `2024-02-01` | `AZURE_OPENAI_API_VERSION` | Azure OpenAI API version string. |
| `provider.openrouter.api-key` | string | *(not set)* | `OPENROUTER_API_KEY` | API key for OpenRouter. Required when using OpenRouter as a provider. |

#### Configuration Scoping

Several keys support **project-scoped** values in addition to the global default. When a project-scoped value is set, it applies only to plans targeting that project. Keys marked **Project-scopable** in the reference above support this feature.

The full dot path is used identically in both global and project-scoped contexts:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Set a global default</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set core.automation-profile trusted

<span style="opacity: 0.7;"># Override for a specific project — same key, scoped to the project</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set core.automation-profile manual <span style="color: cyan;">--project</span> local/production-api

<span style="opacity: 0.7;"># Project-scoped keys under any group work the same way</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set plan.budget.per-plan 2.00 <span style="color: cyan;">--project</span> local/production-api
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set sandbox.strategy git_worktree <span style="color: cyan;">--project</span> local/production-api
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set context.hot.max-tokens 32000 <span style="color: cyan;">--project</span> local/large-codebase
</code></pre></div>

The full list of project-scopable keys: `core.automation-profile`, `plan.concurrency`, `plan.max-child-depth`, `plan.budget.per-plan`, `sandbox.strategy`, `sandbox.checkpoint.enabled`, and all keys under `context.*`.

#### Resolution Order

When resolving the effective value of a configuration key, the following precedence applies (highest to lowest):

1. **CLI flag**: Per-invocation overrides (e.g., `--format` maps to `core.format`, `--data-dir` maps to `core.data-dir`). Highest priority.
2. **Environment variable**: The mapped `CLEVERAGENTS_*` variable or provider-specific variable (e.g., `OPENAI_API_KEY` for `provider.openai.api-key`).
3. **Project-scoped config**: For project-scopable keys, the value set via `agents config set <key> <value> --project <PROJECT>`. Only applies in contexts where a project is known (e.g., during plan execution).
4. **Global config file**: The value in the config file at the path specified by `core.config-path`.
5. **Built-in default**: The hardcoded default value.

The `agents config get <key>` command displays the full resolution chain, showing which level provided the winning value. Listing subtrees is supported:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Show the full resolution chain for a single key</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config get sandbox.checkpoint.enabled

<span style="opacity: 0.7;"># List all keys in a group</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config list index.*

<span style="opacity: 0.7;"># List all keys with their current effective values</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config list
</code></pre></div>

#### Configuration File Format

The global configuration file uses TOML format. The hierarchical key structure maps naturally to TOML tables. A typical `config.toml` after initial setup:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># ~/.cleveragents/config.toml</span>

[<span style="color: cyan; font-weight: 600;">core</span>]
<span style="color: cyan;">data-dir</span> = <span style="color: #66cc66;">"/home/alex/.cleveragents"</span>
<span style="color: cyan;">format</span> = <span style="color: #66cc66;">"rich"</span>
<span style="color: cyan;">namespace</span> = <span style="color: #66cc66;">"local"</span>
<span style="color: cyan;">automation-profile</span> = <span style="color: #66cc66;">"supervised"</span>

[<span style="color: cyan; font-weight: 600;">core.log</span>]
<span style="color: cyan;">level</span> = <span style="color: #66cc66;">"FATAL"</span>
<span style="color: cyan;">terminal</span> = <span style="color: #66cc66;">"auto"</span>
<span style="color: cyan;">terminal-stream</span> = <span style="color: #66cc66;">"stderr"</span>
<span style="color: cyan;">file-enabled</span> = <span style="color: yellow;">true</span>
<span style="color: cyan;">retention-days</span> = <span style="color: yellow;">30</span>

[<span style="color: cyan; font-weight: 600;">core.backup</span>]
<span style="color: cyan;">retention-days</span> = <span style="color: yellow;">7</span>

[<span style="color: cyan; font-weight: 600;">server</span>]
<span style="opacity: 0.7;"># url = "https://agents.example.com"</span>
<span style="opacity: 0.7;"># token = "tok_01HXR..."</span>

[<span style="color: cyan; font-weight: 600;">actor.default</span>]
<span style="color: cyan;">strategy</span> = <span style="color: #66cc66;">"local/strategist"</span>
<span style="color: cyan;">execution</span> = <span style="color: #66cc66;">"local/executor"</span>
<span style="color: cyan;">invariant</span> = <span style="color: #66cc66;">"local/invariant-resolver"</span>
<span style="opacity: 0.7;"># estimation = "local/estimator"</span>
<span style="opacity: 0.7;"># orchestrator = "local/orchestrator"</span>

[<span style="color: cyan; font-weight: 600;">plan</span>]
<span style="color: cyan;">concurrency</span> = <span style="color: yellow;">4</span>
<span style="color: cyan;">max-child-depth</span> = <span style="color: yellow;">5</span>

[<span style="color: cyan; font-weight: 600;">plan.budget</span>]
<span style="color: cyan;">per-plan</span> = <span style="color: yellow;">5.00</span>
<span style="color: cyan;">per-session</span> = <span style="color: yellow;">25.00</span>
<span style="color: cyan;">warn-threshold</span> = <span style="color: yellow;">0.8</span>

[<span style="color: cyan; font-weight: 600;">plan.tool</span>]
<span style="color: cyan;">max-calls-per-step</span> = <span style="color: yellow;">25</span>
<span style="color: cyan;">max-retries</span> = <span style="color: yellow;">3</span>
<span style="color: cyan;">retry-backoff</span> = <span style="color: #66cc66;">"exponential"</span>

[<span style="color: cyan; font-weight: 600;">sandbox</span>]
<span style="color: cyan;">strategy</span> = <span style="color: #66cc66;">"git_worktree"</span>
<span style="color: cyan;">cleanup</span> = <span style="color: #66cc66;">"on_apply"</span>

[<span style="color: cyan; font-weight: 600;">sandbox.checkpoint</span>]
<span style="color: cyan;">enabled</span> = <span style="color: yellow;">true</span>
<span style="color: cyan;">max-per-plan</span> = <span style="color: yellow;">50</span>

[<span style="color: cyan; font-weight: 600;">index.text</span>]
<span style="color: cyan;">backend</span> = <span style="color: #66cc66;">"tantivy"</span>

[<span style="color: cyan; font-weight: 600;">index.vector</span>]
<span style="color: cyan;">backend</span> = <span style="color: #66cc66;">"faiss"</span>

[<span style="color: cyan; font-weight: 600;">index.graph</span>]
<span style="color: cyan;">backend</span> = <span style="color: #66cc66;">"none"</span>

[<span style="color: cyan; font-weight: 600;">index.embedding</span>]
<span style="color: cyan;">provider</span> = <span style="color: #66cc66;">"openai"</span>
<span style="color: cyan;">model</span> = <span style="color: #66cc66;">"text-embedding-3-small"</span>

[<span style="color: cyan; font-weight: 600;">context.hot</span>]
<span style="color: cyan;">max-tokens</span> = <span style="color: yellow;">16000</span>

[<span style="color: cyan; font-weight: 600;">context.warm</span>]
<span style="color: cyan;">max-decisions</span> = <span style="color: yellow;">100</span>

[<span style="color: cyan; font-weight: 600;">context.cold</span>]
<span style="color: cyan;">max-decisions</span> = <span style="color: yellow;">500</span>

[<span style="color: cyan; font-weight: 600;">context.query</span>]
<span style="color: cyan;">limit</span> = <span style="color: yellow;">20</span>
<span style="color: cyan;">min-relevance</span> = <span style="color: yellow;">0.3</span>

[<span style="color: cyan; font-weight: 600;">context.file</span>]
<span style="color: cyan;">max-size</span> = <span style="color: yellow;">1048576</span>
<span style="color: cyan;">max-total-size</span> = <span style="color: yellow;">52428800</span>

[<span style="color: cyan; font-weight: 600;">context.summarize</span>]
<span style="color: cyan;">enabled</span> = <span style="color: yellow;">true</span>
<span style="color: cyan;">max-tokens</span> = <span style="color: yellow;">1000</span>

<span style="opacity: 0.7;"># Provider keys — prefer environment variables for secrets</span>
[<span style="color: cyan; font-weight: 600;">provider.openai</span>]
<span style="opacity: 0.7;"># api-key = "sk-..."</span>

[<span style="color: cyan; font-weight: 600;">provider.anthropic</span>]
<span style="opacity: 0.7;"># api-key = "sk-ant-..."</span>

<span style="opacity: 0.7;"># Project-scoped overrides</span>
[<span style="color: cyan; font-weight: 600;">project.<span style="color: #66cc66;">"local/production-api"</span></span>]
<span style="color: #66cc66;">"core.automation-profile"</span> = <span style="color: #66cc66;">"manual"</span>
<span style="color: #66cc66;">"plan.budget.per-plan"</span> = <span style="color: yellow;">2.00</span>
<span style="color: #66cc66;">"sandbox.strategy"</span> = <span style="color: #66cc66;">"git_worktree"</span>
<span style="color: #66cc66;">"sandbox.checkpoint.enabled"</span> = <span style="color: yellow;">true</span>

[<span style="color: cyan; font-weight: 600;">project.<span style="color: #66cc66;">"local/docs"</span></span>]
<span style="color: #66cc66;">"core.automation-profile"</span> = <span style="color: #66cc66;">"auto"</span>
<span style="color: #66cc66;">"plan.budget.per-plan"</span> = <span style="color: yellow;">10.00</span>
<span style="color: #66cc66;">"context.hot.max-tokens"</span> = <span style="color: yellow;">32000</span>
</code></pre></div>

### Design Principles

All CleverAgents configuration files share a consistent set of design principles:

1. **YAML-first**: All configuration files use YAML syntax. JSON is also accepted where a configuration file is loaded (since valid JSON is valid YAML), but YAML is the canonical format for human-authored configurations.

2. **Namespace/Name convention**: Every configurable entity follows the `<namespace>/<name>` naming convention. The `local/` namespace is reserved for local-only items. User namespaces (`<username>/`) and organization namespaces (`<orgname>/`) are stored on the server. Built-in entities use provider namespaces (e.g., `openai/`, `anthropic/`).

3. **Config-as-complete-definition pattern**: For entity registration commands (`actor add`, `skill add`, `tool add`, `validation add`, `resource type add`, `action create`, `automation-profile add`), the YAML configuration file is the **sole source of truth** — the `--config` file fully defines the entity and no CLI override flags are accepted. For runtime commands that reference existing entities (e.g., `plan use`), CLI options may override entity defaults to customize behavior per-invocation.

4. **Environment variable interpolation**: All configuration files support `${ENV_VAR}` and `${ENV_VAR:default_value}` syntax for environment variable interpolation. If a variable is not set and no default is provided, an error is raised. Boolean strings (`true`/`false`) and numeric strings are automatically converted to their native types.

5. **Jinja2 template support**: Actor configuration files support Jinja2 template syntax within string values (particularly `system_prompt` fields). Template placeholders like `{{ context.project_name }}` are preserved during YAML parsing and rendered at runtime.

6. **Idempotent registration**: Adding an entity that already exists fails unless `--update` is provided. This prevents accidental overwrites while allowing intentional updates.

7. **Declarative structure**: Configuration files are declarative — they describe *what* should exist, not *how* to create it. The system handles all lifecycle management.

8. **Schema version**: Configuration files may include a top-level `cleveragents.version` field to indicate which schema version they target (currently `"3.0"`). When omitted, the latest schema version is assumed.

---

### Actor Configuration Files

Actor configuration files define intelligent agents — anything conversational, from a single LLM to an entire graph of interconnected actors and tools. Actors are registered via `agents actor add --config <file>`.

#### JSON Schema

The following is the formal [JSON Schema](https://json-schema.org/) definition for actor configuration files. Since YAML is a superset of JSON, this schema can be used directly to validate actor YAML files using any JSON Schema validator.

<div class="highlight"><pre><code>
{
  <span style="color: cyan; font-weight: 600;">&quot;$schema&quot;</span>: <span style="color: #66cc66;">&quot;https://json-schema.org/draft/2020-12/schema&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;$id&quot;</span>: <span style="color: #66cc66;">&quot;https://cleveragents.dev/schemas/actor-config.json&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;title&quot;</span>: <span style="color: #66cc66;">&quot;CleverAgents Actor Configuration&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Configuration file schema for defining CleverAgents actors — intelligent agents composed of LLMs, tools, and graph topologies.&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;pattern&quot;</span>: <span style="color: #66cc66;">&quot;^[a-z0-9_-]+/[a-z0-9_-]+$&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Namespaced actor name in &lt;namespace&gt;/&lt;name&gt; format (e.g., &#x27;local/reviewer&#x27;, &#x27;myorg/deploy-agent&#x27;). Required. When the actor is added via the CLI, this value is used as the registered name.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;cleveragents&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Metadata block containing schema version, logging, template engine, and safety settings.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;version&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Schema version for this configuration file.&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: #66cc66;">&quot;3.0&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;logging&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;level&quot;</span>: {
              <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;DEBUG&quot;</span>, <span style="color: #66cc66;">&quot;INFO&quot;</span>, <span style="color: #66cc66;">&quot;WARNING&quot;</span>, <span style="color: #66cc66;">&quot;ERROR&quot;</span>],
              <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: #66cc66;">&quot;INFO&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Logging level.&quot;</span>
            }
          },
          <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;template_engine&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;JINJA2&quot;</span>, <span style="color: #66cc66;">&quot;NONE&quot;</span>],
          <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: #66cc66;">&quot;JINJA2&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Template engine for string interpolation.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;unsafe&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;When true, allows actors to perform operations flagged as unsafe. Requires --unsafe CLI flag.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;default_actor&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Name of the default actor when multiple actors are defined.&quot;</span>
        }
      },
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;actors&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;$ref&quot;</span>: <span style="color: #66cc66;">&quot;#/$defs/actorMap&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;agents&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;$ref&quot;</span>: <span style="color: #66cc66;">&quot;#/$defs/actorMap&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Alias for &#x27;actors&#x27;. Both keys are accepted; use one or the other.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;routes&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Map of route names to their definitions. Routes connect actors via stream or graph topologies.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;$ref&quot;</span>: <span style="color: #66cc66;">&quot;#/$defs/route&quot;</span>
      }
    },
    <span style="color: cyan; font-weight: 600;">&quot;merges&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Stream merge operations combining multiple streams into one.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;sources&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Source stream names to merge.&quot;</span>
          },
          <span style="color: cyan; font-weight: 600;">&quot;target&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Target stream name for merged output.&quot;</span>
          }
        },
        <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;sources&quot;</span>, <span style="color: #66cc66;">&quot;target&quot;</span>],
        <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
      }
    },
    <span style="color: cyan; font-weight: 600;">&quot;splits&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Stream split operations dividing one stream into multiple.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;source&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Source stream name to split.&quot;</span>
          },
          <span style="color: cyan; font-weight: 600;">&quot;targets&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Target stream names for split output.&quot;</span>
          }
        },
        <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;source&quot;</span>, <span style="color: #66cc66;">&quot;targets&quot;</span>],
        <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
      }
    },
    <span style="color: cyan; font-weight: 600;">&quot;templates&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Reusable template definitions for Jinja2 template inheritance.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;instances&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Instantiated templates with bound parameters.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;global_context&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Key-value pairs available to all actors via {{ context.key }} in templates.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;prompts&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Named prompt templates that can be referenced by actors.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> }
    },
    <span style="color: cyan; font-weight: 600;">&quot;pipelines&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Hybrid pipeline definitions combining stream and graph stages.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;stages&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: {
              <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
                <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
                <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
                <span style="color: cyan; font-weight: 600;">&quot;config&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span> }
              },
              <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;name&quot;</span>, <span style="color: #66cc66;">&quot;type&quot;</span>]
            }
          },
          <span style="color: cyan; font-weight: 600;">&quot;metadata&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span> }
        },
        <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;stages&quot;</span>]
      }
    }
  },
  <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;name&quot;</span>],
  <span style="color: cyan; font-weight: 600;">&quot;oneOf&quot;</span>: [
    { <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;actors&quot;</span>] },
    { <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;agents&quot;</span>] }
  ],
  <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
  <span style="color: cyan; font-weight: 600;">&quot;$defs&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;actorMap&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Map of actor names to their definitions.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;$ref&quot;</span>: <span style="color: #66cc66;">&quot;#/$defs/actorDefinition&quot;</span>
      }
    },
    <span style="color: cyan; font-weight: 600;">&quot;actorDefinition&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;A single actor definition.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;llm&quot;</span>, <span style="color: #66cc66;">&quot;tool&quot;</span>],
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Actor type: &#x27;llm&#x27; for language model actors, &#x27;tool&#x27; for tool-based actors.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;config&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Actor configuration. Fields depend on actor type.&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;provider&quot;</span>: {
              <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;LLM provider identifier: openai, anthropic, google, azure, openrouter, etc.&quot;</span>
            },
            <span style="color: cyan; font-weight: 600;">&quot;model&quot;</span>: {
              <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Model identifier within the provider: gpt-4, claude-3.5-sonnet, gemini-pro, etc.&quot;</span>
            },
            <span style="color: cyan; font-weight: 600;">&quot;actor&quot;</span>: {
              <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Combined provider/model format (e.g., &#x27;anthropic/claude-3.5-sonnet&#x27;). Alternative to specifying provider and model separately.&quot;</span>
            },
            <span style="color: cyan; font-weight: 600;">&quot;system_prompt&quot;</span>: {
              <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;System prompt text. Supports Jinja2 template syntax for dynamic content.&quot;</span>
            },
            <span style="color: cyan; font-weight: 600;">&quot;temperature&quot;</span>: {
              <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;number&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">0.0</span>,
              <span style="color: cyan; font-weight: 600;">&quot;maximum&quot;</span>: <span style="color: yellow;">2.0</span>,
              <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Sampling temperature. Lower values are more deterministic.&quot;</span>
            },
            <span style="color: cyan; font-weight: 600;">&quot;max_tokens&quot;</span>: {
              <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;integer&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">1</span>,
              <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Maximum number of tokens in the generated response.&quot;</span>
            },
            <span style="color: cyan; font-weight: 600;">&quot;memory_enabled&quot;</span>: {
              <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
              <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Enable conversation memory for multi-turn interactions.&quot;</span>
            },
            <span style="color: cyan; font-weight: 600;">&quot;max_history&quot;</span>: {
              <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;integer&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: yellow;">50</span>,
              <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">1</span>,
              <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Maximum number of conversation turns retained in memory.&quot;</span>
            },
            <span style="color: cyan; font-weight: 600;">&quot;unsafe&quot;</span>: {
              <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
              <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Allow this specific actor to perform unsafe operations.&quot;</span>
            },
            <span style="color: cyan; font-weight: 600;">&quot;options&quot;</span>: {
              <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Provider-specific options passed through to the underlying LLM API.&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>
            },
            <span style="color: cyan; font-weight: 600;">&quot;tools&quot;</span>: {
              <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;List of inline tool definitions for tool-type actors.&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: {
                <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
                <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
                  <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: {
                    <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
                    <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Tool name.&quot;</span>
                  },
                  <span style="color: cyan; font-weight: 600;">&quot;code&quot;</span>: {
                    <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
                    <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Inline Python code defining the tool&#x27;s behavior.&quot;</span>
                  }
                },
                <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;name&quot;</span>, <span style="color: #66cc66;">&quot;code&quot;</span>],
                <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
              }
            }
          },
          <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
        }
      },
      <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;type&quot;</span>, <span style="color: #66cc66;">&quot;config&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;route&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;A route definition — either a stream or a graph topology.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;stream&quot;</span>, <span style="color: #66cc66;">&quot;graph&quot;</span>],
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Route type.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;stream_type&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;cold&quot;</span>, <span style="color: #66cc66;">&quot;hot&quot;</span>, <span style="color: #66cc66;">&quot;replay&quot;</span>],
          <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: #66cc66;">&quot;cold&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Stream type (stream routes only).&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;operators&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Processing operators (stream routes).&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
              <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: {
                <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
                <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;map&quot;</span>, <span style="color: #66cc66;">&quot;graph_execute&quot;</span>],
                <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Operator type.&quot;</span>
              },
              <span style="color: cyan; font-weight: 600;">&quot;params&quot;</span>: {
                <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
                <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
                  <span style="color: cyan; font-weight: 600;">&quot;agent&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Actor name for map operators.&quot;</span> },
                  <span style="color: cyan; font-weight: 600;">&quot;graph&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Graph route name for graph_execute operators.&quot;</span> }
                },
                <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>
              }
            },
            <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;type&quot;</span>]
          }
        },
        <span style="color: cyan; font-weight: 600;">&quot;subscriptions&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Input stream subscriptions.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;publications&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Output stream publications.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;agents&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Actor names used by this route.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;initial_value&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Initial stream value.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;buffer_size&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;integer&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: yellow;">10</span>,
          <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">1</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Stream buffer size.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;template_config&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Template-specific configuration.&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;bridge&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Bridge configuration for stream-to-graph upgrades.&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;upgrade_conditions&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span> },
            <span style="color: cyan; font-weight: 600;">&quot;downgrade_conditions&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span> },
            <span style="color: cyan; font-weight: 600;">&quot;state_extractor&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
            <span style="color: cyan; font-weight: 600;">&quot;state_flattener&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
            <span style="color: cyan; font-weight: 600;">&quot;preserve_subscriptions&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span> },
            <span style="color: cyan; font-weight: 600;">&quot;preserve_checkpointing&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span> }
          },
          <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;metadata&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;nodes&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Graph nodes (required for graph routes).&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;$ref&quot;</span>: <span style="color: #66cc66;">&quot;#/$defs/graphNode&quot;</span>
          }
        },
        <span style="color: cyan; font-weight: 600;">&quot;edges&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Graph edges (required for graph routes).&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;$ref&quot;</span>: <span style="color: #66cc66;">&quot;#/$defs/graphEdge&quot;</span>
          }
        },
        <span style="color: cyan; font-weight: 600;">&quot;entry_point&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Entry point node name (required for graph routes).&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;checkpointing&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Enable graph checkpointing.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;checkpoint_dir&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Directory for checkpoint storage.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;enable_time_travel&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Enable time travel debugging.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;parallel_execution&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Allow parallel node execution.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;state_class&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Custom state class name.&quot;</span>
        }
      },
      <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;type&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;graphNode&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;A graph node definition.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;agent&quot;</span>, <span style="color: #66cc66;">&quot;function&quot;</span>, <span style="color: #66cc66;">&quot;tool&quot;</span>, <span style="color: #66cc66;">&quot;conditional&quot;</span>, <span style="color: #66cc66;">&quot;subgraph&quot;</span>, <span style="color: #66cc66;">&quot;start&quot;</span>, <span style="color: #66cc66;">&quot;end&quot;</span>, <span style="color: #66cc66;">&quot;message_router&quot;</span>],
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Node type.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;agent&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Actor name for agent nodes.&quot;</span> },
        <span style="color: cyan; font-weight: 600;">&quot;function&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Function name for function nodes.&quot;</span> },
        <span style="color: cyan; font-weight: 600;">&quot;tools&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Tool references for tool nodes.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;condition&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>, <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Condition for conditional nodes.&quot;</span> },
        <span style="color: cyan; font-weight: 600;">&quot;subgraph&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Route name for subgraph nodes.&quot;</span> },
        <span style="color: cyan; font-weight: 600;">&quot;retry_policy&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>, <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Retry configuration.&quot;</span> },
        <span style="color: cyan; font-weight: 600;">&quot;timeout&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;integer&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">1</span>, <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Timeout in seconds.&quot;</span> },
        <span style="color: cyan; font-weight: 600;">&quot;parallel&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>, <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Allow parallel execution.&quot;</span> },
        <span style="color: cyan; font-weight: 600;">&quot;metadata&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span> }
      },
      <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;type&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;graphEdge&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;A graph edge connecting two nodes.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;source&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Source node name.&quot;</span> },
        <span style="color: cyan; font-weight: 600;">&quot;target&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Target node name.&quot;</span> },
        <span style="color: cyan; font-weight: 600;">&quot;condition&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>, <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Edge condition for conditional routing.&quot;</span> },
        <span style="color: cyan; font-weight: 600;">&quot;metadata&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span> }
      },
      <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;source&quot;</span>, <span style="color: #66cc66;">&quot;target&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
    }
  }
}
</code></pre></div>

#### Informal YAML Schema

The following annotated YAML provides an easier-to-read overview of the same schema defined formally above. It is **not** a validatable schema — it uses informal annotations (comments, `<placeholder>` syntax, and `|` alternatives) to describe the structure. Refer to the JSON Schema above for the authoritative, machine-validatable definition.

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># ─── Name ───────────────────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">&lt;namespace&gt;/&lt;actor-name&gt;</span><span style="opacity: 0.7;">       # Namespaced actor name (required). Used as the registered name.</span>
                                    <span style="opacity: 0.7;"># Must follow &lt;namespace&gt;/&lt;name&gt; format (e.g., local/reviewer).</span>

<span style="opacity: 0.7;"># ─── Metadata ───────────────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">&quot;3.0&quot;</span><span style="opacity: 0.7;">                    # Schema version (optional, default: latest)</span>
  <span style="color: cyan; font-weight: 600;">logging</span>:
    <span style="color: cyan; font-weight: 600;">level</span>: <span style="color: #66cc66;">&quot;INFO&quot;</span><span style="opacity: 0.7;">                   # Log level: DEBUG, INFO, WARNING, ERROR (optional)</span>
  <span style="color: cyan; font-weight: 600;">template_engine</span>: <span style="color: #66cc66;">&quot;JINJA2&quot;</span><span style="opacity: 0.7;">         # Template engine: JINJA2 or NONE (optional, default: JINJA2)</span>
  <span style="color: cyan; font-weight: 600;">unsafe</span>: <span style="color: magenta; font-weight: 600;">false</span><span style="opacity: 0.7;">                     # Allow unsafe operations (optional, default: false)</span>
  <span style="color: cyan; font-weight: 600;">default_actor</span>: <span style="color: #66cc66;">&lt;actor_name&gt;</span><span style="opacity: 0.7;">       # Default actor to use when multiple are defined (optional)</span>

<span style="opacity: 0.7;"># ─── Actor Definitions ──────────────────────────────────────────────</span>
<span style="opacity: 0.7;"># The top-level key can be either &quot;actors&quot; or &quot;agents&quot; (both accepted).</span>
<span style="color: cyan; font-weight: 600;">actors</span>:
  &lt;actor_name&gt;:
    <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: magenta;">llm | tool</span><span style="opacity: 0.7;">                # Actor type (required)</span>
    <span style="color: cyan; font-weight: 600;">config</span>:
<span style="opacity: 0.7;">      # ── For type: llm ──────────────────────────────────────────</span>
      <span style="color: cyan; font-weight: 600;">provider</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">            # Provider identifier: openai, anthropic, google, azure, openrouter, etc. (required for LLM)</span>
      <span style="color: cyan; font-weight: 600;">model</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">               # Model identifier: gpt-4, claude-3.5-sonnet, etc. (required for LLM)</span>
<span style="opacity: 0.7;">      # OR use the combined format:</span>
      <span style="color: cyan; font-weight: 600;">actor</span>: <span style="color: #66cc66;">&quot;&lt;provider&gt;/&lt;model&gt;&quot;</span><span style="opacity: 0.7;">   # Combined provider/model (alternative to provider + model)</span>

      <span style="color: cyan; font-weight: 600;">system_prompt</span>: |<span style="opacity: 0.7;">              # System prompt text, supports Jinja2 templates (optional)</span>
        You are a helpful assistant.
        <span style="color: cyan; font-weight: 600;">Project</span>: {{ context.project_name }}
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.7</span><span style="opacity: 0.7;">              # Sampling temperature 0.0-2.0 (optional, default: provider default)</span>
      <span style="color: cyan; font-weight: 600;">max_tokens</span>: <span style="color: yellow;">4096</span><span style="opacity: 0.7;">              # Maximum output tokens (optional, default: provider default)</span>
      <span style="color: cyan; font-weight: 600;">memory_enabled</span>: <span style="color: magenta; font-weight: 600;">true</span><span style="opacity: 0.7;">          # Enable conversation memory (optional, default: false)</span>
      <span style="color: cyan; font-weight: 600;">max_history</span>: <span style="color: yellow;">50</span><span style="opacity: 0.7;">               # Maximum conversation turns to retain (optional, default: 50)</span>
      <span style="color: cyan; font-weight: 600;">unsafe</span>: <span style="color: magenta; font-weight: 600;">false</span><span style="opacity: 0.7;">                 # Allow unsafe operations for this actor (optional, default: false)</span>
      <span style="color: cyan; font-weight: 600;">options</span>:                      # Additional provider-specific options (optional)
        <span style="color: cyan; font-weight: 600;">top_p</span>: <span style="color: yellow;">1.0</span>
        <span style="color: cyan; font-weight: 600;">frequency_penalty</span>: <span style="color: yellow;">0.0</span>
        <span style="color: cyan; font-weight: 600;">presence_penalty</span>: <span style="color: yellow;">0.0</span>
        <span style="color: cyan; font-weight: 600;">stop_sequences</span>: [<span style="color: #66cc66;">&quot;END&quot;</span>]
        <span style="color: cyan; font-weight: 600;">seed</span>: <span style="color: yellow;">42</span>

<span style="opacity: 0.7;">      # ── For type: tool ─────────────────────────────────────────</span>
      <span style="color: cyan; font-weight: 600;">tools</span>:
        - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">&lt;tool_name&gt;</span><span style="opacity: 0.7;">         # Tool name (required per tool)</span>
          <span style="color: cyan; font-weight: 600;">code</span>: |<span style="opacity: 0.7;">                   # Inline Python code (required per tool)</span>
            def run(input_data):
                return {&quot;result&quot;: input_data[&quot;query&quot;]}

<span style="opacity: 0.7;"># ─── Routes ─────────────────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">routes</span>:
  &lt;route_name&gt;:
    <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: magenta;">stream | graph</span><span style="opacity: 0.7;">            # Route type (required)</span>

<span style="opacity: 0.7;">    # ── Stream route fields ──────────────────────────────────────</span>
    <span style="color: cyan; font-weight: 600;">stream_type</span>: <span style="color: magenta;">cold | hot | replay</span><span style="opacity: 0.7;">  # Stream type (optional, default: cold)</span>
    <span style="color: cyan; font-weight: 600;">operators</span>:                      # Processing operators (optional)
      - <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: magenta;">map | graph_execute</span><span style="opacity: 0.7;">   # Operator type</span>
        <span style="color: cyan; font-weight: 600;">params</span>:                     # Operator parameters
          <span style="color: cyan; font-weight: 600;">agent</span>: <span style="color: #66cc66;">&lt;actor_name&gt;</span><span style="opacity: 0.7;">       # Actor to use (for map)</span>
          <span style="color: cyan; font-weight: 600;">graph</span>: <span style="color: #66cc66;">&lt;route_name&gt;</span><span style="opacity: 0.7;">       # Graph to execute (for graph_execute)</span>
    <span style="color: cyan; font-weight: 600;">subscriptions</span>:                  # Input subscriptions (optional)
      - <span style="color: #66cc66;">&lt;stream_name&gt;</span>
    <span style="color: cyan; font-weight: 600;">publications</span>:                   # Output publications (optional)
      - <span style="color: #66cc66;">&lt;stream_name&gt;</span>
    <span style="color: cyan; font-weight: 600;">agents</span>:                         # Actors used by this route (optional)
      - <span style="color: #66cc66;">&lt;actor_name&gt;</span>
    <span style="color: cyan; font-weight: 600;">initial_value</span>: <span style="color: #66cc66;">&lt;any&gt;</span><span style="opacity: 0.7;">            # Initial stream value (optional)</span>
    <span style="color: cyan; font-weight: 600;">buffer_size</span>: <span style="color: yellow;">10</span><span style="opacity: 0.7;">                 # Stream buffer size (optional, default: 10)</span>
    <span style="color: cyan; font-weight: 600;">template_config</span>: {}<span style="opacity: 0.7;">             # Template-specific configuration (optional)</span>
    <span style="color: cyan; font-weight: 600;">bridge</span>:                         # Bridge configuration for stream↔graph upgrades (optional)
      <span style="color: cyan; font-weight: 600;">upgrade_conditions</span>: {}<span style="opacity: 0.7;">        # Conditions to upgrade from stream to graph</span>
      <span style="color: cyan; font-weight: 600;">downgrade_conditions</span>: {}<span style="opacity: 0.7;">      # Conditions to downgrade from graph to stream</span>
      <span style="color: cyan; font-weight: 600;">state_extractor</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">     # Function to extract state during upgrade</span>
      <span style="color: cyan; font-weight: 600;">state_flattener</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">     # Function to flatten state during downgrade</span>
      <span style="color: cyan; font-weight: 600;">preserve_subscriptions</span>: <span style="color: magenta; font-weight: 600;">true</span><span style="opacity: 0.7;">  # Keep subscriptions during transition (optional)</span>
      <span style="color: cyan; font-weight: 600;">preserve_checkpointing</span>: <span style="color: magenta; font-weight: 600;">true</span><span style="opacity: 0.7;">  # Keep checkpoints during transition (optional)</span>
    <span style="color: cyan; font-weight: 600;">metadata</span>: {}<span style="opacity: 0.7;">                    # Arbitrary metadata (optional)</span>

<span style="opacity: 0.7;">    # ── Graph route fields ───────────────────────────────────────</span>
    <span style="color: cyan; font-weight: 600;">nodes</span>:                          # Graph nodes (required for graph routes)
      &lt;node_name&gt;:
        <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: magenta;">agent | function | tool | conditional | subgraph | start | end | message_router</span>
        <span style="color: cyan; font-weight: 600;">agent</span>: <span style="color: #66cc66;">&lt;actor_name&gt;</span><span style="opacity: 0.7;">         # Actor for agent nodes</span>
        <span style="color: cyan; font-weight: 600;">function</span>: <span style="color: #66cc66;">&lt;function_name&gt;</span><span style="opacity: 0.7;">   # Function for function nodes</span>
        <span style="color: cyan; font-weight: 600;">tools</span>:                      # Tools for tool nodes
          - <span style="color: #66cc66;">&lt;tool_ref&gt;</span>
        <span style="color: cyan; font-weight: 600;">condition</span>: {}<span style="opacity: 0.7;">               # Condition for conditional nodes</span>
        <span style="color: cyan; font-weight: 600;">subgraph</span>: <span style="color: #66cc66;">&lt;route_name&gt;</span><span style="opacity: 0.7;">      # Subgraph for subgraph nodes</span>
        <span style="color: cyan; font-weight: 600;">retry_policy</span>: {}<span style="opacity: 0.7;">            # Retry configuration (optional)</span>
        <span style="color: cyan; font-weight: 600;">timeout</span>: <span style="color: yellow;">30</span><span style="opacity: 0.7;">                 # Timeout in seconds (optional)</span>
        <span style="color: cyan; font-weight: 600;">parallel</span>: <span style="color: magenta; font-weight: 600;">false</span><span style="opacity: 0.7;">             # Allow parallel execution (optional)</span>
        <span style="color: cyan; font-weight: 600;">metadata</span>: {}<span style="opacity: 0.7;">                # Arbitrary metadata (optional)</span>
    <span style="color: cyan; font-weight: 600;">edges</span>:                          # Graph edges (required for graph routes)
      - <span style="color: cyan; font-weight: 600;">source</span>: <span style="color: #66cc66;">&lt;node_name&gt;</span><span style="opacity: 0.7;">         # Source node (required)</span>
        <span style="color: cyan; font-weight: 600;">target</span>: <span style="color: #66cc66;">&lt;node_name&gt;</span><span style="opacity: 0.7;">         # Target node (required)</span>
        <span style="color: cyan; font-weight: 600;">condition</span>: {}<span style="opacity: 0.7;">               # Edge condition (optional)</span>
        <span style="color: cyan; font-weight: 600;">metadata</span>: {}<span style="opacity: 0.7;">                # Arbitrary metadata (optional)</span>
    <span style="color: cyan; font-weight: 600;">entry_point</span>: <span style="color: #66cc66;">&lt;node_name&gt;</span><span style="opacity: 0.7;">        # Entry point node (required for graph routes)</span>
    <span style="color: cyan; font-weight: 600;">checkpointing</span>: <span style="color: magenta; font-weight: 600;">false</span><span style="opacity: 0.7;">            # Enable graph checkpointing (optional, default: false)</span>
    <span style="color: cyan; font-weight: 600;">checkpoint_dir</span>: <span style="color: #66cc66;">&lt;path&gt;</span><span style="opacity: 0.7;">          # Checkpoint directory (optional)</span>
    <span style="color: cyan; font-weight: 600;">enable_time_travel</span>: <span style="color: magenta; font-weight: 600;">false</span><span style="opacity: 0.7;">       # Enable time travel debugging (optional, default: false)</span>
    <span style="color: cyan; font-weight: 600;">parallel_execution</span>: <span style="color: magenta; font-weight: 600;">false</span><span style="opacity: 0.7;">       # Allow parallel node execution (optional, default: false)</span>
    <span style="color: cyan; font-weight: 600;">state_class</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">           # Custom state class name (optional)</span>
    <span style="color: cyan; font-weight: 600;">metadata</span>: {}<span style="opacity: 0.7;">                    # Arbitrary metadata (optional)</span>

<span style="opacity: 0.7;"># ─── Merges &amp; Splits ────────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">merges</span>:                             # Stream merge definitions (optional)
  - <span style="color: cyan; font-weight: 600;">sources</span>:                        # Source streams to merge
      - <span style="color: #66cc66;">&lt;stream_name&gt;</span>
    <span style="color: cyan; font-weight: 600;">target</span>: <span style="color: #66cc66;">&lt;stream_name&gt;</span><span style="opacity: 0.7;">           # Target stream for merged output</span>

<span style="color: cyan; font-weight: 600;">splits</span>:                             # Stream split definitions (optional)
  - <span style="color: cyan; font-weight: 600;">source</span>: <span style="color: #66cc66;">&lt;stream_name&gt;</span><span style="opacity: 0.7;">           # Source stream to split</span>
    <span style="color: cyan; font-weight: 600;">targets</span>:                        # Target streams for split output
      - <span style="color: #66cc66;">&lt;stream_name&gt;</span>

<span style="opacity: 0.7;"># ─── Templates &amp; Context ────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">templates</span>: {}<span style="opacity: 0.7;">                       # Reusable template definitions (optional)</span>
<span style="color: cyan; font-weight: 600;">instances</span>: {}<span style="opacity: 0.7;">                       # Template instances (optional)</span>
<span style="color: cyan; font-weight: 600;">global_context</span>: {}<span style="opacity: 0.7;">                  # Global context available to all actors (optional)</span>
<span style="color: cyan; font-weight: 600;">prompts</span>: {}<span style="opacity: 0.7;">                         # Named prompt templates (optional)</span>

<span style="opacity: 0.7;"># ─── Pipelines ──────────────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">pipelines</span>:                          # Hybrid pipeline definitions (optional)
  &lt;pipeline_name&gt;:
    <span style="color: cyan; font-weight: 600;">stages</span>:
      - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">&lt;stage_name&gt;</span>
        <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: #66cc66;">&lt;stage_type&gt;</span>
        <span style="color: cyan; font-weight: 600;">config</span>: {}
    <span style="color: cyan; font-weight: 600;">metadata</span>: {}
</code></pre></div>

#### Structure Reference

**Top-Level Keys**

| Key | Type | Required | Description |
|-----|------|----------|-------------|
| `cleveragents` | object | No | Metadata block containing version, logging, template engine, and safety settings. |
| `actors` (or `agents`) | object | Yes | Map of actor names to their definitions. Both `actors` and `agents` are accepted as the key name. |
| `routes` | object | No | Map of route names to their definitions. Routes connect actors via stream or graph topologies. |
| `merges` | list | No | Stream merge operations combining multiple streams into one. |
| `splits` | list | No | Stream split operations dividing one stream into multiple. |
| `templates` | object | No | Reusable template definitions for Jinja2 template inheritance. |
| `instances` | object | No | Instantiated templates with bound parameters. |
| `global_context` | object | No | Key-value pairs available to all actors via `{{ context.key }}` in templates. |
| `prompts` | object | No | Named prompt templates that can be referenced by actors. |
| `pipelines` | object | No | Hybrid pipelines combining stream and graph stages into sequential workflows. |

**`cleveragents` Block**

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `version` | string | `"3.0"` | Schema version for this configuration file. |
| `logging.level` | string | `"INFO"` | Logging level: `DEBUG`, `INFO`, `WARNING`, `ERROR`. |
| `template_engine` | string | `"JINJA2"` | Template engine for string interpolation: `JINJA2` or `NONE`. |
| `unsafe` | boolean | `false` | When `true`, allows actors to perform operations flagged as unsafe. Requires `--unsafe` CLI flag. |
| `default_actor` | string | (first actor) | Name of the default actor when multiple actors are defined. |

**Actor Definition Fields**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `type` | string | Yes | Actor type. `llm` for language model actors, `tool` for tool-based actors. |
| `config.provider` | string | Yes (LLM) | LLM provider identifier: `openai`, `anthropic`, `google`, `azure`, `openrouter`, etc. |
| `config.model` | string | Yes (LLM) | Model identifier within the provider: `gpt-4`, `claude-3.5-sonnet`, `gemini-pro`, etc. |
| `config.actor` | string | No | Combined `provider/model` format. Alternative to specifying `provider` and `model` separately. |
| `config.system_prompt` | string | No | System prompt text. Supports Jinja2 template syntax for dynamic content. |
| `config.temperature` | float | Provider default | Sampling temperature (0.0 to 2.0). Lower values are more deterministic. |
| `config.max_tokens` | integer | Provider default | Maximum number of tokens in the generated response. |
| `config.memory_enabled` | boolean | `false` | Enable conversation memory for multi-turn interactions. |
| `config.max_history` | integer | `50` | Maximum number of conversation turns retained in memory. |
| `config.unsafe` | boolean | `false` | Allow this specific actor to perform unsafe operations. |
| `config.options` | object | `{}` | Provider-specific options passed through to the underlying LLM API. |
| `config.tools` | list | Yes (tool) | List of inline tool definitions for tool-type actors. Each tool has `name` and `code`. |

**Node Types (Graph Routes)**

| Type | Description |
|------|-------------|
| `agent` | A node backed by an actor. Requires `agent` field pointing to an actor name. |
| `function` | A node backed by a Python function. Requires `function` field. |
| `tool` | A node that invokes one or more tools. Requires `tools` list. |
| `conditional` | A branching node that routes based on conditions. Requires `condition` field. |
| `subgraph` | A node that delegates to another graph route. Requires `subgraph` field. |
| `start` | The explicit start node (alternative to `entry_point`). |
| `end` | A terminal node that ends graph execution. |
| `message_router` | Routes messages to different nodes based on message content or metadata. |

#### Examples

**Example 1: Minimal Chat Actor (Simple)**

A bare-minimum actor configuration for a simple conversational agent:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># minimal-chat.yaml</span>
<span style="opacity: 0.7;"># Register: agents actor add --config minimal-chat.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: local/chat

<span style="color: cyan; font-weight: 600;">actors</span>:
  <span style="color: cyan; font-weight: 600;">chat</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">provider</span>: anthropic
      <span style="color: cyan; font-weight: 600;">model</span>: claude-3.5-sonnet
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: <span style="color: #66cc66;">&quot;You are a helpful assistant.&quot;</span>

<span style="color: cyan; font-weight: 600;">routes</span>:
  <span style="color: cyan; font-weight: 600;">main</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: stream
    <span style="color: cyan; font-weight: 600;">operators</span>:
      - <span style="color: cyan; font-weight: 600;">type</span>: map
        <span style="color: cyan; font-weight: 600;">params</span>:
          <span style="color: cyan; font-weight: 600;">agent</span>: chat
    <span style="color: cyan; font-weight: 600;">publications</span>:
      - output

<span style="color: cyan; font-weight: 600;">merges</span>:
  - <span style="color: cyan; font-weight: 600;">sources</span>: [output]
    <span style="color: cyan; font-weight: 600;">target</span>: final
</code></pre></div>

This is the simplest possible actor: one LLM actor, one stream route, one merge. No graph complexity, no tools, no templates.

---

**Example 2: Code Reviewer with Tools (Medium)**

An actor that can read files and search code to perform code reviews:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># code-reviewer.yaml</span>
<span style="opacity: 0.7;"># Register: agents actor add --config code-reviewer.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: local/reviewer

<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">&quot;3.0&quot;</span>
  <span style="color: cyan; font-weight: 600;">logging</span>:
    <span style="color: cyan; font-weight: 600;">level</span>: <span style="color: #66cc66;">&quot;INFO&quot;</span>

<span style="color: cyan; font-weight: 600;">actors</span>:
  <span style="color: cyan; font-weight: 600;">reviewer</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">provider</span>: openai
      <span style="color: cyan; font-weight: 600;">model</span>: gpt-4
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.2</span>
      <span style="color: cyan; font-weight: 600;">max_tokens</span>: <span style="color: yellow;">4096</span>
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: |
        You are a senior code reviewer. Analyze code for:
        - Security vulnerabilities
        - Performance issues
        - Code style violations
        - Missing error handling
        Provide specific, actionable feedback with file and line references.

  <span style="color: cyan; font-weight: 600;">file_reader</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: tool
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">tools</span>:
        - <span style="color: cyan; font-weight: 600;">name</span>: read_file
          <span style="color: cyan; font-weight: 600;">code</span>: |
            def run(input_data):
                path = input_data.get(&quot;path&quot;, &quot;&quot;)
                with open(path, &quot;r&quot;) as f:
                    return {&quot;content&quot;: f.read(), &quot;path&quot;: path}

<span style="color: cyan; font-weight: 600;">routes</span>:
  <span style="color: cyan; font-weight: 600;">review_graph</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: graph
    <span style="color: cyan; font-weight: 600;">nodes</span>:
      <span style="color: cyan; font-weight: 600;">analyze</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: reviewer
      <span style="color: cyan; font-weight: 600;">read</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: tool
        <span style="color: cyan; font-weight: 600;">tools</span>: [read_file]
      <span style="color: cyan; font-weight: 600;">report</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: reviewer
    <span style="color: cyan; font-weight: 600;">edges</span>:
      - <span style="color: cyan; font-weight: 600;">source</span>: analyze
        <span style="color: cyan; font-weight: 600;">target</span>: read
      - <span style="color: cyan; font-weight: 600;">source</span>: read
        <span style="color: cyan; font-weight: 600;">target</span>: report
      - <span style="color: cyan; font-weight: 600;">source</span>: analyze
        <span style="color: cyan; font-weight: 600;">target</span>: report
        <span style="color: cyan; font-weight: 600;">condition</span>:
          <span style="color: cyan; font-weight: 600;">no_files_needed</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">entry_point</span>: analyze
    <span style="color: cyan; font-weight: 600;">checkpointing</span>: <span style="color: magenta; font-weight: 600;">false</span>

  <span style="color: cyan; font-weight: 600;">output_stream</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: stream
    <span style="color: cyan; font-weight: 600;">operators</span>:
      - <span style="color: cyan; font-weight: 600;">type</span>: graph_execute
        <span style="color: cyan; font-weight: 600;">params</span>:
          <span style="color: cyan; font-weight: 600;">graph</span>: review_graph
    <span style="color: cyan; font-weight: 600;">publications</span>:
      - review_output

<span style="color: cyan; font-weight: 600;">merges</span>:
  - <span style="color: cyan; font-weight: 600;">sources</span>: [review_output]
    <span style="color: cyan; font-weight: 600;">target</span>: final
</code></pre></div>

This actor defines an LLM reviewer and a file-reading tool, connected via a graph route with conditional edges.

---

**Example 3: Multi-Agent Research Pipeline with Templates (Complex)**

A complex actor configuration with multiple LLM actors, Jinja2 templates, environment variable interpolation, memory, and hybrid routing:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># research-pipeline.yaml</span>
<span style="opacity: 0.7;"># Register: agents actor add --config research-pipeline.yaml --unsafe</span>

<span style="color: cyan; font-weight: 600;">name</span>: local/research

<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">&quot;3.0&quot;</span>
  <span style="color: cyan; font-weight: 600;">logging</span>:
    <span style="color: cyan; font-weight: 600;">level</span>: <span style="color: #66cc66;">&quot;DEBUG&quot;</span>
  <span style="color: cyan; font-weight: 600;">template_engine</span>: <span style="color: #66cc66;">&quot;JINJA2&quot;</span>
  <span style="color: cyan; font-weight: 600;">unsafe</span>: <span style="color: magenta; font-weight: 600;">true</span>
  <span style="color: cyan; font-weight: 600;">default_actor</span>: orchestrator

<span style="color: cyan; font-weight: 600;">actors</span>:
  <span style="color: cyan; font-weight: 600;">orchestrator</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">provider</span>: anthropic
      <span style="color: cyan; font-weight: 600;">model</span>: claude-3.5-sonnet
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.7</span>
      <span style="color: cyan; font-weight: 600;">max_tokens</span>: <span style="color: yellow;">8192</span>
      <span style="color: cyan; font-weight: 600;">memory_enabled</span>: <span style="color: magenta; font-weight: 600;">true</span>
      <span style="color: cyan; font-weight: 600;">max_history</span>: <span style="color: yellow;">100</span>
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: |
        You are an orchestrator managing a research pipeline for {{ context.project_name }}.
        <span style="color: cyan; font-weight: 600;">Topic</span>: {{ context.research_topic }}

        Your job is to:
        1. Break down the research question into sub-questions
        2. Delegate to specialist researchers
        3. Synthesize findings into a coherent report

        {% if context.deadline %}
        <span style="color: cyan; font-weight: 600;">Deadline</span>: {{ context.deadline }}. Prioritize breadth over depth.
        {% endif %}

  <span style="color: cyan; font-weight: 600;">researcher</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">provider</span>: openai
      <span style="color: cyan; font-weight: 600;">model</span>: gpt-4
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.3</span>
      <span style="color: cyan; font-weight: 600;">max_tokens</span>: <span style="color: yellow;">4096</span>
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: |
        You are a domain expert researcher. Provide thorough, factual analysis.
        Always cite sources and note confidence levels.

  <span style="color: cyan; font-weight: 600;">synthesizer</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">provider</span>: anthropic
      <span style="color: cyan; font-weight: 600;">model</span>: claude-3.5-sonnet
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.5</span>
      <span style="color: cyan; font-weight: 600;">max_tokens</span>: <span style="color: yellow;">16384</span>
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: |
        You are an expert at synthesizing multiple research reports into coherent narratives.
        Resolve contradictions, highlight consensus, and note gaps.

  <span style="color: cyan; font-weight: 600;">web_searcher</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: tool
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">tools</span>:
        - <span style="color: cyan; font-weight: 600;">name</span>: search_web
          <span style="color: cyan; font-weight: 600;">code</span>: |
            import os, json
            def run(input_data):
                api_key = os.environ.get(&quot;SEARCH_API_KEY&quot;, &quot;&quot;)
                query = input_data.get(&quot;query&quot;, &quot;&quot;)
<span style="opacity: 0.7;">                # Simulated web search</span>
                return {&quot;results&quot;: [], &quot;query&quot;: query}

        - <span style="color: cyan; font-weight: 600;">name</span>: fetch_url
          <span style="color: cyan; font-weight: 600;">code</span>: |
            def run(input_data):
                url = input_data.get(&quot;url&quot;, &quot;&quot;)
                return {&quot;content&quot;: f&quot;Content from {url}&quot;, &quot;url&quot;: url}

<span style="color: cyan; font-weight: 600;">routes</span>:
  <span style="color: cyan; font-weight: 600;">research_graph</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: graph
    <span style="color: cyan; font-weight: 600;">nodes</span>:
      <span style="color: cyan; font-weight: 600;">plan</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: orchestrator
      <span style="color: cyan; font-weight: 600;">research_parallel</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: researcher
        <span style="color: cyan; font-weight: 600;">parallel</span>: <span style="color: magenta; font-weight: 600;">true</span>
      <span style="color: cyan; font-weight: 600;">search</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: tool
        <span style="color: cyan; font-weight: 600;">tools</span>: [search_web, fetch_url]
      <span style="color: cyan; font-weight: 600;">synthesize</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: synthesizer
      <span style="color: cyan; font-weight: 600;">review</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: orchestrator
    <span style="color: cyan; font-weight: 600;">edges</span>:
      - <span style="color: cyan; font-weight: 600;">source</span>: plan
        <span style="color: cyan; font-weight: 600;">target</span>: research_parallel
      - <span style="color: cyan; font-weight: 600;">source</span>: plan
        <span style="color: cyan; font-weight: 600;">target</span>: search
      - <span style="color: cyan; font-weight: 600;">source</span>: research_parallel
        <span style="color: cyan; font-weight: 600;">target</span>: synthesize
      - <span style="color: cyan; font-weight: 600;">source</span>: search
        <span style="color: cyan; font-weight: 600;">target</span>: synthesize
      - <span style="color: cyan; font-weight: 600;">source</span>: synthesize
        <span style="color: cyan; font-weight: 600;">target</span>: review
      - <span style="color: cyan; font-weight: 600;">source</span>: review
        <span style="color: cyan; font-weight: 600;">target</span>: plan
        <span style="color: cyan; font-weight: 600;">condition</span>:
          <span style="color: cyan; font-weight: 600;">needs_more_research</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">entry_point</span>: plan
    <span style="color: cyan; font-weight: 600;">checkpointing</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">checkpoint_dir</span>: <span style="color: #66cc66;">&quot;${CHECKPOINT_DIR:/tmp/research_checkpoints}&quot;</span>
    <span style="color: cyan; font-weight: 600;">enable_time_travel</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">parallel_execution</span>: <span style="color: magenta; font-weight: 600;">true</span>

  <span style="color: cyan; font-weight: 600;">progress_stream</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: stream
    <span style="color: cyan; font-weight: 600;">stream_type</span>: hot
    <span style="color: cyan; font-weight: 600;">operators</span>:
      - <span style="color: cyan; font-weight: 600;">type</span>: map
        <span style="color: cyan; font-weight: 600;">params</span>:
          <span style="color: cyan; font-weight: 600;">agent</span>: orchestrator
    <span style="color: cyan; font-weight: 600;">subscriptions</span>:
      - research_updates
    <span style="color: cyan; font-weight: 600;">publications</span>:
      - progress_output
    <span style="color: cyan; font-weight: 600;">buffer_size</span>: <span style="color: yellow;">50</span>

  <span style="color: cyan; font-weight: 600;">output_stream</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: stream
    <span style="color: cyan; font-weight: 600;">operators</span>:
      - <span style="color: cyan; font-weight: 600;">type</span>: graph_execute
        <span style="color: cyan; font-weight: 600;">params</span>:
          <span style="color: cyan; font-weight: 600;">graph</span>: research_graph
    <span style="color: cyan; font-weight: 600;">publications</span>:
      - research_output

<span style="color: cyan; font-weight: 600;">merges</span>:
  - <span style="color: cyan; font-weight: 600;">sources</span>: [progress_output, research_output]
    <span style="color: cyan; font-weight: 600;">target</span>: final

<span style="color: cyan; font-weight: 600;">global_context</span>:
  <span style="color: cyan; font-weight: 600;">project_name</span>: <span style="color: #66cc66;">&quot;AI Safety Research&quot;</span>
  <span style="color: cyan; font-weight: 600;">research_topic</span>: <span style="color: #66cc66;">&quot;Alignment techniques in large language models&quot;</span>
  <span style="color: cyan; font-weight: 600;">deadline</span>: <span style="color: #66cc66;">&quot;2026-03-01&quot;</span>

<span style="color: cyan; font-weight: 600;">prompts</span>:
  <span style="color: cyan; font-weight: 600;">deep_dive</span>: <span style="color: #66cc66;">&quot;Provide an in-depth analysis of {topic} with at least 5 sources.&quot;</span>
  <span style="color: cyan; font-weight: 600;">summary</span>: <span style="color: #66cc66;">&quot;Summarize the following research in 500 words: {content}&quot;</span>

<span style="color: cyan; font-weight: 600;">templates</span>:
  <span style="color: cyan; font-weight: 600;">research_section</span>:
    <span style="color: cyan; font-weight: 600;">template</span>: |
<span style="opacity: 0.7;">      ## {{ section_title }}</span>
      {{ section_content }}
      **Confidence:** {{ confidence_level }}
      <span style="color: magenta;">**Sources:** {{ sources | join(&#x27;, &#x27;) }}</span>
</code></pre></div>

This configuration demonstrates multi-actor orchestration, graph routing with parallel execution, hot stream monitoring, Jinja2 templates with conditionals, environment variables, checkpointing, and global context.

---

**Example 4: Simple Echo/Tool Actor (Simple)**

A non-LLM actor that processes input with pure Python code:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># echo-actor.yaml</span>
<span style="opacity: 0.7;"># Register: agents actor add --config echo-actor.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: local/echo

<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">&quot;3.0&quot;</span>

<span style="color: cyan; font-weight: 600;">actors</span>:
  <span style="color: cyan; font-weight: 600;">echo</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: tool
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">tools</span>:
        - <span style="color: cyan; font-weight: 600;">name</span>: echo_tool
          <span style="color: cyan; font-weight: 600;">code</span>: |
            def run(input_data):
                message = input_data.get(&quot;content&quot;, &quot;&quot;)
                return {&quot;response&quot;: f&quot;Echo: {message}&quot;}

<span style="color: cyan; font-weight: 600;">routes</span>:
  <span style="color: cyan; font-weight: 600;">main</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: stream
    <span style="color: cyan; font-weight: 600;">operators</span>:
      - <span style="color: cyan; font-weight: 600;">type</span>: map
        <span style="color: cyan; font-weight: 600;">params</span>:
          <span style="color: cyan; font-weight: 600;">agent</span>: echo
    <span style="color: cyan; font-weight: 600;">publications</span>:
      - output

<span style="color: cyan; font-weight: 600;">merges</span>:
  - <span style="color: cyan; font-weight: 600;">sources</span>: [output]
    <span style="color: cyan; font-weight: 600;">target</span>: final
</code></pre></div>

---

**Example 5: Graph Actor with Conditional Routing (Medium)**

An actor that routes between different specialists based on input classification:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># classifier-router.yaml</span>
<span style="opacity: 0.7;"># Register: agents actor add --config classifier-router.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: local/smart-router

<span style="color: cyan; font-weight: 600;">actors</span>:
  <span style="color: cyan; font-weight: 600;">classifier</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">provider</span>: openai
      <span style="color: cyan; font-weight: 600;">model</span>: gpt-4
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.0</span>
      <span style="color: cyan; font-weight: 600;">max_tokens</span>: <span style="color: yellow;">100</span>
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: |
        Classify the user&#x27;s request into exactly one category:
        CODING, WRITING, ANALYSIS, or GENERAL.
        Respond with only the category name.

  <span style="color: cyan; font-weight: 600;">coding_expert</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">provider</span>: anthropic
      <span style="color: cyan; font-weight: 600;">model</span>: claude-3.5-sonnet
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.2</span>
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: <span style="color: #66cc66;">&quot;You are an expert software engineer. Write clean, well-tested code.&quot;</span>

  <span style="color: cyan; font-weight: 600;">writing_expert</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">provider</span>: openai
      <span style="color: cyan; font-weight: 600;">model</span>: gpt-4
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.7</span>
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: <span style="color: #66cc66;">&quot;You are a professional writer. Produce clear, engaging prose.&quot;</span>

  <span style="color: cyan; font-weight: 600;">analyst</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">provider</span>: anthropic
      <span style="color: cyan; font-weight: 600;">model</span>: claude-3.5-sonnet
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.3</span>
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: <span style="color: #66cc66;">&quot;You are a data analyst. Provide thorough, evidence-based analysis.&quot;</span>

  <span style="color: cyan; font-weight: 600;">generalist</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">provider</span>: openai
      <span style="color: cyan; font-weight: 600;">model</span>: gpt-4
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.5</span>
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: <span style="color: #66cc66;">&quot;You are a helpful general-purpose assistant.&quot;</span>

<span style="color: cyan; font-weight: 600;">routes</span>:
  <span style="color: cyan; font-weight: 600;">router_graph</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: graph
    <span style="color: cyan; font-weight: 600;">nodes</span>:
      <span style="color: cyan; font-weight: 600;">classify</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: classifier
      <span style="color: cyan; font-weight: 600;">code</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: coding_expert
      <span style="color: cyan; font-weight: 600;">write</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: writing_expert
      <span style="color: cyan; font-weight: 600;">analyze</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: analyst
      <span style="color: cyan; font-weight: 600;">general</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: generalist
    <span style="color: cyan; font-weight: 600;">edges</span>:
      - <span style="color: cyan; font-weight: 600;">source</span>: classify
        <span style="color: cyan; font-weight: 600;">target</span>: code
        <span style="color: cyan; font-weight: 600;">condition</span>:
          <span style="color: cyan; font-weight: 600;">category</span>: <span style="color: #66cc66;">&quot;CODING&quot;</span>
      - <span style="color: cyan; font-weight: 600;">source</span>: classify
        <span style="color: cyan; font-weight: 600;">target</span>: write
        <span style="color: cyan; font-weight: 600;">condition</span>:
          <span style="color: cyan; font-weight: 600;">category</span>: <span style="color: #66cc66;">&quot;WRITING&quot;</span>
      - <span style="color: cyan; font-weight: 600;">source</span>: classify
        <span style="color: cyan; font-weight: 600;">target</span>: analyze
        <span style="color: cyan; font-weight: 600;">condition</span>:
          <span style="color: cyan; font-weight: 600;">category</span>: <span style="color: #66cc66;">&quot;ANALYSIS&quot;</span>
      - <span style="color: cyan; font-weight: 600;">source</span>: classify
        <span style="color: cyan; font-weight: 600;">target</span>: general
        <span style="color: cyan; font-weight: 600;">condition</span>:
          <span style="color: cyan; font-weight: 600;">category</span>: <span style="color: #66cc66;">&quot;GENERAL&quot;</span>
    <span style="color: cyan; font-weight: 600;">entry_point</span>: classify

  <span style="color: cyan; font-weight: 600;">main</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: stream
    <span style="color: cyan; font-weight: 600;">operators</span>:
      - <span style="color: cyan; font-weight: 600;">type</span>: graph_execute
        <span style="color: cyan; font-weight: 600;">params</span>:
          <span style="color: cyan; font-weight: 600;">graph</span>: router_graph
    <span style="color: cyan; font-weight: 600;">publications</span>:
      - output

<span style="color: cyan; font-weight: 600;">merges</span>:
  - <span style="color: cyan; font-weight: 600;">sources</span>: [output]
    <span style="color: cyan; font-weight: 600;">target</span>: final
</code></pre></div>

---

### Skill Configuration Files

Skill configuration files define reusable, namespaced collections of tools. Skills assemble tools by referencing named tools from the Tool Registry, defining anonymous inline tools, and including other skills. Skills are registered via `agents skill add --config <file>`.

#### JSON Schema

The following is the formal [JSON Schema](https://json-schema.org/) definition for skill configuration files.

<div class="highlight"><pre><code>
{
  <span style="color: cyan; font-weight: 600;">&quot;$schema&quot;</span>: <span style="color: #66cc66;">&quot;https://json-schema.org/draft/2020-12/schema&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;$id&quot;</span>: <span style="color: #66cc66;">&quot;https://cleveragents.dev/schemas/skill-config.json&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;title&quot;</span>: <span style="color: #66cc66;">&quot;CleverAgents Skill Configuration&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Configuration file schema for defining CleverAgents skills — reusable, namespaced collections of tools.&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;pattern&quot;</span>: <span style="color: #66cc66;">&quot;^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Fully qualified skill name in &lt;namespace&gt;/&lt;name&gt; format.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Human-readable description of what this skill provides.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;tools&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;References to named tools from the Tool Registry.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;pattern&quot;</span>: <span style="color: #66cc66;">&quot;^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Fully qualified name of a tool registered in the Tool Registry.&quot;</span>
          },
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Override the tool&#x27;s registered description within this skill context.&quot;</span>
          },
          <span style="color: cyan; font-weight: 600;">&quot;writes&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Override the tool&#x27;s writes capability flag.&quot;</span>
          },
          <span style="color: cyan; font-weight: 600;">&quot;checkpointable&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Override the tool&#x27;s checkpointable capability flag.&quot;</span>
          }
        },
        <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;name&quot;</span>],
        <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
      }
    },
    <span style="color: cyan; font-weight: 600;">&quot;inline_tools&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Anonymous tool definitions that exist only within this skill. Not registered in the Tool Registry.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Tool name, unique within this skill.&quot;</span>
          },
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Human-readable description of the tool&#x27;s purpose.&quot;</span>
          },
          <span style="color: cyan; font-weight: 600;">&quot;source&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;const&quot;</span>: <span style="color: #66cc66;">&quot;custom&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Source type. Always &#x27;custom&#x27; for inline tools.&quot;</span>
          },
          <span style="color: cyan; font-weight: 600;">&quot;code&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Python code defining the tool&#x27;s behavior. Must contain a run(input_data) function.&quot;</span>
          },
          <span style="color: cyan; font-weight: 600;">&quot;input_schema&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;$ref&quot;</span>: <span style="color: #66cc66;">&quot;https://json-schema.org/draft/2020-12/schema&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;JSON Schema describing the tool&#x27;s input parameters.&quot;</span>
          },
          <span style="color: cyan; font-weight: 600;">&quot;writes&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whether this tool performs write operations.&quot;</span>
          },
          <span style="color: cyan; font-weight: 600;">&quot;checkpointable&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whether this tool supports checkpointing.&quot;</span>
          },
          <span style="color: cyan; font-weight: 600;">&quot;side_effects&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
            <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: [],
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Descriptions of side effects (e.g., &#x27;network_call&#x27;, &#x27;schema_mutation&#x27;).&quot;</span>
          }
        },
        <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;name&quot;</span>, <span style="color: #66cc66;">&quot;source&quot;</span>, <span style="color: #66cc66;">&quot;code&quot;</span>],
        <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
      }
    },
    <span style="color: cyan; font-weight: 600;">&quot;includes&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Other skills whose tools are merged into this skill.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;pattern&quot;</span>: <span style="color: #66cc66;">&quot;^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Fully qualified skill name to include.&quot;</span>
          },
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Override the included skill&#x27;s description.&quot;</span>
          }
        },
        <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;name&quot;</span>],
        <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
      }
    },
    <span style="color: cyan; font-weight: 600;">&quot;mcp_servers&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;MCP server specifications for exposing remote tools.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;$ref&quot;</span>: <span style="color: #66cc66;">&quot;#/$defs/mcpServer&quot;</span>
      }
    },
    <span style="color: cyan; font-weight: 600;">&quot;agent_skill_folders&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Agent Skills Standard folders to include.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;path&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Path to the folder containing SKILL.md.&quot;</span>
          },
          <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Override the skill bundle name.&quot;</span>
          }
        },
        <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;path&quot;</span>],
        <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
      }
    }
  },
  <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;name&quot;</span>],
  <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
  <span style="color: cyan; font-weight: 600;">&quot;$defs&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;mcpServer&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;An MCP server specification.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Identifier for the MCP server.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;transport&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;stdio&quot;</span>, <span style="color: #66cc66;">&quot;sse&quot;</span>, <span style="color: #66cc66;">&quot;streamable-http&quot;</span>],
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Transport protocol.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;command&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Command to start the server (required for stdio transport).&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;args&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Command-line arguments for the server command.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;env&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Environment variables to set when starting the server.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;url&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;format&quot;</span>: <span style="color: #66cc66;">&quot;uri&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Server URL (required for sse and streamable-http transports).&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;headers&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;HTTP headers for remote server connections.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;tool_filter&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;include&quot;</span>: {
              <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
              <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whitelist of tool names to expose.&quot;</span>
            },
            <span style="color: cyan; font-weight: 600;">&quot;exclude&quot;</span>: {
              <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
              <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
              <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Blacklist of tool names to hide.&quot;</span>
            }
          },
          <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
        }
      },
      <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;name&quot;</span>, <span style="color: #66cc66;">&quot;transport&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
    }
  }
}
</code></pre></div>

#### Informal YAML Schema

The following annotated YAML provides an easier-to-read overview of the same schema defined formally above. It is **not** a validatable schema — it uses informal annotations to describe the structure. Refer to the JSON Schema above for the authoritative, machine-validatable definition.

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># ─── Skill Metadata ─────────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">&lt;namespace&gt;/&lt;name&gt;</span><span style="opacity: 0.7;">            # Fully qualified skill name (required)</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">               # Human-readable description (optional)</span>

<span style="opacity: 0.7;"># ─── Tool References ────────────────────────────────────────────────</span>
<span style="opacity: 0.7;"># Named tools from the Tool Registry, referenced by fully-qualified name.</span>
<span style="color: cyan; font-weight: 600;">tools</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">&lt;namespace&gt;/&lt;tool_name&gt;</span><span style="opacity: 0.7;">   # Reference to a registered tool (required)</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">           # Override the tool&#x27;s description (optional)</span>
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: #66cc66;">&lt;boolean&gt;</span><span style="opacity: 0.7;">               # Override the tool&#x27;s writes flag (optional)</span>
    <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: #66cc66;">&lt;boolean&gt;</span><span style="opacity: 0.7;">       # Override the tool&#x27;s checkpointable flag (optional)</span>

<span style="opacity: 0.7;"># ─── Inline (Anonymous) Tools ───────────────────────────────────────</span>
<span style="opacity: 0.7;"># Tools defined directly within this skill. These are NOT registered</span>
<span style="opacity: 0.7;"># in the Tool Registry and cannot be reused outside this skill.</span>
<span style="color: cyan; font-weight: 600;">inline_tools</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                  # Tool name (unique within this skill, required)</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">           # Tool description (optional)</span>
    <span style="color: cyan; font-weight: 600;">source</span>: custom<span style="opacity: 0.7;">                  # Source type (required, always &quot;custom&quot; for inline)</span>
    <span style="color: cyan; font-weight: 600;">code</span>: |<span style="opacity: 0.7;">                         # Inline Python code (required)</span>
      def run(input_data):
          return {&quot;result&quot;: &quot;value&quot;}
    <span style="color: cyan; font-weight: 600;">input_schema</span>:                   # JSON Schema for tool inputs (optional)
      <span style="color: cyan; font-weight: 600;">type</span>: object
      <span style="color: cyan; font-weight: 600;">properties</span>:
        <span style="color: cyan; font-weight: 600;">param_name</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: string
          <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Parameter description&quot;</span>
      <span style="color: cyan; font-weight: 600;">required</span>: [<span style="color: #66cc66;">&quot;param_name&quot;</span>]
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">false</span><span style="opacity: 0.7;">                   # Whether this tool writes (optional, default: false)</span>
    <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">false</span><span style="opacity: 0.7;">           # Whether this tool supports checkpointing (optional, default: false)</span>
    <span style="color: cyan; font-weight: 600;">side_effects</span>: []<span style="opacity: 0.7;">                # List of side effect descriptions (optional)</span>

<span style="opacity: 0.7;"># ─── Included Skills ────────────────────────────────────────────────</span>
<span style="opacity: 0.7;"># Other skills whose tools are merged into this skill.</span>
<span style="color: cyan; font-weight: 600;">includes</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">&lt;namespace&gt;/&lt;skill_name&gt;</span><span style="opacity: 0.7;">  # Fully qualified skill name to include (required)</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">           # Override the included skill&#x27;s description (optional)</span>

<span style="opacity: 0.7;"># ─── MCP Server Specifications ──────────────────────────────────────</span>
<span style="opacity: 0.7;"># MCP servers whose tools are exposed through this skill.</span>
<span style="color: cyan; font-weight: 600;">mcp_servers</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                  # Server name for identification (required)</span>
    <span style="color: cyan; font-weight: 600;">transport</span>: <span style="color: magenta;">stdio | sse | streamable-http</span><span style="opacity: 0.7;">  # Transport protocol (required)</span>
    <span style="color: cyan; font-weight: 600;">command</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">               # Server command (required for stdio)</span>
    <span style="color: cyan; font-weight: 600;">args</span>:                           # Command arguments (optional)
      - <span style="color: #66cc66;">&lt;string&gt;</span>
    <span style="color: cyan; font-weight: 600;">env</span>:                            # Environment variables for the server (optional)
      <span style="color: cyan; font-weight: 600;">KEY</span>: <span style="color: #66cc66;">&quot;value&quot;</span>
    <span style="color: cyan; font-weight: 600;">url</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                   # Server URL (required for sse/streamable-http)</span>
    <span style="color: cyan; font-weight: 600;">headers</span>: {}<span style="opacity: 0.7;">                     # HTTP headers (optional, for sse/streamable-http)</span>
    <span style="color: cyan; font-weight: 600;">tool_filter</span>:                    # Filter which tools to expose (optional)
      <span style="color: cyan; font-weight: 600;">include</span>:                      # Include only these tools (optional)
        - <span style="color: #66cc66;">&lt;tool_name&gt;</span>
      <span style="color: cyan; font-weight: 600;">exclude</span>:                      # Exclude these tools (optional)
        - <span style="color: #66cc66;">&lt;tool_name&gt;</span>

<span style="opacity: 0.7;"># ─── Agent Skills Standard Folders ──────────────────────────────────</span>
<span style="opacity: 0.7;"># References to Agent Skills Standard (SKILL.md-based) tool bundles.</span>
<span style="color: cyan; font-weight: 600;">agent_skill_folders</span>:
  - <span style="color: cyan; font-weight: 600;">path</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                  # Path to the folder containing SKILL.md (required)</span>
    <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                  # Override the skill bundle name (optional)</span>
</code></pre></div>

#### Structure Reference

**Top-Level Fields**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Fully qualified skill name in `<namespace>/<name>` format. This value is used as the skill's registered name. |
| `description` | string | No | Human-readable description of what this skill provides. |
| `tools` | list | No | References to named tools from the Tool Registry. |
| `inline_tools` | list | No | Anonymous tool definitions that exist only within this skill. |
| `includes` | list | No | Other skills to include (their tools are merged in). |
| `mcp_servers` | list | No | MCP server specifications for exposing remote tools. |
| `agent_skill_folders` | list | No | Agent Skills Standard folders to include. |

**Tool Reference Fields (`tools[]`)**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Fully qualified name of a tool registered in the Tool Registry. |
| `description` | string | No | Override the tool's registered description within this skill context. |
| `writes` | boolean | No | Override the tool's `writes` capability flag. |
| `checkpointable` | boolean | No | Override the tool's `checkpointable` capability flag. |

**Inline Tool Fields (`inline_tools[]`)**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Tool name, unique within this skill. |
| `description` | string | No | Human-readable description of the tool's purpose. |
| `source` | string | Yes | Always `custom` for inline tools. |
| `code` | string | Yes | Python code defining the tool's behavior. Must contain a `run(input_data)` function. |
| `input_schema` | object | No | JSON Schema describing the tool's input parameters. |
| `writes` | boolean | No | Whether this tool performs write operations. Default: `false`. |
| `checkpointable` | boolean | No | Whether this tool supports checkpointing. Default: `false`. |
| `side_effects` | list | No | Descriptions of any side effects (e.g., `["network_call"]`, `["schema_mutation"]`). |

**MCP Server Fields (`mcp_servers[]`)**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Identifier for the MCP server. |
| `transport` | string | Yes | Transport protocol: `stdio`, `sse`, or `streamable-http`. |
| `command` | string | Conditional | Command to start the server (required for `stdio` transport). |
| `args` | list | No | Command-line arguments for the server command. |
| `env` | object | No | Environment variables to set when starting the server. |
| `url` | string | Conditional | Server URL (required for `sse` and `streamable-http` transports). |
| `headers` | object | No | HTTP headers for remote server connections. |
| `tool_filter.include` | list | No | Whitelist of tool names to expose. When set, only these tools are available. |
| `tool_filter.exclude` | list | No | Blacklist of tool names to hide. Applied after `include`. |

#### Examples

**Example 1: Minimal Read-Only Skill (Simple)**

A skill that bundles a few built-in file operations:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># file-reader-skill.yaml</span>
<span style="opacity: 0.7;"># Register: agents skill add --config file-reader-skill.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/file-reader</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Basic file reading operations&quot;</span>

<span style="color: cyan; font-weight: 600;">tools</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">builtin/read_file</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">builtin/list_directory</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">builtin/search_files</span>
</code></pre></div>

---

**Example 2: Git Operations Skill with MCP (Medium)**

A skill that combines built-in git tools with GitHub tools via an MCP server:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># git-and-github-skill.yaml</span>
<span style="opacity: 0.7;"># Register: agents skill add --config git-and-github-skill.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/git-github</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Git operations and GitHub integration&quot;</span>

<span style="color: cyan; font-weight: 600;">tools</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">builtin/git_status</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">builtin/git_diff</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">builtin/git_log</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">builtin/git_blame</span>

<span style="color: cyan; font-weight: 600;">includes</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/file-reader</span>

<span style="color: cyan; font-weight: 600;">mcp_servers</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: github
    <span style="color: cyan; font-weight: 600;">transport</span>: stdio
    <span style="color: cyan; font-weight: 600;">command</span>: npx
    <span style="color: cyan; font-weight: 600;">args</span>:
      - <span style="color: #66cc66;">&quot;-y&quot;</span>
      - <span style="color: #66cc66;">&quot;@modelcontextprotocol/server-github&quot;</span>
    <span style="color: cyan; font-weight: 600;">env</span>:
      <span style="color: cyan; font-weight: 600;">GITHUB_PERSONAL_ACCESS_TOKEN</span>: <span style="color: #66cc66;">&quot;${GITHUB_TOKEN}&quot;</span>
    <span style="color: cyan; font-weight: 600;">tool_filter</span>:
      <span style="color: cyan; font-weight: 600;">include</span>:
        - create_issue
        - create_pull_request
        - list_repos
        - get_file_contents
</code></pre></div>

This skill includes another skill (`local/file-reader`) and adds GitHub tools from an MCP server, filtered to only expose four specific tools.

---

**Example 3: Full DevOps Toolkit (Complex)**

A comprehensive skill with multiple includes, MCP servers, inline tools, and agent skill folders:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># devops-toolkit.yaml</span>
<span style="opacity: 0.7;"># Register: agents skill add --config devops-toolkit.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/devops-toolkit</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Full-stack development and operations toolkit&quot;</span>

<span style="color: cyan; font-weight: 600;">tools</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">builtin/shell_execute</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Execute shell commands in the project sandbox&quot;</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/validate-api-compat</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Check API backward compatibility&quot;</span>

<span style="color: cyan; font-weight: 600;">includes</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/file-reader</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/git-github</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/docker-tools</span>

<span style="color: cyan; font-weight: 600;">inline_tools</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: run_migrations
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Run database migrations with rollback support&quot;</span>
    <span style="color: cyan; font-weight: 600;">source</span>: custom
    <span style="color: cyan; font-weight: 600;">code</span>: |
      import subprocess
      def run(input_data):
          direction = input_data.get(&quot;direction&quot;, &quot;up&quot;)
          count = input_data.get(&quot;count&quot;, 1)
          result = subprocess.run(
              [&quot;alembic&quot;, direction, str(count)],
              capture_output=True, text=True
          )
          return {
              <span style="color: cyan; font-weight: 600;">&quot;success&quot;</span>: result.returncode == 0,
              <span style="color: cyan; font-weight: 600;">&quot;stdout&quot;</span>: result.stdout,
              <span style="color: cyan; font-weight: 600;">&quot;stderr&quot;</span>: result.stderr
          }
    <span style="color: cyan; font-weight: 600;">input_schema</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: object
      <span style="color: cyan; font-weight: 600;">properties</span>:
        <span style="color: cyan; font-weight: 600;">direction</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: string
          <span style="color: cyan; font-weight: 600;">enum</span>: [<span style="color: #66cc66;">&quot;up&quot;</span>, <span style="color: #66cc66;">&quot;down&quot;</span>]
          <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Migration direction&quot;</span>
        <span style="color: cyan; font-weight: 600;">count</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: integer
          <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: yellow;">1</span>
          <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Number of migrations to run&quot;</span>
      <span style="color: cyan; font-weight: 600;">required</span>: [<span style="color: #66cc66;">&quot;direction&quot;</span>]
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">side_effects</span>: [<span style="color: #66cc66;">&quot;schema_mutation&quot;</span>]

  - <span style="color: cyan; font-weight: 600;">name</span>: health_check
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Check service health endpoints&quot;</span>
    <span style="color: cyan; font-weight: 600;">source</span>: custom
    <span style="color: cyan; font-weight: 600;">code</span>: |
      import urllib.request
      def run(input_data):
          <span style="color: #66cc66;">url = input_data.get(&quot;url&quot;, &quot;http://localhost:8000/health&quot;)</span>
          <span style="color: cyan; font-weight: 600;">try</span>:
              resp = urllib.request.urlopen(url, timeout=10)
              return {&quot;status&quot;: resp.status, &quot;healthy&quot;: resp.status == 200}
          except Exception as e:
              return {&quot;status&quot;: 0, &quot;healthy&quot;: False, &quot;error&quot;: str(e)}
    <span style="color: cyan; font-weight: 600;">input_schema</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: object
      <span style="color: cyan; font-weight: 600;">properties</span>:
        <span style="color: cyan; font-weight: 600;">url</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: string
          <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Health check URL&quot;</span>
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">false</span>

<span style="color: cyan; font-weight: 600;">mcp_servers</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: linear
    <span style="color: cyan; font-weight: 600;">transport</span>: stdio
    <span style="color: cyan; font-weight: 600;">command</span>: npx
    <span style="color: cyan; font-weight: 600;">args</span>: [<span style="color: #66cc66;">&quot;-y&quot;</span>, <span style="color: #66cc66;">&quot;@modelcontextprotocol/server-linear&quot;</span>]
    <span style="color: cyan; font-weight: 600;">env</span>:
      <span style="color: cyan; font-weight: 600;">LINEAR_API_KEY</span>: <span style="color: #66cc66;">&quot;${LINEAR_API_KEY}&quot;</span>

<span style="color: cyan; font-weight: 600;">agent_skill_folders</span>:
  - <span style="color: cyan; font-weight: 600;">path</span>: <span style="color: #66cc66;">./skills/deploy-to-staging</span>
    <span style="color: cyan; font-weight: 600;">name</span>: deploy-staging
  - <span style="color: cyan; font-weight: 600;">path</span>: <span style="color: #66cc66;">./skills/code-review-bundle</span>
    <span style="color: cyan; font-weight: 600;">name</span>: code-review
</code></pre></div>

---

**Example 4: Skill with Only Inline Tools (Simple)**

A self-contained skill that defines everything inline, with no external dependencies:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># text-processing-skill.yaml</span>
<span style="opacity: 0.7;"># Register: agents skill add --config text-processing-skill.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/text-processing</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Simple text transformation utilities&quot;</span>

<span style="color: cyan; font-weight: 600;">inline_tools</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: word_count
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Count words in text&quot;</span>
    <span style="color: cyan; font-weight: 600;">source</span>: custom
    <span style="color: cyan; font-weight: 600;">code</span>: |
      def run(input_data):
          text = input_data.get(&quot;text&quot;, &quot;&quot;)
          return {&quot;count&quot;: len(text.split())}
    <span style="color: cyan; font-weight: 600;">input_schema</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: object
      <span style="color: cyan; font-weight: 600;">properties</span>:
        <span style="color: cyan; font-weight: 600;">text</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: string
          <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Text to count words in&quot;</span>
      <span style="color: cyan; font-weight: 600;">required</span>: [<span style="color: #66cc66;">&quot;text&quot;</span>]
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">false</span>

  - <span style="color: cyan; font-weight: 600;">name</span>: to_uppercase
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Convert text to uppercase&quot;</span>
    <span style="color: cyan; font-weight: 600;">source</span>: custom
    <span style="color: cyan; font-weight: 600;">code</span>: |
      def run(input_data):
          return {&quot;result&quot;: input_data.get(&quot;text&quot;, &quot;&quot;).upper()}
    <span style="color: cyan; font-weight: 600;">input_schema</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: object
      <span style="color: cyan; font-weight: 600;">properties</span>:
        <span style="color: cyan; font-weight: 600;">text</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: string
      <span style="color: cyan; font-weight: 600;">required</span>: [<span style="color: #66cc66;">&quot;text&quot;</span>]
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">false</span>

  - <span style="color: cyan; font-weight: 600;">name</span>: extract_urls
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Extract URLs from text&quot;</span>
    <span style="color: cyan; font-weight: 600;">source</span>: custom
    <span style="color: cyan; font-weight: 600;">code</span>: |
      import re
      def run(input_data):
          text = input_data.get(&quot;text&quot;, &quot;&quot;)
          <span style="color: #66cc66;">urls = re.findall(r&#x27;https?://[^\s&lt;&gt;&quot;{}|\\^`\[\]]+&#x27;, text)</span>
          return {&quot;urls&quot;: urls, &quot;count&quot;: len(urls)}
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">false</span>
</code></pre></div>

---

### Action Configuration Files

Action configuration files define reusable plan templates — complete specifications for work that can be applied to projects. Actions are created via `agents action create --config <file>`.

#### JSON Schema

The following is the formal [JSON Schema](https://json-schema.org/) definition for action configuration files.

<div class="highlight"><pre><code>
{
  <span style="color: cyan; font-weight: 600;">&quot;$schema&quot;</span>: <span style="color: #66cc66;">&quot;https://json-schema.org/draft/2020-12/schema&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;$id&quot;</span>: <span style="color: #66cc66;">&quot;https://cleveragents.dev/schemas/action-config.json&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;title&quot;</span>: <span style="color: #66cc66;">&quot;CleverAgents Action Configuration&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Configuration file schema for defining CleverAgents actions — reusable plan templates that specify work to be applied to projects.&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;pattern&quot;</span>: <span style="color: #66cc66;">&quot;^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Fully qualified action name in &lt;namespace&gt;/&lt;name&gt; format.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Short (one-line) description of the action.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;long_description&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Detailed multi-line description explaining purpose, usage, and expected outcomes.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;strategy_actor&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;pattern&quot;</span>: <span style="color: #66cc66;">&quot;^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Actor to use during the Strategize phase. Must reference a registered actor.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;execution_actor&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;pattern&quot;</span>: <span style="color: #66cc66;">&quot;^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Actor to use during the Execute phase. Must reference a registered actor.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;estimation_actor&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;pattern&quot;</span>: <span style="color: #66cc66;">&quot;^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Actor for effort and cost estimation before execution.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;review_actor&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;pattern&quot;</span>: <span style="color: #66cc66;">&quot;^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Actor for reviewing execution results.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;apply_actor&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;pattern&quot;</span>: <span style="color: #66cc66;">&quot;^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Actor to use during the Apply phase.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;invariant_actor&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;pattern&quot;</span>: <span style="color: #66cc66;">&quot;^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Actor for reconciling conflicting invariants across scopes.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;definition_of_done&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Clear, measurable criteria that define when the action&#x27;s work is complete.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;reusable&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whether the action persists after being used.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;read_only&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whether the action is restricted to read-only operations.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;state&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;available&quot;</span>, <span style="color: #66cc66;">&quot;archived&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: #66cc66;">&quot;available&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;State of the action.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;arguments&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Typed parameters that users supply when using the action via agents plan use --arg name=value.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;$ref&quot;</span>: <span style="color: #66cc66;">&quot;#/$defs/argument&quot;</span>
      }
    },
    <span style="color: cyan; font-weight: 600;">&quot;automation_profile&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Default automation profile for plans created from this action.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;invariants&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Constraints carried forward as plan-level invariants when the action is used.&quot;</span>
    }
  },
  <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;name&quot;</span>, <span style="color: #66cc66;">&quot;description&quot;</span>, <span style="color: #66cc66;">&quot;strategy_actor&quot;</span>, <span style="color: #66cc66;">&quot;execution_actor&quot;</span>, <span style="color: #66cc66;">&quot;definition_of_done&quot;</span>],
  <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
  <span style="color: cyan; font-weight: 600;">&quot;$defs&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;argument&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;A typed parameter for the action.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Argument name. Used as the key in --arg name=value.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;string&quot;</span>, <span style="color: #66cc66;">&quot;integer&quot;</span>, <span style="color: #66cc66;">&quot;float&quot;</span>, <span style="color: #66cc66;">&quot;boolean&quot;</span>, <span style="color: #66cc66;">&quot;list&quot;</span>],
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Data type of the argument.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whether the argument must be provided.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Human-readable description shown in help text.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Default value when the argument is not provided. Type must match the &#x27;type&#x27; field.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;validation_pattern&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Regex pattern for validating string arguments.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;min_value&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;number&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Minimum acceptable value for integer and float arguments.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;max_value&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;number&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Maximum acceptable value for integer and float arguments.&quot;</span>
        }
      },
      <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;name&quot;</span>, <span style="color: #66cc66;">&quot;type&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
    }
  }
}
</code></pre></div>

#### Informal YAML Schema

The following annotated YAML provides an easier-to-read overview of the same schema defined formally above. It is **not** a validatable schema — it uses informal annotations to describe the structure. Refer to the JSON Schema above for the authoritative, machine-validatable definition.

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># ─── Action Identity ────────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">&lt;namespace&gt;/&lt;name&gt;</span><span style="opacity: 0.7;">            # Fully qualified action name (required)</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">               # Short description (required)</span>
<span style="color: cyan; font-weight: 600;">long_description</span>: |<span style="opacity: 0.7;">                 # Detailed description (optional)</span>
  Multi-line detailed explanation of what this action does,
  when to use it, and what outcomes to expect.

<span style="opacity: 0.7;"># ─── Lifecycle Actors ───────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">strategy_actor</span>: <span style="color: #66cc66;">&lt;namespace&gt;/&lt;name&gt;</span><span style="opacity: 0.7;">  # Actor for the Strategize phase (required)</span>
<span style="color: cyan; font-weight: 600;">execution_actor</span>: <span style="color: #66cc66;">&lt;namespace&gt;/&lt;name&gt;</span><span style="opacity: 0.7;"> # Actor for the Execute phase (required)</span>
<span style="color: cyan; font-weight: 600;">estimation_actor</span>: <span style="color: #66cc66;">&lt;namespace&gt;/&lt;name&gt;</span><span style="opacity: 0.7;"> # Actor for effort/cost estimation (optional)</span>
<span style="color: cyan; font-weight: 600;">review_actor</span>: <span style="color: #66cc66;">&lt;namespace&gt;/&lt;name&gt;</span><span style="opacity: 0.7;">    # Actor for reviewing results (optional)</span>
<span style="color: cyan; font-weight: 600;">apply_actor</span>: <span style="color: #66cc66;">&lt;namespace&gt;/&lt;name&gt;</span><span style="opacity: 0.7;">     # Actor for the Apply phase (optional)</span>
<span style="color: cyan; font-weight: 600;">invariant_actor</span>: <span style="color: #66cc66;">&lt;namespace&gt;/&lt;name&gt;</span><span style="opacity: 0.7;"> # Invariant Reconciliation Actor (optional)</span>

<span style="opacity: 0.7;"># ─── Completion Criteria ────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">definition_of_done</span>: |<span style="opacity: 0.7;">               # Criteria for when the action is complete (required)</span>
  Clear, measurable criteria that define success.
  Multiple criteria can be listed.

<span style="opacity: 0.7;"># ─── Action Properties ──────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">reusable</span>: <span style="color: magenta; font-weight: 600;">true</span><span style="opacity: 0.7;">                      # Keep action after use (optional, default: true)</span>
<span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">false</span><span style="opacity: 0.7;">                    # Restrict to read-only operations (optional, default: false)</span>
<span style="color: cyan; font-weight: 600;">state</span>: available<span style="opacity: 0.7;">                    # State of the action: available or archived (optional, default: available)</span>
<span style="opacity: 0.7;"># ─── Arguments ──────────────────────────────────────────────────────</span>
<span style="opacity: 0.7;"># Arguments are typed parameters that must be supplied when using</span>
<span style="opacity: 0.7;"># the action via `agents plan use --arg name=value`.</span>
<span style="color: cyan; font-weight: 600;">arguments</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                  # Argument name (required)</span>
    <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: magenta;">string | integer | float | boolean | list</span><span style="opacity: 0.7;">  # Argument type (required)</span>
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">true</span><span style="opacity: 0.7;">                  # Whether the argument must be provided (optional, default: false)</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">           # Human-readable description (optional)</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">&lt;value&gt;</span><span style="opacity: 0.7;">                # Default value when not provided (optional)</span>
    <span style="color: cyan; font-weight: 600;">validation_pattern</span>: <span style="color: #66cc66;">&lt;regex&gt;</span><span style="opacity: 0.7;">     # Regex pattern for string validation (optional)</span>
    <span style="color: cyan; font-weight: 600;">min_value</span>: <span style="color: #66cc66;">&lt;number&gt;</span><span style="opacity: 0.7;">             # Minimum value for numeric types (optional)</span>
    <span style="color: cyan; font-weight: 600;">max_value</span>: <span style="color: #66cc66;">&lt;number&gt;</span><span style="opacity: 0.7;">             # Maximum value for numeric types (optional)</span>

<span style="opacity: 0.7;"># ─── Automation ─────────────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">automation_profile</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">        # Default automation profile name (optional)</span>

<span style="opacity: 0.7;"># ─── Invariants ─────────────────────────────────────────────────────</span>
<span style="opacity: 0.7;"># Invariants carried forward as plan-level invariants when this action is used.</span>
<span style="color: cyan; font-weight: 600;">invariants</span>:
  - <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                        # Invariant text</span>
</code></pre></div>

#### Structure Reference

**Top-Level Fields**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Fully qualified action name in `<namespace>/<name>` format. This value is used as the action's registered name. |
| `description` | string | Yes | Short (one-line) description of the action. |
| `long_description` | string | No | Detailed multi-line description explaining purpose, usage, and expected outcomes. |
| `strategy_actor` | string | Yes | Actor to use during the Strategize phase. Must reference a registered actor. |
| `execution_actor` | string | Yes | Actor to use during the Execute phase. Must reference a registered actor. |
| `estimation_actor` | string | No | Actor to use for effort and cost estimation before execution. |
| `review_actor` | string | No | Actor to use for reviewing execution results. |
| `apply_actor` | string | No | Actor to use during the Apply phase. |
| `invariant_actor` | string | No | Actor for reconciling conflicting invariants across scopes. Carried forward to plans. |
| `definition_of_done` | string | Yes | Clear, measurable criteria that define when the action's work is complete. |
| `reusable` | boolean | No | Whether the action persists after being used. Default: `true`. |
| `read_only` | boolean | No | Whether the action is restricted to read-only operations. Default: `false`. |
| `state` | string | No | State of the action: `available` or `archived`. Default: `available`. |
| `arguments` | list | No | Typed parameters that users supply when using the action. |
| `automation_profile` | string | No | Default automation profile for plans created from this action. |
| `invariants` | list | No | Constraints carried forward as plan-level invariants when the action is used. |

**Argument Fields (`arguments[]`)**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Argument name. Used as the key in `--arg name=value`. |
| `type` | string | Yes | Data type: `string`, `integer`, `float`, `boolean`, `list`. |
| `required` | boolean | No | Whether the argument must be provided. Default: `false`. |
| `description` | string | No | Human-readable description shown in help text and `agents action show`. |
| `default` | any | No | Default value when the argument is not provided. Type must match `type`. |
| `validation_pattern` | string | No | Regex pattern for validating string arguments. |
| `min_value` | number | No | Minimum acceptable value for `integer` and `float` arguments. |
| `max_value` | number | No | Maximum acceptable value for `integer` and `float` arguments. |

#### Examples

**Example 1: Simple Linting Action (Simple)**

A minimal action for running linters on a project:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># lint-check.yaml</span>
<span style="opacity: 0.7;"># Create: agents action create --config lint-check.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/lint-check</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Run linting checks on the project&quot;</span>

<span style="color: cyan; font-weight: 600;">strategy_actor</span>: <span style="color: #66cc66;">local/strategist</span>
<span style="color: cyan; font-weight: 600;">execution_actor</span>: <span style="color: #66cc66;">local/executor</span>

<span style="color: cyan; font-weight: 600;">definition_of_done</span>: |
  All linting checks pass with zero errors.

<span style="color: cyan; font-weight: 600;">reusable</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">state</span>: available
</code></pre></div>

Usage: `agents plan use local/lint-check local/api-service`

---

**Example 2: Code Coverage Action with Arguments (Medium)**

An action with typed arguments, invariants, and a specific automation profile:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># code-coverage.yaml</span>
<span style="opacity: 0.7;"># Create: agents action create --config code-coverage.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/code-coverage</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Increase test coverage to a target percentage&quot;</span>
<span style="color: cyan; font-weight: 600;">long_description</span>: |
  Analyzes the current test coverage of a project, identifies
  modules with low coverage, and generates comprehensive test
  suites to meet the target coverage percentage.

  The action prioritizes:
  1. Business-critical modules (auth, payments)
  2. Recently modified code
  3. Error-prone areas based on git history

<span style="color: cyan; font-weight: 600;">strategy_actor</span>: <span style="color: #66cc66;">local/strategist</span>
<span style="color: cyan; font-weight: 600;">execution_actor</span>: <span style="color: #66cc66;">local/executor</span>
<span style="color: cyan; font-weight: 600;">estimation_actor</span>: <span style="color: #66cc66;">local/estimator</span>

<span style="color: cyan; font-weight: 600;">definition_of_done</span>: |
  Test coverage reaches the target_coverage_percent threshold
  across all specified modules. All generated tests pass.
  No existing tests are broken by the changes.

<span style="color: cyan; font-weight: 600;">reusable</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">false</span>
<span style="color: cyan; font-weight: 600;">arguments</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: target_coverage_percent
    <span style="color: cyan; font-weight: 600;">type</span>: integer
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Target test coverage percentage (1-100)&quot;</span>
    <span style="color: cyan; font-weight: 600;">min_value</span>: <span style="color: yellow;">1</span>
    <span style="color: cyan; font-weight: 600;">max_value</span>: <span style="color: yellow;">100</span>

  - <span style="color: cyan; font-weight: 600;">name</span>: test_command
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Test framework command to use&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">&quot;pytest --cov&quot;</span>

  - <span style="color: cyan; font-weight: 600;">name</span>: exclude_patterns
    <span style="color: cyan; font-weight: 600;">type</span>: list
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;File patterns to exclude from coverage analysis&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: [<span style="color: #66cc66;">&quot;**/migrations/**&quot;</span>, <span style="color: #66cc66;">&quot;**/conftest.py&quot;</span>]

  - <span style="color: cyan; font-weight: 600;">name</span>: focus_modules
    <span style="color: cyan; font-weight: 600;">type</span>: list
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Specific modules to prioritize for coverage&quot;</span>

<span style="color: cyan; font-weight: 600;">automation_profile</span>: trusted

<span style="color: cyan; font-weight: 600;">invariants</span>:
  - <span style="color: #66cc66;">&quot;Generated tests must not import production secrets or credentials&quot;</span>
  - <span style="color: #66cc66;">&quot;Test files must follow the project&#x27;s existing test naming conventions&quot;</span>
  - <span style="color: #66cc66;">&quot;All database interactions in tests must use mocks or fixtures&quot;</span>
</code></pre></div>

Usage: `agents plan use local/code-coverage local/api-service --arg target_coverage_percent=85`

---

**Example 3: Security Audit Action (Complex)**

A comprehensive security audit action with multiple actors, extensive arguments, and strong invariants:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># security-audit.yaml</span>
<span style="opacity: 0.7;"># Create: agents action create --config security-audit.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/security-audit</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Comprehensive security audit of a project&quot;</span>
<span style="color: cyan; font-weight: 600;">long_description</span>: |
  Performs a thorough security audit covering:
  - Dependency vulnerability scanning (CVEs)
  - Static Application Security Testing (SAST)
  - Authentication and authorization review
  - Input validation and injection prevention
  - Secrets detection and credential scanning
  - API security (rate limiting, CORS, headers)
  - Data handling and privacy compliance

  Generates a detailed report with severity ratings (Critical,
  High, Medium, Low, Informational) and remediation guidance.
  Optionally creates fix plans for identified issues.

<span style="color: cyan; font-weight: 600;">strategy_actor</span>: <span style="color: #66cc66;">local/security-strategist</span>
<span style="color: cyan; font-weight: 600;">execution_actor</span>: <span style="color: #66cc66;">local/security-scanner</span>
<span style="color: cyan; font-weight: 600;">estimation_actor</span>: <span style="color: #66cc66;">local/estimator</span>
<span style="color: cyan; font-weight: 600;">review_actor</span>: <span style="color: #66cc66;">local/security-reviewer</span>
<span style="color: cyan; font-weight: 600;">invariant_actor</span>: <span style="color: #66cc66;">local/invariant-resolver</span>

<span style="color: cyan; font-weight: 600;">definition_of_done</span>: |
  All critical and high severity findings have been identified.
  A complete security report has been generated with:
  - Severity classification for each finding
  - Remediation steps for each finding
  - Risk score for the overall project
  If auto_fix is enabled, all critical findings have remediation
  plans created as child plans.

<span style="color: cyan; font-weight: 600;">reusable</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">false</span>
<span style="color: cyan; font-weight: 600;">state</span>: available

<span style="color: cyan; font-weight: 600;">arguments</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: severity_threshold
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Minimum severity to include in report&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">&quot;low&quot;</span>
    <span style="color: cyan; font-weight: 600;">validation_pattern</span>: <span style="color: #66cc66;">&quot;^(critical|high|medium|low|informational)$&quot;</span>

  - <span style="color: cyan; font-weight: 600;">name</span>: auto_fix
    <span style="color: cyan; font-weight: 600;">type</span>: boolean
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Automatically create fix plans for critical findings&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: magenta; font-weight: 600;">false</span>

  - <span style="color: cyan; font-weight: 600;">name</span>: scan_dependencies
    <span style="color: cyan; font-weight: 600;">type</span>: boolean
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Include dependency vulnerability scanning&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: magenta; font-weight: 600;">true</span>

  - <span style="color: cyan; font-weight: 600;">name</span>: compliance_frameworks
    <span style="color: cyan; font-weight: 600;">type</span>: list
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Compliance frameworks to check against&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: [<span style="color: #66cc66;">&quot;owasp-top-10&quot;</span>]

  - <span style="color: cyan; font-weight: 600;">name</span>: max_findings
    <span style="color: cyan; font-weight: 600;">type</span>: integer
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Maximum number of findings to report&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: yellow;">100</span>
    <span style="color: cyan; font-weight: 600;">min_value</span>: <span style="color: yellow;">1</span>
    <span style="color: cyan; font-weight: 600;">max_value</span>: <span style="color: yellow;">1000</span>

  - <span style="color: cyan; font-weight: 600;">name</span>: ignore_paths
    <span style="color: cyan; font-weight: 600;">type</span>: list
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Paths to exclude from scanning&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: [<span style="color: #66cc66;">&quot;**/node_modules/**&quot;</span>, <span style="color: #66cc66;">&quot;**/vendor/**&quot;</span>, <span style="color: #66cc66;">&quot;**/.git/**&quot;</span>]

<span style="color: cyan; font-weight: 600;">automation_profile</span>: supervised

<span style="color: cyan; font-weight: 600;">invariants</span>:
  - <span style="color: #66cc66;">&quot;Never modify production database schemas during audit&quot;</span>
  - <span style="color: #66cc66;">&quot;Never execute discovered exploit code against live systems&quot;</span>
  - <span style="color: #66cc66;">&quot;All findings must include reproducible steps&quot;</span>
  - <span style="color: #66cc66;">&quot;Secrets found during scanning must be redacted in reports&quot;</span>
  - <span style="color: #66cc66;">&quot;Remediation fixes must not break existing tests&quot;</span>
</code></pre></div>

Usage: `agents plan use local/security-audit local/api-service local/web-app --arg auto_fix=true --arg severity_threshold=medium`

---

**Example 4: Database Migration Action (Medium)**

An action for managing database schema migrations:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># db-migrate.yaml</span>
<span style="opacity: 0.7;"># Create: agents action create --config db-migrate.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/db-migrate</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Plan and execute database schema migrations&quot;</span>

<span style="color: cyan; font-weight: 600;">strategy_actor</span>: <span style="color: #66cc66;">local/db-strategist</span>
<span style="color: cyan; font-weight: 600;">execution_actor</span>: <span style="color: #66cc66;">local/db-executor</span>

<span style="color: cyan; font-weight: 600;">definition_of_done</span>: |
  All migration scripts are generated and pass dry-run validation.
  Rollback scripts are generated for each migration.
  The migration can be applied without data loss.

<span style="color: cyan; font-weight: 600;">reusable</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">false</span>

<span style="color: cyan; font-weight: 600;">arguments</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: migration_tool
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Migration tool to use&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">&quot;alembic&quot;</span>
    <span style="color: cyan; font-weight: 600;">validation_pattern</span>: <span style="color: #66cc66;">&quot;^(alembic|flyway|django|knex)$&quot;</span>

  - <span style="color: cyan; font-weight: 600;">name</span>: dry_run
    <span style="color: cyan; font-weight: 600;">type</span>: boolean
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Only generate and validate, do not apply&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: magenta; font-weight: 600;">true</span>

  - <span style="color: cyan; font-weight: 600;">name</span>: target_schema
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Target schema version identifier&quot;</span>

<span style="color: cyan; font-weight: 600;">automation_profile</span>: supervised

<span style="color: cyan; font-weight: 600;">invariants</span>:
  - <span style="color: #66cc66;">&quot;All migrations must include corresponding rollback scripts&quot;</span>
  - <span style="color: #66cc66;">&quot;Data migrations must preserve existing data integrity&quot;</span>
  - <span style="color: #66cc66;">&quot;Schema changes must maintain backward compatibility for 24 hours&quot;</span>
</code></pre></div>

---

### Tool Configuration Files

Tool configuration files define namespaced, independently registered, callable operations. Tools are the atomic unit of execution — each has a name, input/output schemas, capability metadata, and an implementation. Tools are registered via `agents tool add --config <file>` and can then be referenced by name in skills and actor graphs.

#### JSON Schema

The following is the formal [JSON Schema](https://json-schema.org/) definition for tool configuration files.

<div class="highlight"><pre><code>
{
  <span style="color: cyan; font-weight: 600;">&quot;$schema&quot;</span>: <span style="color: #66cc66;">&quot;https://json-schema.org/draft/2020-12/schema&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;$id&quot;</span>: <span style="color: #66cc66;">&quot;https://cleveragents.dev/schemas/tool-config.json&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;title&quot;</span>: <span style="color: #66cc66;">&quot;CleverAgents Tool Configuration&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Configuration file schema for defining CleverAgents tools — namespaced, independently registered, callable operations.&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;pattern&quot;</span>: <span style="color: #66cc66;">&quot;^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Fully qualified tool name in &lt;namespace&gt;/&lt;name&gt; format.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Human-readable description of the tool&#x27;s purpose and behavior.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;source&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;custom&quot;</span>, <span style="color: #66cc66;">&quot;mcp&quot;</span>, <span style="color: #66cc66;">&quot;agent_skill&quot;</span>, <span style="color: #66cc66;">&quot;builtin&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Tool source type. Determines which implementation fields are required.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;code&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Python code implementing the tool. Required when source is &#x27;custom&#x27;. Must define a run(input_data) function.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;mcp_server&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Name of the MCP server exposing this tool. Required when source is &#x27;mcp&#x27;.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;mcp_tool_name&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Name of the tool on the MCP server. Required when source is &#x27;mcp&#x27;.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;agent_skill_path&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Path to the Agent Skills Standard folder containing SKILL.md. Required when source is &#x27;agent_skill&#x27;.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;input_schema&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;$ref&quot;</span>: <span style="color: #66cc66;">&quot;https://json-schema.org/draft/2020-12/schema&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;JSON Schema describing the tool&#x27;s input parameters.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;output_schema&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;$ref&quot;</span>: <span style="color: #66cc66;">&quot;https://json-schema.org/draft/2020-12/schema&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;JSON Schema describing the tool&#x27;s output format.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;writes&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whether the tool performs any write operations.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;write_scope&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Scope of write operations (e.g., &#x27;filesystem&#x27;, &#x27;database:migrations&#x27;, &#x27;api:github&#x27;).&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;checkpointable&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whether the tool supports checkpointing — saving state before execution and restoring on failure.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;checkpoint_scope&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;file&quot;</span>, <span style="color: #66cc66;">&quot;transaction&quot;</span>, <span style="color: #66cc66;">&quot;snapshot&quot;</span>, <span style="color: #66cc66;">&quot;composite&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;The checkpointing strategy.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;side_effects&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: [],
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Side effects that cannot be undone by checkpointing alone (e.g., &#x27;network_call&#x27;, &#x27;schema_mutation&#x27;, &#x27;email_sent&#x27;).&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;idempotent&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whether the tool is safe to retry — calling it multiple times with the same input produces the same result.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;read_only&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whether the tool only reads data without modifying anything.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;unsafe&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whether the tool is flagged as unsafe. Requires allow_unsafe_tools: true in the automation profile.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;timeout&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;integer&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: yellow;">300</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">1</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Default execution timeout in seconds.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;resource_slots&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Declared resource dependencies for this tool.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;$ref&quot;</span>: <span style="color: #66cc66;">&quot;#/$defs/resourceSlot&quot;</span>
      }
    },
    <span style="color: cyan; font-weight: 600;">&quot;lifecycle&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Lifecycle hook implementations.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;discover&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Python code or function name run during tool discovery.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;activate&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Python code or function name run when the tool is activated.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;deactivate&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Python code or function name run when the tool is deactivated.&quot;</span>
        }
      },
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
    },
  },
  <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;name&quot;</span>, <span style="color: #66cc66;">&quot;description&quot;</span>, <span style="color: #66cc66;">&quot;source&quot;</span>],
  <span style="color: cyan; font-weight: 600;">&quot;allOf&quot;</span>: [
    {
      <span style="color: cyan; font-weight: 600;">&quot;if&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;source&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;const&quot;</span>: <span style="color: #66cc66;">&quot;custom&quot;</span> } } },
      <span style="color: cyan; font-weight: 600;">&quot;then&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;code&quot;</span>] }
    },
    {
      <span style="color: cyan; font-weight: 600;">&quot;if&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;source&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;const&quot;</span>: <span style="color: #66cc66;">&quot;mcp&quot;</span> } } },
      <span style="color: cyan; font-weight: 600;">&quot;then&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;mcp_server&quot;</span>, <span style="color: #66cc66;">&quot;mcp_tool_name&quot;</span>] }
    },
    {
      <span style="color: cyan; font-weight: 600;">&quot;if&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;source&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;const&quot;</span>: <span style="color: #66cc66;">&quot;agent_skill&quot;</span> } } },
      <span style="color: cyan; font-weight: 600;">&quot;then&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;agent_skill_path&quot;</span>] }
    }
  ],
  <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
  <span style="color: cyan; font-weight: 600;">&quot;$defs&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;resourceSlot&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;A declared resource dependency slot.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Identifier for this resource slot.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;resource_type&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;The resource type this slot requires (e.g., &#x27;git-checkout&#x27;, &#x27;fs-directory&#x27;).&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;access&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;read_only&quot;</span>, <span style="color: #66cc66;">&quot;read_write&quot;</span>],
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Access level needed.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Human-readable description of how the tool uses this resource.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;binding&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;contextual&quot;</span>, <span style="color: #66cc66;">&quot;static&quot;</span>, <span style="color: #66cc66;">&quot;parameter&quot;</span>],
          <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: #66cc66;">&quot;contextual&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;How the slot is resolved at runtime.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;static_resource&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;pattern&quot;</span>: <span style="color: #66cc66;">&quot;^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Fully qualified name of a specific resource. Required when binding is &#x27;static&#x27;.&quot;</span>
        }
      },
      <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;name&quot;</span>, <span style="color: #66cc66;">&quot;resource_type&quot;</span>, <span style="color: #66cc66;">&quot;access&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;if&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;binding&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;const&quot;</span>: <span style="color: #66cc66;">&quot;static&quot;</span> } } },
      <span style="color: cyan; font-weight: 600;">&quot;then&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;name&quot;</span>, <span style="color: #66cc66;">&quot;resource_type&quot;</span>, <span style="color: #66cc66;">&quot;access&quot;</span>, <span style="color: #66cc66;">&quot;static_resource&quot;</span>] },
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
    }
  }
}
</code></pre></div>

#### Informal YAML Schema

The following annotated YAML provides an easier-to-read overview of the same schema defined formally above. It is **not** a validatable schema — it uses informal annotations to describe the structure. Refer to the JSON Schema above for the authoritative, machine-validatable definition.

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># ─── Tool Identity ──────────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">&lt;namespace&gt;/&lt;name&gt;</span><span style="opacity: 0.7;">            # Fully qualified tool name (required)</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">               # Human-readable description (required)</span>

<span style="opacity: 0.7;"># ─── Source and Implementation ──────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">source</span>: <span style="color: magenta;">custom | mcp | agent_skill | builtin</span><span style="opacity: 0.7;">  # Tool source type (required)</span>

<span style="opacity: 0.7;"># For source: custom — inline Python implementation</span>
<span style="color: cyan; font-weight: 600;">code</span>: |<span style="opacity: 0.7;">                             # Python code with a run(input_data) function (required for custom)</span>
  def run(input_data):
      param = input_data.get(&quot;param_name&quot;, &quot;default&quot;)
<span style="opacity: 0.7;">      # ... tool logic ...</span>
      return {&quot;result&quot;: &quot;value&quot;}

<span style="opacity: 0.7;"># For source: mcp — tool exposed by an MCP server</span>
<span style="color: cyan; font-weight: 600;">mcp_server</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                # MCP server name (required for mcp)</span>
<span style="color: cyan; font-weight: 600;">mcp_tool_name</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">             # Tool name on the MCP server (required for mcp)</span>

<span style="opacity: 0.7;"># For source: agent_skill — tool from an Agent Skills Standard folder</span>
<span style="color: cyan; font-weight: 600;">agent_skill_path</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">          # Path to the SKILL.md folder (required for agent_skill)</span>

<span style="opacity: 0.7;"># ─── Input/Output Schema ────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">input_schema</span>:                       # JSON Schema for tool inputs (optional but recommended)
  <span style="color: cyan; font-weight: 600;">type</span>: object
  <span style="color: cyan; font-weight: 600;">properties</span>:
    <span style="color: cyan; font-weight: 600;">param_name</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Parameter description&quot;</span>
      <span style="color: cyan; font-weight: 600;">enum</span>: [<span style="color: #66cc66;">&quot;value1&quot;</span>, <span style="color: #66cc66;">&quot;value2&quot;</span>]<span style="opacity: 0.7;">    # Enumerated valid values (optional)</span>
      <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">&quot;value1&quot;</span><span style="opacity: 0.7;">             # Default value (optional)</span>
    <span style="color: cyan; font-weight: 600;">numeric_param</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: integer
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;A numeric parameter&quot;</span>
      <span style="color: cyan; font-weight: 600;">minimum</span>: <span style="color: yellow;">0</span><span style="opacity: 0.7;">                    # Minimum value (optional)</span>
      <span style="color: cyan; font-weight: 600;">maximum</span>: <span style="color: yellow;">100</span><span style="opacity: 0.7;">                  # Maximum value (optional)</span>
  <span style="color: cyan; font-weight: 600;">required</span>: [<span style="color: #66cc66;">&quot;param_name&quot;</span>]<span style="opacity: 0.7;">          # Required parameters</span>

<span style="color: cyan; font-weight: 600;">output_schema</span>:                      # JSON Schema for tool outputs (optional)
  <span style="color: cyan; font-weight: 600;">type</span>: object
  <span style="color: cyan; font-weight: 600;">properties</span>:
    <span style="color: cyan; font-weight: 600;">result</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">success</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: boolean

<span style="opacity: 0.7;"># ─── Capability Metadata ────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">false</span><span style="opacity: 0.7;">                       # Whether the tool performs write operations (optional, default: false)</span>
<span style="color: cyan; font-weight: 600;">write_scope</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">               # Scope of writes, e.g. &quot;filesystem&quot;, &quot;database:migrations&quot; (optional)</span>
<span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">false</span><span style="opacity: 0.7;">               # Whether the tool supports checkpointing (optional, default: false)</span>
<span style="color: cyan; font-weight: 600;">checkpoint_scope</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">          # Checkpointing strategy: &quot;file&quot;, &quot;transaction&quot;, &quot;snapshot&quot;, &quot;composite&quot; (optional)</span>
<span style="color: cyan; font-weight: 600;">side_effects</span>:                       # List of side effect types (optional)
  - <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                        # e.g. &quot;network_call&quot;, &quot;schema_mutation&quot;, &quot;process_spawn&quot;</span>
<span style="color: cyan; font-weight: 600;">idempotent</span>: <span style="color: magenta; font-weight: 600;">false</span><span style="opacity: 0.7;">                   # Whether the tool is safe to retry (optional, default: false)</span>
<span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">false</span><span style="opacity: 0.7;">                    # Whether the tool only reads (optional, default: false)</span>
<span style="color: cyan; font-weight: 600;">unsafe</span>: <span style="color: magenta; font-weight: 600;">false</span><span style="opacity: 0.7;">                       # Whether the tool is flagged as unsafe (optional, default: false)</span>
<span style="color: cyan; font-weight: 600;">timeout</span>: <span style="color: yellow;">300</span><span style="opacity: 0.7;">                        # Default execution timeout in seconds (optional, default: 300)</span>

<span style="opacity: 0.7;"># ─── Resource Bindings ──────────────────────────────────────────────</span>
<span style="opacity: 0.7;"># Declare which resources this tool operates on.</span>
<span style="color: cyan; font-weight: 600;">resource_slots</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                  # Slot name for reference (required)</span>
    <span style="color: cyan; font-weight: 600;">resource_type</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">         # Required resource type, e.g. &quot;git-checkout&quot;, &quot;fs-directory&quot; (required)</span>
    <span style="color: cyan; font-weight: 600;">access</span>: <span style="color: magenta;">read_only | read_write</span><span style="opacity: 0.7;">  # Access level needed (required)</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">           # Description of how the resource is used (optional)</span>
    <span style="color: cyan; font-weight: 600;">binding</span>: <span style="color: magenta;">contextual | static | parameter</span><span style="opacity: 0.7;">  # How the slot is resolved (optional, default: contextual)</span>
    <span style="color: cyan; font-weight: 600;">static_resource</span>: <span style="color: #66cc66;">&lt;namespace&gt;/&lt;name&gt;</span><span style="opacity: 0.7;">       # Specific resource (required when binding is static)</span>

<span style="opacity: 0.7;"># ─── Lifecycle Hooks ────────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">lifecycle</span>:
  <span style="color: cyan; font-weight: 600;">discover</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                # Python function or code for tool discovery (optional)</span>
  <span style="color: cyan; font-weight: 600;">activate</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                # Python function or code run when tool is activated (optional)</span>
  <span style="color: cyan; font-weight: 600;">deactivate</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">              # Python function or code run when tool is deactivated (optional)</span>

</code></pre></div>

#### Structure Reference

**Top-Level Fields**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Fully qualified tool name in `<namespace>/<name>` format. This value is used as the tool's registered name. |
| `description` | string | Yes | Human-readable description of the tool's purpose and behavior. |
| `source` | string | Yes | Tool source type. Determines which implementation fields are required: `custom` (inline Python), `mcp` (MCP server), `agent_skill` (SKILL.md folder), `builtin` (first-party operations). |
| `code` | string | Conditional | Python code implementing the tool. Required when `source` is `custom`. Must define a `run(input_data)` function that accepts a dict and returns a dict. |
| `mcp_server` | string | Conditional | Name of the MCP server exposing this tool. Required when `source` is `mcp`. |
| `mcp_tool_name` | string | Conditional | Name of the tool on the MCP server. Required when `source` is `mcp`. |
| `agent_skill_path` | string | Conditional | Path to the Agent Skills Standard folder containing `SKILL.md`. Required when `source` is `agent_skill`. |
| `input_schema` | object | No | JSON Schema describing the tool's input parameters. Strongly recommended for all tools. |
| `output_schema` | object | No | JSON Schema describing the tool's output format. |
**Capability Metadata Fields**

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `writes` | boolean | `false` | Whether the tool performs any write operations (file writes, database mutations, API calls with side effects). |
| `write_scope` | string | — | Describes the scope of write operations, e.g. `"filesystem"`, `"database:migrations"`, `"api:github"`. Used for access checks and audit logging. |
| `checkpointable` | boolean | `false` | Whether the tool supports checkpointing — the ability to save state before execution and restore it on failure. |
| `checkpoint_scope` | string | — | The checkpointing strategy: `file` (file-level backup), `transaction` (database transaction), `snapshot` (full state snapshot), `composite` (multi-resource checkpoint). |
| `side_effects` | list | `[]` | Descriptions of side effects that cannot be undone by checkpointing alone, e.g. `"network_call"`, `"schema_mutation"`, `"email_sent"`, `"process_spawn"`. |
| `idempotent` | boolean | `false` | Whether the tool is safe to retry — calling it multiple times with the same input produces the same result. |
| `read_only` | boolean | `false` | Whether the tool only reads data without modifying anything. When `true`, `writes` must be `false`. |
| `unsafe` | boolean | `false` | Whether the tool is flagged as unsafe. Unsafe tools require `allow_unsafe_tools: true` in the automation profile. |
| `timeout` | integer | `300` | Default execution timeout in seconds. Can be overridden per invocation. |

**Resource Slot Fields (`resource_slots[]`)**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Identifier for this resource slot, used for reference in code and logs. |
| `resource_type` | string | Yes | The resource type this slot requires, e.g. `git-checkout`, `fs-directory`, `fs-file`. |
| `access` | string | Yes | Access level: `read_only` or `read_write`. |
| `description` | string | No | Human-readable description of how the tool uses this resource. |
| `binding` | string | No | How the slot is resolved at runtime. `contextual` (default): resolved from the plan's project. `static`: hardcoded to a specific resource. `parameter`: passed as a tool argument at invocation time. |
| `static_resource` | string | Conditional | Fully qualified name of a specific resource. Required when `binding` is `static`. |

**Lifecycle Hook Fields (`lifecycle`)**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `discover` | string | No | Code or function name run during tool discovery to check prerequisites and report capabilities. |
| `activate` | string | No | Code or function name run when the tool is activated (e.g., establish connections, validate credentials). |
| `deactivate` | string | No | Code or function name run when the tool is deactivated (e.g., close connections, release resources). |

#### Examples

**Example 1: Simple Read-Only Tool (Simple)**

A tool that reads a file and returns its contents:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># read-config-file.yaml</span>
<span style="opacity: 0.7;"># Register: agents tool add --config read-config-file.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/read-config</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Read and parse a configuration file (JSON, YAML, or TOML)&quot;</span>

<span style="color: cyan; font-weight: 600;">source</span>: custom
<span style="color: cyan; font-weight: 600;">code</span>: |
  import json, os
  def run(input_data):
      path = input_data[&quot;path&quot;]
      if not os.path.exists(path):
          return {&quot;error&quot;: f&quot;File not found: {path}&quot;, &quot;success&quot;: False}
      with open(path, &quot;r&quot;) as f:
          content = f.read()
      ext = os.path.splitext(path)[1].lower()
      if ext == &quot;.json&quot;:
          parsed = json.loads(content)
      elif ext in (&quot;.yaml&quot;, &quot;.yml&quot;):
          import yaml
          parsed = yaml.safe_load(content)
      <span style="color: cyan; font-weight: 600;">else</span>:
          parsed = None
      return {&quot;content&quot;: content, &quot;parsed&quot;: parsed, &quot;path&quot;: path, &quot;success&quot;: True}

<span style="color: cyan; font-weight: 600;">input_schema</span>:
  <span style="color: cyan; font-weight: 600;">type</span>: object
  <span style="color: cyan; font-weight: 600;">properties</span>:
    <span style="color: cyan; font-weight: 600;">path</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Path to the configuration file&quot;</span>
  <span style="color: cyan; font-weight: 600;">required</span>: [<span style="color: #66cc66;">&quot;path&quot;</span>]

<span style="color: cyan; font-weight: 600;">output_schema</span>:
  <span style="color: cyan; font-weight: 600;">type</span>: object
  <span style="color: cyan; font-weight: 600;">properties</span>:
    <span style="color: cyan; font-weight: 600;">content</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">parsed</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: object
    <span style="color: cyan; font-weight: 600;">success</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: boolean

<span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">false</span>
<span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">idempotent</span>: <span style="color: magenta; font-weight: 600;">true</span>
</code></pre></div>

---

**Example 2: Database Migration Tool (Medium)**

A tool that runs database migrations with rollback support:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># run-migrations.yaml</span>
<span style="opacity: 0.7;"># Register: agents tool add --config run-migrations.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/run-migrations</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Run database migrations with direction control and rollback support&quot;</span>

<span style="color: cyan; font-weight: 600;">source</span>: custom
<span style="color: cyan; font-weight: 600;">code</span>: |
  import subprocess
  def run(input_data):
      direction = input_data.get(&quot;direction&quot;, &quot;up&quot;)
      count = input_data.get(&quot;count&quot;, 1)
      dry_run = input_data.get(&quot;dry_run&quot;, False)

      cmd = [&quot;alembic&quot;]
      if dry_run:
          cmd.append(&quot;<span style="color: cyan;">--sql</span>&quot;)
      cmd.extend([direction, str(count)])

      result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
      return {
          <span style="color: cyan; font-weight: 600;">&quot;success&quot;</span>: result.returncode == 0,
          <span style="color: cyan; font-weight: 600;">&quot;stdout&quot;</span>: result.stdout,
          <span style="color: cyan; font-weight: 600;">&quot;stderr&quot;</span>: result.stderr,
          <span style="color: cyan; font-weight: 600;">&quot;direction&quot;</span>: direction,
          <span style="color: cyan; font-weight: 600;">&quot;count&quot;</span>: count,
          <span style="color: cyan; font-weight: 600;">&quot;dry_run&quot;</span>: dry_run,
          <span style="color: cyan; font-weight: 600;">&quot;return_code&quot;</span>: result.returncode
      }

<span style="color: cyan; font-weight: 600;">input_schema</span>:
  <span style="color: cyan; font-weight: 600;">type</span>: object
  <span style="color: cyan; font-weight: 600;">properties</span>:
    <span style="color: cyan; font-weight: 600;">direction</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
      <span style="color: cyan; font-weight: 600;">enum</span>: [<span style="color: #66cc66;">&quot;up&quot;</span>, <span style="color: #66cc66;">&quot;down&quot;</span>]
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Migration direction: &#x27;up&#x27; to apply, &#x27;down&#x27; to rollback&quot;</span>
    <span style="color: cyan; font-weight: 600;">count</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: integer
      <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: yellow;">1</span>
      <span style="color: cyan; font-weight: 600;">minimum</span>: <span style="color: yellow;">1</span>
      <span style="color: cyan; font-weight: 600;">maximum</span>: <span style="color: yellow;">50</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Number of migrations to run&quot;</span>
    <span style="color: cyan; font-weight: 600;">dry_run</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: boolean
      <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: magenta; font-weight: 600;">false</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Generate SQL without executing&quot;</span>
  <span style="color: cyan; font-weight: 600;">required</span>: [<span style="color: #66cc66;">&quot;direction&quot;</span>]

<span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">write_scope</span>: <span style="color: #66cc66;">&quot;database:migrations&quot;</span>
<span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">checkpoint_scope</span>: <span style="color: #66cc66;">&quot;transaction&quot;</span>
<span style="color: cyan; font-weight: 600;">side_effects</span>:
  - <span style="color: #66cc66;">&quot;schema_mutation&quot;</span>
<span style="color: cyan; font-weight: 600;">idempotent</span>: <span style="color: magenta; font-weight: 600;">false</span>
<span style="color: cyan; font-weight: 600;">timeout</span>: <span style="color: yellow;">120</span>

<span style="color: cyan; font-weight: 600;">resource_slots</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: database
    <span style="color: cyan; font-weight: 600;">resource_type</span>: <span style="color: #66cc66;">&quot;local/database&quot;</span>
    <span style="color: cyan; font-weight: 600;">access</span>: read_write
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;The database to run migrations against&quot;</span>
    <span style="color: cyan; font-weight: 600;">binding</span>: contextual
</code></pre></div>

---

**Example 3: MCP-Backed GitHub Tool (Simple)**

A tool that delegates to a GitHub MCP server:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># github-create-issue.yaml</span>
<span style="opacity: 0.7;"># Register: agents tool add --config github-create-issue.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/github-create-issue</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Create a GitHub issue via the GitHub MCP server&quot;</span>

<span style="color: cyan; font-weight: 600;">source</span>: mcp
<span style="color: cyan; font-weight: 600;">mcp_server</span>: github
<span style="color: cyan; font-weight: 600;">mcp_tool_name</span>: create_issue

<span style="color: cyan; font-weight: 600;">input_schema</span>:
  <span style="color: cyan; font-weight: 600;">type</span>: object
  <span style="color: cyan; font-weight: 600;">properties</span>:
    <span style="color: cyan; font-weight: 600;">owner</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Repository owner&quot;</span>
    <span style="color: cyan; font-weight: 600;">repo</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Repository name&quot;</span>
    <span style="color: cyan; font-weight: 600;">title</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Issue title&quot;</span>
    <span style="color: cyan; font-weight: 600;">body</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Issue body (Markdown)&quot;</span>
    <span style="color: cyan; font-weight: 600;">labels</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: array
      <span style="color: cyan; font-weight: 600;">items</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: string
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Labels to apply&quot;</span>
  <span style="color: cyan; font-weight: 600;">required</span>: [<span style="color: #66cc66;">&quot;owner&quot;</span>, <span style="color: #66cc66;">&quot;repo&quot;</span>, <span style="color: #66cc66;">&quot;title&quot;</span>]

<span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">write_scope</span>: <span style="color: #66cc66;">&quot;api:github&quot;</span>
<span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">false</span>
<span style="color: cyan; font-weight: 600;">side_effects</span>:
  - <span style="color: #66cc66;">&quot;network_call&quot;</span>
<span style="color: cyan; font-weight: 600;">idempotent</span>: <span style="color: magenta; font-weight: 600;">false</span>
</code></pre></div>

---

**Example 4: Deployment Tool with Resource Bindings (Complex)**

A comprehensive deployment tool with multiple resource slots, lifecycle hooks, and safety metadata:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># deploy-staging.yaml</span>
<span style="opacity: 0.7;"># Register: agents tool add --config deploy-staging.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/deploy-staging</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Deploy the current build to the staging environment with health checks&quot;</span>

<span style="color: cyan; font-weight: 600;">source</span>: custom
<span style="color: cyan; font-weight: 600;">code</span>: |
  import subprocess, time, urllib.request, json

  def run(input_data):
      service = input_data[&quot;service&quot;]
      version = input_data.get(&quot;version&quot;, &quot;latest&quot;)
      wait_healthy = input_data.get(&quot;wait_healthy&quot;, True)
      health_timeout = input_data.get(&quot;health_timeout&quot;, 120)

<span style="opacity: 0.7;">      # Build the deployment command</span>
      cmd = [&quot;kubectl&quot;, &quot;set&quot;, &quot;image&quot;,
             <span style="color: #66cc66;">f&quot;deployment/{service}&quot;,</span>
             f&quot;{service}={service}:{version}&quot;,
             &quot;<span style="color: cyan;">--namespace</span>=staging&quot;]
      result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
      if result.returncode != 0:
          return {&quot;success&quot;: False, &quot;error&quot;: result.stderr, &quot;phase&quot;: &quot;deploy&quot;}

<span style="opacity: 0.7;">      # Wait for rollout</span>
      rollout = subprocess.run(
          <span style="color: #66cc66;">[&quot;kubectl&quot;, &quot;rollout&quot;, &quot;status&quot;, f&quot;deployment/{service}&quot;,</span>
           &quot;<span style="color: cyan;">--namespace</span>=staging&quot;, f&quot;<span style="color: cyan;">--timeout</span>={health_timeout}s&quot;],
          capture_output=True, text=True, timeout=health_timeout + 10
      )
      if rollout.returncode != 0:
          return {&quot;success&quot;: False, &quot;error&quot;: rollout.stderr, &quot;phase&quot;: &quot;rollout&quot;}

<span style="opacity: 0.7;">      # Health check</span>
      if wait_healthy:
          <span style="color: #66cc66;">health_url = f&quot;http://{service}.staging.svc.cluster.local/health&quot;</span>
          start = time.time()
          while time.time() - start &lt; health_timeout:
              <span style="color: cyan; font-weight: 600;">try</span>:
                  resp = urllib.request.urlopen(health_url, timeout=5)
                  if resp.status == 200:
                      body = json.loads(resp.read())
                      if body.get(&quot;status&quot;) == &quot;healthy&quot;:
                          return {
                              <span style="color: cyan; font-weight: 600;">&quot;success&quot;</span>: True,
                              <span style="color: cyan; font-weight: 600;">&quot;service&quot;</span>: service,
                              <span style="color: cyan; font-weight: 600;">&quot;version&quot;</span>: version,
                              <span style="color: cyan; font-weight: 600;">&quot;health&quot;</span>: body
                          }
              except Exception:
                  pass
              time.sleep(5)
          return {&quot;success&quot;: False, &quot;error&quot;: &quot;Health check timeout&quot;, &quot;phase&quot;: &quot;health&quot;}

      return {&quot;success&quot;: True, &quot;service&quot;: service, &quot;version&quot;: version}

<span style="color: cyan; font-weight: 600;">input_schema</span>:
  <span style="color: cyan; font-weight: 600;">type</span>: object
  <span style="color: cyan; font-weight: 600;">properties</span>:
    <span style="color: cyan; font-weight: 600;">service</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Name of the service to deploy&quot;</span>
    <span style="color: cyan; font-weight: 600;">version</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
      <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">&quot;latest&quot;</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Docker image version tag&quot;</span>
    <span style="color: cyan; font-weight: 600;">wait_healthy</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: boolean
      <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: magenta; font-weight: 600;">true</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Wait for health check to pass&quot;</span>
    <span style="color: cyan; font-weight: 600;">health_timeout</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: integer
      <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: yellow;">120</span>
      <span style="color: cyan; font-weight: 600;">minimum</span>: <span style="color: yellow;">10</span>
      <span style="color: cyan; font-weight: 600;">maximum</span>: <span style="color: yellow;">600</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Health check timeout in seconds&quot;</span>
  <span style="color: cyan; font-weight: 600;">required</span>: [<span style="color: #66cc66;">&quot;service&quot;</span>]

<span style="color: cyan; font-weight: 600;">output_schema</span>:
  <span style="color: cyan; font-weight: 600;">type</span>: object
  <span style="color: cyan; font-weight: 600;">properties</span>:
    <span style="color: cyan; font-weight: 600;">success</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: boolean
    <span style="color: cyan; font-weight: 600;">service</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">version</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">error</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">phase</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string

<span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">write_scope</span>: <span style="color: #66cc66;">&quot;infrastructure:kubernetes&quot;</span>
<span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">checkpoint_scope</span>: <span style="color: #66cc66;">&quot;composite&quot;</span>
<span style="color: cyan; font-weight: 600;">side_effects</span>:
  - <span style="color: #66cc66;">&quot;network_call&quot;</span>
  - <span style="color: #66cc66;">&quot;process_spawn&quot;</span>
  - <span style="color: #66cc66;">&quot;infrastructure_mutation&quot;</span>
<span style="color: cyan; font-weight: 600;">idempotent</span>: <span style="color: magenta; font-weight: 600;">false</span>
<span style="color: cyan; font-weight: 600;">unsafe</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">timeout</span>: <span style="color: yellow;">300</span>

<span style="color: cyan; font-weight: 600;">resource_slots</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: repo
    <span style="color: cyan; font-weight: 600;">resource_type</span>: git-checkout
    <span style="color: cyan; font-weight: 600;">access</span>: read_only
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Source repository for build artifacts&quot;</span>
    <span style="color: cyan; font-weight: 600;">binding</span>: contextual
  - <span style="color: cyan; font-weight: 600;">name</span>: cluster_config
    <span style="color: cyan; font-weight: 600;">resource_type</span>: fs-file
    <span style="color: cyan; font-weight: 600;">access</span>: read_only
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Kubernetes cluster configuration (kubeconfig)&quot;</span>
    <span style="color: cyan; font-weight: 600;">binding</span>: static
    <span style="color: cyan; font-weight: 600;">static_resource</span>: <span style="color: #66cc66;">local/staging-kubeconfig</span>

<span style="color: cyan; font-weight: 600;">lifecycle</span>:
  <span style="color: cyan; font-weight: 600;">activate</span>: |
    def activate(context):
        import subprocess
        result = subprocess.run([&quot;kubectl&quot;, &quot;cluster-info&quot;], capture_output=True, text=True)
        if result.returncode != 0:
            raise RuntimeError(&quot;Cannot connect to Kubernetes cluster&quot;)
        return {&quot;cluster&quot;: &quot;connected&quot;}
  <span style="color: cyan; font-weight: 600;">deactivate</span>: |
    def deactivate(context):
        pass<span style="opacity: 0.7;">  # No cleanup needed</span>
</code></pre></div>

---

**Example 5: API Compatibility Checker (Medium)**

A tool that validates API backward compatibility:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># validate-api-compat.yaml</span>
<span style="opacity: 0.7;"># Register: agents tool add --config validate-api-compat.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/validate-api-compat</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Validate that API changes maintain backward compatibility with existing clients&quot;</span>

<span style="color: cyan; font-weight: 600;">source</span>: custom
<span style="color: cyan; font-weight: 600;">code</span>: |
  import subprocess, json

  def run(input_data):
      spec_path = input_data.get(&quot;spec_path&quot;, &quot;openapi.yaml&quot;)
      base_branch = input_data.get(&quot;base_branch&quot;, &quot;main&quot;)

<span style="opacity: 0.7;">      # Get the base spec from the main branch</span>
      base_result = subprocess.run(
          [&quot;git&quot;, &quot;show&quot;, f&quot;{base_branch}:{spec_path}&quot;],
          capture_output=True, text=True
      )
      if base_result.returncode != 0:
          return {&quot;compatible&quot;: True, &quot;reason&quot;: &quot;No base spec found (new API)&quot;, &quot;changes&quot;: []}

<span style="opacity: 0.7;">      # Run OpenAPI diff</span>
      diff_result = subprocess.run(
          [&quot;oasdiff&quot;, &quot;breaking&quot;, &quot;<span style="color: cyan;">--format</span>&quot;, &quot;json&quot;,
           <span style="color: #66cc66;">&quot;--base&quot;, &quot;/dev/stdin&quot;, &quot;--revision&quot;, spec_path],</span>
          input=base_result.stdout,
          capture_output=True, text=True
      )

      if diff_result.returncode == 0:
          return {&quot;compatible&quot;: True, &quot;changes&quot;: [], &quot;reason&quot;: &quot;No breaking changes&quot;}

      <span style="color: cyan; font-weight: 600;">try</span>:
          breaking = json.loads(diff_result.stdout)
      except json.JSONDecodeError:
          breaking = [{&quot;description&quot;: diff_result.stdout}]

      return {
          <span style="color: cyan; font-weight: 600;">&quot;compatible&quot;</span>: False,
          <span style="color: cyan; font-weight: 600;">&quot;changes&quot;</span>: breaking,
          <span style="color: cyan; font-weight: 600;">&quot;reason&quot;</span>: f&quot;Found {len(breaking)} breaking change(s)&quot;
      }

<span style="color: cyan; font-weight: 600;">input_schema</span>:
  <span style="color: cyan; font-weight: 600;">type</span>: object
  <span style="color: cyan; font-weight: 600;">properties</span>:
    <span style="color: cyan; font-weight: 600;">spec_path</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
      <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">&quot;openapi.yaml&quot;</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Path to the OpenAPI specification file&quot;</span>
    <span style="color: cyan; font-weight: 600;">base_branch</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: string
      <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">&quot;main&quot;</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Branch to compare against for backward compatibility&quot;</span>
  <span style="color: cyan; font-weight: 600;">required</span>: []

<span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: magenta; font-weight: 600;">false</span>
<span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: magenta; font-weight: 600;">false</span>
<span style="color: cyan; font-weight: 600;">idempotent</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">timeout</span>: <span style="color: yellow;">60</span>

<span style="color: cyan; font-weight: 600;">resource_slots</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: repo
    <span style="color: cyan; font-weight: 600;">resource_type</span>: git-checkout
    <span style="color: cyan; font-weight: 600;">access</span>: read_only
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Git repository containing the API spec&quot;</span>
    <span style="color: cyan; font-weight: 600;">binding</span>: contextual
</code></pre></div>

---

### Validation Configuration Files

Validation configuration files define Validations — a specialized subtype of Tool. A Validation YAML file uses the **same format** as a Tool YAML file, with an additional `validation` block containing the validation-specific metadata. Because Validation extends Tool, all tool fields (`name`, `description`, `source`, `code`, `input_schema`, `output_schema`, capability metadata, resource bindings, lifecycle hooks) are available and behave identically. Validations are registered via `agents validation add --config <file>`.

**Read-only enforcement**: Validations are always read-only. The `writes` and `checkpointable` fields are always forced to `false` regardless of what the YAML file specifies — if a validation YAML includes `writes: true` or `checkpointable: true`, these values are silently overridden to `false` at registration time. Because this is enforced, it is idiomatic to omit `read_only`, `writes`, and `checkpointable` from validation YAML files entirely (they are unnecessary). The examples below include `read_only: true` for documentation clarity, but it is not required.

**Shared namespace**: The `name` field in a validation YAML occupies the same namespace as tools. Registration will fail if a tool with the same name already exists.

#### Validation-Specific Fields

In addition to all fields from the Tool Configuration schema, a Validation YAML adds:

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `validation.mode` | string | `"required"` | `"required"` or `"informational"`. Required validations must pass for execution to proceed; informational validations report results without blocking. |
| `wraps` | string | (none) | Name of an existing registered Tool to wrap. When set, the Validation delegates execution to the wrapped Tool and passes its output through the `transform` function. Mutually exclusive with `source` and `code`. |
| `transform` | string | (none) | Python function that converts the wrapped Tool's output to the Validation return format. Required when `wraps` is set (unless the wrapped Tool already returns validation-format output). The function receives the Tool's output as its argument and must return `{ "passed": bool, ... }`. |
| `argument_mapping` | object | (none) | Dictionary mapping the wrapped Tool's input parameter names to either a Validation input parameter name (string) or a fixed literal value. When present, only mapped arguments are forwarded to the wrapped Tool. When absent, the Validation's input arguments are passed through unchanged. Only valid when `wraps` is set. |

When `wraps` is used, the `source` and `code` fields must be omitted — the Validation's implementation is the wrapped Tool plus the transform. The Validation inherits the wrapped Tool's `input_schema`, `resource_slots`, and `timeout` unless explicitly overridden. When the Validation defines a custom `input_schema`, an `argument_mapping` should be provided to specify how the Validation's inputs map to the wrapped Tool's expected inputs. See the **Tool Wrapping** subsection under Core Concepts > Validation for full semantics.

The output of a validation tool must conform to a structured JSON format:

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `passed` | boolean | Yes | Whether the validation passed (`true`) or failed (`false`). |
| `message` | string | No | Human-readable summary of the validation result. |
| `data` | object | No | Arbitrary structured data in any format the validation chooses to convey informational output about the result. |

#### Examples

**Example 1: Unit Test Validation (Required)**

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># validations/run-tests.yaml</span>
<span style="opacity: 0.7;"># Register: agents validation add --config validations/run-tests.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/run-tests</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Run unit tests with coverage and report pass/fail&quot;</span>

<span style="color: cyan; font-weight: 600;">source</span>: custom
<span style="color: cyan; font-weight: 600;">code</span>: |
  import subprocess, json
  def run(input_data):
      threshold = input_data.get(&quot;coverage_threshold&quot;, 80)
      result = subprocess.run(
          [&quot;pytest&quot;, &quot;--cov=src&quot;, f&quot;--cov-fail-under={threshold}&quot;, &quot;--tb=short&quot;, &quot;-q&quot;],
          capture_output=True, text=True
      )
      passed = result.returncode == 0
      return {
          &quot;passed&quot;: passed,
          &quot;message&quot;: &quot;All tests passed&quot; if passed else f&quot;Tests failed (exit code {result.returncode})&quot;,
          &quot;data&quot;: {
              &quot;stdout&quot;: result.stdout,
              &quot;stderr&quot;: result.stderr,
              &quot;returncode&quot;: result.returncode,
              &quot;coverage_threshold&quot;: threshold
          }
      }

<span style="color: cyan; font-weight: 600;">validation</span>:
  <span style="color: cyan; font-weight: 600;">mode</span>: required

<span style="color: cyan; font-weight: 600;">input_schema</span>:
  <span style="color: cyan; font-weight: 600;">type</span>: object
  <span style="color: cyan; font-weight: 600;">properties</span>:
    <span style="color: cyan; font-weight: 600;">coverage_threshold</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: integer
      <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: yellow;">80</span>
      <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Minimum coverage percentage required&quot;</span>

<span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">idempotent</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">timeout</span>: <span style="color: yellow;">600</span>

<span style="color: cyan; font-weight: 600;">resource_slots</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: repo
    <span style="color: cyan; font-weight: 600;">resource_type</span>: git-checkout
    <span style="color: cyan; font-weight: 600;">access</span>: read_only
    <span style="color: cyan; font-weight: 600;">binding</span>: contextual
</code></pre></div>

---

**Example 2: Lint Check Validation (Required, Simple)**

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># validations/lint-check.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/lint-check</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Run linter and report pass/fail&quot;</span>

<span style="color: cyan; font-weight: 600;">source</span>: custom
<span style="color: cyan; font-weight: 600;">code</span>: |
  import subprocess
  def run(input_data):
      result = subprocess.run([&quot;ruff&quot;, &quot;check&quot;, &quot;.&quot;], capture_output=True, text=True)
      passed = result.returncode == 0
      return {
          &quot;passed&quot;: passed,
          &quot;message&quot;: &quot;Lint clean&quot; if passed else f&quot;Lint errors found&quot;,
          &quot;data&quot;: {&quot;stdout&quot;: result.stdout, &quot;stderr&quot;: result.stderr}
      }

<span style="color: cyan; font-weight: 600;">validation</span>:
  <span style="color: cyan; font-weight: 600;">mode</span>: required

<span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">idempotent</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">timeout</span>: <span style="color: yellow;">300</span>
</code></pre></div>

---

**Example 3: Bundle Size Check (Informational)**

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># validations/check-bundle-size.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/check-bundle-size</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Check bundle size (advisory — does not block execution)&quot;</span>

<span style="color: cyan; font-weight: 600;">source</span>: custom
<span style="color: cyan; font-weight: 600;">code</span>: |
  import subprocess, json
  def run(input_data):
      result = subprocess.run([&quot;node&quot;, &quot;scripts/check-bundle-size.js&quot;], capture_output=True, text=True)
      try:
          size_data = json.loads(result.stdout)
      except json.JSONDecodeError:
          size_data = {&quot;raw_output&quot;: result.stdout}
      passed = result.returncode == 0
      return {
          &quot;passed&quot;: passed,
          &quot;message&quot;: &quot;Bundle size within limits&quot; if passed else &quot;Bundle size exceeds advisory threshold&quot;,
          &quot;data&quot;: size_data
      }

<span style="color: cyan; font-weight: 600;">validation</span>:
  <span style="color: cyan; font-weight: 600;">mode</span>: informational

<span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">timeout</span>: <span style="color: yellow;">120</span>
</code></pre></div>

---

**Example 4: MCP-Backed Validation**

A validation that uses an MCP server to perform security scanning:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># validations/security-scan.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/security-scan</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Run security vulnerability scan via MCP&quot;</span>

<span style="color: cyan; font-weight: 600;">source</span>: mcp
<span style="color: cyan; font-weight: 600;">mcp_server</span>: <span style="color: #66cc66;">&quot;npx @security/mcp-scanner&quot;</span>
<span style="color: cyan; font-weight: 600;">mcp_tool_name</span>: scan_vulnerabilities

<span style="color: cyan; font-weight: 600;">validation</span>:
  <span style="color: cyan; font-weight: 600;">mode</span>: required

<span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">timeout</span>: <span style="color: yellow;">300</span>
</code></pre></div>

---

**Example 5: Wrapping an Existing Tool**

A validation that wraps an existing `local/run-tests` tool, reusing its implementation and interpreting its output as pass/fail. No test-running logic is duplicated — only the pass/fail interpretation is defined.

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># validations/tests-pass.yaml</span>
<span style="opacity: 0.7;"># Assumes local/run-tests is already registered as a Tool that runs</span>
<span style="opacity: 0.7;"># the test suite and returns {returncode, tests_run, tests_passed, ...}</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/tests-pass</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Validate that all unit tests pass (wraps local/run-tests)&quot;</span>

<span style="color: cyan; font-weight: 600;">wraps</span>: local/run-tests

<span style="color: cyan; font-weight: 600;">transform</span>: |
  def transform(tool_output):
      passed = tool_output.get(&quot;returncode&quot;) == 0
      tests_run = tool_output.get(&quot;tests_run&quot;, 0)
      tests_passed = tool_output.get(&quot;tests_passed&quot;, 0)
      return {
          &quot;passed&quot;: passed,
          &quot;message&quot;: f&quot;{tests_passed}/{tests_run} tests passed&quot; if passed
                     else f&quot;{tests_run - tests_passed} tests failed&quot;,
          &quot;data&quot;: tool_output
      }

<span style="color: cyan; font-weight: 600;">validation</span>:
  <span style="color: cyan; font-weight: 600;">mode</span>: required

<span style="color: cyan; font-weight: 600;">timeout</span>: <span style="color: yellow;">600</span>
</code></pre></div>

Note: `source`, `code`, `input_schema`, and `resource_slots` are omitted — they are inherited from the wrapped `local/run-tests` tool. Only the `transform`, `validation.mode`, and optional overrides (like `timeout`) are needed. If the Validation defines a custom `input_schema`, an `argument_mapping` should also be provided to map the Validation's inputs to the wrapped Tool's expected inputs.

---

**Example 6: Wrapping with Different Interpretation (Informational)**

A second validation wrapping the same tool but extracting a different signal — coverage threshold — as an advisory check:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># validations/coverage-check.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/coverage-check</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Check test coverage exceeds threshold (advisory)&quot;</span>

<span style="color: cyan; font-weight: 600;">wraps</span>: local/run-tests

<span style="color: cyan; font-weight: 600;">transform</span>: |
  def transform(tool_output):
      coverage = tool_output.get(&quot;coverage_percent&quot;, 0)
      threshold = 80
      return {
          &quot;passed&quot;: coverage >= threshold,
          &quot;message&quot;: f&quot;Coverage: {coverage:.1f}% (threshold: {threshold}%)&quot;,
          &quot;data&quot;: {
              &quot;coverage_percent&quot;: coverage,
              &quot;threshold&quot;: threshold,
              &quot;above_threshold&quot;: coverage >= threshold
          }
      }

<span style="color: cyan; font-weight: 600;">validation</span>:
  <span style="color: cyan; font-weight: 600;">mode</span>: informational
</code></pre></div>

---

### Resource Type Configuration Files

Resource type configuration files define custom resource type schemas that extend the built-in resource types (`git-checkout`, `git`, `fs-mount`, `fs-directory`, etc.). A resource type defines what CLI arguments `agents resource add <type>` accepts, whether instances are physical or virtual, allowed child/parent types, auto-discovery behavior, sandbox strategy, and handler implementation. Custom types are registered via `agents resource type add --config <file>`.

#### JSON Schema

The following is the formal [JSON Schema](https://json-schema.org/) definition for resource type configuration files.

<div class="highlight"><pre><code>
{
  <span style="color: cyan; font-weight: 600;">&quot;$schema&quot;</span>: <span style="color: #66cc66;">&quot;https://json-schema.org/draft/2020-12/schema&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;$id&quot;</span>: <span style="color: #66cc66;">&quot;https://cleveragents.dev/schemas/resource-type-config.json&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;title&quot;</span>: <span style="color: #66cc66;">&quot;CleverAgents Resource Type Configuration&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Configuration file schema for defining custom resource types that extend the built-in resource types.&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;pattern&quot;</span>: <span style="color: #66cc66;">&quot;^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Fully qualified resource type name in &lt;namespace&gt;/&lt;name&gt; format.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Human-readable description of what this resource type represents.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;physical&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;true for physical types (concrete manifestations), false for virtual types (abstract identity linking equivalent physical resources).&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;user_addable&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whether users can create instances directly via &#x27;agents resource add &lt;type&gt;&#x27;.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;cli_args&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Arguments accepted by &#x27;agents resource add &lt;type&gt;&#x27;.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;$ref&quot;</span>: <span style="color: #66cc66;">&quot;#/$defs/cliArg&quot;</span>
      }
    },
    <span style="color: cyan; font-weight: 600;">&quot;child_types&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Resource types that can be children of this type.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;$ref&quot;</span>: <span style="color: #66cc66;">&quot;#/$defs/childType&quot;</span>
      }
    },
    <span style="color: cyan; font-weight: 600;">&quot;parent_types&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Resource types that can be parents of this type. If omitted, the resource can be top-level.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
        <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Parent resource type name.&quot;</span>
          },
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: {
            <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
            <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Description of the parent-child relationship from the child&#x27;s perspective.&quot;</span>
          }
        },
        <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;type&quot;</span>],
        <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
      }
    },
    <span style="color: cyan; font-weight: 600;">&quot;sandbox_strategy&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;git_worktree&quot;</span>, <span style="color: #66cc66;">&quot;copy_on_write&quot;</span>, <span style="color: #66cc66;">&quot;transaction_rollback&quot;</span>, <span style="color: #66cc66;">&quot;snapshot&quot;</span>, <span style="color: #66cc66;">&quot;none&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Sandbox strategy for instances of this type.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;handler&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;The Python handler class that implements resource operations.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;class&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Python class name that implements the resource handler interface.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;module&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Python module path where the handler class is defined.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;config&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Arbitrary configuration passed to the handler constructor.&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>
        }
      },
      <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;class&quot;</span>, <span style="color: #66cc66;">&quot;module&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;auto_discovery&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Controls automatic child resource discovery when a resource of this type is created.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;enabled&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whether auto-discovery runs when a resource of this type is created.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;scan_depth&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;integer&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: yellow;">3</span>,
          <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">1</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Maximum recursion depth for scanning.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;include_patterns&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Glob patterns for resources to discover.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;exclude_patterns&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Glob patterns for resources to skip during discovery.&quot;</span>
        }
      },
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;equivalence&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Equivalence criteria for virtual types. Only applicable when physical is false.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;criteria&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Fields used to determine equivalence (e.g., &#x27;content_hash&#x27;, &#x27;filename&#x27;, &#x27;permissions&#x27;, &#x27;url&#x27;).&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Human-readable description of the equivalence rule.&quot;</span>
        }
      },
      <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;criteria&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
    },
  },
  <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;name&quot;</span>, <span style="color: #66cc66;">&quot;description&quot;</span>, <span style="color: #66cc66;">&quot;physical&quot;</span>, <span style="color: #66cc66;">&quot;sandbox_strategy&quot;</span>, <span style="color: #66cc66;">&quot;handler&quot;</span>],
  <span style="color: cyan; font-weight: 600;">&quot;if&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;physical&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;const&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span> } }
  },
  <span style="color: cyan; font-weight: 600;">&quot;then&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;name&quot;</span>, <span style="color: #66cc66;">&quot;description&quot;</span>, <span style="color: #66cc66;">&quot;physical&quot;</span>, <span style="color: #66cc66;">&quot;sandbox_strategy&quot;</span>, <span style="color: #66cc66;">&quot;handler&quot;</span>, <span style="color: #66cc66;">&quot;equivalence&quot;</span>]
  },
  <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
  <span style="color: cyan; font-weight: 600;">&quot;$defs&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;cliArg&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;A CLI argument definition for &#x27;agents resource add &lt;type&gt;&#x27;.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Argument name. Becomes --&lt;name&gt; on the CLI.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;string&quot;</span>, <span style="color: #66cc66;">&quot;path&quot;</span>, <span style="color: #66cc66;">&quot;integer&quot;</span>, <span style="color: #66cc66;">&quot;boolean&quot;</span>, <span style="color: #66cc66;">&quot;url&quot;</span>],
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Argument type. &#x27;path&#x27; validates that the path exists; &#x27;url&#x27; validates URL format.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whether the argument must be provided.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Description shown in --help.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Default value when the argument is not provided.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;validation_pattern&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Regex pattern for validating string and url type arguments.&quot;</span>
        }
      },
      <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;name&quot;</span>, <span style="color: #66cc66;">&quot;type&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;childType&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;An allowed child resource type relationship.&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Child resource type name.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;auto_discover&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whether children of this type are automatically created when the parent resource is registered.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;manual_link&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whether manual &#x27;agents resource link-child&#x27; is allowed for this relationship.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Description of the parent-child relationship.&quot;</span>
        },
        <span style="color: cyan; font-weight: 600;">&quot;max_count&quot;</span>: {
          <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: [<span style="color: #66cc66;">&quot;integer&quot;</span>, <span style="color: #66cc66;">&quot;null&quot;</span>],
          <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">1</span>,
          <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Maximum number of children of this type. null or omitted means unlimited.&quot;</span>
        }
      },
      <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;type&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
    }
  }
}
</code></pre></div>

#### Informal YAML Schema

The following annotated YAML provides an easier-to-read overview of the same schema defined formally above. It is **not** a validatable schema — it uses informal annotations to describe the structure. Refer to the JSON Schema above for the authoritative, machine-validatable definition.

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># ─── Resource Type Identity ─────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">&lt;namespace&gt;/&lt;name&gt;</span><span style="opacity: 0.7;">            # Fully qualified resource type name (required)</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">               # Human-readable description (required)</span>

<span style="opacity: 0.7;"># ─── Type Classification ────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">physical</span>: <span style="color: magenta; font-weight: 600;">true</span><span style="opacity: 0.7;">                      # Whether instances are physical or virtual (required)</span>
<span style="opacity: 0.7;">                                    # Physical: a specific, concrete manifestation (this file at this path)</span>
<span style="opacity: 0.7;">                                    # Virtual: an abstract identity linking equivalent physical resources</span>
<span style="color: cyan; font-weight: 600;">user_addable</span>: <span style="color: magenta; font-weight: 600;">true</span><span style="opacity: 0.7;">                  # Whether users can create instances directly (optional, default: true)</span>

<span style="opacity: 0.7;"># ─── CLI Arguments ──────────────────────────────────────────────────</span>
<span style="opacity: 0.7;"># Define the arguments accepted by `agents resource add &lt;type&gt;`.</span>
<span style="color: cyan; font-weight: 600;">cli_args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                  # Argument name (becomes --&lt;name&gt; on CLI) (required)</span>
    <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: magenta;">string | path | integer | boolean | url</span><span style="opacity: 0.7;">  # Argument type (required)</span>
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">true</span><span style="opacity: 0.7;">                  # Whether the argument is required (optional, default: false)</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">           # Description shown in help text (optional)</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">&lt;value&gt;</span><span style="opacity: 0.7;">                # Default value (optional)</span>
    <span style="color: cyan; font-weight: 600;">validation_pattern</span>: <span style="color: #66cc66;">&lt;regex&gt;</span><span style="opacity: 0.7;">     # Regex validation for string/url types (optional)</span>

<span style="opacity: 0.7;"># ─── Parent/Child Type Relationships ────────────────────────────────</span>
<span style="opacity: 0.7;"># Define which resource types can be children of this type.</span>
<span style="color: cyan; font-weight: 600;">child_types</span>:
  - <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                  # Child resource type name (required)</span>
    <span style="color: cyan; font-weight: 600;">auto_discover</span>: <span style="color: magenta; font-weight: 600;">true</span><span style="opacity: 0.7;">             # Automatically create children when parent is created (optional, default: false)</span>
    <span style="color: cyan; font-weight: 600;">manual_link</span>: <span style="color: magenta; font-weight: 600;">true</span><span style="opacity: 0.7;">               # Allow manual parent-child linking (optional, default: true)</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">           # Description of the relationship (optional)</span>
    <span style="color: cyan; font-weight: 600;">max_count</span>: <span style="color: #66cc66;">&lt;integer&gt;</span><span style="opacity: 0.7;">            # Maximum number of children of this type (optional, null = unlimited)</span>

<span style="opacity: 0.7;"># Define which resource types can be parents of this type.</span>
<span style="color: cyan; font-weight: 600;">parent_types</span>:
  - <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                  # Parent resource type name (required)</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">           # Description of the relationship (optional)</span>
<span style="opacity: 0.7;"># If parent_types is omitted, the resource can be top-level (no parent required).</span>

<span style="opacity: 0.7;"># ─── Sandbox Strategy ──────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">sandbox_strategy</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">          # Sandbox strategy for instances of this type (required)</span>
<span style="opacity: 0.7;">                                    # Built-in strategies: &quot;git_worktree&quot;, &quot;copy_on_write&quot;,</span>
<span style="opacity: 0.7;">                                    # &quot;transaction_rollback&quot;, &quot;snapshot&quot;, &quot;none&quot;</span>

<span style="opacity: 0.7;"># ─── Handler Implementation ────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">handler</span>:
  <span style="color: cyan; font-weight: 600;">class</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                   # Python class implementing the resource handler (required)</span>
  <span style="color: cyan; font-weight: 600;">module</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                  # Python module path (required)</span>
  <span style="color: cyan; font-weight: 600;">config</span>: {}<span style="opacity: 0.7;">                        # Handler-specific configuration (optional)</span>

<span style="opacity: 0.7;"># ─── Auto-Discovery Configuration ──────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">auto_discovery</span>:
  <span style="color: cyan; font-weight: 600;">enabled</span>: <span style="color: magenta; font-weight: 600;">true</span><span style="opacity: 0.7;">                     # Whether child auto-discovery runs on creation (optional, default: true)</span>
  <span style="color: cyan; font-weight: 600;">scan_depth</span>: <span style="color: #66cc66;">&lt;integer&gt;</span><span style="opacity: 0.7;">             # Max depth for recursive scanning (optional, default: 3)</span>
  <span style="color: cyan; font-weight: 600;">include_patterns</span>:                 # Glob patterns for resources to auto-discover (optional)
    - <span style="color: #66cc66;">&lt;string&gt;</span>
  <span style="color: cyan; font-weight: 600;">exclude_patterns</span>:                 # Glob patterns to exclude from auto-discovery (optional)
    - <span style="color: #66cc66;">&lt;string&gt;</span>

<span style="opacity: 0.7;"># ─── Virtual Type Configuration ─────────────────────────────────────</span>
<span style="opacity: 0.7;"># Only applicable when physical: false (virtual types).</span>
<span style="color: cyan; font-weight: 600;">equivalence</span>:
  <span style="color: cyan; font-weight: 600;">criteria</span>:                         # Fields used to determine equivalence (required for virtual)
    - <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">                      # e.g. &quot;content_hash&quot;, &quot;filename&quot;, &quot;permissions&quot;, &quot;url&quot;</span>
  <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">             # Human-readable description of the equivalence rule (optional)</span>
</code></pre></div>

#### Structure Reference

**Top-Level Fields**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Fully qualified resource type name in `<namespace>/<name>` format. This value is used as the resource type's registered name. |
| `description` | string | Yes | Human-readable description of what this resource type represents. |
| `physical` | boolean | Yes | `true` for physical types (concrete manifestations), `false` for virtual types (abstract identity linking equivalent physical resources). |
| `user_addable` | boolean | No | Whether users can create instances directly via `agents resource add <type>`. Default: `true`. When `false`, instances are only created via auto-discovery as children of other resources. |
| `sandbox_strategy` | string | Yes | The sandbox strategy used when executing within this resource type. |
| `handler` | object | Yes | The Python handler class that implements resource operations. |

**CLI Argument Fields (`cli_args[]`)**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Argument name. Becomes `--<name>` on the CLI. |
| `type` | string | Yes | Argument type: `string`, `path`, `integer`, `boolean`, `url`. The `path` type validates that the path exists; `url` type validates URL format. |
| `required` | boolean | No | Whether the argument must be provided. Default: `false`. |
| `description` | string | No | Description shown in `--help` and `agents resource type show`. |
| `default` | any | No | Default value when the argument is not provided. |
| `validation_pattern` | string | No | Regex pattern for validating `string` and `url` type arguments. |

**Child Type Fields (`child_types[]`)**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `type` | string | Yes | Name of the allowed child resource type (e.g., `fs-directory`, `svn-file`). |
| `auto_discover` | boolean | No | Whether children of this type are automatically created when the parent resource is registered. Default: `false`. |
| `manual_link` | boolean | No | Whether manual `agents resource link-child` is allowed for this relationship. Default: `true`. |
| `description` | string | No | Description of the parent-child relationship. |
| `max_count` | integer | No | Maximum number of children of this type. `null` or omitted means unlimited. |

**Parent Type Fields (`parent_types[]`)**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `type` | string | Yes | Name of the allowed parent resource type. |
| `description` | string | No | Description of the parent-child relationship from the child's perspective. |

**Handler Fields (`handler`)**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `class` | string | Yes | Python class name that implements the resource handler interface. |
| `module` | string | Yes | Python module path where the handler class is defined. |
| `config` | object | No | Arbitrary configuration passed to the handler constructor. |

**Auto-Discovery Fields (`auto_discovery`)**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `enabled` | boolean | No | Whether auto-discovery runs when a resource of this type is created. Default: `true`. |
| `scan_depth` | integer | No | Maximum recursion depth for scanning. Default: `3`. |
| `include_patterns` | list | No | Glob patterns for resources to discover. |
| `exclude_patterns` | list | No | Glob patterns for resources to skip during discovery. |

**Equivalence Fields (`equivalence`) — Virtual Types Only**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `criteria` | list | Yes (virtual) | Fields used to determine whether two physical resources are equivalent. Common criteria: `content_hash`, `filename`, `permissions`, `url`, `commit_hash`, `tree_hash`. |
| `description` | string | No | Human-readable description of the equivalence rule. |

**Built-in Sandbox Strategies**

| Strategy | Description |
|----------|-------------|
| `git_worktree` | Creates a git worktree for isolated execution. Changes are committed to a branch and merged on apply. |
| `copy_on_write` | Creates a CoW copy of the resource. Changes are applied by replacing the original. |
| `transaction_rollback` | Wraps operations in a database transaction. Rolled back on failure, committed on apply. |
| `snapshot` | Takes a full snapshot before execution. Restored on rollback. |
| `none` | No sandbox. Changes are applied directly. Use only for read-only or idempotent operations. |

#### Examples

**Example 1: Simple SVN Repository Type (Simple)**

A custom resource type for Subversion repositories:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># svn-type.yaml</span>
<span style="opacity: 0.7;"># Register: agents resource type add --config svn-type.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/svn</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;A Subversion (SVN) repository checkout&quot;</span>

<span style="color: cyan; font-weight: 600;">physical</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">user_addable</span>: <span style="color: magenta; font-weight: 600;">true</span>

<span style="color: cyan; font-weight: 600;">cli_args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: url
    <span style="color: cyan; font-weight: 600;">type</span>: url
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;SVN repository URL&quot;</span>
    <span style="color: cyan; font-weight: 600;">validation_pattern</span>: <span style="color: #66cc66;">&quot;^svn(\\+ssh)?://.*|^https?://.*&quot;</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: checkout-path
    <span style="color: cyan; font-weight: 600;">type</span>: path
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Local checkout directory&quot;</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: revision
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Specific revision to checkout&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">&quot;HEAD&quot;</span>

<span style="color: cyan; font-weight: 600;">child_types</span>:
  - <span style="color: cyan; font-weight: 600;">type</span>: fs-directory
    <span style="color: cyan; font-weight: 600;">auto_discover</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Working copy directory tree&quot;</span>
  - <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: #66cc66;">local/svn-revision</span>
    <span style="color: cyan; font-weight: 600;">auto_discover</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;SVN revision history&quot;</span>

<span style="color: cyan; font-weight: 600;">sandbox_strategy</span>: copy_on_write

<span style="color: cyan; font-weight: 600;">handler</span>:
  <span style="color: cyan; font-weight: 600;">class</span>: SVNHandler
  <span style="color: cyan; font-weight: 600;">module</span>: cleveragents.resources.handlers.svn
  <span style="color: cyan; font-weight: 600;">config</span>:
    <span style="color: cyan; font-weight: 600;">svn_binary</span>: <span style="color: #66cc66;">&quot;svn&quot;</span>
    <span style="color: cyan; font-weight: 600;">trust_server_cert</span>: <span style="color: magenta; font-weight: 600;">true</span>

<span style="color: cyan; font-weight: 600;">auto_discovery</span>:
  <span style="color: cyan; font-weight: 600;">enabled</span>: <span style="color: magenta; font-weight: 600;">true</span>
  <span style="color: cyan; font-weight: 600;">scan_depth</span>: <span style="color: yellow;">2</span>
  <span style="color: cyan; font-weight: 600;">exclude_patterns</span>:
    - <span style="color: #66cc66;">&quot;**/.svn/**&quot;</span>
</code></pre></div>

Usage: `agents resource add local/svn local/legacy-repo --url svn://svn.example.com/trunk --checkout-path /repos/legacy`

---

**Example 2: S3 Bucket Resource Type (Medium)**

A resource type for Amazon S3 buckets with prefix-based child discovery:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># s3-bucket-type.yaml</span>
<span style="opacity: 0.7;"># Register: agents resource type add --config s3-bucket-type.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/s3-bucket</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;An Amazon S3 bucket with prefix-based object organization&quot;</span>

<span style="color: cyan; font-weight: 600;">physical</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">user_addable</span>: <span style="color: magenta; font-weight: 600;">true</span>

<span style="color: cyan; font-weight: 600;">cli_args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: bucket
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;S3 bucket name&quot;</span>
    <span style="color: cyan; font-weight: 600;">validation_pattern</span>: <span style="color: #66cc66;">&quot;^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$&quot;</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: region
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;AWS region&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">&quot;us-east-1&quot;</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: prefix
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Key prefix to scope resource to a &#x27;subdirectory&#x27;&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">&quot;&quot;</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: profile
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;AWS CLI profile name&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">&quot;default&quot;</span>

<span style="color: cyan; font-weight: 600;">child_types</span>:
  - <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: #66cc66;">local/s3-prefix</span>
    <span style="color: cyan; font-weight: 600;">auto_discover</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;S3 key prefixes (virtual directories)&quot;</span>
    <span style="color: cyan; font-weight: 600;">max_count</span>: <span style="color: yellow;">1000</span>
  - <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: #66cc66;">local/s3-object</span>
    <span style="color: cyan; font-weight: 600;">auto_discover</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;S3 objects (files)&quot;</span>

<span style="color: cyan; font-weight: 600;">sandbox_strategy</span>: copy_on_write

<span style="color: cyan; font-weight: 600;">handler</span>:
  <span style="color: cyan; font-weight: 600;">class</span>: S3BucketHandler
  <span style="color: cyan; font-weight: 600;">module</span>: cleveragents.resources.handlers.s3
  <span style="color: cyan; font-weight: 600;">config</span>:
    <span style="color: cyan; font-weight: 600;">max_object_size</span>: <span style="color: yellow;">104857600</span><span style="opacity: 0.7;">  # 100 MB</span>
    <span style="color: cyan; font-weight: 600;">default_acl</span>: <span style="color: #66cc66;">&quot;private&quot;</span>

<span style="color: cyan; font-weight: 600;">auto_discovery</span>:
  <span style="color: cyan; font-weight: 600;">enabled</span>: <span style="color: magenta; font-weight: 600;">true</span>
  <span style="color: cyan; font-weight: 600;">scan_depth</span>: <span style="color: yellow;">3</span>
  <span style="color: cyan; font-weight: 600;">include_patterns</span>:
    - <span style="color: #66cc66;">&quot;**/*.json&quot;</span>
    - <span style="color: #66cc66;">&quot;**/*.yaml&quot;</span>
    - <span style="color: #66cc66;">&quot;**/*.yml&quot;</span>
    - <span style="color: #66cc66;">&quot;**/*.py&quot;</span>
    - <span style="color: #66cc66;">&quot;**/*.sql&quot;</span>
  <span style="color: cyan; font-weight: 600;">exclude_patterns</span>:
    - <span style="color: #66cc66;">&quot;**/*.log&quot;</span>
    - <span style="color: #66cc66;">&quot;**/*.tmp&quot;</span>
    - <span style="color: #66cc66;">&quot;**/node_modules/**&quot;</span>
</code></pre></div>

---

**Example 3: Database Resource Type (Medium)**

A resource type for relational databases:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># database-type.yaml</span>
<span style="opacity: 0.7;"># Register: agents resource type add --config database-type.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/database</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;A relational database (PostgreSQL, MySQL, SQLite)&quot;</span>

<span style="color: cyan; font-weight: 600;">physical</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">user_addable</span>: <span style="color: magenta; font-weight: 600;">true</span>

<span style="color: cyan; font-weight: 600;">cli_args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: connection-string
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Database connection string (e.g., postgresql://user:pass@host/db)&quot;</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: engine
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Database engine&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">&quot;postgresql&quot;</span>
    <span style="color: cyan; font-weight: 600;">validation_pattern</span>: <span style="color: #66cc66;">&quot;^(postgresql|mysql|sqlite|mssql)$&quot;</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: read-only
    <span style="color: cyan; font-weight: 600;">type</span>: boolean
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Connect in read-only mode&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: magenta; font-weight: 600;">false</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: schema
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Database schema to scope to&quot;</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">&quot;public&quot;</span>

<span style="color: cyan; font-weight: 600;">child_types</span>:
  - <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: #66cc66;">local/db-table</span>
    <span style="color: cyan; font-weight: 600;">auto_discover</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Database tables&quot;</span>
  - <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: #66cc66;">local/db-view</span>
    <span style="color: cyan; font-weight: 600;">auto_discover</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Database views&quot;</span>
  - <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: #66cc66;">local/db-migration</span>
    <span style="color: cyan; font-weight: 600;">auto_discover</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">manual_link</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Migration scripts linked to this database&quot;</span>

<span style="color: cyan; font-weight: 600;">parent_types</span>:
  - <span style="color: cyan; font-weight: 600;">type</span>: git-checkout
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Repository containing the application that owns this database&quot;</span>

<span style="color: cyan; font-weight: 600;">sandbox_strategy</span>: transaction_rollback

<span style="color: cyan; font-weight: 600;">handler</span>:
  <span style="color: cyan; font-weight: 600;">class</span>: DatabaseHandler
  <span style="color: cyan; font-weight: 600;">module</span>: cleveragents.resources.handlers.database
  <span style="color: cyan; font-weight: 600;">config</span>:
    <span style="color: cyan; font-weight: 600;">connection_pool_size</span>: <span style="color: yellow;">5</span>
    <span style="color: cyan; font-weight: 600;">statement_timeout</span>: <span style="color: yellow;">30000</span><span style="opacity: 0.7;">  # 30 seconds</span>
    <span style="color: cyan; font-weight: 600;">log_queries</span>: <span style="color: magenta; font-weight: 600;">true</span>

<span style="color: cyan; font-weight: 600;">auto_discovery</span>:
  <span style="color: cyan; font-weight: 600;">enabled</span>: <span style="color: magenta; font-weight: 600;">true</span>
  <span style="color: cyan; font-weight: 600;">scan_depth</span>: <span style="color: yellow;">1</span>
</code></pre></div>

---

**Example 4: Virtual File Type (Simple)**

A virtual resource type that links equivalent physical files across repositories:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># virtual-config-file-type.yaml</span>
<span style="opacity: 0.7;"># Register: agents resource type add --config virtual-config-file-type.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/config-file</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Virtual type linking equivalent configuration files across repositories&quot;</span>

<span style="color: cyan; font-weight: 600;">physical</span>: <span style="color: magenta; font-weight: 600;">false</span>
<span style="color: cyan; font-weight: 600;">user_addable</span>: <span style="color: magenta; font-weight: 600;">false</span>

<span style="color: cyan; font-weight: 600;">child_types</span>:
  - <span style="color: cyan; font-weight: 600;">type</span>: fs-file
    <span style="color: cyan; font-weight: 600;">auto_discover</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">manual_link</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Physical file instances&quot;</span>
  - <span style="color: cyan; font-weight: 600;">type</span>: git-tree-entry
    <span style="color: cyan; font-weight: 600;">auto_discover</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">manual_link</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Git tree entries representing the same config file&quot;</span>

<span style="color: cyan; font-weight: 600;">sandbox_strategy</span>: none

<span style="color: cyan; font-weight: 600;">handler</span>:
  <span style="color: cyan; font-weight: 600;">class</span>: VirtualConfigFileHandler
  <span style="color: cyan; font-weight: 600;">module</span>: cleveragents.resources.handlers.virtual_config
  <span style="color: cyan; font-weight: 600;">config</span>:
    <span style="color: cyan; font-weight: 600;">track_content_drift</span>: <span style="color: magenta; font-weight: 600;">true</span>

<span style="color: cyan; font-weight: 600;">equivalence</span>:
  <span style="color: cyan; font-weight: 600;">criteria</span>:
    - content_hash
    - filename
  <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Two physical resources represent the same config file when they share the same filename and content hash&quot;</span>
</code></pre></div>

---

**Example 5: Docker Registry Resource Type (Complex)**

A resource type for Docker container registries with full auto-discovery and lifecycle hooks:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># docker-registry-type.yaml</span>
<span style="opacity: 0.7;"># Register: agents resource type add --config docker-registry-type.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/docker-registry</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;A Docker container registry with image and tag discovery&quot;</span>

<span style="color: cyan; font-weight: 600;">physical</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">user_addable</span>: <span style="color: magenta; font-weight: 600;">true</span>

<span style="color: cyan; font-weight: 600;">cli_args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: registry-url
    <span style="color: cyan; font-weight: 600;">type</span>: url
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Docker registry URL (e.g., registry.example.com, ghcr.io/org)&quot;</span>
    <span style="color: cyan; font-weight: 600;">validation_pattern</span>: <span style="color: #66cc66;">&quot;^[a-zA-Z0-9][a-zA-Z0-9.-]+(:[0-9]+)?(/[a-zA-Z0-9._-]+)*$&quot;</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: username
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Registry username for authentication&quot;</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: password-env
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Environment variable name containing the registry password&quot;</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: namespace
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: magenta; font-weight: 600;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Image namespace or organization filter&quot;</span>

<span style="color: cyan; font-weight: 600;">child_types</span>:
  - <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: #66cc66;">local/docker-image</span>
    <span style="color: cyan; font-weight: 600;">auto_discover</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Docker images in the registry&quot;</span>
    <span style="color: cyan; font-weight: 600;">max_count</span>: <span style="color: yellow;">500</span>
  - <span style="color: cyan; font-weight: 600;">type</span>: <span style="color: #66cc66;">local/docker-tag</span>
    <span style="color: cyan; font-weight: 600;">auto_discover</span>: <span style="color: magenta; font-weight: 600;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Image tags&quot;</span>

<span style="color: cyan; font-weight: 600;">sandbox_strategy</span>: none

<span style="color: cyan; font-weight: 600;">handler</span>:
  <span style="color: cyan; font-weight: 600;">class</span>: DockerRegistryHandler
  <span style="color: cyan; font-weight: 600;">module</span>: cleveragents.resources.handlers.docker
  <span style="color: cyan; font-weight: 600;">config</span>:
    <span style="color: cyan; font-weight: 600;">api_version</span>: <span style="color: #66cc66;">&quot;v2&quot;</span>
    <span style="color: cyan; font-weight: 600;">page_size</span>: <span style="color: yellow;">100</span>
    <span style="color: cyan; font-weight: 600;">cache_ttl</span>: <span style="color: yellow;">300</span>

<span style="color: cyan; font-weight: 600;">auto_discovery</span>:
  <span style="color: cyan; font-weight: 600;">enabled</span>: <span style="color: magenta; font-weight: 600;">true</span>
  <span style="color: cyan; font-weight: 600;">scan_depth</span>: <span style="color: yellow;">2</span>
  <span style="color: cyan; font-weight: 600;">include_patterns</span>:
    - <span style="color: #66cc66;">&quot;**/latest&quot;</span>
    - <span style="color: #66cc66;">&quot;**/main&quot;</span>
    - <span style="color: #66cc66;">&quot;**/release-*&quot;</span>
  <span style="color: cyan; font-weight: 600;">exclude_patterns</span>:
    - <span style="color: #66cc66;">&quot;**/sha256:*&quot;</span>
     - <span style="color: #66cc66;">&quot;**/*-dirty&quot;</span>
</code></pre></div>

---

### Context View Configuration

Context views control how project resources are filtered and presented to actors during different plan phases. They are managed via `agents project context set` and its associated CLI flags, but can also be defined declaratively in YAML for portability and version control.

#### JSON Schema

The following is the formal [JSON Schema](https://json-schema.org/) definition for context view configuration files.

<div class="highlight"><pre><code>
{
  <span style="color: cyan; font-weight: 600;">&quot;$schema&quot;</span>: <span style="color: #66cc66;">&quot;https://json-schema.org/draft/2020-12/schema&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;$id&quot;</span>: <span style="color: #66cc66;">&quot;https://cleveragents.dev/schemas/context-view-config.json&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;title&quot;</span>: <span style="color: #66cc66;">&quot;CleverAgents Context View Configuration&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Configuration file schema for defining context views that control how project resources are filtered and presented to actors during plan phases.&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;project&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;pattern&quot;</span>: <span style="color: #66cc66;">&quot;^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Fully qualified project name this view applies to.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;view&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;default&quot;</span>, <span style="color: #66cc66;">&quot;strategize&quot;</span>, <span style="color: #66cc66;">&quot;execute&quot;</span>, <span style="color: #66cc66;">&quot;apply&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Phase view. &#x27;default&#x27; is the fallback for all phases; phase-specific views override &#x27;default&#x27;.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;include_resources&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Whitelist of resource names to include. When specified, only these resources provide context.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;exclude_resources&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Blacklist of resource names to exclude. Applied after include_resources.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;include_paths&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Glob patterns for file paths to include. When specified, only matching files are included.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;exclude_paths&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Glob patterns for file paths to exclude. Applied after include_paths.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;hot_max_tokens&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: [<span style="color: #66cc66;">&quot;integer&quot;</span>, <span style="color: #66cc66;">&quot;null&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">1</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Soft cap on the number of tokens in hot (immediate) context. null means no soft cap.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;warm_max_decisions&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;integer&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">1</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Maximum number of decisions retained in warm context.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;cold_max_decisions&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;integer&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">1</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Maximum number of decisions retained in cold context.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;query_limit&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;integer&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: yellow;">20</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">1</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Maximum number of retrieval results per query against the cold tier.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;max_file_size&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;integer&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: yellow;">1048576</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">1</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Maximum individual file size in bytes that will be included in context. Default: 1 MB.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;max_total_size&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;integer&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: yellow;">52428800</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">1</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Maximum aggregate size in bytes across all included files. Default: 50 MB.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;summarize&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;When true, large context segments are automatically summarized rather than excluded.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;summary_max_tokens&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;integer&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">1</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Maximum tokens for each generated summary. Only applies when summarize is true.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;strategy&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;array&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;items&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span> },
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Ordered list of ACMS context strategies to use for this view. Overrides the global strategy list. Valid built-in values: simple-keyword, semantic-embedding, breadth-depth-navigator, arce, temporal-archaeology, plan-decision-context.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;default_breadth&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;integer&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: yellow;">2</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Default number of hops from focus nodes in the UKO graph for context expansion. 0 = focus nodes only.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;default_depth&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;SIGNATURE&quot;</span>, <span style="color: #66cc66;">&quot;SUMMARY&quot;</span>, <span style="color: #66cc66;">&quot;STUB&quot;</span>, <span style="color: #66cc66;">&quot;FULL&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: #66cc66;">&quot;SUMMARY&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Default detail level for context fragments. SIGNATURE = declarations only; SUMMARY = condensed overview; STUB = signatures + key logic; FULL = complete content.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;depth_gradient&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
        <span style="color: cyan; font-weight: 600;">&quot;0&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;SIGNATURE&quot;</span>, <span style="color: #66cc66;">&quot;SUMMARY&quot;</span>, <span style="color: #66cc66;">&quot;STUB&quot;</span>, <span style="color: #66cc66;">&quot;FULL&quot;</span>] },
        <span style="color: cyan; font-weight: 600;">&quot;1&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;SIGNATURE&quot;</span>, <span style="color: #66cc66;">&quot;SUMMARY&quot;</span>, <span style="color: #66cc66;">&quot;STUB&quot;</span>, <span style="color: #66cc66;">&quot;FULL&quot;</span>] },
        <span style="color: cyan; font-weight: 600;">&quot;2&quot;</span>: { <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>, <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;SIGNATURE&quot;</span>, <span style="color: #66cc66;">&quot;SUMMARY&quot;</span>, <span style="color: #66cc66;">&quot;STUB&quot;</span>, <span style="color: #66cc66;">&quot;FULL&quot;</span>] }
      },
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Per-hop detail level overrides. Key is the hop distance (0 = focus node), value is the DetailLevel. Hops not listed use default_depth.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;skeleton_ratio&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;number&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: yellow;">0.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;maximum&quot;</span>: <span style="color: yellow;">1.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: yellow;">0.15</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Fraction of the context budget reserved for inherited plan skeleton context. 0.0 = no skeleton inheritance; 1.0 = all budget to skeleton.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;temporal_scope&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;enum&quot;</span>: [<span style="color: #66cc66;">&quot;current&quot;</span>, <span style="color: #66cc66;">&quot;recent&quot;</span>, <span style="color: #66cc66;">&quot;all&quot;</span>],
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: #66cc66;">&quot;current&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Temporal scope for UKO node resolution. 'current' = only isCurrent nodes; 'recent' = current + nodes valid within warm retention window; 'all' = include historical versions.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;auto_refresh&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;default&quot;</span>: <span style="color: magenta; font-weight: 600;">true</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;When true, the ACMS automatically re-assembles context when the available budget changes by more than the refresh threshold (default 30%). When false, context is only assembled on explicit request.&quot;</span>
    }
  },
  <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [<span style="color: #66cc66;">&quot;project&quot;</span>, <span style="color: #66cc66;">&quot;view&quot;</span>],
  <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
}
</code></pre></div>

#### Informal YAML Schema

The following annotated YAML provides an easier-to-read overview of the same schema defined formally above. It is **not** a validatable schema — it uses informal annotations to describe the structure. Refer to the JSON Schema above for the authoritative, machine-validatable definition.

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># ─── Context View Identity ──────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">project</span>: <span style="color: #66cc66;">&lt;namespace&gt;/&lt;name&gt;</span><span style="opacity: 0.7;">         # Project this context view applies to (required)</span>
<span style="color: cyan; font-weight: 600;">view</span>: <span style="color: magenta;">default | strategize | execute | apply</span><span style="opacity: 0.7;">  # Which phase view (required)</span>

<span style="opacity: 0.7;"># ─── Resource Filtering ─────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">include_resources</span>:                  # Resources to include (whitelist, optional)
  - <span style="color: #66cc66;">&lt;resource_name&gt;</span>
<span style="color: cyan; font-weight: 600;">exclude_resources</span>:                  # Resources to exclude (blacklist, optional)
  - <span style="color: #66cc66;">&lt;resource_name&gt;</span>

<span style="opacity: 0.7;"># ─── Path Filtering ─────────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">include_paths</span>:                      # Glob patterns for files to include (optional)
  - <span style="color: #66cc66;">&quot;src/**/*.py&quot;</span>
  - <span style="color: #66cc66;">&quot;tests/**/*.py&quot;</span>
<span style="color: cyan; font-weight: 600;">exclude_paths</span>:                      # Glob patterns for files to exclude (optional)
  - <span style="color: #66cc66;">&quot;**/node_modules/**&quot;</span>
  - <span style="color: #66cc66;">&quot;**/__pycache__/**&quot;</span>
  - <span style="color: #66cc66;">&quot;**/.git/**&quot;</span>
  - <span style="color: #66cc66;">&quot;**/dist/**&quot;</span>

<span style="opacity: 0.7;"># ─── Token and Size Budgets ─────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">hot_max_tokens</span>: <span style="color: #66cc66;">&lt;integer&gt;</span><span style="opacity: 0.7;">           # Soft cap on hot context tokens (optional, null = no limit)</span>
<span style="color: cyan; font-weight: 600;">warm_max_decisions</span>: <span style="color: #66cc66;">&lt;integer&gt;</span><span style="opacity: 0.7;">       # Max decisions in warm context (optional)</span>
<span style="color: cyan; font-weight: 600;">cold_max_decisions</span>: <span style="color: #66cc66;">&lt;integer&gt;</span><span style="opacity: 0.7;">       # Max decisions in cold context (optional)</span>
<span style="color: cyan; font-weight: 600;">query_limit</span>: <span style="color: #66cc66;">&lt;integer&gt;</span><span style="opacity: 0.7;">              # Max retrieval results per query (optional, default: 20)</span>
<span style="color: cyan; font-weight: 600;">max_file_size</span>: <span style="color: #66cc66;">&lt;integer&gt;</span><span style="opacity: 0.7;">            # Max file size in bytes to include (optional, default: 1048576)</span>
<span style="color: cyan; font-weight: 600;">max_total_size</span>: <span style="color: #66cc66;">&lt;integer&gt;</span><span style="opacity: 0.7;">           # Max total size across all included files (optional, default: 52428800)</span>

<span style="opacity: 0.7;"># ─── Summarization ──────────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">summarize</span>: <span style="color: magenta; font-weight: 600;">true</span><span style="opacity: 0.7;">                     # Enable summarization for large context segments (optional)</span>
<span style="color: cyan; font-weight: 600;">summary_max_tokens</span>: <span style="color: #66cc66;">&lt;integer&gt;</span><span style="opacity: 0.7;">       # Token limit for generated summaries (optional)</span>

<span style="opacity: 0.7;"># ─── ACMS Strategy & Context Assembly ───────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">strategy</span>:                            # ACMS strategies to use (optional, overrides global list)
  - <span style="color: #66cc66;">simple-keyword</span>
  - <span style="color: #66cc66;">semantic-embedding</span>
  - <span style="color: #66cc66;">breadth-depth-navigator</span>
<span style="color: cyan; font-weight: 600;">default_breadth</span>: <span style="color: #66cc66;">&lt;integer&gt;</span><span style="opacity: 0.7;">          # Default hop count for UKO graph expansion (optional, default: 2)</span>
<span style="color: cyan; font-weight: 600;">default_depth</span>: <span style="color: magenta;">SIGNATURE | SUMMARY | STUB | FULL</span><span style="opacity: 0.7;">  # Default detail level (optional, default: SUMMARY)</span>
<span style="color: cyan; font-weight: 600;">depth_gradient</span>:                     # Per-hop detail level overrides (optional)
  <span style="color: cyan; font-weight: 600;">0</span>: <span style="color: #66cc66;">FULL</span><span style="opacity: 0.7;">                            # Focus nodes get full content</span>
  <span style="color: cyan; font-weight: 600;">1</span>: <span style="color: #66cc66;">SUMMARY</span><span style="opacity: 0.7;">                         # 1-hop neighbors get summaries</span>
  <span style="color: cyan; font-weight: 600;">2</span>: <span style="color: #66cc66;">SIGNATURE</span><span style="opacity: 0.7;">                       # 2-hop neighbors get signatures only</span>
<span style="color: cyan; font-weight: 600;">skeleton_ratio</span>: <span style="color: #66cc66;">&lt;float&gt;</span><span style="opacity: 0.7;">             # Fraction of budget for inherited plan skeleton (optional, default: 0.15)</span>
<span style="color: cyan; font-weight: 600;">temporal_scope</span>: <span style="color: magenta;">current | recent | all</span><span style="opacity: 0.7;">  # Temporal scope for UKO node resolution (optional, default: current)</span>
<span style="color: cyan; font-weight: 600;">auto_refresh</span>: <span style="color: magenta; font-weight: 600;">true</span><span style="opacity: 0.7;">                   # Auto re-assemble context on budget change (optional, default: true)</span>
</code></pre></div>

#### Structure Reference

**Top-Level Fields**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `project` | string | Yes | Fully qualified project name this view applies to. |
| `view` | string | Yes | Phase view: `default` (fallback for all phases), `strategize`, `execute`, or `apply`. Phase-specific views override the `default` view. |
| `include_resources` | list | No | Whitelist of resource names to include. When specified, only these resources provide context. |
| `exclude_resources` | list | No | Blacklist of resource names to exclude. Applied after `include_resources`. |
| `include_paths` | list | No | Glob patterns for file paths to include. When specified, only matching files are included. |
| `exclude_paths` | list | No | Glob patterns for file paths to exclude. Applied after `include_paths`. |
| `hot_max_tokens` | integer | No | Soft cap on the number of tokens in hot (immediate) context. The effective limit is the lesser of this value and the actor's hard context window limit. When `null`, no soft cap is applied. |
| `warm_max_decisions` | integer | No | Maximum number of decisions retained in warm context (recent decisions available for reference). |
| `cold_max_decisions` | integer | No | Maximum number of decisions retained in cold context (older decisions queryable via search). |
| `query_limit` | integer | No | Maximum number of retrieval results per query against the cold tier. Default: 20. |
| `max_file_size` | integer | No | Maximum individual file size in bytes that will be included in context. Files exceeding this are either excluded or summarized. Default: 1 MB (1,048,576). |
| `max_total_size` | integer | No | Maximum aggregate size in bytes across all included files. Default: 50 MB (52,428,800). |
| `summarize` | boolean | No | When `true`, large context segments are automatically summarized rather than excluded. Default: `false`. |
| `summary_max_tokens` | integer | No | Maximum tokens for each generated summary. Only applies when `summarize` is `true`. |
| `strategy` | list | No | Ordered list of ACMS context strategies to use for this view. Overrides the global `context.strategies.enabled` list. Built-in strategies: `simple-keyword`, `semantic-embedding`, `breadth-depth-navigator`, `arce`, `temporal-archaeology`, `plan-decision-context`. |
| `default_breadth` | integer | No | Default number of hops from focus nodes in the UKO graph for context expansion. `0` = focus nodes only. Default: `2`. |
| `default_depth` | string | No | Default detail level for context fragments: `SIGNATURE`, `SUMMARY`, `STUB`, or `FULL`. Default: `SUMMARY`. |
| `depth_gradient` | object | No | Per-hop detail level overrides. Keys are hop distances (0 = focus node), values are `DetailLevel` enums. Hops not listed use `default_depth`. |
| `skeleton_ratio` | number | No | Fraction of context budget reserved for inherited plan skeleton context. Range: 0.0–1.0. Default: `0.15`. |
| `temporal_scope` | string | No | Temporal scope for UKO node resolution: `current` (only `isCurrent` nodes), `recent` (current + warm retention window), `all` (include historical versions). Default: `current`. |
| `auto_refresh` | boolean | No | When `true`, ACMS automatically re-assembles context when the available budget changes by more than the refresh threshold. Default: `true`. |

**Context Tiers**

CleverAgents uses a three-tier context architecture:

| Tier | Description | Controlled By |
|------|-------------|---------------|
| **Hot** | Immediate context sent in the LLM prompt. Includes active files, recent changes, and current task description. | `hot_max_tokens`, `include_paths`, `exclude_paths` |
| **Warm** | Recent decisions and intermediate results. Available for reference but not always in the prompt. | `warm_max_decisions` |
| **Cold** | Historical decisions, full project index, and archived artifacts. Queryable via retrieval. | `cold_max_decisions`, `query_limit` |

**View Resolution Order**

When a plan enters a phase, the context view is resolved as follows:
1. Check for a phase-specific view (e.g., `strategize`).
2. Fall back to the `default` view.
3. Fall back to system defaults (include all resources, no path filtering, default budgets).

#### Examples

**Example 1: Basic Default View (Simple)**

A default context view with minimal filtering:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># context-default.yaml</span>
<span style="opacity: 0.7;"># Apply: agents project context set --view default --include-path &quot;src/**&quot; \</span>
<span style="opacity: 0.7;">#        --exclude-path &quot;**/node_modules/**&quot; local/api-service</span>
<span style="opacity: 0.7;"># Or import this file and apply via the CLI.</span>

<span style="color: cyan; font-weight: 600;">project</span>: <span style="color: #66cc66;">local/api-service</span>
<span style="color: cyan; font-weight: 600;">view</span>: default

<span style="color: cyan; font-weight: 600;">exclude_paths</span>:
  - <span style="color: #66cc66;">&quot;**/node_modules/**&quot;</span>
  - <span style="color: #66cc66;">&quot;**/__pycache__/**&quot;</span>
  - <span style="color: #66cc66;">&quot;**/.git/**&quot;</span>

<span style="color: cyan; font-weight: 600;">max_file_size</span>: <span style="color: yellow;">1048576</span><span style="opacity: 0.7;">   # 1 MB</span>
</code></pre></div>

---

**Example 2: Strategize-Optimized View (Medium)**

A focused view for the Strategize phase that limits context to essential architecture files:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># context-strategize.yaml</span>

<span style="color: cyan; font-weight: 600;">project</span>: <span style="color: #66cc66;">local/api-service</span>
<span style="color: cyan; font-weight: 600;">view</span>: strategize

<span style="color: cyan; font-weight: 600;">include_resources</span>:
  - <span style="color: #66cc66;">local/api-repo</span>

<span style="color: cyan; font-weight: 600;">exclude_resources</span>:
  - <span style="color: #66cc66;">local/staging-db</span>

<span style="color: cyan; font-weight: 600;">include_paths</span>:
  - <span style="color: #66cc66;">&quot;src/**/*.py&quot;</span>
  - <span style="color: #66cc66;">&quot;docs/architecture/**&quot;</span>
  - <span style="color: #66cc66;">&quot;README.md&quot;</span>
  - <span style="color: #66cc66;">&quot;pyproject.toml&quot;</span>

<span style="color: cyan; font-weight: 600;">exclude_paths</span>:
  - <span style="color: #66cc66;">&quot;**/node_modules/**&quot;</span>
  - <span style="color: #66cc66;">&quot;**/test_fixtures/**&quot;</span>
  - <span style="color: #66cc66;">&quot;**/__pycache__/**&quot;</span>
  - <span style="color: #66cc66;">&quot;**/migrations/**&quot;</span>

<span style="color: cyan; font-weight: 600;">hot_max_tokens</span>: <span style="color: yellow;">12000</span>
<span style="color: cyan; font-weight: 600;">warm_max_decisions</span>: <span style="color: yellow;">50</span>
<span style="color: cyan; font-weight: 600;">cold_max_decisions</span>: <span style="color: yellow;">200</span>
<span style="color: cyan; font-weight: 600;">query_limit</span>: <span style="color: yellow;">20</span>

<span style="color: cyan; font-weight: 600;">max_file_size</span>: <span style="color: yellow;">524288</span><span style="opacity: 0.7;">     # 512 KB</span>
<span style="color: cyan; font-weight: 600;">max_total_size</span>: <span style="color: yellow;">10485760</span><span style="opacity: 0.7;">  # 10 MB</span>

<span style="color: cyan; font-weight: 600;">summarize</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">summary_max_tokens</span>: <span style="color: yellow;">800</span>
</code></pre></div>

This view keeps the Strategize phase focused on source code and architecture docs, limits hot context to 12K tokens, and enables summarization for files that exceed the size limits.

---

**Example 3: Execute-Phase View with Full Resources (Medium)**

An execution view with broader access for implementing changes:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># context-execute.yaml</span>

<span style="color: cyan; font-weight: 600;">project</span>: <span style="color: #66cc66;">local/api-service</span>
<span style="color: cyan; font-weight: 600;">view</span>: execute

<span style="color: cyan; font-weight: 600;">include_resources</span>:
  - <span style="color: #66cc66;">local/api-repo</span>
  - <span style="color: #66cc66;">local/staging-db</span>

<span style="color: cyan; font-weight: 600;">include_paths</span>:
  - <span style="color: #66cc66;">&quot;src/**&quot;</span>
  - <span style="color: #66cc66;">&quot;tests/**&quot;</span>
  - <span style="color: #66cc66;">&quot;config/**&quot;</span>
  - <span style="color: #66cc66;">&quot;scripts/**&quot;</span>
  - <span style="color: #66cc66;">&quot;Makefile&quot;</span>
  - <span style="color: #66cc66;">&quot;pyproject.toml&quot;</span>
  - <span style="color: #66cc66;">&quot;requirements*.txt&quot;</span>

<span style="color: cyan; font-weight: 600;">exclude_paths</span>:
  - <span style="color: #66cc66;">&quot;**/node_modules/**&quot;</span>
  - <span style="color: #66cc66;">&quot;**/__pycache__/**&quot;</span>
  - <span style="color: #66cc66;">&quot;**/dist/**&quot;</span>
  - <span style="color: #66cc66;">&quot;**/*.pyc&quot;</span>

<span style="color: cyan; font-weight: 600;">hot_max_tokens</span>: <span style="color: yellow;">24000</span>
<span style="color: cyan; font-weight: 600;">warm_max_decisions</span>: <span style="color: yellow;">100</span>
<span style="color: cyan; font-weight: 600;">cold_max_decisions</span>: <span style="color: yellow;">500</span>
<span style="color: cyan; font-weight: 600;">query_limit</span>: <span style="color: yellow;">30</span>

<span style="color: cyan; font-weight: 600;">max_file_size</span>: <span style="color: yellow;">2097152</span><span style="opacity: 0.7;">     # 2 MB</span>
<span style="color: cyan; font-weight: 600;">max_total_size</span>: <span style="color: yellow;">104857600</span><span style="opacity: 0.7;">  # 100 MB</span>

<span style="color: cyan; font-weight: 600;">summarize</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">summary_max_tokens</span>: <span style="color: yellow;">1200</span>
</code></pre></div>

---

**Example 4: Apply-Phase Minimal View (Simple)**

A minimal view for the Apply phase, focused only on changed files and validation:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># context-apply.yaml</span>

<span style="color: cyan; font-weight: 600;">project</span>: <span style="color: #66cc66;">local/api-service</span>
<span style="color: cyan; font-weight: 600;">view</span>: apply

<span style="color: cyan; font-weight: 600;">include_paths</span>:
  - <span style="color: #66cc66;">&quot;src/**&quot;</span>
  - <span style="color: #66cc66;">&quot;tests/**&quot;</span>

<span style="color: cyan; font-weight: 600;">exclude_paths</span>:
  - <span style="color: #66cc66;">&quot;**/__pycache__/**&quot;</span>

<span style="color: cyan; font-weight: 600;">hot_max_tokens</span>: <span style="color: yellow;">8000</span>
<span style="color: cyan; font-weight: 600;">warm_max_decisions</span>: <span style="color: yellow;">20</span>
<span style="color: cyan; font-weight: 600;">cold_max_decisions</span>: <span style="color: yellow;">50</span>

<span style="color: cyan; font-weight: 600;">summarize</span>: <span style="color: magenta; font-weight: 600;">false</span>
</code></pre></div>

---

**Example 5: Large Monorepo View with Aggressive Filtering (Complex)**

A context view designed for a large monorepo where careful filtering is essential:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># context-monorepo-strategize.yaml</span>

<span style="color: cyan; font-weight: 600;">project</span>: <span style="color: #66cc66;">local/platform</span>
<span style="color: cyan; font-weight: 600;">view</span>: strategize

<span style="color: cyan; font-weight: 600;">include_resources</span>:
  - <span style="color: #66cc66;">local/platform-repo</span>

<span style="color: cyan; font-weight: 600;">include_paths</span>:
  - <span style="color: #66cc66;">&quot;packages/auth/**/*.ts&quot;</span>
  - <span style="color: #66cc66;">&quot;packages/auth/**/*.tsx&quot;</span>
  - <span style="color: #66cc66;">&quot;packages/shared/**/*.ts&quot;</span>
  - <span style="color: #66cc66;">&quot;packages/api-gateway/**/*.ts&quot;</span>
  - <span style="color: #66cc66;">&quot;docs/architecture/**&quot;</span>
  - <span style="color: #66cc66;">&quot;package.json&quot;</span>
  - <span style="color: #66cc66;">&quot;tsconfig.json&quot;</span>
  - <span style="color: #66cc66;">&quot;lerna.json&quot;</span>

<span style="color: cyan; font-weight: 600;">exclude_paths</span>:
  - <span style="color: #66cc66;">&quot;**/node_modules/**&quot;</span>
  - <span style="color: #66cc66;">&quot;**/dist/**&quot;</span>
  - <span style="color: #66cc66;">&quot;**/coverage/**&quot;</span>
  - <span style="color: #66cc66;">&quot;**/*.test.ts&quot;</span>
  - <span style="color: #66cc66;">&quot;**/*.spec.ts&quot;</span>
  - <span style="color: #66cc66;">&quot;**/*.stories.tsx&quot;</span>
  - <span style="color: #66cc66;">&quot;**/fixtures/**&quot;</span>
  - <span style="color: #66cc66;">&quot;**/__snapshots__/**&quot;</span>
  - <span style="color: #66cc66;">&quot;**/generated/**&quot;</span>

<span style="color: cyan; font-weight: 600;">hot_max_tokens</span>: <span style="color: yellow;">16000</span>
<span style="color: cyan; font-weight: 600;">warm_max_decisions</span>: <span style="color: yellow;">30</span>
<span style="color: cyan; font-weight: 600;">cold_max_decisions</span>: <span style="color: yellow;">150</span>
<span style="color: cyan; font-weight: 600;">query_limit</span>: <span style="color: yellow;">15</span>

<span style="color: cyan; font-weight: 600;">max_file_size</span>: <span style="color: yellow;">262144</span><span style="opacity: 0.7;">     # 256 KB - aggressive for a monorepo</span>
<span style="color: cyan; font-weight: 600;">max_total_size</span>: <span style="color: yellow;">5242880</span><span style="opacity: 0.7;">   # 5 MB</span>

<span style="color: cyan; font-weight: 600;">summarize</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">summary_max_tokens</span>: <span style="color: yellow;">600</span>
</code></pre></div>

This configuration is tailored for a TypeScript monorepo, focusing on specific packages and excluding generated code, tests, and build artifacts to keep context within manageable bounds.

---

### Automation Profile Configuration Files

Automation profile configuration files define named collections of **confidence thresholds** (floating-point values from 0.0 to 1.0) and boolean safety flags controlling which operations are automated vs. requiring human approval. Each threshold specifies the minimum confidence score at which the system proceeds automatically; below the threshold, the system drops to manual mode. A threshold of 0.0 means "always automatic" and 1.0 means "always manual." Built-in profiles (`manual`, `review`, `supervised`, `cautious`, `trusted`, `auto`, `ci`, `full-auto`) are always available. Custom profiles are registered via `agents automation-profile add --config <file>`.

#### JSON Schema

The following is the formal [JSON Schema](https://json-schema.org/) definition for automation profile configuration files.

<div class="highlight"><pre><code>
{
  <span style="color: cyan; font-weight: 600;">&quot;$schema&quot;</span>: <span style="color: #66cc66;">&quot;https://json-schema.org/draft/2020-12/schema&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;$id&quot;</span>: <span style="color: #66cc66;">&quot;https://cleveragents.dev/schemas/automation-profile-config.json&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;title&quot;</span>: <span style="color: #66cc66;">&quot;CleverAgents Automation Profile Configuration&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Configuration file schema for defining automation profiles — named collections of confidence thresholds (0.0-1.0) and boolean safety flags controlling which operations are automated vs. requiring human approval.&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;object&quot;</span>,
  <span style="color: cyan; font-weight: 600;">&quot;properties&quot;</span>: {
    <span style="color: cyan; font-weight: 600;">&quot;name&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;pattern&quot;</span>: <span style="color: #66cc66;">&quot;^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Fully qualified profile name in &lt;namespace&gt;/&lt;name&gt; format.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;string&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Human-readable description of the profile&#x27;s purpose and behavior.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;auto_strategize&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;number&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: magenta; font-weight: 600;">0.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;maximum&quot;</span>: <span style="color: magenta; font-weight: 600;">1.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Confidence threshold (0.0-1.0) for automatically transitioning from Action to Strategize. 0.0 = always automatic, 1.0 = always manual.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;auto_execute&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;number&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: magenta; font-weight: 600;">0.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;maximum&quot;</span>: <span style="color: magenta; font-weight: 600;">1.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Confidence threshold (0.0-1.0) for automatically transitioning from Strategize to Execute. 0.0 = always automatic, 1.0 = always manual.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;auto_apply&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;number&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: magenta; font-weight: 600;">0.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;maximum&quot;</span>: <span style="color: magenta; font-weight: 600;">1.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Confidence threshold (0.0-1.0) for automatically applying changes after execution completes. 0.0 = always automatic, 1.0 = always manual.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;auto_decisions_strategize&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;number&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: magenta; font-weight: 600;">0.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;maximum&quot;</span>: <span style="color: magenta; font-weight: 600;">1.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Confidence threshold (0.0-1.0) for autonomously making decisions during Strategize. 0.0 = always automatic, 1.0 = always manual.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;auto_decisions_execute&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;number&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: magenta; font-weight: 600;">0.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;maximum&quot;</span>: <span style="color: magenta; font-weight: 600;">1.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Confidence threshold (0.0-1.0) for autonomously making decisions during Execute. 0.0 = always automatic, 1.0 = always manual.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;auto_validation_fix&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;number&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: magenta; font-weight: 600;">0.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;maximum&quot;</span>: <span style="color: magenta; font-weight: 600;">1.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Confidence threshold (0.0-1.0) for automatically attempting to fix validation failures. 0.0 = always automatic, 1.0 = always manual.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;auto_strategy_revision&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;number&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: magenta; font-weight: 600;">0.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;maximum&quot;</span>: <span style="color: magenta; font-weight: 600;">1.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Confidence threshold (0.0-1.0) for automatically revising the strategy when execution reveals issues. 0.0 = always automatic, 1.0 = always manual.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;auto_retry_transient&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;number&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: magenta; font-weight: 600;">0.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;maximum&quot;</span>: <span style="color: magenta; font-weight: 600;">1.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Confidence threshold (0.0-1.0) for automatically retrying operations that fail due to transient errors. 0.0 = always automatic, 1.0 = always manual.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;auto_checkpoint_restore&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;number&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: magenta; font-weight: 600;">0.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;maximum&quot;</span>: <span style="color: magenta; font-weight: 600;">1.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Confidence threshold (0.0-1.0) for automatically restoring from the most recent checkpoint on failure. 0.0 = always automatic, 1.0 = always manual.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;auto_child_plans&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;number&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;minimum&quot;</span>: <span style="color: magenta; font-weight: 600;">0.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;maximum&quot;</span>: <span style="color: magenta; font-weight: 600;">1.0</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;Confidence threshold (0.0-1.0) for automatically spawning child plans decided during Strategize. 0.0 = always automatic, 1.0 = always manual.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;require_sandbox&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;When true, all write operations must execute within a sandbox. Execution fails if no sandbox strategy is available.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;require_checkpoints&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;When true, checkpoints must be created before any write operation, enabling rollback.&quot;</span>
    },
    <span style="color: cyan; font-weight: 600;">&quot;allow_unsafe_tools&quot;</span>: {
      <span style="color: cyan; font-weight: 600;">&quot;type&quot;</span>: <span style="color: #66cc66;">&quot;boolean&quot;</span>,
      <span style="color: cyan; font-weight: 600;">&quot;description&quot;</span>: <span style="color: #66cc66;">&quot;When true, tools flagged as unsafe can be invoked. When false, unsafe tool invocations are blocked.&quot;</span>
    }
  },
  <span style="color: cyan; font-weight: 600;">&quot;required&quot;</span>: [
    <span style="color: #66cc66;">&quot;name&quot;</span>,
    <span style="color: #66cc66;">&quot;description&quot;</span>,
    <span style="color: #66cc66;">&quot;auto_strategize&quot;</span>,
    <span style="color: #66cc66;">&quot;auto_execute&quot;</span>,
    <span style="color: #66cc66;">&quot;auto_apply&quot;</span>,
    <span style="color: #66cc66;">&quot;auto_decisions_strategize&quot;</span>,
    <span style="color: #66cc66;">&quot;auto_decisions_execute&quot;</span>,
    <span style="color: #66cc66;">&quot;auto_validation_fix&quot;</span>,
    <span style="color: #66cc66;">&quot;auto_strategy_revision&quot;</span>,
    <span style="color: #66cc66;">&quot;auto_retry_transient&quot;</span>,
    <span style="color: #66cc66;">&quot;auto_checkpoint_restore&quot;</span>,
    <span style="color: #66cc66;">&quot;auto_child_plans&quot;</span>,
    <span style="color: #66cc66;">&quot;require_sandbox&quot;</span>,
    <span style="color: #66cc66;">&quot;require_checkpoints&quot;</span>,
    <span style="color: #66cc66;">&quot;allow_unsafe_tools&quot;</span>
  ],
  <span style="color: cyan; font-weight: 600;">&quot;additionalProperties&quot;</span>: <span style="color: magenta; font-weight: 600;">false</span>
}
</code></pre></div>

#### Informal YAML Schema

The following annotated YAML provides an easier-to-read overview of the same schema defined formally above. It is **not** a validatable schema — it uses informal annotations to describe the structure. Refer to the JSON Schema above for the authoritative, machine-validatable definition.

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># ─── Profile Identity ───────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">&lt;namespace&gt;/&lt;name&gt;</span><span style="opacity: 0.7;">            # Fully qualified profile name (required)</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&lt;string&gt;</span><span style="opacity: 0.7;">               # Human-readable description (required)</span>

<span style="opacity: 0.7;"># ─── Phase Transition Thresholds ────────────────────────────────────</span>
<span style="opacity: 0.7;"># Confidence thresholds controlling phase transitions.</span>
<span style="opacity: 0.7;"># 0.0 = always automatic, 1.0 = always manual.</span>
<span style="color: cyan; font-weight: 600;">auto_strategize</span>: <span style="color: #66cc66;">&lt;float: 0.0–1.0&gt;</span><span style="opacity: 0.7;">          # Confidence threshold for Action → Strategize (required, 0.0=auto, 1.0=manual)</span>
<span style="color: cyan; font-weight: 600;">auto_execute</span>: <span style="color: #66cc66;">&lt;float: 0.0–1.0&gt;</span><span style="opacity: 0.7;">             # Confidence threshold for Strategize → Execute (required, 0.0=auto, 1.0=manual)</span>
<span style="color: cyan; font-weight: 600;">auto_apply</span>: <span style="color: #66cc66;">&lt;float: 0.0–1.0&gt;</span><span style="opacity: 0.7;">               # Confidence threshold for Execute → Apply (required, 0.0=auto, 1.0=manual)</span>

<span style="opacity: 0.7;"># ─── Decision Thresholds ────────────────────────────────────────────</span>
<span style="opacity: 0.7;"># Confidence thresholds controlling decisions within each phase.</span>
<span style="opacity: 0.7;"># 0.0 = always automatic, 1.0 = always manual.</span>
<span style="color: cyan; font-weight: 600;">auto_decisions_strategize</span>: <span style="color: #66cc66;">&lt;float: 0.0–1.0&gt;</span><span style="opacity: 0.7;">  # Confidence threshold for decisions during Strategize (required, 0.0=auto, 1.0=manual)</span>
<span style="color: cyan; font-weight: 600;">auto_decisions_execute</span>: <span style="color: #66cc66;">&lt;float: 0.0–1.0&gt;</span><span style="opacity: 0.7;">     # Confidence threshold for decisions during Execute (required, 0.0=auto, 1.0=manual)</span>

<span style="opacity: 0.7;"># ─── Self-Repair Thresholds ─────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">auto_validation_fix</span>: <span style="color: #66cc66;">&lt;float: 0.0–1.0&gt;</span><span style="opacity: 0.7;">      # Confidence threshold for auto-fixing validation failures (required, 0.0=auto, 1.0=manual)</span>
<span style="color: cyan; font-weight: 600;">auto_strategy_revision</span>: <span style="color: #66cc66;">&lt;float: 0.0–1.0&gt;</span><span style="opacity: 0.7;">   # Confidence threshold for auto-revising strategy (required, 0.0=auto, 1.0=manual)</span>
<span style="color: cyan; font-weight: 600;">auto_retry_transient</span>: <span style="color: #66cc66;">&lt;float: 0.0–1.0&gt;</span><span style="opacity: 0.7;">     # Confidence threshold for auto-retrying transient errors (required, 0.0=auto, 1.0=manual)</span>
<span style="color: cyan; font-weight: 600;">auto_checkpoint_restore</span>: <span style="color: #66cc66;">&lt;float: 0.0–1.0&gt;</span><span style="opacity: 0.7;">  # Confidence threshold for auto-restoring from checkpoints (required, 0.0=auto, 1.0=manual)</span>

<span style="opacity: 0.7;"># ─── Execution Control Thresholds ──────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">auto_child_plans</span>: <span style="color: #66cc66;">&lt;float: 0.0–1.0&gt;</span><span style="opacity: 0.7;">         # Confidence threshold for auto-spawning child plans (required, 0.0=auto, 1.0=manual)</span>

<span style="opacity: 0.7;"># ─── Safety Requirements ────────────────────────────────────────────</span>
<span style="color: cyan; font-weight: 600;">require_sandbox</span>: <span style="color: #66cc66;">&lt;boolean&gt;</span><span style="opacity: 0.7;">          # Require sandbox for all write operations (required)</span>
<span style="color: cyan; font-weight: 600;">require_checkpoints</span>: <span style="color: #66cc66;">&lt;boolean&gt;</span><span style="opacity: 0.7;">      # Require checkpoint creation before write operations (required)</span>
<span style="color: cyan; font-weight: 600;">allow_unsafe_tools</span>: <span style="color: #66cc66;">&lt;boolean&gt;</span><span style="opacity: 0.7;">       # Allow tools flagged as unsafe (required)</span>
</code></pre></div>

#### Structure Reference

**Top-Level Fields**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Fully qualified profile name. This value is used as the profile's registered name. |
| `description` | string | Yes | Human-readable description of the profile's purpose and behavior. |

**Phase Transition Thresholds**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `auto_strategize` | number (0.0–1.0) | Yes | Confidence threshold for transitioning from Action to Strategize. When computed confidence >= threshold, Strategize begins automatically. 0.0 = always automatic, 1.0 = always manual. |
| `auto_execute` | number (0.0–1.0) | Yes | Confidence threshold for transitioning from Strategize to Execute. When computed confidence >= threshold, Execute begins automatically. 0.0 = always automatic, 1.0 = always manual. |
| `auto_apply` | number (0.0–1.0) | Yes | Confidence threshold for transitioning from Execute to Apply. When computed confidence >= threshold, Apply begins automatically. 0.0 = always automatic, 1.0 = always manual. **A threshold of 0.0 means changes are committed without human review.** |

**Decision Automation Thresholds**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `auto_decisions_strategize` | number (0.0–1.0) | Yes | Confidence threshold for autonomous decision-making during Strategize. When computed confidence >= threshold, the strategy actor decides autonomously. 0.0 = always automatic, 1.0 = always manual. |
| `auto_decisions_execute` | number (0.0–1.0) | Yes | Confidence threshold for autonomous decision-making during Execute. When computed confidence >= threshold, the execution actor decides autonomously. 0.0 = always automatic, 1.0 = always manual. |

**Self-Repair Thresholds**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `auto_validation_fix` | number (0.0–1.0) | Yes | Confidence threshold for automatically fixing validation failures (e.g., failing tests, lint errors). When computed confidence >= threshold, fix is attempted automatically. 0.0 = always automatic, 1.0 = always manual. |
| `auto_strategy_revision` | number (0.0–1.0) | Yes | Confidence threshold for automatically revising the strategy when execution reveals issues. When computed confidence >= threshold, revision proceeds automatically. 0.0 = always automatic, 1.0 = always manual. |
| `auto_retry_transient` | number (0.0–1.0) | Yes | Confidence threshold for automatically retrying operations that fail due to transient errors (network timeouts, rate limits). When computed confidence >= threshold, retry proceeds automatically. 0.0 = always automatic, 1.0 = always manual. |
| `auto_checkpoint_restore` | number (0.0–1.0) | Yes | Confidence threshold for automatically restoring from the most recent checkpoint on failure. When computed confidence >= threshold, restore proceeds automatically. 0.0 = always automatic, 1.0 = always manual. |

**Execution Control Thresholds**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `auto_child_plans` | number (0.0–1.0) | Yes | Confidence threshold for automatically spawning child plans decided during Strategize. When computed confidence >= threshold, child plans spawn automatically during Execute. 0.0 = always automatic, 1.0 = always manual. |

**Safety Flags**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `require_sandbox` | boolean | Yes | When `true`, all write operations must execute within a sandbox (git worktree, copy-on-write, transaction). Execution fails if no sandbox strategy is available. |
| `require_checkpoints` | boolean | Yes | When `true`, checkpoints must be created before any write operation. This enables rollback. |
| `allow_unsafe_tools` | boolean | Yes | When `true`, tools flagged as `unsafe` can be invoked. When `false`, unsafe tool invocations are blocked. |

**Built-in Profile Reference**

| Threshold | `manual` | `review` | `supervised` | `cautious` | `trusted` | `auto` | `ci` | `full-auto` |
|-----------------|----------|----------|--------------|------------|-----------|--------|------|-------------|
| `auto_strat` | 1.0 | 0.0 | 0.0 | 0.7 | 0.0 | 0.0 | 0.0 | 0.0 |
| `auto_exec` | 1.0 | 0.0 | 1.0 | 0.7 | 0.0 | 0.0 | 0.0 | 0.0 |
| `auto_apply` | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 |
| `auto_dec_strat` | 1.0 | 1.0 | 0.0 | 0.6 | 0.0 | 0.0 | 0.0 | 0.0 |
| `auto_dec_exec` | 1.0 | 1.0 | 1.0 | 0.8 | 0.0 | 0.0 | 0.0 | 0.0 |
| `auto_val_fix` | 1.0 | 1.0 | 1.0 | 0.7 | 0.0 | 0.0 | 0.0 | 0.0 |
| `auto_strat_rev` | 1.0 | 1.0 | 1.0 | 0.8 | 1.0 | 0.0 | 0.0 | 0.0 |
| `auto_child` | 1.0 | 0.0 | 1.0 | 0.7 | 0.0 | 0.0 | 0.0 | 0.0 |
| `require_sandbox` | true | true | true | true | true | true | true | false |
| `allow_unsafe` | false | false | false | false | false | false | false | true |

#### Examples

**Example 1: Careful Autonomous Profile (Simple)**

A profile for autonomous execution with mandatory sandboxing and manual apply:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># careful-auto.yaml</span>
<span style="opacity: 0.7;"># Register: agents automation-profile add --config careful-auto.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/careful-auto</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Autonomous execution with mandatory sandbox and manual apply&quot;</span>

<span style="color: cyan; font-weight: 600;">auto_strategize</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_execute</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_apply</span>: <span style="color: yellow;">1.0</span>

<span style="color: cyan; font-weight: 600;">auto_decisions_strategize</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_decisions_execute</span>: <span style="color: yellow;">0.0</span>

<span style="color: cyan; font-weight: 600;">auto_validation_fix</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_strategy_revision</span>: <span style="color: yellow;">1.0</span>
<span style="color: cyan; font-weight: 600;">auto_retry_transient</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_checkpoint_restore</span>: <span style="color: yellow;">0.0</span>

<span style="color: cyan; font-weight: 600;">auto_child_plans</span>: <span style="color: yellow;">0.0</span>

<span style="color: cyan; font-weight: 600;">require_sandbox</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">require_checkpoints</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">allow_unsafe_tools</span>: <span style="color: magenta; font-weight: 600;">false</span>
</code></pre></div>

This is essentially the `auto` built-in profile but with `auto_checkpoint_restore` set to 0.0 (always automatic) for more aggressive self-repair.

---

**Example 2: CI/CD Pipeline Profile (Medium)**

A profile designed for automated CI/CD pipelines where everything runs autonomously:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># ci-pipeline.yaml</span>
<span style="opacity: 0.7;"># Register: agents automation-profile add --config ci-pipeline.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/ci-pipeline</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Full automation for CI/CD pipelines. All phases automated, sandbox required.&quot;</span>

<span style="color: cyan; font-weight: 600;">auto_strategize</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_execute</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_apply</span>: <span style="color: yellow;">0.0</span>

<span style="color: cyan; font-weight: 600;">auto_decisions_strategize</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_decisions_execute</span>: <span style="color: yellow;">0.0</span>

<span style="color: cyan; font-weight: 600;">auto_validation_fix</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_strategy_revision</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_retry_transient</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_checkpoint_restore</span>: <span style="color: yellow;">0.0</span>

<span style="color: cyan; font-weight: 600;">auto_child_plans</span>: <span style="color: yellow;">0.0</span>

<span style="color: cyan; font-weight: 600;">require_sandbox</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">require_checkpoints</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">allow_unsafe_tools</span>: <span style="color: magenta; font-weight: 600;">false</span>
</code></pre></div>

This profile is similar to `full-auto` but with mandatory sandboxing and checkpoints enabled — suitable for CI/CD environments where you want full automation but with safety nets.

---

**Example 3: Review-Heavy Profile (Medium)**

A profile for regulated environments where every decision must be reviewed:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># review-heavy.yaml</span>
<span style="opacity: 0.7;"># Register: agents automation-profile add --config review-heavy.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/review-heavy</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Maximum human oversight. Every decision and phase requires approval.&quot;</span>

<span style="color: cyan; font-weight: 600;">auto_strategize</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_execute</span>: <span style="color: yellow;">1.0</span>
<span style="color: cyan; font-weight: 600;">auto_apply</span>: <span style="color: yellow;">1.0</span>

<span style="color: cyan; font-weight: 600;">auto_decisions_strategize</span>: <span style="color: yellow;">1.0</span>
<span style="color: cyan; font-weight: 600;">auto_decisions_execute</span>: <span style="color: yellow;">1.0</span>

<span style="color: cyan; font-weight: 600;">auto_validation_fix</span>: <span style="color: yellow;">1.0</span>
<span style="color: cyan; font-weight: 600;">auto_strategy_revision</span>: <span style="color: yellow;">1.0</span>
<span style="color: cyan; font-weight: 600;">auto_retry_transient</span>: <span style="color: yellow;">1.0</span>
<span style="color: cyan; font-weight: 600;">auto_checkpoint_restore</span>: <span style="color: yellow;">1.0</span>

<span style="color: cyan; font-weight: 600;">auto_child_plans</span>: <span style="color: yellow;">1.0</span>

<span style="color: cyan; font-weight: 600;">require_sandbox</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">require_checkpoints</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">allow_unsafe_tools</span>: <span style="color: magenta; font-weight: 600;">false</span>
</code></pre></div>

This profile auto-starts strategize but requires human approval for every decision, every phase transition, and every child plan spawn. Useful in regulated industries (finance, healthcare) where audit trails and human review are mandatory.

---

**Example 4: Development Sandbox Profile (Simple)**

A fast-iteration profile for local development where safety is relaxed:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># dev-sandbox.yaml</span>
<span style="opacity: 0.7;"># Register: agents automation-profile add --config dev-sandbox.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/dev-sandbox</span>
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">&quot;Fast iteration for local development. Relaxed safety, auto execution.&quot;</span>

<span style="color: cyan; font-weight: 600;">auto_strategize</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_execute</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_apply</span>: <span style="color: yellow;">1.0</span>

<span style="color: cyan; font-weight: 600;">auto_decisions_strategize</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_decisions_execute</span>: <span style="color: yellow;">0.0</span>

<span style="color: cyan; font-weight: 600;">auto_validation_fix</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_strategy_revision</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_retry_transient</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_checkpoint_restore</span>: <span style="color: yellow;">0.0</span>

<span style="color: cyan; font-weight: 600;">auto_child_plans</span>: <span style="color: yellow;">0.0</span>

<span style="color: cyan; font-weight: 600;">require_sandbox</span>: <span style="color: magenta; font-weight: 600;">false</span>
<span style="color: cyan; font-weight: 600;">require_checkpoints</span>: <span style="color: magenta; font-weight: 600;">false</span>
<span style="color: cyan; font-weight: 600;">allow_unsafe_tools</span>: <span style="color: magenta; font-weight: 600;">true</span>
</code></pre></div>

This profile removes sandbox and checkpoint requirements for speed during local development. It still requires manual apply to prevent accidental commits. Unsafe tools are allowed for full flexibility.

---

**Example 5: Production Deployment Profile (Complex)**

A profile for production deployments combining autonomous execution with maximum safety:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># production-deploy.yaml</span>
<span style="opacity: 0.7;"># Register: agents automation-profile add --config production-deploy.yaml</span>

<span style="color: cyan; font-weight: 600;">name</span>: <span style="color: #66cc66;">local/production-deploy</span>
<span style="color: cyan; font-weight: 600;">description</span>: |
  Production deployment profile. Fully autonomous execution
  with maximum safety guarantees. All phases require sandbox
  and checkpoint. Apply requires manual approval. Strategy
  revision is enabled to adapt to deployment issues.

<span style="color: cyan; font-weight: 600;">auto_strategize</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_execute</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_apply</span>: <span style="color: yellow;">1.0</span>

<span style="color: cyan; font-weight: 600;">auto_decisions_strategize</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_decisions_execute</span>: <span style="color: yellow;">0.0</span>

<span style="color: cyan; font-weight: 600;">auto_validation_fix</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_strategy_revision</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_retry_transient</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_checkpoint_restore</span>: <span style="color: yellow;">0.0</span>

<span style="color: cyan; font-weight: 600;">auto_child_plans</span>: <span style="color: yellow;">0.0</span>

<span style="color: cyan; font-weight: 600;">require_sandbox</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">require_checkpoints</span>: <span style="color: magenta; font-weight: 600;">true</span>
<span style="color: cyan; font-weight: 600;">allow_unsafe_tools</span>: <span style="color: magenta; font-weight: 600;">false</span>
</code></pre></div>

## Workflow Examples

This section presents complete, end-to-end workflow examples showing how CleverAgents is used in practice. Each example starts from initial setup and walks through every command and decision point. The examples progress from simple single-action workflows to complex multi-project, multi-actor orchestrations.

### Example 1: Hello World — Fix a Single Bug

**Scenario**: A developer finds a bug in their Python web API where the `/health` endpoint returns a 500 error instead of 200 when the database connection is unavailable. They want CleverAgents to fix it with full human oversight.

**Complexity**: Beginner. Single project, single action, manual automation profile.

#### Step 1: Initialize Environment and Register Resources

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Initialize CleverAgents (first-time setup)</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> init <span style="color: cyan;">--yes</span>

╭─ Initialized ────────────────────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Data Dir:</span> /home/dev/.cleveragents (created)              │
│ <span style="color: #66cc66; font-weight: 600;">Config:</span> /home/dev/.cleveragents/config.toml              │
│ <span style="color: #66cc66; font-weight: 600;">Database:</span> initialized (schema v3)                        │
│ <span style="color: #66cc66; font-weight: 600;">Directories:</span> logs, cache, sessions, contexts             │
╰──────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Initialized (non-interactive)
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Register the git checkout as a resource</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add git-checkout local/api-repo \
    <span style="color: cyan;">--path</span> /home/dev/projects/api-service \
    <span style="color: cyan;">--branch</span> main

╭─ Resource ──────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/api-repo                                │
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXR1A1B2C3D4E5F6G7H8J9K0                      │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> git-checkout                                  │
│ <span style="color: #5599ff; font-weight: 600;">Physical/Virtual:</span> physical                          │
│ <span style="color: #66cc66; font-weight: 600;">Path:</span> /home/dev/projects/api-service                │
│ <span style="color: #5599ff; font-weight: 600;">Branch:</span> main                                        │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 09:15                           │
╰─────────────────────────────────────────────────────╯

╭─ Auto-discovered Children ─────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>               <span style="color: cyan; font-weight: 600;">Type</span>            <span style="color: cyan; font-weight: 600;">Status</span>                            │
│ <span style="opacity: 0.7;">───────────────  ──────────────  ─────────────────</span>                 │
│ 01HXR1A1B2C3…   git             <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│ 01HXR1A1B2C4…   git-remote      <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│ 01HXR1A1B2C5…   git-branch      <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│ 01HXR1A1B2C6…   fs-directory    <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│   + 32 git-commit resources                                        │
│   + 187 git-tree-entry resources                                   │
│   + 5 fs-directory + 41 fs-file                                    │
╰────────────────────────────────────────────────────────────────────╯

╭─ Capabilities ─────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Readable:</span> yes                  │
│ <span style="color: yellow; font-weight: 600;">Writable:</span> yes                  │
│ <span style="color: #66cc66; font-weight: 600;">Sandboxable:</span> yes               │
│ <span style="color: #66cc66; font-weight: 600;">Checkpointable:</span> yes            │
│ <span style="color: #5599ff; font-weight: 600;">Sandbox Strategy:</span> git_worktree │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource registered (270 child resources discovered)
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Create the project and link the resource</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project create \
    <span style="color: cyan;">--description</span> <span style="color: #66cc66;">"REST API service"</span> \
    <span style="color: cyan;">--resource</span> local/api-repo \
    local/api-service

╭─ Project Created ──────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/api-service                    │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> REST API service              │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> local                                │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 09:15                  │
╰────────────────────────────────────────────╯

╭─ Linked Resources ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>               <span style="color: cyan; font-weight: 600;">Type</span>          <span style="color: cyan; font-weight: 600;">Read-Only</span>               │
│ <span style="opacity: 0.7;">─────────────────  ──────────────  ─────────</span>             │
│ local/api-repo     git-checkout    no                   │
╰──────────────────────────────────────────────────────────╯

╭─ Defaults ──────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Sandbox:</span> git_worktree                   │
│ <span style="color: #66cc66; font-weight: 600;">Validations:</span> 0                          │
│ <span style="color: yellow; font-weight: 600;">Context Filters:</span> none                   │
│ <span style="color: magenta; font-weight: 600;">Automation Profile:</span> (inherits global)   │
╰─────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project created
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Register a required validation (tests must pass)</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation add \
    <span style="color: cyan;">--config</span> validations/unit-tests.yaml \
    <span style="color: cyan;">--required</span> \
    local/unit-tests

╭─ Validation Registered ─────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/unit-tests                                      │
│ <span style="color: #5599ff; font-weight: 600;">Command:</span> pytest tests/                                      │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Unit tests                                     │
│ <span style="color: #66cc66; font-weight: 600;">Mode:</span> required                                              │
│ <span style="color: yellow; font-weight: 600;">Timeout:</span> 300s (default)                                     │
╰─────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation registered

<span style="opacity: 0.7;"># Attach the validation to the project</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> local/api-service local/unit-tests

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached to project local/api-service
</code></pre></div>

#### Step 2: Create an Action

Create a file `actions/fix-bug.yaml`:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">name</span>: local/fix-bug
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Fix a reported bug in the codebase"</span>
<span style="color: cyan; font-weight: 600;">long_description</span>: |
  Analyze the bug description, locate the relevant code,
  implement a fix, and add or update tests to cover the fix.
<span style="color: cyan; font-weight: 600;">definition_of_done</span>: |
  - The described bug no longer reproduces
  - All existing tests pass
  - At least one new test covers the fixed behavior
  - No unrelated code is modified
<span style="color: cyan; font-weight: 600;">strategy_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">execution_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">reusable</span>: <span style="color: yellow;">true</span>
<span style="color: cyan; font-weight: 600;">state</span>: <span style="color: yellow;">available</span>
<span style="color: cyan; font-weight: 600;">args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: bug_description
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Description of the bug to fix"</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: affected_file
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"File path where the bug is suspected (optional hint)"</span>
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Register the action</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action create <span style="color: cyan;">--config</span> ./actions/fix-bug.yaml

╭─ Action Created ─────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/fix-bug                          │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> 01HXR1B1C2D3E4F5G6H7I8J9K0               │
│ <span style="color: yellow; font-weight: 600;">State:</span> available                             │
│ <span style="color: magenta; font-weight: 600;">Strategy Actor:</span> anthropic/claude-3.5-sonnet  │
│ <span style="color: magenta; font-weight: 600;">Execution Actor:</span> anthropic/claude-3.5-sonnet │
│ <span style="color: #66cc66; font-weight: 600;">Reusable:</span> yes                                │
│ <span style="color: #5599ff; font-weight: 600;">Read Only:</span> no                                │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 09:16                    │
╰──────────────────────────────────────────────╯

╭─ Definition of Done ──────────────────────────────────╮
│ - The described bug no longer reproduces              │
│ - All existing tests pass                             │
│ - At least one new test covers the fixed behavior     │
│ - No unrelated code is modified                       │
╰───────────────────────────────────────────────────────╯

╭─ Arguments ───────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>             <span style="color: cyan; font-weight: 600;">Type</span>    <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>                            │
│ <span style="opacity: 0.7;">───────────────  ──────  ────────  ──────────────────────────────────────</span> │
│ bug_description  string  yes       Description of the bug to fix          │
│ affected_file    string  no        File path where the bug is suspected   │
╰───────────────────────────────────────────────────────────────────────────╯

╭─ Automation ──────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> (inherits global)            │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> default                       │
╰───────────────────────────────────────╯

╭─ Usage ──────────────────────────────────────────────────────────────────╮
│ agents plan use local/fix-bug local/api-service                          │
│   <span style="color: cyan;">--arg</span> bug_description="..."                                            │
╰──────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Action created
</code></pre></div>

#### Step 3: Create and Execute a Plan

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Bind the action to the project with the manual profile for full oversight</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan use \
    <span style="color: cyan;">--automation-profile</span> manual \
    <span style="color: cyan;">--arg</span> bug_description=<span style="color: #66cc66;">"The /health endpoint returns HTTP 500 when the database \
connection is unavailable. It should return HTTP 200 with {\"status\": \"degraded\", \
\"database\": \"unavailable\"} instead of crashing."</span> \
    <span style="color: cyan;">--arg</span> affected_file=<span style="color: #66cc66;">"src/routes/health.py"</span> \
    local/fix-bug local/api-service

╭─ Plan Created ──────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan ID:</span> 01HXR1C1D2E3F4G5H6I7J8K9L0     │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> strategize                       │
│ <span style="color: magenta; font-weight: 600;">Action:</span> local/fix-bug                   │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/api-service              │
│ <span style="color: #66cc66; font-weight: 600;">Automation:</span> manual                      │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                              │
╰─────────────────────────────────────────╯

╭─ Inputs ──────────────────────────────────────────────────────────────╮
│ - bug_description="The /health endpoint returns HTTP 500 when the     │
│   database connection is unavailable. It should return HTTP 200 with  │
│   {\"status\": \"degraded\", \"database\": \"unavailable\"} instead   │
│   of crashing."                                                       │
│ - affected_file="src/routes/health.py"                                │
│ - automation_profile=manual                                           │
╰───────────────────────────────────────────────────────────────────────╯

╭─ Actors ──────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Strategy:</span> anthropic/claude-3.5-sonnet         │
│ <span style="color: magenta; font-weight: 600;">Execution:</span> anthropic/claude-3.5-sonnet        │
│ <span style="color: #5599ff; font-weight: 600;">Estimation:</span> (none)                            │
╰───────────────────────────────────────────────╯

╭─ Automation ──────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> manual                       │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> plan override                 │
│ <span style="color: #5599ff; font-weight: 600;">Read-Only:</span> no                         │
╰───────────────────────────────────────╯

╭─ Context ─────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Resources:</span> 1 (git-checkout)       │
│ <span style="color: #5599ff; font-weight: 600;">Indexed Files:</span> 41                 │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> strategize                  │
│ <span style="color: #5599ff; font-weight: 600;">Hot Token Budget:</span> 8,000           │
╰───────────────────────────────────╯

╭─ Next Steps ───────────────────────────────────────╮
│ - agents plan execute 01HXR1C1D2E3F4G5H6I7J8K9L0   │
│ - agents plan status 01HXR1C1D2E3F4G5H6I7J8K9L0    │
│ - agents plan tree 01HXR1C1D2E3F4G5H6I7J8K9L0      │
╰────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan created
</code></pre></div>

Because the automation profile is `manual`, the plan stops and waits after creation. The developer must explicitly trigger each phase.

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Manually trigger Strategize → the strategy actor analyzes the codebase</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan execute 01HXR1C1D2E3F4G5H6I7J8K9L0

╭─ Execution ─────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR1C1D2E3F4G5H6I7J8K9L0        │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> strategize                       │
│ <span style="color: magenta; font-weight: 600;">Sandbox:</span> git_worktree                   │
│ <span style="color: #5599ff; font-weight: 600;">Worker:</span> anthropic/claude-3.5-sonnet     │
│ <span style="color: #66cc66; font-weight: 600;">Started:</span> 09:17:02                       │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                              │
╰─────────────────────────────────────────╯

╭─ Sandbox ───────────────────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Strategy:</span> git_worktree                                          │
│ <span style="color: #5599ff; font-weight: 600;">Path:</span> /home/dev/projects/api-service/.worktrees/plan-01HXR1C1   │
│ <span style="color: #5599ff; font-weight: 600;">Branch:</span> cleveragents/plan-01HXR1C1D2                            │
│ <span style="color: #66cc66; font-weight: 600;">Status:</span> active                                                  │
╰─────────────────────────────────────────────────────────────────╯

╭─ Strategy Summary ────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Decisions:</span> 4                      │
│ <span style="color: magenta; font-weight: 600;">Invariants:</span> 0                     │
│ <span style="color: #5599ff; font-weight: 600;">Planned Child Plans:</span> 0            │
│ <span style="color: #5599ff; font-weight: 600;">Estimated Files:</span> ~2               │
│ <span style="color: #5599ff; font-weight: 600;">Risk:</span> low                         │
╰───────────────────────────────────╯

╭─ Progress ────────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Collect context │
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Build strategy  │
│ <span style="color: yellow; font-weight: 600;">•</span> Awaiting review │
╰───────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Strategize complete — awaiting manual approval
</code></pre></div>

The strategy actor has read the codebase, identified the relevant files, and produced decisions. Since `auto_decisions_strategize` is 1.0 (manual), the plan pauses for review:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Review the decision tree</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan tree 01HXR1C1D2E3F4G5H6I7J8K9L0

╭─ Decision Tree ───────────────────────────────────────────────────────────────────────────╮
│ Plan: 01HXR1C1D2E3F4G5H6I7J8K9L0                                                          │
│ ├─ <span style="color: white;">[prompt_definition]</span> <span style="color: #66cc66;">"Fix /health endpoint to return 200 when DB unavailable"</span>           │
│ ├─ <span style="color: #5599ff;">[strategy_choice]</span> <span style="color: #66cc66;">"Wrap DB call in try/except, return degraded status"</span> <span style="opacity: 0.7;">(conf: 0.95)</span>    │
│ ├─ <span style="color: #5599ff;">[strategy_choice]</span> <span style="color: #66cc66;">"Modify src/routes/health.py only"</span> <span style="opacity: 0.7;">(conf: 0.91)</span>                      │
│ └─ <span style="color: #5599ff;">[strategy_choice]</span> <span style="color: #66cc66;">"Add test_health_db_unavailable to tests/test_health.py"</span> <span style="opacity: 0.7;">(conf: 0.93)</span>│
╰───────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Tree Summary ─────────────╮
│ <span style="color: yellow; font-weight: 600;">Nodes:</span> 4                   │
│ <span style="color: #5599ff; font-weight: 600;">Depth:</span> 1                   │
│ <span style="color: #66cc66; font-weight: 600;">Child Plans:</span> 0             │
│ <span style="color: magenta; font-weight: 600;">Invariants:</span> 0              │
│ <span style="color: #5599ff; font-weight: 600;">Superseded:</span> 0 (hidden)     │
╰────────────────────────────╯

╭─ Decision IDs (for correction) ──────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Root:</span> 01HXR1D1A2B3C4D5E6F7G8H9                   │
│ <span style="color: #5599ff; font-weight: 600;">Strategy 1:</span> 01HXR1D2A2B3C4D5E6F7G8H9             │
│ <span style="color: #5599ff; font-weight: 600;">Strategy 2:</span> 01HXR1D3A2B3C4D5E6F7G8H9             │
│ <span style="color: #5599ff; font-weight: 600;">Strategy 3:</span> 01HXR1D4A2B3C4D5E6F7G8H9             │
╰──────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Decision tree rendered
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Inspect the main strategy decision in detail</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan explain 01HXR1D2A2B3C4D5E6F7G8H9

╭─ Decision ──────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXR1D2A2B3C4D5E6F7G8H9                                            │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> strategy_choice                                                   │
│ <span style="color: magenta; font-weight: 600;">Question:</span> How should the /health endpoint handle database failures?     │
│ <span style="color: #66cc66; font-weight: 600;">Chosen:</span> Wrap DB call in try/except, return degraded status              │
│ <span style="color: yellow; font-weight: 600;">Confidence:</span> 0.95                                                        │
│ <span style="color: #5599ff; font-weight: 600;">Plan:</span> 01HXR1C1D2E3F4G5H6I7J8K9L0                                        │
│ <span style="color: #5599ff; font-weight: 600;">Sequence:</span> 1 of 3                                                        │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 09:17                                               │
╰─────────────────────────────────────────────────────────────────────────╯

╭─ Alternatives Considered ──────────────────────────────────────────────────╮
│ 1. Wrap DB call in try/except, return degraded status <span style="color: #66cc66; font-weight: 600;">(chosen)</span>             │
│ 2. Add a circuit breaker middleware for all DB-dependent routes            │
│ 3. Return HTTP 503 Service Unavailable with retry-after header             │
╰────────────────────────────────────────────────────────────────────────────╯

╭─ Impact ──────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Downstream Decisions:</span> 2       │
│ <span style="color: #5599ff; font-weight: 600;">Downstream Child Plans:</span> 0     │
│ <span style="color: #66cc66; font-weight: 600;">Artifacts Produced:</span> 2         │
│ <span style="color: yellow; font-weight: 600;">Correction Impact:</span> low        │
╰───────────────────────────────╯

╭─ Rationale ──────────────────────────────────────────────────╮
│ The bug description explicitly requires HTTP 200 with a      │
│ degraded status JSON body. A try/except around the DB call   │
│ in the health endpoint is the minimal, targeted fix. A       │
│ circuit breaker would be over-engineering for a single       │
│ endpoint. HTTP 503 contradicts the requested behavior.       │
╰──────────────────────────────────────────────────────────────╯

╭─ Correction ─────────────────────────────────────────────────╮
│ agents plan correct 01HXR1D2A2B3C4D5E6F7G8H9                 │
│   <span style="color: cyan;">--mode</span> revert <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">"Use a different approach..."</span>     │
╰──────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Decision explained
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Approve and proceed to Execute (manual profile requires explicit trigger)</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan execute 01HXR1C1D2E3F4G5H6I7J8K9L0

╭─ Execution ─────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR1C1D2E3F4G5H6I7J8K9L0        │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> execute                          │
│ <span style="color: magenta; font-weight: 600;">Sandbox:</span> git_worktree                   │
│ <span style="color: #5599ff; font-weight: 600;">Worker:</span> anthropic/claude-3.5-sonnet     │
│ <span style="color: #66cc66; font-weight: 600;">Started:</span> 09:18:30                       │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                              │
╰─────────────────────────────────────────╯

╭─ Sandbox ───────────────────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Strategy:</span> git_worktree                                          │
│ <span style="color: #5599ff; font-weight: 600;">Path:</span> /home/dev/projects/api-service/.worktrees/plan-01HXR1C1   │
│ <span style="color: #5599ff; font-weight: 600;">Branch:</span> cleveragents/plan-01HXR1C1D2                            │
│ <span style="color: #66cc66; font-weight: 600;">Status:</span> active                                                  │
╰─────────────────────────────────────────────────────────────────╯

╭─ Progress ────────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Collect context (0.4s)                  │
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Modify src/routes/health.py (1.2s)      │
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Add tests/test_health.py test (2.1s)    │
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Validate: pytest tests/ (3.8s)          │
╰───────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Execution complete — awaiting apply
</code></pre></div>

The execution actor worked in the sandbox (git worktree), modifying `src/routes/health.py` and adding a test in `tests/test_health.py`. Validations ran automatically within the sandbox and passed.

#### Step 4: Review and Apply

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Review the changes</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan diff 01HXR1C1D2E3F4G5H6I7J8K9L0

╭─ Diff Summary ──────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR1C1D2E3F4G5H6I7J8K9L0                │
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service                      │
│ <span style="color: yellow; font-weight: 600;">Files Changed:</span> 2                                │
│ <span style="color: #66cc66; font-weight: 600;">Insertions:</span> 19                                  │
│ <span style="color: #ff6666; font-weight: 600;">Deletions:</span> 3                                    │
│ <span style="color: #5599ff; font-weight: 600;">Net Change:</span> +16 lines                           │
╰─────────────────────────────────────────────────╯

╭─ Files ────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Path</span>                     <span style="color: cyan; font-weight: 600;">Change</span>  <span style="color: cyan; font-weight: 600;">Status</span>    │
│ <span style="opacity: 0.7;">───────────────────────  ──────  ────────</span>  │
│ src/routes/health.py     <span style="color: #66cc66; font-weight: 600;">+8 -3</span>   modified  │
│ tests/test_health.py     <span style="color: #66cc66; font-weight: 600;">+11 -0</span>  modified  │
╰────────────────────────────────────────────╯

╭─ Patch Preview ──────────────────────────────────────────────────╮
│ <span style="opacity: 0.7;">--- a/src/routes/health.py</span>                                       │
│ <span style="opacity: 0.7;">+++ b/src/routes/health.py</span>                                       │
│ <span style="color: cyan;">@@ -8,6 +8,11 @@</span>                                                 │
│  @app.get("/health")                                             │
│  def health_check():                                             │
│ <span style="color: #ff6666;">-    db_status = check_database_connection()</span>                     │
│ <span style="color: #ff6666;">-    return {"status": "ok", "database": db_status}</span>              │
│ <span style="color: #66cc66;">+    try:</span>                                                        │
│ <span style="color: #66cc66;">+        db_status = check_database_connection()</span>                 │
│ <span style="color: #66cc66;">+        return {"status": "ok", "database": "available"}</span>        │
│ <span style="color: #66cc66;">+    except ConnectionError:</span>                                     │
│ <span style="color: #66cc66;">+        return {"status": "degraded", "database": "unavailable"}</span>│
│ <span style="opacity: 0.7;">--- a/tests/test_health.py</span>                                       │
│ <span style="opacity: 0.7;">+++ b/tests/test_health.py</span>                                       │
│ <span style="color: cyan;">@@ -15,0 +16,11 @@</span>                                               │
│ <span style="color: #66cc66;">+def test_health_db_unavailable(client, monkeypatch):</span>            │
│ <span style="color: #66cc66;">+    def mock_check():</span>                                           │
│ <span style="color: #66cc66;">+        raise ConnectionError("DB unreachable")</span>                 │
│ <span style="color: #66cc66;">+    monkeypatch.setattr("src.routes.health.check_database…")</span>    │
│ <span style="color: #66cc66;">+    response = client.get("/health")</span>                            │
│ <span style="color: #66cc66;">+    assert response.status_code == 200</span>                          │
│ <span style="color: #66cc66;">+    data = response.json()</span>                                      │
│ <span style="color: #66cc66;">+    assert data["status"] == "degraded"</span>                         │
│ <span style="color: #66cc66;">+    assert data["database"] == "unavailable"</span>                    │
╰──────────────────────────────────────────────────────────────────╯

╭─ Risk Assessment ────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">API Compatibility:</span> preserved     │
│ <span style="color: #66cc66; font-weight: 600;">Test Coverage:</span> increased         │
│ <span style="color: yellow; font-weight: 600;">Breaking Changes:</span> none detected  │
╰──────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Diff generated
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Check plan status (should be execute/complete, awaiting apply)</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan status 01HXR1C1D2E3F4G5H6I7J8K9L0

╭─ Plan Status ───────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR1C1D2E3F4G5H6I7J8K9L0        │
│ <span style="color: #66cc66; font-weight: 600;">Phase:</span> execute                          │
│ <span style="color: #66cc66; font-weight: 600;">State:</span> complete                         │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/fix-bug                   │
│ <span style="color: #66cc66; font-weight: 600;">Project:</span> local/api-service              │
│ <span style="color: #5599ff; font-weight: 600;">Automation:</span> manual                      │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                              │
╰─────────────────────────────────────────╯

╭─ Progress ───────────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Strategize         │
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Execute            │
│ <span style="color: yellow; font-weight: 600;">•</span> Apply (awaiting)   │
╰──────────────────────╯

╭─ Timing ───────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Started:</span> 2026-02-11 09:17:02       │
│ <span style="color: yellow; font-weight: 600;">Elapsed:</span> 00:01:42                  │
│ <span style="color: #66cc66; font-weight: 600;">ETA:</span> awaiting manual apply         │
╰────────────────────────────────────╯

╭─ Execution Detail ──────────╮
│ <span style="color: #5599ff; font-weight: 600;">Sandbox:</span> git_worktree       │
│ <span style="color: #5599ff; font-weight: 600;">Tool Calls:</span> 5               │
│ <span style="color: #5599ff; font-weight: 600;">Files Modified:</span> 2           │
│ <span style="color: #5599ff; font-weight: 600;">Child Plans:</span> 0              │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoints:</span> 1 created      │
╰─────────────────────────────╯

╭─ Cost ───────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Tokens Used:</span> 6,840   │
│ <span style="color: yellow; font-weight: 600;">Cost So Far:</span> $0.023  │
│ <span style="color: #5599ff; font-weight: 600;">Estimated:</span> $0.025    │
╰──────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Status refreshed
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Apply the changes to the real repository</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXR1C1D2E3F4G5H6I7J8K9L0

╭─ Apply Summary ──────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR1C1D2E3F4G5H6I7J8K9L0         │
│ <span style="color: #5599ff; font-weight: 600;">Artifacts:</span> 2 files updated               │
│ <span style="color: yellow; font-weight: 600;">Changes:</span> 19 insertions, 3 deletions      │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/api-service               │
│ <span style="color: #66cc66; font-weight: 600;">Applied At:</span> 2026-02-11 09:19             │
╰──────────────────────────────────────────╯

╭─ Validation ───────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Tests:</span> passed (14/14)          │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 3.8s                 │
╰────────────────────────────────╯

╭─ Sandbox Cleanup ──────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Worktree:</span> removed                      │
│ <span style="color: #66cc66; font-weight: 600;">Branch:</span> merged to main                 │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoint:</span> archived                   │
╰────────────────────────────────────────╯

╭─ Plan Lifecycle ──────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Phase:</span> applied                        │
│ <span style="color: #66cc66; font-weight: 600;">State:</span> complete                       │
│ <span style="color: #5599ff; font-weight: 600;">Total Duration:</span> 00:01:58              │
│ <span style="color: yellow; font-weight: 600;">Total Cost:</span> $0.025                    │
│ <span style="color: #5599ff; font-weight: 600;">Decisions Made:</span> 4                     │
│ <span style="color: #5599ff; font-weight: 600;">Child Plans:</span> 0                        │
╰───────────────────────────────────────╯

╭─ Next Steps ──────╮
│ - Review git diff │
│ - Commit changes  │
╰───────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied
</code></pre></div>

The sandbox changes are merged into the main working tree. The bug is fixed.

---

### Example 2: Automated Test Generation for a Module

**Scenario**: A team wants to increase test coverage for their `auth` module from 45% to 80%. They trust CleverAgents to generate tests autonomously, but want to review before applying.

**Complexity**: Intermediate. Single project, trusted automation profile, validation-driven.

#### Step 1: Setup (Assuming Project Exists)

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Register a coverage validation</span>
<span style="opacity: 0.7;"># (project local/api-service and resource local/api-service-repo already exist)</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation add \
    <span style="color: cyan;">--config</span> validations/auth-coverage.yaml \
    <span style="color: cyan;">--required</span> \
    local/auth-coverage

╭─ Validation Registered ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/auth-coverage                                    │
│ <span style="color: #5599ff; font-weight: 600;">Command:</span> pytest <span style="color: cyan;">--cov</span>=src/auth <span style="color: cyan;">--cov-fail-under</span>=80            │
│         tests/test_auth/                                      │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Coverage must be at least 80%                    │
│ <span style="color: #66cc66; font-weight: 600;">Mode:</span> required                                                │
│ <span style="color: yellow; font-weight: 600;">Timeout:</span> 600s                                                 │
╰──────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation registered

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> local/api-service local/auth-coverage

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached to project local/api-service

<span style="opacity: 0.7;"># Automation profile will be set per-plan via --automation-profile on plan use</span>
</code></pre></div>

#### Step 2: Create the Test Generation Action

Create `actions/generate-tests.yaml`:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">name</span>: local/generate-tests
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Generate comprehensive tests for a module"</span>
<span style="color: cyan; font-weight: 600;">long_description</span>: |
  Analyze the target module's code paths, identify untested branches,
  edge cases, and error conditions, then generate thorough test cases.
  Uses the project's existing test framework and conventions.
<span style="color: cyan; font-weight: 600;">definition_of_done</span>: |
  - Coverage of the target module reaches the specified threshold
  - All new tests pass
  - All existing tests continue to pass
  - Tests follow existing project conventions (fixtures, naming, structure)
  - No production code is modified
<span style="color: cyan; font-weight: 600;">strategy_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">execution_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">reusable</span>: <span style="color: yellow;">true</span>
<span style="color: cyan; font-weight: 600;">state</span>: <span style="color: yellow;">available</span>
<span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: yellow;">false</span>
<span style="color: cyan; font-weight: 600;">args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: target_module
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Module path to generate tests for (e.g., src/auth)"</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: coverage_target
    <span style="color: cyan; font-weight: 600;">type</span>: integer
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Target coverage percentage"</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: yellow;">80</span>
<span style="color: cyan; font-weight: 600;">invariants</span>:
  - <span style="color: #66cc66;">"Do not modify any production code — only add or modify test files"</span>
  - <span style="color: #66cc66;">"Follow the existing test file naming convention (test_&lt;module&gt;.py)"</span>
  - <span style="color: #66cc66;">"Use the project's existing test fixtures and conftest.py patterns"</span>
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action create <span style="color: cyan;">--config</span> ./actions/generate-tests.yaml

╭─ Action Created ───────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/generate-tests                         │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> 01HXR2B1C2D3E4F5G6H7I8J9K0                     │
│ <span style="color: yellow; font-weight: 600;">State:</span> available                                    │
│ <span style="color: magenta; font-weight: 600;">Strategy Actor:</span> anthropic/claude-3.5-sonnet        │
│ <span style="color: magenta; font-weight: 600;">Execution Actor:</span> anthropic/claude-3.5-sonnet       │
│ <span style="color: #66cc66; font-weight: 600;">Reusable:</span> yes                                      │
│ <span style="color: #5599ff; font-weight: 600;">Read Only:</span> no                                      │
│ <span style="color: #66cc66; font-weight: 600;">Config:</span> ./actions/generate-tests.yaml              │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 09:15                          │
╰────────────────────────────────────────────────────╯

╭─ Definition of Done ──────────────────────────────────────────────╮
│ - Coverage of the target module reaches the specified threshold   │
│ - All new tests pass                                              │
│ - All existing tests continue to pass                             │
│ - Tests follow existing project conventions                       │
│ - No production code is modified                                  │
╰───────────────────────────────────────────────────────────────────╯

╭─ Arguments ───────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>              <span style="color: cyan; font-weight: 600;">Type</span>     <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>                              │
│ <span style="opacity: 0.7;">────────────────  ───────  ────────  ───────────────────────────────────────</span>  │
│ target_module     string   yes       Module path to generate tests for        │
│ coverage_target   integer  no        Target coverage percentage (default 80)  │
╰───────────────────────────────────────────────────────────────────────────────╯

╭─ Invariants ──────────────────────────────────────────────────────────────────╮
│ 1. Do not modify any production code — only add or modify test files          │
│ 2. Follow the existing test file naming convention (test_&lt;module&gt;.py)         │
│ 3. Use the project's existing test fixtures and conftest.py patterns          │
╰───────────────────────────────────────────────────────────────────────────────╯

╭─ Automation ──────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> supervised                   │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> default                       │
╰───────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Action created
</code></pre></div>

#### Step 3: Execute

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># With trusted profile: Strategize and Execute run automatically,</span>
<span style="opacity: 0.7;"># only Apply requires human approval</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan use \
    <span style="color: cyan;">--automation-profile</span> trusted \
    <span style="color: cyan;">--arg</span> <span style="color: #66cc66;">target_module="src/auth"</span> \
    <span style="color: cyan;">--arg</span> <span style="color: #66cc66;">coverage_target=80</span> \
    local/generate-tests local/api-service

╭─ Plan Created ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR2B3C4D5E6F7G8H9J0K1L2                    │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> strategize                                   │
│ <span style="color: magenta; font-weight: 600;">State:</span> processing                                   │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/generate-tests                        │
│ <span style="color: #66cc66; font-weight: 600;">Project:</span> local/api-service                          │
│ <span style="color: #66cc66; font-weight: 600;">Automation:</span> trusted                                 │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                          │
╰─────────────────────────────────────────────────────╯

╭─ Inputs ────────────────────────────╮
│ - target_module=src/auth            │
│ - coverage_target=80                │
│ - automation_profile=trusted        │
╰─────────────────────────────────────╯

╭─ Actors ────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Strategy:</span> anthropic/claude-3.5-sonnet           │
│ <span style="color: magenta; font-weight: 600;">Execution:</span> anthropic/claude-3.5-sonnet          │
│ <span style="color: #5599ff; font-weight: 600;">Estimation:</span> (none)                              │
╰─────────────────────────────────────────────────╯

╭─ Automation ───────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> trusted                       │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> plan override                  │
│ <span style="color: #5599ff; font-weight: 600;">Read-Only:</span> no                          │
╰────────────────────────────────────────╯

╭─ Context ────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Resources:</span> 1 (repo)              │
│ <span style="color: #5599ff; font-weight: 600;">Indexed Files:</span> 214               │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> strategize                 │
│ <span style="color: #5599ff; font-weight: 600;">Hot Token Budget:</span> 8,000          │
╰──────────────────────────────────╯

╭─ Next Steps ─────────────────────────────────────────────────────────╮
│ <span style="opacity: 0.7;">Trusted profile — strategize and execute will proceed automatically.</span> │
│ - agents plan status 01HXR2B3C4D5E6F7G8H9J0K1L2                      │
│ - agents plan tree 01HXR2B3C4D5E6F7G8H9J0K1L2                        │
╰──────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan created
</code></pre></div>

The system runs through Strategize and Execute automatically. The strategy actor analyzes coverage gaps, identifies 12 untested code paths, and plans test cases. The execution actor writes tests in the sandbox. Validations run. If coverage reaches 80%, the plan reaches `execute/complete` and waits for apply.

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Check progress while it runs</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan status 01HXR2B3C4D5E6F7G8H9J0K1L2

╭─ Plan Status ───────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR2B3C4D5E6F7G8H9J0K1L2            │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> execute                              │
│ <span style="color: magenta; font-weight: 600;">State:</span> processing                           │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/generate-tests                │
│ <span style="color: #66cc66; font-weight: 600;">Project:</span> local/api-service                  │
│ <span style="color: #66cc66; font-weight: 600;">Automation:</span> trusted                         │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                  │
╰─────────────────────────────────────────────╯

╭─ Progress ───────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Strategize     │
│ <span style="color: cyan; font-weight: 600;">⏳</span> Execute        │
│ <span style="color: yellow; font-weight: 600;">•</span> Apply (queued) │
╰──────────────────╯

╭─ Timing ──────────╮
│ <span style="color: #66cc66; font-weight: 600;">Started:</span> 09:15:42 │
│ <span style="color: yellow; font-weight: 600;">Elapsed:</span> 00:02:18 │
│ <span style="color: #66cc66; font-weight: 600;">ETA:</span> 00:04:30     │
╰───────────────────╯

╭─ Execution Detail ──────────╮
│ <span style="color: #5599ff; font-weight: 600;">Sandbox:</span> git_worktree       │
│ <span style="color: #5599ff; font-weight: 600;">Tool Calls:</span> 14              │
│ <span style="color: #5599ff; font-weight: 600;">Files Modified:</span> 5           │
│ <span style="color: #5599ff; font-weight: 600;">Child Plans:</span> 0              │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoints:</span> 3 created      │
╰─────────────────────────────╯

╭─ Cost ───────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Tokens Used:</span> 18,740  │
│ <span style="color: yellow; font-weight: 600;">Cost So Far:</span> $0.062  │
│ <span style="color: #5599ff; font-weight: 600;">Estimated:</span> $0.110    │
╰──────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Status refreshed
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># When complete, review the generated tests</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan diff 01HXR2B3C4D5E6F7G8H9J0K1L2

╭─ Diff Summary ─────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR2B3C4D5E6F7G8H9J0K1L2                   │
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service                         │
│ <span style="color: yellow; font-weight: 600;">Files Changed:</span> 5                                   │
│ <span style="color: #66cc66; font-weight: 600;">Insertions:</span> 287                                    │
│ <span style="color: #ff6666; font-weight: 600;">Deletions:</span> 3                                       │
│ <span style="color: #5599ff; font-weight: 600;">Net Change:</span> +284 lines                             │
╰────────────────────────────────────────────────────╯

╭─ Files ────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Path</span>                            <span style="color: cyan; font-weight: 600;">Change</span>    <span style="color: cyan; font-weight: 600;">Status</span>       │
│ <span style="opacity: 0.7;">──────────────────────────────  ────────  ──────────</span>   │
│ tests/test_auth/test_login.py   <span style="color: #66cc66; font-weight: 600;">+72 -0</span>    new file     │
│ tests/test_auth/test_tokens.py  <span style="color: #66cc66; font-weight: 600;">+68 -0</span>    new file     │
│ tests/test_auth/test_session.py <span style="color: #66cc66; font-weight: 600;">+54 -0</span>    new file     │
│ tests/test_auth/test_rbac.py    <span style="color: #66cc66; font-weight: 600;">+41 -0</span>    new file     │
│ tests/test_auth/conftest.py     <span style="color: #66cc66; font-weight: 600;">+52 -3</span>    modified     │
╰────────────────────────────────────────────────────────╯

╭─ Patch Preview ───────────────────────────────────────────╮
│ <span style="opacity: 0.7;">--- /dev/null</span>                                             │
│ <span style="opacity: 0.7;">+++ b/tests/test_auth/test_login.py</span>                       │
│ <span style="color: cyan;">@@ -0,0 +1,72 @@</span>                                          │
│ <span style="color: #66cc66;">+ import pytest</span>                                           │
│ <span style="color: #66cc66;">+ from src.auth.login import authenticate, verify_mfa</span>     │
│ <span style="color: #66cc66;">+ ...</span>                                                     │
│ <span style="opacity: 0.7;">--- a/tests/test_auth/conftest.py</span>                         │
│ <span style="opacity: 0.7;">+++ b/tests/test_auth/conftest.py</span>                         │
│ <span style="color: cyan;">@@ -1,5 +1,54 @@</span>                                          │
│ <span style="color: #ff6666;">- # minimal fixtures</span>                                      │
│ <span style="color: #66cc66;">+ # shared auth test fixtures</span>                             │
│ <span style="color: #66cc66;">+ @pytest.fixture</span>                                         │
│ <span style="color: #66cc66;">+ def mock_user_db(): ...</span>                                 │
╰───────────────────────────────────────────────────────────╯

╭─ Risk Assessment ────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">API Compatibility:</span> preserved     │
│ <span style="color: #66cc66; font-weight: 600;">Test Coverage:</span> 45% → 83%         │
│ <span style="color: yellow; font-weight: 600;">Breaking Changes:</span> none detected  │
╰──────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Diff generated
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan artifacts 01HXR2B3C4D5E6F7G8H9J0K1L2

╭─ Artifacts ──────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Path</span>                              <span style="color: cyan; font-weight: 600;">Type</span>   <span style="color: cyan; font-weight: 600;">Size</span>    <span style="color: cyan; font-weight: 600;">Change</span>  <span style="color: cyan; font-weight: 600;">Child Plan</span>  │
│ <span style="opacity: 0.7;">────────────────────────────────  ─────  ──────  ──────  ───────</span>     │
│ tests/test_auth/test_login.py     write  3.8 KB  <span style="color: #66cc66; font-weight: 600;">+72 -0</span>  root        │
│ tests/test_auth/test_tokens.py    write  3.4 KB  <span style="color: #66cc66; font-weight: 600;">+68 -0</span>  root        │
│ tests/test_auth/test_session.py   write  2.7 KB  <span style="color: #66cc66; font-weight: 600;">+54 -0</span>  root        │
│ tests/test_auth/test_rbac.py      write  2.1 KB  <span style="color: #66cc66; font-weight: 600;">+41 -0</span>  root        │
│ tests/test_auth/conftest.py       edit   2.6 KB  <span style="color: #66cc66; font-weight: 600;">+52 -3</span>  root        │
╰──────────────────────────────────────────────────────────────────────╯

╭─ Summary ────────────╮
│ <span style="color: yellow; font-weight: 600;">Total:</span> 5             │
│ <span style="color: #66cc66; font-weight: 600;">Writes:</span> 4 (new)      │
│ <span style="color: #5599ff; font-weight: 600;">Edits:</span> 1 (modified)  │
│ <span style="color: #ff6666; font-weight: 600;">Deletes:</span> 0           │
│ <span style="color: #5599ff; font-weight: 600;">Total Size:</span> 14.6 KB  │
╰──────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 5 artifacts listed
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Apply the generated tests to the real repository</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXR2B3C4D5E6F7G8H9J0K1L2

╭─ Apply Summary ──────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR2B3C4D5E6F7G8H9J0K1L2         │
│ <span style="color: #5599ff; font-weight: 600;">Artifacts:</span> 5 files updated               │
│ <span style="color: yellow; font-weight: 600;">Changes:</span> 287 insertions, 3 deletions     │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/api-service               │
│ <span style="color: #66cc66; font-weight: 600;">Applied At:</span> 2026-02-11 09:22             │
╰──────────────────────────────────────────╯

╭─ Validation ──────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Coverage: passed (83% ≥ 80%)        │
│ <span style="color: #66cc66; font-weight: 600;">✓</span> All tests: passed (47/47)           │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 18.2s                       │
╰───────────────────────────────────────╯

╭─ Sandbox Cleanup ─────────╮
│ <span style="color: #66cc66; font-weight: 600;">Worktree:</span> removed         │
│ <span style="color: #66cc66; font-weight: 600;">Branch:</span> merged to main    │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoint:</span> archived      │
╰───────────────────────────╯

╭─ Plan Lifecycle ─────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Phase:</span> applied                           │
│ <span style="color: #66cc66; font-weight: 600;">State:</span> complete                          │
│ <span style="color: #5599ff; font-weight: 600;">Total Duration:</span> 00:06:38                 │
│ <span style="color: yellow; font-weight: 600;">Total Cost:</span> $0.107                       │
│ <span style="color: #5599ff; font-weight: 600;">Decisions Made:</span> 12                       │
│ <span style="color: #5599ff; font-weight: 600;">Child Plans:</span> 0                           │
╰──────────────────────────────────────────╯

╭─ Next Steps ──────╮
│ - Review git diff │
│ - Commit changes  │
╰───────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied
</code></pre></div>

---

### Example 3: Multi-File Refactoring with Invariants

**Scenario**: A senior engineer wants to refactor the authentication module to replace raw SQL queries with an ORM. The refactoring must maintain API backward compatibility and all existing tests must pass. Multiple invariants constrain the work.

**Complexity**: Intermediate-Advanced. Single project, multiple invariants, decision tree review.

#### Step 1: Define Invariants

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> invariant add <span style="color: cyan;">--global</span> <span style="color: #66cc66;">&quot;All public APIs must maintain backward compatibility&quot;</span>

╭─ Invariant Added ──────────────────────────────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Invariant:</span> All public APIs must maintain backward compatibility        │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> global                                                          │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> inv_01HXR3A1B                                                      │
╰────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Invariant added

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> invariant add <span style="color: cyan;">--project</span> local/api-service \
    <span style="color: #66cc66;">&quot;Database queries must use the SQLAlchemy ORM, not raw SQL&quot;</span>

╭─ Invariant Added ───────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service                                              │
│ <span style="color: #66cc66; font-weight: 600;">Invariant:</span> Database queries must use the SQLAlchemy ORM, not raw SQL    │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> project                                                          │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> inv_01HXR3A2C                                                       │
╰─────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Invariant added

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> invariant list <span style="color: cyan;">--project</span> local/api-service <span style="color: cyan;">--effective</span>

╭─ Effective Invariants (Project local/api-service) ─────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>              <span style="color: cyan; font-weight: 600;">Source</span>    <span style="color: cyan; font-weight: 600;">Text</span>                                                         │
│ <span style="opacity: 0.7;">──────────────  ────────  ──────────────────────────────────────────────────────</span>       │
│ inv_01HXR3A1B  global    All public APIs must maintain backward compatibility          │
│ inv_01HXR3A2C  project   Database queries must use the SQLAlchemy ORM, not raw SQL     │
╰────────────────────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 2 effective invariants (1 global, 1 project)
</code></pre></div>

#### Step 2: Create a Refactoring Action with Custom Actors

Create `actors/refactoring-strategist.yaml`:

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">name</span>: local/refactoring-strategist
<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">"3.0"</span>
<span style="color: cyan; font-weight: 600;">actors</span>:
  <span style="color: cyan; font-weight: 600;">strategist</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">provider</span>: anthropic
      <span style="color: cyan; font-weight: 600;">model</span>: claude-3.5-sonnet
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.2</span>
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: |
        You are an expert software architect specializing in database layer refactoring.
        You analyze codebases to plan safe, incremental refactoring strategies.
        You always preserve backward compatibility and plan for comprehensive testing.
        Project: <span style="color: yellow;">{{ context.project_name }}</span>
        Resources: <span style="color: yellow;">{{ context.resources | join(', ') }}</span>
      <span style="color: cyan; font-weight: 600;">memory_enabled</span>: <span style="color: yellow;">true</span>
      <span style="color: cyan; font-weight: 600;">max_history</span>: <span style="color: yellow;">100</span>
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor add <span style="color: cyan;">--config</span> ./actors/refactoring-strategist.yaml

╭─ Actor Added ────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/refactoring-strategist               │
│ <span style="color: #5599ff; font-weight: 600;">Provider:</span> anthropic                              │
│ <span style="color: magenta; font-weight: 600;">Model:</span> claude-3.5-sonnet                         │
│ <span style="color: yellow; font-weight: 600;">Default:</span> yes                                     │
│ <span style="color: #ff6666; font-weight: 600;">Unsafe:</span> no                                       │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> graph                                      │
╰──────────────────────────────────────────────────╯

╭─ Config ────────────────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Path:</span> ./actors/refactoring-strategist.yaml                  │
│ <span style="color: magenta; font-weight: 600;">Hash:</span> 7a1e4c9                                               │
│ <span style="color: #66cc66; font-weight: 600;">Options:</span> 3                                                  │
│ <span style="color: #5599ff; font-weight: 600;">Nodes:</span> 1                                                    │
│ <span style="color: #5599ff; font-weight: 600;">Edges:</span> 0                                                    │
╰─────────────────────────────────────────────────────────────╯

╭─ Capabilities ────────────────╮
│ - database layer refactoring  │
│ - incremental strategy        │
│ - backward compatibility      │
╰───────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Actor added
</code></pre></div>

Create `actions/refactor-to-orm.yaml`:

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">name</span>: local/refactor-to-orm
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Refactor raw SQL queries to use SQLAlchemy ORM"</span>
<span style="color: cyan; font-weight: 600;">long_description</span>: |
  Systematically replace all raw SQL queries in the target module with
  SQLAlchemy ORM equivalents. Create ORM model definitions, replace
  query construction, update transaction handling, and ensure all
  existing behavior is preserved.
<span style="color: cyan; font-weight: 600;">definition_of_done</span>: |
  - Zero raw SQL strings remain in the target module
  - All ORM models are defined with proper relationships
  - All existing tests pass without modification
  - New integration tests verify ORM query correctness
  - API response formats are unchanged
  - Database migration script is generated
<span style="color: cyan; font-weight: 600;">strategy_actor</span>: local/refactoring-strategist
<span style="color: cyan; font-weight: 600;">execution_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">estimation_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">reusable</span>: <span style="color: yellow;">true</span>
<span style="color: cyan; font-weight: 600;">state</span>: <span style="color: yellow;">available</span>
<span style="color: cyan; font-weight: 600;">automation_profile</span>: cautious
<span style="color: cyan; font-weight: 600;">args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: target_module
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Module to refactor"</span>
<span style="color: cyan; font-weight: 600;">invariants</span>:
  - <span style="color: #66cc66;">"Each file must be refactored in a separate commit-sized change"</span>
  - <span style="color: #66cc66;">"ORM models must be defined before queries are converted"</span>
  - <span style="color: #66cc66;">"All raw SQL must be replaced — no partial conversion"</span>
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action create <span style="color: cyan;">--config</span> ./actions/refactor-to-orm.yaml

╭─ Action Created ─────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/refactor-to-orm                                  │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> 01HXR3B1D2E3F4G5H6J7K8L9M0                               │
│ <span style="color: yellow; font-weight: 600;">State:</span> available                                             │
│ <span style="color: magenta; font-weight: 600;">Strategy Actor:</span> local/refactoring-strategist                 │
│ <span style="color: magenta; font-weight: 600;">Execution Actor:</span> anthropic/claude-3.5-sonnet                 │
│ <span style="color: #66cc66; font-weight: 600;">Reusable:</span> yes                                                │
│ <span style="color: #5599ff; font-weight: 600;">Read Only:</span> no                                                │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 09:14                                    │
╰──────────────────────────────────────────────────────────────╯

╭─ Definition of Done ──────────────────────────────────────────╮
│ - Zero raw SQL strings remain in the target module            │
│ - All ORM models are defined with proper relationships        │
│ - All existing tests pass without modification                │
│ - New integration tests verify ORM query correctness          │
│ - API response formats are unchanged                          │
│ - Database migration script is generated                      │
╰───────────────────────────────────────────────────────────────╯

╭─ Arguments ──────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>            <span style="color: cyan; font-weight: 600;">Type</span>    <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>            │
│ <span style="opacity: 0.7;">──────────────  ──────  ────────  ─────────────────────</span>  │
│ target_module   string  yes       Module to refactor     │
╰──────────────────────────────────────────────────────────╯

╭─ Automation ──────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> cautious                     │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> action config                 │
╰───────────────────────────────────────╯

╭─ Action Invariants ──────────────────────────────────────────────────────╮
│ 1. Each file must be refactored in a separate commit-sized change        │
│ 2. ORM models must be defined before queries are converted               │
│ 3. All raw SQL must be replaced — no partial conversion                  │
╰──────────────────────────────────────────────────────────────────────────╯

╭─ Usage ───────────────────────────────────────────────────────────────────╮
│ agents plan use local/refactor-to-orm local/api-service                   │
│   <span style="color: cyan;">--arg</span> target_module=&quot;src/auth&quot;                                          │
╰───────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Action created
</code></pre></div>

#### Step 3: Execute with Cautious Profile

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan use \
    <span style="color: cyan;">--arg</span> target_module=<span style="color: #66cc66;">&quot;src/auth&quot;</span> \
    local/refactor-to-orm local/api-service

╭─ Plan Created ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR3C4D5E6F7G8H9J0K1L2M3                     │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/refactor-to-orm                        │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/api-service                           │
│ <span style="color: #66cc66; font-weight: 600;">Automation:</span> cautious                                 │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                           │
╰──────────────────────────────────────────────────────╯

╭─ Inputs ────────────────────────╮
│ - target_module=&quot;src/auth&quot;      │
│ - automation_profile=cautious   │
╰─────────────────────────────────╯

╭─ Actors ───────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Strategy:</span> local/refactoring-strategist         │
│ <span style="color: magenta; font-weight: 600;">Execution:</span> anthropic/claude-3.5-sonnet         │
│ <span style="color: #5599ff; font-weight: 600;">Estimation:</span> anthropic/claude-3.5-sonnet        │
╰────────────────────────────────────────────────╯

╭─ Automation ──────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> cautious                         │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> action config                     │
│ <span style="color: #5599ff; font-weight: 600;">Read-Only:</span> no                             │
╰───────────────────────────────────────────╯

╭─ Context ───────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Resources:</span> 2 (repo, db)         │
│ <span style="color: #5599ff; font-weight: 600;">Indexed Files:</span> 214              │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> strategize                │
│ <span style="color: #5599ff; font-weight: 600;">Hot Token Budget:</span> 16,000        │
╰─────────────────────────────────╯

╭─ Next Steps ──────────────────────────────────────────╮
│ - agents plan execute 01HXR3C4D5E6F7G8H9J0K1L2M3      │
│ - agents plan status 01HXR3C4D5E6F7G8H9J0K1L2M3       │
│ - agents plan tree 01HXR3C4D5E6F7G8H9J0K1L2M3         │
╰───────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan created
</code></pre></div>

Because the `cautious` profile uses intermediate confidence thresholds, the system:

1. Enters Strategize automatically (threshold 0.7, confidence is high for well-understood tasks)
2. Makes strategy decisions automatically when confidence >= 0.6, but pauses for complex architectural choices
3. The Invariant Reconciliation Actor reconciles global ("backward compatibility"), project ("use ORM"), and action ("separate commits") invariants

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># The system pauses at a decision where confidence is below threshold.</span>
<span style="opacity: 0.7;"># Review the decision tree:</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan tree 01HXR3C4D5E6F7G8H9J0K1L2M3

╭─ Decision Tree ────────────────────────────────────────────────────────────────────────────╮
│ Plan: 01HXR3C4D5E6F7G8H9J0K1L2M3                                                           │
│ ├─ <span style="color: white;">[prompt_definition]</span> <span style="color: #66cc66;">&quot;Refactor raw SQL in src/auth to SQLAlchemy ORM&quot;</span>                    │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">&quot;All public APIs must maintain backward compatibility&quot;</span>             │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">&quot;Database queries must use the SQLAlchemy ORM&quot;</span>                     │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">&quot;Each file refactored in a separate commit-sized change&quot;</span>           │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">&quot;ORM models must be defined before queries are converted&quot;</span>          │
│ ├─ <span style="color: #5599ff;">[strategy_choice]</span> <span style="color: #66cc66;">&quot;Define ORM models first, then convert queries&quot;</span> <span style="opacity: 0.7;">(conf: 0.85)</span>          │
│ ├─ <span style="color: yellow;">[strategy_choice]</span> <span style="color: #66cc66;">&quot;Place models inline in route files&quot;</span> <span style="opacity: 0.7;">(conf: 0.48) ⏸ PAUSED</span>            │
│ └─ <span style="color: yellow; font-weight: 600;">•</span> (awaiting input — confidence below threshold)                                         │
╰────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Tree Summary ─────────────╮
│ <span style="color: yellow; font-weight: 600;">Nodes:</span> 8                   │
│ <span style="color: #5599ff; font-weight: 600;">Depth:</span> 2                   │
│ <span style="color: #66cc66; font-weight: 600;">Child Plans:</span> 0             │
│ <span style="color: magenta; font-weight: 600;">Invariants:</span> 4              │
│ <span style="color: #5599ff; font-weight: 600;">Superseded:</span> 0 (hidden)     │
╰────────────────────────────╯

╭─ Decision IDs (for correction) ──────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Root:</span> 01HXR3D1A2B3C4D5E6F7G8H9                       │
│ <span style="color: magenta; font-weight: 600;">Invariant 1:</span> 01HXR3D1B3C4D5E6F7G8H9J0                │
│ <span style="color: magenta; font-weight: 600;">Invariant 2:</span> 01HXR3D1C4D5E6F7G8H9J0K1                │
│ <span style="color: magenta; font-weight: 600;">Invariant 3:</span> 01HXR3D1D5E6F7G8H9J0K1L2                │
│ <span style="color: magenta; font-weight: 600;">Invariant 4:</span> 01HXR3D1E6F7G8H9J0K1L2M3                │
│ <span style="color: #5599ff; font-weight: 600;">Strategy 1:</span> 01HXR3D2E3F4G5H6I7J8K9L0                 │
│ <span style="color: yellow; font-weight: 600;">Strategy 2:</span> 01HXR3D5F6G7H8I9J0K1L2M3 <span style="color: yellow;">(paused)</span>        │
╰──────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Decision tree rendered

<span style="opacity: 0.7;"># The paused decision is about model placement. Inspect it:</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan explain 01HXR3D5F6G7H8I9J0K1L2M3

╭─ Decision ──────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXR3D5F6G7H8I9J0K1L2M3                            │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> strategy_choice                                   │
│ <span style="color: magenta; font-weight: 600;">Question:</span> Where should ORM model classes be placed?     │
│ <span style="color: #66cc66; font-weight: 600;">Chosen:</span> Place models inline in route files              │
│ <span style="color: yellow; font-weight: 600;">Confidence:</span> 0.48                                        │
│ <span style="color: #5599ff; font-weight: 600;">Plan:</span> 01HXR3C4D5E6F7G8H9J0K1L2M3                        │
│ <span style="color: #5599ff; font-weight: 600;">Sequence:</span> 6 of 7                                        │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 09:15                               │
╰─────────────────────────────────────────────────────────╯

╭─ Alternatives Considered ─────────────────────────────────────╮
│ 1. Place models inline in route files <span style="color: #66cc66; font-weight: 600;">(chosen)</span>                │
│ 2. Separate models/ directory with one model per file         │
│ 3. Single models.py file alongside routes                     │
╰───────────────────────────────────────────────────────────────╯

╭─ Impact ──────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Downstream Decisions:</span> 4       │
│ <span style="color: #5599ff; font-weight: 600;">Downstream Child Plans:</span> 0     │
│ <span style="color: #66cc66; font-weight: 600;">Artifacts Produced:</span> 0         │
│ <span style="color: yellow; font-weight: 600;">Correction Impact:</span> high       │
╰───────────────────────────────╯

╭─ Rationale ────────────────────────────────────────────────────────╮
│ Placing models inline minimizes import changes and keeps related   │
│ code co-located. However, this conflicts with project conventions  │
│ and may make models harder to reuse across modules. The low        │
│ confidence reflects genuine uncertainty about the trade-off.       │
╰────────────────────────────────────────────────────────────────────╯

╭─ Correction ───────────────────────────────────────────────────────╮
│ agents plan correct 01HXR3D5F6G7H8I9J0K1L2M3                       │
│   <span style="color: cyan;">--mode</span> revert <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">&quot;Use separate models/ directory...&quot;</span>     │
╰────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Decision explained

<span style="opacity: 0.7;"># Provide guidance via the plan prompt command</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan prompt 01HXR3C4D5E6F7G8H9J0K1L2M3 \
    <span style="color: #66cc66;">&quot;Convert the User model first, then Session, then Token. \
     Use Alembic for the migration script.&quot;</span>

╭─ Guidance Added ─────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR3C4D5E6F7G8H9J0K1L2M3                                         │
│ <span style="color: magenta; font-weight: 600;">Guidance:</span> Convert the User model first, then Session, then Token.        │
│           Use Alembic for the migration script.                          │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> next execution step                                               │
│ <span style="color: #5599ff; font-weight: 600;">Phase:</span> strategize                                                        │
│ <span style="color: #5599ff; font-weight: 600;">State:</span> awaiting_input → processing                                       │
╰──────────────────────────────────────────────────────────────────────────╯

╭─ Decision Created ───────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> user_intervention                      │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> 01HXR3E1A2B3C4D5E6F7G8H9                 │
│ <span style="color: #5599ff; font-weight: 600;">Parent:</span> 01HXR3D5F6G7H8I9J0K1L2M3             │
╰──────────────────────────────────────────────╯

╭─ Queue ────╮
│ <span style="color: yellow; font-weight: 600;">Pending:</span> 1 │
│ <span style="color: #66cc66; font-weight: 600;">Applied:</span> 0 │
╰────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Guidance queued

<span style="opacity: 0.7;"># Execution continues. Monitor progress:</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan status 01HXR3C4D5E6F7G8H9J0K1L2M3

╭─ Plan Status ───────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR3C4D5E6F7G8H9J0K1L2M3                │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> execute                                  │
│ <span style="color: magenta; font-weight: 600;">State:</span> processing                               │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/refactor-to-orm                   │
│ <span style="color: #66cc66; font-weight: 600;">Project:</span> local/api-service                      │
│ <span style="color: #5599ff; font-weight: 600;">Automation:</span> cautious                            │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                      │
╰─────────────────────────────────────────────────╯

╭─ Progress ───────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Strategize     │
│ <span style="color: cyan; font-weight: 600;">⏳</span> Execute        │
│ <span style="color: yellow; font-weight: 600;">•</span> Apply (queued) │
╰──────────────────╯

╭─ Timing ──────────╮
│ <span style="color: #66cc66; font-weight: 600;">Started:</span> 09:14:22 │
│ <span style="color: yellow; font-weight: 600;">Elapsed:</span> 00:02:38 │
│ <span style="color: #66cc66; font-weight: 600;">ETA:</span> 00:05:10     │
╰───────────────────╯

╭─ Execution Detail ──────────╮
│ <span style="color: #5599ff; font-weight: 600;">Sandbox:</span> git_worktree       │
│ <span style="color: #5599ff; font-weight: 600;">Tool Calls:</span> 14              │
│ <span style="color: #5599ff; font-weight: 600;">Files Modified:</span> 4           │
│ <span style="color: #5599ff; font-weight: 600;">Child Plans:</span> 0/0 complete   │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoints:</span> 3 created      │
╰─────────────────────────────╯

╭─ Cost ───────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Tokens Used:</span> 18,740  │
│ <span style="color: yellow; font-weight: 600;">Cost So Far:</span> $0.062  │
│ <span style="color: #5599ff; font-weight: 600;">Estimated:</span> $0.128    │
╰──────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Status refreshed
</code></pre></div>

#### Step 4: Correct a Decision

During execution, you notice the strategy chose to inline the ORM models in the same file as the routes. You want them in a separate `models/` directory:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Find the decision that chose inline models</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan tree <span style="color: cyan;">--show-superseded</span> 01HXR3C4D5E6F7G8H9J0K1L2M3

╭─ Decision Tree ────────────────────────────────────────────────────────────────────────────╮
│ Plan: 01HXR3C4D5E6F7G8H9J0K1L2M3                                                           │
│ ├─ <span style="color: white;">[prompt_definition]</span> <span style="color: #66cc66;">&quot;Refactor raw SQL in src/auth to SQLAlchemy ORM&quot;</span>                    │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">&quot;All public APIs must maintain backward compatibility&quot;</span>             │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">&quot;Database queries must use the SQLAlchemy ORM&quot;</span>                     │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">&quot;Each file refactored in a separate commit-sized change&quot;</span>           │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">&quot;ORM models must be defined before queries are converted&quot;</span>          │
│ ├─ <span style="color: #5599ff;">[strategy_choice]</span> <span style="color: #66cc66;">&quot;Define ORM models first, then convert queries&quot;</span> <span style="opacity: 0.7;">(conf: 0.85)</span>          │
│ ├─ <span style="opacity: 0.5; text-decoration: line-through;">[strategy_choice]</span> <span style="opacity: 0.5; text-decoration: line-through;">&quot;Place models inline in route files&quot;</span> <span style="opacity: 0.5;">(superseded)</span>                     │
│ ├─ <span style="color: #5599ff;">[user_intervention]</span> <span style="color: #66cc66;">&quot;Convert User first, then Session, then Token&quot;</span>                      │
│ ├─ <span style="color: #5599ff;">[strategy_choice]</span> <span style="color: #66cc66;">&quot;Create User ORM model in routes/auth.py&quot;</span> <span style="opacity: 0.7;">(conf: 0.74)</span>                │
│ ├─ <span style="color: #66cc66;">[tool_invocation]</span> write_file src/auth/routes/auth.py                                    │
│ └─ <span style="color: #66cc66;">[tool_invocation]</span> write_file src/auth/routes/session.py                                 │
╰────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Tree Summary ─────────────╮
│ <span style="color: yellow; font-weight: 600;">Nodes:</span> 11                  │
│ <span style="color: #5599ff; font-weight: 600;">Depth:</span> 3                   │
│ <span style="color: #66cc66; font-weight: 600;">Child Plans:</span> 0             │
│ <span style="color: magenta; font-weight: 600;">Invariants:</span> 4              │
│ <span style="color: yellow; font-weight: 600;">Superseded:</span> 1 (shown)      │
╰────────────────────────────╯

╭─ Decision IDs (for correction) ──────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Root:</span> 01HXR3D1A2B3C4D5E6F7G8H9                       │
│ <span style="color: #5599ff; font-weight: 600;">Strategy 1:</span> 01HXR3D2E3F4G5H6I7J8K9L0                 │
│ <span style="opacity: 0.5;">Strategy 2:</span> <span style="opacity: 0.5;">01HXR3D5F6G7H8I9J0K1L2M3 (superseded)</span>    │
│ <span style="color: #66cc66; font-weight: 600;">Intervention:</span> 01HXR3E1A2B3C4D5E6F7G8H9               │
│ <span style="color: #5599ff; font-weight: 600;">Strategy 3:</span> 01HXR3F1A2B3C4D5E6F7G8H9                 │
│ <span style="color: #66cc66; font-weight: 600;">Tool 1:</span> 01HXR3F2B3C4D5E6F7G8H9J0                     │
│ <span style="color: #66cc66; font-weight: 600;">Tool 2:</span> 01HXR3F3C4D5E6F7G8H9J0K1                     │
╰──────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Decision tree rendered

<span style="opacity: 0.7;"># Correct it — revert mode replays from that decision</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan correct 01HXR3F1A2B3C4D5E6F7G8H9 \
    <span style="color: cyan;">--mode</span> revert \
    <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">&quot;Place ORM models in src/auth/models/ with one model per file. \
                Import them in src/auth/models/__init__.py.&quot;</span> <span style="color: cyan;">--yes</span>

╭─ Correction ────────────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Mode:</span> revert                                                │
│ <span style="color: yellow; font-weight: 600;">Impact:</span> 2 decisions, 0 child plans, 2 artifacts             │
│ <span style="color: #66cc66; font-weight: 600;">New Decision:</span> 01HXR3G1A2B3C4D5E6F7G8H9                      │
│ <span style="color: magenta; font-weight: 600;">Corrects:</span> 01HXR3F1A2B3C4D5E6F7G8H9                          │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 2                                                  │
│ <span style="color: #5599ff; font-weight: 600;">Correction ID:</span> 01HXR3CORR1A2B3C4D5E6                        │
╰─────────────────────────────────────────────────────────────╯

╭─ Affected Subtree ──────────────╮
│ <span style="color: yellow; font-weight: 600;">Decisions Invalidated:</span> 2        │
│ <span style="color: yellow; font-weight: 600;">Child Plans Rolled Back:</span> 0      │
│ <span style="color: yellow; font-weight: 600;">Artifacts Archived:</span> 2           │
│ <span style="color: #5599ff; font-weight: 600;">Unaffected Decisions:</span> 6         │
╰─────────────────────────────────╯

╭─ Sandbox Rollback ─────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Checkpoint:</span> cp_01HXR3C4        │
│ <span style="color: #5599ff; font-weight: 600;">Files Reverted:</span> 2              │
│ <span style="color: #66cc66; font-weight: 600;">Status:</span> restored               │
╰────────────────────────────────╯

╭─ Recompute ───────────────╮
│ <span style="color: yellow; font-weight: 600;">Queued:</span> re-execute        │
│ <span style="color: #66cc66; font-weight: 600;">ETA:</span> 3m                   │
╰───────────────────────────╯

╭─ History ───────────────────────────────────────────────╮
│ - Original decision superseded                          │
│ - Prior artifacts archived for comparison               │
│ - agents plan diff <span style="color: cyan;">--correction</span> 01HXR3CORR1A2B3C4D5E6   │
╰─────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Correction applied

<span style="opacity: 0.7;"># The affected subtree is recomputed. Review the new approach:</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan diff <span style="color: cyan;">--correction</span> 01HXR3CORR1A2B3C4D5E6

╭─ Correction Diff ────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Correction:</span> 01HXR3CORR1A2B3C4D5E6                            │
│ <span style="color: #5599ff; font-weight: 600;">Original Decision:</span> 01HXR3F1A2B3C4D5E6F7G8H9                  │
│ <span style="color: #5599ff; font-weight: 600;">Mode:</span> revert                                                 │
│ <span style="color: yellow;">Files Changed:</span> 5                                             │
│ <span style="color: #66cc66;">New Insertions:</span> 84                                           │
│ <span style="color: #ff6666;">New Deletions:</span> 36                                            │
╰──────────────────────────────────────────────────────────────╯

╭─ Comparison ──────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">File</span>                            <span style="color: cyan; font-weight: 600;">Before (original)</span>  <span style="color: cyan; font-weight: 600;">After (corrected)</span>      │
│ <span style="opacity: 0.7;">──────────────────────────────  ────────────────  ────────────────────</span>    │
│ src/auth/routes/auth.py         +42 -8 (inline)   +6 -8 (imports only)    │
│ src/auth/routes/session.py      +28 -6 (inline)   +4 -6 (imports only)    │
│ src/auth/models/__init__.py     (did not exist)    (new file)             │
│ src/auth/models/user.py         (did not exist)    (new file, +38)        │
│ src/auth/models/session.py      (did not exist)    (new file, +26)        │
╰───────────────────────────────────────────────────────────────────────────╯

╭─ Patch Preview (corrected vs original) ───────────────────────────╮
│ <span style="opacity: 0.7;">--- a/src/auth/routes/auth.py (original)</span>                          │
│ <span style="opacity: 0.7;">+++ b/src/auth/routes/auth.py (corrected)</span>                         │
│ <span style="color: cyan;">@@ -1,42 +1,6 @@</span>                                                  │
│ <span style="color: #ff6666;">- class User(Base):  # was inline</span>                                 │
│ <span style="color: #ff6666;">-     __tablename__ = &quot;users&quot;</span>                                     │
│ <span style="color: #ff6666;">-     id = Column(Integer, primary_key=True)</span>                      │
│ <span style="color: #66cc66;">+ from src.auth.models import User</span>                                │
│   ...                                                             │
│ <span style="opacity: 0.7;">+++ b/src/auth/models/user.py (new file)</span>                          │
│ <span style="color: cyan;">@@ -0,0 +1,38 @@</span>                                                  │
│ <span style="color: #66cc66;">+ from sqlalchemy import Column, Integer, String</span>                  │
│ <span style="color: #66cc66;">+ from sqlalchemy.orm import relationship</span>                         │
│ <span style="color: #66cc66;">+ class User(Base):</span>                                               │
│ <span style="color: #66cc66;">+     __tablename__ = &quot;users&quot;</span>                                     │
│   ...                                                             │
╰───────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Correction diff generated
</code></pre></div>

#### Step 5: Apply

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan diff 01HXR3C4D5E6F7G8H9J0K1L2M3

╭─ Diff Summary ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR3C4D5E6F7G8H9J0K1L2M3                     │
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service                           │
│ <span style="color: yellow; font-weight: 600;">Files Changed:</span> 9                                     │
│ <span style="color: #66cc66; font-weight: 600;">Insertions:</span> 186                                      │
│ <span style="color: #ff6666; font-weight: 600;">Deletions:</span> 94                                        │
│ <span style="color: #5599ff; font-weight: 600;">Net Change:</span> +92 lines                                │
╰──────────────────────────────────────────────────────╯

╭─ Files ───────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Path</span>                            <span style="color: cyan; font-weight: 600;">Change</span>    <span style="color: cyan; font-weight: 600;">Status</span>      │
│ <span style="opacity: 0.7;">──────────────────────────────  ────────  ──────────</span>  │
│ src/auth/models/__init__.py     <span style="color: #66cc66; font-weight: 600;">+8</span>        new file    │
│ src/auth/models/user.py         <span style="color: #66cc66; font-weight: 600;">+38</span>       new file    │
│ src/auth/models/session.py      <span style="color: #66cc66; font-weight: 600;">+26</span>       new file    │
│ src/auth/models/token.py        <span style="color: #66cc66; font-weight: 600;">+22</span>       new file    │
│ src/auth/routes/auth.py         <span style="color: #66cc66; font-weight: 600;">+12 -28</span>   modified    │
│ src/auth/routes/session.py      <span style="color: #66cc66; font-weight: 600;">+8 -22</span>    modified    │
│ src/auth/routes/token.py        <span style="color: #66cc66; font-weight: 600;">+6 -18</span>    modified    │
│ src/auth/db.py                  <span style="color: #66cc66; font-weight: 600;">+14 -26</span>   modified    │
│ alembic/versions/001_orm.py     <span style="color: #66cc66; font-weight: 600;">+52</span>       new file    │
╰───────────────────────────────────────────────────────╯

╭─ Risk Assessment ────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">API Compatibility:</span> preserved     │
│ <span style="color: #66cc66; font-weight: 600;">Test Coverage:</span> maintained        │
│ <span style="color: yellow; font-weight: 600;">Breaking Changes:</span> none detected  │
╰──────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Diff generated

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXR3C4D5E6F7G8H9J0K1L2M3

╭─ Apply Summary ───────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR3C4D5E6F7G8H9J0K1L2M3                  │
│ <span style="color: #5599ff; font-weight: 600;">Artifacts:</span> 9 files updated                        │
│ <span style="color: yellow; font-weight: 600;">Changes:</span> 186 insertions, 94 deletions             │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/api-service                        │
│ <span style="color: #66cc66; font-weight: 600;">Applied At:</span> 2026-02-11 09:23                      │
╰───────────────────────────────────────────────────╯

╭─ Validation ───────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Tests:</span> passed (47/47)              │
│ <span style="color: #66cc66; font-weight: 600;">Lint:</span> passed (0 warnings)          │
│ <span style="color: #66cc66; font-weight: 600;">Type Check:</span> passed (0 errors)      │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 18.6s                    │
╰────────────────────────────────────╯

╭─ Sandbox Cleanup ─────────╮
│ <span style="color: #66cc66; font-weight: 600;">Worktree:</span> removed         │
│ <span style="color: #66cc66; font-weight: 600;">Branch:</span> merged to main    │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoint:</span> archived      │
╰───────────────────────────╯

╭─ Plan Lifecycle ───────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Phase:</span> applied                                 │
│ <span style="color: #66cc66; font-weight: 600;">State:</span> complete                                │
│ <span style="color: #5599ff; font-weight: 600;">Total Duration:</span> 00:08:42                       │
│ <span style="color: yellow; font-weight: 600;">Total Cost:</span> $0.128                             │
│ <span style="color: #5599ff; font-weight: 600;">Decisions Made:</span> 11                             │
│ <span style="color: #5599ff; font-weight: 600;">Corrections:</span> 1                                 │
│ <span style="color: #5599ff; font-weight: 600;">Child Plans:</span> 0                                 │
╰────────────────────────────────────────────────╯

╭─ Next Steps ──────╮
│ - Review git diff │
│ - Commit changes  │
╰───────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied
</code></pre></div>

---

### Example 4: Multi-Project Dependency Update

**Scenario**: An organization has three microservices that share a common library. The library has a breaking change that requires coordinated updates across all three services. The update must be validated in each service independently before any changes are applied.

**Complexity**: Advanced. Multiple projects, child plans, coordinated apply.

#### Step 1: Register All Projects and Resources

<div class="highlight"><pre><code><span style="opacity: 0.7;"># Register the common-lib resource (full output shown)</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add git-checkout local/common-lib-repo <span style="color: cyan;">--path</span> /repos/common-lib <span style="color: cyan;">--branch</span> main

╭─ Resource ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/common-lib-repo                    │
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXR4A1B2C3D4E5F6G7H8J9K0                  │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> git-checkout                              │
│ <span style="color: #5599ff; font-weight: 600;">Physical/Virtual:</span> physical                      │
│ <span style="color: #66cc66; font-weight: 600;">Path:</span> /repos/common-lib                         │
│ <span style="color: #5599ff; font-weight: 600;">Branch:</span> main                                    │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 10:00                       │
╰─────────────────────────────────────────────────╯

╭─ Auto-discovered Children ─────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>               <span style="color: cyan; font-weight: 600;">Type</span>            <span style="color: cyan; font-weight: 600;">Status</span>                            │
│ <span style="opacity: 0.7;">───────────────  ──────────────  ─────────────────</span>                 │
│ 01HXR4A1B2C3…   git             <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│ 01HXR4A1B2C4…   git-remote      <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│ 01HXR4A1B2C5…   git-branch      <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│   + 31 git-commit resources                                        │
│   + 186 git-tree-entry resources                                   │
│   + 2 fs-directory + 14 fs-file                                    │
╰────────────────────────────────────────────────────────────────────╯

╭─ Capabilities ─────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Readable:</span> yes                  │
│ <span style="color: yellow; font-weight: 600;">Writable:</span> yes                  │
│ <span style="color: #66cc66; font-weight: 600;">Sandboxable:</span> yes               │
│ <span style="color: #66cc66; font-weight: 600;">Checkpointable:</span> yes            │
│ <span style="color: #5599ff; font-weight: 600;">Sandbox Strategy:</span> git_worktree │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource registered (236 child resources discovered)

<span style="opacity: 0.7;"># Register the remaining 3 service resources (condensed output)</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add git-checkout local/user-service-repo <span style="color: cyan;">--path</span> /repos/user-service <span style="color: cyan;">--branch</span> main
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource registered — <span style="color: cyan; font-weight: 600;">Name:</span> local/user-service-repo (312 children)

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add git-checkout local/order-service-repo <span style="color: cyan;">--path</span> /repos/order-service <span style="color: cyan;">--branch</span> main
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource registered — <span style="color: cyan; font-weight: 600;">Name:</span> local/order-service-repo (287 children)

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add git-checkout local/billing-service-repo <span style="color: cyan;">--path</span> /repos/billing-service <span style="color: cyan;">--branch</span> main
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource registered — <span style="color: cyan; font-weight: 600;">Name:</span> local/billing-service-repo (264 children)
</code></pre></div>

<div class="highlight"><pre><code><span style="opacity: 0.7;"># Create the common-lib project (full output shown)</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project create <span style="color: cyan;">-d</span> <span style="color: #66cc66;">"Shared common library"</span> \
    <span style="color: cyan;">--resource</span> local/common-lib-repo local/common-lib

╭─ Project Created ─────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/common-lib                    │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Shared common library        │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> local                               │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 10:01                 │
╰───────────────────────────────────────────╯

╭─ Linked Resources ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Resource</span>               <span style="color: cyan; font-weight: 600;">Type</span>          <span style="color: cyan; font-weight: 600;">Read-Only</span>            │
│ <span style="opacity: 0.7;">─────────────────────  ──────────────  ─────────</span>         │
│ local/common-lib-repo  git-checkout    no                 │
╰──────────────────────────────────────────────────────────╯

╭─ Defaults ──────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Sandbox:</span> git_worktree                   │
│ <span style="color: #66cc66; font-weight: 600;">Validations:</span> 0                          │
│ <span style="color: yellow; font-weight: 600;">Context Filters:</span> none                   │
│ <span style="color: magenta; font-weight: 600;">Automation Profile:</span> (inherits global)   │
╰─────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project created

<span style="opacity: 0.7;"># Create the remaining 3 service projects (condensed output)</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project create <span style="color: cyan;">-d</span> <span style="color: #66cc66;">"User microservice"</span> \
    <span style="color: cyan;">--resource</span> local/user-service-repo local/user-service
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project created — <span style="color: cyan; font-weight: 600;">Name:</span> local/user-service

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project create <span style="color: cyan;">-d</span> <span style="color: #66cc66;">"Order microservice"</span> \
    <span style="color: cyan;">--resource</span> local/order-service-repo local/order-service
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project created — <span style="color: cyan; font-weight: 600;">Name:</span> local/order-service

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project create <span style="color: cyan;">-d</span> <span style="color: #66cc66;">"Billing microservice"</span> \
    <span style="color: cyan;">--resource</span> local/billing-service-repo local/billing-service
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project created — <span style="color: cyan; font-weight: 600;">Name:</span> local/billing-service
</code></pre></div>

<div class="highlight"><pre><code><span style="opacity: 0.7;"># Register a shared validation — first one with full output</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation add <span style="color: cyan;">--config</span> validations/pytest-mypy.yaml <span style="color: cyan;">--required</span> local/pytest-mypy

╭─ Validation Registered ─────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/pytest-mypy                              │
│ <span style="color: #5599ff; font-weight: 600;">Command:</span> pytest tests/ && mypy src/                 │
│ <span style="color: #66cc66; font-weight: 600;">Mode:</span> required                                      │
│ <span style="color: yellow; font-weight: 600;">Timeout:</span> 300s                                       │
╰─────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation registered

<span style="opacity: 0.7;"># Attach the validation to all 4 projects</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> local/common-lib local/pytest-mypy
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached to project local/common-lib

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> local/user-service local/pytest-mypy
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached to project local/user-service

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> local/order-service local/pytest-mypy
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached to project local/order-service

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> local/billing-service local/pytest-mypy
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached to project local/billing-service
</code></pre></div>

#### Step 2: Create a Coordinated Update Action

Create `actions/coordinated-dependency-update.yaml`:

<div class="highlight"><pre><code><span style="color: cyan; font-weight: 600;">name</span>: local/coordinated-dep-update
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Update a shared dependency across multiple projects"</span>
<span style="color: cyan; font-weight: 600;">long_description</span>: |
  When a shared library introduces a breaking change, this action coordinates
  the update across all dependent projects. It analyzes the breaking changes,
  creates per-project update plans as child plans, validates each independently,
  and produces a coordinated changeset.
<span style="color: cyan; font-weight: 600;">definition_of_done</span>: |
  - The shared library is updated to the target version
  - All dependent projects compile and pass tests with the new version
  - API contracts between services remain compatible
  - Migration guides are generated for each project if needed
  - All changes can be applied atomically or rolled back as a unit
<span style="color: cyan; font-weight: 600;">strategy_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">execution_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">automation_profile</span>: supervised
<span style="color: cyan; font-weight: 600;">reusable</span>: <span style="color: yellow;">true</span>
<span style="color: cyan; font-weight: 600;">state</span>: <span style="color: yellow;">available</span>
<span style="color: cyan; font-weight: 600;">args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: library_name
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Name of the shared library to update"</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: target_version
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Target version to update to"</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: changelog_url
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"URL to the library changelog or migration guide"</span>
<span style="color: cyan; font-weight: 600;">invariants</span>:
  - <span style="color: #66cc66;">"Each dependent project must be updated in its own child plan"</span>
  - <span style="color: #66cc66;">"All child plans must pass validation before any can be applied"</span>
  - <span style="color: #66cc66;">"The library update in common-lib must be applied first"</span>
</code></pre></div>

<div class="highlight"><pre><code><span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action create <span style="color: cyan;">--config</span> ./actions/coordinated-dependency-update.yaml

╭─ Action Created ─────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/coordinated-dep-update                           │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> 01HXR4B1D2E3F4G5H6J7K8L9M0                               │
│ <span style="color: yellow; font-weight: 600;">State:</span> available                                             │
│ <span style="color: magenta; font-weight: 600;">Strategy Actor:</span> anthropic/claude-3.5-sonnet                  │
│ <span style="color: magenta; font-weight: 600;">Execution Actor:</span> anthropic/claude-3.5-sonnet                 │
│ <span style="color: #66cc66; font-weight: 600;">Reusable:</span> yes                                                │
│ <span style="color: #5599ff; font-weight: 600;">Read Only:</span> no                                                │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 10:02                                    │
╰──────────────────────────────────────────────────────────────╯

╭─ Definition of Done ──────────────────────────────────────────────────╮
│ - The shared library is updated to the target version                 │
│ - All dependent projects compile and pass tests with the new version  │
│ - API contracts between services remain compatible                    │
│ - Migration guides are generated for each project if needed           │
│ - All changes can be applied atomically or rolled back as a unit      │
╰───────────────────────────────────────────────────────────────────────╯

╭─ Arguments ──────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>            <span style="color: cyan; font-weight: 600;">Type</span>    <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>                                    │
│ <span style="opacity: 0.7;">──────────────  ──────  ────────  ──────────────────────────────────────────</span>     │
│ library_name    string  yes       Name of the shared library to update           │
│ target_version  string  yes       Target version to update to                    │
│ changelog_url   string  no        URL to the library changelog or migration      │
╰──────────────────────────────────────────────────────────────────────────────────╯

╭─ Automation ──────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> supervised                   │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> action config                 │
╰───────────────────────────────────────╯

╭─ Action Invariants ──────────────────────────────────────────────────────────────╮
│ 1. Each dependent project must be updated in its own child plan                  │
│ 2. All child plans must pass validation before any can be applied                │
│ 3. The library update in common-lib must be applied first                        │
╰──────────────────────────────────────────────────────────────────────────────────╯

╭─ Usage ───────────────────────────────────────────────────────────────────────────╮
│ agents plan use local/coordinated-dep-update local/common-lib                     │
│   <span style="color: cyan;">--arg</span> library_name=&quot;authlib&quot; <span style="color: cyan;">--arg</span> target_version=&quot;2.0.0&quot;                       │
╰───────────────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Action created
</code></pre></div>

#### Step 3: Execute Across Multiple Projects

<div class="highlight"><pre><code><span style="opacity: 0.7;"># Create a plan targeting all four projects</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan use \
    <span style="color: cyan;">--automation-profile</span> supervised \
    <span style="color: cyan;">--arg</span> library_name=<span style="color: #66cc66;">"authlib"</span> \
    <span style="color: cyan;">--arg</span> target_version=<span style="color: #66cc66;">"2.0.0"</span> \
    <span style="color: cyan;">--arg</span> changelog_url=<span style="color: #66cc66;">"https://authlib.org/changelog/2.0"</span> \
    local/coordinated-dep-update \
    local/common-lib local/user-service local/order-service local/billing-service

╭─ Plan Created ────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR4D5E6F7G8H9J0K1L2M3N4                          │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/coordinated-dep-update                      │
│ <span style="color: #5599ff; font-weight: 600;">Projects:</span> local/common-lib, local/user-service,           │
│           local/order-service, local/billing-service      │
│ <span style="color: #66cc66; font-weight: 600;">Automation:</span> supervised                                    │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                                │
╰───────────────────────────────────────────────────────────╯

╭─ Inputs ───────────────────────────────────────────────────────────╮
│ - library_name=&quot;authlib&quot;                                           │
│ - target_version=&quot;2.0.0&quot;                                           │
│ - changelog_url=&quot;https://authlib.org/changelog/2.0&quot;                │
│ - automation_profile=supervised                                    │
╰────────────────────────────────────────────────────────────────────╯

╭─ Actors ───────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Strategy:</span> anthropic/claude-3.5-sonnet          │
│ <span style="color: magenta; font-weight: 600;">Execution:</span> anthropic/claude-3.5-sonnet         │
╰────────────────────────────────────────────────╯

╭─ Automation ──────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> supervised                       │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> CLI override                      │
│ <span style="color: #5599ff; font-weight: 600;">Read-Only:</span> no                             │
╰───────────────────────────────────────────╯

╭─ Context ──────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Resources:</span> 4 (git-checkout)        │
│ <span style="color: #5599ff; font-weight: 600;">Indexed Files:</span> 1,099               │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> strategize                   │
│ <span style="color: #5599ff; font-weight: 600;">Hot Token Budget:</span> 24,000           │
╰────────────────────────────────────╯

╭─ Next Steps ──────────────────────────────────────────────╮
│ - agents plan tree 01HXR4D5E6F7G8H9J0K1L2M3N4             │
│ - agents plan status 01HXR4D5E6F7G8H9J0K1L2M3N4           │
│ - agents plan execute 01HXR4D5E6F7G8H9J0K1L2M3N4          │
╰───────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan created
</code></pre></div>

The system creates a parent plan. Strategize runs automatically (supervised profile). It produces a strategy that:

1. Analyzes the breaking changes in authlib 2.0.0
2. Plans child plans for each project
3. Orders the updates: common-lib first, then services in parallel

<div class="highlight"><pre><code><span style="opacity: 0.7;"># Review the strategy before execution begins</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan tree 01HXR4D5E6F7G8H9J0K1L2M3N4

╭─ Decision Tree ─────────────────────────────────────────────────────────────────────────────────────╮
│ Plan: 01HXR4D5E6F7G8H9J0K1L2M3N4                                                                    │
│ ├─ <span style="color: white;">[prompt_definition]</span> <span style="color: #66cc66;">&quot;Update authlib to 2.0.0 across 4 projects&quot;</span>                                  │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">&quot;Each dependent project must be updated in its own child plan&quot;</span>              │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">&quot;All child plans must pass validation before any can be applied&quot;</span>            │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">&quot;The library update in common-lib must be applied first&quot;</span>                    │
│ ├─ <span style="color: #5599ff;">[strategy_choice]</span> <span style="color: #66cc66;">&quot;Analyze changelog for breaking API changes&quot;</span> <span style="opacity: 0.7;">(conf: 0.92)</span>                      │
│ ├─ <span style="color: #5599ff;">[strategy_choice]</span> <span style="color: #66cc66;">&quot;Update common-lib first, then services in parallel&quot;</span> <span style="opacity: 0.7;">(conf: 0.88)</span>              │
│ ├─ <span style="color: #5599ff;">[strategy_choice]</span> <span style="color: #66cc66;">&quot;Create 4 child plans: common-lib, user-svc, order-svc, billing-svc&quot;</span>           │
│ │                     <span style="opacity: 0.7;">(conf: 0.90)</span>                                                                  │
│ └─ <span style="color: yellow; font-weight: 600;">•</span> (awaiting execution approval — supervised profile)                                             │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Tree Summary ──────────────╮
│ <span style="color: yellow; font-weight: 600;">Nodes:</span> 8                    │
│ <span style="color: #5599ff; font-weight: 600;">Depth:</span> 2                    │
│ <span style="color: #66cc66; font-weight: 600;">Child Plans:</span> 0 (planned: 4) │
│ <span style="color: magenta; font-weight: 600;">Invariants:</span> 3               │
│ <span style="color: #5599ff; font-weight: 600;">Superseded:</span> 0 (hidden)      │
╰─────────────────────────────╯

╭─ Decision IDs (for correction) ──────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Root:</span> 01HXR4D6A1B2C3D4E5F6G7H8                           │
│ <span style="color: magenta; font-weight: 600;">Invariant 1:</span> 01HXR4D6B2C3D4E5F6G7H8J9                    │
│ <span style="color: magenta; font-weight: 600;">Invariant 2:</span> 01HXR4D6C3D4E5F6G7H8J9K0                    │
│ <span style="color: magenta; font-weight: 600;">Invariant 3:</span> 01HXR4D6D4E5F6G7H8J9K0L1                    │
│ <span style="color: #5599ff; font-weight: 600;">Strategy 1:</span> 01HXR4D7E5F6G7H8I9J0K1L2                     │
│ <span style="color: #5599ff; font-weight: 600;">Strategy 2:</span> 01HXR4D7F6G7H8I9J0K1L2M3                     │
│ <span style="color: #5599ff; font-weight: 600;">Strategy 3:</span> 01HXR4D7G7H8I9J0K1L2M3N4                     │
╰──────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Decision tree rendered

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan status 01HXR4D5E6F7G8H9J0K1L2M3N4

╭─ Plan Status ──────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR4D5E6F7G8H9J0K1L2M3N4                       │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> strategize → execute (pending approval)         │
│ <span style="color: magenta; font-weight: 600;">State:</span> awaiting_input                                  │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/coordinated-dep-update                   │
│ <span style="color: #66cc66; font-weight: 600;">Projects:</span> 4                                            │
│ <span style="color: #5599ff; font-weight: 600;">Automation:</span> supervised                                 │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                             │
╰────────────────────────────────────────────────────────╯

╭─ Progress ────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Strategize                          │
│ <span style="color: yellow; font-weight: 600;">⏸</span> Execute (awaiting approval)         │
│ <span style="color: yellow; font-weight: 600;">•</span> Apply (queued)                      │
╰───────────────────────────────────────╯

╭─ Timing ──────────╮
│ <span style="color: #66cc66; font-weight: 600;">Started:</span> 10:02:14 │
│ <span style="color: yellow; font-weight: 600;">Elapsed:</span> 00:01:42 │
│ <span style="color: #66cc66; font-weight: 600;">ETA:</span> 00:12:00     │
╰───────────────────╯

╭─ Cost ───────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Tokens Used:</span> 8,420   │
│ <span style="color: yellow; font-weight: 600;">Cost So Far:</span> $0.028  │
│ <span style="color: #5599ff; font-weight: 600;">Estimated:</span> $0.340    │
╰──────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Status refreshed

<span style="opacity: 0.7;"># Manually approve execution (supervised requires explicit approval)</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan execute 01HXR4D5E6F7G8H9J0K1L2M3N4

╭─ Execution Started ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR4D5E6F7G8H9J0K1L2M3N4                         │
│ <span style="color: #5599ff; font-weight: 600;">Phase:</span> execute                                           │
│ <span style="color: magenta; font-weight: 600;">State:</span> processing                                        │
│ <span style="color: #66cc66; font-weight: 600;">Automation:</span> supervised                                   │
╰──────────────────────────────────────────────────────────╯

╭─ Child Plans Spawned ───────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan ID</span>                       <span style="color: cyan; font-weight: 600;">Project</span>              <span style="color: cyan; font-weight: 600;">Status</span>               │
│ <span style="opacity: 0.7;">──────────────────────────  ───────────────────  ────────────────</span>       │
│ 01HXR4C1D2E3F4G5H6I7J8K9   local/common-lib     <span style="color: cyan; font-weight: 600;">executing</span>               │
│ 01HXR4C2E3F4G5H6I7J8K9L0   local/user-service    <span style="color: yellow; font-weight: 600;">waiting</span> (common)       │
│ 01HXR4C3F4G5H6I7J8K9L0M1   local/order-service   <span style="color: yellow; font-weight: 600;">waiting</span> (common)       │
│ 01HXR4C4G5H6I7J8K9L0M1N2   local/billing-service <span style="color: yellow; font-weight: 600;">waiting</span> (common)       │
╰─────────────────────────────────────────────────────────────────────────╯

╭─ Execution Order ──────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Phase 1:</span> common-lib (blocking)                             │
│ <span style="color: cyan; font-weight: 600;">Phase 2:</span> user-service, order-service, billing-service      │
│          (parallel, after common-lib completes)            │
╰────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Execution started (4 child plans spawned)
</code></pre></div>

#### Step 4: Review and Apply in Order

Once all child plans complete execution and pass validation, review and apply them in dependency order.

<div class="highlight"><pre><code><span style="opacity: 0.7;"># Review common-lib changes first (must be applied before services)</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan diff 01HXR4C1D2E3F4G5H6I7J8K9

╭─ Diff Summary ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR4C1D2E3F4G5H6I7J8K9                       │
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/common-lib                            │
│ <span style="color: yellow; font-weight: 600;">Files Changed:</span> 4                                     │
│ <span style="color: #66cc66; font-weight: 600;">Insertions:</span> 62                                       │
│ <span style="color: #ff6666; font-weight: 600;">Deletions:</span> 38                                        │
│ <span style="color: #5599ff; font-weight: 600;">Net Change:</span> +24 lines                                │
╰──────────────────────────────────────────────────────╯

╭─ Files ───────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Path</span>                              <span style="color: cyan; font-weight: 600;">Change</span>    <span style="color: cyan; font-weight: 600;">Status</span>            │
│ <span style="opacity: 0.7;">────────────────────────────────  ────────  ──────────</span>        │
│ requirements.txt                  <span style="color: #66cc66; font-weight: 600;">+1 -1</span>     modified          │
│ src/common/auth.py                <span style="color: #66cc66; font-weight: 600;">+28 -19</span>   modified          │
│ src/common/token_validator.py     <span style="color: #66cc66; font-weight: 600;">+18 -12</span>   modified          │
│ tests/test_auth.py                <span style="color: #66cc66; font-weight: 600;">+15 -6</span>    modified          │
╰───────────────────────────────────────────────────────────────╯

╭─ Patch Preview ───────────────────────────────────────────────────╮
│ <span style="opacity: 0.7;">--- a/requirements.txt</span>                                            │
│ <span style="opacity: 0.7;">+++ b/requirements.txt</span>                                            │
│ <span style="color: cyan;">@@ -3,1 +3,1 @@</span>                                                   │
│ <span style="color: #ff6666;">- authlib==1.3.2</span>                                                  │
│ <span style="color: #66cc66;">+ authlib==2.0.0</span>                                                  │
│ <span style="opacity: 0.7;">--- a/src/common/auth.py</span>                                          │
│ <span style="opacity: 0.7;">+++ b/src/common/auth.py</span>                                          │
│ <span style="color: cyan;">@@ -1,6 +1,8 @@</span>                                                   │
│ <span style="color: #ff6666;">- from authlib.integrations.requests_client import OAuth2Session</span>  │
│ <span style="color: #66cc66;">+ from authlib.integrations.httpx_client import AsyncOAuth2Client</span> │
│   ...                                                             │
╰───────────────────────────────────────────────────────────────────╯

╭─ Validation ────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">pytest tests/ && mypy src/:</span> passed  │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 12.4s                     │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Diff generated

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXR4C1D2E3F4G5H6I7J8K9

╭─ Apply Summary ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR4C1D2E3F4G5H6I7J8K9                       │
│ <span style="color: #5599ff; font-weight: 600;">Artifacts:</span> 4 files updated                           │
│ <span style="color: yellow; font-weight: 600;">Changes:</span> 62 insertions, 38 deletions                 │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/common-lib                            │
│ <span style="color: #66cc66; font-weight: 600;">Applied At:</span> 2026-02-11 10:14                         │
╰──────────────────────────────────────────────────────╯

╭─ Validation ───────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Tests:</span> passed (24/24)              │
│ <span style="color: #66cc66; font-weight: 600;">Type Check:</span> passed (0 errors)      │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 12.4s                    │
╰────────────────────────────────────╯

╭─ Sandbox Cleanup ─────────╮
│ <span style="color: #66cc66; font-weight: 600;">Worktree:</span> removed         │
│ <span style="color: #66cc66; font-weight: 600;">Branch:</span> merged to main    │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoint:</span> archived      │
╰───────────────────────────╯

╭─ Plan Lifecycle ───────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Phase:</span> applied                                 │
│ <span style="color: #66cc66; font-weight: 600;">State:</span> complete                                │
│ <span style="color: #5599ff; font-weight: 600;">Total Duration:</span> 00:03:18                       │
│ <span style="color: yellow; font-weight: 600;">Total Cost:</span> $0.064                             │
╰────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied
</code></pre></div>

<div class="highlight"><pre><code><span style="opacity: 0.7;"># Once common-lib is applied, review the 3 service child plans.</span>
<span style="opacity: 0.7;"># Full diff shown for user-service; order-service and billing-service condensed.</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan diff 01HXR4C2E3F4G5H6I7J8K9L0

╭─ Diff Summary ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR4C2E3F4G5H6I7J8K9L0                       │
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/user-service                          │
│ <span style="color: yellow; font-weight: 600;">Files Changed:</span> 6                                     │
│ <span style="color: #66cc66; font-weight: 600;">Insertions:</span> 84                                       │
│ <span style="color: #ff6666; font-weight: 600;">Deletions:</span> 52                                        │
│ <span style="color: #5599ff; font-weight: 600;">Net Change:</span> +32 lines                                │
╰──────────────────────────────────────────────────────╯

╭─ Files ───────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Path</span>                              <span style="color: cyan; font-weight: 600;">Change</span>    <span style="color: cyan; font-weight: 600;">Status</span>            │
│ <span style="opacity: 0.7;">────────────────────────────────  ────────  ──────────</span>        │
│ requirements.txt                  <span style="color: #66cc66; font-weight: 600;">+1 -1</span>     modified          │
│ src/auth/middleware.py             <span style="color: #66cc66; font-weight: 600;">+22 -14</span>   modified         │
│ src/auth/oauth.py                  <span style="color: #66cc66; font-weight: 600;">+18 -12</span>   modified         │
│ src/auth/token.py                  <span style="color: #66cc66; font-weight: 600;">+16 -11</span>   modified         │
│ tests/test_middleware.py           <span style="color: #66cc66; font-weight: 600;">+14 -8</span>    modified         │
│ tests/test_oauth.py                <span style="color: #66cc66; font-weight: 600;">+13 -6</span>    modified         │
╰───────────────────────────────────────────────────────────────╯

╭─ Validation ────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">pytest tests/ && mypy src/:</span> passed  │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 18.2s                     │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Diff generated

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan diff 01HXR4C3F4G5H6I7J8K9L0M1

╭─ Diff Summary ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR4C3F4G5H6I7J8K9L0M1                       │
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/order-service                         │
│ <span style="color: yellow; font-weight: 600;">Files Changed:</span> 5                                     │
│ <span style="color: #66cc66; font-weight: 600;">Insertions:</span> 71                                       │
│ <span style="color: #ff6666; font-weight: 600;">Deletions:</span> 46                                        │
│ <span style="color: #5599ff; font-weight: 600;">Net Change:</span> +25 lines                                │
╰──────────────────────────────────────────────────────╯

╭─ Validation ────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">pytest tests/ && mypy src/:</span> passed  │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 14.7s                     │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Diff generated

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan diff 01HXR4C4G5H6I7J8K9L0M1N2

╭─ Diff Summary ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR4C4G5H6I7J8K9L0M1N2                       │
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/billing-service                       │
│ <span style="color: yellow; font-weight: 600;">Files Changed:</span> 4                                     │
│ <span style="color: #66cc66; font-weight: 600;">Insertions:</span> 58                                       │
│ <span style="color: #ff6666; font-weight: 600;">Deletions:</span> 34                                        │
│ <span style="color: #5599ff; font-weight: 600;">Net Change:</span> +24 lines                                │
╰──────────────────────────────────────────────────────╯

╭─ Validation ────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">pytest tests/ && mypy src/:</span> passed  │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 11.3s                     │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Diff generated

<span style="opacity: 0.7;"># Apply all 3 service child plans</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXR4C2E3F4G5H6I7J8K9L0

╭─ Apply Summary ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR4C2E3F4G5H6I7J8K9L0                       │
│ <span style="color: #5599ff; font-weight: 600;">Artifacts:</span> 6 files updated                           │
│ <span style="color: yellow; font-weight: 600;">Changes:</span> 84 insertions, 52 deletions                 │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/user-service                          │
│ <span style="color: #66cc66; font-weight: 600;">Applied At:</span> 2026-02-11 10:16                         │
╰──────────────────────────────────────────────────────╯

╭─ Validation ───────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Tests:</span> passed (89/89)              │
│ <span style="color: #66cc66; font-weight: 600;">Type Check:</span> passed (0 errors)      │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 18.2s                    │
╰────────────────────────────────────╯

╭─ Sandbox Cleanup ─────────╮
│ <span style="color: #66cc66; font-weight: 600;">Worktree:</span> removed         │
│ <span style="color: #66cc66; font-weight: 600;">Branch:</span> merged to main    │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoint:</span> archived      │
╰───────────────────────────╯

╭─ Plan Lifecycle ───────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Phase:</span> applied                                 │
│ <span style="color: #66cc66; font-weight: 600;">State:</span> complete                                │
│ <span style="color: #5599ff; font-weight: 600;">Total Duration:</span> 00:04:12                       │
│ <span style="color: yellow; font-weight: 600;">Total Cost:</span> $0.082                             │
╰────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXR4C3F4G5H6I7J8K9L0M1

╭─ Apply Summary ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR4C3F4G5H6I7J8K9L0M1                       │
│ <span style="color: #5599ff; font-weight: 600;">Artifacts:</span> 5 files updated                           │
│ <span style="color: yellow; font-weight: 600;">Changes:</span> 71 insertions, 46 deletions                 │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/order-service                         │
│ <span style="color: #66cc66; font-weight: 600;">Applied At:</span> 2026-02-11 10:17                         │
╰──────────────────────────────────────────────────────╯

╭─ Validation ───────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Tests:</span> passed (76/76)              │
│ <span style="color: #66cc66; font-weight: 600;">Type Check:</span> passed (0 errors)      │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 14.7s                    │
╰────────────────────────────────────╯

╭─ Plan Lifecycle ───────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Phase:</span> applied                                 │
│ <span style="color: #66cc66; font-weight: 600;">State:</span> complete                                │
│ <span style="color: #5599ff; font-weight: 600;">Total Duration:</span> 00:03:48                       │
│ <span style="color: yellow; font-weight: 600;">Total Cost:</span> $0.074                             │
╰────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXR4C4G5H6I7J8K9L0M1N2

╭─ Apply Summary ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR4C4G5H6I7J8K9L0M1N2                       │
│ <span style="color: #5599ff; font-weight: 600;">Artifacts:</span> 4 files updated                           │
│ <span style="color: yellow; font-weight: 600;">Changes:</span> 58 insertions, 34 deletions                 │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/billing-service                       │
│ <span style="color: #66cc66; font-weight: 600;">Applied At:</span> 2026-02-11 10:18                         │
╰──────────────────────────────────────────────────────╯

╭─ Validation ───────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Tests:</span> passed (63/63)              │
│ <span style="color: #66cc66; font-weight: 600;">Type Check:</span> passed (0 errors)      │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 11.3s                    │
╰────────────────────────────────────╯

╭─ Plan Lifecycle ───────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Phase:</span> applied                                 │
│ <span style="color: #66cc66; font-weight: 600;">State:</span> complete                                │
│ <span style="color: #5599ff; font-weight: 600;">Total Duration:</span> 00:03:22                       │
│ <span style="color: yellow; font-weight: 600;">Total Cost:</span> $0.068                             │
╰────────────────────────────────────────────────╯

╭─ Parent Plan Complete ──────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR4D5E6F7G8H9J0K1L2M3N4                        │
│ <span style="color: #66cc66; font-weight: 600;">Phase:</span> applied                                          │
│ <span style="color: #66cc66; font-weight: 600;">State:</span> complete                                         │
│ <span style="color: #5599ff; font-weight: 600;">Child Plans:</span> 4/4 complete                               │
│ <span style="color: #5599ff; font-weight: 600;">Total Duration:</span> 00:16:04                                │
│ <span style="color: yellow; font-weight: 600;">Total Cost:</span> $0.340                                      │
│ <span style="color: #66cc66; font-weight: 600;">All Validations:</span> passed                                 │
╰─────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied
</code></pre></div>

---

### Example 5: Database Schema Migration with Safety Nets

**Scenario**: A team needs to add a `last_login_at` column to a users table with 10 million rows, backfill it from an audit log, and update the application code — all without downtime.

**Complexity**: Advanced. Mixed resource types (git + database), custom tools, checkpointing critical.

#### Step 1: Register the Database as a Resource

Register the custom resource type, then create a resource instance and link it to the project:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Register the custom postgres-db resource type</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource type add <span style="color: cyan;">--config</span> ./resource-types/postgres-db.yaml

╭─ Resource Type ─────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/postgres-db                 │
│ <span style="color: #5599ff; font-weight: 600;">Physical/Virtual:</span> physical              │
│ <span style="color: #5599ff; font-weight: 600;">User Addable:</span> yes                       │
│ <span style="color: #66cc66; font-weight: 600;">Registered:</span> 2026-02-11 09:01            │
╰─────────────────────────────────────────╯

╭─ CLI Arguments ──────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Argument</span>      <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>                      │
│ <span style="opacity: 0.7;">────────────  ────────  ──────────────────────────────</span>   │
│ <span style="color: cyan;">--host</span>        yes       Database hostname                │
│ <span style="color: cyan;">--port</span>        no        Port (default: 5432)             │
│ <span style="color: cyan;">--database</span>    yes       Database name                    │
│ <span style="color: cyan;">--schema</span>      no        Schema (default: public)         │
╰──────────────────────────────────────────────────────────╯

╭─ Sandbox ──────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Strategy:</span> transaction_rollback         │
│ <span style="color: #5599ff; font-weight: 600;">Handler:</span> PostgresHandler (custom)      │
╰────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource type registered
<span style="color: cyan; font-weight: 600;">ℹ</span> New subcommand available: agents resource add local/postgres-db
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Register the production database instance</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add local/postgres-db local/prod-users-db \
    <span style="color: cyan;">--host</span> db.internal.example.com \
    <span style="color: cyan;">--port</span> <span style="color: yellow;">5432</span> \
    <span style="color: cyan;">--database</span> users_db \
    <span style="color: cyan;">--schema</span> public

╭─ Resource ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/prod-users-db                       │
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXR5D3E4F5G6H7J8K9L0M1N2                   │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> local/postgres-db                          │
│ <span style="color: #5599ff; font-weight: 600;">Physical/Virtual:</span> physical                       │
│ <span style="color: #66cc66; font-weight: 600;">Host:</span> db.internal.example.com                    │
│ <span style="color: #5599ff; font-weight: 600;">Port:</span> 5432                                       │
│ <span style="color: #5599ff; font-weight: 600;">Database:</span> users_db                               │
│ <span style="color: #5599ff; font-weight: 600;">Schema:</span> public                                   │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 09:02                        │
╰──────────────────────────────────────────────────╯

╭─ Capabilities ──────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Readable:</span> yes                           │
│ <span style="color: yellow; font-weight: 600;">Writable:</span> yes                           │
│ <span style="color: #66cc66; font-weight: 600;">Sandboxable:</span> yes                        │
│ <span style="color: #66cc66; font-weight: 600;">Checkpointable:</span> yes                     │
│ <span style="color: #5599ff; font-weight: 600;">Sandbox Strategy:</span> transaction_rollback  │
╰─────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource registered
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Link the database resource to the project</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project link-resource local/api-service local/prod-users-db

╭─ Resource Linked ────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service                   │
│ <span style="color: #5599ff; font-weight: 600;">Resource:</span> local/prod-users-db                │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> local/postgres-db                      │
│ <span style="color: #5599ff; font-weight: 600;">Read-Only:</span> no                                │
╰──────────────────────────────────────────────╯

╭─ Access ─────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Read:</span> allowed            │
│ <span style="color: yellow; font-weight: 600;">Write:</span> allowed           │
│ <span style="color: #5599ff; font-weight: 600;">Apply:</span> requires approval │
╰──────────────────────────╯

╭─ Project Resources ─────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>                            <span style="color: cyan; font-weight: 600;">Type</span>              <span style="color: cyan; font-weight: 600;">Status</span>          │
│ <span style="opacity: 0.7;">──────────────────────────────  ────────────────  ──────────</span>    │
│ 01HXR1A1B2C3D4E5F6G7H8J9K0   git-checkout      linked           │
│ 01HXR5D3E4F5G6H7J8K9L0M1N2   local/postgres-db <span style="color: #66cc66; font-weight: 600;">linked (new)</span>     │
╰─────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource linked to project
</code></pre></div>

#### Step 2: Create a Custom Skill with Database Tools

Create `skills/database-ops.yaml`:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">name</span>: local/database-ops
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Safe database operations with transaction support"</span>
<span style="color: cyan; font-weight: 600;">tools</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: query_db
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Execute a read-only SQL query and return results"</span>
    <span style="color: cyan; font-weight: 600;">input_schema</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: object
      <span style="color: cyan; font-weight: 600;">properties</span>:
        <span style="color: cyan; font-weight: 600;">sql</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: string
          <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"SQL SELECT query"</span>
        <span style="color: cyan; font-weight: 600;">params</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: array
          <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Query parameters"</span>
      <span style="color: cyan; font-weight: 600;">required</span>: [sql]
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">resource_slots</span>:
      - <span style="color: cyan; font-weight: 600;">name</span>: database
        <span style="color: cyan; font-weight: 600;">type</span>: local/postgres-db
        <span style="color: cyan; font-weight: 600;">binding</span>: contextual

  - <span style="color: cyan; font-weight: 600;">name</span>: execute_migration
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Execute a DDL migration within a transaction"</span>
    <span style="color: cyan; font-weight: 600;">input_schema</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: object
      <span style="color: cyan; font-weight: 600;">properties</span>:
        <span style="color: cyan; font-weight: 600;">up_sql</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: string
          <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Forward migration SQL"</span>
        <span style="color: cyan; font-weight: 600;">down_sql</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: string
          <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Rollback migration SQL"</span>
        <span style="color: cyan; font-weight: 600;">description</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: string
          <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Human-readable description"</span>
      <span style="color: cyan; font-weight: 600;">required</span>: [up_sql, down_sql, description]
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: yellow;">true</span>
    <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: yellow;">true</span>
    <span style="color: cyan; font-weight: 600;">resource_slots</span>:
      - <span style="color: cyan; font-weight: 600;">name</span>: database
        <span style="color: cyan; font-weight: 600;">type</span>: local/postgres-db
        <span style="color: cyan; font-weight: 600;">binding</span>: contextual

  - <span style="color: cyan; font-weight: 600;">name</span>: backfill_column
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Batch-update a column using a source query"</span>
    <span style="color: cyan; font-weight: 600;">input_schema</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: object
      <span style="color: cyan; font-weight: 600;">properties</span>:
        <span style="color: cyan; font-weight: 600;">table</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: string
        <span style="color: cyan; font-weight: 600;">column</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: string
        <span style="color: cyan; font-weight: 600;">source_query</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: string
          <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Query that returns (id, value) pairs"</span>
        <span style="color: cyan; font-weight: 600;">batch_size</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: integer
          <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: yellow;">10000</span>
      <span style="color: cyan; font-weight: 600;">required</span>: [table, column, source_query]
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: yellow;">true</span>
    <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: yellow;">true</span>
    <span style="color: cyan; font-weight: 600;">resource_slots</span>:
      - <span style="color: cyan; font-weight: 600;">name</span>: database
        <span style="color: cyan; font-weight: 600;">type</span>: local/postgres-db
        <span style="color: cyan; font-weight: 600;">binding</span>: contextual
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> skill add <span style="color: cyan;">--config</span> ./skills/database-ops.yaml

╭─ Skill Registered ─────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/database-ops                                       │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Safe database operations with transaction support │
│ <span style="color: #66cc66; font-weight: 600;">Config:</span> ./skills/database-ops.yaml                             │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 09:04                                      │
╰────────────────────────────────────────────────────────────────╯

╭─ Tool Sources ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Source</span>    <span style="color: cyan; font-weight: 600;">Count</span>  <span style="color: cyan; font-weight: 600;">Details</span>                            │
│ <span style="opacity: 0.7;">────────  ─────  ────────────────────────────</span>       │
│ custom    3      query_db, execute_migration,       │
│                  backfill_column                    │
│ <span style="opacity: 0.7;">────────  ─────  ────────────────────────────</span>       │
│ <span style="color: yellow; font-weight: 600;">Total:</span>    3                                         │
╰─────────────────────────────────────────────────────╯

╭─ Resource Slots ───────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Tool</span>               <span style="color: cyan; font-weight: 600;">Slot</span>      <span style="color: cyan; font-weight: 600;">Type</span>                  │
│ <span style="opacity: 0.7;">─────────────────  ────────  ──────────────────</span>    │
│ query_db           database   local/postgres-db    │
│ execute_migration  database   local/postgres-db    │
│ backfill_column    database   local/postgres-db    │
╰────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Skill registered with 3 tools
</code></pre></div>

#### Step 3: Create the Migration Action and Execute the Plan

Create `actions/add-column-with-backfill.yaml`:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">name</span>: local/add-column-with-backfill
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Add a column, backfill data, and update application code"</span>
<span style="color: cyan; font-weight: 600;">definition_of_done</span>: |
  - Database migration adds the column with a sensible default
  - Backfill completes for all rows using the specified source
  - Application code reads/writes the new column
  - All tests pass with the new schema
  - A rollback migration is available and tested
<span style="color: cyan; font-weight: 600;">strategy_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">execution_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">automation_profile</span>: review
<span style="color: cyan; font-weight: 600;">reusable</span>: <span style="color: yellow;">true</span>
<span style="color: cyan; font-weight: 600;">state</span>: <span style="color: yellow;">available</span>
<span style="color: cyan; font-weight: 600;">args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: table_name
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">true</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: column_name
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">true</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: column_type
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">true</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: backfill_source
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Description of where to source backfill data"</span>
<span style="color: cyan; font-weight: 600;">invariants</span>:
  - <span style="color: #66cc66;">"Migration must be backward-compatible (add column, don&#x27;t rename or drop)"</span>
  - <span style="color: #66cc66;">"Backfill must be batched to avoid locking the table"</span>
  - <span style="color: #66cc66;">"Rollback migration must be provided and tested"</span>
  - <span style="color: #66cc66;">"Application code must handle both old (null) and new values gracefully"</span>
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action create <span style="color: cyan;">--config</span> ./actions/add-column-with-backfill.yaml

╭─ Action Created ────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/add-column-with-backfill                │
│ <span style="color: yellow; font-weight: 600;">State:</span> available                                    │
│ <span style="color: magenta; font-weight: 600;">Strategy Actor:</span> anthropic/claude-3.5-sonnet         │
│ <span style="color: magenta; font-weight: 600;">Execution Actor:</span> anthropic/claude-3.5-sonnet        │
│ <span style="color: #66cc66; font-weight: 600;">Reusable:</span> yes                                       │
│ <span style="color: #5599ff; font-weight: 600;">Read Only:</span> no                                       │
│ <span style="color: #66cc66; font-weight: 600;">Config:</span> ./actions/add-column-with-backfill.yaml     │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 09:05                           │
╰─────────────────────────────────────────────────────╯

╭─ Definition of Done ─────────────────────────────────────────────╮
│ - Database migration adds the column with a sensible default     │
│ - Backfill completes for all rows using the specified source     │
│ - Application code reads/writes the new column                   │
│ - All tests pass with the new schema                             │
│ - A rollback migration is available and tested                   │
╰──────────────────────────────────────────────────────────────────╯

╭─ Arguments ────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>              <span style="color: cyan; font-weight: 600;">Type</span>    <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>                        │
│ <span style="opacity: 0.7;">────────────────  ──────  ────────  ─────────────────────────────────</span>  │
│ table_name        string  yes       (none)                             │
│ column_name       string  yes       (none)                             │
│ column_type       string  yes       (none)                             │
│ backfill_source   string  yes       Where to source backfill data      │
╰────────────────────────────────────────────────────────────────────────╯

╭─ Invariants ──────────────────────────────────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">1.</span> Migration must be backward-compatible (add column, don't rename or drop)       │
│ <span style="color: magenta; font-weight: 600;">2.</span> Backfill must be batched to avoid locking the table                            │
│ <span style="color: magenta; font-weight: 600;">3.</span> Rollback migration must be provided and tested                                 │
│ <span style="color: magenta; font-weight: 600;">4.</span> Application code must handle both old (null) and new values gracefully         │
╰───────────────────────────────────────────────────────────────────────────────────╯

╭─ Automation ──────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> review                   │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> action config             │
╰───────────────────────────────────╯

╭─ Usage ─────────────────────────────────────────────────────────────────────────╮
│ agents plan use local/add-column-with-backfill local/api-service                │
│   <span style="color: cyan;">--arg</span> table_name=TABLE <span style="color: cyan;">--arg</span> column_name=COL                                  │
│   <span style="color: cyan;">--arg</span> column_type=TYPE <span style="color: cyan;">--arg</span> backfill_source=SOURCE                           │
╰─────────────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Action created
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan use local/add-column-with-backfill local/api-service \
    <span style="color: cyan;">--arg</span> table_name=<span style="color: #66cc66;">"users"</span> \
    <span style="color: cyan;">--arg</span> column_name=<span style="color: #66cc66;">"last_login_at"</span> \
    <span style="color: cyan;">--arg</span> column_type=<span style="color: #66cc66;">"TIMESTAMP WITH TIME ZONE"</span> \
    <span style="color: cyan;">--arg</span> backfill_source=<span style="color: #66cc66;">"audit_log table, event_type=&#x27;login&#x27;, max(created_at) per user_id"</span>

╭─ Plan Created ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan ID:</span> 01HXR5E6F7G8H9J0K1L2M3N4O5                 │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> strategize                                   │
│ <span style="color: magenta; font-weight: 600;">Action:</span> local/add-column-with-backfill              │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/api-service                          │
│ <span style="color: #66cc66; font-weight: 600;">Automation:</span> review                                  │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                          │
╰─────────────────────────────────────────────────────╯

╭─ Inputs ────────────────────────────────────────────────────────────────────────────╮
│ - table_name=users                                                                  │
│ - column_name=last_login_at                                                         │
│ - column_type=TIMESTAMP WITH TIME ZONE                                              │
│ - backfill_source=audit_log table, event_type='login', max(created_at) per user_id  │
╰─────────────────────────────────────────────────────────────────────────────────────╯

╭─ Actors ───────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Strategy:</span> anthropic/claude-3.5-sonnet      │
│ <span style="color: magenta; font-weight: 600;">Execution:</span> anthropic/claude-3.5-sonnet     │
│ <span style="color: #5599ff; font-weight: 600;">Estimation:</span> (none)                         │
╰────────────────────────────────────────────╯

╭─ Plan Invariants ──────────────────────────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Scope</span>     <span style="color: magenta; font-weight: 600;">Source</span>   <span style="color: magenta; font-weight: 600;">Invariant</span>                                                   │
│ <span style="opacity: 0.7;">────────  ───────  ──────────────────────────────────────────────────────</span>      │
│ plan      action   Migration must be backward-compatible                       │
│ plan      action   Backfill must be batched to avoid locking the table         │
│ plan      action   Rollback migration must be provided and tested              │
│ plan      action   Application code must handle both old (null) and new values │
╰────────────────────────────────────────────────────────────────────────────────╯

╭─ Context ──────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Resources:</span> 2 (git-checkout, postgres)  │
│ <span style="color: #5599ff; font-weight: 600;">Indexed Files:</span> 347                     │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> strategize                       │
│ <span style="color: #5599ff; font-weight: 600;">Hot Token Budget:</span> 12,000               │
╰────────────────────────────────────────╯

╭─ Next Steps ───────────────────────────────────────╮
│ - agents plan execute 01HXR5E6F7G8H9J0K1L2M3N4O5   │
│ - agents plan status 01HXR5E6F7G8H9J0K1L2M3N4O5    │
│ - agents plan tree 01HXR5E6F7G8H9J0K1L2M3N4O5      │
╰────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan created
</code></pre></div>

The strategy produces a phased plan with child plans:
1. Generate Alembic migration (add column with NULL default)
2. Generate rollback migration
3. Backfill from audit_log in batches of 10,000
4. Update ORM model and application code
5. Run tests with new schema

Each phase creates checkpoints. If the backfill fails at batch 850 of 1,000, the system can restore to the pre-backfill checkpoint rather than starting over.

#### Step 4: Monitor Execution and Rollback if Needed

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Monitor the migration execution</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan status 01HXR5E6F7G8H9J0K1L2M3N4O5

╭─ Plan Status ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR5E6F7G8H9J0K1L2M3N4O5                    │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> execute                                      │
│ <span style="color: magenta; font-weight: 600;">State:</span> processing                                   │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/add-column-with-backfill              │
│ <span style="color: #66cc66; font-weight: 600;">Project:</span> local/api-service                          │
│ <span style="color: #5599ff; font-weight: 600;">Automation:</span> review                                  │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                          │
╰─────────────────────────────────────────────────────╯

╭─ Progress ─────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Strategize               │
│ <span style="color: cyan; font-weight: 600;">⏳</span> Execute (phase 3 of 5)   │
│ <span style="color: yellow; font-weight: 600;">•</span> Apply (queued)           │
╰────────────────────────────╯

╭─ Child Plans ────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Phase</span>  <span style="color: cyan; font-weight: 600;">Description</span>                          <span style="color: cyan; font-weight: 600;">Status</span>                       │
│ <span style="opacity: 0.7;">─────  ───────────────────────────────────  ──────────────────────</span>       │
│ 1      Generate Alembic migration              <span style="color: #66cc66; font-weight: 600;">✓ complete</span>                │
│ 2      Generate rollback migration             <span style="color: #66cc66; font-weight: 600;">✓ complete</span>                │
│ 3      Backfill from audit_log                 <span style="color: cyan; font-weight: 600;">⏳ batch 620/1,000</span>         │
│ 4      Update ORM model and application code   <span style="opacity: 0.5;">○ waiting</span>                 │
│ 5      Run tests with new schema               <span style="opacity: 0.5;">○ waiting</span>                 │
╰──────────────────────────────────────────────────────────────────────────╯

╭─ Execution Detail ──────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Sandbox:</span> transaction_rollback           │
│ <span style="color: #5599ff; font-weight: 600;">Tool Calls:</span> 14                          │
│ <span style="color: #5599ff; font-weight: 600;">Files Modified:</span> 2                       │
│ <span style="color: #5599ff; font-weight: 600;">Rows Backfilled:</span> 6,200,000 / 10,000,000 │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoints:</span> 4 created                  │
╰─────────────────────────────────────────╯

╭─ Timing ──────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Started:</span> 09:06:01     │
│ <span style="color: yellow; font-weight: 600;">Elapsed:</span> 00:04:32     │
│ <span style="color: #66cc66; font-weight: 600;">ETA:</span> 00:02:50         │
╰───────────────────────╯

╭─ Cost ───────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Tokens Used:</span> 18,940  │
│ <span style="color: yellow; font-weight: 600;">Cost So Far:</span> $0.063  │
│ <span style="color: #5599ff; font-weight: 600;">Estimated:</span> $0.110    │
╰──────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Status refreshed
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># If something goes wrong during backfill, rollback to the pre-backfill checkpoint</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan rollback <span style="color: cyan;">--yes</span> 01HXR5E6F7G8H9J0K1L2M3N4O5 cp_01HXR5CP3

╭─ Rollback Summary ───────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR5E6F7G8H9J0K1L2M3N4O5                     │
│ <span style="color: magenta; font-weight: 600;">Checkpoint:</span> cp_01HXR5CP3                             │
│ <span style="color: yellow; font-weight: 600;">Label:</span> before backfill (after migration applied)     │
│ <span style="color: yellow; font-weight: 600;">Files:</span> 2 reverted                                    │
╰──────────────────────────────────────────────────────╯

╭─ Changes Reverted ──────────────────────────────────────────╮
│ <span style="color: yellow; font-weight: 600;">File</span>                                         <span style="color: yellow; font-weight: 600;">Action</span>         │
│ <span style="opacity: 0.7;">───────────────────────────────────────────  ──────────</span>     │
│ alembic/versions/20260211_add_last_login.py  restored       │
│ alembic/versions/20260211_rollback.py        restored       │
╰─────────────────────────────────────────────────────────────╯

╭─ Database Rollback ─────────────────────────────────────────╮
│ <span style="color: yellow; font-weight: 600;">Transaction:</span> rolled back                                    │
│ <span style="color: #5599ff; font-weight: 600;">Rows Affected:</span> 6,200,000 updates reverted                   │
│ <span style="color: #5599ff; font-weight: 600;">Schema State:</span> restored to pre-backfill                      │
╰─────────────────────────────────────────────────────────────╯

╭─ Impact ──────────────────────────────────────╮
│ <span style="color: yellow; font-weight: 600;">Child Plans Invalidated:</span> 1 (backfill phase)   │
│ <span style="color: #5599ff; font-weight: 600;">Sandbox:</span> restored to cp_01HXR5CP3             │
│ <span style="color: #5599ff; font-weight: 600;">Decisions After CP:</span> 3 discarded               │
│ <span style="color: #5599ff; font-weight: 600;">Tool Calls After CP:</span> 8 undone                 │
╰───────────────────────────────────────────────╯

╭─ Post-Rollback State ──────────╮
│ <span style="color: yellow; font-weight: 600;">Phase:</span> execute                 │
│ <span style="color: #5599ff; font-weight: 600;">State:</span> queued (awaiting input) │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoints Remaining:</span> 3       │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Rollback complete
</code></pre></div>

---

### Example 6: Writing Technical Documentation from Codebase Analysis

**Scenario**: A project has grown to 50,000 lines of code with minimal documentation. The team wants CleverAgents to generate comprehensive API documentation, architecture guides, and developer onboarding docs by analyzing the actual codebase.

**Complexity**: Intermediate. Read-only action, large context usage, no sandbox modifications to source code.

#### Step 1: Create a Read-Only Documentation Action

Create `actions/generate-docs.yaml`:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">name</span>: local/generate-docs
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Generate comprehensive documentation from codebase analysis"</span>
<span style="color: cyan; font-weight: 600;">long_description</span>: |
  Analyze the project codebase to produce developer documentation:
  API reference, architecture overview, module guides, and onboarding
  material. Uses code intelligence (search, vector similarity, graph
  queries) to understand structure and relationships.
<span style="color: cyan; font-weight: 600;">definition_of_done</span>: |
  - API reference covers all public endpoints/functions
  - Architecture document shows module dependencies and data flow
  - Each major module has a developer guide
  - An onboarding document provides setup and contribution instructions
  - All generated docs are accurate to the current codebase
  - Documentation is written in Markdown format
<span style="color: cyan; font-weight: 600;">strategy_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">execution_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: yellow;">false</span>
<span style="color: cyan; font-weight: 600;">reusable</span>: <span style="color: yellow;">true</span>
<span style="color: cyan; font-weight: 600;">state</span>: <span style="color: yellow;">available</span>
<span style="color: cyan; font-weight: 600;">args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: doc_types
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Comma-separated list: api-reference, architecture, module-guides, onboarding"</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: output_dir
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">"docs/"</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Output directory for generated docs"</span>
<span style="color: cyan; font-weight: 600;">invariants</span>:
  - <span style="color: #66cc66;">"Do not modify any source code files — only create or update files in the output directory"</span>
  - <span style="color: #66cc66;">"All code examples in documentation must be actual code from the project, not fabricated"</span>
  - <span style="color: #66cc66;">"Architecture diagrams must reflect actual module dependencies, not aspirational ones"</span>
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action create <span style="color: cyan;">--config</span> ./actions/generate-docs.yaml

╭─ Action Created ──────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/generate-docs                                                         │
│ <span style="color: yellow; font-weight: 600;">State:</span> available                                                                  │
│ <span style="color: magenta; font-weight: 600;">Strategy Actor:</span> anthropic/claude-3.5-sonnet                                       │
│ <span style="color: magenta; font-weight: 600;">Execution Actor:</span> anthropic/claude-3.5-sonnet                                      │
│ <span style="color: #66cc66; font-weight: 600;">Reusable:</span> yes                                                                     │
│ <span style="color: #5599ff; font-weight: 600;">Read Only:</span> no                                                                     │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 10:30                                                         │
╰───────────────────────────────────────────────────────────────────────────────────╯

╭─ Definition of Done ──────────────────────────────────────────────────────────────╮
│ - API reference covers all public endpoints/functions                             │
│ - Architecture document shows module dependencies and data flow                   │
│ - Each major module has a developer guide                                         │
│ - An onboarding document provides setup and contribution instructions             │
│ - All generated docs are accurate to the current codebase                         │
│ - Documentation is written in Markdown format                                     │
╰───────────────────────────────────────────────────────────────────────────────────╯

╭─ Arguments ───────────────────────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>        <span style="color: cyan; font-weight: 600;">Type</span>    <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>                                                         │
│ <span style="opacity: 0.7;">──────────  ──────  ────────  ──────────────────────────────────────────────────────────────</span>      │
│ doc_types   string  yes       Comma-separated list: api-reference, architecture, module-guides…   │
│ output_dir  string  no        Output directory for generated docs (default: docs/)                │
╰───────────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Invariants ───────────────────────────────────────────────────────────────────────────────────────╮
│ 1. Do not modify any source code files — only create or update files in the output directory       │
│ 2. All code examples in documentation must be actual code from the project, not fabricated         │
│ 3. Architecture diagrams must reflect actual module dependencies, not aspirational ones            │
╰────────────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Automation ──────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> (inherits global)            │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> default                       │
╰───────────────────────────────────────╯

╭─ Usage ────────────────────────────────────────────────────────────────────────────╮
│ agents plan use local/generate-docs local/api-service                              │
│   <span style="color: cyan;">--arg</span> doc_types="api-reference,architecture,module-guides,onboarding"            │
╰────────────────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Action created
</code></pre></div>

#### Step 2: Configure Context for Large Codebase Analysis

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Set a generous context policy for the strategize view (needs to see architecture)</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project context set <span style="color: cyan;">--view</span> strategize \
    <span style="color: cyan;">--include-resource</span> 01HXR6A1B2C3D4E5F6G7H8J9K0 \
    <span style="color: cyan;">--exclude-path</span> <span style="color: #66cc66;">"**/node_modules/**"</span> \
    <span style="color: cyan;">--exclude-path</span> <span style="color: #66cc66;">"**/.git/**"</span> \
    <span style="color: cyan;">--exclude-path</span> <span style="color: #66cc66;">"**/dist/**"</span> \
    <span style="color: cyan;">--hot-max-tokens</span> <span style="color: yellow;">32000</span> \
    <span style="color: cyan;">--warm-max-decisions</span> <span style="color: yellow;">200</span> \
    <span style="color: cyan;">--query-limit</span> <span style="color: yellow;">50</span> \
    <span style="color: cyan;">--max-file-size</span> <span style="color: yellow;">2097152</span> \
    <span style="color: cyan;">--summarize</span> \
    <span style="color: cyan;">--summary-max-tokens</span> <span style="color: yellow;">1500</span> \
    local/api-service

╭─ Context Policy ────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service                              │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> strategize                                        │
│ <span style="color: #66cc66; font-weight: 600;">Include:</span> 01HXR6A1B2C3D4E5F6G7H8J9K0                     │
│ <span style="color: yellow; font-weight: 600;">Exclude:</span> **/node_modules/**, **/.git/**, **/dist/**     │
╰─────────────────────────────────────────────────────────╯

╭─ Limits ──────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Hot Tokens:</span> 32000 (soft cap)      │
│ <span style="color: magenta; font-weight: 600;">Warm Decisions:</span> 200               │
│ <span style="color: #5599ff; font-weight: 600;">Query Limit:</span> 50                   │
│ <span style="color: #5599ff; font-weight: 600;">Max File Size:</span> 2 MB               │
│ <span style="color: #5599ff; font-weight: 600;">Max Total Size:</span> 50 MB             │
╰───────────────────────────────────╯

╭─ Summarization ──────╮
│ <span style="color: #66cc66; font-weight: 600;">Enabled:</span> yes         │
│ <span style="color: #5599ff; font-weight: 600;">Max Tokens:</span> 1500     │
╰──────────────────────╯

╭─ Other Views ──────────╮
│ <span style="color: #5599ff; font-weight: 600;">execute:</span> (default)     │
│ <span style="color: #5599ff; font-weight: 600;">apply:</span> (default)       │
│ <span style="color: #5599ff; font-weight: 600;">default:</span> (unset)       │
╰────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Context policy updated
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Execution view can be narrower (writing docs, not analyzing all code)</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project context set <span style="color: cyan;">--view</span> execute \
    <span style="color: cyan;">--include-resource</span> 01HXR6A1B2C3D4E5F6G7H8J9K0 \
    <span style="color: cyan;">--hot-max-tokens</span> <span style="color: yellow;">16000</span> \
    <span style="color: cyan;">--query-limit</span> <span style="color: yellow;">30</span> \
    <span style="color: cyan;">--summarize</span> \
    local/api-service

╭─ Context Policy ────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service                              │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> execute                                           │
│ <span style="color: #66cc66; font-weight: 600;">Include:</span> 01HXR6A1B2C3D4E5F6G7H8J9K0                     │
╰─────────────────────────────────────────────────────────╯

╭─ Limits ──────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Hot Tokens:</span> 16000 (soft cap)      │
│ <span style="color: #5599ff; font-weight: 600;">Query Limit:</span> 30                   │
│ <span style="color: #5599ff; font-weight: 600;">Max File Size:</span> 1 MB               │
│ <span style="color: #5599ff; font-weight: 600;">Max Total Size:</span> 50 MB             │
╰───────────────────────────────────╯

╭─ Summarization ─╮
│ <span style="color: #66cc66; font-weight: 600;">Enabled:</span> yes    │
│ <span style="color: #5599ff; font-weight: 600;">Max Tokens:</span> 800 │
╰─────────────────╯

╭─ Other Views ──────────────╮
│ <span style="color: #5599ff; font-weight: 600;">strategize:</span> configured     │
│ <span style="color: #5599ff; font-weight: 600;">apply:</span> (default)           │
│ <span style="color: #5599ff; font-weight: 600;">default:</span> (unset)           │
╰────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Context policy updated
</code></pre></div>

#### Step 3: Execute

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan use \
    <span style="color: cyan;">--automation-profile</span> trusted \
    <span style="color: cyan;">--arg</span> doc_types=<span style="color: #66cc66;">"api-reference,architecture,module-guides,onboarding"</span> \
    <span style="color: cyan;">--arg</span> output_dir=<span style="color: #66cc66;">"docs/generated/"</span> \
    local/generate-docs local/api-service

╭─ Plan Created ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR6F7G8H9J0K1L2M3N4O5P6                    │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> strategize                                   │
│ <span style="color: magenta; font-weight: 600;">State:</span> processing                                   │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/generate-docs                         │
│ <span style="color: #66cc66; font-weight: 600;">Project:</span> local/api-service                          │
│ <span style="color: #66cc66; font-weight: 600;">Automation:</span> trusted                                 │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                          │
╰─────────────────────────────────────────────────────╯

╭─ Inputs ─────────────────────────────────────────────────────────────────────╮
│ - doc_types="api-reference,architecture,module-guides,onboarding"            │
│ - output_dir="docs/generated/"                                               │
│ - automation_profile=trusted                                                 │
╰──────────────────────────────────────────────────────────────────────────────╯

╭─ Actors ────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Strategy:</span> anthropic/claude-3.5-sonnet           │
│ <span style="color: magenta; font-weight: 600;">Execution:</span> anthropic/claude-3.5-sonnet          │
│ <span style="color: #5599ff; font-weight: 600;">Estimation:</span> (none)                              │
╰─────────────────────────────────────────────────╯

╭─ Automation ───────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> trusted                       │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> plan override                  │
│ <span style="color: #5599ff; font-weight: 600;">Read-Only:</span> no                          │
╰────────────────────────────────────────╯

╭─ Context ──────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Resources:</span> 1 (git-checkout)        │
│ <span style="color: #5599ff; font-weight: 600;">Indexed Files:</span> 487                 │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> strategize                   │
│ <span style="color: #5599ff; font-weight: 600;">Hot Token Budget:</span> 32,000           │
╰────────────────────────────────────╯

╭─ Next Steps ─────────────────────────────────────────────────────────╮
│ <span style="opacity: 0.7;">Trusted profile — strategize and execute will proceed automatically.</span> │
│ - agents plan status 01HXR6F7G8H9J0K1L2M3N4O5P6                      │
│ - agents plan tree 01HXR6F7G8H9J0K1L2M3N4O5P6                        │
╰──────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan created
</code></pre></div>

The system analyzes the codebase using the code intelligence indexes (full-text, vector, and graph) to understand module relationships, public APIs, and data flows. It generates documentation files in the sandbox.

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Review generated docs</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan artifacts 01HXR6F7G8H9J0K1L2M3N4O5P6

╭─ Artifacts ───────────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Path</span>                                      <span style="color: cyan; font-weight: 600;">Type</span>   <span style="color: cyan; font-weight: 600;">Size</span>     <span style="color: cyan; font-weight: 600;">Change</span>    <span style="color: cyan; font-weight: 600;">Child Plan</span>        │
│ <span style="opacity: 0.7;">────────────────────────────────────────  ─────  ───────  ────────  ───────</span>           │
│ docs/generated/api-reference.md           write  18.2 KB  <span style="color: #66cc66; font-weight: 600;">+412 -0</span>   root              │
│ docs/generated/architecture.md            write  12.6 KB  <span style="color: #66cc66; font-weight: 600;">+284 -0</span>   root              │
│ docs/generated/modules/auth.md            write   6.4 KB  <span style="color: #66cc66; font-weight: 600;">+148 -0</span>   root              │
│ docs/generated/modules/billing.md         write   5.8 KB  <span style="color: #66cc66; font-weight: 600;">+131 -0</span>   root              │
│ docs/generated/modules/notifications.md   write   4.2 KB  <span style="color: #66cc66; font-weight: 600;">+97 -0</span>    root              │
│ docs/generated/modules/data-pipeline.md   write   5.1 KB  <span style="color: #66cc66; font-weight: 600;">+118 -0</span>   root              │
│ docs/generated/onboarding.md              write   8.9 KB  <span style="color: #66cc66; font-weight: 600;">+201 -0</span>   root              │
╰───────────────────────────────────────────────────────────────────────────────────────╯

╭─ Summary ─────────────╮
│ <span style="color: yellow; font-weight: 600;">Total:</span> 7              │
│ <span style="color: #66cc66; font-weight: 600;">Writes:</span> 7 (new)       │
│ <span style="color: #5599ff; font-weight: 600;">Edits:</span> 0              │
│ <span style="color: #ff6666; font-weight: 600;">Deletes:</span> 0            │
│ <span style="color: #5599ff; font-weight: 600;">Total Size:</span> 61.2 KB   │
╰───────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 7 artifacts listed
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan diff 01HXR6F7G8H9J0K1L2M3N4O5P6

╭─ Diff Summary ─────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR6F7G8H9J0K1L2M3N4O5P6                   │
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service                         │
│ <span style="color: yellow; font-weight: 600;">Files Changed:</span> 7                                   │
│ <span style="color: #66cc66; font-weight: 600;">Insertions:</span> 1,391                                  │
│ <span style="color: #ff6666; font-weight: 600;">Deletions:</span> 0                                       │
│ <span style="color: #5599ff; font-weight: 600;">Net Change:</span> +1,391 lines                           │
╰────────────────────────────────────────────────────╯

╭─ Files ──────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Path</span>                                      <span style="color: cyan; font-weight: 600;">Change</span>     <span style="color: cyan; font-weight: 600;">Status</span>      │
│ <span style="opacity: 0.7;">────────────────────────────────────────  ─────────  ─────────</span>   │
│ docs/generated/api-reference.md           <span style="color: #66cc66; font-weight: 600;">+412 -0</span>    new file    │
│ docs/generated/architecture.md            <span style="color: #66cc66; font-weight: 600;">+284 -0</span>    new file    │
│ docs/generated/modules/auth.md            <span style="color: #66cc66; font-weight: 600;">+148 -0</span>    new file    │
│ docs/generated/modules/billing.md         <span style="color: #66cc66; font-weight: 600;">+131 -0</span>    new file    │
│ docs/generated/modules/notifications.md   <span style="color: #66cc66; font-weight: 600;">+97 -0</span>     new file    │
│ docs/generated/modules/data-pipeline.md   <span style="color: #66cc66; font-weight: 600;">+118 -0</span>    new file    │
│ docs/generated/onboarding.md              <span style="color: #66cc66; font-weight: 600;">+201 -0</span>    new file    │
╰──────────────────────────────────────────────────────────────────╯

╭─ Patch Preview ───────────────────────────────────────────────────────╮
│ <span style="opacity: 0.7;">--- /dev/null</span>                                                         │
│ <span style="opacity: 0.7;">+++ b/docs/generated/api-reference.md</span>                                 │
│ <span style="color: cyan;">@@ -0,0 +1,412 @@</span>                                                     │
│ <span style="color: #66cc66;">+ # API Reference</span>                                                     │
│ <span style="color: #66cc66;">+ ## Authentication</span>                                                   │
│ <span style="color: #66cc66;">+ ### POST /auth/login</span>                                                │
│ <span style="color: #66cc66;">+ ...</span>                                                                 │
│ <span style="opacity: 0.7;">--- /dev/null</span>                                                         │
│ <span style="opacity: 0.7;">+++ b/docs/generated/architecture.md</span>                                  │
│ <span style="color: cyan;">@@ -0,0 +1,284 @@</span>                                                     │
│ <span style="color: #66cc66;">+ # Architecture Overview</span>                                             │
│ <span style="color: #66cc66;">+ ## Module Dependency Graph</span>                                          │
│ <span style="color: #66cc66;">+ ...</span>                                                                 │
╰───────────────────────────────────────────────────────────────────────╯

╭─ Risk Assessment ─────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Source Code:</span> unmodified           │
│ <span style="color: #66cc66; font-weight: 600;">Breaking Changes:</span> none detected   │
│ <span style="color: #66cc66; font-weight: 600;">New Files Only:</span> yes               │
╰───────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Diff generated
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Apply the documentation to the project</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXR6F7G8H9J0K1L2M3N4O5P6

╭─ Apply Summary ──────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR6F7G8H9J0K1L2M3N4O5P6             │
│ <span style="color: #5599ff; font-weight: 600;">Artifacts:</span> 7 files created                   │
│ <span style="color: yellow; font-weight: 600;">Changes:</span> 1,391 insertions, 0 deletions       │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/api-service                   │
│ <span style="color: #66cc66; font-weight: 600;">Applied At:</span> 2026-02-11 10:38                 │
╰──────────────────────────────────────────────╯

╭─ Validation ────────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Invariant: no source files modified       │
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Invariant: code examples verified         │
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Invariant: architecture matches codebase  │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 4.1s                              │
╰─────────────────────────────────────────────╯

╭─ Sandbox Cleanup ─────────╮
│ <span style="color: #66cc66; font-weight: 600;">Worktree:</span> removed         │
│ <span style="color: #66cc66; font-weight: 600;">Branch:</span> merged to main    │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoint:</span> archived      │
╰───────────────────────────╯

╭─ Plan Lifecycle ─────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Phase:</span> applied                           │
│ <span style="color: #66cc66; font-weight: 600;">State:</span> complete                          │
│ <span style="color: #5599ff; font-weight: 600;">Total Duration:</span> 00:08:12                 │
│ <span style="color: yellow; font-weight: 600;">Total Cost:</span> $0.184                       │
│ <span style="color: #5599ff; font-weight: 600;">Decisions Made:</span> 18                       │
│ <span style="color: #5599ff; font-weight: 600;">Child Plans:</span> 0                           │
╰──────────────────────────────────────────╯

╭─ Next Steps ──────╮
│ - Review git diff │
│ - Commit changes  │
╰───────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied
</code></pre></div>

---

### Example 7: CI/CD Integration — Automated PR Review and Fix

**Scenario**: A CI pipeline triggers CleverAgents to automatically review incoming pull requests, run analysis, and if issues are found, create fix commits. This runs headlessly without human intervention.

**Complexity**: Advanced. Non-interactive (CI profile), headless execution, full automation.

#### Step 1: Configure for CI

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Set CI-appropriate configuration</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set core.automation-profile ci

╭─ Config Updated ───────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Key:</span> core.automation-profile               │
│ <span style="color: #66cc66; font-weight: 600;">Value:</span> ci                                  │
│ <span style="color: yellow; font-weight: 600;">Previous:</span> (not set)                        │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> config                             │
│ <span style="color: yellow; font-weight: 600;">Scope:</span> global                              │
╰────────────────────────────────────────────╯

╭─ Effective ────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Sessions:</span> new sessions             │
│ <span style="color: yellow; font-weight: 600;">Plans:</span> future plans (unless set)   │
│ <span style="color: #5599ff; font-weight: 600;">Existing:</span> unchanged                │
╰────────────────────────────────────╯

╭─ Saved To ──────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">File:</span> ~/.cleveragents/config.toml   │
│ <span style="color: #5599ff; font-weight: 600;">Line:</span> 3                             │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Config updated

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set core.format json

╭─ Config Updated ─────────────────╮
│ <span style="color: cyan; font-weight: 600;">Key:</span> core.format                 │
│ <span style="color: #66cc66; font-weight: 600;">Value:</span> json                      │
│ <span style="color: yellow; font-weight: 600;">Previous:</span> (not set)              │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> config                   │
│ <span style="color: yellow; font-weight: 600;">Scope:</span> global                    │
╰──────────────────────────────────╯

╭─ Saved To ──────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">File:</span> ~/.cleveragents/config.toml   │
│ <span style="color: #5599ff; font-weight: 600;">Line:</span> 4                             │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Config updated

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set core.log.level WARN

╭─ Config Updated ──────────────────╮
│ <span style="color: cyan; font-weight: 600;">Key:</span> core.log.level               │
│ <span style="color: #66cc66; font-weight: 600;">Value:</span> WARN                       │
│ <span style="color: yellow; font-weight: 600;">Previous:</span> FATAL                   │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> config                    │
│ <span style="color: yellow; font-weight: 600;">Scope:</span> global                     │
╰───────────────────────────────────╯

╭─ Saved To ──────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">File:</span> ~/.cleveragents/config.toml   │
│ <span style="color: #5599ff; font-weight: 600;">Line:</span> 5                             │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Config updated
</code></pre></div>

#### Step 2: Create the PR Review Action

Create `actions/review-pr.yaml`:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">name</span>: local/review-pr
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Automatically review a PR and fix issues"</span>
<span style="color: cyan; font-weight: 600;">definition_of_done</span>: |
  - All lint issues are resolved
  - Type checking passes
  - Test coverage does not decrease
  - Security scan passes
  - All fixes are committed to the PR branch
<span style="color: cyan; font-weight: 600;">strategy_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">execution_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">automation_profile</span>: ci
<span style="color: cyan; font-weight: 600;">reusable</span>: <span style="color: yellow;">true</span>
<span style="color: cyan; font-weight: 600;">state</span>: <span style="color: yellow;">available</span>
<span style="color: cyan; font-weight: 600;">args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: pr_branch
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Branch name of the PR"</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: base_branch
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">"main"</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Base branch to compare against"</span>
<span style="color: cyan; font-weight: 600;">invariants</span>:
  - <span style="color: #66cc66;">"Only modify files that are already changed in the PR"</span>
  - <span style="color: #66cc66;">"Do not change the intent of any code — only fix style, types, and test issues"</span>
  - <span style="color: #66cc66;">"All fixes must include a comment explaining what was changed and why"</span>
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action create <span style="color: cyan;">--config</span> ./actions/review-pr.yaml

╭─ Action Created ──────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/review-pr                         │
│ <span style="color: yellow; font-weight: 600;">State:</span> available                              │
│ <span style="color: magenta; font-weight: 600;">Strategy Actor:</span> anthropic/claude-3.5-sonnet   │
│ <span style="color: magenta; font-weight: 600;">Execution Actor:</span> anthropic/claude-3.5-sonnet  │
│ <span style="color: #66cc66; font-weight: 600;">Reusable:</span> yes                                 │
│ <span style="color: #5599ff; font-weight: 600;">Read Only:</span> no                                 │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 14:00                     │
╰───────────────────────────────────────────────╯

╭─ Definition of Done ─────────────────────────────────────╮
│ - All lint issues are resolved                           │
│ - Type checking passes                                   │
│ - Test coverage does not decrease                        │
│ - Security scan passes                                   │
│ - All fixes are committed to the PR branch               │
╰──────────────────────────────────────────────────────────╯

╭─ Arguments ──────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>        <span style="color: cyan; font-weight: 600;">Type</span>    <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>                        │
│ <span style="opacity: 0.7;">──────────  ──────  ────────  ──────────────────────────────────</span> │
│ pr_branch   string  yes       Branch name of the PR              │
│ base_branch string  no        Base branch to compare against     │
╰──────────────────────────────────────────────────────────────────╯

╭─ Invariants ─────────────────────────────────────────────────────────────────────╮
│ 1. Only modify files that are already changed in the PR                          │
│ 2. Do not change the intent of any code — only fix style, types, and test        │
│    issues                                                                        │
│ 3. All fixes must include a comment explaining what was changed and why          │
╰──────────────────────────────────────────────────────────────────────────────────╯

╭─ Automation ──────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> ci                   │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> action config         │
╰───────────────────────────────╯

╭─ Usage ──────────────────────────────────────────────────────────────────╮
│ agents plan use local/review-pr &lt;PROJECT&gt;                                │
│   <span style="color: cyan;">--arg</span> pr_branch="..."                                                  │
╰──────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Action created
</code></pre></div>

#### Step 3: CI Pipeline Script

<div class="highlight"><pre><code>
#!/bin/bash
<span style="opacity: 0.7;"># ci-review.sh — called by CI when a PR is opened or updated</span>

set -euo pipefail

PR_BRANCH="${1:?Usage: ci-review.sh &lt;branch&gt;}"
BASE_BRANCH="${2:-main}"

<span style="opacity: 0.7;"># Register the resource pointing to the CI workspace.</span>
RESOURCE_NAME="local/ci-${PR_BRANCH}"
<span style="color: cyan; font-weight: 600;">agents</span> resource add git-checkout "$RESOURCE_NAME" \
    <span style="color: cyan;">--path</span> "$GITHUB_WORKSPACE" \
    <span style="color: cyan;">--branch</span> "$PR_BRANCH"

echo <span style="color: #66cc66;">"Registered resource: $RESOURCE_NAME"</span>

<span style="opacity: 0.7;"># Create a project for this CI run, linking the resource by name.</span>
<span style="opacity: 0.7;"># If the project already exists from a previous run, ignore the error.</span>
<span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> json project create <span style="color: yellow;">-d</span> <span style="color: #66cc66;">"CI workspace for PR $PR_BRANCH"</span> \
    <span style="color: cyan;">--resource</span> "$RESOURCE_NAME" \
    local/ci-workspace 2&gt;/dev/null || true

<span style="opacity: 0.7;"># Register and attach validations (idempotent — duplicates are ignored)</span>
<span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> json validation add \
    <span style="color: cyan;">--config</span> validations/lint.yaml <span style="color: cyan;">--required</span> local/ci-lint 2&gt;/dev/null || true
<span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> json validation add \
    <span style="color: cyan;">--config</span> validations/typecheck.yaml <span style="color: cyan;">--required</span> local/ci-typecheck 2&gt;/dev/null || true
<span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> json validation add \
    <span style="color: cyan;">--config</span> validations/tests.yaml <span style="color: cyan;">--required</span> local/ci-tests 2&gt;/dev/null || true
<span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> json validation attach \
    <span style="color: cyan;">--project</span> local/ci-workspace local/ci-lint 2&gt;/dev/null || true
<span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> json validation attach \
    <span style="color: cyan;">--project</span> local/ci-workspace local/ci-typecheck 2&gt;/dev/null || true
<span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> json validation attach \
    <span style="color: cyan;">--project</span> local/ci-workspace local/ci-tests 2&gt;/dev/null || true

<span style="opacity: 0.7;"># Run the plan — ci profile means full automation including apply</span>
PLAN_OUTPUT=$(<span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> json plan use \
    <span style="color: cyan;">--automation-profile</span> ci \
    <span style="color: cyan;">--arg</span> pr_branch=<span style="color: #66cc66;">"$PR_BRANCH"</span> \
    <span style="color: cyan;">--arg</span> base_branch=<span style="color: #66cc66;">"$BASE_BRANCH"</span> \
    local/review-pr local/ci-workspace)

PLAN_ID=$(echo "$PLAN_OUTPUT" | jq -r '.plan_id')
echo <span style="color: #66cc66;">"Plan started: $PLAN_ID"</span>

<span style="opacity: 0.7;"># Wait for completion (ci profile runs everything automatically)</span>
while true; do
    STATUS=$(<span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> json plan status "$PLAN_ID" | jq -r '.state')
    case "$STATUS" in
        applied)
            echo <span style="color: #66cc66;">"PR review complete. Changes applied."</span>
            break
            ;;
        failed|cancelled)
            echo <span style="color: #66cc66;">"PR review failed."</span>
            <span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> json plan status "$PLAN_ID"
            exit 1
            ;;
        *)
            sleep 10
            ;;
    esac
done

<span style="opacity: 0.7;"># Output the diff for the CI log</span>
<span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> json plan diff "$PLAN_ID"
</code></pre></div>

Sample `--format json` output from `resource add` (captured into `$RESOURCE_JSON`):

<div class="highlight"><pre><code>
{
  <span style="color: cyan; font-weight: 600;">"id"</span>: <span style="color: #66cc66;">"01HXR7G1A2B3C4D5E6F7H8J9K0"</span>,
  <span style="color: cyan; font-weight: 600;">"type"</span>: <span style="color: #66cc66;">"git-checkout"</span>,
  <span style="color: cyan; font-weight: 600;">"physical"</span>: <span style="color: yellow;">true</span>,
  <span style="color: cyan; font-weight: 600;">"path"</span>: <span style="color: #66cc66;">"/home/runner/work/acme-api/acme-api"</span>,
  <span style="color: cyan; font-weight: 600;">"branch"</span>: <span style="color: #66cc66;">"fix/handle-null-users"</span>,
  <span style="color: cyan; font-weight: 600;">"created"</span>: <span style="color: #66cc66;">"2026-02-11T14:05:32Z"</span>,
  <span style="color: cyan; font-weight: 600;">"children_discovered"</span>: <span style="color: yellow;">247</span>,
  <span style="color: cyan; font-weight: 600;">"capabilities"</span>: {
    <span style="color: cyan; font-weight: 600;">"readable"</span>: <span style="color: yellow;">true</span>,
    <span style="color: cyan; font-weight: 600;">"writable"</span>: <span style="color: yellow;">true</span>,
    <span style="color: cyan; font-weight: 600;">"sandboxable"</span>: <span style="color: yellow;">true</span>,
    <span style="color: cyan; font-weight: 600;">"checkpointable"</span>: <span style="color: yellow;">true</span>,
    <span style="color: cyan; font-weight: 600;">"sandbox_strategy"</span>: <span style="color: #66cc66;">"git_worktree"</span>
  }
}
</code></pre></div>

Sample `--format json` output from `plan use` (captured into `$PLAN_OUTPUT`):

<div class="highlight"><pre><code>
{
  <span style="color: cyan; font-weight: 600;">"plan_id"</span>: <span style="color: #66cc66;">"01HXR7H2B3C4D5E6F7G8J9K0L1"</span>,
  <span style="color: cyan; font-weight: 600;">"phase"</span>: <span style="color: #66cc66;">"strategize"</span>,
  <span style="color: cyan; font-weight: 600;">"action"</span>: <span style="color: #66cc66;">"local/review-pr"</span>,
  <span style="color: cyan; font-weight: 600;">"project"</span>: <span style="color: #66cc66;">"local/ci-workspace"</span>,
  <span style="color: cyan; font-weight: 600;">"automation_profile"</span>: <span style="color: #66cc66;">"ci"</span>,
  <span style="color: cyan; font-weight: 600;">"attempt"</span>: <span style="color: yellow;">1</span>,
  <span style="color: cyan; font-weight: 600;">"args"</span>: {
    <span style="color: cyan; font-weight: 600;">"pr_branch"</span>: <span style="color: #66cc66;">"fix/handle-null-users"</span>,
    <span style="color: cyan; font-weight: 600;">"base_branch"</span>: <span style="color: #66cc66;">"main"</span>
  },
  <span style="color: cyan; font-weight: 600;">"resources"</span>: [<span style="color: #66cc66;">"01HXR7G1A2B3C4D5E6F7H8J9K0"</span>]
}
</code></pre></div>

---

### Example 8: Cloud Infrastructure Management

**Scenario**: A DevOps team manages Terraform infrastructure. They want CleverAgents to analyze their current infrastructure, propose optimizations (right-sizing, unused resources), and generate the Terraform changes.

**Complexity**: Advanced. Custom resource types, custom skills, infrastructure domain.

#### Step 1: Register Custom Resource Types and Skills

Create `resource-types/terraform-state.yaml`:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">name</span>: local/terraform-state
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Terraform state file resource type"</span>
<span style="color: cyan; font-weight: 600;">physical</span>: <span style="color: yellow;">true</span>
<span style="color: cyan; font-weight: 600;">user_addable</span>: <span style="color: yellow;">true</span>
<span style="color: cyan; font-weight: 600;">sandbox_strategy</span>: filesystem_copy
<span style="color: cyan; font-weight: 600;">cli_args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: state-path
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Path to terraform.tfstate or remote state configuration"</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: workspace
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">"default"</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Terraform workspace name"</span>
<span style="color: cyan; font-weight: 600;">handler</span>: local/terraform-state-handler
<span style="color: cyan; font-weight: 600;">child_types</span>:
  - <span style="color: cyan; font-weight: 600;">type</span>: fs-file
    <span style="color: cyan; font-weight: 600;">relationship</span>: contains
</code></pre></div>

Create `skills/terraform-ops.yaml`:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">name</span>: local/terraform-ops
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Terraform infrastructure operations"</span>
<span style="color: cyan; font-weight: 600;">tools</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: terraform_plan
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Run terraform plan and return the execution plan"</span>
    <span style="color: cyan; font-weight: 600;">input_schema</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: object
      <span style="color: cyan; font-weight: 600;">properties</span>:
        <span style="color: cyan; font-weight: 600;">target</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: string
          <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Specific resource to target (optional)"</span>
      <span style="color: cyan; font-weight: 600;">required</span>: []
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: yellow;">false</span>

  - <span style="color: cyan; font-weight: 600;">name</span>: terraform_show
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Show current state of a Terraform resource"</span>
    <span style="color: cyan; font-weight: 600;">input_schema</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: object
      <span style="color: cyan; font-weight: 600;">properties</span>:
        <span style="color: cyan; font-weight: 600;">resource_address</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: string
          <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Terraform resource address (e.g., aws_instance.web)"</span>
      <span style="color: cyan; font-weight: 600;">required</span>: [resource_address]
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: yellow;">false</span>

  - <span style="color: cyan; font-weight: 600;">name</span>: cloud_metrics
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Fetch CloudWatch/cloud monitoring metrics for a resource"</span>
    <span style="color: cyan; font-weight: 600;">input_schema</span>:
      <span style="color: cyan; font-weight: 600;">type</span>: object
      <span style="color: cyan; font-weight: 600;">properties</span>:
        <span style="color: cyan; font-weight: 600;">resource_id</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: string
        <span style="color: cyan; font-weight: 600;">metric</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: string
          <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"e.g., CPUUtilization, NetworkIn, RequestCount"</span>
        <span style="color: cyan; font-weight: 600;">period_days</span>:
          <span style="color: cyan; font-weight: 600;">type</span>: integer
          <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: yellow;">30</span>
      <span style="color: cyan; font-weight: 600;">required</span>: [resource_id, metric]
    <span style="color: cyan; font-weight: 600;">writes</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">checkpointable</span>: <span style="color: yellow;">false</span>

<span style="color: cyan; font-weight: 600;">include_skills</span>:
  - local/file-ops
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource type add <span style="color: cyan;">--config</span> ./resource-types/terraform-state.yaml

╭─ Resource Type ──────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/terraform-state                  │
│ <span style="color: #5599ff; font-weight: 600;">Physical/Virtual:</span> physical                   │
│ <span style="color: #5599ff; font-weight: 600;">User Addable:</span> yes                            │
│ <span style="color: #66cc66; font-weight: 600;">Registered:</span> 2026-02-11 14:30                 │
╰──────────────────────────────────────────────╯

╭─ CLI Arguments ──────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Argument</span>        <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>                                        │
│ <span style="opacity: 0.7;">──────────────  ────────  ──────────────────────────────────────────────</span>     │
│ <span style="color: cyan;">--state-path</span>    yes       Path to terraform.tfstate or remote state config   │
│ <span style="color: cyan;">--workspace</span>     no        Terraform workspace name (default: "default")      │
╰──────────────────────────────────────────────────────────────────────────────╯

╭─ Child Types ──────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Auto-discover:</span> fs-file     │
╰────────────────────────────╯

╭─ Sandbox ───────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Strategy:</span> filesystem_copy                           │
│ <span style="color: #5599ff; font-weight: 600;">Handler:</span> local/terraform-state-handler (custom)     │
╰─────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource type registered
<span style="color: cyan; font-weight: 600;">ℹ</span> New subcommand available: agents resource add local/terraform-state
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> skill add <span style="color: cyan;">--config</span> ./skills/terraform-ops.yaml

╭─ Skill ──────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/terraform-ops                        │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Terraform infrastructure operations │
│ <span style="color: #66cc66; font-weight: 600;">Config:</span> ./skills/terraform-ops.yaml              │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 14:31                        │
╰──────────────────────────────────────────────────╯

╭─ Includes ────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">local/file-ops</span> (registered)   │
╰───────────────────────────────╯

╭─ Tool Sources ───────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Source</span>    <span style="color: cyan; font-weight: 600;">Count</span>  <span style="color: cyan; font-weight: 600;">Details</span>                                             │
│ <span style="opacity: 0.7;">────────  ─────  ──────────────────────────────────────────────</span>      │
│ custom    3      terraform_plan, terraform_show, cloud_metrics       │
│ included  5      local/file-ops (5)                                  │
│ <span style="opacity: 0.7;">────────  ─────  ──────────────────────────────────────────────</span>      │
│ <span style="color: yellow; font-weight: 600;">Total:</span>    8                                                          │
╰──────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Skill registered with 8 tools
</code></pre></div>

#### Step 2: Set Up the Project

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Register the infrastructure git checkout</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add git-checkout local/infra-repo \
    <span style="color: cyan;">--path</span> /repos/infrastructure <span style="color: cyan;">--branch</span> main

╭─ Resource ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/infra-repo                          │
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXR8A1B2C3D4E5F6G7H8J9K0                  │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> git-checkout                              │
│ <span style="color: #5599ff; font-weight: 600;">Physical/Virtual:</span> physical                      │
│ <span style="color: #66cc66; font-weight: 600;">Path:</span> /repos/infrastructure                     │
│ <span style="color: #5599ff; font-weight: 600;">Branch:</span> main                                    │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 14:32                       │
╰─────────────────────────────────────────────────╯

╭─ Auto-discovered Children ─────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>               <span style="color: cyan; font-weight: 600;">Type</span>            <span style="color: cyan; font-weight: 600;">Status</span>                            │
│ <span style="opacity: 0.7;">───────────────  ──────────────  ─────────────────</span>                 │
│ 01HXR8A1B2C3…   git             <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│ 01HXR8A1B2C4…   git-remote      <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│ 01HXR8A1B2C5…   git-branch      <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│ 01HXR8A1B2C6…   fs-directory    <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│   + 18 git-commit resources                                        │
│   + 84 git-tree-entry resources                                    │
│   + 6 fs-directory + 42 fs-file                                    │
╰────────────────────────────────────────────────────────────────────╯

╭─ Capabilities ─────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Readable:</span> yes                  │
│ <span style="color: yellow; font-weight: 600;">Writable:</span> yes                  │
│ <span style="color: #66cc66; font-weight: 600;">Sandboxable:</span> yes               │
│ <span style="color: #66cc66; font-weight: 600;">Checkpointable:</span> yes            │
│ <span style="color: #5599ff; font-weight: 600;">Sandbox Strategy:</span> git_worktree │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource registered (155 child resources discovered)
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Register the Terraform state for the production workspace</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add local/terraform-state local/prod-tfstate \
    <span style="color: cyan;">--state-path</span> /repos/infrastructure/environments/prod/terraform.tfstate \
    <span style="color: cyan;">--workspace</span> production

╭─ Resource ──────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/prod-tfstate                                                   │
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXR8B2C3D4E5F6G7H8J9K0L1                                              │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> local/terraform-state                                                 │
│ <span style="color: #5599ff; font-weight: 600;">Physical/Virtual:</span> physical                                                  │
│ <span style="color: #66cc66; font-weight: 600;">State Path:</span> /repos/infrastructure/environments/prod/terraform.tfstate       │
│ <span style="color: #5599ff; font-weight: 600;">Workspace:</span> production                                                       │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 14:32                                                   │
╰─────────────────────────────────────────────────────────────────────────────╯

╭─ Auto-discovered Children ─────────────╮
│   + 1 fs-file (terraform.tfstate)      │
╰────────────────────────────────────────╯

╭─ Capabilities ──────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Readable:</span> yes                       │
│ <span style="color: yellow; font-weight: 600;">Writable:</span> yes                       │
│ <span style="color: #66cc66; font-weight: 600;">Sandboxable:</span> yes                    │
│ <span style="color: #66cc66; font-weight: 600;">Checkpointable:</span> yes                 │
│ <span style="color: #5599ff; font-weight: 600;">Sandbox Strategy:</span> filesystem_copy   │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource registered (1 child resource discovered)
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Create the project, linking both resources by name</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project create <span style="color: yellow;">-d</span> <span style="color: #66cc66;">"Production infrastructure"</span> \
    <span style="color: cyan;">--resource</span> local/infra-repo \
    <span style="color: cyan;">--resource</span> local/prod-tfstate \
    <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">"Never delete or modify resources tagged with 'critical: true'"</span> \
    <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">"All changes must be backward-compatible with running services"</span> \
    <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">"Cost changes must be documented in the PR description"</span> \
    local/infra-prod

╭─ Project Created ─────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/infra-prod                        │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Production infrastructure        │
│ <span style="color: #5599ff; font-weight: 600;">Remote:</span> no                                    │
╰───────────────────────────────────────────────╯

╭─ Linked Resources ──────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Resource</span>                       <span style="color: cyan; font-weight: 600;">Type</span>                    <span style="color: cyan; font-weight: 600;">Read-Only</span>    │
│ <span style="opacity: 0.7;">────────────────────────────  ──────────────────────  ─────────</span>     │
│ local/infra-repo              git-checkout              no          │
│ local/prod-tfstate            local/terraform-state     no          │
╰─────────────────────────────────────────────────────────────────────╯

╭─ Invariants ──────────────────────────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">1.</span> Never delete or modify resources tagged with 'critical: true'          │
│ <span style="color: magenta; font-weight: 600;">2.</span> All changes must be backward-compatible with running services          │
│ <span style="color: magenta; font-weight: 600;">3.</span> Cost changes must be documented in the PR description                  │
╰───────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project created
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation add <span style="color: cyan;">--config</span> validations/tf-validate.yaml <span style="color: cyan;">--required</span> local/tf-validate

╭─ Validation Registered ────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/tf-validate                                            │
│ <span style="color: #5599ff; font-weight: 600;">Command:</span> cd environments/prod && terraform validate                │
│ <span style="color: #66cc66; font-weight: 600;">Mode:</span> required                                                     │
│ <span style="color: yellow; font-weight: 600;">Timeout:</span> 300s                                                      │
╰────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation registered

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> local/infra-prod local/tf-validate
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached to project local/infra-prod
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation add <span style="color: cyan;">--config</span> validations/tf-plan.yaml <span style="color: cyan;">--informational</span> local/tf-plan

╭─ Validation Registered ─────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/tf-plan                                                              │
│ <span style="color: #5599ff; font-weight: 600;">Command:</span> cd environments/prod && terraform plan -detailed-exitcode              │
│ <span style="color: yellow; font-weight: 600;">Mode:</span> informational                                                             │
│ <span style="color: yellow; font-weight: 600;">Timeout:</span> 300s                                                                   │
╰─────────────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation registered

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> local/infra-prod local/tf-plan
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached to project local/infra-prod
</code></pre></div>

#### Step 3: Create and Run the Optimization Action

Create `actions/infra-optimize.yaml`:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">name</span>: local/infra-optimize
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Analyze and optimize cloud infrastructure costs"</span>
<span style="color: cyan; font-weight: 600;">definition_of_done</span>: |
  - Unused resources are identified and removal plans generated
  - Over-provisioned resources are identified with right-sizing recommendations
  - Terraform changes implement the approved optimizations
  - terraform validate passes on all changes
  - terraform plan shows no unexpected resource deletions
  - Estimated monthly cost savings are documented
<span style="color: cyan; font-weight: 600;">strategy_actor</span>: local/refactoring-strategist
<span style="color: cyan; font-weight: 600;">execution_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">automation_profile</span>: supervised
<span style="color: cyan; font-weight: 600;">reusable</span>: <span style="color: yellow;">true</span>
<span style="color: cyan; font-weight: 600;">state</span>: <span style="color: yellow;">available</span>
<span style="color: cyan; font-weight: 600;">args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: optimization_targets
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">"all"</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Comma-separated: compute, storage, networking, database, all"</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: min_savings_threshold
    <span style="color: cyan; font-weight: 600;">type</span>: float
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: yellow;">10.0</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Minimum monthly savings (USD) to include an optimization"</span>
<span style="color: cyan; font-weight: 600;">invariants</span>:
  - <span style="color: #66cc66;">"Changes to production databases require manual approval regardless of profile"</span>
  - <span style="color: #66cc66;">"Instance type downgrades must verify current peak CPU &lt; 70% of new capacity"</span>
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action create <span style="color: cyan;">--config</span> ./actions/infra-optimize.yaml

╭─ Action Created ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/infra-optimize                            │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> 01HXR8C3D4E5F6G7H8J9K0L1M2                        │
│ <span style="color: yellow; font-weight: 600;">State:</span> available                                      │
│ <span style="color: magenta; font-weight: 600;">Strategy Actor:</span> local/refactoring-strategist          │
│ <span style="color: magenta; font-weight: 600;">Execution Actor:</span> anthropic/claude-3.5-sonnet          │
│ <span style="color: #66cc66; font-weight: 600;">Reusable:</span> yes                                         │
│ <span style="color: #5599ff; font-weight: 600;">Read Only:</span> no                                         │
│ <span style="color: #66cc66; font-weight: 600;">Config:</span> ./actions/infra-optimize.yaml                 │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 14:33                             │
╰───────────────────────────────────────────────────────╯

╭─ Definition of Done ──────────────────────────────────────────────────╮
│ - Unused resources are identified and removal plans generated         │
│ - Over-provisioned resources identified with right-sizing recs        │
│ - Terraform changes implement the approved optimizations              │
│ - terraform validate passes on all changes                            │
│ - terraform plan shows no unexpected resource deletions               │
│ - Estimated monthly cost savings are documented                       │
╰───────────────────────────────────────────────────────────────────────╯

╭─ Arguments ───────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>                    <span style="color: cyan; font-weight: 600;">Type</span>    <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>                             │
│ <span style="opacity: 0.7;">──────────────────────  ──────  ────────  ──────────────────────────────────</span>      │
│ optimization_targets    string  no        Comma-separated: compute, storage, …    │
│ min_savings_threshold   float   no        Min monthly savings (USD) to include    │
╰───────────────────────────────────────────────────────────────────────────────────╯

╭─ Invariants ──────────────────────────────────────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">1.</span> Changes to production databases require manual approval regardless of profile      │
│ <span style="color: magenta; font-weight: 600;">2.</span> Instance type downgrades must verify current peak CPU &lt; 70% of new capacity        │
╰───────────────────────────────────────────────────────────────────────────────────────╯

╭─ Automation ──────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> supervised                   │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> action config                 │
╰───────────────────────────────────────╯

╭─ Usage ─────────────────────────────────────────────────────────────╮
│ agents plan use local/infra-optimize local/infra-prod               │
│   <span style="color: cyan;">--arg</span> optimization_targets=TARGET <span style="color: cyan;">--arg</span> min_savings_threshold=N   │
╰─────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Action created
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan use \
    <span style="color: cyan;">--arg</span> optimization_targets=<span style="color: #66cc66;">"compute,storage"</span> \
    <span style="color: cyan;">--arg</span> min_savings_threshold=25.0 \
    local/infra-optimize local/infra-prod

╭─ Plan Created ─────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan ID:</span> 01HXR8D4E5F6G7H8J9K0L1M2N3                    │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> strategize                                      │
│ <span style="color: magenta; font-weight: 600;">Action:</span> local/infra-optimize                           │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/infra-prod                              │
│ <span style="color: #66cc66; font-weight: 600;">Automation:</span> supervised                                 │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                             │
╰────────────────────────────────────────────────────────╯

╭─ Inputs ──────────────────────────────────────╮
│ - optimization_targets=compute,storage        │
│ - min_savings_threshold=25.0                  │
╰───────────────────────────────────────────────╯

╭─ Actors ─────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Strategy:</span> local/refactoring-strategist       │
│ <span style="color: magenta; font-weight: 600;">Execution:</span> anthropic/claude-3.5-sonnet       │
│ <span style="color: #5599ff; font-weight: 600;">Estimation:</span> (none)                           │
╰──────────────────────────────────────────────╯

╭─ Plan Invariants ──────────────────────────────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Scope</span>     <span style="color: magenta; font-weight: 600;">Source</span>    <span style="color: magenta; font-weight: 600;">Invariant</span>                                                      │
│ <span style="opacity: 0.7;">────────  ────────  ─────────────────────────────────────────────────────────</span>      │
│ plan      action    Prod DB changes require manual approval regardless             │
│ plan      action    Instance downgrades must verify peak CPU &lt; 70% of new cap      │
│ project   config    Never delete or modify resources tagged 'critical: true'       │
│ project   config    All changes must be backward-compatible with running svcs      │
│ project   config    Cost changes must be documented in PR description              │
╰────────────────────────────────────────────────────────────────────────────────────╯

╭─ Context ──────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Resources:</span> 2 (git-checkout, terraform-state)       │
│ <span style="color: #5599ff; font-weight: 600;">Indexed Files:</span> 156                                 │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> strategize                                   │
│ <span style="color: #5599ff; font-weight: 600;">Hot Token Budget:</span> 12,000                           │
╰────────────────────────────────────────────────────╯

╭─ Next Steps ──────────────────────────────────────────╮
│ - agents plan execute 01HXR8D4E5F6G7H8J9K0L1M2N3      │
│ - agents plan status 01HXR8D4E5F6G7H8J9K0L1M2N3       │
│ - agents plan tree 01HXR8D4E5F6G7H8J9K0L1M2N3         │
╰───────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan created
</code></pre></div>

The strategy actor queries cloud metrics via the `cloud_metrics` tool, analyzes the Terraform state using `terraform_show`, and proposes optimizations with cost estimates. Because the automation profile is `supervised`, the engineer reviews the full strategy — including any proposed instance downgrades or resource removals — before execution modifies any Terraform files. The execution actor then generates the `.tf` changes, and both validations (`terraform validate` and `terraform plan -detailed-exitcode`) run automatically before the plan can be applied.

---

### Example 9: Session-Driven Interactive Exploration

**Scenario**: A developer uses a CleverAgents session to interactively explore a new codebase, ask questions, and gradually build up an action to automate a recurring task.

**Complexity**: Beginner-Intermediate. Session-based, conversational, action creation through natural language.

#### Step 1: Start a Session

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> session create <span style="color: cyan;">--actor</span> anthropic/claude-3.5-sonnet

╭─ Session ────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> 01HXR9A1B2C3D4E5F6G7H8I9J0           │
│ <span style="color: magenta; font-weight: 600;">Actor:</span> anthropic/claude-3.5-sonnet       │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 09:15                │
│ <span style="color: #5599ff; font-weight: 600;">Namespace:</span> local                         │
╰──────────────────────────────────────────╯

╭─ Settings ─────────────╮
│ <span style="color: magenta; font-weight: 600;">Automation:</span> review     │
│ <span style="color: #5599ff; font-weight: 600;">Streaming:</span> off         │
│ <span style="color: #5599ff; font-weight: 600;">Context:</span> default       │
│ <span style="color: #5599ff; font-weight: 600;">Memory:</span> enabled        │
│ <span style="color: yellow; font-weight: 600;">Max History:</span> 50 turns  │
╰────────────────────────╯

╭─ Actor Details ────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Provider:</span> anthropic                    │
│ <span style="color: magenta; font-weight: 600;">Model:</span> claude-3.5-sonnet               │
│ <span style="color: #5599ff; font-weight: 600;">Temperature:</span> 0.7                       │
│ <span style="color: #5599ff; font-weight: 600;">Context Window:</span> 200K tokens            │
╰────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Session created
</code></pre></div>

#### Step 2: Explore the Codebase Interactively

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> session tell <span style="color: cyan;">--session</span> 01HXR9A1B2C3D4E5F6G7H8I9J0 \
    <span style="color: #66cc66;">"I just joined the team and need to understand the api-service project. What are the main modules and how do they interact?"</span>

╭─ Plan Request ──────────────────────────────────────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Actor:</span> anthropic/claude-3.5-sonnet                                                      │
│ <span style="color: cyan; font-weight: 600;">Session:</span> 01HXR9A1B2C3D4E5F6G7H8I9J0                                                     │
│ <span style="color: magenta; font-weight: 600;">Automation:</span> review                                                                      │
│ <span style="color: #5599ff; font-weight: 600;">Prompt:</span> I just joined the team and need to understand the api-service project. Wha...   │
╰─────────────────────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66;">▍</span> The **api-service** project is organized into 5 core modules:

  1. **`src/api/routes/`** — HTTP route definitions (REST + GraphQL). Each domain
     entity has its own router file (e.g. `users.py`, `orders.py`, `products.py`).

  2. **`src/api/services/`** — Business logic layer. Services are injected into
     routes via dependency injection. Key files: `user_service.py`,
     `order_service.py`, `notification_service.py`.

  3. **`src/api/models/`** — SQLAlchemy ORM models and Pydantic schemas. The
     models map 1:1 to database tables; schemas handle request/response validation.

  4. **`src/api/auth/`** — Authentication and authorization. Implements JWT-based
     auth with role-based access control. Middleware in `auth_middleware.py`
     intercepts every request before it reaches a route handler.

  5. **`src/api/workers/`** — Background task processors using Celery. Handles
     async jobs like email dispatch, report generation, and webhook delivery.

  **Data flow**: Routes → Services → Models → Database. Auth middleware gates
  every route. Workers are dispatched by services for async operations.

╭─ Commands Executed ──────────────────────────────────────────────────────────────╮
│ - agents resource inspect local/api-service-repo --tree                          │
│ - agents resource inspect local/api-service-repo --file src/api/__init__.py      │
╰──────────────────────────────────────────────────────────────────────────────────╯

╭─ Usage ─────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Input Tokens:</span> 2,480         │
│ <span style="color: #5599ff; font-weight: 600;">Output Tokens:</span> 846          │
│ <span style="color: yellow; font-weight: 600;">Cost:</span> $0.0128               │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 4.1s              │
│ <span style="color: #5599ff; font-weight: 600;">Tool Calls:</span> 2               │
╰─────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Orchestrator completed 2 commands
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> session tell <span style="color: cyan;">--session</span> 01HXR9A1B2C3D4E5F6G7H8I9J0 \
    <span style="color: #66cc66;">"Show me how authentication works. What's the flow from request to response?"</span>

╭─ Plan Request ───────────────────────────────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Actor:</span> anthropic/claude-3.5-sonnet                                               │
│ <span style="color: cyan; font-weight: 600;">Session:</span> 01HXR9A1B2C3D4E5F6G7H8I9J0                                              │
│ <span style="color: magenta; font-weight: 600;">Automation:</span> review                                                               │
│ <span style="color: #5599ff; font-weight: 600;">Prompt:</span> Show me how authentication works. What's the flow from request to res... │
╰──────────────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66;">▍</span> Here is the authentication flow in **api-service**:

  **1. Request arrives** → `auth_middleware.py:34` extracts the `Authorization`
  header and parses the Bearer token.

  **2. Token validation** → `token_service.py:71` decodes the JWT using the
  public key from `config.AUTH_PUBLIC_KEY`. It verifies:
     - Signature (RS256)
     - Expiry (`exp` claim, default 3600s)
     - Issuer (`iss` must match `api-service`)

  **3. User resolution** → `user_service.py:45` loads the user record from the
  database using the `sub` claim. Returns 401 if the user is inactive or deleted.

  **4. Permission check** → `rbac.py:22` evaluates the user's roles against the
  endpoint's required permissions (defined as decorators on each route, e.g.
  `@require_role("admin")`). Returns 403 on insufficient permissions.

  **5. Context injection** → The authenticated user object is attached to
  `request.state.user` so downstream route handlers can access it without
  repeating lookups.

  **Key files**: `src/api/auth/auth_middleware.py`, `src/api/auth/token_service.py`,
  `src/api/auth/rbac.py`, `src/api/services/user_service.py`.

╭─ Commands Executed ──────────────────────────────────────────────────────────────────────╮
│ - agents resource inspect local/api-service-repo --file src/api/auth/auth_middleware.py  │
│ - agents resource inspect local/api-service-repo --file src/api/auth/token_service.py    │
│ - agents resource inspect local/api-service-repo --file src/api/auth/rbac.py             │
╰──────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Usage ─────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Input Tokens:</span> 3,960         │
│ <span style="color: #5599ff; font-weight: 600;">Output Tokens:</span> 1,024        │
│ <span style="color: yellow; font-weight: 600;">Cost:</span> $0.0187               │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 5.3s              │
│ <span style="color: #5599ff; font-weight: 600;">Tool Calls:</span> 3               │
╰─────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Orchestrator completed 3 commands
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> session tell <span style="color: cyan;">--session</span> 01HXR9A1B2C3D4E5F6G7H8I9J0 \
    <span style="color: #66cc66;">"I notice the team manually runs a dependency lock refresh every week. Can you create an action that automates this?"</span>

╭─ Plan Request ──────────────────────────────────────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Actor:</span> anthropic/claude-3.5-sonnet                                                      │
│ <span style="color: cyan; font-weight: 600;">Session:</span> 01HXR9A1B2C3D4E5F6G7H8I9J0                                                     │
│ <span style="color: magenta; font-weight: 600;">Automation:</span> review                                                                      │
│ <span style="color: #5599ff; font-weight: 600;">Prompt:</span> I notice the team manually runs a dependency lock refresh every week. Can...    │
╰─────────────────────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66;">▍</span> I've created a **local/refresh-locks** action that automates the weekly
  dependency lock refresh. Here's what it does:

  1. Checks out the target project's repository
  2. Runs `pip compile` / `poetry lock` (auto-detected from project config)
  3. Runs the test suite to verify nothing broke
  4. Commits the updated lock files on a new branch
  5. Opens a pull request for review

  The action is now available. You can review the generated config with
  `agents action show local/refresh-locks`.

╭─ Commands Executed ──────────────────────────────────────────────────────╮
│ - agents action create --config ./actions/refresh-locks.yaml             │
╰──────────────────────────────────────────────────────────────────────────╯

╭─ Result ────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Action:</span> local/refresh-locks           │
│ <span style="color: #5599ff; font-weight: 600;">Steps:</span> 5                              │
│ <span style="color: #5599ff; font-weight: 600;">Trigger:</span> manual                       │
╰───────────────────────────────────────╯

╭─ Usage ─────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Input Tokens:</span> 5,210         │
│ <span style="color: #5599ff; font-weight: 600;">Output Tokens:</span> 1,380        │
│ <span style="color: yellow; font-weight: 600;">Cost:</span> $0.0249               │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 6.7s              │
│ <span style="color: #5599ff; font-weight: 600;">Tool Calls:</span> 1               │
╰─────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Orchestrator completed 1 command
</code></pre></div>

#### Step 3: Review Session History

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> session show 01HXR9A1B2C3D4E5F6G7H8I9J0

╭─ Session Summary ─────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> 01HXR9A1B2C3D4E5F6G7H8I9J0                │
│ <span style="color: magenta; font-weight: 600;">Actor:</span> anthropic/claude-3.5-sonnet            │
│ <span style="color: yellow; font-weight: 600;">Messages:</span> 6                                   │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 09:15                     │
│ <span style="color: #66cc66; font-weight: 600;">Updated:</span> 2026-02-11 09:28                     │
│ <span style="color: #5599ff; font-weight: 600;">Automation:</span> review                            │
╰───────────────────────────────────────────────╯

╭─ Recent Messages ──────────────────────────────────────────────────────────────────────╮
│ <span style="opacity: 0.7;">user</span>       I just joined the team and need to understand the api-service project...    │
│ <span style="opacity: 0.7;">assistant</span>  The api-service project is organized into 5 core modules...                 │
│ <span style="opacity: 0.7;">user</span>       Show me how authentication works...                                         │
│ <span style="opacity: 0.7;">assistant</span>  Here is the authentication flow in api-service...                           │
│ <span style="opacity: 0.7;">user</span>       I notice the team manually runs a dependency lock refresh...                │
│ <span style="opacity: 0.7;">assistant</span>  I've created a local/refresh-locks action that automates...                 │
╰────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Linked Plans ──────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan ID</span>                      <span style="color: cyan; font-weight: 600;">Phase</span>    <span style="color: cyan; font-weight: 600;">State</span>     │
│ <span style="opacity: 0.7;">───────────────────────────  ───────  ────────</span>  │
│ 01HXR9K4M7N2P3Q5R6S8T9U0V1  execute  complete   │
╰─────────────────────────────────────────────────╯

╭─ Token Usage ──────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Input Tokens:</span> 11,650       │
│ <span style="color: #5599ff; font-weight: 600;">Output Tokens:</span> 3,250       │
│ <span style="color: yellow; font-weight: 600;">Estimated Cost:</span> $0.0564    │
╰────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Session details loaded
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> session export <span style="color: cyan;">--output</span> /tmp/onboarding-session.json 01HXR9A1B2C3D4E5F6G7H8I9J0

╭─ Session Export ────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Session:</span> 01HXR9A1B2C3D4E5F6G7H8I9J0         │
│ <span style="color: #5599ff; font-weight: 600;">Output:</span> /tmp/onboarding-session.json        │
│ <span style="color: yellow; font-weight: 600;">Messages:</span> 6                                 │
│ <span style="color: #66cc66; font-weight: 600;">Size:</span> 38 KB                                 │
│ <span style="color: #5599ff; font-weight: 600;">Format:</span> JSON                                │
╰─────────────────────────────────────────────╯

╭─ Contents ─────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Messages:</span> 6                │
│ <span style="color: #5599ff; font-weight: 600;">Plan References:</span> 1         │
│ <span style="color: #5599ff; font-weight: 600;">Metadata Keys:</span> 3           │
│ <span style="color: yellow; font-weight: 600;">Actor Config:</span> included     │
│ <span style="color: #5599ff; font-weight: 600;">Schema Version:</span> v3         │
╰────────────────────────────╯

╭─ Integrity ──────────────────╮
│ <span style="color: magenta; font-weight: 600;">Checksum:</span> sha256:3e8f...b7d2 │
│ <span style="color: yellow; font-weight: 600;">Encrypted:</span> no                │
╰──────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Export completed
</code></pre></div>

---

### Example 10: Full-Auto Batch Operations — Formatting and Linting

**Scenario**: A team has 15 Python packages in a monorepo that need to be reformatted with `ruff format` and have their imports sorted. This is low-risk and can be fully automated.

**Complexity**: Simple. Full-auto profile, batch execution, minimal risk.

#### Step 1: Create a Formatting Action

Create `actions/format-codebase.yaml`:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">name</span>: local/format-codebase
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Apply code formatting and import sorting"</span>
<span style="color: cyan; font-weight: 600;">definition_of_done</span>: |
  - ruff format passes with zero changes remaining
  - ruff check --select I passes (imports sorted)
  - All existing tests pass
  - No semantic changes to any code
<span style="color: cyan; font-weight: 600;">strategy_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">execution_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">automation_profile</span>: full-auto
<span style="color: cyan; font-weight: 600;">reusable</span>: <span style="color: yellow;">true</span>
<span style="color: cyan; font-weight: 600;">state</span>: <span style="color: yellow;">available</span>
<span style="color: cyan; font-weight: 600;">args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: formatter_config
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">"pyproject.toml"</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Path to the formatter configuration file"</span>
<span style="color: cyan; font-weight: 600;">invariants</span>:
  - <span style="color: #66cc66;">"Only whitespace and import ordering changes — no semantic modifications"</span>
  - <span style="color: #66cc66;">"Every package must pass its own test suite after formatting"</span>
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action create <span style="color: cyan;">--config</span> ./actions/format-codebase.yaml

╭─ Action Created ─────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/format-codebase                      │
│ <span style="color: yellow; font-weight: 600;">State:</span> available                                 │
│ <span style="color: magenta; font-weight: 600;">Strategy Actor:</span> anthropic/claude-3.5-sonnet      │
│ <span style="color: magenta; font-weight: 600;">Execution Actor:</span> anthropic/claude-3.5-sonnet     │
│ <span style="color: #66cc66; font-weight: 600;">Reusable:</span> yes                                    │
│ <span style="color: #5599ff; font-weight: 600;">Read Only:</span> no                                    │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 14:00                        │
╰──────────────────────────────────────────────────╯

╭─ Definition of Done ──────────────────────────────────────╮
│ - ruff format passes with zero changes remaining          │
│ - ruff check --select I passes (imports sorted)           │
│ - All existing tests pass                                 │
│ - No semantic changes to any code                         │
╰───────────────────────────────────────────────────────────╯

╭─ Arguments ──────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>              <span style="color: cyan; font-weight: 600;">Type</span>    <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>                              │
│ <span style="opacity: 0.7;">────────────────  ──────  ────────  ──────────────────────────────────────</span>   │
│ formatter_config  string  no        Path to the formatter configuration file │
╰──────────────────────────────────────────────────────────────────────────────╯

╭─ Invariants ──────────────────────────────────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">1.</span> Only whitespace and import ordering changes — no semantic modifications        │
│ <span style="color: magenta; font-weight: 600;">2.</span> Every package must pass its own test suite after formatting                    │
╰───────────────────────────────────────────────────────────────────────────────────╯

╭─ Automation ──────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> full-auto                    │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> action                        │
╰───────────────────────────────────────╯

╭─ Usage ─────────────────────────────────────────────────────────╮
│ agents plan use local/format-codebase local/&lt;project&gt;           │
│   <span style="color: cyan;">--arg</span> formatter_config="pyproject.toml"  <span style="opacity: 0.7;">(optional)</span>           │
╰─────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Action created
</code></pre></div>

#### Step 2: Register All Packages and Run in Batch

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Register all 15 packages as resources and projects.</span>
<span style="opacity: 0.7;"># resource add accepts a name — use it to link to project create.</span>

for pkg in auth billing common gateway inventory notifications \
           orders payments reporting search shipping users webhooks \
           workers analytics; do
    <span style="color: cyan; font-weight: 600;">agents</span> resource add git-checkout <span style="color: #66cc66;">"local/pkg-${pkg}-repo"</span> \
        <span style="color: cyan;">--path</span> <span style="color: #66cc66;">"/repos/monorepo/packages/${pkg}"</span> <span style="color: cyan;">--branch</span> main
    <span style="color: cyan; font-weight: 600;">agents</span> project create <span style="color: yellow;">-d</span> <span style="color: #66cc66;">"Package: ${pkg}"</span> \
        <span style="color: cyan;">--resource</span> <span style="color: #66cc66;">"local/pkg-${pkg}-repo"</span> \
        <span style="color: #66cc66;">"local/pkg-${pkg}"</span>
    <span style="color: cyan; font-weight: 600;">agents</span> validation add <span style="color: cyan;">--config</span> <span style="color: #66cc66;">"validations/pkg-${pkg}.yaml"</span> <span style="color: cyan;">--required</span> <span style="color: #66cc66;">"local/pkg-${pkg}-test"</span>
    <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> <span style="color: #66cc66;">"local/pkg-${pkg}"</span> <span style="color: #66cc66;">"local/pkg-${pkg}-test"</span>
done
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Loop output — first 2 iterations shown, remaining 13 condensed</span>

<span style="opacity: 0.7;"># --- auth ---</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add git-checkout local/pkg-auth-repo \
    <span style="color: cyan;">--path</span> /repos/monorepo/packages/auth <span style="color: cyan;">--branch</span> main

╭─ Resource ──────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/pkg-auth-repo                          │
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXR7B1A2B3C4D5E6F7G8H9J0                      │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> git-checkout                                  │
│ <span style="color: #5599ff; font-weight: 600;">Physical/Virtual:</span> physical                          │
│ <span style="color: #66cc66; font-weight: 600;">Path:</span> /repos/monorepo/packages/auth                 │
│ <span style="color: #5599ff; font-weight: 600;">Branch:</span> main                                        │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 14:01                           │
╰─────────────────────────────────────────────────────╯

╭─ Auto-discovered Children ─────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>               <span style="color: cyan; font-weight: 600;">Type</span>            <span style="color: cyan; font-weight: 600;">Status</span>                            │
│ <span style="opacity: 0.7;">───────────────  ──────────────  ─────────────────</span>                 │
│ 01HXR7B1A2B3…   git             <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│ 01HXR7B1A2B4…   git-remote      <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│ 01HXR7B1A2B5…   git-branch      <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│   + 22 git-commit resources                                        │
│   + 134 git-tree-entry resources                                   │
│   + 2 fs-directory + 11 fs-file                                    │
╰────────────────────────────────────────────────────────────────────╯

╭─ Capabilities ─────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Readable:</span> yes                  │
│ <span style="color: yellow; font-weight: 600;">Writable:</span> yes                  │
│ <span style="color: #66cc66; font-weight: 600;">Sandboxable:</span> yes               │
│ <span style="color: #66cc66; font-weight: 600;">Checkpointable:</span> yes            │
│ <span style="color: #5599ff; font-weight: 600;">Sandbox Strategy:</span> git_worktree │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource registered (172 child resources discovered)

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project create <span style="color: yellow;">-d</span> <span style="color: #66cc66;">"Package: auth"</span> \
    <span style="color: cyan;">--resource</span> local/pkg-auth-repo local/pkg-auth

╭─ Project Created ──────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/pkg-auth                           │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Package: auth                     │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> local                                    │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 14:01                      │
╰────────────────────────────────────────────────╯

╭─ Linked Resources ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Resource</span>           <span style="color: cyan; font-weight: 600;">Type</span>          <span style="color: cyan; font-weight: 600;">Read-Only</span>               │
│ <span style="opacity: 0.7;">─────────────────  ──────────────  ─────────</span>             │
│ local/pkg-auth-repo  git-checkout    no                  │
╰──────────────────────────────────────────────────────────╯

╭─ Defaults ──────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Sandbox:</span> git_worktree                   │
│ <span style="color: #66cc66; font-weight: 600;">Validations:</span> 0                          │
│ <span style="color: yellow; font-weight: 600;">Context Filters:</span> none                   │
│ <span style="color: magenta; font-weight: 600;">Automation Profile:</span> (inherits global)   │
╰─────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project created

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation add <span style="color: cyan;">--config</span> validations/pkg-auth.yaml <span style="color: cyan;">--required</span> local/pkg-auth-test

╭─ Validation Registered ─────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/pkg-auth-test                                                │
│ <span style="color: #5599ff; font-weight: 600;">Command:</span> cd /repos/monorepo/packages/auth &amp;&amp; pytest tests/              │
│ <span style="color: #66cc66; font-weight: 600;">Mode:</span> required                                                          │
│ <span style="color: yellow; font-weight: 600;">Timeout:</span> 300s                                                           │
╰─────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation registered

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> local/pkg-auth local/pkg-auth-test
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached to project local/pkg-auth

<span style="opacity: 0.7;"># --- billing ---</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add git-checkout local/pkg-billing-repo \
    <span style="color: cyan;">--path</span> /repos/monorepo/packages/billing <span style="color: cyan;">--branch</span> main
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource registered — <span style="color: cyan; font-weight: 600;">Name:</span> local/pkg-billing-repo (189 children)

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project create <span style="color: yellow;">-d</span> <span style="color: #66cc66;">"Package: billing"</span> \
    <span style="color: cyan;">--resource</span> local/pkg-billing-repo local/pkg-billing
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project created — <span style="color: cyan; font-weight: 600;">Name:</span> local/pkg-billing

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation add <span style="color: cyan;">--config</span> validations/pkg-billing.yaml <span style="color: cyan;">--required</span> local/pkg-billing-test
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation registered — <span style="color: cyan; font-weight: 600;">Name:</span> local/pkg-billing-test

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> local/pkg-billing local/pkg-billing-test
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached to project local/pkg-billing

<span style="opacity: 0.7;"># ... (common, gateway, inventory, notifications, orders, payments,</span>
<span style="opacity: 0.7;">#      reporting, search, shipping, users, webhooks, workers, analytics)</span>
<span style="opacity: 0.7;"># Each iteration: resource add → project create → validation add → validation attach</span>
<span style="opacity: 0.7;"># All 15 packages registered.</span>
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Run formatting across all packages.</span>
<span style="opacity: 0.7;"># full-auto: Strategize, Execute, AND Apply all run without human intervention.</span>
<span style="opacity: 0.7;"># Capture plan IDs so we can check results afterward.</span>

PLAN_IDS=()
for pkg in auth billing common gateway inventory notifications \
           orders payments reporting search shipping users webhooks \
           workers analytics; do
    PID=$(<span style="color: cyan; font-weight: 600;">agents</span> <span style="color: cyan;">--format</span> json plan use \
        <span style="color: cyan;">--automation-profile</span> full-auto \
        local/format-codebase <span style="color: #66cc66;">"local/pkg-${pkg}"</span> \
        | jq -r '.data.plan_id')
    PLAN_IDS+=("$PID")
done
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Plan creation output — first 2 shown, remaining condensed</span>

<span style="opacity: 0.7;"># --- auth ---</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan use \
    <span style="color: cyan;">--automation-profile</span> full-auto \
    local/format-codebase local/pkg-auth

╭─ Plan Created ───────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan ID:</span> 01HXR7D1A2B3C4D5E6F7G8H9J0              │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> strategize (running)                      │
│ <span style="color: magenta; font-weight: 600;">Action:</span> local/format-codebase                    │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/pkg-auth                          │
│ <span style="color: #66cc66; font-weight: 600;">Automation:</span> full-auto                            │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                       │
╰──────────────────────────────────────────────────╯

╭─ Invariants ─────────────────────────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Scope</span>   <span style="color: magenta; font-weight: 600;">Source</span>  <span style="color: magenta; font-weight: 600;">Invariant</span>                                                │
│ <span style="opacity: 0.7;">──────  ──────  ─────────────────────────────────────────────────────</span>    │
│ plan    action  Only whitespace and import ordering changes — no se…     │
│ plan    action  Every package must pass its own test suite after fo…     │
╰──────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan created — full-auto: strategize → execute → apply will proceed automatically

<span style="opacity: 0.7;"># --- billing ---</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan use \
    <span style="color: cyan;">--automation-profile</span> full-auto \
    local/format-codebase local/pkg-billing

╭─ Plan Created ───────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan ID:</span> 01HXR7D2B3C4D5E6F7G8H9J0K1              │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> strategize (running)                      │
│ <span style="color: magenta; font-weight: 600;">Action:</span> local/format-codebase                    │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/pkg-billing                       │
│ <span style="color: #66cc66; font-weight: 600;">Automation:</span> full-auto                            │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                       │
╰──────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan created — full-auto: strategize → execute → apply will proceed automatically

<span style="opacity: 0.7;"># ... (common, gateway, inventory, notifications, orders, payments,</span>
<span style="opacity: 0.7;">#      reporting, search, shipping, users, webhooks, workers, analytics)</span>
<span style="opacity: 0.7;"># 15 plans launched — all running full-auto in background.</span>
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Wait for all plans to finish, then check results</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan list <span style="color: cyan;">--state</span> applied

╭─ Plans ──────────────────────────────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>        <span style="color: cyan; font-weight: 600;">Phase</span>    <span style="color: cyan; font-weight: 600;">State</span>     <span style="color: cyan; font-weight: 600;">Action</span>                 <span style="color: cyan; font-weight: 600;">Project</span>                <span style="color: cyan; font-weight: 600;">Elapsed</span>                   │
│ <span style="opacity: 0.7;">────────  ───────  ────────  ─────────────────────  ─────────────────────  ─────────</span>                 │
│ 01HXR7D1  <span style="color: #66cc66; font-weight: 600;">applied</span>  <span style="color: #66cc66; font-weight: 600;">complete</span>  local/format-codebase  local/pkg-auth         00:02:14                  │
│ 01HXR7D2  <span style="color: #66cc66; font-weight: 600;">applied</span>  <span style="color: #66cc66; font-weight: 600;">complete</span>  local/format-codebase  local/pkg-billing      00:02:31                  │
│ 01HXR7D3  <span style="color: #66cc66; font-weight: 600;">applied</span>  <span style="color: #66cc66; font-weight: 600;">complete</span>  local/format-codebase  local/pkg-common       00:01:47                  │
│ 01HXR7D4  <span style="color: #66cc66; font-weight: 600;">applied</span>  <span style="color: #66cc66; font-weight: 600;">complete</span>  local/format-codebase  local/pkg-gateway      00:02:08                  │
│ 01HXR7D5  <span style="color: #66cc66; font-weight: 600;">applied</span>  <span style="color: #66cc66; font-weight: 600;">complete</span>  local/format-codebase  local/pkg-inventory    00:01:55                  │
│ 01HXR7D6  <span style="color: #66cc66; font-weight: 600;">applied</span>  <span style="color: #66cc66; font-weight: 600;">complete</span>  local/format-codebase  local/pkg-notifications 00:02:42                 │
│ 01HXR7D7  <span style="color: #66cc66; font-weight: 600;">applied</span>  <span style="color: #66cc66; font-weight: 600;">complete</span>  local/format-codebase  local/pkg-orders       00:02:19                  │
│ 01HXR7D8  <span style="color: #66cc66; font-weight: 600;">applied</span>  <span style="color: #66cc66; font-weight: 600;">complete</span>  local/format-codebase  local/pkg-payments     00:01:58                  │
│ 01HXR7D9  <span style="color: #66cc66; font-weight: 600;">applied</span>  <span style="color: #66cc66; font-weight: 600;">complete</span>  local/format-codebase  local/pkg-reporting    00:02:36                  │
│ 01HXR7DA  <span style="color: #66cc66; font-weight: 600;">applied</span>  <span style="color: #66cc66; font-weight: 600;">complete</span>  local/format-codebase  local/pkg-search       00:01:41                  │
│ 01HXR7DB  <span style="color: #66cc66; font-weight: 600;">applied</span>  <span style="color: #66cc66; font-weight: 600;">complete</span>  local/format-codebase  local/pkg-shipping     00:02:22                  │
│ 01HXR7DC  <span style="color: #66cc66; font-weight: 600;">applied</span>  <span style="color: #66cc66; font-weight: 600;">complete</span>  local/format-codebase  local/pkg-users        00:01:49                  │
│ 01HXR7DD  <span style="color: #66cc66; font-weight: 600;">applied</span>  <span style="color: #66cc66; font-weight: 600;">complete</span>  local/format-codebase  local/pkg-webhooks     00:02:05                  │
│ 01HXR7DE  <span style="color: #66cc66; font-weight: 600;">applied</span>  <span style="color: #66cc66; font-weight: 600;">complete</span>  local/format-codebase  local/pkg-analytics    00:02:11                  │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Filters ───────────────────╮
│ <span style="color: yellow; font-weight: 600;">Phase:</span> (any)                │
│ <span style="color: magenta; font-weight: 600;">State:</span> applied              │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> (any)              │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> (any)               │
╰─────────────────────────────╯

╭─ Summary ─────────────╮
│ <span style="color: yellow; font-weight: 600;">Total:</span> 14             │
│ <span style="color: cyan; font-weight: 600;">Processing:</span> 0         │
│ <span style="color: #66cc66; font-weight: 600;">Completed:</span> 14         │
│ <span style="color: #ff6666; font-weight: 600;">Errored:</span> 0            │
╰───────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 14 plans listed

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan list <span style="color: cyan;">--state</span> failed

╭─ Plans ──────────────────────────────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>        <span style="color: cyan; font-weight: 600;">Phase</span>    <span style="color: cyan; font-weight: 600;">State</span>    <span style="color: cyan; font-weight: 600;">Action</span>                 <span style="color: cyan; font-weight: 600;">Project</span>              <span style="color: cyan; font-weight: 600;">Elapsed</span>                      │
│ <span style="opacity: 0.7;">────────  ───────  ───────  ─────────────────────  ───────────────────  ─────────</span>                    │
│ 01HXR7DF  <span style="color: #ff6666; font-weight: 600;">execute</span>  <span style="color: #ff6666; font-weight: 600;">errored</span>  local/format-codebase  local/pkg-workers    00:03:07                     │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Filters ───────────────────╮
│ <span style="color: yellow; font-weight: 600;">Phase:</span> (any)                │
│ <span style="color: magenta; font-weight: 600;">State:</span> failed               │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> (any)              │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> (any)               │
╰─────────────────────────────╯

╭─ Summary ─────────────╮
│ <span style="color: yellow; font-weight: 600;">Total:</span> 1              │
│ <span style="color: cyan; font-weight: 600;">Processing:</span> 0         │
│ <span style="color: #66cc66; font-weight: 600;">Completed:</span> 0          │
│ <span style="color: #ff6666; font-weight: 600;">Errored:</span> 1            │
╰───────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 1 plan listed
</code></pre></div>

---

### Example 11: Complex Graph Actor for Multi-Stage Code Review

**Scenario**: A team builds a custom multi-stage code review actor that performs security analysis, performance analysis, and style checking in a graph topology — with each stage running a different specialized sub-actor.

**Complexity**: Expert. Custom actor graph, multiple sub-actors, advanced actor configuration.

#### Step 1: Define Specialized Sub-Actors

Create `actors/review-pipeline.yaml`:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">name</span>: local/review-pipeline
<span style="color: cyan; font-weight: 600;">cleveragents</span>:
  <span style="color: cyan; font-weight: 600;">version</span>: <span style="color: #66cc66;">"3.0"</span>
  <span style="color: cyan; font-weight: 600;">template_engine</span>: JINJA2
  <span style="color: cyan; font-weight: 600;">default_actor</span>: orchestrator

<span style="color: cyan; font-weight: 600;">global_context</span>:
  <span style="color: cyan; font-weight: 600;">review_standards</span>: <span style="color: #66cc66;">"Google Python Style Guide"</span>
  <span style="color: cyan; font-weight: 600;">severity_levels</span>: <span style="color: #66cc66;">"critical, high, medium, low, info"</span>

<span style="color: cyan; font-weight: 600;">actors</span>:
  <span style="color: cyan; font-weight: 600;">orchestrator</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">actor</span>: anthropic/claude-3.5-sonnet
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.1</span>
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: |
        You are a code review orchestrator. You coordinate specialized reviewers
        and synthesize their findings into a unified review report.
        Standards: {{ context.review_standards }}
        Severity levels: {{ context.severity_levels }}
      <span style="color: cyan; font-weight: 600;">memory_enabled</span>: <span style="color: yellow;">true</span>

  <span style="color: cyan; font-weight: 600;">security_reviewer</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">actor</span>: anthropic/claude-3.5-sonnet
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.0</span>
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: |
        You are a security-focused code reviewer. Analyze code for:
        - Injection vulnerabilities (SQL, command, XSS)
        - Authentication and authorization flaws
        - Sensitive data exposure
        - Insecure cryptographic practices
        - Dependency vulnerabilities
        Report findings with severity levels: {{ context.severity_levels }}

  <span style="color: cyan; font-weight: 600;">performance_reviewer</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">actor</span>: anthropic/claude-3.5-sonnet
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.0</span>
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: |
        You are a performance-focused code reviewer. Analyze code for:
        - N+1 query patterns
        - Unbounded loops or recursion
        - Memory leaks and excessive allocation
        - Missing caching opportunities
        - Blocking operations in async contexts
        Report findings with severity levels: {{ context.severity_levels }}

  <span style="color: cyan; font-weight: 600;">style_reviewer</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: llm
    <span style="color: cyan; font-weight: 600;">config</span>:
      <span style="color: cyan; font-weight: 600;">actor</span>: anthropic/claude-3.5-sonnet
      <span style="color: cyan; font-weight: 600;">temperature</span>: <span style="color: yellow;">0.0</span>
      <span style="color: cyan; font-weight: 600;">system_prompt</span>: |
        You are a code style and maintainability reviewer.
        Standards: {{ context.review_standards }}
        Analyze code for:
        - Naming conventions
        - Function/class design
        - Documentation completeness
        - Test coverage patterns
        - Code duplication

<span style="color: cyan; font-weight: 600;">routes</span>:
  <span style="color: cyan; font-weight: 600;">review_graph</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: graph
    <span style="color: cyan; font-weight: 600;">entry_point</span>: dispatch
    <span style="color: cyan; font-weight: 600;">checkpointing</span>: <span style="color: yellow;">true</span>
    <span style="color: cyan; font-weight: 600;">nodes</span>:
      <span style="color: cyan; font-weight: 600;">dispatch</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: orchestrator
      <span style="color: cyan; font-weight: 600;">security</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: security_reviewer
      <span style="color: cyan; font-weight: 600;">performance</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: performance_reviewer
      <span style="color: cyan; font-weight: 600;">style</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: style_reviewer
      <span style="color: cyan; font-weight: 600;">synthesize</span>:
        <span style="color: cyan; font-weight: 600;">type</span>: agent
        <span style="color: cyan; font-weight: 600;">agent</span>: orchestrator
    <span style="color: cyan; font-weight: 600;">edges</span>:
      - <span style="color: cyan; font-weight: 600;">from</span>: dispatch
        <span style="color: cyan; font-weight: 600;">to</span>: security
      - <span style="color: cyan; font-weight: 600;">from</span>: dispatch
        <span style="color: cyan; font-weight: 600;">to</span>: performance
      - <span style="color: cyan; font-weight: 600;">from</span>: dispatch
        <span style="color: cyan; font-weight: 600;">to</span>: style
      - <span style="color: cyan; font-weight: 600;">from</span>: security
        <span style="color: cyan; font-weight: 600;">to</span>: synthesize
      - <span style="color: cyan; font-weight: 600;">from</span>: performance
        <span style="color: cyan; font-weight: 600;">to</span>: synthesize
      - <span style="color: cyan; font-weight: 600;">from</span>: style
        <span style="color: cyan; font-weight: 600;">to</span>: synthesize
    <span style="color: cyan; font-weight: 600;">parallel_execution</span>: <span style="color: yellow;">true</span>
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor add <span style="color: cyan;">--config</span> ./actors/review-pipeline.yaml \
    <span style="color: cyan;">--skill</span> local/code-analysis \
    <span style="color: cyan;">--skill</span> local/file-ops

╭─ Actor Added ──────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/review-pipeline                    │
│ <span style="color: #5599ff; font-weight: 600;">Provider:</span> anthropic                            │
│ <span style="color: magenta; font-weight: 600;">Model:</span> claude-3.5-sonnet                       │
│ <span style="color: yellow; font-weight: 600;">Default:</span> yes                                   │
│ <span style="color: #ff6666; font-weight: 600;">Unsafe:</span> no                                     │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> graph                                    │
╰────────────────────────────────────────────────╯

╭─ Config ─────────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Path:</span> ./actors/review-pipeline.yaml                  │
│ <span style="color: magenta; font-weight: 600;">Hash:</span> 4f7a1e3                                        │
│ <span style="color: #66cc66; font-weight: 600;">Options:</span> 6                                           │
│ <span style="color: #5599ff; font-weight: 600;">Nodes:</span> 5                                             │
│ <span style="color: #5599ff; font-weight: 600;">Edges:</span> 6                                             │
╰──────────────────────────────────────────────────────╯

╭─ Graph ────────────────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Route:</span> review_graph                                        │
│ <span style="color: #5599ff; font-weight: 600;">Entry Point:</span> dispatch                                      │
│ <span style="color: magenta; font-weight: 600;">Checkpointing:</span> yes                                         │
│ <span style="color: #66cc66; font-weight: 600;">Parallel Execution:</span> yes                                    │
│                                                            │
│ <span style="color: cyan; font-weight: 600;">Node</span>         <span style="color: cyan; font-weight: 600;">Type</span>   <span style="color: cyan; font-weight: 600;">Agent</span>                                  │
│ <span style="opacity: 0.7;">───────────  ─────  ──────────────────────────────</span>         │
│ dispatch     agent  orchestrator                           │
│ security     agent  security_reviewer                      │
│ performance  agent  performance_reviewer                   │
│ style        agent  style_reviewer                         │
│ synthesize   agent  orchestrator                           │
│                                                            │
│ <span style="color: cyan; font-weight: 600;">From</span>         <span style="color: cyan; font-weight: 600;">To</span>                                            │
│ <span style="opacity: 0.7;">───────────  ───────────</span>                                   │
│ dispatch     security                                      │
│ dispatch     performance                                   │
│ dispatch     style                                         │
│ security     synthesize                                    │
│ performance  synthesize                                    │
│ style        synthesize                                    │
╰────────────────────────────────────────────────────────────╯

╭─ Capabilities ──────────────────────╮
│ - multi-stage code review           │
│ - security analysis                 │
│ - performance analysis              │
│ - style and maintainability checks  │
│ - unified report synthesis          │
╰─────────────────────────────────────╯

╭─ Skills ──────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Skill</span>                <span style="color: cyan; font-weight: 600;">Status</span>                       │
│ <span style="opacity: 0.7;">───────────────────  ────────────────────────</span>     │
│ local/code-analysis  <span style="color: #66cc66; font-weight: 600;">attached</span>                     │
│ local/file-ops       <span style="color: #66cc66; font-weight: 600;">attached</span>                     │
╰───────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Actor added
</code></pre></div>

#### Step 2: Create the Review Action Using the Graph Actor

Create `actions/deep-review.yaml`:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">name</span>: local/deep-review
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Multi-stage deep code review with specialized reviewers"</span>
<span style="color: cyan; font-weight: 600;">definition_of_done</span>: |
  - Security analysis complete with all findings classified by severity
  - Performance analysis complete with all findings classified by severity
  - Style analysis complete with all findings classified by severity
  - Unified review report generated with prioritized action items
  - Critical and high-severity issues have suggested fixes
<span style="color: cyan; font-weight: 600;">strategy_actor</span>: local/review-pipeline
<span style="color: cyan; font-weight: 600;">execution_actor</span>: local/review-pipeline
<span style="color: cyan; font-weight: 600;">read_only</span>: <span style="color: yellow;">true</span>
<span style="color: cyan; font-weight: 600;">reusable</span>: <span style="color: yellow;">true</span>
<span style="color: cyan; font-weight: 600;">state</span>: <span style="color: yellow;">available</span>
<span style="color: cyan; font-weight: 600;">args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: target_paths
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Comma-separated file or directory paths to review"</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: review_depth
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">"standard"</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Review depth: quick, standard, thorough"</span>
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action create <span style="color: cyan;">--config</span> ./actions/deep-review.yaml

╭─ Action Created ─────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/deep-review                                      │
│ <span style="color: yellow; font-weight: 600;">State:</span> available                                             │
│ <span style="color: magenta; font-weight: 600;">Strategy Actor:</span> local/review-pipeline                        │
│ <span style="color: magenta; font-weight: 600;">Execution Actor:</span> local/review-pipeline                       │
│ <span style="color: #66cc66; font-weight: 600;">Reusable:</span> yes                                                │
│ <span style="color: #5599ff; font-weight: 600;">Read Only:</span> yes                                               │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 16:30                                    │
╰──────────────────────────────────────────────────────────────╯

╭─ Definition of Done ──────────────────────────────────────────────────────╮
│ - Security analysis complete with all findings classified by severity     │
│ - Performance analysis complete with all findings classified by severity  │
│ - Style analysis complete with all findings classified by severity        │
│ - Unified review report generated with prioritized action items           │
│ - Critical and high-severity issues have suggested fixes                  │
╰───────────────────────────────────────────────────────────────────────────╯

╭─ Arguments ───────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>          <span style="color: cyan; font-weight: 600;">Type</span>    <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>                                       │
│ <span style="opacity: 0.7;">────────────  ──────  ────────  ──────────────────────────────────────────────</span>    │
│ target_paths  string  yes       Comma-separated file or directory paths to review │
│ review_depth  string  no        Review depth: quick, standard, thorough           │
╰───────────────────────────────────────────────────────────────────────────────────╯

╭─ Automation ──────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> supervised                   │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> default                       │
╰───────────────────────────────────────╯

╭─ Usage ────────────────────────────────────────────────────────────────────────╮
│ agents plan use local/deep-review local/&lt;project&gt;                              │
│   <span style="color: cyan;">--arg</span> target_paths=&quot;src/auth/,src/routes/&quot;                                   │
│   <span style="color: cyan;">--arg</span> review_depth=&quot;thorough&quot;  <span style="opacity: 0.7;">(optional, default: &quot;standard&quot;)</span>               │
╰────────────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Action created
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan use \
    <span style="color: cyan;">--automation-profile</span> trusted \
    <span style="color: cyan;">--arg</span> target_paths=<span style="color: #66cc66;">"src/auth/,src/routes/"</span> \
    <span style="color: cyan;">--arg</span> review_depth=<span style="color: #66cc66;">"thorough"</span> \
    local/deep-review local/api-service

╭─ Plan Created ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXR8D2E3F4G5H6J7K8L9M0N1                     │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> strategize                                    │
│ <span style="color: magenta; font-weight: 600;">State:</span> processing                                    │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/deep-review                            │
│ <span style="color: #66cc66; font-weight: 600;">Project:</span> local/api-service                           │
│ <span style="color: #66cc66; font-weight: 600;">Automation:</span> trusted                                  │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                           │
╰──────────────────────────────────────────────────────╯

╭─ Inputs ───────────────────────────────────────╮
│ - target_paths="src/auth/,src/routes/"         │
│ - review_depth="thorough"                      │
│ - automation_profile=trusted                   │
╰────────────────────────────────────────────────╯

╭─ Actors ────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Strategy:</span> local/review-pipeline                 │
│ <span style="color: magenta; font-weight: 600;">Execution:</span> local/review-pipeline                │
│ <span style="color: #5599ff; font-weight: 600;">Estimation:</span> (none)                              │
│ <span style="color: #5599ff; font-weight: 600;">Actor Type:</span> graph (5 nodes, 6 edges)            │
╰─────────────────────────────────────────────────╯

╭─ Automation ───────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> trusted                       │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> plan override                  │
│ <span style="color: #5599ff; font-weight: 600;">Read-Only:</span> yes                         │
╰────────────────────────────────────────╯

╭─ Context ──────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Resources:</span> 1 (git-checkout)        │
│ <span style="color: #5599ff; font-weight: 600;">Indexed Files:</span> 312                 │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> strategize                   │
│ <span style="color: #5599ff; font-weight: 600;">Hot Token Budget:</span> 24,000           │
╰────────────────────────────────────╯

╭─ Next Steps ─────────────────────────────────────────────────────────╮
│ <span style="opacity: 0.7;">Trusted profile — strategize and execute will proceed automatically.</span> │
│ - agents plan status 01HXR8D2E3F4G5H6J7K8L9M0N1                      │
│ - agents plan tree 01HXR8D2E3F4G5H6J7K8L9M0N1                        │
╰──────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan created
</code></pre></div>

The graph actor executes `review_graph` with parallel fan-out. The `dispatch` node (orchestrator) analyzes the target paths and prepares review context, then three edges fire concurrently: `security`, `performance`, and `style` nodes each run their specialized sub-actor in parallel. Once all three complete, their outputs converge at the `synthesize` node, where the orchestrator merges findings into a single prioritized report. Because `read_only: true`, no file modifications are produced — only the review report.

---

### Example 12: Large-Scale Feature Implementation with Hierarchical Decomposition

**Scenario**: A startup is building a new notification system that spans the backend API, a message queue, a worker service, and a frontend dashboard. The feature requires changes across 4 projects and should decompose into manageable child plans.

**Complexity**: Expert. Multi-project, hierarchical child plans, deep decision tree, invariant reconciliation, full plan lifecycle.

#### Step 1: Set Up All Projects

<div class="highlight"><pre><code><span style="opacity: 0.7;"># Register the API repo resource (full output shown)</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add git-checkout local/api-repo <span style="color: cyan;">--path</span> /repos/api <span style="color: cyan;">--branch</span> main

╭─ Resource ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/api-repo                            │
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXRA1A2B3C4D5E6F7G8H9J0K                  │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> git-checkout                              │
│ <span style="color: #5599ff; font-weight: 600;">Physical/Virtual:</span> physical                      │
│ <span style="color: #66cc66; font-weight: 600;">Path:</span> /repos/api                                │
│ <span style="color: #5599ff; font-weight: 600;">Branch:</span> main                                    │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 14:00                       │
╰─────────────────────────────────────────────────╯

╭─ Auto-discovered Children ─────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>               <span style="color: cyan; font-weight: 600;">Type</span>            <span style="color: cyan; font-weight: 600;">Status</span>                            │
│ <span style="opacity: 0.7;">───────────────  ──────────────  ─────────────────</span>                 │
│ 01HXRA1A2B3C…   git             <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│ 01HXRA1A2B3D…   git-remote      <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│ 01HXRA1A2B3E…   git-branch      <span style="color: #66cc66; font-weight: 600;">created</span>                            │
│   + 48 git-commit resources                                        │
│   + 312 git-tree-entry resources                                   │
│   + 6 fs-directory + 42 fs-file                                    │
╰────────────────────────────────────────────────────────────────────╯

╭─ Capabilities ─────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Readable:</span> yes                  │
│ <span style="color: yellow; font-weight: 600;">Writable:</span> yes                  │
│ <span style="color: #66cc66; font-weight: 600;">Sandboxable:</span> yes               │
│ <span style="color: #66cc66; font-weight: 600;">Checkpointable:</span> yes            │
│ <span style="color: #5599ff; font-weight: 600;">Sandbox Strategy:</span> git_worktree │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource registered (412 child resources discovered)

<span style="opacity: 0.7;"># Register the remaining 3 resources (condensed output)</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add git-checkout local/worker-repo <span style="color: cyan;">--path</span> /repos/worker <span style="color: cyan;">--branch</span> main
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource registered — <span style="color: cyan; font-weight: 600;">Name:</span> local/worker-repo (278 children)

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add git-checkout local/frontend-repo <span style="color: cyan;">--path</span> /repos/frontend <span style="color: cyan;">--branch</span> main
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource registered — <span style="color: cyan; font-weight: 600;">Name:</span> local/frontend-repo (524 children)

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> resource add git-checkout local/protos-repo <span style="color: cyan;">--path</span> /repos/protos <span style="color: cyan;">--branch</span> main
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Resource registered — <span style="color: cyan; font-weight: 600;">Name:</span> local/protos-repo (96 children)
</code></pre></div>

<div class="highlight"><pre><code><span style="opacity: 0.7;"># Create the Backend API project (full output shown)</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project create <span style="color: yellow;">-d</span> <span style="color: #66cc66;">"Backend API"</span> \
    <span style="color: cyan;">--resource</span> local/api-repo \
    <span style="color: cyan;">--resource</span> local/protos-repo \
    <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">"All new endpoints must have OpenAPI docs"</span> \
    <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">"All database changes require migration scripts"</span> \
    local/api

╭─ Project Created ─────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/api                           │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Backend API                  │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> local                               │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 14:01                 │
╰───────────────────────────────────────────╯

╭─ Linked Resources ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Resource</span>           <span style="color: cyan; font-weight: 600;">Type</span>          <span style="color: cyan; font-weight: 600;">Read-Only</span>               │
│ <span style="opacity: 0.7;">─────────────────  ──────────────  ─────────</span>             │
│ local/api-repo     git-checkout    no                    │
│ local/protos-repo  git-checkout    no                    │
╰──────────────────────────────────────────────────────────╯

╭─ Invariants ─────────────────────────────────────────────╮
│ 1. All new endpoints must have OpenAPI docs              │
│ 2. All database changes require migration scripts        │
╰──────────────────────────────────────────────────────────╯

╭─ Defaults ──────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Sandbox:</span> git_worktree                   │
│ <span style="color: #66cc66; font-weight: 600;">Validations:</span> 0                          │
│ <span style="color: yellow; font-weight: 600;">Context Filters:</span> none                   │
│ <span style="color: magenta; font-weight: 600;">Automation Profile:</span> (inherits global)   │
╰─────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project created

<span style="opacity: 0.7;"># Create the remaining 3 projects (condensed output)</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project create <span style="color: yellow;">-d</span> <span style="color: #66cc66;">"Background worker service"</span> \
    <span style="color: cyan;">--resource</span> local/worker-repo \
    <span style="color: cyan;">--resource</span> local/protos-repo \
    <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">"Workers must be idempotent"</span> \
    <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">"All queue consumers must implement dead-letter handling"</span> \
    local/worker
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project created — <span style="color: cyan; font-weight: 600;">Name:</span> local/worker

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project create <span style="color: yellow;">-d</span> <span style="color: #66cc66;">"Frontend dashboard"</span> \
    <span style="color: cyan;">--resource</span> local/frontend-repo \
    <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">"All components must have Storybook stories"</span> \
    <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">"Accessibility: WCAG 2.1 AA compliance required"</span> \
    local/frontend
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project created — <span style="color: cyan; font-weight: 600;">Name:</span> local/frontend

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> project create <span style="color: yellow;">-d</span> <span style="color: #66cc66;">"Shared protobuf definitions"</span> \
    <span style="color: cyan;">--resource</span> local/protos-repo \
    <span style="color: cyan;">--invariant</span> <span style="color: #66cc66;">"Proto changes must be backward-compatible (no field renumbering)"</span> \
    local/protos
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Project created — <span style="color: cyan; font-weight: 600;">Name:</span> local/protos
</code></pre></div>

<div class="highlight"><pre><code><span style="opacity: 0.7;"># Register validations — first one with full output</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation add <span style="color: cyan;">--config</span> validations/api-tests.yaml <span style="color: cyan;">--required</span> local/api-tests

╭─ Validation Registered ─────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/api-tests                                │
│ <span style="color: #5599ff; font-weight: 600;">Command:</span> pytest tests/ && mypy src/                 │
│ <span style="color: #66cc66; font-weight: 600;">Mode:</span> required                                      │
│ <span style="color: yellow; font-weight: 600;">Timeout:</span> 300s                                       │
╰─────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation registered

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation add <span style="color: cyan;">--config</span> validations/worker-tests.yaml <span style="color: cyan;">--required</span> local/worker-tests
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation registered — <span style="color: cyan; font-weight: 600;">Name:</span> local/worker-tests

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation add <span style="color: cyan;">--config</span> validations/frontend-tests.yaml <span style="color: cyan;">--required</span> local/frontend-tests
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation registered — <span style="color: cyan; font-weight: 600;">Name:</span> local/frontend-tests

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation add <span style="color: cyan;">--config</span> validations/proto-lint.yaml <span style="color: cyan;">--required</span> local/proto-lint
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation registered — <span style="color: cyan; font-weight: 600;">Name:</span> local/proto-lint

<span style="opacity: 0.7;"># Attach validations to their respective projects</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> local/api local/api-tests
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached to project local/api

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> local/worker local/worker-tests
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached to project local/worker

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> local/frontend local/frontend-tests
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached to project local/frontend

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> validation attach <span style="color: cyan;">--project</span> local/protos local/proto-lint
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Validation attached to project local/protos
</code></pre></div>

<div class="highlight"><pre><code><span style="opacity: 0.7;"># Global invariant for this effort</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> invariant add <span style="color: cyan;">--global</span> \
    <span style="color: #66cc66;">"All inter-service communication must use the shared proto definitions"</span>

╭─ Invariant Added ──────────────────────────────────────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Invariant:</span> All inter-service communication must use the shared proto defs.     │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> global                                                                  │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> inv_01HXRI1A                                                               │
╰────────────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Invariant added
</code></pre></div>

#### Step 2: Create the Feature Action

Create `actions/build-notification-system.yaml`:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">name</span>: local/build-notification-system
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Build a complete notification system spanning multiple services"</span>
<span style="color: cyan; font-weight: 600;">long_description</span>: |
  Implement a full notification system with:
  - Backend API: notification preferences, send endpoints, delivery tracking
  - Message Queue: notification event schemas, routing rules
  - Worker: email/SMS/push delivery workers with retry logic
  - Frontend: notification center UI, preference settings, real-time updates
  
  The system must be designed for reliability (at-least-once delivery),
  scalability (async processing via queue), and user control (per-channel
  preferences with quiet hours).
<span style="color: cyan; font-weight: 600;">definition_of_done</span>: |
  - Proto definitions for notification events are complete and compatible
  - API endpoints: CRUD for preferences, send notification, list history
  - Worker processes: email, SMS, push delivery with retry and dead-letter
  - Frontend: notification center, preference settings, real-time badge
  - Integration tests verify end-to-end notification flow
  - All per-project validations pass
  - API docs updated, Storybook stories added
<span style="color: cyan; font-weight: 600;">strategy_actor</span>: local/refactoring-strategist
<span style="color: cyan; font-weight: 600;">execution_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">estimation_actor</span>: anthropic/claude-3.5-sonnet
<span style="color: cyan; font-weight: 600;">invariant_actor</span>: local/invariant-resolver
<span style="color: cyan; font-weight: 600;">automation_profile</span>: cautious
<span style="color: cyan; font-weight: 600;">reusable</span>: <span style="color: yellow;">false</span>
<span style="color: cyan; font-weight: 600;">state</span>: <span style="color: yellow;">available</span>
<span style="color: cyan; font-weight: 600;">args</span>:
  - <span style="color: cyan; font-weight: 600;">name</span>: notification_channels
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">true</span>
    <span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Comma-separated: email, sms, push, in-app"</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: priority_levels
    <span style="color: cyan; font-weight: 600;">type</span>: string
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: #66cc66;">"critical,high,normal,low"</span>
  - <span style="color: cyan; font-weight: 600;">name</span>: max_retry_attempts
    <span style="color: cyan; font-weight: 600;">type</span>: integer
    <span style="color: cyan; font-weight: 600;">required</span>: <span style="color: yellow;">false</span>
    <span style="color: cyan; font-weight: 600;">default</span>: <span style="color: yellow;">5</span>
<span style="color: cyan; font-weight: 600;">invariants</span>:
  - <span style="color: #66cc66;">"Proto definitions must be implemented and reviewed before any service code"</span>
  - <span style="color: #66cc66;">"Each service must be deployable independently after its changes"</span>
  - <span style="color: #66cc66;">"Frontend must gracefully degrade if the notification API is unavailable"</span>
  - <span style="color: #66cc66;">"All notification delivery must be async — API endpoints return immediately"</span>
</code></pre></div>

<div class="highlight"><pre><code><span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action create <span style="color: cyan;">--config</span> ./actions/build-notification-system.yaml

╭─ Action Created ──────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/build-notification-system                             │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> 01HXRB1A2B3C4D5E6F7G8H9J0                                     │
│ <span style="color: yellow; font-weight: 600;">State:</span> available                                                  │
│ <span style="color: magenta; font-weight: 600;">Strategy Actor:</span> local/refactoring-strategist                      │
│ <span style="color: magenta; font-weight: 600;">Execution Actor:</span> anthropic/claude-3.5-sonnet                      │
│ <span style="color: magenta; font-weight: 600;">Estimation Actor:</span> anthropic/claude-3.5-sonnet                     │
│ <span style="color: magenta; font-weight: 600;">Invariant Actor:</span> local/invariant-resolver                         │
│ <span style="color: #66cc66; font-weight: 600;">Reusable:</span> no                                                      │
│ <span style="color: #5599ff; font-weight: 600;">Read Only:</span> no                                                     │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 14:02                                         │
╰───────────────────────────────────────────────────────────────────╯

╭─ Definition of Done ───────────────────────────────────────────────────╮
│ - Proto definitions for notification events are complete/compatible    │
│ - API endpoints: CRUD for preferences, send notification, list hist.   │
│ - Worker: email, SMS, push delivery with retry and dead-letter         │
│ - Frontend: notification center, preference settings, real-time badge  │
│ - Integration tests verify end-to-end notification flow                │
│ - All per-project validations pass                                     │
│ - API docs updated, Storybook stories added                            │
╰────────────────────────────────────────────────────────────────────────╯

╭─ Arguments ──────────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>                    <span style="color: cyan; font-weight: 600;">Type</span>      <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>                              │
│ <span style="opacity: 0.7;">──────────────────────  ────────  ────────  ──────────────────────────────────</span>       │
│ notification_channels   string    yes       Comma-separated: email, sms, push        │
│ priority_levels         string    no        (default: critical,high,normal,low)      │
│ max_retry_attempts      integer   no        (default: 5)                             │
╰──────────────────────────────────────────────────────────────────────────────────────╯

╭─ Automation ──────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> cautious                     │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> action config                 │
╰───────────────────────────────────────╯

╭─ Action Invariants ───────────────────────────────────────────────────────────────────╮
│ 1. Proto definitions must be implemented and reviewed before any service code         │
│ 2. Each service must be deployable independently after its changes                    │
│ 3. Frontend must gracefully degrade if the notification API is unavailable            │
│ 4. All notification delivery must be async — API endpoints return immediately         │
╰───────────────────────────────────────────────────────────────────────────────────────╯

╭─ Usage ────────────────────────────────────────────────────────────────────────────╮
│ agents plan use local/build-notification-system local/protos                       │
│   <span style="color: cyan;">--arg</span> notification_channels=&quot;email,push,in-app&quot;                                  │
╰────────────────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Action created
</code></pre></div>

#### Step 3: Initiate the Plan

<div class="highlight"><pre><code><span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan use \
    <span style="color: cyan;">--arg</span> notification_channels=<span style="color: #66cc66;">"email,push,in-app"</span> \
    <span style="color: cyan;">--arg</span> priority_levels=<span style="color: #66cc66;">"critical,high,normal,low"</span> \
    <span style="color: cyan;">--arg</span> max_retry_attempts=5 \
    local/build-notification-system \
    local/protos local/api local/worker local/frontend

╭─ Plan Created ────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXRF1A2B3C4D5E6F7G8H9J0                               │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/build-notification-system                       │
│ <span style="color: #5599ff; font-weight: 600;">Projects:</span> local/protos, local/api,                            │
│           local/worker, local/frontend                        │
│ <span style="color: #66cc66; font-weight: 600;">Automation:</span> cautious                                          │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                                    │
╰───────────────────────────────────────────────────────────────╯

╭─ Inputs ───────────────────────────────────────────────────────────╮
│ - notification_channels=&quot;email,push,in-app&quot;                        │
│ - priority_levels=&quot;critical,high,normal,low&quot;                       │
│ - max_retry_attempts=5                                             │
│ - automation_profile=cautious                                      │
╰────────────────────────────────────────────────────────────────────╯

╭─ Actors ────────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Strategy:</span> local/refactoring-strategist              │
│ <span style="color: magenta; font-weight: 600;">Execution:</span> anthropic/claude-3.5-sonnet              │
│ <span style="color: magenta; font-weight: 600;">Estimation:</span> anthropic/claude-3.5-sonnet             │
│ <span style="color: magenta; font-weight: 600;">Invariant:</span> local/invariant-resolver                 │
╰─────────────────────────────────────────────────────╯

╭─ Automation ──────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> cautious                         │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> action config                     │
│ <span style="color: #5599ff; font-weight: 600;">Read-Only:</span> no                             │
╰───────────────────────────────────────────╯

╭─ Context ──────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Resources:</span> 4 (git-checkout)        │
│ <span style="color: #5599ff; font-weight: 600;">Indexed Files:</span> 1,310               │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> strategize                   │
│ <span style="color: #5599ff; font-weight: 600;">Hot Token Budget:</span> 32,000           │
╰────────────────────────────────────╯

╭─ Next Steps ──────────────────────────────────────────────╮
│ - agents plan tree 01HXRF1A2B3C4D5E6F7G8H9J0              │
│ - agents plan status 01HXRF1A2B3C4D5E6F7G8H9J0            │
│ - agents plan execute 01HXRF1A2B3C4D5E6F7G8H9J0           │
╰───────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan created
</code></pre></div>

The plan (`01HXRF1A2B3C4D5E6F7G8H9J0`) enters Strategize. The strategy actor:

1. Reconciles invariants from all four projects plus global plus action-level
2. Decomposes the work into ordered child plans:
   - **Phase 1**: Proto definitions (local/protos)
   - **Phase 2** (parallel): API endpoints (local/api) + Worker skeleton (local/worker)
   - **Phase 3** (parallel): Worker delivery logic (local/worker) + Frontend notification center (local/frontend)
   - **Phase 4**: Integration wiring and end-to-end tests

Because the `cautious` profile uses confidence thresholds, the system pauses on complex architectural decisions (e.g., "Should notifications use a fan-out or point-to-point queue topology?") but proceeds automatically on routine decisions.

#### Step 4: Monitor and Guide the Hierarchical Execution

<div class="highlight"><pre><code><span style="opacity: 0.7;"># View the full plan tree with child plans</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan tree 01HXRF1A2B3C4D5E6F7G8H9J0

╭─ Decision Tree ─────────────────────────────────────────────────────────────────────────────────────────╮
│ Plan: 01HXRF1A2B3C4D5E6F7G8H9J0                                                                         │
│ ├─ <span style="color: white;">[prompt_definition]</span> <span style="color: #66cc66;">&quot;Build notification system across 4 projects&quot;</span>                                    │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">&quot;All inter-service communication must use shared proto defs&quot;</span>                    │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">&quot;Proto definitions must be implemented before any service code&quot;</span>                 │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">&quot;Each service must be deployable independently after its changes&quot;</span>               │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">&quot;Frontend must gracefully degrade if notification API unavailable&quot;</span>              │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">&quot;All notification delivery must be async&quot;</span>                                       │
│ ├─ <span style="color: #5599ff;">[strategy_choice]</span> <span style="color: #66cc66;">&quot;Phase 1: proto definitions first (blocking)&quot;</span> <span style="opacity: 0.7;">(conf: 0.95)</span>                         │
│ ├─ <span style="color: #5599ff;">[strategy_choice]</span> <span style="color: #66cc66;">&quot;Phase 2: API + worker skeleton in parallel&quot;</span> <span style="opacity: 0.7;">(conf: 0.88)</span>                          │
│ ├─ <span style="color: #5599ff;">[strategy_choice]</span> <span style="color: #66cc66;">&quot;Phase 3: worker delivery + frontend UI in parallel&quot;</span> <span style="opacity: 0.7;">(conf: 0.84)</span>                  │
│ ├─ <span style="color: #5599ff;">[strategy_choice]</span> <span style="color: #66cc66;">&quot;Phase 4: integration wiring and e2e tests&quot;</span> <span style="opacity: 0.7;">(conf: 0.90)</span>                           │
│ ├─ <span style="color: yellow;">[strategy_choice]</span> <span style="color: #66cc66;">&quot;Queue topology: fan-out vs point-to-point?&quot;</span> <span style="opacity: 0.7;">(conf: 0.55 — <span style="color: yellow; font-weight: 600;">PAUSED</span>)</span>                 │
│ ├─ <span style="color: cyan;">[child_plan]</span> 01HXRC1A2B3C4D5E6F7G8H9J0 (Phase 1: proto defs) <span style="color: #66cc66; font-weight: 600;">[execute/complete]</span>                      │
│ ├─ <span style="color: cyan;">[child_plan]</span> 01HXRC2B3C4D5E6F7G8H9J0K1 (Phase 2a: API endpoints) <span style="color: cyan; font-weight: 600;">[execute/processing]</span>                │
│ ├─ <span style="color: cyan;">[child_plan]</span> 01HXRC3C4D5E6F7G8H9J0K1L2 (Phase 2b: worker skeleton) <span style="color: cyan; font-weight: 600;">[execute/processing]</span>              │
│ ├─ <span style="color: cyan;">[child_plan]</span> 01HXRC4D5E6F7G8H9J0K1L2M3 (Phase 3a: worker delivery) <span style="opacity: 0.5;">[strategize/pending]</span>              │
│ ├─ <span style="color: cyan;">[child_plan]</span> 01HXRC5E6F7G8H9J0K1L2M3N4 (Phase 3b: frontend UI) <span style="opacity: 0.5;">[strategize/pending]</span>                  │
│ └─ <span style="color: cyan;">[child_plan]</span> 01HXRC6F7G8H9J0K1L2M3N4P5 (Phase 4: integration) <span style="opacity: 0.5;">[strategize/pending]</span>                   │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Tree Summary ──────────────────╮
│ <span style="color: yellow; font-weight: 600;">Nodes:</span> 17                       │
│ <span style="color: #5599ff; font-weight: 600;">Depth:</span> 2                        │
│ <span style="color: #66cc66; font-weight: 600;">Child Plans:</span> 6 (1 done, 2 exec) │
│ <span style="color: magenta; font-weight: 600;">Invariants:</span> 5                   │
│ <span style="color: #5599ff; font-weight: 600;">Superseded:</span> 0 (hidden)          │
╰─────────────────────────────────╯

╭─ Decision IDs (for correction) ──────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Root:</span> 01HXRD1A2B3C4D5E6F7G8H9J                           │
│ <span style="color: magenta; font-weight: 600;">Invariant 1:</span> 01HXRD1B3C4D5E6F7G8H9J0                     │
│ <span style="color: magenta; font-weight: 600;">Invariant 2:</span> 01HXRD1C4D5E6F7G8H9J0K1                     │
│ <span style="color: magenta; font-weight: 600;">Invariant 3:</span> 01HXRD1D5E6F7G8H9J0K1L2                     │
│ <span style="color: magenta; font-weight: 600;">Invariant 4:</span> 01HXRD1E6F7G8H9J0K1L2M3                     │
│ <span style="color: magenta; font-weight: 600;">Invariant 5:</span> 01HXRD1F7G8H9J0K1L2M3N4                     │
│ <span style="color: #5599ff; font-weight: 600;">Strategy 1:</span> 01HXRD2A3B4C5D6E7F8G9H0                      │
│ <span style="color: #5599ff; font-weight: 600;">Strategy 2:</span> 01HXRD2B4C5D6E7F8G9H0J1                      │
│ <span style="color: #5599ff; font-weight: 600;">Strategy 3:</span> 01HXRD2C5D6E7F8G9H0J1K2                      │
│ <span style="color: #5599ff; font-weight: 600;">Strategy 4:</span> 01HXRD2D6E7F8G9H0J1K2L3                      │
│ <span style="color: yellow; font-weight: 600;">Paused:</span> 01HXRD2E7F8G9H0J1K2L3M4                          │
╰──────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Decision tree rendered
</code></pre></div>

<div class="highlight"><pre><code><span style="opacity: 0.7;"># The system paused at a decision about queue topology (confidence 0.55 &lt; threshold 0.7)</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan explain 01HXRD2E7F8G9H0J1K2L3M4

╭─ Decision ──────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXRD2E7F8G9H0J1K2L3M4                                 │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> strategy_choice                                       │
│ <span style="color: magenta; font-weight: 600;">Question:</span> Queue topology for notification delivery          │
│ <span style="color: #66cc66; font-weight: 600;">Chosen:</span> (none — paused for user input)                      │
│ <span style="color: yellow; font-weight: 600;">Confidence:</span> 0.55                                            │
│ <span style="color: #5599ff; font-weight: 600;">Plan:</span> 01HXRF1A2B3C4D5E6F7G8H9J0                             │
│ <span style="color: #5599ff; font-weight: 600;">Sequence:</span> 5 of 5 strategy choices                           │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 14:04                                   │
╰─────────────────────────────────────────────────────────────╯

╭─ Alternatives Considered ──────────────────────────────────────────────────────╮
│ 1. Fan-out exchange: one exchange per event type, separate queues per channel  │
│ 2. Point-to-point: single queue, worker routes by notification type            │
│ 3. Topic-based: single exchange with routing keys for channel + priority       │
╰────────────────────────────────────────────────────────────────────────────────╯

╭─ Impact ─────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Downstream Decisions:</span> 4          │
│ <span style="color: #5599ff; font-weight: 600;">Downstream Child Plans:</span> 3        │
│ <span style="color: #66cc66; font-weight: 600;">Artifacts Produced:</span> 0 (pending)  │
│ <span style="color: yellow; font-weight: 600;">Correction Impact:</span> high          │
╰──────────────────────────────────╯

╭─ Rationale ──────────────────────────────────────────────────────────╮
│ The confidence is low because both fan-out and topic-based patterns  │
│ are viable. Fan-out gives independent scaling per channel but adds   │
│ more exchanges. Topic-based is simpler but couples routing logic.    │
│ The existing codebase uses RabbitMQ but has no precedent for this    │
│ pattern — no strong signal either way.                               │
╰──────────────────────────────────────────────────────────────────────╯

╭─ Correction ──────────────────────────────────────────────────╮
│ agents plan correct 01HXRD2E7F8G9H0J1K2L3M4                   │
│   <span style="color: cyan;">--mode</span> revert <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">"Use fan-out exchange pattern..."</span>  │
╰───────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Decision explained
</code></pre></div>

<div class="highlight"><pre><code><span style="opacity: 0.7;"># Provide guidance to resolve the paused decision</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan prompt 01HXRF1A2B3C4D5E6F7G8H9J0 \
    <span style="color: #66cc66;">"Use a fan-out exchange pattern: one exchange per notification event type, \
     with separate queues per delivery channel. This matches our existing \
     RabbitMQ setup in the order service."</span>

╭─ Guidance Added ────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXRF1A2B3C4D5E6F7G8H9J0                                         │
│ <span style="color: magenta; font-weight: 600;">Guidance:</span> Use a fan-out exchange pattern: one exchange per              │
│           notification event type, with separate queues per delivery    │
│           channel. This matches our existing RabbitMQ setup.            │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> next execution step                                              │
│ <span style="color: #5599ff; font-weight: 600;">Phase:</span> strategize                                                       │
│ <span style="color: #5599ff; font-weight: 600;">State:</span> awaiting_input → processing                                      │
╰─────────────────────────────────────────────────────────────────────────╯

╭─ Decision Created ────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> user_intervention                   │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> 01HXRD3A2B3C4D5E6F7G8H9J              │
│ <span style="color: #5599ff; font-weight: 600;">Parent:</span> 01HXRD2E7F8G9H0J1K2L3M4           │
╰───────────────────────────────────────────╯

╭─ Queue ────╮
│ <span style="color: yellow; font-weight: 600;">Pending:</span> 1 │
│ <span style="color: #66cc66; font-weight: 600;">Applied:</span> 0 │
╰────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Guidance queued
</code></pre></div>

#### Step 5: Handle a Failure in One Child Plan

The worker delivery child plan fails validation because the SMS provider SDK is not installed. Rather than failing the entire tree:

<div class="highlight"><pre><code><span style="opacity: 0.7;"># Check which child plan failed</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan status 01HXRC4D5E6F7G8H9J0K1L2M3

╭─ Plan Status ──────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXRC4D5E6F7G8H9J0K1L2M3                            │
│ <span style="color: #ff6666; font-weight: 600;">Phase:</span> execute                                             │
│ <span style="color: #ff6666; font-weight: 600;">State:</span> errored                                             │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/build-notification-system (child plan)       │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/worker                                      │
│ <span style="color: #5599ff; font-weight: 600;">Automation:</span> cautious                                       │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                                 │
│ <span style="color: #5599ff; font-weight: 600;">Parent:</span> 01HXRF1A2B3C4D5E6F7G8H9J0                          │
╰────────────────────────────────────────────────────────────╯

╭─ Progress ───────────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Strategize         │
│ <span style="color: #ff6666; font-weight: 600;">✗</span> Execute            │
│ <span style="opacity: 0.5;">○</span> Apply (skipped)    │
╰──────────────────────╯

╭─ Error Detail ──────────────────────────────────────────────────────────╮
│ <span style="color: #ff6666; font-weight: 600;">Error:</span> Validation failed: ModuleNotFoundError: No module named          │
│         'twilio' — SMS provider SDK not installed                       │
│ <span style="color: #5599ff; font-weight: 600;">Tool:</span> execute_command (pip install check)                               │
│ <span style="color: #5599ff; font-weight: 600;">Step:</span> 3 of 8                                                            │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoint:</span> cp_01HXRC4D (sandbox state preserved)                       │
│ <span style="opacity: 0.7;">Recoverable: yes — use <span style="color: #66cc66;">"agents plan prompt"</span> to provide guidance</span>         │
╰─────────────────────────────────────────────────────────────────────────╯

╭─ Cost ───────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Tokens Used:</span> 14,280  │
│ <span style="color: yellow;">Cost So Far:</span> $0.048  │
╰──────────────────────╯

<span style="color: #ff6666; font-weight: 600;">✗ ERROR</span> Plan errored — use `agents plan prompt` to resume or `agents plan cancel` to abort
</code></pre></div>

<div class="highlight"><pre><code><span style="opacity: 0.7;"># Correct the strategy — tell it to skip SMS for now</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan correct 01HXRD4A2B3C4D5E6F7G8H9J \
    <span style="color: cyan;">--mode</span> append \
    <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">"Skip SMS delivery for the initial implementation. \
                Add a placeholder worker that logs a warning. \
                SMS support will be added in a follow-up action."</span>

╭─ Correction ─────────────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Mode:</span> append                                                 │
│ <span style="color: #66cc66; font-weight: 600;">Impact:</span> adds to existing subtree, no rollback                │
│ <span style="color: #66cc66; font-weight: 600;">New Decision:</span> 01HXRD5A2B3C4D5E6F7G8H9J                       │
│ <span style="color: #5599ff; font-weight: 600;">Appended After:</span> 01HXRD4A2B3C4D5E6F7G8H9J                     │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 2                                                   │
╰──────────────────────────────────────────────────────────────╯

╭─ Append Detail ────────────────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Original decision preserved:</span> yes                                   │
│ <span style="color: #5599ff; font-weight: 600;">Existing artifacts kept:</span> yes                                       │
│ <span style="color: #66cc66; font-weight: 600;">Additional work:</span> re-execute with SMS placeholder                   │
│ <span style="opacity: 0.7;">The worker delivery plan will be re-executed. Email and push</span>       │
│ <span style="opacity: 0.7;">workers are kept; SMS worker replaced with a logging stub.</span>         │
│ <span style="opacity: 0.7;">Other child plans (API, frontend, integration) are unaffected.</span>     │
╰────────────────────────────────────────────────────────────────────╯

╭─ Queued ──────────────╮
│ <span style="color: yellow;">Re-execute:</span> 1 child   │
│ <span style="color: #66cc66; font-weight: 600;">ETA:</span> 3m               │
╰───────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Append correction queued
</code></pre></div>

#### Step 6: Apply in Phases

<div class="highlight"><pre><code><span style="opacity: 0.7;"># Apply proto definitions first (other plans depend on this)</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXRC1A2B3C4D5E6F7G8H9J0

╭─ Apply Summary ──────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXRC1A2B3C4D5E6F7G8H9J0                          │
│ <span style="color: #5599ff; font-weight: 600;">Artifacts:</span> 3 files updated                               │
│ <span style="color: yellow; font-weight: 600;">Changes:</span> 84 insertions, 0 deletions                      │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/protos                                    │
│ <span style="color: #66cc66; font-weight: 600;">Applied At:</span> 2026-02-11 14:18                             │
╰──────────────────────────────────────────────────────────╯

╭─ Validation ──────────────────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">buf lint:</span> passed                                      │
│ <span style="color: #66cc66; font-weight: 600;">buf breaking:</span> passed (no breaking changes)            │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 2.1s                                        │
╰───────────────────────────────────────────────────────╯

╭─ Sandbox Cleanup ─────────╮
│ <span style="color: #66cc66; font-weight: 600;">Worktree:</span> removed         │
│ <span style="color: #66cc66; font-weight: 600;">Branch:</span> merged to main    │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoint:</span> archived      │
╰───────────────────────────╯

╭─ Plan Lifecycle ─────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Phase:</span> applied                           │
│ <span style="color: #66cc66; font-weight: 600;">State:</span> complete                          │
│ <span style="color: #5599ff; font-weight: 600;">Total Duration:</span> 00:02:41                 │
│ <span style="color: yellow; font-weight: 600;">Total Cost:</span> $0.024                       │
│ <span style="color: #5599ff; font-weight: 600;">Decisions Made:</span> 4                        │
│ <span style="color: #5599ff; font-weight: 600;">Child Plans:</span> 0                           │
╰──────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied

<span style="opacity: 0.7;"># Apply API and worker in parallel</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXRC2B3C4D5E6F7G8H9J0K1
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied — <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXRC2B...J0K1 <span style="color: #5599ff; font-weight: 600;">Project:</span> local/api (8 files, +246 -12)

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXRC3C4D5E6F7G8H9J0K1L2
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied — <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXRC3C...K1L2 <span style="color: #5599ff; font-weight: 600;">Project:</span> local/worker (5 files, +178 -4)

<span style="opacity: 0.7;"># Apply worker delivery and frontend</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXRC4D5E6F7G8H9J0K1L2M3
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied — <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXRC4D...L2M3 <span style="color: #5599ff; font-weight: 600;">Project:</span> local/worker (6 files, +312 -18)

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXRC5E6F7G8H9J0K1L2M3N4
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied — <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXRC5E...M3N4 <span style="color: #5599ff; font-weight: 600;">Project:</span> local/frontend (12 files, +487 -22)

<span style="opacity: 0.7;"># Apply integration tests</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXRC6F7G8H9J0K1L2M3N4P5
<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied — <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXRC6F...N4P5 <span style="color: #5599ff; font-weight: 600;">Projects:</span> local/api, local/worker (4 files, +156 -0)

<span style="opacity: 0.7;"># Apply the parent plan (finalizes everything)</span>

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXRF1A2B3C4D5E6F7G8H9J0

╭─ Apply Summary ───────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXRF1A2B3C4D5E6F7G8H9J0                           │
│ <span style="color: #5599ff; font-weight: 600;">Artifacts:</span> 38 files across 4 projects                     │
│ <span style="color: yellow; font-weight: 600;">Changes:</span> 1,463 insertions, 56 deletions                   │
│ <span style="color: #5599ff; font-weight: 600;">Projects:</span> local/protos, local/api,                        │
│           local/worker, local/frontend                    │
│ <span style="color: #66cc66; font-weight: 600;">Applied At:</span> 2026-02-11 14:32                              │
╰───────────────────────────────────────────────────────────╯

╭─ Validation ─────────────────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">local/protos:</span> passed (buf lint + breaking)           │
│ <span style="color: #66cc66; font-weight: 600;">local/api:</span> passed (pytest 48/48, mypy 0 err)         │
│ <span style="color: #66cc66; font-weight: 600;">local/worker:</span> passed (pytest 31/31, mypy 0)          │
│ <span style="color: #66cc66; font-weight: 600;">local/frontend:</span> passed (tests + lint)                │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 34.2s                                      │
╰──────────────────────────────────────────────────────╯

╭─ Sandbox Cleanup ─────────╮
│ <span style="color: #66cc66; font-weight: 600;">Worktrees:</span> 4 removed      │
│ <span style="color: #66cc66; font-weight: 600;">Branches:</span> merged to main  │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoints:</span> archived     │
╰───────────────────────────╯

╭─ Plan Lifecycle ────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Phase:</span> applied                          │
│ <span style="color: #66cc66; font-weight: 600;">State:</span> complete                         │
│ <span style="color: #5599ff; font-weight: 600;">Total Duration:</span> 00:30:14                │
│ <span style="color: yellow; font-weight: 600;">Total Cost:</span> $0.847                      │
│ <span style="color: #5599ff; font-weight: 600;">Decisions Made:</span> 42                      │
│ <span style="color: #5599ff; font-weight: 600;">Child Plans:</span> 6 (all completed)          │
│ <span style="color: #5599ff; font-weight: 600;">Corrections:</span> 1                          │
╰─────────────────────────────────────────╯

╭─ Next Steps ──────╮
│ - Review git diff │
│ - Commit changes  │
╰───────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied
</code></pre></div>

---

### Example 13: Custom Automation Profile with Semantic Escalation

**Scenario**: A team wants fine-grained automation control. They trust the system with routine planning but want human oversight on any decision involving database schema changes or security-sensitive code, regardless of confidence.

**Complexity**: Intermediate. Custom profile, invariant-driven escalation.

#### Step 1: Create a Custom Profile

Create `profiles/db-cautious.yaml`:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">name</span>: local/db-cautious
<span style="color: cyan; font-weight: 600;">description</span>: <span style="color: #66cc66;">"Auto for most tasks, manual for database and security decisions"</span>

<span style="color: cyan; font-weight: 600;">auto_strategize</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_execute</span>: <span style="color: yellow;">0.3</span>
<span style="color: cyan; font-weight: 600;">auto_apply</span>: <span style="color: yellow;">1.0</span>
<span style="color: cyan; font-weight: 600;">auto_decisions_strategize</span>: <span style="color: yellow;">0.4</span>
<span style="color: cyan; font-weight: 600;">auto_decisions_execute</span>: <span style="color: yellow;">0.6</span>
<span style="color: cyan; font-weight: 600;">auto_validation_fix</span>: <span style="color: yellow;">0.5</span>
<span style="color: cyan; font-weight: 600;">auto_strategy_revision</span>: <span style="color: yellow;">0.8</span>
<span style="color: cyan; font-weight: 600;">auto_child_plans</span>: <span style="color: yellow;">0.3</span>
<span style="color: cyan; font-weight: 600;">auto_retry_transient</span>: <span style="color: yellow;">0.0</span>
<span style="color: cyan; font-weight: 600;">auto_checkpoint_restore</span>: <span style="color: yellow;">0.0</span>

<span style="color: cyan; font-weight: 600;">require_sandbox</span>: <span style="color: yellow;">true</span>
<span style="color: cyan; font-weight: 600;">require_checkpoints</span>: <span style="color: yellow;">true</span>
<span style="color: cyan; font-weight: 600;">allow_unsafe_tools</span>: <span style="color: yellow;">false</span>
</code></pre></div>

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> automation-profile add <span style="color: cyan;">--config</span> ./profiles/db-cautious.yaml

╭─ Profile Registered ──────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> local/db-cautious                                                   │
│ <span style="color: #5599ff; font-weight: 600;">Description:</span> Auto for most tasks, manual for database and security        │
│              decisions                                                    │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 09:00                                                 │
╰───────────────────────────────────────────────────────────────────────────╯

╭─ Confidence Thresholds ────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">auto_strategize:</span> 0.0                   │
│ <span style="color: #66cc66; font-weight: 600;">auto_execute:</span> 0.3                      │
│ <span style="color: #ff6666; font-weight: 600;">auto_apply:</span> 1.0                        │
│ <span style="color: #66cc66; font-weight: 600;">auto_decisions_strategize:</span> 0.4         │
│ <span style="color: #66cc66; font-weight: 600;">auto_decisions_execute:</span> 0.6            │
│ <span style="color: #66cc66; font-weight: 600;">auto_validation_fix:</span> 0.5               │
│ <span style="color: #66cc66; font-weight: 600;">auto_strategy_revision:</span> 0.8            │
│ <span style="color: #66cc66; font-weight: 600;">auto_child_plans:</span> 0.3                  │
│ <span style="color: #66cc66; font-weight: 600;">auto_retry_transient:</span> 0.0              │
│ <span style="color: #66cc66; font-weight: 600;">auto_checkpoint_restore:</span> 0.0           │
│ <span style="color: #66cc66; font-weight: 600;">require_sandbox:</span> true                  │
│ <span style="color: #66cc66; font-weight: 600;">require_checkpoints:</span> true              │
│ <span style="color: #ff6666; font-weight: 600;">allow_unsafe_tools:</span> false              │
╰────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Profile registered
</code></pre></div>

#### Step 2: Apply to a Project with Database Resources

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set core.automation-profile local/db-cautious <span style="color: cyan;">--project</span> local/api-service

╭─ Config Updated ─────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Key:</span> core.automation-profile                     │
│ <span style="color: #66cc66; font-weight: 600;">Value:</span> local/db-cautious                         │
│ <span style="color: yellow; font-weight: 600;">Previous:</span> review                                 │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> config                                   │
│ <span style="color: yellow; font-weight: 600;">Scope:</span> project (local/api-service)               │
╰──────────────────────────────────────────────────╯

╭─ Effective ────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Sessions:</span> new sessions on local/api-service    │
│ <span style="color: yellow; font-weight: 600;">Plans:</span> future plans (unless overridden)        │
│ <span style="color: #5599ff; font-weight: 600;">Existing:</span> unchanged                            │
╰────────────────────────────────────────────────╯

╭─ Saved To ──────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">File:</span> ~/.cleveragents/config.toml   │
│ <span style="color: #5599ff; font-weight: 600;">Line:</span> 24                            │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Config updated
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Add invariants that force escalation on sensitive operations</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> invariant add <span style="color: cyan;">--project</span> local/api-service \
    <span style="color: #66cc66;">"Any change to database migration files requires explicit human approval"</span>

╭─ Invariant Added ───────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service                                                      │
│ <span style="color: #66cc66; font-weight: 600;">Invariant:</span> Any change to database migration files requires explicit human       │
│            approval                                                             │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> project                                                                  │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> inv_01HXRBA1A                                                               │
╰─────────────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Invariant added

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> invariant add <span style="color: cyan;">--project</span> local/api-service \
    <span style="color: #66cc66;">"Changes to authentication or authorization logic require security review"</span>

╭─ Invariant Added ───────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service                                                      │
│ <span style="color: #66cc66; font-weight: 600;">Invariant:</span> Changes to authentication or authorization logic require             │
│            security review                                                      │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> project                                                                  │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> inv_01HXRBA2B                                                               │
╰─────────────────────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Invariant added
</code></pre></div>

#### Step 3: Run a Plan and Observe Escalation

<div class="highlight"><pre><code>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan use \
    <span style="color: cyan;">--arg</span> target_module=<span style="color: #66cc66;">"src/auth"</span> \
    local/refactor-to-orm local/api-service

╭─ Plan Created ─────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan ID:</span> 01HXRBG1H2I3J4K5L6M7N8O9P0                │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> strategize (running)                        │
│ <span style="color: magenta; font-weight: 600;">Action:</span> local/refactor-to-orm                      │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/api-service                         │
│ <span style="color: #66cc66; font-weight: 600;">Automation:</span> local/db-cautious                      │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                         │
╰────────────────────────────────────────────────────╯

╭─ Inputs ─────────────────────╮
│ - target_module=src/auth     │
╰──────────────────────────────╯

╭─ Actors ───────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Strategy:</span> anthropic/claude-3.5-sonnet  │
│ <span style="color: magenta; font-weight: 600;">Execution:</span> anthropic/claude-3.5-sonnet │
│ <span style="color: #5599ff; font-weight: 600;">Invariant:</span> local/invariant-resolver    │
╰────────────────────────────────────────╯

╭─ Plan Invariants ──────────────────────────────────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Scope</span>     <span style="color: magenta; font-weight: 600;">Source</span>   <span style="color: magenta; font-weight: 600;">Invariant</span>                                                   │
│ <span style="opacity: 0.7;">────────  ───────  ──────────────────────────────────────────────────────</span>      │
│ project   config   Any change to database migration files requires explicit    │
│                     human approval                                             │
│ project   config   Changes to authentication or authorization logic require    │
│                     security review                                            │
╰────────────────────────────────────────────────────────────────────────────────╯

╭─ Next Steps ─────────────────────────────────────────╮
│ - agents plan status 01HXRBG1H2I3J4K5L6M7N8O9P0      │
│ - agents plan tree 01HXRBG1H2I3J4K5L6M7N8O9P0        │
╰──────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan created — strategize in progress
</code></pre></div>

During execution, the system encounters a decision to create a new Alembic migration. The confidence score is 0.82 (the system is fairly confident), but the invariant "database migration files require explicit human approval" causes the Invariant Reconciliation Actor to enforce escalation regardless. The system pauses:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># The plan pauses — check why</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan status 01HXRBG1H2I3J4K5L6M7N8O9P0

╭─ Plan Status ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXRBG1H2I3J4K5L6M7N8O9P0                    │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> execute                                      │
│ <span style="color: yellow; font-weight: 600;">State:</span> awaiting_input                               │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/refactor-to-orm                       │
│ <span style="color: #66cc66; font-weight: 600;">Project:</span> local/api-service                          │
│ <span style="color: #5599ff; font-weight: 600;">Automation:</span> local/db-cautious                       │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                          │
╰─────────────────────────────────────────────────────╯

╭─ Progress ────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Strategize              │
│ <span style="color: yellow; font-weight: 600;">⏸</span> Execute (paused)        │
│ <span style="opacity: 0.5;">○</span> Apply (waiting)         │
╰───────────────────────────╯

╭─ Escalation ───────────────────────────────────────────────────────────────╮
│ <span style="color: yellow; font-weight: 600;">⚠  Decision paused — invariant forced escalation</span>                           │
│ <span style="color: #5599ff; font-weight: 600;">Decision:</span> 01HXRBD1E2F3G4H5I6J7K8L9                                         │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> implementation_choice                                                │
│ <span style="color: magenta; font-weight: 600;">Question:</span> Create Alembic migration for users table schema change?          │
│ <span style="color: yellow; font-weight: 600;">Confidence:</span> 0.82 (would auto-proceed, but invariant overrides)             │
│ <span style="color: #ff6666; font-weight: 600;">Invariant:</span> "Any change to database migration files requires explicit       │
│             human approval"                                                │
╰────────────────────────────────────────────────────────────────────────────╯

╭─ Timing ───────────╮
│ <span style="color: #66cc66; font-weight: 600;">Started:</span> 09:05:12  │
│ <span style="color: yellow; font-weight: 600;">Elapsed:</span> 00:02:48  │
│ <span style="color: #66cc66; font-weight: 600;">ETA:</span> (paused)      │
╰────────────────────╯

╭─ Cost ───────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Tokens Used:</span> 18,740  │
│ <span style="color: yellow; font-weight: 600;">Cost So Far:</span> $0.062  │
│ <span style="color: #5599ff; font-weight: 600;">Estimated:</span> $0.095    │
╰──────────────────────╯

<span style="color: yellow; font-weight: 600;">⚠ WARN</span> Plan paused — awaiting human input for escalated decision
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Review the decision requiring approval</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan explain 01HXRBD1E2F3G4H5I6J7K8L9

╭─ Decision ───────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXRBD1E2F3G4H5I6J7K8L9                                         │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> implementation_choice                                          │
│ <span style="color: magenta; font-weight: 600;">Question:</span> Create Alembic migration for users table schema change?    │
│ <span style="color: #66cc66; font-weight: 600;">Chosen:</span> Add nullable `orm_version` column with migration             │
│ <span style="color: yellow; font-weight: 600;">Confidence:</span> 0.82                                                     │
│ <span style="color: #5599ff; font-weight: 600;">Plan:</span> 01HXRBG1H2I3J4K5L6M7N8O9P0                                     │
│ <span style="color: #5599ff; font-weight: 600;">Sequence:</span> 4 of 7                                                     │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 09:07                                            │
╰──────────────────────────────────────────────────────────────────────╯

╭─ Alternatives Considered ────────────────────────────────────────────╮
│ 1. Add nullable `orm_version` column with migration <span style="color: #66cc66; font-weight: 600;">(chosen)</span>         │
│ 2. Use a shadow table approach (no schema change)                    │
│ 3. In-place column rename via ALTER (risky in production)            │
╰──────────────────────────────────────────────────────────────────────╯

╭─ Escalation Reason ──────────────────────────────────────────────────╮
│ <span style="color: #ff6666; font-weight: 600;">Invariant Override:</span> inv_01HXRBA1A                                    │
│ <span style="color: #5599ff; font-weight: 600;">Text:</span> "Any change to database migration files requires explicit      │
│       human approval"                                                │
│ <span style="color: #5599ff; font-weight: 600;">Effect:</span> Confidence 0.82 would normally auto-proceed (threshold       │
│         0.6), but invariant forces manual escalation regardless      │
╰──────────────────────────────────────────────────────────────────────╯

╭─ Impact ─────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Downstream Decisions:</span> 3          │
│ <span style="color: #5599ff; font-weight: 600;">Downstream Child Plans:</span> 0        │
│ <span style="color: #66cc66; font-weight: 600;">Artifacts Produced:</span> 2            │
│ <span style="color: yellow; font-weight: 600;">Correction Impact:</span> medium        │
╰──────────────────────────────────╯

╭─ Rationale ──────────────────────────────────────────────────────────╮
│ The auth module currently uses raw SQL queries. Refactoring to ORM   │
│ requires an `orm_version` tracking column on the users table.        │
│ Adding as nullable first avoids downtime; the backfill + NOT NULL    │
│ constraint can follow in a second migration after data is populated. │
╰──────────────────────────────────────────────────────────────────────╯

╭─ Correction ────────────────────────────────────────────────╮
│ agents plan prompt 01HXRBG1H2I3J4K5L6M7N8O9P0               │
│   <span style="color: cyan;">"Approved. &lt;guidance&gt;"</span>                                    │
│ agents plan correct 01HXRBD1E2F3G4H5I6J7K8L9                │
│   <span style="color: cyan;">--mode</span> revert <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">"Use approach 2 instead..."</span>      │
╰─────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Decision explained
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Approve the migration approach with specific guidance</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan prompt 01HXRBG1H2I3J4K5L6M7N8O9P0 \
    <span style="color: #66cc66;">"Approved. Use a two-phase migration: first add the column as nullable, \
     then in a separate migration add the NOT NULL constraint after backfill."</span>

╭─ Guidance Added ──────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXRBG1H2I3J4K5L6M7N8O9P0                                          │
│ <span style="color: magenta; font-weight: 600;">Guidance:</span> Approved. Use a two-phase migration: first add the column as    │
│           nullable, then in a separate migration add the NOT NULL         │
│           constraint after backfill.                                      │
│ <span style="color: #5599ff; font-weight: 600;">Scope:</span> next execution step                                                │
│ <span style="color: #5599ff; font-weight: 600;">Phase:</span> execute                                                            │
│ <span style="color: #5599ff; font-weight: 600;">State:</span> awaiting_input → processing                                        │
╰───────────────────────────────────────────────────────────────────────────╯

╭─ Decision Created ──────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> user_intervention                         │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> 01HXRBE2F3G4H5I6J7K8L9M0                    │
│ <span style="color: #5599ff; font-weight: 600;">Parent:</span> 01HXRBD1E2F3G4H5I6J7K8L9                │
╰─────────────────────────────────────────────────╯

╭─ Queue ────╮
│ <span style="color: yellow; font-weight: 600;">Pending:</span> 1 │
│ <span style="color: #66cc66; font-weight: 600;">Applied:</span> 0 │
╰────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Guidance queued — execution resuming
</code></pre></div>

---

### Example 14: Server Mode — Team Collaboration

**Scenario**: A distributed team uses CleverAgents in server mode. Multiple engineers share actions, actors, and projects while working on the same codebase from different machines.

**Complexity**: Intermediate. Server mode, multi-user, namespace management.

#### Step 1: Connect to the Server

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Configure server connection</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set server.url https://agents.example.com

╭─ Config Updated ──────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Key:</span> server.url                               │
│ <span style="color: #66cc66; font-weight: 600;">Value:</span> https://agents.example.com             │
│ <span style="color: yellow; font-weight: 600;">Previous:</span> (not set)                           │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> config                                │
│ <span style="color: yellow; font-weight: 600;">Scope:</span> global                                 │
╰───────────────────────────────────────────────╯

╭─ Saved To ──────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">File:</span> ~/.cleveragents/config.toml   │
│ <span style="color: #5599ff; font-weight: 600;">Line:</span> 3                             │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Config updated

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set server.token <span style="color: #66cc66;">"tok_01HXR..."</span>

╭─ Config Updated ──────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Key:</span> server.token                         │
│ <span style="color: #66cc66; font-weight: 600;">Value:</span> tok_01HXR... (redacted)            │
│ <span style="color: yellow; font-weight: 600;">Previous:</span> (not set)                       │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> config                            │
│ <span style="color: yellow; font-weight: 600;">Scope:</span> global                             │
╰───────────────────────────────────────────╯

╭─ Saved To ──────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">File:</span> ~/.cleveragents/config.toml   │
│ <span style="color: #5599ff; font-weight: 600;">Line:</span> 4                             │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Config updated

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set core.namespace myteam

╭─ Config Updated ──────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Key:</span> core.namespace                   │
│ <span style="color: #66cc66; font-weight: 600;">Value:</span> myteam                         │
│ <span style="color: yellow; font-weight: 600;">Previous:</span> local                       │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> config                        │
│ <span style="color: yellow; font-weight: 600;">Scope:</span> global                         │
╰───────────────────────────────────────╯

╭─ Saved To ──────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">File:</span> ~/.cleveragents/config.toml   │
│ <span style="color: #5599ff; font-weight: 600;">Line:</span> 5                             │
╰─────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Config updated
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Verify connection</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> diagnostics

╭─ Checks ────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Check</span>            <span style="color: cyan; font-weight: 600;">Status</span>  <span style="color: cyan; font-weight: 600;">Details</span>                        │
│ <span style="opacity: 0.7;">───────────────  ──────  ───────────────────────</span>        │
│ Config file      <span style="color: #66cc66; font-weight: 600;">OK</span>      readable                       │
│ Database         <span style="color: #66cc66; font-weight: 600;">OK</span>      writable                       │
│ Anthropic key    <span style="color: #66cc66; font-weight: 600;">OK</span>      configured                     │
│ OPENAI_API_KEY   <span style="color: yellow; font-weight: 600;">WARN</span>    missing                        │
│ Disk space       <span style="color: #66cc66; font-weight: 600;">OK</span>      4.8 GB free                    │
│ Text index       <span style="color: #66cc66; font-weight: 600;">OK</span>      tantivy 0.22                   │
│ Vector index     <span style="color: #66cc66; font-weight: 600;">OK</span>      faiss (CPU)                    │
│ Graph store      <span style="color: #66cc66; font-weight: 600;">OK</span>      neo4j 5.15                     │
│ File permissions <span style="color: #66cc66; font-weight: 600;">OK</span>      data dir r/w                   │
│ Git              <span style="color: #66cc66; font-weight: 600;">OK</span>      git 2.43.0                     │
│ Server           <span style="color: #66cc66; font-weight: 600;">OK</span>      connected (agents.example.com) │
│ Namespace        <span style="color: #66cc66; font-weight: 600;">OK</span>      myteam (4 members)             │
╰─────────────────────────────────────────────────────────╯

╭─ Summary ─────────╮
│ <span style="color: #5599ff; font-weight: 600;">Checks:</span> 12 total  │
│ <span style="color: yellow; font-weight: 600;">Warnings:</span> 1       │
│ <span style="color: #ff6666; font-weight: 600;">Errors:</span> 0         │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 0.8s    │
╰───────────────────╯

╭─ Server ────────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">URL:</span> https://agents.example.com     │
│ <span style="color: #66cc66; font-weight: 600;">Auth:</span> valid (tok_01HXR...)          │
│ <span style="color: #5599ff; font-weight: 600;">Namespace:</span> myteam                   │
│ <span style="color: #5599ff; font-weight: 600;">Members:</span> 4                          │
│ <span style="color: #5599ff; font-weight: 600;">Shared Actions:</span> 7                   │
│ <span style="color: #5599ff; font-weight: 600;">Shared Actors:</span> 3                    │
│ <span style="color: #5599ff; font-weight: 600;">Latency:</span> 42ms                       │
╰─────────────────────────────────────╯

╭─ Recommendations ──────────────────────────────╮
│ - Set OPENAI_API_KEY to enable OpenAI models   │
╰────────────────────────────────────────────────╯

<span style="color: yellow; font-weight: 600;">⚠ WARN</span> 1 warning requires attention
</code></pre></div>

#### Step 2: Publish Shared Resources

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Publish an action to the team namespace (visible to all team members)</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action create <span style="color: cyan;">--config</span> ./actions/generate-tests.yaml

╭─ Action Created ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> myteam/generate-tests                           │
│ <span style="color: #5599ff; font-weight: 600;">ID:</span> 01HXRC1A2B3C4D5E6F7G8H9J0K                        │
│ <span style="color: yellow; font-weight: 600;">State:</span> available                                      │
│ <span style="color: magenta; font-weight: 600;">Strategy Actor:</span> anthropic/claude-3.5-sonnet           │
│ <span style="color: magenta; font-weight: 600;">Execution Actor:</span> anthropic/claude-3.5-sonnet          │
│ <span style="color: #66cc66; font-weight: 600;">Reusable:</span> yes                                         │
│ <span style="color: #5599ff; font-weight: 600;">Read Only:</span> no                                         │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 09:15                             │
╰───────────────────────────────────────────────────────╯

╭─ Definition of Done ───────────────────────────────────╮
│ All target modules have test coverage above 80%        │
│ Tests pass in CI without flaky failures                │
╰────────────────────────────────────────────────────────╯

╭─ Arguments ─────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>            <span style="color: cyan; font-weight: 600;">Type</span>    <span style="color: cyan; font-weight: 600;">Required</span>  <span style="color: cyan; font-weight: 600;">Description</span>                   │
│ <span style="opacity: 0.7;">──────────────  ──────  ────────  ───────────────────────</span>       │
│ target_module   string  yes       Module path to generate tests │
╰─────────────────────────────────────────────────────────────────╯

╭─ Automation ────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Profile:</span> supervised                 │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> action default              │
╰─────────────────────────────────────╯

╭─ Usage ───────────────────────────────────────────────────────────╮
│ agents plan use myteam/generate-tests local/my-project            │
│   <span style="color: cyan;">--arg</span> target_module=<span style="color: #66cc66;">"src/payments"</span>                              │
╰───────────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Action created
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Publish a shared actor</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> actor add <span style="color: cyan;">--config</span> ./actors/review-pipeline.yaml

╭─ Actor Added ──────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name:</span> myteam/review-pipeline                   │
│ <span style="color: #5599ff; font-weight: 600;">Provider:</span> anthropic                            │
│ <span style="color: magenta; font-weight: 600;">Model:</span> claude-3.5-sonnet                       │
│ <span style="color: yellow; font-weight: 600;">Default:</span> no                                    │
│ <span style="color: #ff6666; font-weight: 600;">Unsafe:</span> no                                     │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> graph                                    │
╰────────────────────────────────────────────────╯

╭─ Config ───────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Path:</span> ./actors/review-pipeline.yaml    │
│ <span style="color: magenta; font-weight: 600;">Hash:</span> 5a7c2e1                          │
│ <span style="color: #66cc66; font-weight: 600;">Options:</span> 3                             │
│ <span style="color: #5599ff; font-weight: 600;">Nodes:</span> 5                               │
│ <span style="color: #5599ff; font-weight: 600;">Edges:</span> 6                               │
╰────────────────────────────────────────╯

╭─ Capabilities ──────────────────╮
│ - multi-stage code review       │
│ - security analysis             │
│ - performance analysis          │
│ - style checking                │
╰─────────────────────────────────╯

╭─ Tools ────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Tool</span>          <span style="color: cyan; font-weight: 600;">Read-Only</span>  <span style="color: cyan; font-weight: 600;">Safe</span>  │
│ <span style="opacity: 0.7;">────────────  ─────────  ────</span>  │
│ read_file     yes        yes   │
│ search_files  yes        yes   │
│ git_diff      yes        yes   │
│ run_tests     yes        yes   │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Actor added
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># List available actions (team namespace)</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> action list <span style="color: cyan;">--namespace</span> myteam

╭─ Actions ────────────────────────────────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Name</span>                      <span style="color: cyan; font-weight: 600;">State</span>      <span style="color: cyan; font-weight: 600;">Strategy Actor</span>               <span style="color: cyan; font-weight: 600;">Execution Actor</span>              <span style="color: cyan; font-weight: 600;">Reusable</span>  │
│ <span style="opacity: 0.7;">────────────────────────  ─────────  ───────────────────────────  ───────────────────────────  ────────</span>  │
│ myteam/generate-tests    available  anthropic/claude-3.5-sonnet  anthropic/claude-3.5-sonnet  ✓          │
│ myteam/deep-review       available  myteam/review-pipeline       myteam/review-pipeline       ✓          │
│ myteam/format-codebase   available  anthropic/claude-3.5-sonnet  anthropic/claude-3.5-sonnet  ✓          │
│ myteam/security-audit    available  anthropic/claude-3.5-sonnet  anthropic/claude-3.5-sonnet  ✓          │
│ myteam/refactor-to-orm   available  anthropic/claude-3.5-sonnet  anthropic/claude-3.5-sonnet  ✗          │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Filters ──────────────────╮
│ <span style="color: yellow; font-weight: 600;">State:</span> (any)               │
│ <span style="color: #5599ff; font-weight: 600;">Namespace:</span> myteam          │
╰────────────────────────────╯

╭─ Summary ──────────────────╮
│ <span style="color: yellow; font-weight: 600;">Total:</span> 5                   │
│ <span style="color: #66cc66; font-weight: 600;">Available:</span> 5               │
│ <span style="color: yellow; font-weight: 600;">Archived:</span> 0                │
╰────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 5 actions listed
</code></pre></div>

#### Step 3: Use Shared Resources from Another Machine

On a different developer's machine:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Configure server connection</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set server.url https://agents.example.com

╭─ Config Updated ──────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Key:</span> server.url                               │
│ <span style="color: #66cc66; font-weight: 600;">Value:</span> https://agents.example.com             │
│ <span style="color: yellow; font-weight: 600;">Previous:</span> (not set)                           │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> config                                │
│ <span style="color: yellow; font-weight: 600;">Scope:</span> global                                 │
╰───────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Config updated

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set server.token <span style="color: #66cc66;">"tok_01HXS..."</span>

╭─ Config Updated ──────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Key:</span> server.token                         │
│ <span style="color: #66cc66; font-weight: 600;">Value:</span> tok_01HXS... (redacted)            │
│ <span style="color: yellow; font-weight: 600;">Previous:</span> (not set)                       │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> config                            │
│ <span style="color: yellow; font-weight: 600;">Scope:</span> global                             │
╰───────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Config updated

<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> config set core.namespace myteam

╭─ Config Updated ──────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Key:</span> core.namespace                   │
│ <span style="color: #66cc66; font-weight: 600;">Value:</span> myteam                         │
│ <span style="color: yellow; font-weight: 600;">Previous:</span> local                       │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> config                        │
│ <span style="color: yellow; font-weight: 600;">Scope:</span> global                         │
╰───────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Config updated
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Use the team's shared action</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan use \
    <span style="color: cyan;">--arg</span> target_module=<span style="color: #66cc66;">"src/payments"</span> \
    myteam/generate-tests local/payment-service

╭─ Plan Created ─────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan ID:</span> 01HXRC2B3C4D5E6F7G8H9J0K1L2                   │
│ <span style="color: yellow; font-weight: 600;">Phase:</span> strategize (running)                            │
│ <span style="color: magenta; font-weight: 600;">Action:</span> myteam/generate-tests                          │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/payment-service                         │
│ <span style="color: #66cc66; font-weight: 600;">Automation:</span> supervised                                 │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                             │
╰────────────────────────────────────────────────────────╯

╭─ Inputs ──────────────────────╮
│ - target_module=src/payments  │
╰───────────────────────────────╯

╭─ Actors ──────────────────────────────────╮
│ <span style="color: magenta; font-weight: 600;">Strategy:</span> anthropic/claude-3.5-sonnet     │
│ <span style="color: magenta; font-weight: 600;">Execution:</span> anthropic/claude-3.5-sonnet    │
│ <span style="color: #5599ff; font-weight: 600;">Source:</span> server (myteam)                   │
╰───────────────────────────────────────────╯

╭─ Context ───────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Resources:</span> 1 (repo)             │
│ <span style="color: #5599ff; font-weight: 600;">Indexed Files:</span> 189              │
│ <span style="color: #5599ff; font-weight: 600;">View:</span> strategize                │
│ <span style="color: #5599ff; font-weight: 600;">Hot Token Budget:</span> 12,000        │
╰─────────────────────────────────╯

╭─ Next Steps ──────────────────────────────────────────────╮
│ - agents plan status 01HXRC2B3C4D5E6F7G8H9J0K1L2          │
│ - agents plan tree 01HXRC2B3C4D5E6F7G8H9J0K1L2            │
╰───────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Plan created — strategize in progress
</code></pre></div>

#### Step 4: Monitor Across the Team

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># List all plans across the team</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan list <span style="color: cyan;">--namespace</span> myteam

╭─ Plans ────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>        <span style="color: cyan; font-weight: 600;">Phase</span>     <span style="color: cyan; font-weight: 600;">State</span>       <span style="color: cyan; font-weight: 600;">Action</span>                  <span style="color: cyan; font-weight: 600;">Project</span>                <span style="color: cyan; font-weight: 600;">User</span>     <span style="color: cyan; font-weight: 600;">Elapsed</span>                │
│ <span style="opacity: 0.7;">────────  ────────  ──────────  ──────────────────────  ─────────────────────  ───────  ─────────</span>              │
│ 01HXRC2B  <span style="color: cyan; font-weight: 600;">execute</span>   <span style="color: cyan; font-weight: 600;">processing</span>  myteam/generate-tests   local/payment-service  jdoe     00:04:12               │
│ 01HXRC3C  <span style="color: #66cc66; font-weight: 600;">applied</span>   <span style="color: #66cc66; font-weight: 600;">complete</span>    myteam/deep-review      local/api-service      asmith   00:08:47               │
│ 01HXRC4D  <span style="color: cyan; font-weight: 600;">execute</span>   <span style="color: cyan; font-weight: 600;">processing</span>  myteam/generate-tests   local/api-service      mwong    00:02:35               │
│ 01HXRC5E  <span style="color: #66cc66; font-weight: 600;">applied</span>   <span style="color: #66cc66; font-weight: 600;">complete</span>    myteam/format-codebase  local/frontend         blee     00:01:58               │
│ 01HXRC6F  <span style="color: yellow; font-weight: 600;">execute</span>   <span style="color: yellow; font-weight: 600;">awaiting</span>    myteam/security-audit   local/worker-service   asmith   00:06:20               │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Filters ──────────────────╮
│ <span style="color: yellow; font-weight: 600;">Phase:</span> (any)               │
│ <span style="color: magenta; font-weight: 600;">State:</span> (any)               │
│ <span style="color: #5599ff; font-weight: 600;">Namespace:</span> myteam          │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> (any)             │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> (any)              │
╰────────────────────────────╯

╭─ Summary ─────────────╮
│ <span style="color: yellow; font-weight: 600;">Total:</span> 5              │
│ <span style="color: cyan; font-weight: 600;">Processing:</span> 2         │
│ <span style="color: #66cc66; font-weight: 600;">Completed:</span> 2          │
│ <span style="color: yellow; font-weight: 600;">Awaiting:</span> 1           │
│ <span style="color: #ff6666; font-weight: 600;">Errored:</span> 0            │
╰───────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 5 plans listed
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># See who is running what — filter to executing state</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan list <span style="color: cyan;">--namespace</span> myteam <span style="color: cyan;">--state</span> processing

╭─ Plans ────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>        <span style="color: cyan; font-weight: 600;">Phase</span>    <span style="color: cyan; font-weight: 600;">State</span>       <span style="color: cyan; font-weight: 600;">Action</span>                 <span style="color: cyan; font-weight: 600;">Project</span>                <span style="color: cyan; font-weight: 600;">User</span>     <span style="color: cyan; font-weight: 600;">Elapsed</span>                  │
│ <span style="opacity: 0.7;">────────  ───────  ──────────  ─────────────────────  ─────────────────────  ───────  ─────────</span>                │
│ 01HXRC2B  <span style="color: cyan; font-weight: 600;">execute</span>  <span style="color: cyan; font-weight: 600;">processing</span>  myteam/generate-tests  local/payment-service  jdoe     00:04:12                 │
│ 01HXRC4D  <span style="color: cyan; font-weight: 600;">execute</span>  <span style="color: cyan; font-weight: 600;">processing</span>  myteam/generate-tests  local/api-service      mwong    00:02:35                 │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Filters ──────────────────────╮
│ <span style="color: yellow; font-weight: 600;">Phase:</span> (any)                   │
│ <span style="color: magenta; font-weight: 600;">State:</span> processing              │
│ <span style="color: #5599ff; font-weight: 600;">Namespace:</span> myteam              │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> (any)                 │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> (any)                  │
╰────────────────────────────────╯

╭─ Summary ─────────────╮
│ <span style="color: yellow; font-weight: 600;">Total:</span> 2              │
│ <span style="color: cyan; font-weight: 600;">Processing:</span> 2         │
│ <span style="color: #66cc66; font-weight: 600;">Completed:</span> 0          │
│ <span style="color: #ff6666; font-weight: 600;">Errored:</span> 0            │
╰───────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 2 plans listed
</code></pre></div>

---

### Example 15: Disaster Recovery — Rollback a Failed Apply

**Scenario**: A plan was applied, but the changes broke production. The team needs to understand what happened and roll back.

**Complexity**: Intermediate. Rollback, checkpoint restore, post-mortem analysis.

#### Step 1: Investigate the Failed Apply

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Check the plan status</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan status 01HXRCF1G2H3I4J5K6L7M8N9O0

╭─ Plan Status ───────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXRCF1G2H3I4J5K6L7M8N9O0                    │
│ <span style="color: #66cc66; font-weight: 600;">Phase:</span> applied                                      │
│ <span style="color: #ff6666; font-weight: 600;">State:</span> errored                                      │
│ <span style="color: #5599ff; font-weight: 600;">Action:</span> local/optimize-db-connections               │
│ <span style="color: #66cc66; font-weight: 600;">Project:</span> local/api-service                          │
│ <span style="color: #5599ff; font-weight: 600;">Automation:</span> trusted                                 │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 1                                          │
╰─────────────────────────────────────────────────────╯

╭─ Progress ─────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Strategize                   │
│ <span style="color: #66cc66; font-weight: 600;">✓</span> Execute                      │
│ <span style="color: #ff6666; font-weight: 600;">✗</span> Apply (post-apply failure)   │
╰────────────────────────────────╯

╭─ Timing ──────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Started:</span> 2026-02-11 08:30:00      │
│ <span style="color: #66cc66; font-weight: 600;">Applied At:</span> 2026-02-11 08:42:18   │
│ <span style="color: #ff6666; font-weight: 600;">Failed At:</span> 2026-02-11 08:44:05    │
│ <span style="color: #5599ff; font-weight: 600;">Total Duration:</span> 00:14:05          │
╰───────────────────────────────────╯

╭─ Result ───────────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Decisions Made:</span> 6                                      │
│ <span style="color: #5599ff; font-weight: 600;">Child Plans:</span> 0                                         │
│ <span style="color: #66cc66; font-weight: 600;">Artifacts:</span> 4 files updated                             │
│ <span style="color: #ff6666; font-weight: 600;">Validations:</span> 2/3 passed (1 FAILED post-apply)          │
│ <span style="color: yellow; font-weight: 600;">Total Cost:</span> $0.072                                     │
╰────────────────────────────────────────────────────────╯

╭─ Error ──────────────────────────────────────────────────────────────────────╮
│ <span style="color: #ff6666; font-weight: 600;">Post-apply health check failed:</span> connection pool exhaustion detected          │
│ <span style="color: #ff6666; font-weight: 600;">Impact:</span> API response times increased 10x, 503 errors in production           │
│ <span style="color: #5599ff; font-weight: 600;">Root Cause Decision:</span> 01HXRCD3E4F5G6H7I8J9K0L1                                │
╰──────────────────────────────────────────────────────────────────────────────╯

╭─ Recovery Options ──────────────────────────────────────────────────╮
│ - <span style="color: cyan;">agents plan rollback</span> <span style="opacity: 0.7;">— restore to a previous checkpoint</span>           │
│ - <span style="color: cyan;">agents plan correct</span> <span style="opacity: 0.7;">— revert and re-execute with guidance</span>         │
│ - <span style="color: cyan;">agents plan explain</span> <span style="opacity: 0.7;">— investigate the root cause decision</span>         │
╰─────────────────────────────────────────────────────────────────────╯

<span style="color: #ff6666; font-weight: 600;">✗ ERROR</span> Plan applied but post-apply validation failed
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Review the decision tree to understand what was done</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan tree 01HXRCF1G2H3I4J5K6L7M8N9O0

╭─ Decision Tree ────────────────────────────────────────────────────────────────────────────────╮
│ Plan: 01HXRCF1G2H3I4J5K6L7M8N9O0                                                               │
│ ├─ <span style="color: white;">[prompt_definition]</span> <span style="color: #66cc66;">"Optimize database connection handling"</span>                                 │
│ ├─ <span style="color: magenta;">[invariant_enforced]</span> <span style="color: #66cc66;">"All DB config changes must preserve existing pool limits"</span>             │
│ ├─ <span style="color: #5599ff;">[strategy_choice]</span> <span style="color: #66cc66;">"Refactor connection pool configuration"</span> <span style="opacity: 0.7;">(confidence: 0.91)</span>               │
│ ├─ <span style="color: #66cc66;">[tool_invocation]</span> write_file: src/db/pool_config.py                                         │
│ ├─ <span style="color: #ff6666;">[implementation_choice]</span> <span style="color: #66cc66;">"Increase pool size to 100"</span> <span style="opacity: 0.7;">(confidence: 0.78)</span> <span style="color: #ff6666; font-weight: 600;">← ROOT CAUSE</span>         │
│ └─ <span style="color: #66cc66;">[tool_invocation]</span> write_file: src/db/health_check.py                                        │
╰────────────────────────────────────────────────────────────────────────────────────────────────╯

╭─ Tree Summary ──────────────────╮
│ <span style="color: yellow; font-weight: 600;">Nodes:</span> 6                        │
│ <span style="color: #5599ff; font-weight: 600;">Depth:</span> 2                        │
│ <span style="color: #66cc66; font-weight: 600;">Child Plans:</span> 0                  │
│ <span style="color: magenta; font-weight: 600;">Invariants:</span> 1                   │
│ <span style="color: #5599ff; font-weight: 600;">Superseded:</span> 0 (hidden)          │
╰─────────────────────────────────╯

╭─ Decision IDs (for correction) ──────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Root:</span> 01HXRCC1D2E3F4G5H6I7J8K9                       │
│ <span style="color: magenta; font-weight: 600;">Invariant 1:</span> 01HXRCC2E3F4G5H6I7J8K9L0                │
│ <span style="color: #5599ff; font-weight: 600;">Strategy:</span> 01HXRCC3F4G5H6I7J8K9L0M1                   │
│ <span style="color: #66cc66; font-weight: 600;">Tool 1:</span> 01HXRCC4G5H6I7J8K9L0M1N2                     │
│ <span style="color: #ff6666; font-weight: 600;">Pool Size (root cause):</span> 01HXRCD3E4F5G6H7I8J9K0L1     │
│ <span style="color: #66cc66; font-weight: 600;">Tool 2:</span> 01HXRCE4F5G6H7I8J9K0L1M2                     │
╰──────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Decision tree rendered
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Look at the specific changes that were applied</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan diff 01HXRCF1G2H3I4J5K6L7M8N9O0

╭─ Diff Summary ─────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXRCF1G2H3I4J5K6L7M8N9O0                   │
│ <span style="color: cyan; font-weight: 600;">Project:</span> local/api-service                         │
│ <span style="color: yellow; font-weight: 600;">Files Changed:</span> 4                                   │
│ <span style="color: #66cc66; font-weight: 600;">Insertions:</span> 38                                     │
│ <span style="color: #ff6666; font-weight: 600;">Deletions:</span> 12                                      │
│ <span style="color: #5599ff; font-weight: 600;">Net Change:</span> +26 lines                              │
╰────────────────────────────────────────────────────╯

╭─ Files ──────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Path</span>                      <span style="color: cyan; font-weight: 600;">Change</span>  <span style="color: cyan; font-weight: 600;">Status</span>     │
│ <span style="opacity: 0.7;">────────────────────────  ──────  ────────</span>   │
│ src/db/pool_config.py     <span style="color: #66cc66; font-weight: 600;">+14 -6</span>  modified   │
│ src/db/health_check.py    <span style="color: #66cc66; font-weight: 600;">+18 -0</span>  new file   │
│ src/db/__init__.py         <span style="color: #66cc66; font-weight: 600;">+4 -4</span>  modified   │
│ config/database.toml       <span style="color: #66cc66; font-weight: 600;">+2 -2</span>  modified   │
╰──────────────────────────────────────────────╯

╭─ Patch Preview ──────────────────────────────────╮
│ <span style="opacity: 0.7;">--- a/src/db/pool_config.py</span>                      │
│ <span style="opacity: 0.7;">+++ b/src/db/pool_config.py</span>                      │
│ <span style="color: cyan;">@@ -8,6 +8,14 @@</span>                                 │
│ <span style="color: #ff6666;">- POOL_SIZE = 20</span>                                 │
│ <span style="color: #ff6666;">- POOL_MAX_OVERFLOW = 10</span>                         │
│ <span style="color: #66cc66;">+ POOL_SIZE = 100</span>                                │
│ <span style="color: #66cc66;">+ POOL_MAX_OVERFLOW = 50</span>                         │
│ <span style="color: #66cc66;">+ POOL_RECYCLE = 3600</span>                            │
│ <span style="color: #66cc66;">+ POOL_PRE_PING = True</span>                           │
│ <span style="opacity: 0.7;">--- a/config/database.toml</span>                       │
│ <span style="opacity: 0.7;">+++ b/config/database.toml</span>                       │
│ <span style="color: cyan;">@@ -3,2 +3,2 @@</span>                                  │
│ <span style="color: #ff6666;">- pool_size = 20</span>                                 │
│ <span style="color: #66cc66;">+ pool_size = 100</span>                                │
╰──────────────────────────────────────────────────╯

╭─ Risk Assessment ──────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">API Compatibility:</span> preserved               │
│ <span style="color: #66cc66; font-weight: 600;">Test Coverage:</span> maintained                  │
│ <span style="color: #ff6666; font-weight: 600;">Breaking Changes:</span> pool size 5x increase    │
│ <span style="color: #ff6666; font-weight: 600;">Resource Impact:</span> high (connection limit)   │
╰────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Diff generated
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Examine the decision that led to the problematic change</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan explain 01HXRCD3E4F5G6H7I8J9K0L1 <span style="color: cyan;">--show-context</span> <span style="color: cyan;">--show-reasoning</span>

╭─ Decision ───────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID:</span> 01HXRCD3E4F5G6H7I8J9K0L1                                         │
│ <span style="color: #5599ff; font-weight: 600;">Type:</span> implementation_choice                                          │
│ <span style="color: magenta; font-weight: 600;">Question:</span> What pool size should be configured?                       │
│ <span style="color: #66cc66; font-weight: 600;">Chosen:</span> Increase pool size from 20 to 100                            │
│ <span style="color: yellow; font-weight: 600;">Confidence:</span> 0.78                                                     │
│ <span style="color: #5599ff; font-weight: 600;">Plan:</span> 01HXRCF1G2H3I4J5K6L7M8N9O0                                     │
│ <span style="color: #5599ff; font-weight: 600;">Sequence:</span> 5 of 6                                                     │
│ <span style="color: #66cc66; font-weight: 600;">Created:</span> 2026-02-11 08:38                                            │
╰──────────────────────────────────────────────────────────────────────╯

╭─ Alternatives Considered ─────────────────────────────────────╮
│ 1. Increase pool size from 20 to 100 <span style="color: #66cc66; font-weight: 600;">(chosen)</span>                 │
│ 2. Keep pool at 20, add connection health checks only         │
│ 3. Increase to 50 with overflow to 75                         │
╰───────────────────────────────────────────────────────────────╯

╭─ Impact ─────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Downstream Decisions:</span> 1          │
│ <span style="color: #5599ff; font-weight: 600;">Downstream Child Plans:</span> 0        │
│ <span style="color: #66cc66; font-weight: 600;">Artifacts Produced:</span> 2            │
│ <span style="color: yellow; font-weight: 600;">Correction Impact:</span> low           │
╰──────────────────────────────────╯

╭─ Context Snapshot ────────────────────────────────────────────────╮
│ - Current pool_size=20 in config/database.toml                    │
│ - Database server: PostgreSQL 15, max_connections=150             │
│ - 3 application replicas running (total: 60 connections used)     │
│ - Slow query logs show connection wait times of 200-500ms         │
│ <span style="color: #5599ff; font-weight: 600;">Hot Context Hash:</span> sha256:9c4f...a1b2                              │
╰───────────────────────────────────────────────────────────────────╯

╭─ Rationale ─────────────────────────────────────────────────────╮
│ Connection wait times of 200-500ms suggest pool exhaustion.     │
│ Increasing to 100 connections per replica provides headroom     │
│ for burst traffic and eliminates the queueing bottleneck.       │
╰─────────────────────────────────────────────────────────────────╯

╭─ Model Reasoning (raw) ────────────────────────────────────────────────╮
│ <span style="opacity: 0.7;">The slow query logs show connection acquisition delays of 200-500ms</span>    │
│ <span style="opacity: 0.7;">which indicates the pool is frequently exhausted. Current config:</span>      │
│ <span style="opacity: 0.7;">pool_size=20, max_overflow=10 (total 30 per replica).</span>                  │
│ <span style="opacity: 0.7;"></span>                                                                       │
│ <span style="opacity: 0.7;">With 3 replicas that's 90 connections max. The PostgreSQL server</span>       │
│ <span style="opacity: 0.7;">allows 150. I'll increase to 100 per replica (300 total with</span>           │
│ <span style="opacity: 0.7;">overflow). This exceeds the server's max_connections=150 but</span>           │
│ <span style="opacity: 0.7;">overflow connections are temporary and unlikely to all be active</span>       │
│ <span style="opacity: 0.7;">simultaneously.</span>                                                        │
│ <span style="opacity: 0.7;"></span>                                                                       │
│ <span style="opacity: 0.7;">[NOTE: The model failed to account for 3 replicas × 100 = 300</span>          │
│ <span style="opacity: 0.7;"> exceeding PostgreSQL max_connections=150]</span>                             │
╰────────────────────────────────────────────────────────────────────────╯

╭─ Correction ─────────────────────────────────────────────────╮
│ agents plan correct 01HXRCD3E4F5G6H7I8J9K0L1                 │
│   <span style="color: cyan;">--mode</span> revert <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">"Keep pool at 20, add health..."</span>  │
╰──────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Decision explained
</code></pre></div>

#### Step 2: Roll Back to a Checkpoint

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># List available checkpoints for this plan</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan artifacts 01HXRCF1G2H3I4J5K6L7M8N9O0

╭─ Artifacts ────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Path</span>                     <span style="color: cyan; font-weight: 600;">Type</span>   <span style="color: cyan; font-weight: 600;">Size</span>    <span style="color: cyan; font-weight: 600;">Change</span>   <span style="color: cyan; font-weight: 600;">Child Plan</span>        │
│ <span style="opacity: 0.7;">───────────────────────  ─────  ──────  ───────  ──────────</span>        │
│ src/db/pool_config.py    edit   1.4 KB  <span style="color: #66cc66; font-weight: 600;">+14 -6</span>  root               │
│ src/db/health_check.py   write  2.1 KB  <span style="color: #66cc66; font-weight: 600;">+18 -0</span>  root               │
│ src/db/__init__.py       edit   0.8 KB   <span style="color: #66cc66; font-weight: 600;">+4 -4</span>  root               │
│ config/database.toml     edit   0.3 KB   <span style="color: #66cc66; font-weight: 600;">+2 -2</span>  root               │
╰────────────────────────────────────────────────────────────────────╯

╭─ Summary ───────────╮
│ <span style="color: yellow; font-weight: 600;">Total:</span> 4            │
│ <span style="color: #66cc66; font-weight: 600;">Writes:</span> 1 (new)     │
│ <span style="color: #5599ff; font-weight: 600;">Edits:</span> 3 (modified) │
│ <span style="color: #ff6666; font-weight: 600;">Deletes:</span> 0          │
│ <span style="color: #5599ff; font-weight: 600;">Total Size:</span> 4.6 KB  │
╰─────────────────────╯

╭─ Checkpoints ──────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">ID</span>                  <span style="color: cyan; font-weight: 600;">Label</span>                        <span style="color: cyan; font-weight: 600;">Created</span>           │
│ <span style="opacity: 0.7;">────────────────────  ───────────────────────────  ──────────────</span>  │
│ checkpoint_01HXRCP1  before pool config changes    08:36:12        │
│ checkpoint_01HXRCP2  before health check addition  08:39:45        │
│ checkpoint_01HXRCP3  pre-apply snapshot            08:42:00        │
╰────────────────────────────────────────────────────────────────────╯

╭─ By Plan ──────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Root Plan:</span> 4 artifacts │
╰────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> 4 artifacts listed
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Roll back to the checkpoint before the problematic pool config change</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan rollback <span style="color: cyan;">--yes</span> 01HXRCF1G2H3I4J5K6L7M8N9O0 checkpoint_01HXRCP1

╭─ Rollback Summary ─────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXRCF1G2H3I4J5K6L7M8N9O0                   │
│ <span style="color: magenta; font-weight: 600;">Checkpoint:</span> checkpoint_01HXRCP1                    │
│ <span style="color: yellow; font-weight: 600;">Label:</span> before pool config changes                  │
│ <span style="color: yellow; font-weight: 600;">Files:</span> 4 reverted                                  │
╰────────────────────────────────────────────────────╯

╭─ Changes Reverted ──────────────────────╮
│ <span style="color: yellow; font-weight: 600;">File</span>                      <span style="color: yellow; font-weight: 600;">Action</span>        │
│ <span style="opacity: 0.7;">────────────────────────  ──────────</span>    │
│ src/db/pool_config.py     restored      │
│ src/db/health_check.py    removed       │
│ src/db/__init__.py        restored      │
│ config/database.toml      restored      │
╰─────────────────────────────────────────╯

╭─ Impact ──────────────────────────────────╮
│ <span style="color: yellow; font-weight: 600;">Child Plans Invalidated:</span> 0                │
│ <span style="color: #5599ff; font-weight: 600;">Sandbox:</span> restored to checkpoint_01HXRCP1  │
│ <span style="color: #5599ff; font-weight: 600;">Decisions After CP:</span> 2 discarded           │
│ <span style="color: #5599ff; font-weight: 600;">Tool Calls After CP:</span> 3 undone             │
╰───────────────────────────────────────────╯

╭─ Post-Rollback State ──────────╮
│ <span style="color: yellow; font-weight: 600;">Phase:</span> execute                 │
│ <span style="color: #5599ff; font-weight: 600;">State:</span> queued (awaiting input) │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoints Remaining:</span> 1       │
╰────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Rollback complete
</code></pre></div>

#### Step 3: Correct and Re-Execute

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Correct the decision that caused the issue</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan correct 01HXRCD3E4F5G6H7I8J9K0L1 \
    <span style="color: cyan;">--mode</span> revert \
    <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">"The connection pool size change caused the outage. \
                Keep the pool at 20 connections maximum and add \
                connection health checks instead."</span> <span style="color: cyan;">--yes</span>

╭─ Correction ──────────────────────────────────────────────╮
│ <span style="color: #5599ff; font-weight: 600;">Mode:</span> revert                                              │
│ <span style="color: yellow; font-weight: 600;">Impact:</span> 1 decision, 0 child plans, 2 artifacts            │
│ <span style="color: #66cc66; font-weight: 600;">New Decision:</span> 01HXRCCORR1A2B3C4D5                         │
│ <span style="color: magenta; font-weight: 600;">Corrects:</span> 01HXRCD3E4F5G6H7I8J9K0L1                        │
│ <span style="color: #5599ff; font-weight: 600;">Attempt:</span> 2                                                │
╰───────────────────────────────────────────────────────────╯

╭─ Affected Subtree ──────────────╮
│ <span style="color: yellow; font-weight: 600;">Decisions Invalidated:</span> 1        │
│ <span style="color: yellow; font-weight: 600;">Child Plans Rolled Back:</span> 0      │
│ <span style="color: yellow; font-weight: 600;">Artifacts Archived:</span> 2           │
│ <span style="color: #5599ff; font-weight: 600;">Unaffected Decisions:</span> 4         │
╰─────────────────────────────────╯

╭─ Sandbox Rollback ──────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Checkpoint:</span> checkpoint_01HXRCP1     │
│ <span style="color: #5599ff; font-weight: 600;">Files Reverted:</span> 2                   │
│ <span style="color: #66cc66; font-weight: 600;">Status:</span> restored                    │
╰─────────────────────────────────────╯

╭─ Recompute ───────────╮
│ <span style="color: yellow; font-weight: 600;">Queued:</span> 1 re-execute  │
│ <span style="color: #66cc66; font-weight: 600;">ETA:</span> 2m               │
╰───────────────────────╯

╭─ History ───────────────────────────────────────────────╮
│ - Original decision superseded                          │
│ - Prior artifacts archived for comparison               │
│ - agents plan diff <span style="color: cyan;">--correction</span> 01HXRCCORR1A2B3C4D5     │
╰─────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Correction applied — re-executing affected subtree
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># The affected subtree is re-executed. Review the new changes.</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan diff <span style="color: cyan;">--correction</span> 01HXRCCORR1A2B3C4D5

╭─ Correction Diff ────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Correction:</span> 01HXRCCORR1A2B3C4D5                      │
│ <span style="color: #5599ff; font-weight: 600;">Original Decision:</span> 01HXRCD3E4F5G6H7I8J9K0L1          │
│ <span style="color: #5599ff; font-weight: 600;">Mode:</span> revert                                         │
│ <span style="color: yellow; font-weight: 600;">Files Changed:</span> 3                                     │
│ <span style="color: #66cc66; font-weight: 600;">New Insertions:</span> 32                                   │
│ <span style="color: #ff6666; font-weight: 600;">New Deletions:</span> 4                                     │
╰──────────────────────────────────────────────────────╯

╭─ Comparison ─────────────────────────────────────────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">File</span>                      <span style="color: cyan; font-weight: 600;">Before (original)</span>   <span style="color: cyan; font-weight: 600;">After (corrected)</span>          │
│ <span style="opacity: 0.7;">────────────────────────  ──────────────────  ──────────────────────</span>     │
│ src/db/pool_config.py     +14 -6 (pool=100)  +8 -2 (pool=20, checks)     │
│ src/db/health_check.py    +18 -0 (basic)     +24 -0 (robust checks)      │
│ config/database.toml      +2 -2 (pool=100)   (unchanged — pool=20)       │
╰──────────────────────────────────────────────────────────────────────────╯

╭─ Patch Preview (corrected vs original) ───────────────────────╮
│ <span style="opacity: 0.7;">--- a/src/db/pool_config.py (original)</span>                        │
│ <span style="opacity: 0.7;">+++ b/src/db/pool_config.py (corrected)</span>                       │
│ <span style="color: cyan;">@@ -8,6 +8,10 @@</span>                                              │
│ <span style="color: #ff6666;">- POOL_SIZE = 100</span>                                             │
│ <span style="color: #ff6666;">- POOL_MAX_OVERFLOW = 50</span>                                      │
│ <span style="color: #66cc66;">+ POOL_SIZE = 20</span>                                              │
│ <span style="color: #66cc66;">+ POOL_MAX_OVERFLOW = 10</span>                                      │
│ <span style="color: #66cc66;">+ POOL_PRE_PING = True</span>                                        │
│ <span style="color: #66cc66;">+ POOL_HEALTH_CHECK_INTERVAL = 30</span>                             │
│ <span style="opacity: 0.7;">--- a/src/db/health_check.py (original)</span>                       │
│ <span style="opacity: 0.7;">+++ b/src/db/health_check.py (corrected)</span>                      │
│ <span style="color: cyan;">@@ -1,18 +1,24 @@</span>                                             │
│ <span style="color: #66cc66;">+ # Added: connection validation, stale connection eviction,</span>  │
│ <span style="color: #66cc66;">+ # periodic health probes, and circuit breaker pattern</span>       │
│   <span style="opacity: 0.7;">...</span>                                                         │
╰───────────────────────────────────────────────────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Correction diff generated
</code></pre></div>

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># Re-apply with the fix</span>
<span style="color: #66cc66; font-weight: 600;">$</span> <span style="color: cyan; font-weight: 600;">agents</span> plan apply <span style="color: cyan;">--yes</span> 01HXRCF1G2H3I4J5K6L7M8N9O0

╭─ Apply Summary ──────────────────────────╮
│ <span style="color: cyan; font-weight: 600;">Plan:</span> 01HXRCF1G2H3I4J5K6L7M8N9O0         │
│ <span style="color: #5599ff; font-weight: 600;">Artifacts:</span> 3 files updated               │
│ <span style="color: yellow; font-weight: 600;">Changes:</span> 32 insertions, 4 deletions      │
│ <span style="color: #5599ff; font-weight: 600;">Project:</span> local/api-service               │
│ <span style="color: #66cc66; font-weight: 600;">Applied At:</span> 2026-02-11 09:02             │
╰──────────────────────────────────────────╯

╭─ Validation ───────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Tests:</span> passed (31/31)          │
│ <span style="color: #66cc66; font-weight: 600;">Lint:</span> passed (0 warnings)      │
│ <span style="color: #66cc66; font-weight: 600;">Type Check:</span> passed (0 errors)  │
│ <span style="color: #66cc66; font-weight: 600;">Health Check:</span> passed           │
│ <span style="color: #66cc66; font-weight: 600;">Duration:</span> 18.6s                │
╰────────────────────────────────╯

╭─ Sandbox Cleanup ─────────╮
│ <span style="color: #66cc66; font-weight: 600;">Worktree:</span> removed         │
│ <span style="color: #66cc66; font-weight: 600;">Branch:</span> merged to main    │
│ <span style="color: #5599ff; font-weight: 600;">Checkpoint:</span> archived      │
╰───────────────────────────╯

╭─ Plan Lifecycle ──────────────────────────╮
│ <span style="color: #66cc66; font-weight: 600;">Phase:</span> applied                            │
│ <span style="color: #66cc66; font-weight: 600;">State:</span> complete                           │
│ <span style="color: #5599ff; font-weight: 600;">Total Duration:</span> 00:32:02 (incl. rollback) │
│ <span style="color: yellow; font-weight: 600;">Total Cost:</span> $0.118                        │
│ <span style="color: #5599ff; font-weight: 600;">Decisions Made:</span> 7 (1 corrected)           │
│ <span style="color: #5599ff; font-weight: 600;">Child Plans:</span> 0                            │
╰───────────────────────────────────────────╯

╭─ Next Steps ──────╮
│ - Review git diff │
│ - Commit changes  │
╰───────────────────╯

<span style="color: #66cc66; font-weight: 600;">✓ OK</span> Changes applied
</code></pre></div>

## Architecture

This section provides the complete architectural blueprint for CleverAgents. It defines the system's structural composition, technology choices, layer boundaries, data flow, and operational characteristics. An implementor should be able to build the entire system from this section combined with the behavioral specification above.

### Architecture Overview

CleverAgents is architected as a **layered, event-driven application** following Domain-Driven Design (DDD) principles with clean architecture boundaries. The system is organized into four primary layers — Presentation, Application, Domain, and Infrastructure — with strict dependency rules: outer layers depend on inner layers, never the reverse. Cross-cutting concerns (logging, configuration, security) are handled through dependency injection and aspect-oriented patterns.

The architecture supports two deployment modes:

1. **Local Mode**: A single-process CLI application where all components run in the same Python process. The CLI is the primary entry point, the database is SQLite, and all resources are local.
2. **Server Mode**: A multi-user service where the CLI acts as a thin client communicating with a remote server over HTTPS. The server hosts shared storage, namespace resolution, and remote plan execution.

Both modes share the same domain model and application layer. The infrastructure layer provides swappable implementations for each deployment target.

#### High-Level Component Diagram

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                          Presentation Layer                                  │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌──────────────┐  ┌────────────┐  │
│  │   CLI   │  │   TUI   │  │   Web   │  │  IDE Plugin  │  │  REST API  │  │
│  │ (Typer) │  │(Textual)│  │(Textual │  │  (Language   │  │ (uvicorn/  │  │
│  │         │  │         │  │  Web)   │  │   Server)    │  │  FastAPI)  │  │
│  └────┬────┘  └────┬────┘  └────┬────┘  └──────┬───────┘  └─────┬──────┘  │
│       │            │            │               │                │          │
│       └────────────┴────────────┴───────────────┴────────────────┘          │
│                                    │                                         │
├────────────────────────────────────┼─────────────────────────────────────────┤
│                          Application Layer                                   │
│  ┌────────────────────┐  ┌─────────────────────┐  ┌──────────────────────┐  │
│  │  Service Facade    │  │  Workflow Engine     │  │  Event Bus           │  │
│  │  ┌──────────────┐  │  │  ┌───────────────┐  │  │  ┌────────────────┐  │  │
│  │  │PlanService   │  │  │  │PlanLifecycle  │  │  │  │StructuredLog   │  │  │
│  │  │ProjectService│  │  │  │SessionWorkflow│  │  │  │EventEmitter    │  │  │
│  │  │ActorService  │  │  │  │CorrectionFlow │  │  │  │MetricsCollector│  │  │
│  │  │ContextService│  │  │  │MergeWorkflow  │  │  │  └────────────────┘  │  │
│  │  │ToolService   │  │  │  └───────────────┘  │  │                      │  │
│  │  │SkillService  │  │  │                     │  │                      │  │
│  │  │ResourceSvc   │  │  │                     │  │                      │  │
│  │  └──────────────┘  │  └─────────────────────┘  └──────────────────────┘  │
│  └────────────────────┘                                                      │
│       │                                                                      │
│  ┌────────────────────────────────────────────────────────────────────────┐  │
│  │  DI Container (dependency-injector DeclarativeContainer)               │  │
│  └────────────────────────────────────────────────────────────────────────┘  │
│                                    │                                         │
├────────────────────────────────────┼─────────────────────────────────────────┤
│                            Domain Layer                                      │
│  ┌──────────────────────┐  ┌─────────────────────┐  ┌────────────────────┐  │
│  │  Domain Models       │  │  Domain Services     │  │  Domain Events     │  │
│  │  ┌────────────────┐  │  │  ┌───────────────┐  │  │  ┌──────────────┐  │  │
│  │  │Plan            │  │  │  │InvariantEnfrc │  │  │  │PlanCreated   │  │  │
│  │  │Decision        │  │  │  │AutonomyCtrl  │  │  │  │PhaseChanged  │  │  │
│  │  │Project         │  │  │  │ContextBuilder│  │  │  │DecisionMade  │  │  │
│  │  │Resource        │  │  │  │MergeResolver │  │  │  │ToolInvoked   │  │  │
│  │  │Actor           │  │  │  └───────────────┘  │  │  │ApplyCompleted│  │  │
│  │  │Action          │  │  │                     │  │  │CorrectionReq │  │  │
│  │  │Tool / Skill    │  │  │  Repository Ifaces  │  │  └──────────────┘  │  │
│  │  │Session         │  │  │  (Protocol classes) │  │                    │  │
│  │  │Invariant       │  │  │                     │  │                    │  │
│  │  │AutomationProf  │  │  │                     │  │                    │  │
│  │  │Checkpoint      │  │  │                     │  │                    │  │
│  │  │CorrectionAtmpt │  │  │                     │  │                    │  │
│  │  └────────────────┘  │  └─────────────────────┘  └────────────────────┘  │
│  └──────────────────────┘                                                    │
│                                    │                                         │
├────────────────────────────────────┼─────────────────────────────────────────┤
│                         Infrastructure Layer                                 │
│  ┌──────────────┐ ┌─────────────┐ ┌──────────────┐ ┌──────────────────────┐│
│  │  Database     │ │  Indexing    │ │  Sandbox     │ │  LLM / AI Runtime   ││
│  │  ┌────────┐  │ │  ┌───────┐  │ │  ┌────────┐  │ │  ┌──────────────┐   ││
│  │  │SQLite  │  │ │  │Tantivy│  │ │  │GitWrktree│ │ │  │LangChain     │   ││
│  │  │SQLAlch.│  │ │  │FAISS  │  │ │  │FsCopy   │  │ │  │LangGraph     │   ││
│  │  │Alembic │  │ │  │Neo4j  │  │ │  │TxnRollbk│  │ │  │ProviderReg   │   ││
│  │  │UoW     │  │ │  │Qdrant │  │ │  │NoOp     │  │ │  │RxPY Bridge   │   ││
│  │  └────────┘  │ │  │RDFLib │  │ │  └────────┘  │ │  │MCP SDK       │   ││
│  └──────────────┘ │  └───────┘  │ └──────────────┘ │  └──────────────┘   ││
│                   └─────────────┘                   └──────────────────────┘│
│  ┌───────────────────────┐ ┌────────────────────────────────────────────┐   │
│  │  External Integrations│ │  File System / OS                          │   │
│  │  ┌─────────────────┐  │ │  ┌──────────┐ ┌──────────┐ ┌───────────┐ │   │
│  │  │MCP Servers      │  │ │  │Watchdog  │ │Git CLI   │ │OS Process │ │   │
│  │  │Agent Skills Std │  │ │  │File I/O  │ │Subprocess│ │Signals    │ │   │
│  │  │REST/gRPC Clients│  │ │  └──────────┘ └──────────┘ └───────────┘ │   │
│  │  └─────────────────┘  │ └────────────────────────────────────────────┘   │
│  └───────────────────────┘                                                   │
└─────────────────────────────────────────────────────────────────────────────┘
```

#### Architectural Principles

1. **Hexagonal Architecture (Ports and Adapters)**: The domain layer defines abstract repository interfaces (ports). The infrastructure layer provides concrete implementations (adapters). This allows swapping SQLite for PostgreSQL, FAISS for Qdrant, or local execution for remote server execution without touching domain logic.

2. **Command Query Responsibility Segregation (CQRS)**: Write operations (plan creation, decision recording, resource modification) flow through command handlers that enforce invariants and emit domain events. Read operations (plan status, decision tree visualization, context queries) use optimized read paths that may bypass the ORM for performance.

3. **Event-Driven Architecture**: All significant state changes emit domain events through a structured event bus. Events flow through RxPY reactive streams for real-time processing and through the structured logging pipeline for persistence. This enables decoupled observability, audit logging, and future webhook/notification systems.

4. **Dependency Injection**: All service dependencies are wired through a `DeclarativeContainer` (from the `dependency-injector` library). This eliminates hidden coupling, enables testing with mock implementations, and supports runtime reconfiguration (e.g., switching providers).

5. **Convention over Configuration**: Default behavior requires zero configuration. For entity registration commands, YAML configuration files are the complete definition (no CLI overrides). For runtime commands (e.g., `plan use`), CLI flags may override entity defaults. Environment variables can be interpolated into configuration files via `${ENV_VAR}` syntax. The resolution chain depends on context: entity registration uses config-file-only semantics, while runtime commands support per-invocation CLI overrides of entity defaults.

#### Data Flow: Plan Lifecycle

The following diagram traces data flow through the system during a complete plan lifecycle:

```
User                CLI              Application         Domain            Infrastructure
 │                   │                   │                  │                    │
 │  plan use         │                   │                  │                    │
 │──────────────────>│                   │                  │                    │
 │                   │  PlanService      │                  │                    │
 │                   │  .create_plan()   │                  │                    │
 │                   │──────────────────>│                  │                    │
 │                   │                   │  Plan(phase=     │                    │
 │                   │                   │  strategize)     │                    │
 │                   │                   │─────────────────>│                    │
 │                   │                   │                  │  PlanRepository    │
 │                   │                   │                  │  .save(plan)       │
 │                   │                   │                  │───────────────────>│
 │                   │                   │                  │                    │
 │                   │                   │  InvariantEnfrc  │                    │
 │                   │                   │  .reconcile()    │                    │
 │                   │                   │─────────────────>│                    │
 │                   │                   │                  │                    │
 │                   │                   │  AutonomyCtrl    │                    │
 │                   │                   │  .should_proceed │                    │
 │                   │                   │─────────────────>│                    │
 │                   │                   │                  │                    │
 │                   │                   │  [if auto]       │                    │
 │                   │                   │  StrategyActor   │                    │
 │                   │                   │  .invoke()       │                    │
 │                   │                   │─────────────────>│                    │
 │                   │                   │                  │  LangGraph         │
 │                   │                   │                  │  StateGraph.invoke │
 │                   │                   │                  │───────────────────>│
 │                   │                   │                  │                    │
 │                   │                   │                  │  ContextBuilder    │
 │                   │                   │                  │  .build_hot_ctx()  │
 │                   │                   │                  │───────────────────>│
 │                   │                   │                  │  [FAISS/Tantivy]   │
 │                   │                   │                  │<───────────────────│
 │                   │                   │                  │                    │
 │                   │                   │                  │  LLM Provider      │
 │                   │                   │                  │  .generate()       │
 │                   │                   │                  │───────────────────>│
 │                   │                   │                  │<───────────────────│
 │                   │                   │                  │                    │
 │                   │                   │  Decision[]      │                    │
 │                   │                   │<─────────────────│                    │
 │                   │                   │                  │  DecisionRepo      │
 │                   │                   │                  │  .save_batch()     │
 │                   │                   │                  │───────────────────>│
 │                   │                   │                  │                    │
 │                   │                   │  [Execute phase] │                    │
 │                   │                   │  SandboxManager  │                    │
 │                   │                   │  .create()       │                    │
 │                   │                   │─────────────────>│                    │
 │                   │                   │                  │  GitWorktree       │
 │                   │                   │                  │  .create_worktree()│
 │                   │                   │                  │───────────────────>│
 │                   │                   │                  │                    │
 │                   │                   │  ExecutionActor  │                    │
 │                   │                   │  .invoke(sandbox)│                    │
 │                   │                   │─────────────────>│                    │
 │                   │                   │                  │  Tool calls via    │
 │                   │                   │                  │  SkillRegistry     │
 │                   │                   │                  │───────────────────>│
 │                   │                   │                  │                    │
 │                   │                   │  ChangeSet       │                    │
 │                   │                   │<─────────────────│                    │
 │                   │                   │                  │                    │
 │                   │                   │  [Apply phase]   │                    │
 │                   │                   │  Validation      │                    │
 │                   │                   │  .run_all()      │                    │
 │                   │                   │─────────────────>│                    │
 │                   │                   │                  │  Subprocess        │
 │                   │                   │                  │  .run(commands)    │
 │                   │                   │                  │───────────────────>│
 │                   │                   │                  │                    │
 │                   │                   │  SandboxManager  │                    │
 │                   │                   │  .commit()       │                    │
 │                   │                   │─────────────────>│                    │
 │                   │                   │                  │  git merge         │
 │                   │                   │                  │───────────────────>│
 │                   │                   │                  │                    │
 │  ✓ OK Applied     │                  │                  │                    │
 │<──────────────────│                   │                  │                    │
```

### Technical Stack

This section enumerates every technology choice in the CleverAgents stack, organized by functional area. Version constraints are minimum versions; newer compatible versions are acceptable.

#### Core Runtime

| Technology | Version | Role | Rationale |
|---|---|---|---|
| **Python** | >= 3.13 | Primary language | Type hint maturity, async/await, pattern matching, performance improvements in 3.13. The entire codebase is Python-only for consistency and LLM ecosystem alignment. |
| **Hatchling** | >= 1.21.0 | PEP 517 build backend | Lightweight, standards-compliant build system. Produces wheels and sdists without complex configuration. |
| **uv** | >= 0.8.0 | Package installer and resolver | 10-100x faster than pip. Used in CI, Docker builds, and Nox sessions for dependency installation. Drop-in replacement for pip with full PEP 723 support. |

#### CLI and Presentation

| Technology | Version | Role | Rationale |
|---|---|---|---|
| **Typer** | >= 0.9.0 | CLI framework | Built on Click with automatic help generation, type inference from Python type hints, and Rich integration for styled output. Supports nested command groups matching the `agents <noun> <verb>` pattern. |
| **Rich** | (transitive via Typer) | Terminal rendering | Provides Panel, Table, Tree, Syntax, Progress, Spinner, and Markdown rendering used by all output formats except `plain` and structured (`json`/`yaml`). |
| **Textual** | (future) | TUI framework | Built by the Rich maintainers. Provides a reactive terminal UI framework that can be served as a web app via Textual Web, enabling the "single UI codebase" strategy for TUI, Web, and IDE plugin. |

#### LLM and AI Runtime

| Technology | Version | Role | Rationale |
|---|---|---|---|
| **LangChain** | >= 0.2.14 | LLM abstraction layer | Provider-agnostic interface for chat models, embeddings, output parsing, prompt templates, and tool calling. The `BaseLanguageModel` protocol enables swapping providers without changing application code. |
| **LangGraph** | (transitive) | Stateful workflow orchestration | `StateGraph` with conditional edges, checkpointing (`MemorySaver`), and streaming execution. Used for the plan generation graph (`load_context -> analyze -> generate -> validate`) and auto-debug graph. |
| **LangChain Provider Packages** | varies | LLM provider integrations | `langchain-openai` (>= 0.2.0), `langchain-google-genai` (>= 0.2.0), `langchain-anthropic`, `langchain-groq`, `langchain-together`, `langchain-cohere`. Each provides a `ChatModel` implementation. |
| **LangChain Community** | >= 0.2.14 | Community integrations | FAISS vector store, FakeListLLM/FakeEmbeddings for testing. |
| **RxPY** | >= 3.2.0 | Reactive stream processing | `Subject`, `BehaviorSubject`, `ReplaySubject`, and operators (`map`, `filter`, `flat_map`, `debounce`, `throttle`, `scan`) for real-time event routing between actors, stream-to-graph bridging, and backpressure management. |
| **MCP SDK** | >= 1.4.0 | Model Context Protocol | Client SDK for communicating with MCP servers. Enables CleverAgents to discover and invoke tools exposed by any MCP-compliant server. |

#### Data and Persistence

| Technology | Version | Role | Rationale |
|---|---|---|---|
| **SQLite** | (system) | Primary database | Zero-configuration, file-based, ACID-compliant. Sufficient for local mode; supports WAL mode for concurrent reads during plan execution. For server mode, the infrastructure layer swaps in PostgreSQL via the same SQLAlchemy interface. |
| **SQLAlchemy** | (transitive via Alembic) | ORM and database abstraction | Declarative model mapping, session management, Unit of Work pattern, and dialect abstraction enabling database portability. |
| **Alembic** | >= 1.13.1 | Database migrations | Version-controlled schema migrations with upgrade/downgrade support. Migrations are auto-applied on first run and during `agents init`. |
| **python-ulid** | >= 2.7.0 | ID generation | ULID generation for plans, decisions, resources, and correction attempts. ULIDs are lexicographically sortable by creation time, enabling efficient time-range queries without separate timestamp indexes. |

#### Indexing and Code Intelligence

| Technology | Version | Role | Rationale |
|---|---|---|---|
| **Tantivy** (via tantivy-py) | configurable | Full-text search | Rust-based search engine providing sub-millisecond full-text search across project resources. Used for keyword-based code search during context building. Alternative: SQLite FTS5 for zero-dependency installations. |
| **FAISS** (faiss-cpu) | >= 1.7.4 | Vector similarity search | Facebook AI Similarity Search for semantic code search. Indexes embedding vectors generated from project files. Supports approximate nearest neighbor search for fast retrieval during context building. |
| **Qdrant** | configurable | Vector search (alternative) | External vector database for production deployments requiring horizontal scaling, persistence, and filtering. Connected via `qdrant-client`. |
| **Neo4j** | configurable | Knowledge graph | Graph database for structural code relationships (class hierarchies, call graphs, dependency trees). Enables queries like "find all callers of function X" during Strategize. Alternative: `rdflib` for in-process graph queries. |
| **rdflib** | >= 7.1.4 | In-process graph store | Python RDF library for lightweight structural code analysis without external dependencies. Stores RDF triples representing code relationships. |
| **OpenAI Embeddings** | configurable | Vector generation | Default embedding provider (`text-embedding-3-small`). Alternative providers: Anthropic, local sentence-transformers models via `index.embedding.provider` config. |

#### Configuration and Validation

| Technology | Version | Role | Rationale |
|---|---|---|---|
| **Pydantic** | >= 2.7.0 | Data validation and modeling | All domain models, configuration objects, and API schemas use Pydantic v2 for runtime validation, JSON Schema generation, and serialization. Provides type-safe data boundaries between layers. |
| **Pydantic Settings** | >= 2.11.0 | Environment configuration | `BaseSettings` subclasses for environment variable loading with the `CLEVERAGENTS_` prefix, `.env` file support, and nested model resolution. Implements the four-tier configuration resolution chain. |
| **Jinja2** | >= 3.1.0 | Template rendering | Used for actor system prompts, YAML configuration interpolation, and prompt template rendering. Supports `{{ context.* }}` variable expansion with sandboxed execution. |
| **TOML** | (stdlib tomllib) | Configuration file format | Global configuration uses TOML for its native support of nested tables, which maps naturally to the dot-separated hierarchical key structure. Python 3.13 includes `tomllib` in stdlib. |
| **YAML** | (via PyYAML) | Entity configuration format | All entity definitions (actors, skills, tools, actions, resource types, automation profiles) use YAML as the canonical human-authored format. JSON is accepted as valid YAML. |

#### Testing

| Technology | Version | Role | Rationale |
|---|---|---|---|
| **Behave** | >= 1.2.6 | BDD feature tests | Gherkin `.feature` files describe behavioral scenarios in natural language. Step implementations exercise the full application stack. Custom `behave-parallel` runner enables parallel execution via `ProcessPoolExecutor`. |
| **Robot Framework** | >= 7.3.2 | Integration tests | Keyword-driven integration tests for end-to-end CLI workflows. `robotframework-pabot` enables parallel suite execution. |
| **pytest** | >= 8.0.0 | Unit tests | Standard Python test framework for unit-level testing with fixtures, parametrization, and plugin support. |
| **pytest-asyncio** | >= 0.23.0 | Async test support | Enables `async def test_*` functions for testing async LangGraph workflows and RxPY stream operations. |
| **pytest-cov / coverage** | >= 7.11.0 | Coverage reporting | Target: 85% line coverage. HTML and XML reports generated by Nox sessions. Coverage gates enforce minimum thresholds in CI. |
| **Hypothesis** | >= 6.136.6 | Property-based testing | Generates randomized test inputs for invariant verification, particularly useful for testing decision tree operations, merge strategies, and context tier boundaries. |
| **ASV (Airspeed Velocity)** | >= 0.6.5 | Performance benchmarks | Tracks plan generation latency, CLI startup time, and indexing throughput across commits. Prevents performance regressions. |

#### Code Quality

| Technology | Version | Role | Rationale |
|---|---|---|---|
| **Ruff** | >= 0.1.0 | Linting and formatting | Single tool replacing Black, Flake8, isort, and pyupgrade. Rules: E, F, W, B, UP, I, SIM, RUF. Line length: 88. Double quotes. 4-space indent. |
| **Pyright** | >= 1.1.350 | Static type checking | Strict mode type checking for the entire codebase. Catches type errors at development time rather than runtime. Configured via `pyrightconfig.json`. |

#### Infrastructure and Deployment

| Technology | Version | Role | Rationale |
|---|---|---|---|
| **Docker** | multi-stage | Containerization | Production image uses `python:3.13-slim` with multi-stage build. Non-root user (`appuser`, uid 1000). Entrypoint: `python -m cleveragents`. |
| **Helm** | (chart) | Kubernetes deployment | Helm chart in `k8s/` directory for server mode deployment. Linted and template-tested in CI. |
| **Nox** | >= 2025.4.22 | Task automation | Session-based task runner for lint, test, build, docs, benchmarks, and coverage. Uses `uv` as the virtual environment backend for fast session creation. |
| **Forgejo CI** | (workflow) | Continuous integration | Self-hosted Forgejo instance with GitHub Actions-compatible workflow syntax. Pipeline: lint -> typecheck -> behave (matrix 3.11/3.12/3.13) -> build -> docker -> helm. |

#### Monitoring and Observability

| Technology | Version | Role | Rationale |
|---|---|---|---|
| **structlog** | >= 24.4.0 | Structured logging | JSON-structured log output with context binding (plan_id, decision_id, actor_name, tool_name). Enables log aggregation, filtering, and correlation across complex plan hierarchies. |
| **LangSmith** | (optional) | LLM observability | Optional integration for tracing LLM calls, token usage, latency, and cost. Configured via `CLEVERAGENTS_LANGSMITH_*` environment variables. Syncs to `LANGCHAIN_TRACING_V2`. |

#### Additional Libraries

| Technology | Version | Role | Rationale |
|---|---|---|---|
| **dependency-injector** | >= 4.41.0 | DI container | `DeclarativeContainer` with `Singleton`, `Factory`, and `Configuration` providers. Wires all services, repositories, and infrastructure components. |
| **watchdog** | >= 4.0.0 | File system monitoring | Watches project resource directories for changes. Triggers automatic re-indexing when `index.auto-reindex` is enabled. |
| **numpy** | >= 2.1.0 | Numerical computing | Vector operations for embedding similarity computation, confidence score aggregation, and distance calculations in the vector store layer. |
| **uvicorn** | >= 0.30.1 | ASGI server | HTTP server for server mode REST API. Serves the FastAPI application for remote plan execution, namespace resolution, and multi-user collaboration. |

### ACMS (Advanced Context Management System)

This section provides the complete architectural design of the Advanced Context Management System (ACMS). For the conceptual overview, core data types, CRP skill definition, strategy protocol, and plan lifecycle integration, see **Core Concepts > Advanced Context Management System (ACMS)**.

#### Architectural Overview

```
                                  +-------------------------------+
                                  |        Actor / Skill          |
                                  |  (issues ContextRequests via  |
                                  |   Context Request Protocol)   |
                                  +---------------+---------------+
                                                  |
                                                  v
                                  +-------------------------------+
                                  |     Strategy Coordinator      |
                                  |        & Fusion Engine        |
                                  |  (merges results from all     |
                                  |   active strategies, dedupes, |
                                  |   fits to token budget)       |
                                  +------+-------+-------+-------+
                                         |       |       |
                          +--------------+  +----+----+  +---------------+
                          |                 |         |                  |
                          v                 v         v                  v
                   +-----------+    +-----------+ +-----------+  +-----------+
                   | Strategy  |    | Strategy  | | Strategy  |  | Strategy  |
                   |   ARCE    |    |  Simple   | | Breadth/  |  |  Custom   |
                   | (graph-   |    | (keyword/ | | Depth     |  | (user-    |
                   |  aware)   |    |  embed)   | | Navigator |  |  defined) |
                   +-----------+    +-----------+ +-----------+  +-----------+
                          |              |             |                |
                          v              v             v                v
                   +----------------------------------------------------------+
                   |              Backend Abstraction Layer (BAL)              |
                   |  +------------+  +------------+  +-------------------+   |
                   |  | ScopedView |  | ScopedView |  |    ScopedView     |   |
                   |  | (Text DB)  |  | (Vector DB)|  |    (Graph DB)     |   |
                   |  +-----+------+  +-----+------+  +--------+----------+  |
                   +--------|---------------|-------------------|-------------+
                            |               |                   |
                            v               v                   v
                   +----------------------------------------------------------+
                   |               Physical Data Stores                       |
                   |  +-----------+  +-----------+  +---------------------+   |
                   |  | Tantivy / |  | FAISS /   |  | Blazegraph / Jena / |   |
                   |  | SQLite    |  | Qdrant /  |  | Neo4j / Stardog     |   |
                   |  | FTS       |  | Weaviate  |  | (UKO triples)       |   |
                   |  +-----------+  +-----------+  +---------------------+   |
                   +----------------------------------------------------------+
                                              |
                                              v
                   +----------------------------------------------------------+
                   |                  Resource Registry                       |
                   |        (physical/virtual resources, DAG links)           |
                   +----------------------------------------------------------+
```

**Key Design Principles:**

1. **Strategy-agnostic framework**: The framework itself has no opinion about *how* context is assembled. That is the job of strategies. The framework provides the request protocol, the data plumbing, and the fusion engine.
2. **Dynamic budget**: The token budget for context assembly may change on every invocation. Strategies receive the current budget and must respect it. The coordinator enforces the budget as a hard ceiling.
3. **Hierarchical by default**: Every context assembly occurs within the context of a plan hierarchy. The system tracks parent context and provides progressive focusing primitives.
4. **Provenance everywhere**: Every piece of context delivered to an actor can be traced back to a specific resource, a specific location within that resource, a specific revision, and a specific UKO node.
5. **Pluggable Architecture**: Every component can be extended or replaced.
6. **Progressive Enhancement**: System works with basic text search, enhances with advanced features.
7. **Eager Indexing**: Indices are built immediately when resources are added and kept continuously up-to-date.
8. **Agent Awareness**: Agents understand available indices through skills.
9. **Real-time Synchronization**: Indices update immediately as code changes.

#### Universal Knowledge Ontology (UKO)

##### Design Philosophy

The UKO is designed around a single principle: **everything that an actor might want to know about a resource should be representable as a node in the knowledge graph, at any level of detail, with provenance back to the originating resource.**

The ontology uses an inheritance hierarchy so that:

- **Layer 0** defines universal concepts that apply to any information (code, docs, data, infra).
- **Layer 1** specializes for general software concepts (modules, callables, types).
- **Layer 2** specializes for paradigm-specific concepts (OO, functional, procedural).
- **Layer 3** specializes for language-specific concepts (Python's decorators, TypeScript's interfaces, Rust's lifetimes).

This layering means a strategy that operates at Layer 0 can work with *any* resource, while a strategy that operates at Layer 3 can provide language-specific intelligence. The `breadth-depth-navigator` strategy typically operates at Layers 0-1 (universal graph traversal), while `arce` leverages all layers.

##### Ontology Hierarchy

The UKO defines five namespace prefixes:

| Prefix | IRI | Purpose |
|--------|-----|---------|
| `uko:` | `https://cleveragents.ai/ontology/uko#` | Layer 0: Universal foundation |
| `uko-code:` | `https://cleveragents.ai/ontology/uko/code#` | Layer 1: General software |
| `uko-oo:` | `https://cleveragents.ai/ontology/uko/oo#` | Layer 2: Object-oriented paradigm |
| `uko-func:` | `https://cleveragents.ai/ontology/uko/func#` | Layer 2: Functional paradigm |
| `uko-proc:` | `https://cleveragents.ai/ontology/uko/proc#` | Layer 2: Procedural paradigm |
| `uko-py:` | `https://cleveragents.ai/ontology/uko/py#` | Layer 3: Python-specific |
| `uko-ts:` | `https://cleveragents.ai/ontology/uko/ts#` | Layer 3: TypeScript-specific |
| `uko-rs:` | `https://cleveragents.ai/ontology/uko/rs#` | Layer 3: Rust-specific |
| `uko-java:` | `https://cleveragents.ai/ontology/uko/java#` | Layer 3: Java-specific |
| `uko-doc:` | `https://cleveragents.ai/ontology/uko/doc#` | Non-code: Documents |
| `uko-data:` | `https://cleveragents.ai/ontology/uko/data#` | Non-code: Data schemas |
| `uko-infra:` | `https://cleveragents.ai/ontology/uko/infra#` | Non-code: Infrastructure |

###### Layer 0: Universal Foundation (`uko:`)

Every UKO node, regardless of domain, is one of five base classes:

```turtle
@prefix uko: <https://cleveragents.ai/ontology/uko#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

# ── Base Classes ──────────────────────────────────────────────────
uko:InformationUnit a owl:Class ;
    rdfs:comment "The root of every UKO node. Anything that can appear in an actor's context." .

uko:Container a owl:Class ;
    rdfs:subClassOf uko:InformationUnit ;
    rdfs:comment "An information unit that contains other information units (file, module, class, section)." .

uko:Atom a owl:Class ;
    rdfs:subClassOf uko:InformationUnit ;
    rdfs:comment "A leaf-level information unit (function body, paragraph, config value)." .

uko:Annotation a owl:Class ;
    rdfs:subClassOf uko:InformationUnit ;
    rdfs:comment "Metadata attached to another information unit (comment, docstring, attribute)." .

uko:Boundary a owl:Class ;
    rdfs:subClassOf uko:InformationUnit ;
    rdfs:comment "An interface point between containers (export, API endpoint, public method signature)." .

# ── Core Relationships ────────────────────────────────────────────
uko:contains a owl:ObjectProperty ;
    rdfs:domain uko:Container ;
    rdfs:range uko:InformationUnit ;
    rdfs:comment "Parent contains child (e.g., module contains class)." .

uko:references a owl:ObjectProperty ;
    rdfs:domain uko:InformationUnit ;
    rdfs:range uko:InformationUnit ;
    rdfs:comment "Weak reference (e.g., a function mentions a type in a docstring)." .

uko:dependsOn a owl:ObjectProperty ;
    rdfs:domain uko:InformationUnit ;
    rdfs:range uko:InformationUnit ;
    rdfs:comment "Strong dependency (e.g., import, inheritance, call)." .

# ── Content Properties ────────────────────────────────────────────
uko:hasSignature a owl:DatatypeProperty ;
    rdfs:domain uko:InformationUnit ;
    rdfs:range xsd:string ;
    rdfs:comment "SIGNATURE-level rendering of this node." .

uko:hasSummary a owl:DatatypeProperty ;
    rdfs:domain uko:InformationUnit ;
    rdfs:range xsd:string ;
    rdfs:comment "SUMMARY-level rendering of this node." .

uko:hasContent a owl:DatatypeProperty ;
    rdfs:domain uko:InformationUnit ;
    rdfs:range xsd:string ;
    rdfs:comment "FULL-level rendering of this node." .

# ── Provenance ────────────────────────────────────────────────────
uko:sourceResource a owl:ObjectProperty ;
    rdfs:domain uko:InformationUnit ;
    rdfs:comment "The CleverAgents Resource (by ULID) this node was extracted from." .

uko:sourcePath a owl:DatatypeProperty ;
    rdfs:domain uko:InformationUnit ;
    rdfs:range xsd:string ;
    rdfs:comment "Path within the resource (e.g., file path relative to the resource root)." .

uko:sourceRange a owl:DatatypeProperty ;
    rdfs:domain uko:InformationUnit ;
    rdfs:range xsd:string ;
    rdfs:comment "Byte or line range within the source file (e.g., '42:1-87:0')." .

# ── Temporal ──────────────────────────────────────────────────────
uko:validFrom a owl:DatatypeProperty ;
    rdfs:domain uko:InformationUnit ;
    rdfs:range xsd:dateTime .

uko:validUntil a owl:DatatypeProperty ;
    rdfs:domain uko:InformationUnit ;
    rdfs:range xsd:dateTime .

uko:isCurrent a owl:DatatypeProperty ;
    rdfs:domain uko:InformationUnit ;
    rdfs:range xsd:boolean .

uko:isRevisionOf a owl:ObjectProperty ;
    rdfs:domain uko:InformationUnit ;
    rdfs:range uko:InformationUnit ;
    rdfs:comment "Links a revised node to its predecessor." .
```

###### Layer 1: Domain Specializations

**General Software (`uko-code:`)**:

```turtle
@prefix uko-code: <https://cleveragents.ai/ontology/uko/code#> .

uko-code:Module a owl:Class ;
    rdfs:subClassOf uko:Container ;
    rdfs:comment "A source code module (file, package, namespace)." .

uko-code:Callable a owl:Class ;
    rdfs:subClassOf uko:Atom ;
    rdfs:comment "Any callable unit (function, method, procedure, lambda)." .

uko-code:TypeDefinition a owl:Class ;
    rdfs:subClassOf uko:Atom ;
    rdfs:comment "A type or schema definition (class, struct, interface, enum, typedef)." .

uko-code:TestCase a owl:Class ;
    rdfs:subClassOf uko:Atom ;
    rdfs:comment "A test case or test function." .

uko-code:Import a owl:Class ;
    rdfs:subClassOf uko:Annotation ;
    rdfs:comment "An import/include/require statement." .

uko-code:hasReturnType a owl:DatatypeProperty ;
    rdfs:domain uko-code:Callable ;
    rdfs:range xsd:string .

uko-code:hasParameters a owl:DatatypeProperty ;
    rdfs:domain uko-code:Callable ;
    rdfs:range xsd:string ;
    rdfs:comment "JSON-encoded parameter list." .

uko-code:testsCallable a owl:ObjectProperty ;
    rdfs:domain uko-code:TestCase ;
    rdfs:range uko-code:Callable ;
    rdfs:comment "Links a test case to the callable it tests." .
```

**Object-Oriented (`uko-oo:`)**:

```turtle
@prefix uko-oo: <https://cleveragents.ai/ontology/uko/oo#> .

uko-oo:Class a owl:Class ;
    rdfs:subClassOf uko-code:TypeDefinition, uko:Container ;
    rdfs:comment "An OO class that contains methods and attributes." .

uko-oo:Interface a owl:Class ;
    rdfs:subClassOf uko-code:TypeDefinition, uko:Boundary ;
    rdfs:comment "An interface or abstract base class." .

uko-oo:Method a owl:Class ;
    rdfs:subClassOf uko-code:Callable .

uko-oo:Attribute a owl:Class ;
    rdfs:subClassOf uko:Atom .

uko-oo:inheritsFrom a owl:ObjectProperty ;
    rdfs:subPropertyOf uko:dependsOn ;
    rdfs:domain uko-oo:Class ;
    rdfs:range uko-oo:Class .

uko-oo:implements a owl:ObjectProperty ;
    rdfs:subPropertyOf uko:dependsOn ;
    rdfs:domain uko-oo:Class ;
    rdfs:range uko-oo:Interface .
```

**Functional (`uko-func:`)**:

```turtle
@prefix uko-func: <https://cleveragents.ai/ontology/uko/func#> .

uko-func:PureFunction a owl:Class ;
    rdfs:subClassOf uko-code:Callable .

uko-func:TypeClass a owl:Class ;
    rdfs:subClassOf uko-code:TypeDefinition, uko:Boundary .

uko-func:Monad a owl:Class ;
    rdfs:subClassOf uko-code:TypeDefinition .
```

**Non-Code Domains**:

```turtle
# Documents
@prefix uko-doc: <https://cleveragents.ai/ontology/uko/doc#> .

uko-doc:Document a owl:Class ; rdfs:subClassOf uko:Container .
uko-doc:Section a owl:Class ; rdfs:subClassOf uko:Container .
uko-doc:Paragraph a owl:Class ; rdfs:subClassOf uko:Atom .
uko-doc:CodeBlock a owl:Class ; rdfs:subClassOf uko:Atom .

# Data Schemas
@prefix uko-data: <https://cleveragents.ai/ontology/uko/data#> .

uko-data:Schema a owl:Class ; rdfs:subClassOf uko:Container .
uko-data:Table a owl:Class ; rdfs:subClassOf uko:Container .
uko-data:Column a owl:Class ; rdfs:subClassOf uko:Atom .
uko-data:Constraint a owl:Class ; rdfs:subClassOf uko:Annotation .

# Infrastructure
@prefix uko-infra: <https://cleveragents.ai/ontology/uko/infra#> .

uko-infra:Service a owl:Class ; rdfs:subClassOf uko:Container .
uko-infra:Endpoint a owl:Class ; rdfs:subClassOf uko:Boundary .
uko-infra:ConfigBlock a owl:Class ; rdfs:subClassOf uko:Container .
uko-infra:ConfigKey a owl:Class ; rdfs:subClassOf uko:Atom .
```

##### The Universal View Guarantee

Because every language-specific class ultimately inherits from Layer 0 (`uko:InformationUnit`, `uko:Container`, etc.), any strategy or query written against Layer 0 automatically works across all languages. For example:

```sparql
# "Find all containers that depend on this atom" — works for Python classes,
# TypeScript modules, Rust crates, or SQL tables.
SELECT ?container WHERE {
    ?container a uko:Container .
    ?container uko:dependsOn <target_atom> .
}
```

##### Provenance Contract

Every UKO node carries provenance back to the originating resource:

```
uko-py:class/AuthManager
    uko:sourceResource  <resource-ulid-01HXM7...>
    uko:sourcePath      "src/auth/manager.py"
    uko:sourceRange     "15:1-87:0"
    uko:validFrom       "2026-01-15T10:30:00Z"
    uko:isCurrent       true
```

This allows the Fusion Engine to generate provenance summaries in the context preamble, and allows actors to trace any piece of context back to its exact source location.

#### Temporal Data Model and Storage Tiers

##### Revision-Aware RDF

Each UKO node carries temporal metadata. When code changes, existing nodes are **not deleted** — instead, their `validUntil` is set and `isCurrent` becomes `false`, and a new node is created with `isRevisionOf` pointing to the predecessor:

```turtle
# Before code change:
uko-py:class/AuthManager_v1
    uko:isCurrent true ;
    uko:validFrom "2026-01-10T00:00:00Z"^^xsd:dateTime .

# After code change:
uko-py:class/AuthManager_v1
    uko:isCurrent false ;
    uko:validFrom "2026-01-10T00:00:00Z"^^xsd:dateTime ;
    uko:validUntil "2026-01-15T10:30:00Z"^^xsd:dateTime .

uko-py:class/AuthManager_v2
    uko:isCurrent true ;
    uko:validFrom "2026-01-15T10:30:00Z"^^xsd:dateTime ;
    uko:isRevisionOf uko-py:class/AuthManager_v1 .
```

This temporal chain is what enables the `temporal-archaeology` strategy to find patterns like "this class was refactored 3 times in the last month" or "this function's signature changed after we updated the auth library."

##### Three Storage Tiers with Temporal Alignment

| Tier | Content | Retention | Access Pattern | Temporal |
|------|---------|-----------|---------------|----------|
| **Hot** | Current UKO graph + recent embeddings + active text index | Until resource removed | Direct query via BAL | `isCurrent = true` only |
| **Warm** | Recent decision contexts, plan context snapshots | `context.tiers.warm.retention-hours` (default: 24h) | Scoped query via plan hierarchy | Current + recently-expired nodes |
| **Cold** | Archived decision contexts, historical UKO snapshots | `context.tiers.cold.retention-days` (default: 90d) | Full historical query | All temporal versions |

#### Scoped Views and Plan Subgraph Projection

##### Resource Scope Resolution

When a plan is created (via `agents plan use`), the system resolves its resource scope:

```python
class ResourceScopeResolver:
    """Determines which resources a plan can see."""

    def resolve(self, plan: Plan) -> ResourceScope:
        # 1. Get all projects this plan targets
        projects = plan.target_projects
        # 2. Collect all resources linked to those projects
        resources = set()
        for project in projects:
            resources.update(project.linked_resources)
        # 3. Expand to include child resources (DAG traversal)
        expanded = set()
        for resource in resources:
            expanded.add(resource)
            expanded.update(self.registry.get_descendants(resource))
        # 4. Apply context view filters (include/exclude)
        view = self._resolve_view(plan)
        filtered = self._apply_filters(expanded, view)
        return ResourceScope(resources=filtered, projects=projects)
```

##### UKO Subgraph Projection

Given a resource scope, the system projects only the relevant UKO subgraph:

```python
class UKOSubgraphProjector:
    """Projects the UKO graph to only include nodes from scoped resources."""

    def project(self, scope: ResourceScope,
                graph_backend: GraphBackend) -> ProjectedGraph:
        # Only include UKO nodes whose sourceResource is in scope
        return graph_backend.subgraph_by_resources(
            resource_ulids=[r.ulid for r in scope.resources],
            include_temporal=scope.temporal_scope,
        )
```

##### Scoped Backend Views

Each backend (text, vector, graph) is wrapped in a `ScopedView` that automatically filters queries to only return results from in-scope resources:

```python
class ScopedBackendView:
    """Wraps a backend to restrict queries to a resource scope."""

    def __init__(self, backend, scope: ResourceScope):
        self.backend = backend
        self.scope = scope
        self._resource_filter = {r.ulid for r in scope.resources}

    def search(self, query, **kwargs):
        # Inject the resource filter into the backend query
        results = self.backend.search(
            query,
            resource_filter=self._resource_filter,
            **kwargs,
        )
        return results
```

This is critical for multi-project isolation: a plan targeting `local/api-service` never sees resources from `local/frontend`, even if both projects share the same physical database indices.

#### Backend Abstraction Layer (BAL)

The BAL provides a uniform interface to heterogeneous data stores. Each backend type has a protocol:

##### Backend Protocols

```python
class TextBackend(Protocol):
    def search(self, query: str, *, resource_filter: set[str],
               limit: int = 20) -> list[TextResult]: ...
    def index(self, resource_ulid: str, content: str,
              metadata: dict) -> None: ...

class VectorBackend(Protocol):
    def search(self, embedding: list[float], *, resource_filter: set[str],
               limit: int = 20, threshold: float = 0.3) -> list[VectorResult]: ...
    def index(self, resource_ulid: str, chunks: list[EmbeddingChunk]) -> None: ...

class GraphBackend(Protocol):
    def query_sparql(self, sparql: str, *, resource_filter: set[str]) -> list[dict]: ...
    def add_triples(self, triples: list[Triple]) -> None: ...
    def subgraph_by_resources(self, resource_ulids: list[str],
                              include_temporal: TemporalScope) -> ProjectedGraph: ...
    def traverse(self, start_uri: str, max_hops: int,
                 edge_types: list[str], resource_filter: set[str]) -> SubGraph: ...
```

##### Unified Result Types

```python
@dataclass
class TextResult:
    resource_ulid: str
    path: str
    line_range: tuple[int, int]
    content: str
    score: float

@dataclass
class VectorResult:
    resource_ulid: str
    uko_node: str
    content: str
    similarity: float
    metadata: dict
```

#### Strategy Coordinator and Fusion Engine

The coordinator is the central orchestrator of context assembly. It receives a `ContextRequest`, determines which strategies to invoke, collects their results, and fuses them into a single, budget-respecting `AssembledContext`.

```python
class StrategyCoordinator:
    """Orchestrates multiple context strategies into unified context."""

    def assemble(self, request: ContextRequest,
                 backends: BackendSet,
                 budget: int,
                 plan_context: PlanContext) -> AssembledContext:
        # 1. Ask each strategy if it can handle this request
        candidates = [(s, s.can_handle(request, backends))
                      for s in self.strategies if s.can_handle(request, backends) > 0]
        # 2. Apply strategy preferences from the request
        candidates = self._apply_preferences(candidates, request)
        # 3. Sort by confidence * quality_score
        candidates.sort(key=lambda sc: sc[1] * sc[0].capabilities.quality_score, reverse=True)
        # 4. Allocate budget shares proportional to confidence
        budget_allocations = self._allocate_budgets(candidates, budget)
        # 5. Execute strategies (potentially in parallel)
        all_fragments = []
        with ThreadPoolExecutor() as pool:
            futures = {pool.submit(s.assemble, request, backends, alloc, plan_context): s.name
                       for (s, _), alloc in zip(candidates, budget_allocations)}
            for future in as_completed(futures):
                try:
                    all_fragments.extend(future.result(timeout=30))
                except Exception as e:
                    logger.warning(f"Strategy {futures[future]} failed: {e}")
        # 6. Fuse all fragments into final context
        return self.fusion.fuse(all_fragments, budget, plan_context)
```

##### The Fusion Engine

The fusion engine merges fragments from multiple strategies:

1. **Deduplicate**: Same UKO node / same location -- keep highest relevance score.
2. **Resolve detail conflicts**: Same item at different detail levels -- keep highest detail that fits budget.
3. **Apply hierarchical weighting**: Items closer to the plan's focus area get higher weight.
4. **Rank by composite score**: `relevance_score * strategy_quality * hierarchy_weight`.
5. **Greedy knapsack**: Fit within budget. If an item doesn't fit at FULL, try SUMMARY, then SIGNATURE.
6. **Order for coherence**: Group by resource, order by containment depth then position.
7. **Generate preamble**: Provenance summary, structure map.

#### Initial Context Assembly

Before the actor's first turn, the system assembles initial context:

```python
class InitialContextAssembler:
    """Produces the starting context for an actor invocation."""

    def assemble(self, plan: Plan, actor: Actor,
                 token_budget: int) -> AssembledContext:
        # 1. Resolve resource scope
        scope = self.scope_resolver.resolve(plan)
        # 2. Get inherited context from parent plan (if any)
        inherited = self._get_inherited_context(plan)
        # 3. Create scoped backend views
        backends = self.bal.create_scoped_views(scope)
        # 4. Build the initial context request from plan metadata
        initial_request = self._build_initial_request(plan, actor, inherited)
        # 5. Run through strategy coordinator
        result = self.coordinator.assemble(
            request=initial_request,
            backends=backends,
            budget=token_budget,
            plan_context=PlanContext(
                plan=plan,
                parent_context=inherited,
                depth_in_tree=plan.depth_in_tree,
            ),
        )
        return result
```

#### Context Inheritance Mechanism

```python
class PlanContextInheritance:
    """Manages how child plans inherit and refine parent context."""

    def compute_child_context(self, parent_plan, child_plan, parent_context):
        # 1. Determine the child's focus from the parent's decisions
        child_focus = self._extract_child_focus(parent_plan, child_plan)
        # 2. Compute depth/breadth adjustments
        depth_delta = child_plan.depth_in_tree - parent_plan.depth_in_tree
        child_detail = self._increase_detail(self._avg_detail(parent_context), depth_delta)
        child_breadth = max(1, parent_context.avg_breadth - depth_delta)
        # 3. Build the inherited context request with parent skeleton
        return ContextRequest(
            focus=child_focus,
            breadth=child_breadth,
            depth=child_detail,
            depth_gradient=True,
            metadata={
                "parent_context_hash": parent_context.context_hash,
                "parent_skeleton": self._build_skeleton(parent_context, child_focus),
                "inherited_decisions": self._relevant_parent_decisions(parent_plan, child_focus),
            },
        )
```

##### Skeleton Context Propagation

The **skeleton** is a compact, SIGNATURE-level representation of the parent's context window that is passed to every child. This ensures children always have the "big picture" available, even though they focus on a narrow area. The skeleton typically consumes 5-15% of the child's token budget.

```
Parent's hot context (32K tokens):
  ┌─ Module: src/auth/          [SUMMARY: 2K tokens]
  ├─ Module: src/core/          [SUMMARY: 2K tokens]
  ├─ Module: src/api/           [SUMMARY: 2K tokens]
  ├─ Module: src/services/      [SUMMARY: 2K tokens]
  └─ ... 12 more modules        [SUMMARY: 24K tokens]

Child's hot context (32K tokens):
  ┌─ [SKELETON from parent]     [SIGNATURE: 3K tokens]
  │   Module: src/auth/         [just header + method list]
  │   Module: src/core/         [just header + method list]
  │   Module: src/api/          [just header + method list]
  │   ... etc.
  ├─ [CHILD FOCUS AREA]         [FULL: 25K tokens]
  │   Class: AuthManager        [FULL: all methods with bodies]
  │   Class: TokenValidator     [FULL: referenced by AuthManager]
  │   Class: User               [STUB: used as parameter type]
  └─ [INHERITED DECISIONS]      [4K tokens]
      Decision: "Use async patterns for all auth operations"
      Decision: "Maintain backward compat with sync callers"
```

#### Dynamic Context Window Adaptation

The context window size may change between invocations. Different LLM providers, different models, different configurations, and even dynamic adjustments during a session can alter the available budget. The ACMS handles this seamlessly.

##### Budget Computation

```python
class ContextBudgetCalculator:
    """Computes the effective context budget for each assembly cycle."""

    def compute(self, actor: Actor, plan: Plan,
                conversation_history_tokens: int) -> int:
        # 1. Get the actor's hard context window limit
        model_limit = actor.model_config.context_window_tokens
        # 2. Reserve space for system prompt, history, tools, response
        reserved = (self._count_tokens(actor.system_prompt) +
                    conversation_history_tokens +
                    self._estimate_tool_tokens(actor.skills) +
                    actor.model_config.max_output_tokens)
        # 3. Apply the soft cap from context view policy
        soft_cap = self._resolve_view(plan).hot_max_tokens or float('inf')
        # 4. Calculate available budget
        effective_budget = max(0, min(model_limit - reserved, soft_cap))
        return effective_budget
```

##### Adaptive Behavior

When the budget changes between context assembly cycles:

1. **Budget increase**: The coordinator re-runs strategies with the expanded budget. Fragments previously compressed to SIGNATURE may be expanded to SUMMARY or FULL.
2. **Budget decrease**: The fusion engine re-applies the knapsack with the new budget, potentially compressing fragments or dropping low-relevance items.
3. **Strategies are stateless**: Each assembly cycle is independent. Strategies receive the current budget and must respect it.

##### Progressive Refinement Within a Session

As an actor makes tool calls during a session, the conversation grows and the available budget shrinks. The ACMS handles this through a **context refresh cycle** that triggers re-assembly when the budget changes by more than 30% (configurable via `context.budget.refresh_threshold`).

#### Built-in Strategy Catalogue

The ACMS ships with several built-in strategies. The ARCE pipeline is one of them, not the only one.

##### Strategy: `simple-keyword`

Basic keyword/regex text search. Works with any backend, any resource type. No graph or vector required. This is the universal fallback. Quality score: 0.3.

##### Strategy: `semantic-embedding`

Vector similarity search. Finds semantically related content even without exact keyword matches. Requires a vector backend. Quality score: 0.6.

##### Strategy: `breadth-depth-navigator`

The graph-aware strategy that uses the depth/breadth projection system. Works with the UKO graph to provide structurally-aware context at any detail level. Supports focus items, hop traversal, and detail gradients. This is the primary strategy for code-aware context. Quality score: 0.85.

##### Strategy: `arce` (Analyze, Retrieve, Contextualize, Execute)

The sophisticated multi-modal pipeline. Combines text, vector, and graph search with intent analysis and actor-type-aware patterns. This is the "kitchen sink" strategy that produces the highest quality results but requires all backends. Quality score: 0.95.

Actor-type-specific graph traversal patterns:

- **Strategy actors**: Broader, shallower traversal. Emphasis on module boundaries and dependency structures. Prioritizes `uko:Container` and `uko:Boundary` nodes.
- **Execution actors**: Narrower, deeper traversal. Emphasis on implementation details, function bodies, and test coverage. Prioritizes `uko:Atom` nodes.
- **Estimation actors**: Focus on size metrics, complexity indicators, and historical data. Prioritizes temporal data.

##### Strategy: `temporal-archaeology`

Searches the cold tier for historical patterns. Useful for understanding "what changed last time we touched this area" or "what decisions were made about this module in the past." Requires graph + cold tier access. Quality score: 0.5.

##### Strategy: `plan-decision-context`

Retrieves context from parent and ancestor plan decisions. This is how child plans "remember" what their parent decided and why. Operates on the warm/cold tiers. Quality score: 0.7.

#### Plugin Architecture for Extensibility

The system is designed for extensibility at every level:

##### Language-Specific Analyzers

```yaml
PluginSystem:
  analyzers:
    python:
      class: "PythonAnalyzer"
      features: [AST parsing, Type inference via mypy, Import resolution, Docstring extraction]
    typescript:
      class: "TypeScriptAnalyzer"
      features: [TSC-based parsing, Type extraction, Module resolution, JSDoc parsing]
    rust:
      class: "RustAnalyzer"
      features: [rust-analyzer integration, Lifetime analysis, Trait resolution, Macro expansion]
    custom_dsl:
      class: "CustomDSLAnalyzer"
      config:
        grammar: "path/to/grammar.peg"
        semantic_rules: "path/to/rules.yaml"
```

##### Index Backend Providers

```yaml
  backends:
    graph:
      - { name: "blazegraph", class: "BlazegraphBackend", features: ["SPARQL", "reasoning"] }
      - { name: "neo4j", class: "Neo4jBackend", features: ["Cypher", "APOC", "GDS"] }
    vector:
      - { name: "faiss", class: "FaissBackend", features: ["GPU acceleration", "HNSW"] }
      - { name: "qdrant", class: "QdrantBackend", features: ["filtering", "payloads"] }
  embedders:
    - { name: "openai", class: "OpenAIEmbedder", models: ["text-embedding-3-large"] }
    - { name: "local", class: "LocalEmbedder", models: ["all-MiniLM-L6-v2"] }
```

##### Adding a New UKO Vocabulary (e.g., for Terraform)

```turtle
@prefix uko-tf: <https://cleveragents.ai/ontology/uko/infra/terraform#> .

uko-tf:TerraformModule a owl:Class ;
    rdfs:subClassOf uko-infra:ConfigBlock, uko:Container .
uko-tf:Resource a owl:Class ;
    rdfs:subClassOf uko:Container .
uko-tf:Variable a owl:Class ;
    rdfs:subClassOf uko-infra:ConfigKey .
uko-tf:Output a owl:Class ;
    rdfs:subClassOf uko:Boundary .
uko-tf:provisionsOn a owl:ObjectProperty ;
    rdfs:subPropertyOf uko:dependsOn ;
    rdfs:domain uko-tf:Resource ;
    rdfs:range uko-infra:Service .
```

##### Adding a New Context Strategy

```python
class MyDomainStrategy:
    name = "my-namespace/domain-strategy"
    capabilities = StrategyCapabilities(
        uses_graph=True, uses_text=True,
        uko_levels=["uko:", "uko-tf:"],
        resource_types=["*"],
        supports_depth_breadth=True,
        quality_score=0.8,
    )

    def can_handle(self, request, backends):
        if any("terraform" in f for f in request.focus):
            return 0.9
        return 0.0

    def assemble(self, request, backends, budget, plan_context):
        # Custom logic...
        ...
```

Register via config:
```toml
[context.strategies.custom]
"my-namespace/domain-strategy" = "my_package.strategies.MyDomainStrategy"
```

#### Real-time Index Synchronization

The system maintains index freshness through immediate, proactive updates. The `UKOIndexer` produces UKO triples from resources using pluggable analyzers, and simultaneously indexes into text and vector backends:

```python
class UKOIndexer:
    """Produces UKO triples from resources using pluggable analyzers."""

    def index_resource(self, resource: Resource):
        # 1. Determine the best analyzer for this resource
        analyzer = self.analyzers.get_for_resource(resource)
        # 2. Produce UKO triples using the most specific vocabulary
        triples = analyzer.analyze(resource)
        # 3. Add provenance
        for triple in triples:
            self._add_provenance(triple, resource)
        # 4. Store in graph backend
        self.graph_backend.add_triples(triples)
        # 5. Also index into text and vector backends
        self.text_indexer.index(resource, triples)
        self.vector_indexer.index(resource, triples)
```

##### Index Lifecycle

| Stage | Trigger | Action | Result |
|-------|---------|--------|--------|
| Resource added | `agents resource add` / `agents project link-resource` | Immediate full indexing | All indices ready for instant search |
| Code changed | File modification detected | Immediate incremental update | Indices reflect latest state |
| Resource removed | `agents resource remove` / `agents project unlink-resource` | Immediate cleanup | Stale data removed, UKO nodes marked historical |
| Maintenance | Scheduled | Full reindex, consistency check | Indices verified and optimized |

##### Fallback to Traditional Search

When advanced features are unavailable, the system gracefully degrades. The strategy coordinator automatically routes to simpler strategies:

1. Try `arce` (requires all backends) -> if unavailable:
2. Try `breadth-depth-navigator` (requires graph) -> if unavailable:
3. Try `semantic-embedding` (requires vector) -> if unavailable:
4. Fall back to `simple-keyword` (requires only text search / ripgrep)

#### ACMS Performance Characteristics

##### Assembly Latency

| Operation | Target Latency | Notes |
|-----------|---------------|-------|
| Resource scope resolution | < 10ms | In-memory set operations |
| Scoped backend view creation | < 5ms | Filter injection |
| Strategy `can_handle` check (all) | < 20ms | Simple capability checks |
| `simple-keyword` assembly | < 100ms | Text search |
| `semantic-embedding` assembly | < 200ms | Vector search |
| `breadth-depth-navigator` assembly | < 500ms | Graph traversal + materialization |
| `arce` assembly | < 1s | Multi-modal search + ranking |
| `temporal-archaeology` assembly | < 2s | Cold tier queries |
| Fusion engine | < 100ms | Dedup + knapsack + ordering |
| **Total initial assembly** | **< 2s** | Parallel strategy execution |
| **Incremental refresh** | **< 500ms** | Re-compression only |

##### Indexing and Query Performance

| Metric | Performance |
|--------|------------|
| Text indexing speed | 10,000 files/minute |
| Vector indexing speed | 1,000 files/minute (with GPU) |
| Graph indexing speed | 5,000 files/minute |
| Text search query | < 100ms for 1M files |
| Vector search query | < 200ms for 10M embeddings |
| Graph traversal query | < 500ms for 3-hop queries |

##### Scalability Guarantees

- **100K+ file projects**: The scoping mechanism ensures strategies never see the full dataset. Scoped views filter at the backend level.
- **Deep plan hierarchies (10+ levels)**: Skeleton compression ensures parent context overhead stays bounded (10% per level, multiplicatively compressed).
- **Concurrent plans**: Each plan gets independent ScopedBackendViews. No cross-plan interference.
- **Dynamic budgets**: The knapsack algorithm is O(n) in the number of fragments. Re-compression is O(1) per fragment.
- **Maximum scale tested**: 10M files, 1B+ triples, 100M+ embeddings.

##### Progressive Enhancement Path

Organizations can adopt ACMS features progressively. At each stage, existing resources are reindexed to take advantage of new capabilities:

| Stage | Features | Requirements | Benefit |
|-------|----------|-------------|---------|
| Basic | Text search, file watching | ripgrep, sqlite | Instant exact-match search |
| Semantic | Vector embeddings, similarity search | Embedding model, vector DB | Instant semantic similarity search |
| Structural | UKO graph, relationship queries | Graph database, language analyzers | Instant relationship queries |
| Intelligent | ML-driven ranking, automated analysis | GPU, training data | Instant intelligent suggestions |
| Custom | Domain-specific ontologies, custom analyzers | Domain expertise | Instant domain-aware intelligence |

**Summary of Timing**:
- **Indexing**: Eager (happens immediately when resources are added/changed)
- **Searching**: Instant (because indices are pre-computed and ready)
- **Sandboxing**: Lazy (only when execution needs to modify a resource)
- **Context Assembly**: Real-time (but fast because it queries ready indices)

This design ensures agents never wait for index building during execution, providing a responsive and predictable experience even on massive codebases.

### Storage and Persistence

This section defines the complete storage strategy for every persistent concept in CleverAgents, specifying the storage backend, data format, lifecycle management, and migration strategy for each entity type.

#### Storage Architecture Overview

CleverAgents uses a **hybrid storage model** combining a relational database for structured data, the filesystem for configuration files and artifacts, and specialized indexes for search operations. The storage layer is accessed exclusively through repository interfaces defined in the domain layer, ensuring that storage backends can be swapped without affecting application logic.

```
┌─────────────────────────────────────────────────────────────┐
│                    Storage Architecture                       │
│                                                               │
│  ┌──────────────┐  ┌──────────────┐  ┌────────────────────┐ │
│  │  Relational   │  │  Filesystem  │  │  Search Indexes    │ │
│  │  Database     │  │              │  │                    │ │
│  │  ┌──────────┐ │  │  ┌────────┐ │  │  ┌──────────────┐ │ │
│  │  │Plans     │ │  │  │Config  │ │  │  │Text (Tantivy)│ │ │
│  │  │Decisions │ │  │  │YAML    │ │  │  │Vector (FAISS)│ │ │
│  │  │Projects  │ │  │  │Files   │ │  │  │Graph (Neo4j) │ │ │
│  │  │Resources │ │  │  ├────────┤ │  │  └──────────────┘ │ │
│  │  │Sessions  │ │  │  │Sandbox │ │  │                    │ │
│  │  │Actors(db)│ │  │  │Worktree│ │  │  ┌──────────────┐ │ │
│  │  │Invariants│ │  │  │Files   │ │  │  │Checkpoint    │ │ │
│  │  │Changes   │ │  │  ├────────┤ │  │  │Store         │ │ │
│  │  │Checkpoint│ │  │  │Artifact│ │  │  │(filesystem)  │ │ │
│  │  │Metadata  │ │  │  │Storage │ │  │  └──────────────┘ │ │
│  │  │CorrAtmpt │ │  │  └────────┘ │  │                    │ │
│  │  │AuditLog  │ │  │             │  │                    │ │
│  │  └──────────┘ │  └──────────────┘  └────────────────────┘ │
│  └──────────────┘                                             │
└─────────────────────────────────────────────────────────────┘
```

#### Entity Storage Map

The following table specifies where each CleverAgents concept is persisted, in both local and server modes:

| Entity | Local Storage | Server Storage | Format | Identifier |
|---|---|---|---|---|
| **Plans** | SQLite `plans` table | Server PostgreSQL | Relational rows | ULID (`plan_id`) |
| **Decisions** | SQLite `decisions` table | Server PostgreSQL | Relational rows + JSON `context_snapshot` | ULID (`decision_id`) |
| **Projects** | SQLite `projects` table | Server PostgreSQL (for non-`local/` namespaces) | Relational rows | Namespaced name |
| **Resources** | SQLite `resources` table + `resource_links` table | Server PostgreSQL | Relational rows + DAG edges | ULID (`resource_id`) |
| **Resource Types** | SQLite `resource_types` table + YAML config files | Server PostgreSQL + synced YAML | Relational rows | Namespaced name (built-ins unnamespaced) |
| **Actions** | SQLite `actions` table + YAML config files | Server PostgreSQL + synced YAML | Relational rows | Namespaced name |
| **Actors** | SQLite `actors` table + YAML config files | Server PostgreSQL + synced YAML | Relational rows + file reference | Namespaced name |
| **Skills** | SQLite `skills` table + YAML config files | Server PostgreSQL + synced YAML | Relational rows + file reference | Namespaced name |
| **Tools** | SQLite `tools` table + YAML config files | Server PostgreSQL + synced YAML | Relational rows + file reference | Namespaced name |
| **Sessions** | SQLite `sessions` table + `session_messages` table | Server PostgreSQL | Relational rows | ULID (`session_id`) |
| **Invariants** | SQLite `invariants` table | Server PostgreSQL | Relational rows | Auto-generated ID |
| **Automation Profiles** | SQLite `automation_profiles` table + YAML config files | Server PostgreSQL + synced YAML | Relational rows | Namespaced name (built-ins unnamespaced) |
| **Changes / ChangeSets** | SQLite `changes` table | Server PostgreSQL | Relational rows | ULID per change |
| **Checkpoints** | Filesystem (`<data-dir>/checkpoints/<plan_id>/`) + SQLite `checkpoint_metadata` table | Server object storage + PostgreSQL metadata | Git refs or filesystem snapshots + metadata rows | ULID (`checkpoint_id`) |
| **Correction Attempts** | SQLite `correction_attempts` table + archived artifacts on filesystem | Server PostgreSQL + object storage | Relational rows + file archives | ULID (`correction_attempt_id`) |
| **Artifacts** | Filesystem (`<data-dir>/artifacts/<plan_id>/`) | Server object storage (S3-compatible) | Raw files (code, documents, images, etc.) | Filesystem path relative to plan |
| **Context Indexes (Text)** | Filesystem (`<data-dir>/index/text/`) | Server-managed index cluster | Tantivy index files or SQLite FTS5 | Index directory per project |
| **Context Indexes (Vector)** | Filesystem (`<data-dir>/index/vector/`) | Server-managed FAISS/Qdrant cluster | FAISS index files or Qdrant collections | Index directory per project |
| **Context Indexes (Graph)** | Neo4j database or rdflib files | Server-managed Neo4j instance | Graph triples | Graph database per project |
| **Configuration** | TOML file (`<data-dir>/config.toml`) | N/A (server has own config) | TOML | Single file |
| **Logs** | Filesystem (`<data-dir>/logs/`) | Server-managed log aggregation | Structured JSON (structlog) | Rotated log files |
| **Audit Logs** | SQLite `audit_log` table | Server PostgreSQL | Relational rows | Auto-incrementing ID |

#### Database Schema Design

The relational database follows a normalized design with foreign key constraints enforcing referential integrity. The schema is version-controlled through Alembic migrations.

**Key design decisions:**

1. **ULID primary keys**: All time-series entities (plans, decisions, checkpoints, correction attempts) use ULID primary keys. This provides natural time-ordering without separate timestamp indexes, collision-free generation without coordination, and URL-safe string representation.

2. **JSON columns for semi-structured data**: Fields like `context_snapshot`, `alternatives_considered`, `artifacts_produced`, and `resource_bindings` are stored as JSON text columns. This avoids over-normalization for data that is always read and written as a unit, while still being queryable via SQLite's `json_extract()` or PostgreSQL's `jsonb` operators.

3. **Soft delete pattern**: Entities that support archival (actions, actors, skills) use a `state` column with values like `available`, `archived`. No rows are physically deleted except during explicit `agents init` reset or retention policy enforcement.

4. **Optimistic concurrency control**: The `updated_at` timestamp column on mutable entities serves as a version check. Update operations include `WHERE updated_at = <previous_value>` to detect concurrent modifications. On conflict, the operation fails with an explicit error rather than silently overwriting.

**Core tables (SQLite DDL):**

```sql
-- Plans table: the fundamental unit of orchestration
CREATE TABLE plans (
    plan_id TEXT PRIMARY KEY,                    -- ULID
    parent_plan_id TEXT REFERENCES plans(plan_id),
    root_plan_id TEXT NOT NULL REFERENCES plans(plan_id),
    action_name TEXT NOT NULL,                    -- namespaced action name
    phase TEXT NOT NULL DEFAULT 'strategize',     -- strategize|execute|apply
    state TEXT NOT NULL DEFAULT 'queued',         -- queued|processing|errored|complete|cancelled
    attempt INTEGER NOT NULL DEFAULT 1,
    automation_profile_name TEXT NOT NULL,
    effective_profile_snapshot TEXT NOT NULL,      -- JSON: frozen profile at creation
    arguments TEXT,                                -- JSON: action arguments
    project_names TEXT NOT NULL,                   -- JSON array of project names
    strategy_actor_name TEXT,
    execution_actor_name TEXT,
    estimation_actor_name TEXT,
    invariant_actor_name TEXT,
    created_by TEXT,                               -- session ID or user identity
    created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
    updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
    completed_at TEXT,
    error_message TEXT,
    error_traceback TEXT,
    cost_estimate_usd REAL,
    cost_actual_usd REAL,
    token_count_input INTEGER DEFAULT 0,
    token_count_output INTEGER DEFAULT 0
);

CREATE INDEX idx_plans_parent ON plans(parent_plan_id);
CREATE INDEX idx_plans_root ON plans(root_plan_id);
CREATE INDEX idx_plans_phase_state ON plans(phase, state);
CREATE INDEX idx_plans_action ON plans(action_name);
CREATE INDEX idx_plans_created ON plans(created_at);

-- Decisions table: the decision tree
CREATE TABLE decisions (
    decision_id TEXT PRIMARY KEY,                 -- ULID
    plan_id TEXT NOT NULL REFERENCES plans(plan_id),
    parent_decision_id TEXT REFERENCES decisions(decision_id),
    decision_type TEXT NOT NULL,                   -- prompt_definition|invariant_enforced|
                                                   -- strategy_choice|subplan_spawn|
                                                   -- subplan_parallel_spawn|implementation_choice
    question TEXT NOT NULL,
    chosen_option TEXT NOT NULL,
    alternatives_considered TEXT,                  -- JSON array of alternative options
    confidence_score REAL,                         -- 0.0-1.0
    rationale TEXT,
    context_snapshot TEXT NOT NULL,                -- JSON: hot_context_hash, relevant_resources,
                                                   --       actor_state_ref
    downstream_plan_ids TEXT,                      -- JSON array of child plan ULIDs
    artifacts_produced TEXT,                       -- JSON array of artifact references
    is_correction BOOLEAN DEFAULT FALSE,
    corrects_decision_id TEXT REFERENCES decisions(decision_id),
    superseded_by TEXT REFERENCES decisions(decision_id),
    sequence_number INTEGER NOT NULL,              -- ordering within this plan
    created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now'))
);

CREATE INDEX idx_decisions_plan ON decisions(plan_id);
CREATE INDEX idx_decisions_parent ON decisions(parent_decision_id);
CREATE INDEX idx_decisions_type ON decisions(decision_type);
CREATE INDEX idx_decisions_superseded ON decisions(superseded_by) WHERE superseded_by IS NOT NULL;

-- Resources table: the resource registry
CREATE TABLE resources (
    resource_id TEXT PRIMARY KEY,                  -- ULID
    name TEXT,                                     -- namespaced name (NULL for auto-discovered children)
    resource_type_name TEXT NOT NULL,              -- namespaced type name
    classification TEXT NOT NULL,                  -- physical|virtual
    description TEXT,
    properties TEXT,                               -- JSON: type-specific properties
    location TEXT,                                 -- physical resources only
    content_hash TEXT,                             -- for equivalence tracking
    sandbox_strategy TEXT,                         -- override per resource
    created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
    updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now'))
);

CREATE UNIQUE INDEX idx_resources_name ON resources(name) WHERE name IS NOT NULL;
CREATE INDEX idx_resources_type ON resources(resource_type_name);
CREATE INDEX idx_resources_classification ON resources(classification);

-- Resource DAG: parent/child relationships
CREATE TABLE resource_links (
    parent_id TEXT NOT NULL REFERENCES resources(resource_id),
    child_id TEXT NOT NULL REFERENCES resources(resource_id),
    link_type TEXT DEFAULT 'contains',            -- contains|references|derived_from
    created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
    PRIMARY KEY (parent_id, child_id)
);

CREATE INDEX idx_resource_links_child ON resource_links(child_id);

-- Project-resource linkage
CREATE TABLE project_resources (
    project_name TEXT NOT NULL,
    resource_id TEXT NOT NULL REFERENCES resources(resource_id),
    read_only BOOLEAN DEFAULT FALSE,
    linked_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
    PRIMARY KEY (project_name, resource_id)
);

-- Checkpoint metadata (actual data on filesystem)
CREATE TABLE checkpoint_metadata (
    checkpoint_id TEXT PRIMARY KEY,               -- ULID
    plan_id TEXT NOT NULL REFERENCES plans(plan_id),
    decision_id TEXT REFERENCES decisions(decision_id),
    checkpoint_type TEXT NOT NULL,                 -- pre_write|post_step|manual
    resource_id TEXT REFERENCES resources(resource_id),
    filesystem_path TEXT NOT NULL,                 -- relative path within checkpoint dir
    size_bytes INTEGER,
    created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now'))
);

CREATE INDEX idx_checkpoints_plan ON checkpoint_metadata(plan_id);

-- Correction attempts
CREATE TABLE correction_attempts (
    correction_attempt_id TEXT PRIMARY KEY,        -- ULID
    plan_id TEXT NOT NULL REFERENCES plans(plan_id),
    original_decision_id TEXT NOT NULL REFERENCES decisions(decision_id),
    new_decision_id TEXT REFERENCES decisions(decision_id),
    mode TEXT NOT NULL,                            -- revert|append
    guidance TEXT NOT NULL,
    archived_artifacts_path TEXT,                  -- filesystem path to archived originals
    state TEXT NOT NULL DEFAULT 'pending',         -- pending|executing|complete|failed
    created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now')),
    completed_at TEXT
);

CREATE INDEX idx_corrections_plan ON correction_attempts(plan_id);

-- Audit log for apply operations
CREATE TABLE audit_log (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    event_type TEXT NOT NULL,                      -- plan_applied|plan_cancelled|resource_modified|
                                                   -- correction_applied|config_changed
    plan_id TEXT,
    project_name TEXT,
    actor_name TEXT,
    user_identity TEXT,
    details TEXT NOT NULL,                         -- JSON: event-specific details
    created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%f', 'now'))
);

CREATE INDEX idx_audit_event ON audit_log(event_type);
CREATE INDEX idx_audit_plan ON audit_log(plan_id) WHERE plan_id IS NOT NULL;
CREATE INDEX idx_audit_created ON audit_log(created_at);
```

#### Filesystem Layout

The data directory follows a deterministic layout. All paths are relative to `core.data-dir` (default: `~/.cleveragents`):

```
~/.cleveragents/
├── config.toml                    # Global configuration
├── cleveragents.db                # SQLite database (WAL mode)
├── cleveragents.db-wal            # WAL file (auto-managed by SQLite)
├── cleveragents.db-shm            # Shared memory file (auto-managed)
├── logs/
│   ├── cleveragents.log           # Current log file (structured JSON)
│   ├── cleveragents.log.1         # Rotated log files
│   └── ...
├── cache/
│   ├── models/                    # Cached model artifacts
│   ├── tools/                     # Cached tool downloads
│   └── templates/                 # Compiled Jinja2 templates
├── backups/
│   ├── 2026-02-08T12-30-00/       # Timestamped backup snapshots
│   └── ...
├── checkpoints/
│   ├── 01HXR1C1D2E3F4G5H6I7.../  # Per-plan checkpoint directories
│   │   ├── chk_01HXR1E1.tar.gz   # Compressed checkpoint snapshots
│   │   └── ...
│   └── ...
├── artifacts/
│   ├── 01HXR1C1D2E3F4G5H6I7.../  # Per-plan artifact directories
│   │   ├── src/routes/health.py   # Generated/modified artifacts
│   │   └── ...
│   └── ...
├── index/
│   ├── text/
│   │   ├── local_api-service/     # Per-project Tantivy indexes
│   │   └── ...
│   ├── vector/
│   │   ├── local_api-service/     # Per-project FAISS indexes
│   │   └── ...
│   └── graph/
│       └── ...                     # rdflib stores or Neo4j connection info
├── sessions/
│   └── ...                         # Session state files (if needed beyond DB)
└── contexts/
    └── ...                         # Exported/cached context snapshots
```

#### Data Lifecycle and Retention

| Data Type | Retention Policy | Cleanup Trigger |
|---|---|---|
| Plans (active) | Indefinite until applied or cancelled | Manual deletion |
| Plans (terminal) | Governed by `core.backup.retention-days` for archives | Automatic cleanup daemon |
| Decisions | Retained as long as parent plan exists | Cascade delete with plan |
| Checkpoints | `sandbox.checkpoint.max-per-plan` per plan; oldest pruned first (keeping first + most recent) | After apply or on retention limit |
| Correction archives | `core.backup.retention-days` after plan is applied | Automatic cleanup daemon |
| Logs | `core.log.retention-days` | Daily rotation + age-based cleanup |
| Backups | `core.backup.retention-days` | Age-based cleanup |
| Cache | No automatic retention; manual cleanup via `agents diagnostics --cleanup` | User-initiated |
| Search indexes | Rebuilt on resource add/remove; no explicit retention | Re-index on change |
| Audit logs | Indefinite (critical for compliance) | Manual archival only |

#### Migration Strategy

Database schema changes are managed through Alembic migrations with the following rules:

1. **Forward-only in production**: Downgrade scripts are provided but only used in development. Production deployments only move forward.
2. **Auto-apply on startup**: When `CLEVERAGENTS_AUTO_APPLY_MIGRATIONS` is set (default in development), migrations run automatically on first database access. In production, migrations are triggered by `agents init` or explicit upgrade commands.
3. **Backward compatibility window**: Each migration maintains backward compatibility with the previous schema version for at least one minor release cycle, allowing rolling upgrades in server mode.
4. **Data migration separation**: Schema DDL changes and data transformations are kept in separate migration steps to enable rollback of data changes independently.

### Observability

CleverAgents implements a comprehensive observability strategy across three pillars — logging, metrics, and tracing — designed to provide full visibility into plan execution, actor behavior, tool invocations, and resource access. Every significant operation in the system is observable, enabling debugging of complex multi-plan hierarchies and performance optimization.

#### Structured Logging

All logging uses **structlog** with JSON output format. Every log entry includes contextual fields that enable correlation across plan hierarchies:

```python
import structlog

logger = structlog.get_logger()

# Every log entry automatically includes bound context
logger = logger.bind(
    plan_id="01HXR1C1D2E3F4G5H6I7J8K9L0",
    phase="execute",
    actor_name="anthropic/claude-3.5-sonnet",
    session_id="01HXM2A6K1P2E9Q9D4GQ7J4S7Z",
)

# Example: tool invocation logging
logger.info(
    "tool_invoked",
    tool_name="local/write-file",
    skill_name="local/file-ops",
    resource_id="01HXR1A1B2C3D4E5F6G7H8J9K0",
    resource_type="git-checkout",
    input_schema_hash="sha256:a1b2c3...",
    duration_ms=142,
    writes=True,
    checkpoint_created=True,
)
```

**Log levels and their semantics:**

| Level | Usage | Examples |
|---|---|---|
| `DEBUG` | Internal state transitions, context building details, LLM prompt construction | "Building hot context: 12 files, 8,420 tokens", "Decision confidence computed: 0.87" |
| `INFO` | Significant lifecycle events, phase transitions, tool completions | "Plan entered execute phase", "Tool write-file completed in 142ms", "Validation passed: pytest" |
| `WARNING` | Degraded operations, approaching limits, non-fatal issues | "Budget at 82% ($4.10/$5.00)", "Checkpoint pruned: exceeded max-per-plan", "Provider fallback: openai -> anthropic" |
| `ERROR` | Operation failures, invariant violations, unrecoverable tool errors | "Validation failed: pytest exited 1", "Invariant violated: API compatibility", "LLM provider error: rate limited" |

**Log correlation**: Every log entry within a plan execution context includes `plan_id`, `root_plan_id`, `parent_plan_id`, `phase`, `state`, and `attempt`. This enables tracing a single decision through the entire plan hierarchy using standard log querying tools (e.g., `jq '.plan_id == "01HXR1C1..."'`).

#### Event System

CleverAgents emits domain events for every significant state change. Events flow through two channels:

1. **RxPY Reactive Stream**: Real-time event stream for in-process subscribers (TUI updates, progress bars, streaming output). Uses `Subject` for fan-out distribution.
2. **Persistent Event Log**: All events are written to the `audit_log` table for post-hoc analysis and compliance.

**Event taxonomy:**

```python
from enum import Enum
from pydantic import BaseModel
from datetime import datetime

class EventType(str, Enum):
    # Plan lifecycle events
    PLAN_CREATED = "plan.created"
    PLAN_PHASE_CHANGED = "plan.phase_changed"
    PLAN_STATE_CHANGED = "plan.state_changed"
    PLAN_APPLIED = "plan.applied"
    PLAN_CANCELLED = "plan.cancelled"
    PLAN_ERRORED = "plan.errored"

    # Decision events
    DECISION_CREATED = "decision.created"
    DECISION_APPROVED = "decision.approved"
    DECISION_CORRECTED = "decision.corrected"
    DECISION_SUPERSEDED = "decision.superseded"

    # Invariant events
    INVARIANT_RECONCILED = "invariant.reconciled"
    INVARIANT_VIOLATED = "invariant.violated"
    INVARIANT_ENFORCED = "invariant.enforced"

    # Actor events
    ACTOR_INVOKED = "actor.invoked"
    ACTOR_COMPLETED = "actor.completed"
    ACTOR_ERRORED = "actor.errored"
    ACTOR_ESCALATED = "actor.escalated"       # confidence below threshold

    # Tool events
    TOOL_INVOKED = "tool.invoked"
    TOOL_COMPLETED = "tool.completed"
    TOOL_ERRORED = "tool.errored"
    TOOL_RETRIED = "tool.retried"

    # Resource events
    RESOURCE_ACCESSED = "resource.accessed"
    RESOURCE_MODIFIED = "resource.modified"
    RESOURCE_INDEXED = "resource.indexed"

    # Sandbox events
    SANDBOX_CREATED = "sandbox.created"
    SANDBOX_COMMITTED = "sandbox.committed"
    SANDBOX_ROLLED_BACK = "sandbox.rolled_back"
    CHECKPOINT_CREATED = "checkpoint.created"
    CHECKPOINT_RESTORED = "checkpoint.restored"

    # Context events
    CONTEXT_BUILT = "context.built"
    CONTEXT_QUERY_EXECUTED = "context.query_executed"

    # Validation events
    VALIDATION_STARTED = "validation.started"
    VALIDATION_PASSED = "validation.passed"
    VALIDATION_FAILED = "validation.failed"

    # Session events
    SESSION_CREATED = "session.created"
    SESSION_MESSAGE_SENT = "session.message_sent"

    # Cost events
    BUDGET_WARNING = "budget.warning"
    BUDGET_EXCEEDED = "budget.exceeded"


class DomainEvent(BaseModel):
    """Base event model emitted by all domain operations."""
    event_type: EventType
    timestamp: datetime
    plan_id: str | None = None
    root_plan_id: str | None = None
    session_id: str | None = None
    actor_name: str | None = None
    project_name: str | None = None
    details: dict  # Event-type-specific payload
```

**Event emission pattern**: Domain services emit events through an injected `EventBus` interface. The infrastructure layer provides two implementations:

```python
from typing import Protocol
import rx
from rx.subject import Subject

class EventBus(Protocol):
    def emit(self, event: DomainEvent) -> None: ...
    def subscribe(self, event_type: EventType, handler: Callable) -> None: ...

class ReactiveEventBus:
    """In-process event bus using RxPY for real-time distribution."""
    def __init__(self):
        self._subject = Subject()
        self._subscriptions: dict[EventType, list[Callable]] = {}

    def emit(self, event: DomainEvent) -> None:
        # Push to reactive stream for real-time subscribers
        self._subject.on_next(event)
        # Persist to audit log
        self._persist_audit(event)
        # Dispatch to type-specific handlers
        for handler in self._subscriptions.get(event.event_type, []):
            handler(event)

    def subscribe(self, event_type: EventType, handler: Callable) -> None:
        self._subscriptions.setdefault(event_type, []).append(handler)

    @property
    def stream(self) -> rx.Observable:
        """Raw observable stream for advanced RxPY operators."""
        return self._subject
```

#### LLM Call Tracing

Every LLM invocation is traced with full context for debugging and cost tracking:

```python
# Trace record for each LLM call
class LLMTrace(BaseModel):
    trace_id: str                     # ULID
    plan_id: str
    decision_id: str | None
    actor_name: str
    provider: str                     # openai, anthropic, google, etc.
    model: str                        # gpt-4o, claude-3.5-sonnet, etc.
    prompt_tokens: int
    completion_tokens: int
    total_tokens: int
    cost_usd: float
    latency_ms: int
    temperature: float
    tool_calls: list[str]             # tool names invoked by the LLM
    context_hash: str                 # hash of the context window contents
    context_refs: list[str]           # resource IDs referenced in context
    streaming: bool
    retry_count: int
    error: str | None
    timestamp: datetime
```

**LangSmith integration**: When `CLEVERAGENTS_LANGSMITH_ENABLED` is `true`, all LLM traces are additionally forwarded to LangSmith for visualization, comparison, and cost analysis. The integration maps CleverAgents plan IDs to LangSmith run tags, enabling filtering by plan hierarchy in the LangSmith UI.

#### Metrics Collection

CleverAgents collects operational metrics for performance monitoring and capacity planning. Metrics are emitted as structured log entries (for local mode) and optionally exported to Prometheus (for server mode):

| Metric | Type | Description |
|---|---|---|
| `plan.duration_seconds` | Histogram | Total wall-clock time per plan, labeled by phase |
| `plan.cost_usd` | Counter | Cumulative API cost per plan |
| `plan.decisions_count` | Counter | Number of decisions per plan |
| `plan.child_plans_count` | Counter | Number of child plans spawned |
| `actor.invocation_duration_ms` | Histogram | Per-actor invocation latency |
| `actor.token_usage` | Counter | Token counts by provider and model |
| `tool.invocation_duration_ms` | Histogram | Per-tool invocation latency |
| `tool.error_rate` | Counter | Tool invocation failures by tool name |
| `context.build_duration_ms` | Histogram | Context building time by tier (hot/warm/cold) |
| `context.tokens_used` | Gauge | Current token usage in hot context |
| `index.query_duration_ms` | Histogram | Index query latency by backend (text/vector/graph) |
| `sandbox.operation_duration_ms` | Histogram | Sandbox create/commit/rollback time |
| `validation.duration_seconds` | Histogram | Per-validation tool invocation execution time |
| `validation.pass_rate` | Counter | Validation pass/fail counts (from `passed` field in return JSON) |

#### Diagnostic Dashboard

The `agents diagnostics` command provides a real-time health check combining all observability data:

1. **System health**: Config file readability, database accessibility, disk space, provider API key validation.
2. **Index health**: Text index status, vector index dimensionality and count, graph store connectivity.
3. **Active plan overview**: Running plans, queued plans, resource utilization.
4. **Cost summary**: Current session cost, budget utilization, provider-level breakdown.
5. **Performance summary**: Average plan duration, tool call latency percentiles, context build times.

### Security Model

CleverAgents implements a defense-in-depth security model addressing five concerns: sandbox isolation, access control, prompt injection mitigation, secret management, and audit logging. The security model differs between local mode (single-user, trusted environment) and server mode (multi-user, potentially untrusted environment).

#### Sandbox Isolation

The sandbox is the primary safety mechanism preventing untested changes from reaching production resources. Every plan's Execute phase runs within an isolated sandbox unless explicitly disabled by the automation profile (`require_sandbox: false`).

**Sandbox strategies and their security properties:**

| Strategy | Isolation Level | Resource Type | Mechanism | Rollback |
|---|---|---|---|---|
| `git_worktree` | Process-level filesystem isolation | Git repositories | Creates a separate git worktree on a plan-specific branch. Changes are confined to the worktree directory. Merge back to main requires explicit apply. | `git checkout -- .` or worktree deletion |
| `filesystem_copy` | Process-level filesystem isolation | Non-git filesystems | Creates a copy-on-write snapshot (using `cp --reflink=auto` where supported, falling back to full copy). Original files are never modified during execution. | Delete the copy directory |
| `transaction_rollback` | Database transaction isolation | Databases | Opens a database transaction with `SERIALIZABLE` isolation level. All changes are staged within the transaction. Commit on apply; rollback on cancel/error. | `ROLLBACK` |
| `none` | No isolation | Any | Changes are applied directly. Requires `require_sandbox: false` in the automation profile. Only appropriate when external safety mechanisms exist. | No automatic rollback |

**Sandbox security invariants:**

1. **No cross-sandbox access**: Each plan's sandbox is isolated. Plan A cannot read or write Plan B's sandbox contents. The sandbox path is derived deterministically from the plan ULID, preventing path traversal.
2. **Read-only source guarantee during Execute**: The original project resources are never modified during Execute. All tool write operations target the sandbox copy.
3. **Atomic apply**: The Apply phase is an atomic operation — either all sandbox changes are committed to the real resources, or none are. For git-based resources, this uses git merge. For database resources, this uses transaction commit.
4. **Sandbox cleanup**: Sandbox directories are cleaned up according to `sandbox.cleanup` policy. Sensitive data (API responses, LLM outputs) is purged from the sandbox on cleanup.

#### Prompt Injection Mitigation

In server mode, where user-provided content may flow into LLM prompts, CleverAgents implements several mitigations:

1. **Input sanitization**: User-provided text in action arguments, invariant text, and session prompts is sanitized before inclusion in LLM prompts. HTML entities, control characters, and known injection patterns are escaped or rejected.

2. **Prompt boundary markers**: System prompts and user content are separated by clear boundary markers that the LLM is instructed to recognize. The system prompt explicitly states that content between `[USER_CONTENT_START]` and `[USER_CONTENT_END]` markers is user-provided and should not be treated as system instructions.

3. **Output validation**: LLM outputs that are used as tool invocations are validated against the tool's JSON Schema before execution. This prevents the LLM from being tricked into invoking tools with malicious parameters.

4. **Tool capability restrictions**: Tools declare their capabilities (`read_only`, `writes`, `checkpointable`, `side_effects`). The execution engine enforces these declarations — a tool declared as `read_only` cannot invoke write operations even if the LLM requests it.

5. **Unsafe tool gating**: Tools marked as `unsafe` (e.g., arbitrary shell execution, network access) are blocked unless the automation profile explicitly sets `allow_unsafe_tools: true`. In server mode, only administrators can create automation profiles that allow unsafe tools.

#### Secret Management

Secrets (API keys, database credentials, authentication tokens) are managed through a layered approach:

1. **Environment variables (preferred)**: Provider API keys (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, etc.) and the server token (`CLEVERAGENTS_SERVER_TOKEN`) are read from environment variables. This is the recommended approach for both local and CI environments.

2. **Configuration file (fallback)**: API keys can be stored in `config.toml` under the `provider.*` section. The config file should have restrictive permissions (`chmod 600`). The `agents diagnostics` command warns if config file permissions are too permissive.

3. **Secret masking in logs**: All log output and CLI display automatically masks values that match known secret patterns (keys starting with `sk-`, `sk-ant-`, `tok_`, etc.). Masked values are replaced with `***REDACTED***`. The masking is applied at the structlog processor level, ensuring no secret leaks through any log path.

4. **Secret masking in LLM context**: Before constructing LLM prompts, the context builder scans for patterns matching known secret formats and replaces them with `[REDACTED]`. This prevents accidental exposure of secrets in LLM training data (for providers that use customer data for training, which CleverAgents discourages).

5. **Server mode credential isolation**: In server mode, each user's API keys are stored encrypted in the server database using AES-256-GCM with a per-user key derived from the server's master secret. Keys are decrypted only at the moment of LLM invocation and are never transmitted to the client CLI.

#### Audit Logging

All security-relevant operations are recorded in the `audit_log` table with the following events:

| Event Type | Trigger | Details Captured |
|---|---|---|
| `plan_applied` | `agents plan apply` | Plan ID, project names, files changed, validation results, user identity |
| `plan_cancelled` | `agents plan cancel` | Plan ID, reason, resources released |
| `resource_modified` | Tool write operations during Execute | Resource ID, modification type, sandbox path, tool name |
| `correction_applied` | `agents plan correct` | Correction attempt ID, original decision ID, mode, guidance |
| `config_changed` | `agents config set` | Key, old value (masked if secret), new value (masked if secret), user identity |
| `entity_deleted` | `agents <entity> delete/remove` | Entity type, entity name, cascade effects |
| `session_created` | `agents session create` | Session ID, actor name, user identity |
| `auth_success` | Server mode login | User identity, IP address, token prefix |
| `auth_failure` | Server mode failed login | Attempted identity, IP address, failure reason |


**Audit log retention**: Audit logs are never automatically deleted. In server mode, audit logs can be exported for compliance archival using server administration commands. In local mode, audit logs are preserved in the SQLite database indefinitely and are included in backup snapshots.

### Extensibility

CleverAgents is designed as an extensible platform where every major subsystem supports custom implementations. The extensibility model follows the **Open/Closed Principle** — the system is open for extension through well-defined interfaces, but closed for modification of core behavior.

#### Plugin Architecture Overview

```
┌────────────────────────────────────────────────────────┐
│                   Extension Points                      │
│                                                         │
│  ┌─────────────┐  ┌──────────────┐  ┌───────────────┐ │
│  │ Custom Tools │  │ Custom Skills│  │ Custom Actors │ │
│  │ (YAML/Python)│  │ (YAML)       │  │ (YAML/Graph) │ │
│  └──────┬──────┘  └──────┬───────┘  └───────┬───────┘ │
│         │                │                   │          │
│  ┌──────┴──────┐  ┌──────┴───────┐  ┌───────┴───────┐ │
│  │ MCP Servers │  │ Agent Skills │  │ Custom LLM    │ │
│  │ (stdio/SSE) │  │ Standard     │  │ Providers     │ │
│  └──────┬──────┘  └──────┬───────┘  └───────┬───────┘ │
│         │                │                   │          │
│  ┌──────┴────────────────┴───────────────────┴───────┐ │
│  │              Tool Registry                         │ │
│  │              Skill Registry                        │ │
│  │              Actor Registry                        │ │
│  │              Provider Registry                     │ │
│  └──────────────────────┬────────────────────────────┘ │
│                         │                               │
│  ┌──────────────────────┴────────────────────────────┐ │
│  │  Custom Resource    │  Custom Sandbox  │  Custom  │ │
│  │  Types (YAML)       │  Strategies     │  Index   │ │
│  │                     │  (Python)       │  Backends│ │
│  └─────────────────────┴─────────────────┴──────────┘ │
└────────────────────────────────────────────────────────┘
```

#### Tool Extensibility

Tools are the atomic unit of execution and the primary extension point. There are five ways to add tools:

1. **Custom Python tools**: Define a tool with inline Python code in a YAML configuration file. The code runs in a sandboxed execution context with access to the plan context, resource bindings, and checkpoint API.

   ```yaml
   # File: tools/my-custom-tool.yaml
   tool:
     name: local/analyze-complexity
     description: "Compute cyclomatic complexity for Python files"
     source: custom

     input_schema:
       type: object
       properties:
         file_path: { type: string }
       required: [file_path]

     output_schema:
       type: object
       properties:
         complexity: { type: integer }
         functions: { type: array }

     capability:
       writes: false
       checkpointable: false

     resource_slots:
       - name: source
         type: git-checkout
         binding: contextual

     code: |
       import ast
       content = ctx.resources["source"].read(params["file_path"])
       tree = ast.parse(content)
       # ... complexity analysis ...
       return {"complexity": total, "functions": results}
   ```

2. **MCP server tools**: Any MCP-compliant server can expose tools to CleverAgents. Skills reference MCP servers by their transport configuration:

   ```yaml
   # File: skills/kubernetes-ops.yaml
   skill:
     name: local/kubernetes-ops
     description: "Kubernetes cluster management tools"
     mcp_servers:
       - transport: stdio
         command: npx
         args: ["-y", "@anthropic/mcp-kubernetes"]
   ```

3. **Agent Skills Standard tools**: Tools organized in standard folder structures are auto-discovered and registered:

   ```yaml
   skill:
     name: local/project-tools
     agent_skills_dirs:
       - ./agent-skills/
   ```

4. **Built-in tools**: Core file operations (`read_file`, `write_file`, `edit_file`, `delete_file`, `move_file`, `list_files`, `search_files`), plan operations (`create-subplan`), and system operations are provided as built-in tools grouped into built-in skills.

5. **Anonymous inline tools**: Tools can be defined inline within actor graph nodes or skill definitions for one-off operations that don't need global registration.

**Tool lifecycle hooks**: Every tool follows a four-phase lifecycle — `discover` (find available capabilities), `activate` (prepare for use, acquire connections), `execute` (perform the operation), `deactivate` (release resources). The tool registry manages these lifecycle transitions.

#### Skill Extensibility

Skills compose tools into capability collections. Skills support:

- **Tool aggregation**: Reference named tools from the Tool Registry
- **Inline anonymous tools**: Define tools directly in the skill YAML
- **Skill inclusion**: Include other skills by reference (composability)
- **MCP server aggregation**: Expose tools from one or more MCP servers
- **Agent Skills Standard**: Expose tools from Agent Skills Standard directories

#### Actor Extensibility

Actors can be extended through:

1. **YAML-defined agents**: Single LLM actors with custom system prompts, temperature settings, tool bindings, and capability constraints.
2. **YAML-defined graphs**: LangGraph topologies with multiple actors and tool nodes connected by edges, conditional routing, and parallel execution groups.
3. **Provider extension**: New LLM providers can be added by implementing the `AIProviderInterface` protocol and registering with the `ProviderRegistry`. The registry uses auto-discovery to detect installed `langchain-*` packages.

```python
from typing import Protocol

class AIProviderInterface(Protocol):
    """Protocol for LLM provider implementations."""

    @property
    def provider_name(self) -> str: ...

    @property
    def capabilities(self) -> ProviderCapabilities: ...

    def create_chat_model(
        self,
        model: str,
        temperature: float = 0.7,
        **kwargs,
    ) -> BaseChatModel: ...

    def create_embedding_model(
        self,
        model: str,
        **kwargs,
    ) -> BaseEmbeddings: ...
```

#### Custom Resource Types

New resource types extend CleverAgents to manage any kind of resource:

```yaml
# File: resource-types/docker-registry.yaml
resource_type:
  name: local/docker-registry
  description: "Docker container registry"
  classification: physical
  user_addable: true

  cli_args:
    - name: registry_url
      type: string
      required: true
    - name: repository
      type: string
      required: true
    - name: tag
      type: string
      default: "latest"

  sandbox_strategy: none    # Docker images are immutable
  handler: docker_registry_handler

  child_types:
    - type: local/docker-image
      relationship: contains
      auto_discover: true

  auto_discovery:
    enabled: true
    strategy: list_tags
```

#### Custom Index Backends

The indexing layer is abstracted behind three interfaces (text, vector, graph). Custom implementations can be registered for each:

```python
class TextIndexBackend(Protocol):
    """Interface for full-text search backends."""
    def index_document(self, project: str, doc_id: str, content: str, metadata: dict) -> None: ...
    def search(self, project: str, query: str, limit: int) -> list[SearchResult]: ...
    def remove_document(self, project: str, doc_id: str) -> None: ...
    def rebuild_index(self, project: str) -> None: ...

class VectorIndexBackend(Protocol):
    """Interface for vector similarity search backends."""
    def index_embedding(self, project: str, doc_id: str, embedding: list[float], metadata: dict) -> None: ...
    def search_similar(self, project: str, query_embedding: list[float], limit: int, min_relevance: float) -> list[VectorResult]: ...
    def remove_embedding(self, project: str, doc_id: str) -> None: ...

class GraphIndexBackend(Protocol):
    """Interface for knowledge graph backends."""
    def add_triple(self, project: str, subject: str, predicate: str, obj: str) -> None: ...
    def query(self, project: str, sparql: str) -> list[dict]: ...
    def remove_triples(self, project: str, subject: str | None, predicate: str | None, obj: str | None) -> None: ...
```

New backends are registered via configuration:

```toml
# config.toml
[index.text]
backend = "custom"
custom_module = "my_extensions.elasticsearch_backend"
custom_class = "ElasticsearchTextIndex"

[index.text.custom_options]
hosts = ["http://localhost:9200"]
index_prefix = "cleveragents"
```

#### Custom Sandbox Strategies

The sandbox layer supports custom isolation strategies for specialized resource types:

```python
class SandboxStrategy(Protocol):
    """Interface for sandbox isolation strategies."""
    def create(self, plan_id: str, resource: Resource) -> SandboxRef: ...
    def read(self, ref: SandboxRef, path: str) -> bytes: ...
    def write(self, ref: SandboxRef, path: str, content: bytes) -> Change: ...
    def diff(self, ref: SandboxRef) -> DiffView: ...
    def commit(self, ref: SandboxRef) -> None: ...
    def rollback(self, ref: SandboxRef) -> None: ...
    def checkpoint(self, ref: SandboxRef, checkpoint_id: str) -> None: ...
    def restore_checkpoint(self, ref: SandboxRef, checkpoint_id: str) -> None: ...
    def cleanup(self, ref: SandboxRef) -> None: ...
```

Custom strategies are mapped to resource types via the resource type configuration's `sandbox_strategy` field, or globally via `sandbox.strategy` config.

#### Extension Points Summary

| Extension Point | Registration Mechanism | Configuration Format | Discovery |
|---|---|---|---|
| **Custom Tools** | `agents tool add --config <file>` | YAML | Manual registration |
| **MCP Server Tools** | Referenced in skill YAML `mcp_servers` section | YAML | Auto-discovered from MCP server |
| **Agent Skills Standard** | Referenced in skill YAML `agent_skills_dirs` section | Folder structure | Auto-discovered from directory |
| **Custom Skills** | `agents skill add --config <file>` | YAML | Manual registration |
| **Custom Actors** | `agents actor add --config <file>` | YAML | Manual registration |
| **Custom Resource Types** | `agents resource type add --config <file>` | YAML | Manual registration |
| **Custom LLM Providers** | Python package installation + ProviderRegistry auto-discovery | Python module | Auto-discovered via `langchain-*` package naming |
| **Custom Index Backends** | `config.toml` `index.*.custom_module` | TOML + Python module | Configuration-driven |
| **Custom Sandbox Strategies** | Resource type `sandbox_strategy` field | YAML + Python module | Configuration-driven |
| **Custom Automation Profiles** | `agents automation-profile add --config <file>` | YAML | Manual registration |
| **Custom Invariant Actors** | Standard actor registration + assignment via `--invariant-actor` | YAML | Manual assignment |

## Work Remaining 

This section describes what remains to be done to bring the current CleverAgents codebase up to the specification. 

**Last Updated:** February 6, 2026

### Current State Assessment

#### What's Implemented

Based on analysis of the current codebase:

1. **Plan Lifecycle Foundation** - The 3-phase lifecycle (Strategize → Execute → Apply), instantiated from Action templates, is partially implemented in `plan_lifecycle_service.py`
2. **Database Models** - Models exist for projects, plans, contexts, changes, and actors
3. **LangGraph Integration** - Graph-based workflow support exists but is not fully connected to the plan workflow
4. **Reactive System** - A reactive system with stream routing is present
5. **Actor System** - Actor models and services exist but lack full behavioral definitions
6. **Basic Context Analysis** - Simple context loading and analysis capabilities
7. **Change Tracking** - Basic `Change` and `ChangeSet` models exist

#### What's Missing

Critical gaps between the specification and current implementation:

1. **No Resource Abstraction** - The unified resource layer for files, databases, APIs is entirely missing
2. **No Sandboxing** - Execute phase writes directly to files without isolation
3. **No Decision Tree** - No decision tracking, storage, or correction mechanism
4. **No Skills/MCP Integration** - No skill registry, skill YAML parsing, tool adapters, or MCP protocol support
5. **Single-File Limitation** - Hard-coded to generate exactly one file per plan
6. **Text-Based Code Generation** - Still parsing LLM output instead of tool-based approach
7. **No Checkpointing** - No rollback or checkpoint capabilities
8. **No Code Intelligence / ACMS** - Missing ACMS implementation: UKO ontology analyzers, strategy framework, Fusion Engine, CRP skill, context budget calculator, and backend indices (text, vector, graph). The full design is specified in the "Advanced Context Management System (ACMS)" section.
9. **No Context Tiers** - No hot/warm/cold memory architecture, no warm-to-cold demotion, no temporal versioning of UKO nodes
10. **Limited Validation** - Basic stub validation instead of semantic checks

### Work Items by Priority

### 1) Implement Tool-Based Resource Modification (Critical Foundation)

#### Problem
The current system generates code as a single text blob that gets written to one file. The specification requires a modern tool-based approach where LLMs invoke discrete operations on resources.

#### Implementation Steps

1. **Create Resource Abstraction Layer**
   <div class="highlight"><pre><code>
   <span style="opacity: 0.7;"># New modules needed:</span>
   src/cleveragents/domain/models/resources.py
   src/cleveragents/domain/resources/handlers.py
   src/cleveragents/domain/resources/sandbox.py
   </code></pre></div>

2. **Implement Built-in Tools (via built-in skills)**
   <div class="highlight"><pre><code>
   <span style="opacity: 0.7;"># Core file operations (provided by built-in skill groups)</span>
   read_file(path: <span style="color: cyan;">str</span>) -&gt; <span style="color: cyan;">str</span>
   write_file(path: <span style="color: cyan;">str</span>, content: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>
   edit_file(path: <span style="color: cyan;">str</span>, changes: <span style="color: cyan;">list</span>[Edit]) -&gt; <span style="color: magenta; font-weight: 600;">None</span>
   delete_file(path: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>
   move_file(src: <span style="color: cyan;">str</span>, dst: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>
   create_directory(path: <span style="color: cyan;">str</span>) -&gt; <span style="color: magenta; font-weight: 600;">None</span>
   list_files(pattern: <span style="color: cyan;">str</span>) -&gt; <span style="color: cyan;">list</span>[<span style="color: cyan;">str</span>]
   search_files(pattern: <span style="color: cyan;">str</span>, content_pattern: <span style="color: cyan;">str</span>) -&gt; <span style="color: cyan;">list</span>[Match]
   </code></pre></div>

3. **Connect Tools to ChangeSet**
   - Each tool invocation that modifies resources creates a `Change` record
   - ChangeSet accumulates these changes during execution
   - No more parsing LLM text output for code

#### Estimated Effort: 2-3 weeks

### 2) Implement Sandbox Infrastructure (Critical for Safety)

#### Problem
Execute phase currently writes directly to the project. The specification requires all changes happen in an isolated sandbox that can be reviewed before applying.

#### Implementation Steps

1. **Define Sandbox Interface**
   <div class="highlight"><pre><code>
   <span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">Sandbox</span>(<span style="color: cyan;">Protocol</span>):
       <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">create</span>() -&gt; SandboxRef
       <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">read</span>(path: <span style="color: cyan;">str</span>) -&gt; Content
       <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">write</span>(path: <span style="color: cyan;">str</span>, content: Content) -&gt; Change
       <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">diff</span>() -&gt; DiffView
       <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">commit</span>() -&gt; <span style="color: magenta; font-weight: 600;">None</span>
       <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">rollback</span>() -&gt; <span style="color: magenta; font-weight: 600;">None</span>
   </code></pre></div>

2. **Implement Sandbox Strategies**
   - `GitWorktreeSandbox` - For git repositories (preferred)
   - `FilesystemCopySandbox` - For non-git projects
   - `TransactionSandbox` - For databases
   - `NoOpSandbox` - For non-sandboxable resources

3. **Lazy Sandbox Creation**
   - Only create sandboxes when resources are accessed
   - Each plan gets its own sandbox namespace

#### Estimated Effort: 2 weeks

### 3) Build Decision Tree System (Core Innovation)

#### Problem
No decision tracking exists. The specification's key innovation is recording every decision with full context, enabling correction without full re-execution.

#### Implementation Steps

1. **Create Decision Models**
   <div class="highlight"><pre><code>
   <span style="opacity: 0.7;">-- New tables needed</span>
   <span style="color: #5599ff; font-weight: 600;">CREATE</span> <span style="color: #5599ff; font-weight: 600;">TABLE</span> decisions (
       decision_id <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">PRIMARY</span> <span style="color: #5599ff; font-weight: 600;">KEY</span>,  -- ULID
       plan_id <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,
       parent_decision_id <span style="color: #5599ff; font-weight: 600;">TEXT</span>,
       decision_type <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,
       question <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,
       chosen_option <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,
       alternatives_considered <span style="color: #5599ff; font-weight: 600;">TEXT</span>,  -- JSON array
       context_snapshot <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>,  -- JSON
       created_at <span style="color: #5599ff; font-weight: 600;">TEXT</span> <span style="color: #5599ff; font-weight: 600;">NOT</span> <span style="color: #5599ff; font-weight: 600;">NULL</span>
   );
   </code></pre></div>

2. **Implement Decision Recording**
   - Every choice during Strategize creates a Decision record
   - Capture complete context snapshot with each decision
   - Track downstream dependencies

3. **Build Correction Mechanism**
   <div class="highlight"><pre><code>
   agents plan correct &lt;decision_id&gt; <span style="color: cyan;">--mode</span>=revert <span style="color: cyan;">--guidance</span> <span style="color: #66cc66;">&quot;&lt;new decision&gt;&quot;</span>
   </code></pre></div>
   - Mark decision as superseded
   - Recompute only affected subtree
   - Preserve unaffected work

#### Estimated Effort: 3 weeks

### 4) Implement Advanced Context Management System (ACMS) (Scalability Enabler)

#### Problem
Current context is limited to a few hundred characters from a few files. Large codebases require intelligent, pluggable context discovery with multiple retrieval strategies, a universal knowledge representation, and demand-driven context assembly. The full ACMS design is specified in the "Advanced Context Management System (ACMS)" section of this document.

#### Implementation Steps

1. **Universal Knowledge Ontology (UKO) Foundation**
   - Implement the four-layer UKO ontology hierarchy (Layer 0: universal, Layer 1: general software, Layer 2: paradigm, Layer 3: language-specific)
   - Build language-specific analyzers for Python, TypeScript, Rust, Java (extract UKO nodes from source code)
   - Implement non-code domain analyzers: `uko-doc:` (documents), `uko-data:` (schemas), `uko-infra:` (infrastructure)
   - Implement temporal versioning (`validFrom`, `validUntil`, `isCurrent`, `isRevisionOf`)
   - Integrate eager indexing on resource add via the Resource Registry lifecycle hooks

2. **Three-Index Backend Architecture**
   - **Text Index**: Tantivy/SQLite FTS for exact keyword matches
   - **Vector Index**: FAISS/Qdrant for semantic embedding search
   - **Graph Store**: RDF store for UKO relationship traversal
   - Implement `ScopedBackendView` to auto-filter all queries to plan project resources

3. **Context Request Protocol (CRP)**
   - Implement the `builtin/context` skill with tools: `request_context`, `query_history`, `get_context_budget`
   - Implement `ContextRequest` and `ContextResponse` data structures
   - Integrate CRP with actor execution loop

4. **Pluggable Strategy Framework**
   - Implement `ContextStrategy` base class and strategy registration
   - Build six built-in strategies: `simple-keyword` (0.3), `semantic-embedding` (0.6), `breadth-depth-navigator` (0.85), `arce` (0.95), `temporal-archaeology` (0.5), `plan-decision-context` (0.7)
   - Implement `StrategyCoordinator` for parallel strategy execution with budget allocation

5. **Fusion Engine**
   - Implement deduplication (content-hash, UKO-identity, semantic)
   - Implement detail-level conflict resolution (max-detail wins)
   - Implement greedy knapsack budget packing
   - Implement coherence-aware ordering and optional preamble generation

6. **Context Budget Calculator & Refresh Manager**
   - Dynamic budget computation from model context window, response reserve, tool definitions, system prompt
   - Skeleton compression and plan context inheritance
   - Automatic re-assembly on budget change exceeding refresh threshold

7. **Tiered Context System**
   - **Hot**: Current working set assembled by ACMS (in LLM context)
   - **Warm**: Recent decisions and search results (warm retention window)
   - **Cold**: Historical data, patterns, and archived UKO snapshots (queryable via retrieval)

#### Estimated Effort: 8-10 weeks

### 5) Complete Actor System with Behavioral Definitions

#### Problem
Actors exist but don't define behavior beyond model selection. The specification requires actors to be composable graphs with tools, memory, and context policies.

#### Implementation Steps

1. **Extend Actor Configuration**
   <div class="highlight"><pre><code>
   <span style="color: cyan; font-weight: 600;">actors</span>:
     <span style="color: cyan; font-weight: 600;">my_strategist</span>:
       <span style="color: cyan; font-weight: 600;">type</span>: graph
       <span style="color: cyan; font-weight: 600;">config</span>:
         <span style="color: cyan; font-weight: 600;">provider</span>: anthropic
         <span style="color: cyan; font-weight: 600;">model</span>: claude-3-opus
         <span style="color: cyan; font-weight: 600;">memory_policy</span>: per_plan
         <span style="color: cyan; font-weight: 600;">context_view</span>: architect <span style="opacity: 0.7;"># High-level view</span>
       <span style="color: cyan; font-weight: 600;">skills</span>:
         - local/file-ops             # provides read_file
         - local/code-intelligence    # provides search_code, analyze_dependencies
       <span style="color: cyan; font-weight: 600;">routes</span>:
         <span style="color: cyan; font-weight: 600;">strategize</span>:
           <span style="color: cyan; font-weight: 600;">entry_point</span>: analyze
           <span style="color: cyan; font-weight: 600;">nodes</span>:
             - <span style="color: cyan;">name</span>: analyze
               <span style="color: cyan; font-weight: 600;">type</span>: llm
             - <span style="color: cyan;">name</span>: plan
               <span style="color: cyan; font-weight: 600;">type</span>: llm
   </code></pre></div>

2. **Implement Tool Access Policies**
   - Strategy actors: read-only tools
   - Execute actors: read/write within sandbox
   - Apply actors: commit tools

3. **Actor-Specific Context Views**
   - Strategist: Architecture, dependencies, patterns
   - Executor: Implementation details, specific files
   - Reviewer: Diffs, tests, risk analysis

#### Estimated Effort: 2 weeks

### 6) Resource System, Resource Types, and Resource Registry

#### Problem
Resources are currently defined inline within projects. The specification requires resources to be independently registered first-class entities with a type system, DAG relationships (physical/virtual), auto-discovery, and content-identity tracking. Tools need resource bindings to declare and resolve their resource dependencies.

#### Implementation Steps

1. **Resource Type Registry and CLI**
   - Implement 24 built-in resource types: 15 physical (`git-checkout`, `git`, `git-remote`, `git-branch`, `git-tag`, `git-commit`, `git-tree`, `git-tree-entry`, `git-stash`, `git-submodule`, `fs-mount`, `fs-directory`, `fs-file`, `fs-symlink`, `fs-hardlink`) and 9 virtual (`file`, `directory`, `symlink`, `commit`, `branch`, `tag`, `remote`, `submodule`, `tree`)
   - Implement resource type YAML parsing and validation for custom types
   - Implement `agents resource type add [<span style="color: cyan;">--update</span>]/remove/list/show` commands
   - Implement dynamic CLI subcommand registration (custom types create new `agents resource add` subcommands)

2. **Resource Registry and CLI**
   - Implement `agents resource add <type>/remove/list/show/tree` commands
   - Implement Resource Registry persistence in database
   - Implement DAG parent/child relationships with type constraints and cycle detection
   - Implement `agents resource link-child`/`unlink-child` for manual DAG management

3. **Auto-Discovery System**
   - Implement handler-driven child resource discovery (git-checkout discovers git + fs-directory worktree root; git discovers remotes, branches, tags, commits, stashes, submodules; git-commit discovers root git-tree; git-tree discovers tree entries + subtrees; fs-mount discovers root fs-directory; fs-directory discovers subdirectories, files, symlinks, hardlinks)
   - Implement resource reuse during discovery (link existing resources instead of duplicating)
   - Implement refresh mechanism for keeping discovered children up to date

4. **Physical/Virtual Resource Model**
   - Implement content hashing for identity tracking
   - Implement virtual resource linking (shared virtual parents for identical physical resources)
   - Implement divergence detection (unlink when content changes)

5. **Project-Resource Linking**
   - Replace `agents project add-resource`/`remove-resource` with `link-resource`/`unlink-resource`
   - Implement project-level overrides (read-only, alias)
   - Migrate any existing inline resource data to Resource Registry

6. **Resource Handlers**
   - Implement `GitCheckoutHandler` with auto-discovery, sandbox creation, checkpoint support
   - Implement `GitHandler` for git repository structure discovery (remotes, branches, tags, commits, stashes, submodules)
   - Implement `GitObjectHandler` for git-commit, git-tree, git-tree-entry (read-only access to git objects)
   - Implement `GitRefHandler` for git-branch, git-tag, git-stash (read/write ref manipulation)
   - Implement `GitConfigHandler` for git-remote, git-submodule (read-only config access)
   - Implement `FilesystemHandler` with auto-discovery for fs-mount, fs-directory, fs-file, fs-symlink, fs-hardlink
   - Implement handler plugin system for custom resource types

#### Estimated Effort: 5 weeks

### 7) MCP Integration, Tool System, Skill System, and Tool-Resource Bindings

#### Problem
No tool or skill abstraction exists. The specification defines tools as independently registered operations managed via `agents tool` CLI commands, and skills as namespaced collections of tools managed via `agents skill` CLI commands. Tools can be sourced from MCP servers, Agent Skills folders, built-ins, and custom code. Tools also need resource bindings to declare and resolve their dependencies on resources.

#### Implementation Steps

1. **Tool Registry and CLI**
   - Implement tool YAML parsing and validation (including `resources` section for resource slots)
   - Implement `agents tool add [<span style="color: cyan;">--update</span>]/remove/list/show` commands
   - Implement Tool Registry persistence in database
   - Implement anonymous tool support (inline definitions without registration)

2. **Skill Registry and CLI**
   - Implement skill YAML parsing and validation
   - Implement `agents skill add [<span style="color: cyan;">--update</span>]/remove/list/show/tools` commands
   - Implement hierarchical skill composition (includes) with per-tool metadata overrides
   - Implement Skill Registry persistence in database
   - Implement named tool references (resolving from Tool Registry) and anonymous inline tools

3. **Tool-Resource Binding System**
   - Implement resource slot parsing and validation in tool YAML
   - Implement three binding modes: contextual, static, parameter
   - Implement binding resolution at activation time (contextual/static) and invocation time (parameter)
   - Implement resource type compatibility validation
   - Implement built-in tool implicit resource bindings
   - Inject bound resources into `ToolExecutionContext.resources`

4. **MCP Tool Adapter**
   <div class="highlight"><pre><code>
   <span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">MCPToolAdapter</span>:
       <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">wrap_mcp_tool</span>(self, tool) -&gt; Tool:
           <span style="opacity: 0.7;"># Add sandbox interception</span>
           <span style="opacity: 0.7;"># Add change tracking</span>
           <span style="opacity: 0.7;"># Add capability metadata</span>
           <span style="opacity: 0.7;"># Add resource binding support</span>
   </code></pre></div>

5. **Tool Capability Metadata**
   <div class="highlight"><pre><code>
   <span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">ToolCapability</span>:
       read_only: <span style="color: cyan;">bool</span>
       write_scope: <span style="color: cyan;">list</span>[<span style="color: cyan;">str</span>]       <span style="opacity: 0.7;"># References resource slot names</span>
       checkpointable: <span style="color: cyan;">bool</span>
       idempotent: <span style="color: cyan;">bool</span>
       side_effects: <span style="color: cyan;">list</span>[<span style="color: cyan;">str</span>]
   </code></pre></div>

6. **External MCP Server Support**
   <div class="highlight"><pre><code>
   <span style="opacity: 0.7;"># In tool or skill YAML configuration</span>
   <span style="color: cyan; font-weight: 600;">mcp_servers</span>:
     - <span style="color: cyan;">name</span>: github
       <span style="color: cyan; font-weight: 600;">command</span>: <span style="color: #66cc66;">&quot;npx @anthropic/mcp-github&quot;</span>
       <span style="color: cyan; font-weight: 600;">env</span>: {GITHUB_TOKEN: &quot;${GITHUB_TOKEN}&quot;}
   </code></pre></div>

7. **Agent Skills Adapter**
   - Implement SKILL.md frontmatter parsing for discovery
   - Implement progressive disclosure (metadata → instructions → resources)
   - Implement sandboxed script execution

8. **Metadata Override System**
   - Implement shallow-merge override logic for tool capability metadata
   - Support overrides at skill-level (tool refs), include-level (tool_overrides), and actor graph node-level
   - Built-in tool metadata is not overridable

#### Estimated Effort: 5 weeks

### 8) Implement Validation and Semantic Error Prevention

#### Problem
Current validation is a stub. The specification requires multi-layer semantic validation. Validations are now a specialized subtype of Tool — they extend the Tool class with a `mode` (required/informational) and a structured JSON return format (`passed`, `message`, `data`). They can be attached to resources directly, through projects, or through plans.

#### Implementation Steps

1. **Decision-Time Validation**
   - Validate choices during Strategize
   - Check alternatives for feasibility
   - Record validation in decision metadata

2. **Execution-Time Guards**
   <div class="highlight"><pre><code>
   <span style="opacity: 0.7;"># Actor references a skill containing validation tools</span>
   <span style="color: cyan; font-weight: 600;">skills</span>:
     - local/semantic-validators   # validate_api_compatibility,
   <span style="opacity: 0.7;">                                # check_invariants, verify_test_coverage</span>
   </code></pre></div>

3. **Validation as Tool Subtype**
   <div class="highlight"><pre><code>
   <span style="opacity: 0.7;"># Register validations (tool subtypes)</span>
   agents validation add <span style="color: cyan;">--config</span> ./validations/run-tests.yaml <span style="color: cyan;">--required</span> local/run-tests
   agents validation add <span style="color: cyan;">--config</span> ./validations/lint-check.yaml <span style="color: cyan;">--required</span> local/lint-check

   <span style="opacity: 0.7;"># Attach to resource (directly or scoped to a project)</span>
   agents validation attach <span style="color: cyan;">--project</span> my-api my-api-repo local/run-tests
   agents validation attach my-api-repo local/lint-check
   </code></pre></div>

4. **Validation Class Inheritance**
   - Implement Validation as a class extending Tool
   - Reuse Tool Registry, binding resolution, and execution flow
   - Add only: mode field, return format enforcement, attachment scoping

5. **Tool Wrapping**
   - Implement `wraps` field resolution: validate wrapped Tool exists at registration time, store reference
   - Implement `transform` function: sandboxed Python execution that converts wrapped Tool output to `{ "passed", "message", "data" }`
   - Implement property inheritance from wrapped Tool (`input_schema`, `resource_slots`, `timeout`) with override semantics
   - Enforce read-only semantics on wrapped Tool invocation regardless of wrapped Tool's `writes` flag
   - Emit registration-time warning when wrapping a Tool with `writes: true`
   - Implement `argument_mapping` field: map Validation input arguments to wrapped Tool input arguments with support for renaming and fixed values
   - (Deferred) Wrapped Tool deduplication: when multiple Validations wrap the same Tool with identical forwarded arguments, invoke it once and fan out output to each `transform`. Deferred due to complexity around argument equivalence and cache invalidation during fix-then-revalidate loops
   - Implement default transform (pass-through for output already containing `passed` field)

#### Estimated Effort: 2 weeks

### 9) Connect LangGraph to Plan Lifecycle

#### Problem
The reactive/LangGraph infrastructure exists but isn't connected to the main plan workflow.

#### Implementation Steps

1. **Create Unified Plan Graph**
   <div class="highlight"><pre><code>
   <span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">PlanLifecycleGraph</span>:
       <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">strategize_subgraph</span>(self) -&gt; StateGraph
       <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">execute_subgraph</span>(self) -&gt; StateGraph
       <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">apply_subgraph</span>(self) -&gt; StateGraph
   </code></pre></div>

2. **Wire Phase Transitions**
   - `use` command triggers strategize graph
   - `execute` command triggers execute graph
   - `apply` command triggers apply graph

3. **Remove Linear Pipeline**
   - Replace tell/build/apply with graph execution
   - Maintain backward compatibility at CLI level

#### Estimated Effort: 1 week

### Implementation Roadmap

#### Phase 1: Foundation (8-10 weeks)
1. Tool-based resource modification (critical foundation)
2. Sandbox infrastructure
3. Decision tree system

#### Phase 2: Core Systems (10-12 weeks)
4. Advanced Context Management System (ACMS) — UKO, CRP, strategies, fusion, budget
5. Actor system with behavioral definitions
6. Resource system, resource types, and resource registry
7. MCP integration, tool system, skill system, and tool-resource bindings

#### Phase 3: Validation and Integration (3 weeks)
8. Validation and semantic error prevention
9. Connect LangGraph to plan lifecycle

#### Phase 4: Production Hardening (4 weeks)
10. Checkpointing and rollback
11. Cost controls and rate limiting
12. Security fixes (remove eval, fix async)

### Total Estimated Timeline: 6-7 months

### Key Success Metrics

1. **Multi-file generation**: Can generate a REST API with routes/, models/, tests/
2. **Safe execution**: All changes happen in sandbox, reviewed before apply
3. **Decision correction**: Can correct a decision and recompute only affected work
4. **Scale to large codebases**: ACMS with UKO, pluggable strategies, and fusion can work with 10K+ file projects efficiently
5. **Semantic safety**: Catches breaking changes before they're applied

### Migration Strategy

The implementation can proceed incrementally:

1. Start with resource abstraction (enables everything else)
2. Add sandboxing to existing execute phase
3. Gradually replace text parsing with tool invocations
4. Build decision tree alongside existing flow
5. Enhance context as indexing comes online

This allows the system to remain functional during development while progressively adding the architectural improvements described in the specification.

## CleverAgents Architecture FAQ

### Q: How does CleverAgents handle persistent repository knowledge beyond ephemeral context windows?

**What exists today architecturally**: The specification defines the Advanced Context Management System (ACMS) — a sophisticated, pluggable, strategy-driven framework that goes far beyond ephemeral context windows. At its core are three innovations: (1) the Universal Knowledge Ontology (UKO), an inheritance-based RDF ontology that represents any resource at multiple abstraction levels with full provenance and temporal versioning; (2) the Context Request Protocol (CRP), through which actors dynamically declare what information they need at what detail level; and (3) a pluggable Strategy Framework with a Fusion Coordinator that runs multiple retrieval strategies in parallel and merges their results into a budget-respecting context payload. Underlying this is the Decision Tree structure which provides a durable, queryable record of every choice made during planning.

**How the persistent model works in practice**:

When a strategy actor analyzes a codebase during the Strategize phase, the ACMS assembles context dynamically using the CRP. The actor issues `request_context` calls specifying focus nodes (UKO URIs), breadth (hop count), depth (SIGNATURE/SUMMARY/STUB/FULL), and optional depth gradients. The Strategy Coordinator runs applicable strategies (e.g., `breadth-depth-navigator` for graph traversal, `semantic-embedding` for similarity search, `plan-decision-context` for historical decisions) in parallel, and the Fusion Engine deduplicates, resolves detail conflicts, and packs the results into the available budget.

Each decision creates a comprehensive Decision record that includes:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">context_snapshot</span>:
  <span style="color: cyan; font-weight: 600;">hot_context_hash</span>: str <span style="opacity: 0.7;"># Cryptographic hash of the exact context</span>
  <span style="color: cyan; font-weight: 600;">hot_context_ref</span>: str <span style="opacity: 0.7;"># Pointer to the full stored snapshot</span>
  <span style="color: cyan; font-weight: 600;">relevant_resources</span>: list[ResourceRef] <span style="opacity: 0.7;"># Every file/symbol that influenced this decision</span>
  <span style="color: cyan; font-weight: 600;">actor_state_ref</span>: str <span style="opacity: 0.7;"># Complete LangGraph checkpoint</span>
  <span style="color: cyan; font-weight: 600;">uko_focus_nodes</span>: list[UKO_URI] <span style="opacity: 0.7;"># UKO nodes that were the focus of this context assembly</span>
  <span style="color: cyan; font-weight: 600;">strategies_used</span>: list[str] <span style="opacity: 0.7;"># Which ACMS strategies contributed to this context</span>
</code></pre></div>

This means when the system decides "refactor the authentication module to use async patterns," it permanently records:
- Which UKO nodes (files, classes, functions) were the focus of context assembly
- Which strategies retrieved context and at what detail levels
- What symbols and dependencies were traced via UKO graph traversal
- The exact code state that was analyzed (with temporal versioning via `validFrom`/`validUntil`)
- The reasoning chain that led to this choice
- Alternative approaches that were considered but rejected

**The three-tier memory architecture enables scale**:

1. **Hot tier**: Immediate working context assembled by the ACMS — the Fusion Engine's output loaded into the LLM context window, dynamically computed based on the actor's model context window minus response reserve and tool definitions
2. **Warm tier**: Recent decisions and their contexts from this plan tree — quickly accessible, retained for `context.tiers.warm.retention-hours` (default: 24h), queryable via the `plan-decision-context` strategy
3. **Cold tier**: Historical decisions from past plans on this codebase — queryable via `temporal-archaeology` strategy, retained for `context.tiers.cold.retention-days` (default: 90 days)

When working on a 50,000 file codebase, the system doesn't need to hold all files in memory. Instead:
- Hot context focuses on the immediate task via demand-driven CRP requests (e.g., `request_context` with focus on 10-20 UKO nodes, breadth=2, depth_gradient={0:FULL, 1:SUMMARY, 2:SIGNATURE})
- Warm context maintains the decision chain via the `plan-decision-context` strategy, with skeleton compression propagating parent plan context to child plans
- Cold context provides historical patterns via the `temporal-archaeology` strategy ("last time we refactored auth, we also had to update these services")

**Why this scales to massive codebases**:

The key insight is that software development is inherently local - even in huge codebases, individual changes typically touch a bounded set of files. The Decision Tree captures these localities. When converting Firefox to Rust (your example), the system would:

1. Make high-level architectural decisions and enforce invariants (captured as root decision nodes)
2. Decompose into major subsystem conversions (each a `subplan_parallel_spawn` or `subplan_spawn` decision spawning child plans)
3. Each subsystem plan makes decisions about its modules, inheriting applicable invariants
4. Module plans make decisions about individual files

At each level, only the relevant context is loaded. The persistent decision graph means we can always reconstruct why we're converting a particular module and what constraints apply from higher-level decisions.

**Concrete example of persistence in action**:

<div class="highlight"><pre><code>
Plan: Convert Firefox Renderer to Rust
├── [<span style="color: magenta;">invariant_enforced</span>] &quot;Maintain API compatibility with existing C++ callers&quot;
├── [<span style="color: magenta;">invariant_enforced</span>] &quot;All converted modules must pass existing C++ test suites&quot;
├── [<span style="color: magenta;">strategy_choice</span>] Architecture approach: Start with leaf modules, work inward
│   Context: Analyzed module dependency graph, 2,847 modules total
│   Resources: module_graph.json, architecture_docs.md
│   
├── [<span style="color: magenta;">subplan_parallel_spawn</span>] Phase 1: Convert utility libraries (no external deps)
│   └── [<span style="color: magenta;">subplan_spawn</span>] Convert string_utils module
│       └── Plan: 01KH29R8WPKPBHRY7Q0NA9XW86
│           ├── [<span style="color: magenta;">prompt_definition</span>] &quot;Convert string_utils module to Rust&quot;
│           ├── [<span style="color: magenta;">invariant_enforced</span>] &quot;Maintain API compatibility with existing C++ callers&quot;
│           ├── [<span style="color: magenta;">implementation_choice</span>] Use Rust&#x27;s String type, not custom implementation
│           │   Context: Analyzed 47 string_utils.cpp functions
│           │   Resources: string_utils.cpp, string_utils.h, 12 dependent files
│           │   Rationale: Rust&#x27;s String provides same guarantees with better ergonomics
│           └── ...
</code></pre></div>

Even months later, we can query: "Why did we use Rust's String type?" and get the exact context and reasoning, without reprocessing the entire codebase.

### Q: How does the system compute task-specific dependency closures for large-scale operations?

**What exists today architecturally**: The specification defines multiple mechanisms for computing and maintaining minimal dependency closures. The execution blueprint produced during the Strategize phase doesn't just list steps - it includes a complete dependency graph with explicit scoping for each operation.

**How dependency closure computation works**:

During the Strategize phase, the strategy actor employs several mechanisms to compute precise dependency closures:

1. **Resource-aware analysis**: The actor uses specialized skills to trace dependencies:
   <div class="highlight"><pre><code>
   <span style="opacity: 0.7;"># Pseudocode of what happens inside a strategy actor</span>
   <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">compute_closure_for_refactoring</span>(target_module):
       closure = ResourceClosure()
       
       <span style="opacity: 0.7;"># Direct file dependencies</span>
       closure.add_files(find_imports(target_module))
       closure.add_files(find_includes(target_module))
       
       <span style="opacity: 0.7;"># Symbol dependencies</span>
       <span style="color: magenta; font-weight: 600;">for</span> symbol <span style="color: magenta; font-weight: 600;">in</span> extract_exported_symbols(target_module):
           closure.add_files(find_symbol_usage(symbol, scope=<span style="color: #66cc66;">&#x27;project&#x27;</span>))
       
       <span style="opacity: 0.7;"># Test dependencies</span>
       closure.add_files(find_tests_for_module(target_module))
       
       <span style="opacity: 0.7;"># Build system dependencies</span>
       closure.add_files(find_build_references(target_module))
       
       <span style="color: magenta; font-weight: 600;">return</span> closure
   </code></pre></div>

2. **Hierarchical scoping**: When spawning child plans (via `subplan_spawn` or `subplan_parallel_spawn`), each child plan receives:
   - An explicit `relevant_resources` list
   - A `sandbox_strategy` appropriate for those resources
   - Clear boundaries of what it can and cannot modify
   - The parent plan's effective invariant view (already reconciled from action, project, and global scopes)

3. **Decision-based tracking**: Each `subplan_spawn` decision records the child plan it creates, and `subplan_parallel_spawn` decisions group parallel child plans:
   <div class="highlight"><pre><code>
   <span style="opacity: 0.7;"># Individual child plan spawn</span>
   <span style="color: cyan; font-weight: 600;">decision_type</span>: subplan_spawn
   <span style="color: cyan; font-weight: 600;">chosen_option</span>: <span style="color: #66cc66;">&quot;Refactor authentication module&quot;</span>
   <span style="color: cyan; font-weight: 600;">downstream_plan_ids</span>: [&quot;plan-auth-refactor-123&quot;]
   <span style="color: cyan; font-weight: 600;">artifacts_produced</span>: 
     - <span style="color: cyan;">auth_module_files</span>: [&quot;auth.rs&quot;, &quot;auth_test.rs&quot;, &quot;auth_types.rs&quot;]
     - <span style="color: cyan;">api_updates</span>: [&quot;api/v2/login.rs&quot;, &quot;api/v2/logout.rs&quot;]
   
   <span style="opacity: 0.7;"># Parallel group of child plans</span>
   <span style="color: cyan; font-weight: 600;">decision_type</span>: subplan_parallel_spawn
   <span style="color: cyan; font-weight: 600;">chosen_option</span>: <span style="color: #66cc66;">&quot;Convert utility libraries in parallel&quot;</span>
   <span style="opacity: 0.7;"># Contains subplan_spawn children, each with their own downstream_plan_ids</span>
   </code></pre></div>

**Concrete example - Converting a subsystem to Rust**:

Let's trace how the system handles "Convert Firefox's Network Stack to Rust":

<div class="highlight"><pre><code>
STRATEGIZE PHASE:
1. Analyze network stack structure
   - Identifies 847 C++ files in netwerk/ directory
   - Traces public API surface (237 exported functions)
   - Maps internal dependencies (1,432 internal calls)
   
2. Compute minimal closure for Phase 1 (DNS resolver):
   - Core files: dns_resolver.cpp, dns_cache.cpp, dns_config.cpp (3 files)
   - Direct dependencies: 12 files in netwerk/base/
   - Test files: 8 test files specific to DNS
   - Build files: 2 moz.build files
   - Total closure: 25 files (not 847!)
   
3. Generate execution blueprint with child plans:
   - [<span style="color: magenta;">subplan_parallel_spawn</span>] DNS module conversions:
     - convert-dns-types: Closure of 5 files (type definitions)
     - convert-dns-cache: Closure of 8 files (cache + tests)  
     - convert-dns-resolver: Closure of 12 files (resolver + integration)
</code></pre></div>

**Why this is tractable even for massive codebases**:

The system leverages several key insights about real software:

1. **Modular boundaries exist**: Even in legacy codebases, there are natural boundaries
2. **Changes are incremental**: We don't convert 50,000 files atomically
3. **Dependencies are sparse**: Most modules depend on a small fraction of the codebase
4. **Interfaces are narrow**: Public APIs are much smaller than implementations

The Firefox example would decompose into ~1,000 bounded child plans (grouped via `subplan_parallel_spawn` decisions where independent), each touching 10-100 files. The parent plan tracks the overall architecture and enforces invariants, while each child plan maintains its focused closure.

**How we prevent closure explosion**:

- **Lazy expansion**: Dependencies are traced only as deep as needed for correctness
- **Interface-based boundaries**: When possible, work against stable interfaces
- **Incremental validation**: Each child plan validates its changes don't break dependents
- **Hierarchical merge strategies**: Parent plans resolve conflicts between child plan changes

### Q: What mechanisms enforce global consistency during parallel execution across many files?

**What exists today architecturally**: The sandbox model combined with hierarchical plan execution provides strong guarantees about consistency during parallel execution. This isn't just process isolation - it's semantic isolation with intelligent merge strategies.

**How the coordination mechanism prevents compound errors**:

1. **Complete isolation during execution**:
   Each plan executes in its own sandbox, which means:
   <div class="highlight"><pre><code>
   Plan A (refactoring auth module):
   - Sandbox A1: Contains only auth/*.cpp, auth_tests/*.cpp
   - Cannot see Plan B&#x27;s intermediate states
   - Cannot accidentally depend on Plan B&#x27;s half-done work
   
   Plan B (updating API endpoints):
   - Sandbox B1: Contains only api/*.cpp, api_tests/*.cpp  
   - Makes changes assuming current auth interface
   - Protected from Plan A&#x27;s intermediate refactoring
   </code></pre></div>

2. **Resource-specific sandbox strategies provide natural coordination**:
   <div class="highlight"><pre><code>
   Git repositories:
     - <span style="color: cyan;">Strategy</span>: git worktrees
     - <span style="color: cyan;">Coordination</span>: Git&#x27;s three-way merge algorithm
     - Conflict detection: Built into Git
     - <span style="color: cyan;">Rollback</span>: git reset/checkout
   
   <span style="color: cyan; font-weight: 600;">Databases</span>:
     - <span style="color: cyan;">Strategy</span>: Transaction isolation  
     - <span style="color: cyan;">Coordination</span>: MVCC (multi-version concurrency control)
     - Conflict detection: Serialization failures
     - <span style="color: cyan;">Rollback</span>: Transaction abort
   
   Cloud Infrastructure:
     - <span style="color: cyan;">Strategy</span>: Terraform workspaces
     - <span style="color: cyan;">Coordination</span>: State locking
     - Conflict detection: Resource conflicts in plan
     - <span style="color: cyan;">Rollback</span>: Previous state restoration
   </code></pre></div>

3. **Hierarchical merge resolution**:
   When child plans complete, the parent plan performs intelligent merging:
   <div class="highlight"><pre><code>
   <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">merge_subplan_results</span>(subplan_results):
       <span style="opacity: 0.7;"># Group by resource type</span>
       by_resource = group_by_resource_type(subplan_results)
       
       <span style="opacity: 0.7;"># Apply resource-specific merge strategies</span>
        <span style="color: magenta; font-weight: 600;">for</span> resource_type, changes <span style="color: magenta; font-weight: 600;">in</span> by_resource:
            <span style="color: magenta; font-weight: 600;">if</span> resource_type == <span style="color: #66cc66;">&#x27;git-checkout&#x27;</span>:
                merge_git_changes(changes)  <span style="opacity: 0.7;"># Three-way merge</span>
            <span style="color: magenta; font-weight: 600;">elif</span> resource_type == <span style="color: #66cc66;">&#x27;fs-mount&#x27;</span>:
                merge_fs_changes(changes)   <span style="opacity: 0.7;"># Copy-on-write reconciliation</span>
            <span style="color: magenta; font-weight: 600;">elif</span> resource_type.startswith(<span style="color: #66cc66;">&#x27;database&#x27;</span>):
                merge_db_changes(changes)   <span style="opacity: 0.7;"># Sequential application</span>
       
       <span style="opacity: 0.7;"># Validate merged state</span>
       run_integration_tests()
   </code></pre></div>

**Concrete example - Preventing cascading failures**:

Consider refactoring a shared authentication library used by 15 services:

<div class="highlight"><pre><code>
PARALLEL EXECUTION WITHOUT COORDINATION (what we prevent):
- Service A refactors to async auth → breaks Service B
- Service B compensates with workaround → breaks Service C  
- Service C changes error handling → breaks Services D, E, F
- Cascade of failures!

CLEVERAGENTS COORDINATED EXECUTION:
Parent Plan: Refactor auth library
├── [<span style="color: magenta;">invariant_enforced</span>] &quot;Auth library public API must remain backward compatible during transition&quot;
├── [<span style="color: magenta;">subplan_spawn</span>] Plan 1: Update auth library interface
│   Sandbox: Only auth library files
│   Output: New interface definition
│   
├── Barrier: Wait for Plan 1 completion
│   
├── [<span style="color: magenta;">subplan_parallel_spawn</span>] Plans 2-16: Update each service (in parallel)
│   Each sandbox: Only that service&#x27;s files
│   Each uses: New interface from Plan 1
│   No inter-service dependencies during execution
│   
└── Merge Phase:
    - Collect all service updates
    - <span style="color: yellow; font-weight: 600;">Apply</span> to main branch in order
    - Run integration tests
    - If conflicts: Parent plan resolves using semantic understanding
</code></pre></div>

**Advanced coordination patterns**:

1. **Optimistic concurrency with semantic conflict resolution**:
   <div class="highlight"><pre><code>
   Two child plans both modify api/user.rs:
   - Plan A: Adds async fn get_user_profile()
   - Plan B: Adds fn validate_user_permissions()
   
   Merge strategy:
   - Git merge succeeds (different functions)
   - Semantic validation ensures both functions work together
   - Parent plan adds integration glue if needed
   </code></pre></div>

2. **Checkpoint-based coordination**:
   <div class="highlight"><pre><code>
   Execution timeline:
   T1: Plan A creates checkpoint before major refactor
   T2: Plan B creates checkpoint before API changes
   T3: Plan A encounters error, rolls back to T1
   T4: Plan B completes successfully
   T5: Plan A retries with knowledge of B&#x27;s success
   </code></pre></div>

3. **Resource locking for critical sections**:
   <div class="highlight"><pre><code>
   When modifying shared schema files:
   - Acquire exclusive lock on schema resources
   - Make changes atomically
   - Release lock with new version
   - Other plans rebase on new schema
   </code></pre></div>

### Q: How does the system proactively prevent semantic errors before they propagate?

**What exists today architecturally**: The specification defines multiple layers of proactive error prevention that go far beyond traditional testing. This is a comprehensive defense-in-depth approach that catches semantic errors before they can propagate.

**Layer 1: Decision-time validation during Strategize**:

Every decision includes semantic validation:
<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">Decision</span>: Refactor payment module to async
<span style="color: cyan; font-weight: 600;">alternatives_considered</span>:
  - &quot;Convert to async/await patterns&quot; (chosen)
  - &quot;Use thread pool with channels&quot; (rejected: doesn&#x27;t integrate with async ecosystem)
  - &quot;Keep synchronous with timeout&quot; (rejected: doesn&#x27;t solve core latency issue)
<span style="color: cyan; font-weight: 600;">confidence_score</span>: <span style="color: yellow;">0.85</span>
<span style="color: cyan; font-weight: 600;">validation_performed</span>:
  - Checked all payment API consumers can handle async
  - Verified database driver supports async operations
  - Confirmed no regulatory requirement for sync processing
</code></pre></div>

**Layer 2: Execution-time semantic guards**:

The execution actor uses a tool node that references the independently registered `local/validate-api-compat` tool:

<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">actors</span>:
  <span style="color: cyan; font-weight: 600;">code_executor</span>:
    <span style="color: cyan; font-weight: 600;">type</span>: graph
    <span style="color: cyan; font-weight: 600;">skills</span>:
      - local/semantic-validators    # Contains validation tools for LLM tool-calling
    <span style="color: cyan; font-weight: 600;">nodes</span>:
      - <span style="color: cyan;">name</span>: semantic_validator
        <span style="color: cyan; font-weight: 600;">type</span>: tool
        <span style="color: cyan; font-weight: 600;">tool</span>: local/validate-api-compat <span style="opacity: 0.7;"># Named tool from Tool Registry</span>
</code></pre></div>

The `local/validate-api-compat` tool (independently registered via `agents tool add`) performs semantic validation — not just syntax checking. It extracts API signatures, finds breaking changes, checks affected consumers, and either auto-migrates or raises a `SemanticError` for manual review.

**Layer 3: Invariant enforcement through the decision tree**:

Invariants are attached at four scopes (global, project, action, plan) and managed via the unified `agents invariant` command or `--invariant` flags on creation commands. When a plan enters Strategize, the **Invariant Reconciliation Actor** (set via `--invariant-actor` on actions/plans/projects, or globally via `agents config set actor.default.invariant`) computes the effective invariant view by applying precedence rules (plan > project > global) to resolve conflicts. Each effective invariant is recorded as an `invariant_enforced` decision, making them visible, correctable, and auditable:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># The system collects, reconciles, and enforces semantic invariants</span>
<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">InvariantEnforcer</span>:
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">compute_effective_invariants</span>(self, plan):
        <span style="color: #66cc66;">&quot;&quot;&quot;Compute the effective invariant view using the Invariant Reconciliation Actor.&quot;&quot;&quot;</span>
        raw = self.collect_all_invariants(plan)
        reconciler = (
            self.get_plan_invariant_actor(plan)
            <span style="color: magenta; font-weight: 600;">or</span> self.get_project_invariant_actor(plan)
            <span style="color: magenta; font-weight: 600;">or</span> self.get_global_invariant_actor()
        )
        <span style="opacity: 0.7;"># Apply precedence: plan &gt; project &gt; global</span>
        <span style="color: magenta; font-weight: 600;">return</span> reconciler.reconcile(raw, precedence=[<span style="color: #66cc66;">&#x27;plan&#x27;</span>, <span style="color: #66cc66;">&#x27;project&#x27;</span>, <span style="color: #66cc66;">&#x27;global&#x27;</span>])
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">collect_all_invariants</span>(self, plan):
        <span style="color: #66cc66;">&quot;&quot;&quot;Collect invariants from all scopes accessible to this plan.&quot;&quot;&quot;</span>
        invariants = []
        invariants.extend(self.get_global_invariants())
        <span style="color: magenta; font-weight: 600;">for</span> project <span style="color: magenta; font-weight: 600;">in</span> plan.projects:
            invariants.extend(self.get_project_invariants(project))
        invariants.extend(self.get_action_invariants(plan.action))
        invariants.extend(self.get_plan_invariants(plan))
        <span style="color: magenta; font-weight: 600;">return</span> invariants
    
    <span style="opacity: 0.7;"># Example invariants at different scopes:</span>
    <span style="opacity: 0.7;"># Global:  &quot;Payment processing must be idempotent&quot;</span>
    <span style="opacity: 0.7;"># Project: &quot;Database transactions must complete within 5 seconds&quot;</span>
    <span style="opacity: 0.7;"># Action:  &quot;Test files must not import production secrets&quot;</span>
    <span style="opacity: 0.7;"># Plan:    &quot;All API calls over TCP must be mocked&quot;</span>
    
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">check_invariant_preservation</span>(self, changes, enforced_invariants):
        <span style="color: magenta; font-weight: 600;">for</span> invariant <span style="color: magenta; font-weight: 600;">in</span> enforced_invariants:
            <span style="color: magenta; font-weight: 600;">if</span> <span style="color: magenta; font-weight: 600;">not</span> self.verify_invariant(invariant, changes):
                <span style="color: magenta; font-weight: 600;">return</span> InvariantViolation(invariant, changes)
        <span style="color: magenta; font-weight: 600;">return</span> Success()
</code></pre></div>

**Layer 4: Predictive error prevention through pattern matching**:

The system learns from past failures:
<div class="highlight"><pre><code>
Error Pattern Database:
  - <span style="color: cyan;">pattern</span>: <span style="color: #66cc66;">&quot;Async conversion in payment module&quot;</span>
    <span style="color: cyan; font-weight: 600;">historical_failures</span>:
      - &quot;Race condition in payment confirmation&quot;
      - &quot;Timeout handling breaks idempotency&quot;
    <span style="color: cyan; font-weight: 600;">preventive_checks</span>:
      - &quot;Add explicit transaction boundaries&quot;
      - &quot;Verify idempotency keys are preserved&quot;
      - &quot;Check distributed lock acquisition&quot;
</code></pre></div>

**Concrete example - Preventing a subtle distributed systems bug**:

Scenario: Refactoring a service to use event sourcing:

<div class="highlight"><pre><code>
PROACTIVE CONTAINMENT IN ACTION:

1. Strategy Phase Semantic Analysis:
   - Decision: &quot;Convert order service to event sourcing&quot;
   - Semantic check: &quot;Event sourcing requires eventual consistency&quot;
   - Identifies: 3 services assume immediate consistency
   - Adds decision: &quot;Update dependent services for eventual consistency&quot;

2. Execution Phase Invariant Checking:
   - Detects: PaymentService.chargeCard() called after OrderCreated event
   - Semantic issue: Payment before order confirmation violates business rules
   - Automatic fix: Insert OrderConfirmed event requirement
   
3. Validation Node Catches Edge Case:
   - Discovers: Audit service expects synchronous order numbers
   - Impact: Async events break compliance reporting
   - Resolution: Add audit event buffer with guaranteed ordering
   
4. Pre-<span style="color: yellow; font-weight: 600;">Apply</span> Semantic Verification:
   - Simulates production event flow
   - Detects: Under high load, events can arrive out of order
   - Adds: Event ordering guarantees via vector clocks
</code></pre></div>

**Why this prevents issues that traditional testing misses**:

Traditional tests check "does the code work?" Our semantic containment asks:
- Does it preserve business invariants?
- Does it maintain architectural patterns?
- Does it respect distributed systems principles?
- Does it handle the edge cases we've seen before?

**Integration with Definition of Done (DoD)**:

Each plan's DoD includes semantic requirements:
<div class="highlight"><pre><code>
<span style="color: cyan; font-weight: 600;">definition_of_done</span>:
  <span style="color: cyan; font-weight: 600;">must</span>:
    - &quot;All API changes maintain backward compatibility&quot;
    - &quot;No increase in p99 latency&quot;
    - &quot;Audit trail remains complete&quot;
  <span style="color: cyan; font-weight: 600;">should</span>:
    - &quot;Improve code coverage by 10%&quot;
    - &quot;Reduce cyclomatic complexity&quot;
  <span style="color: cyan; font-weight: 600;">may</span>:
    - &quot;Optimize for memory usage&quot;
</code></pre></div>

The validation nodes enforce these semantics, not just test passage.

### Q: How does the system balance human supervision with autonomous operation?

**What exists today architecturally**: The specification defines a comprehensive automation profile system with 10 confidence thresholds (0.0–1.0) and 3 boolean safety flags controlling every aspect of human-vs-automated operation. This isn't a binary human/AI split — it's a continuously adjustable matrix where each threshold specifies the minimum confidence level for automatic operation, tunable per task, per project, or per organization.

**How the automation profiles work in practice**:

<div class="highlight"><pre><code>
manual Profile (all thresholds = 1.0):
  - Every phase transition pauses for human action
  - Every decision point pauses for human input
  - User sees: Context, alternatives, recommendation, confidence score
  - User provides: Explicit choice or custom guidance
  - Use case: New users, critical production changes, first-time codebase exploration

review Profile (phase thresholds = 0.0, decision thresholds = 1.0):
  - Phases run automatically (Strategize, Execute proceed without pausing)
  - Every decision within those phases pauses for human input
  - Apply is manual; transient retries and child plans are automatic
  - Use case: Teams that want to stay in the decision loop without triggering phases

supervised Profile (strategize thresholds = 0.0, execute/apply = 1.0):
  - Strategize runs automatically with autonomous decisions
  - System pauses before Execute for human review of strategy
  - Transient failures retried automatically
  - Use case: Projects where you trust planning but want to review before execution

cautious Profile (intermediate thresholds = 0.6-0.8):
  - System proceeds automatically only when Semantic Escalation reports high confidence
  - Escalates to human when uncertain (confidence below threshold)
  - Higher bars (0.8) for risky operations, lower bars (0.6) for safer ones
  - Use case: Gradual automation adoption, mixed-complexity projects

trusted Profile (most thresholds = 0.0, apply = 1.0):
  - Strategize and Execute run automatically with autonomous decisions
  - Validation failures self-fixed within strategy bounds
  - Child plans spawned automatically
  - System pauses before Apply for human diff review
  - Use case: Normal feature development, refactoring

autonomous Profile (all thresholds = 0.0 except apply = 1.0):
  - Everything automatic except Apply
  - Can revise its own strategy if execution hits a wall
  - Restores from checkpoints on failure
  - Use case: Well-understood projects, batch operations

ci Profile (all thresholds = 0.0, sandbox + checkpoints required):
  - Complete end-to-end automation including Apply
  - Sandbox and checkpoints remain mandatory for safety
  - Unsafe tools blocked
  - Use case: CI/CD pipelines, headless batch jobs, scheduled automation

full-auto Profile (all thresholds = 0.0):
  - Complete end-to-end automation including Apply
  - No sandbox or checkpoint requirements
  - Unsafe tools allowed
  - Use case: Routine updates, environments with external safety mechanisms

Custom profiles with intermediate thresholds (e.g., 0.3, 0.5, 0.7):
  - Fine-grained control: auto-execute with confidence >= 0.5 but escalate below
  - Different thresholds per flag: low bar for retries, high bar for strategy revision
  - Enables &quot;trust but verify&quot; patterns without binary on/off
  - Use case: Teams building confidence gradually, mixed-risk projects
</code></pre></div>

**The decision correction mechanism enables progressive automation**:

The `agents plan correct` command is crucial for building trust:

<div class="highlight"><pre><code>
<span style="opacity: 0.7;"># User observes AI made suboptimal choice</span>
agents plan tree &lt;plan_id&gt;
<span style="opacity: 0.7;"># Sees: [Decision] &quot;Use REST API for service communication&quot;</span>

<span style="opacity: 0.7;"># User knows gRPC would be better for this use case</span>
agents plan correct &lt;decision_id&gt; <span style="color: cyan;">--mode</span>=revert <span style="opacity: 0.7;">\</span>
  <span style="color: cyan;">--guidance</span> &quot;Use gRPC instead of REST. This service requires streaming 
             updates and binary protocol efficiency. Set up protocol 
             buffer definitions and generate client/server stubs.&quot;

<span style="opacity: 0.7;"># System:</span>
<span style="opacity: 0.7;"># 1. Marks original decision as superseded</span>
<span style="opacity: 0.7;"># 2. Creates new decision with user guidance</span>
<span style="opacity: 0.7;"># 3. Recomputes ONLY affected downstream decisions</span>
<span style="opacity: 0.7;"># 4. Preserves all unrelated work</span>
</code></pre></div>

**Progressive trust building through automation profiles**:

New users typically follow this progression:
1. Start with `manual` to understand system behavior
2. Move to `supervised` as confidence in the planning phase builds, or customize a profile with intermediate thresholds (e.g., 0.5) for gradual autonomy
3. Adopt `trusted` for routine development tasks
4. Enable `auto` for well-understood projects
5. Use `full-auto` for low-risk batch operations

**Real autonomy through semantic understanding**:

True autonomy isn't about removing humans - it's about the system understanding when it needs help:

<div class="highlight"><pre><code>
<span style="color: magenta; font-weight: 600;">class</span> <span style="color: cyan; font-weight: 600;">AutonomyController</span>:
    <span style="color: magenta; font-weight: 600;">def</span> <span style="color: cyan; font-weight: 600;">assess_decision_confidence</span>(self, decision, context, profile):
        factors = {
            <span style="color: #66cc66;">&#x27;past_success_rate&#x27;</span>: self.get_historical_success(decision.type),
            <span style="color: #66cc66;">&#x27;codebase_familiarity&#x27;</span>: self.get_familiarity_score(context.project),
            <span style="color: #66cc66;">&#x27;risk_assessment&#x27;</span>: self.evaluate_risk(decision),
            <span style="color: #66cc66;">&#x27;invariant_complexity&#x27;</span>: self.analyze_invariants(decision)
        }
        
        confidence = self.compute_confidence(factors)  <span style="opacity: 0.7;"># Returns 0.0–1.0</span>
        threshold = profile.get_threshold(decision.flag)  <span style="opacity: 0.7;"># From profile</span>
        
        <span style="color: magenta; font-weight: 600;">if</span> confidence &gt;= threshold:
            <span style="color: magenta; font-weight: 600;">return</span> ProceedAutonomously(decision, confidence)
        <span style="color: magenta; font-weight: 600;">else</span>:
            <span style="opacity: 0.7;"># Confidence below profile threshold — escalate to human</span>
            <span style="color: magenta; font-weight: 600;">return</span> RequestHumanGuidance(decision, confidence, threshold, factors)
</code></pre></div>

**Concrete example - Autonomous handling of a complex refactoring**:

<div class="highlight"><pre><code>
Scenario: &quot;Modernize legacy e-commerce system&quot;

INITIAL PLAN (Full Automation Mode):
1. System analyzes 50,000 line codebase
2. Identifies modernization opportunities
3. Creates plan with 47 child plans

AUTONOMOUS EXECUTION WITH SMART ESCALATION:

[<span style="color: magenta;">subplan_parallel_spawn</span>] Plans 1-15: Update utility functions (executes autonomously)
- Confidence: 0.95 (straightforward transformations)
- Result: Success

[<span style="color: magenta;">subplan_spawn</span>] Plan 16: Refactor payment processing
- Confidence: 0.4 (critical business logic)
- [<span style="color: magenta;">invariant_enforced</span>] &quot;Preserve exact penny rounding behavior&quot;
- <span style="color: yellow; font-weight: 600;">Action</span>: ESCALATES to human
- Human provides: &quot;Preserve exact penny rounding behavior&quot;
- Continues autonomously with constraint

[<span style="color: magenta;">subplan_parallel_spawn</span>] Plans 17-30: UI component updates (executes autonomously)
- Confidence: 0.9 (isolated changes)
- Result: Success

[<span style="color: magenta;">subplan_spawn</span>] Plan 31: Database schema migration
- Detects: Would require 6-hour downtime
- <span style="color: yellow; font-weight: 600;">Action</span>: ESCALATES to human
- Human provides: &quot;Use online migration with feature flags&quot;
- Re-plans with zero-downtime approach

[<span style="color: magenta;">subplan_parallel_spawn</span>] Plans 32-47: Complete autonomously
</code></pre></div>

**The path to greater autonomy**:

The system becomes more autonomous through:

1. **Learning from corrections**:
   - Every correction teaches the system about user preferences
   - Patterns emerge: "This team always prefers gRPC for microservices"
   - Future decisions incorporate these learnings

2. **Building project-specific context**:
   - Each successful plan adds to project knowledge
   - System learns codebase patterns, team conventions, business rules
   - Confidence increases with familiarity

3. **Hierarchical delegation**:
   - Proven child plan patterns become fully autonomous
   - Human focuses on high-level decisions
   - System handles implementation details

4. **Semantic safety nets**:
   - Comprehensive invariant checking reduces risk
   - Rollback capabilities provide recovery path
   - Humans can trust system won't cause catastrophic failures

### Q: What's actually implemented today versus planned for the future?

**Concrete implementations in the architecture**:

1. **Decision Tree with Complete Context Capture**
   - Full schema defined
   - Storage model specified
   - Correction mechanism detailed
   - Query patterns established

2. **Hierarchical Plan System**
   - Spawning mechanism defined (sequential `subplan_spawn` and parallel `subplan_parallel_spawn`)
   - Execution semantics specified (child plans are full Plans with their own decision trees)
   - Invariant inheritance from parent plans, projects, and global scope
   - Merge strategies documented
   - Failure handling described

3. **Resource-Aware Sandbox Isolation**
   - Multiple strategies defined (git worktree, filesystem overlay, transactions)
   - Lazy sandboxing for efficiency
   - Resource-specific merge algorithms
   - Cleanup behavior specified

4. **Multi-Layer Error Prevention**
   - Decision validation during planning
   - Semantic validation nodes
   - Invariant enforcement
   - Definition of Done checking

5. **Graduated Automation Controls**
   - Three levels clearly defined
   - Decision correction without full re-execution
   - Confidence-based escalation
   - Progressive trust building

**Near-term implementations** (architecture complete, engineering straightforward):

1. **Memory Tier Management**
   - Hot/warm/cold distinction clear
   - Context loading patterns defined
   - Just needs LRU cache and storage backend

2. **Cross-Plan Learning**
   - Decision history provides training data
   - Pattern extraction is standard ML
   - Confidence scoring is well-understood

3. **Cost/Risk Estimation**
   - Dedicated estimation actor role defined
   - Historical data provides baselines
   - Standard prediction problem

4. **Extended Validation Patterns**
   - Pluggable validation architecture
   - Project-specific rules as configuration
   - Industry patterns can be packaged

**Research territory** (requires innovation but architecture supports):

1. **Optimal Context Selection for 100K+ file codebases**
   - Current: Heuristic-based selection
   - Research: ML-driven relevance ranking
   - Architecture supports: Any selection algorithm can plug in

2. **Automated Invariant Discovery**
   - Current: User-defined invariants
   - Research: Mining invariants from code patterns
   - Architecture supports: Invariants are just validation rules

3. **Cross-Project Knowledge Transfer**
   - Current: Project-specific learning
   - Research: Generalized pattern recognition
   - Architecture supports: Cold tier can span projects

4. **Fully Autonomous Recovery Strategies**
   - Current: Rollback and retry with guidance
   - Research: Automatic error understanding and fixing
   - Architecture supports: Recovery is just another plan type

**Why we can confidently handle Firefox-scale projects**:

The architecture doesn't require magical AI breakthroughs. It requires:
- **Hierarchical decomposition**: ✓ Fully specified
- **Bounded context operations**: ✓ Dependency closure computation defined
- **Parallel execution with isolation**: ✓ Sandbox model complete
- **Semantic validation**: ✓ Multi-layer approach specified
- **Progressive automation**: ✓ Automation profiles and correction defined

The difference between handling a 1,000 file project and a 100,000 file project is:
- More child plans (hierarchical decomposition handles this)
- Larger cold storage (standard database scaling)
- Better context selection (improves with use but works with heuristics)
- More validation patterns (accumulate over time)

This isn't speculative architecture astronautics - it's applying proven distributed systems principles to AI agent coordination. The innovation is in the integration, not in requiring fundamental breakthroughs.

