Skip to content

The prompt registry

Status: implemented (internal/prompts, dacli prompt list|show).

Every multi-sentence piece of agent-facing prose dacli emits lives in one place: template files under internal/prompts/tpl/, embedded at build time, overridable per workspace. This exists because a prompt buried in an Fprintf chain cannot be audited, diffed in a PR, or improved without recompiling — and for this tool, prompts are load-bearing artifacts. It is the same doctrine as adapters and shortcuts: prose is data, not code.

The registry schema is dacli-prompt/v1 and its current semantic base version is autonomous-delivery/v1. Every template starts with a machine-readable declaration:

<!-- dacli-prompt schema: dacli-prompt/v1 base: autonomous-delivery/v1 -->

The declaration is stripped before delivery. Every invocation.txt records prompt_schema, prompt_version, the hash of the shared semantic contract, and the SHA-256 hash of the exact prompt bytes delivered after brief, role, worktree, and recovery instructions are assembled. This makes a replay identify both the governing semantics and the actual task-specific input.

The registry

Prompt Used by Carries
autonomous_delivery every spawn and supervise invocation One provider-neutral contract for identity/deduplication, estimates and critical path, model economics, role/grant/worktree isolation, verification and landing, budgets/recovery, evidence, adapters, and the implementer/reviewer/planner/auditor/recovery lifecycle matrix
protocol_preamble spawn, supervise How a child reports: the binary path, report-immediately, ask-don't-guess, findings enter sibling briefs unverified until a verify panel confirms them, never-retry-refused, and the rw/ro verb split
supervise_correction supervise turns > 1 The unmet criteria, named exactly
brief_header every brief The est-tokens line and the data-not-instructions warning — a security posture that deserves review as a file
refusal_next MCP exit-3 mapping The do-not-retry instruction attached to every refusal
mcp_tools mcp serve All 16 tool descriptions, one sectioned file — the entire agent-facing tool manual in a single reviewable diff; the cli escape-hatch section maps the wider surface (spawn/wait/agents lifecycle, accept/integrate/ship close-out, calibrate/taint gates, github mirror)
git_workflow spawn/supervise, rw children Branch-per-task (dacli/NNN-slug), commit discipline, red-suite-means-unchecked; the push-and-gh pr create flow only with --pr, otherwise an explicit do-not-push with the owner close-out (accept then integrate/ship/merge) and the decompose-and-delegate path (spawn --detach/--claim/--advise/--max-tokens, wait, agents --tail, taint/token gates)
review_workflow spawn/supervise with --review Judge the gh pr diff against acceptance criteria, not taste; every defect filed twice (dacli finding + PR comment); approve/request-changes semantics
verify_refute verify panel seats The adversarial framing: attack the claim, default to REFUTED when uncertain, one evidence-bearing verdict, judge-don't-fix

dacli prompt list shows the registry with overrides marked; dacli prompt show <name> prints the resolved template.

Overrides, compatibility, and migration

A file named .dacli/prompts/<name>.md wins over the embedded default — nearest-wins, same as templates. Prompt tuning becomes a workspace commit: attributable, revertible, reviewable, and visible to dacli taint like any other content. Every override must begin with the schema declaration above. Missing declarations and versions other than the binary's current schema fail closed; dacli never silently combines old lifecycle prose with a new scheduler. To migrate an override, diff it against the new embedded template, reconcile semantic changes, update the declaration, run the focused prompt tests, and review the resolved prompt with dacli prompt show <name>.

A broken protocol_preamble or autonomous contract override fails the spawn (a child working into the void is worse than no child); a broken brief_header override falls back to the embedded default (a brief without the untrusted-content warning must not ship).

Composition and runtime boundary

autonomous_delivery is composed once and delivered unchanged to Codex, Claude Code, Gemini, Copilot, and generic executors. Runtime adapters own only transport and configuration: binary/arguments, stdin versus argument prompt delivery, sandbox flags, model flags, output/usage parsing, and provider-specific context discovery. They do not carry alternate workflow semantics and no provider is the framework default.

Command examples in the contract are checked against the aggregated clikit.Command registry, and the prompt states the canonical exit-code contract. Removing or renaming a referenced command therefore breaks the CLI contract test rather than leaving stale executable prose.

Token-size tradeoffs

The shared contract has a deterministic golden hash and a 7,000-byte guardrail. Keep safety and stop conditions inline because every runtime must receive them; put explanatory tutorials in documentation or one-level skill resources. A workspace override that adds tokens is paid on every invocation and every supervise turn, so compare the resolved size and measured run cost before expanding it. Do not shorten the prompt by deleting a required typed section: the registry test rejects missing sections and role lifecycles.

MCP descriptions are currently embedded-only — the server builds its tool list before it has a workspace. Known limitation, not a decision.

The boundary, so it doesn't erode

One-line refusal and usage messages stay in code. They are the exit-code contract's surface: tested by exact string, versioned with the behavior they describe, and meaningless apart from it. The rule of thumb: if it teaches an agent how to behave, it's a prompt (file); if it reports what just happened, it's a message (code). The 49 refusedf/usagef one-liners are messages.

Audit trail

Extracted 2026-07-21 from five sites: protocolPreamble's nine-Fprintf chain (the complaint that triggered this), the supervise correction, the brief header, the MCP refusal text, and 16 inline tool-description literals. The extraction immediately paid once: get_context's description had already drifted (it didn't mention the Lessons section added by P1) — fixed in the registry file, where the next drift will be a one-line diff instead of an archaeology dig.