Decapod Documentation

Decapod is a daemonless, repo-native governance kernel for AI coding agents. It turns human intent into bounded, durable, and proof-backed agent work.

This book explains the product, its execution model, and the repository contracts used by humans, agents, and reviewers.


πŸš€ Getting Started

  • Introduction: What is Decapod? Learn about the governance gap and the core pillars of repo-native agent control.
  • Quickstart: Install, initialize, and run your first agent handshake and validation in under five minutes.
  • Mental Model: Understand how agents, tasks, sessions, and workspaces interact.
  • Configuration: Structure your repository config, enable cloud backends, and configure containerization.

πŸ”„ Governed Workflows

Learn how agents move through the lifecycle of planning, execution, validation, and completion.


πŸ’‘ Core Concepts

Deep dive into the architecture and mechanisms that make Decapod unique.


πŸ“– Reference Manual

Hard specifications, command lists, configuration schemas, and error codes.


πŸ› οΈ Developer Resources

To contribute or integrate Decapod into your platform:

Introduction

Decapod occupies a specific layer in the delivery system:

Models produce intelligence.
Agents perform work.
Repositories preserve state.
Decapod governs the transition from intent to proof.

Reliability is designed, not hoped for. As agents make code generation easier, the differentiator is whether an organization can trust what was generated. Decapod turns that trust requirement into repository-native intent, boundaries, durable state, validation, supported recovery, and evidence.

Decapod is a daemonless, repo-native governance kernel for AI coding agents. It turns human intent into bounded, durable, and proof-backed agent work.

That substrate is .decapod/: the project-local state layer where intent, selected context, workspace custody, protected boundaries, validation evidence, and completion status become durable and inspectable. Agents can come and go; the repository keeps the work bounded, attributable, resumable, and provable.

The execution problem

AI agents make software easier to direct, but natural language alone does not make execution reliable. People still have to notice drift, restore lost context, resolve conflicting work, recognize false completion, and prompt an agent to continue after a recoverable failure. Decapod moves those execution burdens into a governed system.

Chat transcripts and tool logs are useful during a run, but they are not a durable source of project truth. A governed Decapod run should be recoverable without trusting the original conversation: another agent, human reviewer, or CI system can inspect repository state to understand what was requested, what was understood, which boundaries applied, which workspace was used, what validation ran, and whether the work is complete.

How governance produces convergence

Convergence is a concrete execution property. The agent preserves the accepted intent, works within explicit boundaries, maintains durable state, responds to validation, remediates supported failures, and produces evidence before completion.

  1. Repo-Native State: Governed execution state, from accepted tasks to architectural specifications and proof artifacts, lives with the repository under .decapod/. External trackers may remain the organizational system of record; Decapod governs accepted work at the execution layer (see Configuration).
  2. Isolated Execution: Decapod automates the creation of isolated git worktrees and (optionally) Docker containers for every task. This prevents environment corruption and race conditions, especially in concurrent multi-agent workflows.
  3. Explicit Intent: The agent records its interpretation in versioned plans, todos, and living specifications before implementation proceeds.
  4. Proof-Backed Completion: "Done" is not merely a claim an agent makes. Publication requires the applicable validation gates and evidence to pass.

Responsibility boundaries

  • Human: expresses intent, provides judgment, and approves meaningful outcomes.
  • Agent: interprets the request and repository, performs the work, authors living specifications, follows validation feedback, and gathers evidence.
  • Decapod: makes accepted intent and boundaries explicit, maintains governance state, validates invariants, and blocks publication when required conditions are unsatisfied.
  • Repository: preserves governed state, custody, history, and proof across processes, models, harnesses, and Decapod invocations.

Decapod does not perform the agent's work or author the repository's meaning. It makes the agent's interpretation and evidence visible before publication. See Common Questions for the architectural boundaries behind that division.

Quickstart

Get Decapod operational in your repository in under five minutes.

1. Installation

Install the Decapod binary using Cargo:

cargo install decapod

For an existing Decapod repository, installation is followed by an autonomous, idempotent upgrade on the next normal command. decapod init, decapod validate, and other governed commands one-shot-import any residual legacy event JSONL into the canonical SQLite event store (decapod.db) and move those files under .decapod/data/.retired-jsonl/. Runtime writers never append to JSONL. Legacy SQLite stores recreated by an older binary are copied forward and removed. Existing override body bytes are preserved while sections are rendered into fenced documentation source areas with visible authoring instructions; unsafe or ambiguous authority fails closed.

2. Initialization

Initialize your repository. This is the only human-facing setup command: use --backend cloud when the repository should use the Propodus todo service. Initialization creates the .decapod/ directory and scaffolds the initial agent entrypoints (AGENTS.md, etc.). .decapod/ is the repo-native substrate where governed agent work records intent, context, custody, boundaries, validation evidence, and completion state. Agents will routinely run this during validation stages with the --proof flag for non-interactive agent-driven autonomous upgrades (see Configuration and Constitution).

decapod init
# For Propodus-backed todos:
decapod init --backend cloud

3. Orientation

Verify that your repository meets basic governance requirements. Decapod will check for the presence of mandatory files and invariants, then report whether the current repo state satisfies the governed execution contract. Agents will automatically call decapod validate as needed (see Proof & Validation).

decapod validate

4. The Agent Handshake

Before performing governed work, an agent must acquire a session. This establishes the agent's identity and permissions for the current work period so later task, workspace, and proof records are attributable (see CLI Reference). For cloud repositories, session acquisition first establishes local custody and then reuses or refreshes the machine-local Propodus session. Human users should never call this.

decapod session acquire

5. Claiming a Task

Identify a task from the backlog and claim it. The todo turns a user request into explicit project state and prevents other agents from attempting the same work simultaneously (see Single-Agent Workflows and Multi-Agent Workflows). Human users should never call this.

# Add a task if one doesn't exist
decapod todo add "Refactor the parser logic" --priority high

# List and claim
decapod todo list
decapod todo claim --id <task-id>

6. Entering the Workspace

Create an isolated git worktree for the task. Decapod turns workspace custody into inspectable repo state and ensures you are working in a clean environment, safely away from the main branch (see Workspace Sandboxing). Human users should never call this.

decapod workspace ensure

Note: If container_workspaces = true is set in your config (see Config Specification), add the --container flag to wrap the workspace in Docker (see Workspace Isolation Workflow).

7. Delivery and Proof

After the agent has performed the work in the isolated workspace, it runs validation. A failed gate leaves the task incomplete. When the result includes supported remediation, the agent corrects the violated artifact or state, re-runs validation, and continues. Only passing required gates and evidence permit the governed completion and publication transitions (see Artifact Reference). Human users should never call these commands.

decapod validate
decapod todo done --id <task-id>

Mental Model

Decapod is a governance kernel, not a prompt framework, model router, swarm manager, or wrapper. Humans usually express intent through an agent. The agent invokes Decapod through its CLI or structured RPC interface.

Each invocation is ephemeral. Decapod deliberately runs without a daemon. The repository is the durable execution surface: .decapod/ preserves the intent, selected context, workspace custody, boundaries, validation evidence, and publication state that should not live only in a chat transcript. One agent task may span many invocations, processes, models, or harnesses.

The Kernel Analogy

In an operating system, the kernel manages hardware resources and provides a stable API for user-space applications. Decapod performs a similar role for the repository:

  • Resources: Decapod manages git worktrees, containers, and the state of work units (Todos).
  • API: Agents call Decapod via a structured CLI or Decapod-specific RPC interface to request resources or validate their state.
  • Isolation: Decapod ensures that processes (agents) don't interfere with each other or the system's "main memory" (the root repository branch).
  • State: Decapod records the governed trail of the work in the repository so another agent, reviewer, or CI run can resume or audit without depending on the original transcript.

The governed execution loop

Decapod is not called for every mechanical step (see the Single-Agent Workflow). Agents invoke it at decision and state-transition boundaries:

  1. Intent Pressure: "I know what to do, but I need to formalize the spec." (see Explicit Intent, decapod todo add, decapod infer orientation)
  2. Boundary Pressure: "I'm about to touch a sensitive file or move to a new area." (see Workspace Sandboxing, decapod workspace ensure, decapod govern gatekeeper)
  3. Coordination Pressure: "I need to ensure no one else is working on this." (see Multi-Agent Workflows, decapod todo claim, decapod workspace status)
  4. Validation Pressure: "I need to test the work against repository invariants and respond to the result." (see Proof & Validation, decapod validate)
  5. Publication Pressure: "The required gates and evidence pass, so the work may move to a published state." (see decapod workspace publish, decapod todo done)

The lifecycle is:

intent β†’ interpretation β†’ bounded execution β†’ validation
       β†’ remediation when required β†’ revalidation
       β†’ publication β†’ proof-backed completion

A validation failure is not completion. When remediation is supported, the agent inspects the result, identifies the violated invariant, performs the sanctioned remediation, updates the relevant artifact, re-runs validation, and continues toward publication. Some failures require human judgment or cannot be recovered automatically; Decapod keeps those blockers visible.

Optional probabilistic observations

Decapod may be configured with the optional jev decision provider at the assurance boundary. After reconstructing governance, Decapod supplies Jev with the declared intent, proposed trajectory, governance obligations, and labeled snapshots of the existing plan, claims, trajectory, and validation artifacts. Missing and invalid artifact state stays explicit. Jev then returns one typed noul probability for the observation trajectory_satisfies_intent. This is an observation for Decapod to retainβ€”not a threshold, approval, policy waiver, boundary change, proof result, or completion claim. Decapod's existing interlocks and proof gates remain authoritative.

The default is local and provider-free:

[decision]
provider = "none"

Selecting provider = "jev" uses TYPESAFE_API_KEY from the machine environment, falling back to the machine-local ~/.local/share/decapod/secrets.json file. decapod init --decision-provider jev stores an explicitly supplied environment key there; missing credentials, network failure, timeout, or malformed data produces an explicit no_observation result and cannot authorize work. See Configuration and the TypeSafe API reference.

To revisit an existing setup, decapod init --refresh reopens the initialization questionnaire with current values as defaults. Enter keeps a setting; selecting another option enables or disables it. The refresh is non-destructive and requires an existing .decapod directory.

Each Jev attempt is also appended to the active trajectory's jev section of .decapod/governance.json. The ledger is a per-run evidence bundle: it can contain many keyed results in one PR, is schema-validated, and is reset when trajectory init begins a fresh run. Git history, not the working-tree file, preserves previous runs.

