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.
- Single-Agent Workflows: The lifecycle of an agent claim, ensure, validate, and finish loop.
- Multi-Agent Workflows: Handling concurrent agents, task claiming, and locking database state.
- Workspace Isolation: Setting up isolated Git worktrees and Docker containers to run tasks securely.
- External Trackers: Integrating Decapod with Jira, Linear, or GitHub Issues.
π‘ Core Concepts
Deep dive into the architecture and mechanisms that make Decapod unique.
- Agent-First Architecture: Why Decapod is designed to be called directly at agent "inference pressure points".
- Explicit Intent: Converting ambiguous prompts into concrete, versioned specifications.
- Workspace Sandboxing: How isolated execution layers keep your primary branches clean and safe.
- Proof & Validation: Verifying correctness programmatically through policy evaluation instead of agent self-reporting.
- Common Questions: Short architectural answers about agents, specifications, daemonless execution, trackers, and proof-backed completion.
- Repository Constitution: Setting the global guidelines that steer agent behavior.
- Config Overrides: Project-specific adjustments to constitutional guidelines.
- Model Context Protocol (MCP): Navigating Decapod tools through structured agent protocols.
π Reference Manual
Hard specifications, command lists, configuration schemas, and error codes.
- Config Specification (config.toml): Key-value reference for repo-level policy control.
- CLI Reference: Detailed breakdown of commands and options (init, validate, session, todo, decide).
- Error Reference: Decapod exit codes, validator failures, and self-healing instructions.
- Artifact Reference: Layout and schema of generated intent, handshake, and validation specs.
π οΈ Developer Resources
To contribute or integrate Decapod into your platform:
- Read the Contributing Guidelines.
- Visit the main GitHub Repository: DecapodLabs/decapod
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.
- 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). - 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.
- Explicit Intent: The agent records its interpretation in versioned plans, todos, and living specifications before implementation proceeds.
- 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:
- Intent Pressure: "I know what to do, but I need to formalize the spec." (see Explicit Intent,
decapod todo add,decapod infer orientation) - 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) - Coordination Pressure: "I need to ensure no one else is working on this." (see Multi-Agent Workflows,
decapod todo claim,decapod workspace status) - Validation Pressure: "I need to test the work against repository invariants and respond to the result." (see Proof & Validation,
decapod validate) - 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
- Orientation: The agent reads
AGENTS.mdand initializes its session (see CLI Reference).decapod session acquire
- Intent Capture: The agent identifies its task and formalizes the intent (see Explicit Intent).
decapod todo claim --id <id>update specs/INTENT.md(see Artifacts Reference)
- Workspace Entry: The agent moves into an isolated environment (see Workspace Sandboxing).
decapod workspace ensure
- Implementation: The agent performs the work within the workspace.
- 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
- 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 publishdecapod 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:
- 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. - 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).
- 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 handoffto transfer a task (and its current uncommitted state) between agents. - Centralized Validation: Always run
decapod validatebefore 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
- Organizational Layer (External): A human creates an issue in Linear (e.g.,
DEV-456). - 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" - Execution (Isolated): The agent claims the todo and enters its isolated workspace (see Workspace Isolation).
- Proof (Verification): The agent marks the task as done, satisfying the Decapod proof gates (see Proof & Validation).
- 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 installfor 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:
- Ingestion & Orientation: The agent reads
docs/agent/and queries theconstitution(see Repository Constitution) to understand the repo's rules and available tools. - Task Claiming: The agent claims a
todoto establish exclusive custody and prevent collisions (see Single-Agent Workflow). - Context Resolution: The agent uses
rpc --op context.resolveorinfer orientationto gather the precise context needed for the specific task. - Implementation: The agent works in an isolated
workspace(see Workspace Sandboxing). - 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). - Publication: Passing gates and evidence permit a governed publication transition. Marking a task
donerecords 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.mdspec. - Follow validation: Use
decapod validateearly, 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:
- Capture: Vague requests are converted into explicit tasks via
decapod todo add(see CLI Reference). - Formalize: Agents are required to update or verify the
specs/INTENT.mddocument scaffolded in the repository (see Artifacts Reference). - 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:
- Branch Isolation: Every task is performed on a dedicated git branch, preventing accidental mutations to
main. - 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.
- 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 (likenode_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 publishbundles 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:
- inspect the validation result;
- identify the violated invariant;
- perform the sanctioned remediation;
- update the relevant artifact;
- re-run validation; and
- 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:
- Global Constitution: Over 100 normative documents embedded in the Decapod binary. These cover universal engineering standards (e.g., "Always write tests", "Minimize breaking changes").
- 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). - 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.
| Key | Type | Default | Description |
|---|---|---|---|
specs | bool | true | If true, scaffolds living documentation under .decapod/managed/specs/. |
diagram_style | enum | "ascii" | Preferred style for generated architecture diagrams ("ascii" or "mermaid"). |
entrypoints | list | [...] | The agent entrypoint files to maintain (e.g., AGENTS.md, CLAUDE.md). |
The [repo] Section
Defines the operational policy and metadata for the repository.
| Key | Type | Default | Description |
|---|---|---|---|
product_name | string | None | The canonical name of the software product. |
product_summary | string | None | A high-level description of the product's purpose. |
architecture_direction | string | None | The intended architectural style (e.g., "monolithic", "event-driven"). |
product_type | string | None | Categorization (e.g., "cli", "library", "service"). |
done_criteria | string | None | The global definition of "done" that all work must satisfy. |
primary_languages | list | [] | The primary programming languages used in the repository. |
detected_surfaces | list | [] | Entrypoints and interfaces detected in the repo (e.g., "cargo", "npm"). |
external_tracker | bool | false | Whether Decapod should expect and validate external issue references. |
container_workspaces | bool | true | If true, Decapod will strongly encourage/enforce Docker isolation for worktrees. |
backend | enum | "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.
| Key | Type | Default | Description |
|---|---|---|---|
provider | enum | "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->validatei->initt->todow->workspaceg->governs->sessiond->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; whenjevis selected, an explicitly suppliedTYPESAFE_API_KEYis 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 todecapod 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 isopen,supported,refuted, orblocked. 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.--repairinitializes absent empty claims;--claims-note <text>records a current-PR checkpoint;--compactpreserves 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.
| Operation | Dactyl request | Scope/authentication |
|---|---|---|
| Read/list | POST /query | SQL plus opaque versioned context |
| Add/claim/release/complete | POST /batch | ordered 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:
- an explicit client credential;
DECAPOD_ACCESS_TOKENfor controlled development and CI use;- the selected endpoint-scoped machine session for Supabase, or the legacy
~/.local/share/decapod/session_token.jsononly 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:
- Run
decapod init --backend cloud --proofand confirm.decapod/config.tomlcontains only the backend selectionrepo.backend = "cloud"for cloud composition. The Propodus endpoint and provider are binary-owned; no service URL or project identifier is stored in project configuration. - Ensure
originis 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. - Run
decapod todo list,add,get,show,claim, ordone. If no machine session exists, first completedecapod init --backend cloud; the initialized machine state then resumes the one-time browser handoff on the next invocation. A controlledDECAPOD_ACCESS_TOKENremains available for protected proofs. - Cloud todo commands use the same
TodoStorecommand 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 validationoutcome_unknown: a dispatched mutation may have committed, or an interrupted attempt has not been reconciled. Never interpret it as rollbacksucceeded: 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
- Decapod consumes
dactyl-db0.11.1 from crates.io, including the Supabase client capability reviewed in Dactyl #92 and released in v0.11.1.Cargo.lockrecords the registry source and checksum; there is no Git or local-path dependency override. Build withcargo build --locked; the default features includesupabase-cloud. A--no-default-featuresbuild 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, runcargo package --lockedandcargo publish --locked --dry-runto verify the packaged registry dependency. - 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.
- In machine-local runtime configuration, set
DECAPOD_PROPODUS_API_URLto that service's HTTPS origin. No datastore override is required: omittedDECAPOD_CLOUD_DATASTOREselects Supabase. Explicitsupabaseis also accepted. Literal-loopback HTTP is supported for disposable test services only. This is neither a PostgreSQL DSN nor Supabase REST. - Select
repo.backend = "cloud". Production use requires a service that also implements the existingdecapod init --backend cloudonboarding, session exchange and refresh contract. A task-only/queryand/batchservice 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. - Run normal
todo list,add,get,show,claim,release, anddonecommands.todo done --validatedremains 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_boundarywithsupabase-cloudchecks 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_contractis 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_contractis separately ignored. Run it only in an operator-approved protected environment withDECAPOD_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:
| Section | Writer | Purpose |
|---|---|---|
| Plan | decapod govern plan | Refined intent, scope, phases, decisions, and proof hooks |
| Claims | decapod govern artifacts claim | Current-PR falsifiable claims; support requires proof |
| Trajectory | decapod govern trajectory | Intent custody, scope, actions, assumptions, checks, and evidence |
| Validation | decapod validate | Receipt bound to current repository inputs and trajectory |
| Jev (optional) | assurance.evaluate with Jev enabled | Advisory 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:
- Begin one stable PR identity with
govern artifacts begin-pr. - Populate intent, todo binding, and scope with
govern plan initorupdate. - Record actual current-PR claims with falsifiers and planned checks/proof hooks; do not create placeholder claims or claim support before evidence exists.
- Perform the work and record its inspected/modified paths, checks, evidence,
and unresolved assumptions with
govern trajectory initandrecord. - Run
decapod validateagainst the current completed batch. - 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:
- Master is generated by Decapod
vN(pins sayvN). - User/agent PRs with installed
vNmerge. - A new release
vN+1is cut from master (Cargo/CHANGELOG only). - Users install
vN+1. Master pins remainvNuntil a user/agent PR runs validate withvN+1and 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
| Status | Meaning | Description |
|---|---|---|
| 0 | Success | The operation completed successfully. |
| 1 | Decapod operation failure | A domain, validation, configuration, session, I/O, or storage error was returned. decapod validate also uses status 1 when a gate fails. |
| 2 | CLI syntax failure | Clap rejected an unknown command, argument, or option before Decapod ran the operation. |
| 127 | Shell command not found | This 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.tomlor the relevant environment setting.ContextPackError: inspect the context pack and its integrity metadata.SessionError: rundecapod 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_codedistinguishes details such asmalformed_databaseandcorrupt_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 ensureafter claiming a todo. Do not work directly onmaster. - Run
decapod validateand ensure it passes successfully. - Managed spec projections (
.decapod/managed/specs/*) are written only inside that claimed worktree.workspace statusdoes 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 (
workflowscope)If you are contributing changes that trigger GitHub Actions workflows or edit files under
.github/workflows/, your Personal Access Token (PAT) must have theworkflowscope.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/userInspect the
X-OAuth-Scopesheader in the response. It must contain theworkflowscope (for example:X-OAuth-Scopes: repo, workflow).