The developer-only evaluation corpus is opt-in and never runs as an ordinary test or CI dependency. With a TypeSafe credential, run:

DECAPOD_RUN_JEV_EVAL=1 TYPESAFE_API_KEY=... \
  cargo test --test decision_provider_live -- --ignored --nocapture

The corpus emits one JSON record per governance case with its human expectation, observation status, probability, latency, and API token usage when available. It gathers evidence about the observation; it does not define an approval threshold.

Epistemic Custody

A central concept in Decapod is Epistemic Custody. This is the preserved, auditable chain between the initial human intent, the context provided to the model, the assumptions made during implementation, and the final proof of completion. Decapod keeps that chain in governed repo state, making agent work fully falsifiable and transparent even after the original session has ended (see Artifact Reference).

Configuration

Decapod is configured via .decapod/config.toml (see the Config Specification Reference). This file is human-editable and should be committed to your repository.

The [init] Section

Controls how decapod init behaves.

  • specs: (bool) Whether to generate spec scaffolding under .decapod/managed/specs/.
  • diagram_style: ("ascii" or "mermaid") The style for generated architecture diagrams.
  • entrypoints: (list) Which agent entrypoints to create (e.g., ["AGENTS.md", "CLAUDE.md"]).

The [repo] Section

Defines project-specific policy and metadata.

  • product_name: The name of your project.
  • product_summary: A short description of what the project does.
  • architecture_direction: A high-level note on the architectural style (e.g., "modular monolith").
  • product_type: (e.g., "library", "service", "application").
  • done_criteria: Global "done" criteria that all tasks must satisfy.
  • primary_languages: A list of languages used in the repo.
  • container_workspaces: (bool) Whether to enforce container isolation for all work. Recommended for multi-agent workflows.

Project Overrides

For deep behavioral changes, use .decapod/OVERRIDE.md (see Config Overrides). Find the generated directive section and replace the instruction inside its four-backtick source block with Markdown or any documentation style you prefer. Decapod extracts the block contents as authority while the outer file renders them as code. Duplicate or Decapod-namespaced unknown directive headings outside a body block fail closed instead of applying partial authority.

Single-Agent Workflow

Even in single-agent environments, Decapod provides a rigorous structure that prevents common agentic errors and ensures high-quality delivery (see Agent-First Architecture).

The Standard Loop

  1. Orientation: The agent reads AGENTS.md and initializes its session (see CLI Reference).
    • decapod session acquire
  2. Intent Capture: The agent identifies its task and formalizes the intent (see Explicit Intent).
  3. Workspace Entry: The agent moves into an isolated environment (see Workspace Sandboxing).
    • decapod workspace ensure
  4. Implementation: The agent performs the work within the workspace.
  5. Validation and Recovery: The agent verifies the change against project policy. If a gate fails and remediation is supported, the agent corrects the violated artifact or state and re-runs validation.
    • decapod validate
  6. Publication and Completion: After required gates pass, the agent publishes through the governed workspace path, records proof, and marks the task as done (see Proof & Validation).
    • decapod workspace publish
    • decapod todo done --id <id> --validated

Key Benefits

  • Safe Iteration: The agent works on a dedicated branch, meaning it can't accidentally break the main build while experimenting.
  • Visible Interpretation: Agent-authored living specifications make the intended outcome and repository understanding reviewable before publication.
  • Verifiable Outcome: The human operator receives a PR with identified validation and evidence instead of relying on an agent completion claim.

Multi-Agent Workflow

Decapod is designed from the ground up to support concurrent multi-agent operations, providing the coordination and isolation necessary to prevent collisions.

The Coordination Model

Decapod uses a Lock-then-Isolate model for multi-agent work:

  1. Global Lock: Agents use decapod todo claim (see CLI Reference) to acquire an exclusive lock on a task. This prevents two agents from working on the same logical unit of work.
  2. Filesystem Isolation: Each agent is assigned a unique git worktree. Even if multiple agents are working on the same repository, they never see each other's uncommitted files (see Workspace Isolation).
  3. Container Isolation: For maximum safety, container_workspaces = true (see Config Specification) ensures that each agent has its own process space and system dependencies.

Shared Context

While execution is isolated, context is shared. Agents use decapod data memory (Aptitude) to share learned preferences and project-specific knowledge across sessions. This allows Agent B to benefit from a code convention learned by Agent A five minutes earlier (see Agent-First Architecture).

Best Practices

  • Frequent Heartbeats: Agents should run decapod todo heartbeat (see CLI Reference) to signal they are still active.
  • Explicit Handoffs: Use decapod todo handoff to transfer a task (and its current uncommitted state) between agents.
  • Centralized Validation: Always run decapod validate before publishing to ensure your changes haven't introduced regressions against the latest state of the root repository (see Proof & Validation).

External Trackers

Decapod does not replace project-management systems such as GitHub Issues, Linear, Jira, or Beads. Those systems may remain the organizational system of record. Decapod governs accepted work at the repository execution layer.

The Integration Pattern

  1. Organizational Layer (External): A human creates an issue in Linear (e.g., DEV-456).
  2. Execution Layer (Decapod): An agent adds a Decapod todo that references the external issue (see CLI Reference).
    decapod todo add "Fix regression in auth" --ref "DEV-456"
    
  3. Execution (Isolated): The agent claims the todo and enters its isolated workspace (see Workspace Isolation).
  4. Proof (Verification): The agent marks the task as done, satisfying the Decapod proof gates (see Proof & Validation).
  5. Sync (Closure): The passing Decapod state provides the "green light" to close the external Linear issue.

Why This Bridge Matters

External trackers organize work but do not enforce Decapod's repository invariants. Decapod contributes execution-layer custody, validation, and evidence. The external item is closed according to the team's own approval policy after the governed work reaches its required publication state.

Workspace Isolation

Workspace isolation is Decapod's primary defense against the "dirty tree" problem and multi-agent environment corruption (see Workspace Sandboxing).

Git Worktrees: The First Line of Defense

By default, decapod workspace ensure (see CLI Reference) creates a Git Worktree. Unlike a standard clone, a worktree allows you to have multiple branches checked out simultaneously in different directories while sharing a single .git database.

  • Speed: Creating a worktree is nearly instantaneous.
  • Integrity: Each workspace is a clean slate. There are no residual build artifacts from other branches.

Container Isolation: The Gold Standard

When working with multiple agents or complex dependency chains, filesystem isolation is often not enough. Decapod can wrap each worktree in a Docker container (see Multi-Agent Workflow).

Benefits of Containerization:

  • Dependency Sandboxing: One agent can run npm install for Node 18 while another uses Node 20 in a separate workspace.
  • Process Protection: A rogue agent process (e.g., an infinite loop or a memory leak) cannot crash the host machine or affect other agents.
  • Restricted Access: You can define network and volume policies to limit what an agent can see outside its workspace.

Managing the Workspace Pool

Use decapod workspace status to view the health and ownership of all active workspaces. Decapod handles the complex plumbing of mapping these directories to specific agents and tasks, so you don't have to.

Agent-First Architecture

Decapod exposes a machine-facing governance contract for agents. The human expresses intent and applies judgment; the agent calls the kernel while performing the work.

The Agentic Lifecycle

Decapod structures agent work into a predictable, machine-readable lifecycle:

  1. Ingestion & Orientation: The agent reads docs/agent/ and queries the constitution (see Repository Constitution) to understand the repo's rules and available tools.
  2. Task Claiming: The agent claims a todo to establish exclusive custody and prevent collisions (see Single-Agent Workflow).
  3. Context Resolution: The agent uses rpc --op context.resolve or infer orientation to gather the precise context needed for the specific task.
  4. Implementation: The agent works in an isolated workspace (see Workspace Sandboxing).
  5. Validation and Recovery: The agent runs decapod validate, follows supported remediation, updates the affected artifact, and revalidates until the work passes or reaches a blocker (see Proof & Validation).
  6. Publication: Passing gates and evidence permit a governed publication transition. Marking a task done records completion against that proof surface (see Artifacts Reference).

Key Agent-First Concepts

1. Deterministic Context

AI models are sensitive to context pollution. Decapod's Context Capsules ensure that every agent sees exactly what it needs, and nothing more. This reduces hallucinations and token waste.

2. Living Specifications

Living specifications (.decapod/managed/specs/*) are the acting agent's explicit interpretation of the repository. The agent authors and maintains them; Decapod requires and validates them. Decapod may refresh supported attestations or projections, but it does not invent the specifications' semantic claims (see Explicit Intent).

An incorrect specification exposes the agent's misunderstanding before publication. That is a successful governance outcome: a visible misunderstanding can be reviewed and corrected, while one hidden in transient model context cannot. A stale specification generally means the governed work remains incomplete.

3. Aptitude & Memory

Shared memory allows agents to learn from each other. If one agent discovers an obscure bug in a library, it can record that observation in Aptitude, which subsequent agents will automatically retrieve during context resolution.

4. Protocol-Native (MCP)

Decapod reserves an adapter boundary for the Model Context Protocol (MCP) so future integrations can expose the repository as a structured resource graph (see Model Context Protocol (MCP)). The current binary provides a Decapod-specific RPC interface; it does not itself implement MCP.

Design Patterns for Agents

  • Pressure Points: Call Decapod at decision boundaries (e.g., before choosing a library).
  • Epistemic Custody: Preserve the "Why" behind a change in the INTENT.md spec.
  • Follow validation: Use decapod validate early, remediate supported failures, and re-run it before publication.

Intent

In Decapod, Intent is the primary driver of the development lifecycle. It is the human-originated "Why" that must be preserved and formalized before implementation begins.

The Spec-First Mandate

Agents often dive into implementation before fully understanding the human operator's goal. Decapod prevents this by mandating a spec-first approach:

  1. Capture: Vague requests are converted into explicit tasks via decapod todo add (see CLI Reference).
  2. Formalize: Agents are required to update or verify the specs/INTENT.md document scaffolded in the repository (see Artifacts Reference).
  3. Validate: The final implementation is checked against this intent. If the outcome deviates from the recorded intent, validation fails (see Proof & Validation).

Intent Pressure

"Intent Pressure" occurs when an agent encounters ambiguity. Decapod's philosophy is that uncertainty must be preserved, not compressed. If an agent is 70% sure of a requirement, it must not guess the remaining 30%. Instead, it should record the ambiguity in the task's metadata or INTENT.md and request human clarification.

Versioned Specifications

Because Decapod is repo-native, your specifications are versioned alongside your code. This creates a permanent, auditable link between a feature's requirements and its implementation, which is invaluable for long-term maintenance and multi-agent handover.

Workspaces

Decapod workspaces are isolated execution environments that ensure agentic work is performed safely and reproducibly.

The Isolation Hierarchy

Decapod provides three levels of isolation:

  1. Branch Isolation: Every task is performed on a dedicated git branch, preventing accidental mutations to main.
  2. Filesystem Isolation: Decapod uses Git Worktrees to create unique directory structures for every task. This allows multiple agents to work on the same repository concurrently without filesystem collisions.
  3. Process Isolation: By enabling container_workspaces, Decapod wraps each worktree in a Docker container. This ensures that an agent's processes, environment variables, and local dependencies (like node_modules) are completely isolated from other agents.

Workspace Lifecycle

  • Acquisition: Triggered by decapod workspace ensure. Decapod calculates the necessary isolation level based on project config.
  • Entry: The agent cds into the workspace. All subsequent tool calls (compilers, linters, tests) must be executed within this boundary.
  • Promotion: Once work is verified, decapod workspace publish bundles the changes for merging back into the root repository.
  • Eviction: Completed or abandoned workspaces are automatically cleaned up to save disk space and maintain repository hygiene.

Why it Matters

Without workspace isolation, multi-agent systems are prone to "environment drift" and race conditions. Decapod's workspace model makes concurrent agent work as safe as concurrent human work on separate machines.

Proof

Decapod distinguishes an agent's completion claim from proof-backed completion. A claim reports what the agent believes. Proof-backed completion establishes that the required gates ran against identified repository state, produced evidence, and permitted the governed publication transition.

Verification Gates

A "Gate" is a discrete check that must pass for a task to be considered valid. Common gates include:

  • Compliance Gates: Checked by decapod validate (see CLI Reference).
  • Quality Gates: Unit tests, linting, and type-checking.
  • Security Gates: Secret scanning and dependency audits.
  • Human Gates: Explicit approval for high-risk changes.

The Evidence Ledger

When an agent completes validated work, Decapod binds validation receipts and evidence references to governed repository state (see Artifacts Reference). Agent testimony alone does not satisfy that boundary.

This creates epistemic custody: a reviewable chain from accepted intent and assumptions to the checks that ran and the repository state they measured.

Failure and recovery

A failed gate means the proof requirement is unsatisfied; it does not mean the task is complete. If the result provides a supported recovery path, the agent should:

  1. inspect the validation result;
  2. identify the violated invariant;
  3. perform the sanctioned remediation;
  4. update the relevant artifact;
  5. re-run validation; and
  6. continue toward publication.

Decapod does not assume every failure is recoverable. Decision gates, contradictions, unsupported remediation, and unavailable proof remain blockers for human review.

Determinism

Decapod strives for deterministic proof. A proof is valid only if it can be re-run or re-verified by another agent or a human at a later date. This ensures that the repository's integrity is not dependent on a single agent's transient state.

Common Questions

Why does Decapod not write my specifications?

The agent interprets the request and repository, so the agent authors the semantic claims. Decapod requires, validates, and may refresh supported projections of those claims.

Why are living specifications required?

They move the agent's interpretation out of transient model context and into a durable, reviewable repository artifact.

Why can specifications be wrong?

They record an agent interpretation, not an independent truth invented by Decapod. Validation makes a misunderstanding visible before publication so it can be corrected.

Why does validation block publication?

Publication is a governed state transition. It remains blocked while required invariants or evidence are unsatisfied.

Why are governance artifacts committed?

Plans, claims, trajectories, validation receipts, and related evidence must remain available to reviewers, CI, and later agents after the original process ends.

Why does durable state live in the repository?

The repository already provides shared custody and history. Keeping governed state with the work allows execution to continue across processes, models, harnesses, and Decapod invocations.

Why is Decapod daemonless?

Agents invoke it when governance is needed. No background process is required because the repository, not process memory, is the durable execution surface.

Why can one task span many invocations?

Each CLI or RPC call is ephemeral. The task continues through durable repository state until validation, publication, and proof requirements are satisfied.

Why should an agent continue after a recoverable validation failure?

Failure means a required condition is still unsatisfied. The agent should follow the supported remediation, update the affected artifact, revalidate, and continue toward publication.

How is Decapod different from an agent?

The agent interprets and performs the work. Decapod governs accepted work and validates the conditions around it.

How is it different from an orchestrator?

An orchestrator schedules or coordinates execution. Decapod defines and enforces repository-native governance boundaries; it does not replace the harness that runs the agent.

How is it different from a task tracker?

Trackers organize work. Decapod governs accepted work at the execution layer. GitHub Issues, Jira, Linear, or another tracker may remain the organizational system of record.

What does convergence mean?

The agent preserves accepted intent, stays within explicit boundaries, maintains durable state, responds to validation, remediates supported failures, and produces evidence before completion.

What does proof-backed completion establish?

It establishes that required checks ran against identified repository state, produced the required evidence, and permitted the governed completion or publication transition.

Constitution

The Constitution is the foundational set of rules and engineering standards that govern all behavior within a Decapod-managed repository.

Authority Layers

Decapod's authority model is hierarchical:

  1. Global Constitution: Over 100 normative documents embedded in the Decapod binary. These cover universal engineering standards (e.g., "Always write tests", "Minimize breaking changes").
  2. Project Overrides (.decapod/OVERRIDE.md): Repo-local rules that extend or supersede the global constitution. This is where you define team-specific conventions (see Overrides and Configuration).
  3. Task Policy: Temporary rules or constraints defined for a specific work unit.

Selective Context

Agents do not ingest the entire constitution. Instead, Decapod provides a Context Capsule interface (see Agent-First Architecture). Agents perform targeted queries (see CLI Reference) to retrieve only the directives relevant to their current task.

decapod rpc --op constitution.get --params '{"section":"core/DECAPOD"}'

This high-signal, low-noise approach ensures that agents remain oriented without being overwhelmed by irrelevant documentation.

Resolved context and capsules include derived proof for each applied project override. The human contract is documentation authored inside each generated fenced source block; Decapod owns exact-ID boundary recognition, fail-closed ambiguity handling, hashing, and precedence.

Enforcement

The constitution is not merely "guidance"β€”it is enforced. decapod validate checks the repository state against the normative claims made in the constitution. If a change violates a constitutional rule, it cannot be promoted to main (see Proof & Validation).

Overrides

Overrides are the primary mechanism for customizing Decapod's behavior for a specific project. They allow you to apply your team's unique engineering culture to the Decapod governance kernel (see Configuration).

The OVERRIDE.md Substrate

The .decapod/OVERRIDE.md file is a human-authored Markdown document where you can redefine specific constitution directives (see Repository Constitution). Each generated directive subsection owns a four-backtick source block. Find the appropriate subsection and replace the visible instruction inside that block with Markdown or whatever documentation style best expresses the policy.

The outer fence prevents headings in the policy from rendering as structure in OVERRIDE.md. Decapod removes that wrapper and loads its contents as binding authority. Four backticks allow ordinary triple-backtick examples inside the body. A duplicate registered directive, an unclosed body fence, or an unknown ID in a Decapod namespace outside a body block is ambiguous and fails closed; Decapod never applies only part of an ambiguous override file.

Decapod derives the machine evidence. Resolved context reports the directive ID, .decapod/OVERRIDE.md source path, whole-file source hash, directive-body hash and byte count, and repository-project precedence. Users do not author those fields.

Example Override

If the global constitution mandates "100% test coverage" but your project allows for "80%", you can override the specific directive:

### methodology/TESTING
````markdown
For this repository, we target a minimum of 80% line coverage. Critical paths in `src/decapod/core/` still require 100%.
````

When to use Overrides

  • Custom Style Guides: Mandate specific linting rules or naming conventions.
  • Tighter Security: Block agents from touching specific directories or files.
  • Workflow Adjustments: Add mandatory manual review steps for specific subsystems.
  • Platform Specifics: Define how Decapod should interact with your specific CI/CD pipeline.

Policy as Code

Because overrides are committed to the repository, they serve as "Policy as Code". They are versioned, auditable, and provide a clear, shared understanding of the rules for both humans and agents.

On upgrade, decapod init renders the current scaffold and moves each valid legacy body byte-for-byte inside its fenced source area. If an authored body already contains a four-backtick run, Decapod chooses a longer outer fence. Empty retired generated sections are ignored, while a non-empty retired or unknown Decapod directive fails visibly so policy is not discarded. decapod init and decapod validate reject ambiguous binding authority rather than applying only part of it.

Model Context Protocol (MCP)

Decapod's current agent interface is a Decapod-specific structured RPC envelope over process stdin/stdout. It is not JSON-RPC 2.0 and the binary does not currently implement an MCP server, MCP lifecycle, or native MCP resource and tool discovery.

MCP support is an adapter boundary tracked separately from the current runtime. Future adapters may expose Decapod resources and operations through MCP, but those bindings should not be read as capabilities of the current binary.

Current local handshake

decapod handshake records local declarations, scope, proof declarations, document hashes, and a deterministic artifact hash. That hash provides tamper-evident integrity for the recorded handshake data; it does not authenticate a model provider, harness, binary, human principal, or organization.

The handshake’s identity_assertions preserve identity claims separately from verification. An assertion carries its claim kind, subject type, value, evidence class, scope, lifecycle, authority/verifier slots, method, and result. Environment-provided agent and provider values are self-declared and unverified unless a configured trust root establishes stronger evidence.

The repository-local session credential establishes local custody and correlation for the current session. It is not external provider authentication. See the interoperability profile, capability negotiation, the native MCP adapter, the A2A adapter, the optional HTTP transport, and identity and provenance for the boundaries future adapters must preserve.

Configuration Reference

Decapod project policy is defined in .decapod/config.toml. This file should be committed to source control and is the primary mechanism for humans to communicate global rules to agents.

The [init] Section

Governs the behavior of the decapod init command.

KeyTypeDefaultDescription
specsbooltrueIf true, scaffolds living documentation under .decapod/managed/specs/.
diagram_styleenum"ascii"Preferred style for generated architecture diagrams ("ascii" or "mermaid").
entrypointslist[...]The agent entrypoint files to maintain (e.g., AGENTS.md, CLAUDE.md).

The [repo] Section

Defines the operational policy and metadata for the repository.

KeyTypeDefaultDescription
product_namestringNoneThe canonical name of the software product.
product_summarystringNoneA high-level description of the product's purpose.
architecture_directionstringNoneThe intended architectural style (e.g., "monolithic", "event-driven").
product_typestringNoneCategorization (e.g., "cli", "library", "service").
done_criteriastringNoneThe global definition of "done" that all work must satisfy.
primary_languageslist[]The primary programming languages used in the repository.
detected_surfaceslist[]Entrypoints and interfaces detected in the repo (e.g., "cargo", "npm").
external_trackerboolfalseWhether Decapod should expect and validate external issue references.
container_workspacesbooltrueIf true, Decapod will strongly encourage/enforce Docker isolation for worktrees.
backendenum"local"Storage backend for the project todo path ("local" or "cloud"). Cloud uses the binary-owned Propodus endpoint and GitHub origin identity.

Cloud service details are intentionally not project configuration. Decapod owns the Propodus deployment defaults in the binary, derives repo_id from the GitHub origin, and keeps credentials machine-local.

The [decision] Section

The optional decision provider supplies structured observations to Decapod's assurance result. It does not make policy decisions or replace governance.

KeyTypeDefaultDescription
providerenum"none""none" keeps operation local; "jev" enables the bounded Jev trajectory-satisfaction observation.

When Jev is enabled, Decapod reads the API credential from the machine environment variable TYPESAFE_API_KEY, falling back to the machine-local ~/.local/share/decapod/secrets.json file (or the XDG_DATA_HOME equivalent). Running decapod init --decision-provider jev persists an explicitly supplied environment key to that file with restrictive permissions. The file is separate from the Propodus session_token.json; credentials are never written to this project file. Jev uses TypeSafe's documented System One API. A missing credential, unavailable service, timeout, or malformed response yields no_observation; it never clears an interlock or satisfies a proof gate.

For an initialized project, decapod init --refresh reopens the interactive initialization questionnaire with the current configuration as each default. Pressing Enter preserves a setting; selecting another option can enable or disable it, including the decision provider. The refresh path preserves the existing repository setup and does not require --force.

With an active trajectory run, every Jev attempt is retained in the schema-versioned jev section of .decapod/governance.json. A new trajectory run resets that working-tree ledger, while committed prior ledgers remain recoverable through Git history. The ledger is advisory evidence and is not included as a governance authority or completion proof.

The live semantic corpus is separate from normal validation and must be enabled explicitly with DECAPOD_RUN_JEV_EVAL=1; it emits machine-readable observations for comparison and does not interpret them as policy. See the repository README for the exact command and corpus scope.

Schema Versioning

Decapod uses a schema_version key at the root to ensure forward and backward compatibility as the governance kernel evolves.

schema_version = "1.0.0"

[init]
specs = true
diagram_style = "mermaid"

[repo]
product_name = "decapod"
container_workspaces = true
done_criteria = "Validate passes and all unit tests are green."

CLI Reference

Decapod provides a unified CLI that supports both human-friendly text output and machine-readable JSON.

Command Aliases

Decapod provides short aliases for common subcommands:

  • v -> validate
  • i -> init
  • t -> todo
  • w -> workspace
  • g -> govern
  • s -> session
  • d -> docs

Core Operations

validate (alias: v)

Perform methodology compliance checks.

  • --store <repo|user>: The task store to validate.
  • --format <text|json>: Output formatting.
  • --verbose: Enable detailed per-gate timing.

init (alias: i)

Bootstrap or manage the Decapod lifecycle.

  • with: Apply explicit options (non-interactive).
  • clean: Remove all Decapod state from the directory.
  • --refresh: Re-open the interactive initialization questionnaire for an existing project, preserving current values as defaults and keeping the refresh non-destructive. In non-interactive environments it preserves the current configuration without prompting.
  • --decision-provider <none|jev>: Configure the optional advisory provider; when jev is selected, an explicitly supplied TYPESAFE_API_KEY is stored in the machine-local Decapod secret file, never in project configuration.

capabilities

Discover the features supported by the current Decapod binary.

cloud

Optional cloud credential operations. These commands do not enable cloud storage or change the local SQLite default.

  • cloud login: deprecated compatibility alias. Human setup belongs to decapod init --backend cloud; the alias remains only for existing scripts.
  • cloud status: report credential availability and source without printing a token.

Local database maintenance

These commands apply only to the canonical local .decapod/data/decapod.db store and are explicit operator workflows:

decapod data db verify
decapod data db backup --destination <unused-database-path>
decapod data db recover --preserve-original-at <unused-sibling-archive-path>

verify is read-only and reports Dactyl v0.10.0 integrity metadata. backup uses Dactyl's online SQLite backup, so a WAL source is captured without copying live -wal/-shm files into the destination. recover performs the verified logical dump/reload only when explicitly requested; it preserves the original, atomically publishes the replacement, rolls back on failure when possible, and reports rollback failure distinctly. Recovery returns DELETE journal mode while retaining application data and relevant SQLite metadata.

Do not run recovery while writers or same-process Dactyl connections are open. The Decapod sidecar lock bounds contention between cooperating Decapod processes, but it cannot coordinate arbitrary external SQLite writers or unreliable filesystems/mounted storage. No command repairs a store automatically, including startup, validation, event append, or connection creation. JSON diagnostics distinguish healthy, unavailable, locked, corrupt, unsupported, recovery_failed, and recovery_rollback_failed; inspect failure_code for Dactyl's precise code.


Workspace Management (alias: w)

workspace ensure

Create or enter an isolated task worktree.

  • --branch <name>: Provide a custom branch name.
  • --container: Wrap the workspace in a Docker container.

workspace status

Display active workspaces, their owners, and their current state.

workspace publish

Prepare and bundle changes from an isolated workspace for promotion (PR/merge). The promotion push is fast-forward-only. Decapod never force-pushes a governed workspace branch. A non-fast-forward rejection is a blocker: reconcile the remote divergence, rerun validation, and retry publication rather than rewriting shared history.


Task Tracking (alias: t)

todo list

List tasks from the backlog.

  • --status <open|claimed|done|archived>: Filter by state.
  • --category <name>: Filter by task category.

todo claim

Lock a task for active implementation.

  • --id <task-id>: The specific ULID of the task.
  • --mode <exclusive|shared>: Set the locking mode.

todo done

Complete a work unit and generate proof artifacts.

  • --id <task-id>: The task to close.
  • --validated: Capture a cryptographic proof baseline of the changes.

Governance & Subsystems (alias: g)

govern policy

Classification and approval for high-risk actions.

govern health

Claims, proofs, and system-wide integrity status.

govern artifacts

Manage the single .decapod/governance.json document through logical sections: Populate in dependency order: stable PR identity, intent/scope plan, current claims and planned checks, work/evidence trajectory, validation, then staged-material checkpoints. Record meaningful boundaries throughout the work, not only at completion.

  • migrate: losslessly import legacy split files; reads never migrate implicitly.
  • begin-pr --id <change> --base-branch <branch>: start an explicit PR boundary after verifying discarded evidence is recoverable from Git.
  • claim --id <id> --statement <text> --falsifier <text> --status <status>: record a current-PR claim; status is open, supported, refuted, or blocked. Repeat --proof-ref <ref> for evidence; support requires proof.
  • resolve-obligation --id <id> --resolution <text> --proof-ref <ref>: explicitly retire a carried obligation with one or more proof references.
  • checkpoint --id <unique-id> --summary <text> [--proof-ref <ref>]: bind staged authored material and logical governance inputs. Stage the updated governance document afterward and commit both.
  • status: read current normalized state without creating runtime state.
  • verify-checkpoints --base-branch <ref> [--head-ref HEAD]: read-only verification of exact-material checkpoints across the full commit graph.
  • inventory [--base-branch <branch>]: inspect logical sections, semantic currency, and PR participation. --repair initializes absent empty claims; --claims-note <text> records a current-PR checkpoint; --compact preserves legacy semantics while normalizing storage. Existing evidence is not overwritten.

Research claims are separate from Health Engine claims in .decapod/data/decapod.db.

govern capsule query

Perform a deterministic query over the embedded constitution.

  • --topic <name>: The subject of inquiry.
  • --scope <scope>: The context boundary (e.g., "interfaces").

Cloud Todo Boundary

Propodus is the hosted authentication and authorization boundary; Dactyl is the physical storage boundary. They are not interchangeable. repo.backend = "cloud" selects the cloud backend: Decapod authenticates through Propodus, opens Dactyl with a versioned storage context, and never silently falls back to local SQLite.

Dactyl storage contract

The Decapod bridge constructs local Dactyl SQLite or cloud Supabase HTTP routes by default; Neon HTTP remains an explicitly selected alternative. It does not set or trust ambient DATASTORE, DATASTORE_ROUTE, or DATASTORE_TOKEN during connection construction. The cloud route receives an opaque machine-session bearer and the versioned repository context. Individual SQL operations do not select a provider or interpret authorization.

The Supabase HTTP capability, enabled in standard builds, is described in Supabase consumer validation. Decapod consumes the published dactyl-db 0.11.1 registry release containing the client reviewed in Dactyl #92. The committed lockfile supplies its registry checksum; registry publication is not hosted service proof. Cloud selects Supabase unless DECAPOD_CLOUD_DATASTORE=neon is set. Local SQLite behavior is unchanged. Supabase still requires a configured compatible authenticated service endpoint; no production deployment is implied.

OperationDactyl requestScope/authentication
Read/listPOST /querySQL plus opaque versioned context
Add/claim/release/completePOST /batchordered Dactyl operations plus context

The bearer is sent in the HTTP Authorization header by Dactyl. The context is forwarded as an opaque JSON object; Propodus resolves its authenticated principal and repository authorization. Add, claim, release, and complete use a Dactyl batch containing the conditional state write, the matching event write, and a task observation. The event insert is conditioned on the state transition marker. The service must also require a successful preceding state mutation before writing an event, including when a stale request reuses a timestamp marker; a timestamp alone is not authorization for an event.

The checked-in tests/cloud_dactyl_boundary.rs proof verifies /query, the bearer header, the versioned context, and the absence of a per-query backend field without contacting Vercel or Neon. The older Propodus fixture and propodus_contract test remain compatibility coverage for the legacy /api/todos client; they are not the active Decapod storage implementation.

The deployed onboarding/session shape is recorded separately in tests/fixtures/propodus/onboarding-contract-v1.json: Decapod starts with the canonical repo_id, prints/opens the one-time URL, polls status, consumes the ready flow once, exchanges the returned code for a machine session, and rotates that session through the refresh route. Credentials stay outside the repository.

The command boundary is covered by tests/cloud_command_path.rs, which proves that list, add, get, claim, release, and complete are routed through the backend-neutral TodoStore adapter. Unsupported local-only operations return an explicit error on the cloud backend.

The production-dispatch proof is tests/cloud_cli_boundary.rs; it uses a mock Dactyl store factory and exercises the same run_todo_cli composition used by the binary. It proves config discovery, canonical-origin validation, credential preflight, list/add/get/show/claim/done routing, not-found behavior, and the absence of local SQLite initialization for cloud todo commands.

The opt-in live proof is tests/propodus_live.rs. Run it only with DECAPOD_PROPODUS_LIVE=1, DECAPOD_PROPODUS_API_URL, DECAPOD_PROPODUS_ACCESS_TOKEN, and a disposable DECAPOD_PROPODUS_DISPOSABLE_REPO_ID:

DECAPOD_PROPODUS_LIVE=1 \
DECAPOD_PROPODUS_API_URL=https://your-stable-propodus.example \
DECAPOD_PROPODUS_ACCESS_TOKEN=... \
DECAPOD_PROPODUS_DISPOSABLE_REPO_ID=example/decapod-live-deny \
cargo test --test propodus_live -- --ignored --nocapture

The proof creates one uniquely named todo in the canonical repository, claims it, completes it, and verifies that the disposable repository receives 403 repository_not_authorized. It also verifies that an invalid bearer token is rejected with a 401 authentication failure. The command-level proof also uses two Decapod agents to verify shared visibility and rejects a fork before any request is sent. It does not delete the sentinel because the v1 client contract has no delete operation; remove it with Propodus operator tooling after the run. The test is ignored by default, and the CI job is manual, environment-protected, and gated by the DECAPOD_PROPODUS_LIVE repository variable.

Propodus also uses 403 organization_seat_required when a valid GitHub bearer token lacks the required organization seat for the canonical repository.

Backend-neutral storage context

Decapod's versioned core::backend::StorageContext is the handoff from logical backend selection to a physical driver. A local context contains only the repository-local SQLite route and has no organization, user, or cloud repository fields. A remote context contains the opaque service route and the logical repository scope derived from origin; it requires an authenticated session bearer, but the bearer is memory-only and is omitted from serialized context data.

The Dactyl bridge forwards the explicit route, versioned context envelope, and opaque bearer without interpreting membership or authorization. The bearer never enters ambient Dactyl environment variables. Context debug formatting redacts the bearer and endpoint; serialization excludes the bearer. The versioned context carries the target org/repo scope unchanged. Propodus remains responsible for resolving the authenticated principal, organization membership, and repository access. The Decapod bridge opens the canonical local decapod.db directly through Dactyl's local adapter and opens the cloud route through Dactyl's Supabase adapter by default (or explicit Neon); it does not create a snapshot or bundled compatibility database. Existing SQLite state is inspected and migrated by Decapod through the same Dactyl-backed facade. This keeps one canonical Dactyl authority and prevents cloud operations from silently falling back to local storage. See Decapod #1254, Dactyl #64, and Propodus #79.

Credentials

Credentials are never read from .decapod/config.toml. Lookup precedence is:

  1. an explicit client credential;
  2. DECAPOD_ACCESS_TOKEN for controlled development and CI use;
  3. the selected endpoint-scoped machine session for Supabase, or the legacy ~/.local/share/decapod/session_token.json only for explicit Neon.

cloud status checks the same selected session store without network I/O.

Run decapod init --backend cloud as the only human-facing cloud setup step. It starts or resumes the repository-bound browser handoff through Decapod's baked-in Propodus endpoint. Agents acquire custody with decapod session acquire, which reuses or refreshes the machine-local session without asking for another human action. Use decapod cloud status only to check whether a bearer is configured without printing the token. The deprecated cloud login compatibility alias remains for existing scripts and is not part of the setup flow. Interactive terminals open the URL when a browser launcher is available and always print it as a fallback; headless callers receive a bounded resume instruction. A completed exchange is stored machine-locally with restrictive permissions and expired sessions refresh through the provider. Bearer tokens are sent only in the Authorization header; Decapod never logs or writes them to repository configuration, generated governance, URLs, or commits.

Repeatable dogfood setup

From a fresh checkout of the canonical repository:

  1. Run decapod init --backend cloud --proof and confirm .decapod/config.toml contains only the backend selection repo.backend = "cloud" for cloud composition. The Propodus endpoint and provider are binary-owned; no service URL or project identifier is stored in project configuration.
  2. Ensure origin is an unambiguous GitHub remote. Decapod derives the canonical owner/name from it and sends that binding to the provider; the provider decides whether the authenticated session may use the repository.
  3. Run decapod todo list, add, get, show, claim, or done. If no machine session exists, first complete decapod init --backend cloud; the initialized machine state then resumes the one-time browser handoff on the next invocation. A controlled DECAPOD_ACCESS_TOKEN remains available for protected proofs.
  4. Cloud todo commands use the same TodoStore command boundary as local todo commands, but compose Dactyl storage with the Propodus-authenticated context instead of local SQLite. They do not acquire the local agent session or create/migrate the local todo database. Missing credentials or a canonical GitHub remote fail closed and never fall back to SQLite.

Repository identity

The cloud backend derives a canonical owner/name binding from the origin remote and rejects non-GitHub or ambiguous remotes. Forks remain distinct identities and are passed to the provider for authorization; Decapod does not maintain a repo allowlist or accept a project-configured repository identifier.

Current governance limits

The cloud Dactyl todo slice supports repo-scoped list/add/get/claim/release/ complete operations. get and show use keyed reads through Dactyl rather than list-and-filter. Add, claim, release, and complete each use one Dactyl atomic batch for the conditional task transition, matching event, and final task observation. A compatible service must enforce that a zero-row task transition cannot create an event, even if a timestamp marker matches an older operation. Client checks of returned counts occur after the remote transaction and cannot alone enforce rollback. The Supabase service proof tests this server-side requirement; timestamps alone are not compare-and-swap authority. A missing item returns status = "not_found". todo done --validated is intentionally rejected because v1 has no proof capture or verification-artifact contract. This is an explicit unsupported boundary, not full remote governance completion; a future proof-contract issue must define the service-side evidence model before Decapod can compose it; see Decapod issue #1038.

Delivery boundary

Local SQLite maintenance

Local operators can inspect and maintain the canonical store explicitly:

decapod data db verify
decapod data db backup --destination /same-directory-or-approved-backup/decapod.backup.db
decapod data db recover --preserve-original-at /same-directory/decapod.before-recovery.db

verify is read-only and calls Dactyl v0.10.0's typed native integrity verification. backup uses Dactyl's SQLite online-backup contract, including WAL/SHM correctness, and publishes a standalone destination after verification. recover is an explicit operator action only: it invokes Dactyl's logical dump/reload workflow, preserves the original at the requested unused sibling path, and atomically replaces the active database only after the replacement passes verification. Dactyl reports rollback or recovery failures without silently repairing the store. The recovered database uses DELETE journal mode and preserves application rows, schema, user_version, and application_id.

The canonical Decapod sidecar lock is held for each operation. Recovery also requires all cooperating Decapod writers and same-process Dactyl connections to be quiesced; backup requires normal cooperating-client coordination. The archive must not already exist and must be on the same filesystem where Dactyl can perform its atomic replacement. The sidecar does not coordinate arbitrary external SQLite writers or make unreliable network/container mounts safe. Lock contention, unavailable runtimes, malformed/corrupt stores, unsupported capabilities, and recovery/rollback failures remain explicit diagnostic outcomes. Decapod never runs repair during startup, validation, event append, or connection creation.

This Decapod slice activates the explicit cloud todo command path, remote-derived repository identity, Propodus onboarding/session exchange, machine-local refresh, Dactyl 0.10.0 adapter-level command and event-atomicity proof, and a wire-level /query proof without moving hosted authentication, repository authorization, persistence, or deployment into Decapod. Local mode continues to use the same backend-neutral todo command boundary, with physical canonical storage owned by Dactyl. Live Neon/Vercel availability, Propodus/Dactyl service deployment, cross-organization isolation, schema/migration parity, and hosted event atomicity remain deployment-dependent proof gates; the client-side batch contract and local rollback proof do not claim those hosted properties.

For interrupted cloud creation and auth-blocked custody, see Resuming cloud todo creation. A returned operation token is a retry identity, never an authorization grant or local task-store fallback.

Resuming cloud todo creation

Cloud todo add assigns a distinct operation token before authentication. A fresh invocation means new work, even when its title and other inputs are identical to an earlier task. Never issue a fresh add to retry an uncertain operation.

When onboarding is pending or a response is lost, retain operation_id from the JSON diagnostic. After fixing the reported prerequisite, repeat the original arguments and add --operation-id TOKEN, for example:

decapod todo add "Implement a feature" --priority high --operation-id TOKEN --format json

TOKEN is the exact value returned by that operation, not a title, task ID, or credential. Repeat all original options. A restarted agent may resume the request; the original creation event keeps its original audit actor. The client refuses a token for changed arguments, repository, or service endpoint before contacting the service. To change an unsubmitted request, intentionally start a new operation; do not mutate the identity of the old one. Recovery text does not interpolate task text into a shell command.

After an interrupted process, decapod todo operations --format json lists the machine's retained receipt metadata. Match the original operation and replay its original arguments with its token. This inspection never opens the repository's local task database. It is metadata inspection, not authentication or a task store: task descriptions and other request contents are not retained there.

Outcomes

  • blocked_before_submit: this attempt did not dispatch the mutation. Its failure category distinguishes authentication, onboarding pending, authorization, offline, transport, conflict, cancellation, and validation
  • outcome_unknown: a dispatched mutation may have committed, or an interrupted attempt has not been reconciled. Never interpret it as rollback
  • succeeded: the client observed the mutation result or an exact immutable creation receipt through the authorized service boundary

attempt_status records whether this individual attempt dispatched. Once an operation is uncertain, a blocked retry cannot downgrade its overall status; only an exact authorized receipt can establish success.

The failure JSON schema is decapod.cloud.todo-operation.v1. It contains only operation identity, status, failure category, retryability, and a next action. Task data, bearer tokens, refresh tokens, endpoints, and arbitrary service error messages are excluded. Authentication/authorization failures remain distinct; a retry token never provides repository access. The service continues to own authenticated principal identity and authorization; Decapod neither parses unverified bearer claims nor treats a local successful receipt as access.

Duplicate protection and receipts

The existing Dactyl atomic batch inserts the task, its creation event, and reads the task. A resumed operation reuses its task ID and deterministic event ID. The creation event binds an immutable request fingerprint. Retries inspect that event through the same authenticated Dactyl query boundary; subsequent changes to a task's title, status, or assignee do not invalidate its creation receipt. An ID collision or a changed request cannot overwrite an existing task. A concurrent loser or lost acknowledgement can reconcile the winner's exact receipt. Authentication or authorization errors are never bypassed by a second reconciliation request.

Unknown outcomes stay unknown if the confirming read is unavailable. The client never substitutes local SQLite, generates a new identity for a retry, or infers rollback from an HTTP error. A successful local receipt still requires normal authentication and authorized remote reconciliation when explicitly retried.

Local metadata and retention

Non-secret receipt metadata lives under the machine configuration directory in decapod/todo-operations. It stores token, fingerprint, task ID, outcome, failure category, and update time. It contains no task payload or credentials, and has no repository-local fallback. Private creation permissions, bounded exclusive locking, and atomic replacement protect concurrent writers.

The journal is limited to 256 records and 1 MiB. Successful receipts older than seven days are removed when preparing new work; the oldest successful receipt may also be removed at capacity because the durable service event remains the authority. Unresolved records are never silently evicted. When all slots are unresolved, new operations fail before submission and ask for reconciliation. An existing operation can still be retried at capacity.

Proof boundary

Local SQLite adapter tests prove the client uses a task-plus-event atomic transaction, handles transaction failure without partial state, and reconciles an immutable creation event after task changes. Synthetic public Dactyl HTTP fixtures exercise response loss, interrupted reconciliation, and denied receipt reads. These are client/adapter proofs, not deployed service authorization or hosted transaction-isolation proofs. Hosted parity and service atomicity remain separate downstream acceptance work (#1377 and #1378).

Supabase consumer validation

The cloud backend selects the public Dactyl Supabase HTTP capability by default. The client uses the published dactyl-db 0.11.1 registry release. This dependency alignment does not migrate historical state, provision Supabase, or prove a production deployment. Local storage remains SQLite; Neon is an explicit cloud alternative.

Fresh activation

  1. Decapod consumes dactyl-db 0.11.1 from crates.io, including the Supabase client capability reviewed in Dactyl #92 and released in v0.11.1. Cargo.lock records the registry source and checksum; there is no Git or local-path dependency override. Build with cargo build --locked; the default features include supabase-cloud. A --no-default-features build retains SQLite and explicit Neon, and fails closed if the unavailable Supabase route is selected. Nix vendoring uses the same lockfile checksum. Before publishing Decapod, run cargo package --locked and cargo publish --locked --dry-run to verify the packaged registry dependency.
  2. An operator must first provide a fresh compatible authenticated service backed by PostgreSQL, its task/event schema, and resource permissions. The client does not initialize hosted schemas or connect to PostgreSQL.
  3. In machine-local runtime configuration, set DECAPOD_PROPODUS_API_URL to that service's HTTPS origin. No datastore override is required: omitted DECAPOD_CLOUD_DATASTORE selects Supabase. Explicit supabase is also accepted. Literal-loopback HTTP is supported for disposable test services only. This is neither a PostgreSQL DSN nor Supabase REST.
  4. Select repo.backend = "cloud". Production use requires a service that also implements the existing decapod init --backend cloud onboarding, session exchange and refresh contract. A task-only /query and /batch service does not provide those authentication endpoints. The isolated conformance profile supplies disposable ordinary user tokens directly; it does not establish production onboarding. Ordinary clients receive only user/session credentials. Database passwords, operator credentials, and service-role keys never enter Decapod.
  5. Run normal todo list, add, get, show, claim, release, and done commands. todo done --validated remains unsupported pending the separate remote proof-capture contract.

The selector is distinct from repo.backend = local|cloud and from the hosting-provider label. Its default is supabase. Set DECAPOD_CLOUD_DATASTORE=neon to select the retained Neon route explicitly; only that selection can use the legacy Neon service endpoint by default. An unknown selector, a build without supabase-cloud, an invalid endpoint, or a missing Supabase service endpoint fails closed before onboarding or todo I/O. Authentication, authorization, timeout, transport, protocol, and storage failures never initialize or fall back to local todos.

Dactyl validates the Supabase endpoint before session onboarding or refresh. Both Supabase authentication and data requests refuse redirects so an HTTP redirect cannot forward a refresh body or user bearer to another origin. Supabase authentication passes bearer headers and JSON through the child transport's private stdin, not process arguments or a secret temporary file; ambient curl configuration is disabled for that path. Supabase sessions are stored in endpoint-scoped machine-local files. Switching service endpoints never reuses or refreshes the legacy global Neon session or another endpoint's session. A new endpoint requires its own onboarding. An explicit DECAPOD_ACCESS_TOKEN remains a controlled test/operator override; set it only for the selected service. Test fixtures isolate HOME and both XDG directories and use synthetic/disposable session material exclusively. No credentials appear in the versioned context, debug output, or repository configuration. The client selector is also omitted from the wire context.

Ownership and permissions

Git continues to hold governance plans, claims, trajectory, validation, specs, and proof artifacts. Supported shared operational tasks and matching events use the configured backend. There is no SQLite-file upload or synchronization.

The authenticated service resolves the principal, organization, group/team membership, repository identity and effective permission. Client-supplied scope is a request target, never a grant. Decapod exercises public allowed and denied outcomes instead of copying the service's authorization rules.

The conformance profile covers the reviewed todo task/event schema. It does not establish arbitrary Decapod catalog or schema portability. A compatible service implements the current reviewed task SQL and ordered three-operation batches: task mutation, matching event, final task read. It must commit both state and event or neither. It must gate event insertion on the preceding mutation affecting one row; a matching timestamp by itself is insufficient. Concurrent claims have one winner. Stale or missing transitions return a conflict/zero count and cannot append success events. A response lost after commit is ambiguous: observe task state before deciding whether to retry. This client contract does not add or claim mutation idempotency.

Separate evidence profiles

  • Default SQLite/Neon regression and cloud boundary tests need no hosted credentials. Local HTTP fixtures establish client composition and error handling only. They are not PostgreSQL, RLS, or hosted Supabase evidence.
  • cloud_supabase_boundary with supabase-cloud checks actual CLI dispatch, bearer/context placement, normalized rows, safe failure diagnostics, no local fallback, and no credential forwarding across redirects. Actual CLI add/claim/release/done requests must use one ordered task-write, event-write, task-read batch with the same explicit ID and timestamp. Zero or non-singleton task/event counts must fail even when the response contains a task row. Get/show check keyed reads and explicit missing results. These scripted HTTP responses prove client composition only, never service atomicity or policy.
  • supabase_service::local_postgres_service_contract is ignored by default. An external service harness must start actual PostgreSQL, apply a fresh schema, provision authenticated principals and grants, create a protected fixture, run the test, verify its receipt against the real event ledger, then deterministically destroy only its disposable database/roles.
  • supabase_service::protected_hosted_supabase_service_contract is separately ignored. Run it only in an operator-approved protected environment with DECAPOD_SUPABASE_HOSTED_PROOF=1, HTTPS and disposable/namespaced data. The external fixture owner must guarantee cleanup on failure as well as success. No hosted endpoint, credential, or completed hosted result ships with this branch.

Invoke the local service test with:

DECAPOD_SUPABASE_FIXTURE=/protected/temporary/fixture.json \
  cargo test --locked --features supabase-cloud --test supabase_service \
  local_postgres_service_contract -- --ignored --nocapture

The hosted command uses the other test name and hosted opt-in. Missing inputs cause an explicit failure when an ignored test is selected; an unselected ignored test is unavailable evidence, not a pass. A fixture declaration does not prove its backend: the harness's actual PostgreSQL observations and cleanup result must accompany the client receipt.

Protected fixture contract

The fixture file is created outside Git with restrictive permissions. Do not print it, attach it to CI artifacts, or include it in logs. Its schema is:

{
  "profile": "local-postgres",
  "endpoint": "http://127.0.0.1:PORT",
  "repository": "fixture-owner/disposable-repo",
  "allowed_tokens": ["FIRST_USER_SESSION", "SECOND_USER_SESSION"],
  "denials": [
    {
      "case": "cross_org",
      "token": "DENIED_USER_SESSION",
      "repository": "fixture-owner/disposable-repo",
      "expected_error": "repository_not_authorized"
    }
  ],
  "disposable": true,
  "receipt_path": "/protected/temporary/client-receipt.json"
}

Required denial cases are cross_org, wrong_group, wrong_team, unauthorized_user, insufficient_access, revoked_access, and expired_session. Each must be provisioned by the service's public permission contract. Insufficient-access fixtures may read but must deny add/claim/release/done; other cases must also deny list/get/show. expected_error is a safe public error category. The two allowed tokens must belong to independently authenticated users with access to the same fresh repository slice, not two copies of one bearer.

The client proof creates one task, checks shared list/get/show and missing rows, races two CLI claim processes, rejects a stale claim, releases/reclaims and completes. Missing-task transitions and non-owner release/completion must fail. Repeated transitions after completion must fail, and a subsequent read by the other principal must still match the completed row. Denials must reveal no task data and must leave task state and event counts unchanged. Its non-secret receipt declares expected version 5 and exactly these events: task.add, task.claim, task.release, task.claim, task.done. The service harness verifies the ledger and adds separate deliberate-failure rollback, equal-timestamp stale-CAS, type/count, fresh-schema and permission proof. Those are service-side assertions, not conclusions inferred from a successful client response.

Gatekeeper source context

Gatekeeper checks path policy, protected paths, diff size, credential patterns, and dangerous source patterns. Context may discharge one exact matched source span only when the supported parser establishes the relevant meaning. Other matches on the same line remain independent.

Explicit scan inputs

Repeat --paths for each file:

decapod govern gatekeeper check --paths src/decapod/lib.rs --paths src/decapod/core/dactyl_todo.rs

Comma-separated arguments are not expanded. Missing, non-text, or unreadable explicit files and explicit directories fail rather than reporting a successful empty scan. Without --paths, staged paths come from Git's NUL-delimited output. A Git failure is an error. Deleted paths and both sides of renames still participate in protected-path checks even when there are no remaining bytes to scan.

Literal Rust include_str! dependencies are followed, including calls nested within macro input. General include! expansion and include_bytes! interpretation are outside this recognizer. Included files retain credential and path-policy checks. Included text with an unknown suffix still receives conservative raw dangerous-pattern checks. Missing, dynamic, unreadable, out-of-repository, or excessively large dependency graphs cannot establish a successful scan. Moving source into an included file is not an exemption.

Supported evidence

  • Explicit bearer-scheme syntax remains distinct from ordinary credential prose. Short or word-like credentials in explicit syntax remain findings
  • Rust password formatting uses exact literal spans and proven runtime provenance. Supported immutable environment bindings and a narrowly checked random-byte generator can carry evidence through supported local tuple, option, branch, and match flow. A helper name alone proves nothing
  • Positional SQL parameters require a verified terminal database operation. Constructing an operation object alone is insufficient because its SQL can escape. Supported local wrappers are resolved through the actual Cargo module graph and must forward directly to the external connection contract
  • Native shell context distinguishes quoted parameter expansion from executable substitutions and unsafe constructs. Dockerfile context keeps instruction substitution separate from shell execution in RUN
  • Fully qualified standard primitive string comparisons consume their input as text. They do not make other literals, credentials, or shell operations on that source line safe
  • Explicit Rust shell or unresolved interpreter construction produces an independent review finding, including multiline, alias, and included-input forms. A filename's native grammar cannot discharge that execution boundary

These are bounded recognizers, not Rust macro expansion, a compiler, complete shell interpretation, or dependency-supply-chain verification. Ambiguous bindings, namespace shadows, unsupported attributes, mutation, unknown escaping values, unresolved module evidence, and unsupported syntax retain findings. SQL evidence assumes genuine external database and async-trait implementations; local path/package substitution and manifest patches cannot supply that evidence. Cargo configuration, environment overrides, downloaded code, and toolchains are not authenticated by this source recognizer. Native data-command recognition likewise assumes standard command implementations and runtime shell behavior; it does not authenticate PATH or executable contents. Source-defined overrides and known executable options remain part of the adversarial test boundary. Arbitrary custom-runner semantics and whole-program reinterpretation of included text are outside these bounded recognizers. Visible standard-library manifest substitution or an invalid manifest prevents Rust password-context exemptions; standalone source without a manifest retains the documented standard-library assumption.

Findings that intentionally remain

Literal credentials remain detectable in source, documentation, tests, and synthetic fixtures. Contextual exemptions do not rely on filenames, comments, placeholder words, credential length, or test labels. Broader legacy pattern recognizers retain their documented shape limits. The tests retain short quoted and explicit-assignment passwords, alongside the old literal setup instruction, as positive controls. Typed Rust let, const, and static password/passwd/pwd declarations are scanned across whitespace and newlines, including short literal values. The additive textual matcher supports ref/ref mut bindings and simple array/slice annotations with literal or named lengths. It stops at statement semicolons, braces, or an earlier equals sign; nested arrays and arbitrary length expressions are outside this bounded recognizer. It is not a complete Rust type parser. Detection does not require successful parsing. Runtime provenance can discharge only its exact initializer span, so a nearby literal remains a finding. These bounded recognizers do not supply universal secret detection.

Actual shell command substitutions remain executable-shell findings even when quoted. For example, a fixed script that queries process identity still contains a command invocation; recognizing its quoted variables does not certify every command in the script. Dynamic shell execution, unknown command provenance, and dangerous operations remain subject to review.

The session setup instruction now identifies the generated password rather than telling callers to use the separately displayed session token. This is an instruction correction; it does not add a placeholder exception.

Verification boundary

Paired tests cover each supported safe form and nearby adversarial changes: literal fallbacks, mutation and shadowing, operation-string escapes, altered wrapper implementations, custom macros and methods, shell function overrides, missing includes, and mixed safe/unsafe lines. Extracted native templates have byte-equivalence and rendered-output regressions against their original representations, and remain part of the Cargo package.

Scanner implementation tests do not waive publication policy or establish container custody. Run the official validator separately and preserve actual passed, failed, ignored, and unavailable evidence. A new scanner must not act as its own authority for publication approval.

Governance Artifact Inventory

.decapod/governance.json is the sole tracked governance authority. It holds a compact baseline, current-PR identity and claims, cumulative checkpoints, explicit unresolved obligations, and normalized logical sections:

SectionWriterPurpose
Plandecapod govern planRefined intent, scope, phases, decisions, and proof hooks
Claimsdecapod govern artifacts claimCurrent-PR falsifiable claims; support requires proof
Trajectorydecapod govern trajectoryIntent custody, scope, actions, assumptions, checks, and evidence
Validationdecapod validateReceipt bound to current repository inputs and trajectory
Jev (optional)assurance.evaluate with Jev enabledAdvisory observations for the active trajectory

Health Engine claims remain in .decapod/data/decapod.db, and runtime workunit manifests in .decapod/data/workunits/. Neither is a second tracked research ledger. See the governed execution model.

Explicit PR lifecycle and publication invariant

Use decapod govern artifacts migrate to import valid legacy split files losslessly. Read operations never write. Conflicting or malformed authority fails closed instead of being silently repaired. begin-pr --id <change> --base-branch <branch> starts the explicit boundary only when discarded state is recoverable from Git. Accepted completed claims stay in Git history; explicit unresolved obligations carry forward. Resolve an obligation with resolve-obligation --id <id> --resolution <text> --proof-ref <evidence>.

Before each authored commit, finish the relevant plan, trajectory, claim, spec, and validation work; stage authored files; record a unique checkpoint; then stage the governance document and commit:

git add <authored-paths>
decapod govern artifacts checkpoint --id <unique-id> --summary "What changed and was checked" --proof-ref <evidence>
git add .decapod/governance.json
git commit -m "Describe the governed change"

Checkpoints are cumulative within the current PR. Publication and CI verify exact immutable material at every authored commit, including merges, and reject erased or rewritten checkpoints. A valid file only at the PR tip is insufficient. Pre-adoption legacy history is not retroactively represented as verified proof. A new trajectory resets only its current Jev observations; committed prior observations remain recoverable through Git.

Population order and write boundaries

Use the existing commands in dependency order:

  1. Begin one stable PR identity with govern artifacts begin-pr.
  2. Populate intent, todo binding, and scope with govern plan init or update.
  3. Record actual current-PR claims with falsifiers and planned checks/proof hooks; do not create placeholder claims or claim support before evidence exists.
  4. Perform the work and record its inspected/modified paths, checks, evidence, and unresolved assumptions with govern trajectory init and record.
  5. Run decapod validate against the current completed batch.
  6. Stage material, record a unique checkpoint, stage governance.json, and commit.

Persist meaningful intent, scope, evidence, and commit boundaries throughout the work instead of reconstructing them only at the end. Combine related updates at one boundary, and skip repeated unchanged content. A new claim or changed scope returns to the affected earlier step; it does not restart the PR identity.

Release pin flywheel

Master entrypoint/Dockerfile/manifest pins record the Decapod version that generated that master tip. A cargo-only release-plz merge does not rewrite pins. There is no Release Artifact Sync workflow and no post-release heal PR.

Flywheel:

  1. Master is generated by Decapod vN (pins say vN).
  2. User/agent PRs with installed vN merge.
  3. A new release vN+1 is cut from master (Cargo/CHANGELOG only).
  4. Users install vN+1. Master pins remain vN until a user/agent PR runs validate with vN+1 and commits healed entrypoints, Dockerfile pin, and specs manifest (first PR for the new installed binary must refresh all of them).

Inventory and repair

decapod govern artifacts inventory --base-branch master
decapod govern artifacts inventory --repair

Repair initializes absent empty claims and preserves existing evidence. Inventory reports each logical section's schema and semantic currency; it does not invent claims or replace plan, trajectory, or validation work.

inventory --claims-note "..." records a current-PR checkpoint without inventing a research claim. inventory --compact performs lossless legacy normalization. Successful validation writes the logical validation section without a self-referential hash cycle. Do not use DECAPOD_VALIDATE_SKIP_GIT_GATES as an agent publication shortcut. Stage and checkpoint the final material before committing.

An external tracker such as GitHub Issues, Jira, Linear, or Beads may remain the organizational system of record. Decapod's todo and claim state governs the accepted work at the repository execution layer.

Current-contract review and remote publication proof

When a PR changes implementation surfaces, workspace publish requires explicit reviews of the current INTERFACES, ARCHITECTURE, and SECURITY contracts. This is agent-authored review evidence, not automated proof that prose is semantically correct. An accurate unchanged spec does not need a cosmetic rewrite:

decapod govern plan review-spec \
  --path .decapod/managed/specs/INTERFACES.md \
  --disposition unchanged-with-reason \
  --reason "Inspected the changed command: existing response and error contracts remain accurate"

Repeat for ARCHITECTURE and SECURITY with findings specific to each review. Use updated for a material authored correction, or requires-decision when human judgment is needed. The command computes the spec's material hash and the current code fingerprint; callers cannot supply their own hashes. Later code or authored spec changes invalidate the review. Fingerprint refresh alone is not a review.

Ordinary review-spec cannot silently approve an unchanged pending decision. After receiving an explicit human answer, record that answer deliberately:

decapod govern plan resolve-spec-review \
  --path .decapod/managed/specs/INTERFACES.md \
  --decision-ref "review thread and human answer reference" \
  --reason "The human accepted the documented contract and its stated tradeoff"

This uses the same declared-approval authority as govern plan approve; the reference preserves provenance and is not cryptographic human authentication. The original question remains in the review record. A decision about stale code or stale spec content is rejected. Never invent a decision reference or infer approval. Existing 1.0 plans remain readable; recording reviews writes plan 1.1.

After review, refresh supported projections and run validation. The validation epoch binds the plan (including review evidence), claims, authored and generated spec content, entrypoints, and managed Dockerfile. It excludes the logical validation section itself so committing a receipt does not create a self-referential commit loop. Plan and trajectory must name the same current todo. Required logical sections must be valid, and the normalized document must match committed bytes and participate in the PR diff. Checkpoints bind every authored commit to its exact material.

Publication pushes the captured commit to the captured push URL, reads the exact remote head and base back, fetches those immutable objects, and checks their base-to-head diff. GitHub publication reuses an existing matching open PR or creates a draft, verifies repository/head/base/SHA and the complete paginated PR file list, and checks for head/base movement during readback. It does not infer success from git push or gh pr create exit status alone.

remote_verified and pr_verified are separate result fields. Non-GitHub branch publication can succeed with an explicit warning that PR proof is unavailable. Missing GitHub CLI/authentication, PR creation errors, wrong targets, truncated file lists, or remote races are hard failures. PUBLICATION_INCOMPLETE means the branch was already pushed but the PR must not be reported ready. Fix the stated condition and retry workspace publish; retries reuse matching PRs and never force-push or delete the published branch. Transport diagnostics are not echoed because they may contain credentials.

Fresh work branches

workspace ensure initializes the branch-local document from the embedded, versioned template after creating an isolated branch from the selected accepted base. Its draft plan and initial trajectory describe the current claimed task, including captured intent and scope. agent.init and validation share this initializer for manually created fresh worktree branches. They do not rewrite main/master or treat initialization as successful validation.

A stable change ID survives repeated calls, process restarts, branch renames, and rebases. New-branch evidence must agree with Git's accepted base and the inherited document must be recoverable in Git. Dirty, malformed, missing-task, and ambiguous accepted context is preserved with an actionable error. Old accepted claims, checkpoints, and receipts stay in Git history; policy and explicit unresolved obligations carry forward. Read-only status and inventory never initialize.

Container workspace paths

Container workspaces share .decapod/data and .decapod/managed/migrations with the host for coordination databases, leases, and datastore locks. The clone retains branch-local tracked governance, accepted project configuration and overrides, living specs, sessions, and awareness. Initialization happens before launch against the exact prepared base, and startup preserves that branch. An older whole-.decapod bind mount or symlink is rejected with GOVERNANCE_WORKSPACE_ALIAS; recreate the workspace with the supported layout before writing governance.

Host-root runtime lookups alias the branch's managed directory, with only managed/migrations overlaid from the shared host ledger. This preserves atomic ledger updates and prevents historical migrations from rerunning, while version counters and tracked specs remain branch-local. Existing host config and overrides are available read-only for shared-datastore policy decisions; branch files remain the input to source and document validation.

Error Handling

Decapod uses Rust's Result<T, DecapodError> contract internally. Commands return errors to the process boundary, where Decapod prints a human-readable message on stderr and exits unsuccessfully. The error variant is useful for the message and recovery guidance; it does not currently select a distinct process exit status.

Process Exit Status

StatusMeaningDescription
0SuccessThe operation completed successfully.
1Decapod operation failureA domain, validation, configuration, session, I/O, or storage error was returned. decapod validate also uses status 1 when a gate fails.
2CLI syntax failureClap rejected an unknown command, argument, or option before Decapod ran the operation.
127Shell command not foundThis is normally emitted by the calling shell when decapod or another command is absent; Decapod does not use 127 for its Rust errors.

Do not infer a unique status from DecapodError::Config, NotFound, or SessionError: all of those domain errors currently use status 1. Scripts that need to distinguish failures should inspect the command output or use a structured command surface rather than depend on the error text as a stable API.

Idiomatic Rust Error Handling

Functions that can fail return Result and use ? to propagate errors. Use map_err when a lower-level error needs to be translated into Decapod's domain error type or given application context:

fn load_config(path: &Path) -> Result<Config, DecapodError> {
    let text = std::fs::read_to_string(path)?;
    toml::from_str(&text).map_err(|error| DecapodError::Config(error.to_string()))
}

fn run(path: &Path) -> Result<(), DecapodError> {
    let config = load_config(path)?;
    validate_config(&config)
        .map_err(|message| DecapodError::ValidationError(message))?;
    Ok(())
}

The ? operator preserves the original error when a From conversion exists (for example, std::io::Error becomes DecapodError::IoError). map_err is appropriate when the caller needs a different domain variant or additional context. Avoid unwrap and expect for user input, files, environment variables, or external commands; reserve them for proven invariants and test fixtures.

At the CLI boundary, src/main.rs matches the result from decapod::run(), prints the error with its Display implementation, and exits with status 1. That keeps error propagation explicit without exposing Rust's debug-style enum representation to command-line users.

Error Variants and Recovery

DecapodError currently contains these variants:

  • StorageError: inspect the Dactyl route, host-runtime availability, schema, and lock state.
  • IoError: check the referenced path, permissions, and external process.
  • DatabaseInitializationError: inspect repository initialization and schema setup.
  • PathError: correct the repository, workspace, or artifact path.
  • EnvVarError: check the required environment variable and its encoding.
  • ValidationError: follow the reported gate and remediation command.
  • NotFound: verify the requested task, workspace, document, or artifact ID/path.
  • NotImplemented: use a supported command or defer the operation.
  • Config: correct .decapod/config.toml or the relevant environment setting.
  • ContextPackError: inspect the context pack and its integrity metadata.
  • SessionError: run decapod session acquire, then retry the operation.

Local Dactyl SQLite prerequisite

LOCAL_SQLITE_RUNTIME_REQUIRED is a targeted agent remediation, not a repository corruption report. It means the project selected backend=local and Dactyl could not load a host SQLite shared library. Install the operating system SQLite runtime or set DACTYL_SQLITE_LIBRARY once in the current shell to an absolute library path. Decapod persists a discovered path in the user-level ~/.config/decapod/runtime.toml, so the setting is reused across projects on that machine; cloud-backed commands do not require this runtime.

The wrapped SQLite, I/O, and environment errors remain available through the standard std::error::Error::source chain, so callers can log the underlying cause without parsing the display string.

Local database maintenance diagnostics

data db verify, backup, and recover emit JSON before returning a failure. The diagnostic_status field is the stable operator classification:

  • healthy: Dactyl completed the requested operation and its verification.
  • unavailable: the SQLite runtime or storage is unavailable.
  • locked: bounded coordination or SQLite lock contention prevented progress.
  • corrupt: Dactyl found a malformed database or failed integrity verification; failure_code distinguishes details such as malformed_database and corrupt_database.
  • unsupported: the selected Dactyl capability or access mode is unsupported.
  • recovery_failed: recovery failed after it was explicitly requested.
  • recovery_rollback_failed: recovery and rollback both failed and require human review.

automatic_repair is always false. A failed diagnostic does not trigger REINDEX, dump/reload, replacement, or any other repair. Recovery is an operator-only command and requires writer quiescence; Dactyl owns WAL/SHM handling, atomic replacement, rollback, and DELETE journal-mode activation.

Artifacts

Decapod governs authored state and produces generated evidence and projections. Those classes are not interchangeable.

These artifacts are the inspectable surface of .decapod/ as the repo-native substrate for governed agent work. They preserve the state that should survive beyond a chat transcript: intent, architecture assumptions, selected context, validation output, and proof provenance.

Authored and managed state

The files under .decapod/managed/ include agent-authored project contracts and Decapod-managed state. They are not all generated.

specs/

Living documentation of the project's intent and design. The acting agent authors and maintains this prose; Decapod requires and validates it.

  • INTENT.md: What the project is trying to achieve.
  • ARCHITECTURE.md: High-level design and diagrams.
  • INTERFACES.md: Defined APIs and boundaries.

Generated evidence and projections

Decapod generates supported context capsules, attestations, manifests, receipts, and proof artifacts from governed inputs. A generated projection is a consumable view, not an independent authority that can replace its source.

Evidence and provenance records

  • provenance/: Manifests and checklists for promotion.
  • custody/: Detailed evidence logs and contradiction records.
  • diagnostics/: Optional logs for troubleshooting.

Context capsules

Deterministic, generated projections used by agents to orient themselves. Their provenance identifies the authority from which they were resolved.

AGENTS.md, CLAUDE.md, etc.

Root-level entrypoints for AI agents. These files point agents to the Decapod kernel and provide their starting instructions.

See Governance Artifact Inventory for state ownership and lifecycle details.

Contributing to Decapod

Decapod is a governed agent control plane. Contributions are accepted when they increase enforcement value with minimal surface area.

Non-Negotiable PR Rules

Every PR MUST include:

  • Intent: What invariant or behavior is being changed.
  • Invariants affected: An explicit list of impacted invariants.
  • Proof added: A test, gate, or command that enforces the change.

Local Dev & Tooling

Decapod uses Bazel (coordinated via Bazelisk) as its primary build and test system.

# Build the decapod binary
bazelisk build //:decapod

# Run all tests
bazelisk test //:core_tests

# Initialize and validate decapod locally
bazel run //:decapod -- init --proof
bazel run //:decapod -- validate

Nix Development Shell

If you are using Nix, you can enter a fully reproducible development shell containing all the required tooling by running:

nix develop

You can also build Decapod using Nix:

nix build

Before You Open a PR

Before submitting your PR, ensure that Decapod's governance gates and CI expectations are satisfied:

  • Work in an isolated worktree via decapod workspace ensure after claiming a todo. Do not work directly on master.
  • Run decapod validate and ensure it passes successfully.
  • Managed spec projections (.decapod/managed/specs/*) are written only inside that claimed worktree. workspace status does not refresh them on the protected root. Include the refreshed specs in the same PR as the code change (GitHub #1255).

GitHub Workflow Permissions

[!IMPORTANT] GitHub Workflow Permissions (workflow scope)

If you are contributing changes that trigger GitHub Actions workflows or edit files under .github/workflows/, your Personal Access Token (PAT) must have the workflow scope.

To verify if your token has the appropriate permission level, run the following API call:

curl -I -H "Authorization: Bearer YOUR_GITHUB_TOKEN" https://api.github.com/user

Inspect the X-OAuth-Scopes header in the response. It must contain the workflow scope (for example: X-OAuth-Scopes: repo, workflow).