contract-driven-delivery
v3.13.1
Published
Contract-driven delivery kit for AI coding agents with deterministic context indexes, manifest-backed read-scope governance, and orchestrated contracts-first delivery.
Maintainers
Readme
Contract-Driven Delivery Kit
cdd-kit is a contract-driven delivery runtime for Claude Code and Codex. Its default agent-native flow selects a risk profile, a small capability/Doctrine set, executable checks, independent review, and approvals. Contracts and deterministic evidence remain authoritative; routine work no longer requires a fixed agent procession or seven hand-authored change artifacts.
Designed for solo developers and small teams building brownfield production systems (dashboards, APIs, workflow tools, data apps), especially when non-engineers or product owners want AI to do the implementation while they stay in the spec-author and reviewer seat.
Context Governance v1 adds a manifest-driven planning layer for AI agents. New changes include context-manifest.md; agents should use cdd-kit index query and cdd-kit index impact before broad source reads. cdd-kit gate focuses on delivery quality, not post-run read paperwork.
Install
npm install -g contract-driven-deliveryRequires Node.js 18+ and Python 3.8+ (for contract validators).
Quick Start
# 1. Install globally
npm install -g contract-driven-delivery
# 2. Go to your repo
cd your-repo
# 3. Deploy the kit (one command: scaffold + arm chokepoints + MCP + indexes)
cdd-kit setup
# 4. Start agent-native work from Claude Code or Codex:
cdd-kit work add-jwt-auth "Add JWT authentication to the API"
cdd-kit setupis the one-command path: it scaffolds the project, arms the enforcement chokepoints, registers the MCP server (best-effort), and builds the context indexes, then prints what to do next. It is idempotent — re-run it any time, including afternpm update, and it upgrades in place. Prefer the fine-grained commands (init,refresh,install-hooks, …) only when you need to control a single step.
Agent-native workflow (default)
cdd-kit work add-jwt-auth "Add JWT authentication to the API" --provider claude
cdd-kit runtime agent prompt <run-id>
# implement inside capsule scope
cdd-kit runtime agent complete <run-id> --status passed --actor claude --summary "Implemented scoped JWT behavior"
cdd-kit runtime check run <run-id> --all
# Controlled only: independent reviewer + named approvals
cdd-kit runtime approval import signed-approval.json <run-id>
cdd-kit runtime verify <run-id>
cdd-kit gate add-jwt-authUse --provider codex for Codex. Lightweight, balanced, and controlled profiles
store concise state/evidence under .cdd/runtime/; specs/changes/<id> and the
legacy seven artifacts are not required. Controlled work cannot pass without a
digest-bound independent review. High-risk approval identity is verified using
trusted public keys in .cdd/approval-policy.yml; free-form --actor text
cannot approve work, and configured approvals cannot be skipped.
The human-authored acceptance oracle is retained: strict always requires it;
controlled requires it when policy/capsule risk activates it or the user passes
--require-acceptance. The runtime never invents or silently relocks an oracle.
cdd-kit runtime agent prompt loads only Doctrine selected by the capsule.
Checks, implementation records, review, and approvals become stale after source
or policy changes. cdd-kit guidance audit measures recurring guidance cost;
cdd-kit runtime parity compares a completed runtime with the strict lane.
Hit a problem with the kit itself? cdd-kit report --title "..." --body "..."
drafts a GitHub issue (enriched with version/environment context) against the
kit's upstream repo. It only files when you add --confirm, so an agent shows
you the draft first and files it only after you approve. The same capability is
exposed to MCP clients (Claude Code, Codex) as the cdd_report_problem tool.
Thinking about giving agents more autonomy and dropping some of this harness?
Read docs/loosening-the-harness.md first -- it is the decision rule for which
checks are ceremony you can drop and which are load-bearing bone to keep as
agents get stronger, plus how to loosen reversibly on mutation evidence.
Strict compatibility workflow
The following /cdd-new documentation describes the preserved strict workflow
for existing projects and explicit maximum-ceremony changes. It is no longer the
default for balanced/controlled work.
How to Direct Claude Code in strict mode
All workflows are started by typing a natural language instruction to Claude Code in your IDE or terminal. The
/cdd-*prefixed commands are Claude Code skills — not shell commands.
Starting a new project (first time)
After cdd-kit init, open Claude Code and say:
Scan this repo and create a project profile. Tell me what contracts are
missing and what the minimum setup should be before we start any feature work.Claude will:
- Run
cdd-kit detect-stackto detect the tech stack - Read your existing code structure
- Create
specs/project-profile.md - Identify gaps in
contracts/and recommend filling order
Then fill your contracts in this order (Claude can help draft them):
| Contract | File | What it captures |
|---|---|---|
| Env | contracts/env/env-contract.md | Every env var, secret flag, default, validation |
| API | contracts/api/api-contract.md | Every endpoint: method, path, auth, schemas, errors |
| Data | contracts/data/data-shape-contract.md | Schemas, types, nullability, bad-data behavior |
| CSS/UI | contracts/css/css-contract.md | Design tokens, component states, forbidden raw values |
| Business | contracts/business/business-rules.md | Rules, edge cases, decision tables |
| CI/CD | contracts/ci/ci-gate-contract.md | Gate tiers, promotion policy, rollback policy |
Starting a strict legacy task / feature / bug fix
Type this in Claude Code:
/cdd-new add JWT authentication to the APIor
/cdd-new redesign the user dashboard to show real-time metricsor
/cdd-new fix the order export timeout when result set exceeds 10 000 rowsWhat happens:
- Claude generates a
change-id(e.g.add-jwt-auth) and scaffoldsspecs/changes/add-jwt-auth/ - If the request is ambiguous, Claude asks back for affected surface, desired behavior, and success criterion before spending a classifier round-trip
- The
change-classifieragent (Opus) reads the request, classifies risk and tier, decides which agents are needed - If the request is too broad, the classifier can return an atomic split proposal instead of forcing one Tier 0/1 monolith
- For Tier 0-1 work, Claude's narration uses stage badges so users can tell whether the flow is deciding, implementing, testing, or reviewing
- Agents run in order: contracts → test plan →
spec-architectwritesdesign.mdif required → CI/CD gates → implementation plan → backend engineer → frontend engineer → QA implementation-plannerreads the confirmed artifacts and writesimplementation-plan.md, the concise execution packet implementation agents follow. It does not createdesign.md; missing required design routes back tospec-architect.- Implementation agents write code/tests from that plan and optional concise handoff notes
cdd-kit gate <change-id>runs automatically to confirm all artifacts are complete- Claude reports a summary and the suggested git commit
Workflow Lanes: Avoiding Ceremony for Small Fixes
CDD is a governance workflow, not a rule that every edit must become a full proposal. Use the tracked /cdd-new flow when a change can affect product behavior, contracts, data shape, API behavior, env/deploy rules, CI/CD, security, permissions, cross-module architecture, or release risk.
Use a lightweight maintenance lane for small corrections where the intent is already obvious:
| Lane | Examples | Required record |
|---|---|---|
| maintenance / micro-change | typo fixes, comment updates, README cleanup, formatting, lint-only fixes, tiny local test repair | normal commit message and test output if applicable |
| tracked CDD change | behavior changes, contract updates, API/data/env/security/CI changes, cross-module refactors, high-risk bug fixes | specs/changes/<id>/, implementation-plan.md, tasks.yml, context-manifest.md, and cdd-kit gate |
Do not add hard pre-commit rules that block every src/, tests/, or contracts/ edit unless your team explicitly wants that policy. The default kit favors low-friction traceability: make risky changes reviewable, but let obvious maintenance edits stay small.
Machine-readable metadata such as future change.yml / trace.yml should follow the same rule: generated from existing artifacts to reduce token use and markdown parsing, not introduced as extra forms. See docs/machine-readable-change-design.md for the proposed shape.
Agent Ownership Model
CDD uses two agent classes on purpose:
change-classifier,contract-reviewer,qa-reviewer,visual-reviewer,dependency-security-reviewer,ui-ux-reviewer,repo-context-scanner, andspec-drift-auditorare non-writing agents: none hasEdit,Write, orMultiEdit, so they cannot author artifacts — they return analysis, verdicts, or optional handoff notes and main Claude writes the corresponding files. Note thatqa-reviewer,visual-reviewer,dependency-security-reviewer,repo-context-scanner, andspec-drift-auditoralso carryBash— they need it to run gates,npm audit, screenshot capture, and drift scans.Bashis not a hard read-only boundary (a shell can write files), so their read-only behaviour is a prompt convention on top of the enforced no-Edit/Writetool set, not a tool-level guarantee.bug-fix-engineeris an implementation agent for symptom-driven defects. It converts user-visible reports into graph/index-guided hypotheses, reproduces the issue where feasible, applies the smallest fix, and adds regression evidence.implementation-planner,backend-engineer,frontend-engineer,e2e-resilience-engineer,monkey-test-engineer,stress-soak-engineer,ci-cd-gatekeeper,test-strategist, andspec-architectare write-capable. They write their own owned artifacts directly: for example,spec-architectownsdesign.md, whileimplementation-plannerownsimplementation-plan.md.
This split is deliberate:
- Review and audit agents carry no
Edit/Write/MultiEdittool so they cannot silently author or overwrite the thing they are supposed to assess. - Implementation and planning agents write directly so large artifacts and code edits do not have to be relayed back through the main orchestrator, which reduces token waste and preserves clearer ownership.
tasks.ymlremains owned by main Claude so task state changes stay centralized even when multiple agents contribute files.
Artifact Minimization
CDD keeps the authoritative artifact set small. Routine reviewer findings should not become new markdown files.
| artifact class | files | rule |
|---|---|---|
| Core decision and planning | change-classification.md, context-manifest.md, test-plan.md, ci-gates.md, implementation-plan.md, tasks.yml | required for implementation changes |
| Conditional design | design.md | only when spec-architect is required |
| Durable evidence reports | qa-report.md, visual-review-report.md, regression-report.md, monkey-test-report.md, stress-soak-report.md | only for blocking findings, approved-with-risk, visual evidence bundles, or high-risk load/soak results |
| Lightweight traces | agent-log/*.yml | optional concise pointers for routine evidence and resume/debugging |
Later artifacts should reference earlier artifacts by path, section, acceptance criterion, decision id, or gate name. They should not copy full test strategy, CI policy, design rationale, or contract prose. This keeps token use bounded and prevents multiple markdown files from becoming conflicting sources of truth.
You stay in control by:
- Reviewing the
change-classification.mdbefore implementation starts - Checking the
test-plan.mdto confirm the right test families are planned - Checking
implementation-plan.mdwhen you want to review the exact execution packet before code changes - Reading the final QA summary for the release-readiness verdict
Updating architecture or contracts
/cdd-new update the API contract to add pagination to all list endpoints/cdd-new migrate the database from MySQL to PostgreSQL/cdd-new add Redis caching layer to the reporting queriesThe change-classifier will detect that these are architectural or contract-level changes, assign a higher risk tier (0–1), and automatically require:
- Architecture review (
spec-architectagent) - E2E, resilience, stress, and monkey tests
- Updated contracts before any implementation begins
Resuming an interrupted task
If a session was cut off or you need to return to an in-progress change:
/cdd-resume add-jwt-author, if you're unsure of the change-id:
What changes are currently in progress? (cdd-kit list)What happens:
- Claude reads
tasks.ymland existing change artifacts to determine what was completed - Reports the current state (which agents ran, which tasks are pending)
- Asks if you want to continue from the next pending agent
- Resumes the full agent flow from where it stopped, with no duplication
If you're upgrading from an older version and your change was created before v2.0.0, Claude will automatically run
cdd-kit migrate <change-id>to upgrade the format before resuming.
Closing a completed change
After the PR is merged:
/cdd-close add-jwt-authWhat happens:
- Runs
cdd-kit gateto confirm the change still passes - Synthesizes
archive.md— a permanent record of what changed, what tests were added, and what lessons were found - Promotes only evidence-backed durable learnings to
contracts/or project guidance (CLAUDE.md/CODEX.md). General agents record evidence and findings only; durable learning promotion happens during/cdd-closeStep 3. - Runs
cdd-kit archive add-jwt-auth— moves the change fromspecs/changes/tospecs/archive/2026/ - Reduces the active context that future Claude sessions need to load
Keeping
CLAUDE.mdsmall.CLAUDE.mdis loaded into every session, so each promoted line is a recurring token cost./cdd-closetherefore promotes the bulk of learnings tocontracts/(queried on demand, not auto-loaded) and keepsCLAUDE.mdto a delimitedcdd-kit:learningsregion of one-line rule + pointer entries that it consolidates (merge/replace) rather than appends — content you write outside the markers is never touched. If a project already grew a bloatedCLAUDE.mdbefore this discipline existed, run/cdd-consolidate-guidanceonce to migrate and shrink it in place.
Abandoning a change
If you decide not to proceed with a change:
/cdd-close add-jwt-authThen when Claude asks for confirmation, say "abandon it." Claude will run:
cdd-kit abandon add-jwt-auth --reason "decided to use a third-party auth service instead"The directory stays on disk for git history, but cdd-kit list will show it as abandoned.
Checking the status of all active changes
Type to Claude:
What changes are currently in progress?Claude will run cdd-kit list, which shows:
Active changes:
add-jwt-auth [in-progress] (3 pending)
fix-export-timeout [gate-blocked]
redesign-dashboard [in-progress] (12 pending)Bounded test execution and evidence
Implementation changes prove themselves through a bounded test ladder, not
broad pytest / npm test runs. Each phase runs the narrowest useful tests,
stops at the first failure, and records a durable, machine-readable result that
the gate checks.
| phase | required | proves | |---|---|---| | collect | always | selected tests are discoverable | | targeted | always | acceptance criteria pass (narrowest mapped tests) | | changed-area | always | tests near changed source paths pass | | contract | if contracts/API/data/env/CI affected | contract validators pass | | quality | if configured | lint/typecheck/build pass | | full | final/CI | bounded full-suite smoke passes |
collect, targeted, and changed-area are the always-required floor.
cdd-kit test run writes artifacts under specs/changes/<id>/test-runs/<run-id>/
and records each phase in specs/changes/<id>/test-evidence.yml.
The gate validates that evidence, not the assistant's claims: required phases
must have passed, no failure may be waived (known-failures,
pre-existing-failures, allowed-failures, waived-failures, and
ignored-failures are rejected by the schema), and each run must reference its
own summary.json under this change's test-runs/. A required failure is
cleared only by fixing it, expanding the change's scope to cover the fix, or
opening a separate tracked change. A change with no testable code surface opts
out with test-evidence-not-applicable: "<reason>" in tasks.yml frontmatter.
See the cdd-kit test reference below and references/sdd-tdd-policy.md.
Bug-fix lane (ADR 0006)
Bug fixing starts from a symptom ("the filter is empty", "pytest fails", "the
API returns the wrong shape"), not from a desired behavior. When the
change-classifier detects a symptom-driven request it sets ## Lane\n- bug-fix
and a ## Bug Symptom Type in change-classification.md. That activates the
bug-fix lane: bug-fix-engineer must diagnose before editing
(cdd-kit bug suspects → hypotheses → reproduce), and cdd-kit gate then
requires a structured, machine-readable repair record at
specs/changes/<id>/agent-log/bug-fix-engineer.yml — the standard agent-log
envelope with a nested bug-fix: evidence block.
A behavior-changing fix must carry: symptom / expected_behavior /
actual_behavior, exactly one reproduction.status
(reproduced / test-reproduced / visual-reproduced for a behavior fix), at
least one confirmed hypothesis once reproduced, a root_cause.pointer, a fix,
a regression with status: passed, residual_risk, and a passing
test-evidence.yml (the bounded ladder above). Referenced reproduction/regression
summaries must be this change's own real cdd-kit test run artifacts under its
test-runs/. No failure may be waived.
A complete, gate-passing record:
docs/examples/bug-fix/bug-fix-engineer.sample.yml.
A real gate rejection of an incomplete one:
docs/examples/bug-fix/gate-failure.txt.
Worked examples
Each example shows the classifier markers and the salient bug-fix: block fields
for that symptom class (including the ADR 0006 PR-5 typed evidence pointer it
attaches). Full envelope omitted for brevity — see the sample above.
1. UI / visual bug (a panel renders empty). Reproduce with a screenshot/browser
capture; a visual-reproduced reproduction requires visual_evidence.before
(a durable, repo-relative pre-fix artifact — the gate rejects an absolute or
missing path).
## Lane
- bug-fix
## Bug Symptom Type
- visualbug-fix:
reproduction: { status: visual-reproduced }
visual_evidence:
before: "specs/changes/<id>/evidence/before.png" # required for visual-reproduced
after: "specs/changes/<id>/evidence/after.png" # optional
root_cause: { pointer: "src/pages/Orders.tsx:42-68" }
regression: { status: passed, command: "npm test -- orders-filter", summary: "specs/changes/<id>/test-runs/<reg>/summary.json" }2. pytest failure repair (a test reproduces the defect). Use
test-reproduced with failing_before_fix: true: the reproduction.summary must
point at a run that failed (or timed out) before the fix, with its
reproduction.command; the regression then references the post-fix passing
run. Both summaries are real cdd-kit test run artifacts.
## Lane
- bug-fix
## Bug Symptom Type
- test-failurebug-fix:
reproduction:
status: test-reproduced
command: "pytest tests/orders/test_filter.py"
failing_before_fix: true
summary: "specs/changes/<id>/test-runs/<repro>/summary.json" # a FAILED pre-fix run
hypotheses:
- { id: H1, candidate: "src/pages/Orders.tsx::buildFilterOptions", reason: "graph match", result: confirmed }
root_cause: { pointer: "src/pages/Orders.tsx:42-68" }
regression:
status: passed
command: "pytest tests/orders/test_filter.py"
summary: "specs/changes/<id>/test-runs/<reg>/summary.json" # the PASSING post-fix run3. API response-shape bug (the endpoint returns the wrong shape). Record
data_evidence — a kind plus a request/response or contract pointer (a
durable, repo-relative artifact).
## Lane
- bug-fix
## Bug Symptom Type
- apibug-fix:
reproduction: { status: test-reproduced, command: "pytest tests/api/test_orders.py", failing_before_fix: true, summary: "specs/changes/<id>/test-runs/<repro>/summary.json" }
data_evidence:
kind: request-response
pointer: "specs/changes/<id>/evidence/orders-response.json"
summary: "GET /api/orders omitted the canonical status field"
root_cause: { pointer: "src/api/orders.ts:88-104" }
regression: { status: passed, command: "pytest tests/api/test_orders.py", summary: "specs/changes/<id>/test-runs/<reg>/summary.json" }4. Intermittent, diagnostic-only change (add instrumentation; do not claim a
fix yet). Mark it diagnostic-only in both places — the classifier's
## Diagnostic Only\n- yes and bug-fix.diagnostic_only: true (the gate requires
the classifier's explicit yes, not silence). A diagnostic-only record uses a
diagnostic reproduction status (intermittent / environment-blocked /
not-reproduced) and is exempt from root_cause / fix / regression — in
fact it must NOT carry them, nor a successful reproduction status. It still cannot
pass with required test failures: either record a passing test-evidence.yml for
the instrumentation, or, when no code path is exercised, set an auditable
test-evidence-not-applicable: "<reason>" in tasks.yml (one of the two is
required — it cannot pass with neither). Open a follow-up change for the real fix.
## Lane
- bug-fix
## Bug Symptom Type
- ci-failure
## Diagnostic Only
- yesbug-fix:
diagnostic_only: true
reproduction: { status: intermittent }
hypotheses:
- { id: H1, candidate: "src/export/worker.ts::run", reason: "CI-only path", result: unconfirmed }
# no root_cause / fix / regression — this change does not fix the symptom yetCLI Reference
These are shell commands — not Claude Code skills. Run them directly in the terminal, or Claude Code will run them on your behalf.
cdd-kit setup
The one-command onboarding path. Takes a repo from zero to a fully wired, enforcement-armed cdd-kit project — and brings an existing project up to date — in a single idempotent run. This is the recommended way to start; the fine-grained commands below remain available for step-by-step control.
cdd-kit setup # fresh install or in-place upgrade (auto-detected)
cdd-kit setup --provider both # scaffold Claude Code + Codex guidance
cdd-kit setup --force # fresh install: overwrite existing project files
cdd-kit setup --no-arm # skip arming the pre-commit gate and agent hooks
cdd-kit setup --no-mcp # skip the best-effort MCP registrationWhat it does, in order, with a per-step success/failure summary at the end:
- Scaffold — runs
initon a fresh repo (no.cdd/) orrefresh --yeson an existing one, so you never have to choose between update/upgrade/refresh. - Detect stack — reports the detected tech stack.
- Arm chokepoints — installs the pre-commit gate and the agent PreToolUse
hooks (graph-first + test-runner, both advisory). Skipped by
--no-arm. - Register MCP — best-effort
claude mcp add --scope user cdd-kit -- cdd-kit mcp. If theclaudeCLI is absent or the call fails, it prints the manual command and continues — agents fall back to the slower CLI path. Skipped by--no-mcp. - Context scan — builds
specs/context/project-map.md. - Code map — builds
.cdd/code-map.yml.
Every step is best-effort: a missing git repo or claude CLI becomes a warning,
never a failed run, so you always get a complete report. The run ends by telling
you the one thing to do next — open Claude Code and run /cdd-new <describe your
change>.
cdd-kit init
Installs Claude assets into ~/.claude, Codex skills into
$HOME/.agents/skills, and scaffolds project files.
cdd-kit init # global + local (recommended)
cdd-kit init --global-only # only install into ~/.claude
cdd-kit init --local-only # only scaffold project files
cdd-kit init --provider codex # install Codex skill + scaffold AGENTS.md guidance
cdd-kit init --provider both # scaffold Claude Code + Codex guidance
cdd-kit init --force # overwrite existing project files
cdd-kit init --no-arm # scaffold without arming enforcement chokepoints
cdd-kit init --no-test-runner # arm graph-first but leave the test-runner hook dormantBy default init arms the enforcement chokepoints so a fresh repo enforces
the workflow instead of carrying it dormant: the graph-first and test-runner
PreToolUse hooks (Claude provider, both advisory) and the pre-commit gate hook
are wired in place. This matters most in a fully automated, no-human-reviewer
workflow — dormant enforcement means the contracts only look like they prevent
drift, and a non-engineer would never run install-agent-hooks --test-runner
themselves. Arming is best-effort (a missing .git becomes a warning, never a
failed init); pass --no-arm to skip all of it or --no-test-runner to keep
graph-first but leave the test-runner hook dormant, and cdd-kit doctor reports
the live/dormant status of each chokepoint.
Creates: contracts/, specs/templates/, provider guidance files (CLAUDE.md, AGENTS.md, and/or CODEX.md), hooks/
.cdd/model-policy.json stores role-to-model classes (opus, sonnet, haiku) instead of provider release IDs such as claude-opus-4-7. This keeps the policy stable across Claude and Codex adapters; provider-specific tooling can map the class to the concrete model available in that environment.
Recommended: register the cdd-kit MCP server with the selected provider after init:
claude mcp add --scope user cdd-kit -- cdd-kit mcp
claude mcp list
codex mcp add cdd-kit -- cdd-kit mcp
codex mcp listThis writes the server to ~/.claude.json and exposes graph/code-map tools
directly to the agent (cdd_graph_context, cdd_graph_query,
cdd_graph_impact, cdd_index_query, cdd_index_impact). Do not rely on
manually adding mcpServers to ~/.claude/settings.json; that file is a Claude
Code UI settings format and is not the MCP registry read by the CLI.
cdd-kit update
Updates provider assets to the latest installed version. By default, update reads .cdd/model-policy.json and updates only the matching provider adapter. It does not overwrite project guidance files such as CLAUDE.md, AGENTS.md, or CODEX.md.
cdd-kit update
cdd-kit update --yes # apply without confirmation
cdd-kit update --provider codex
cdd-kit update --provider bothCodex updates the provider-neutral cdd-work skill under
$HOME/.agents/skills. Codex project guidance is AGENTS.md; CODEX.md
remains as a compatibility pointer for older cdd-kit installations.
User-level assets are tracked in ~/.cdd-kit/install-manifest.json. Interactive
updates show a dry-run and back up provider assets under
~/.cdd-kit/backups/<timestamp>/. npm postinstall updates only assets that
were previously owned by cdd-kit and remain unmodified; user-edited files are
left untouched until an explicit cdd-kit update --yes.
After Updating the npm Package
Updating npm only replaces the cdd-kit CLI package. Existing repos and
global Claude Code/Codex assets keep their previously copied agents, skills,
templates, hooks, and .cdd/model-policy.json until you sync them.
Simplest path — one idempotent command that detects the upgrade and re-wires everything (scaffold, chokepoints, MCP, indexes):
cdd-kit setup # auto-detects the existing project and upgrades in placeOr drive the steps yourself after npm update -g contract-driven-delivery:
cdd-kit refresh # dry-run preview
cdd-kit refresh --yes # apply agents, skills, templates, model policy, hook, code-map
cdd-kit migrate --all # add new per-change scaffolds such as implementation-plan.md
cdd-kit doctor --strictAfter syncing, register MCP-capable agents with
claude mcp add --scope user cdd-kit -- cdd-kit mcp. This is the recommended
way for agents to use the regenerated code graph and code-map; shell commands
remain the fallback.
What gets updated:
| command | updates | preserves |
|---|---|---|
| cdd-kit setup | everything below in one idempotent run, plus chokepoint arming, MCP registration, and context indexes | user source, contracts content, active change content |
| cdd-kit update --yes | ~/.claude/agents/ and ~/.claude/skills/ for Claude provider projects | project files |
| cdd-kit upgrade --yes | missing repo files only: contracts, templates, .cdd/, guidance, workflows | existing files and project guidance |
| cdd-kit refresh --yes | global agents/skills, missing project files, kit-shipped templates with backup, model policy roles, hooks, .cdd/code-map.yml | user source, contracts content, active change content |
| cdd-kit migrate --all | existing specs/changes/* metadata and new required scaffolds | implementation code and completed archive history |
For releases 2.0.18 and newer, run cdd-kit refresh --yes so the
implementation-planner agent, updated /cdd-new and /cdd-resume skills,
fresh specs/templates/, and .cdd/model-policy.json role binding are all in
place. Then run cdd-kit migrate --all so existing active change directories
receive implementation-plan.md; fill required design.md with
spec-architect before resuming the planner or implementation agents.
Upgrading to 2.2.0
2.2.0 arms enforcement chokepoints by default on a fresh cdd-kit init, adds
the mechanical tier floor, cdd-kit classify-check, and cdd-kit code-map
--watch. A repo first set up with an older version keeps its chokepoints
dormant after a plain npm/refresh update — cdd-kit doctor will show them
as such. To bring an existing repo up to the 2.2.0 enforcement posture:
npm install -g contract-driven-delivery # get 2.2.0
cdd-kit refresh --yes # sync agents/skills/templates/hooks/code-map
cdd-kit install-hooks # arm the pre-commit gate
cdd-kit install-agent-hooks --graph-first advisory # arm the graph-first hook (or: strict)
cdd-kit install-agent-hooks --test-runner advisory # opt-in: steer broad test runs to the bounded ladder (ADR 0005 §10)
cdd-kit doctor # confirm both chokepoints report "live"The tier floor needs no policy file — built-in defaults apply when
.cdd/tier-policy.json is absent, so existing repos are protected without a
re-init. To customize or disable it, scaffold the policy with cdd-kit upgrade
--yes (writes an editable .cdd/tier-policy.json) and set rules or
"enabled": false. Bypass a single change with tier-floor-override:
"<reason>" in its tasks.yml frontmatter (recorded as an audit warning).
A malformed .cdd/tier-policy.json (invalid JSON, rules not an array, or a
rule with a bad maxTier/patterns) no longer fails silently: each problem is
warned with the offending field and the note that your custom tier rules are
NOT in effect (the built-in defaults take over), so a typo can't leave you
believing a custom policy is active when it is being ignored.
If you do not want template overwrites, run the narrower path:
cdd-kit update --yes
cdd-kit upgrade --yes
cdd-kit migrate --all
cdd-kit doctor --strictAgent-native runtime and Boundary Guard
The agent-native runtime is the default for lightweight, balanced, and controlled profiles; the existing strict workflow remains available while parity is measured.
cdd-kit boundary init
cdd-kit boundary check --base origin/main
cdd-kit boundary check --base origin/main --verify-captures --verify-generated
cdd-kit work <change-id> "<objective>"
cdd-kit work <change-id> "<human-sensitive objective>" --require-acceptance
cdd-kit runtime status
cdd-kit runtime resume
cdd-kit runtime agent prompt
cdd-kit runtime check run --all
cdd-kit runtime review --verdict passed --actor reviewer --summary "Independent review passed"
cdd-kit runtime approval import signed-approval.json <run-id>
cdd-kit runtime verify
cdd-kit runtime parity
cdd-kit runtime parity <run-id> --mutations mutation-results.json
cdd-kit guidance audit
cdd-kit runtime migrate --provider codex # dry run
cdd-kit runtime migrate --provider codex --yes # reversible applySee Boundary Guard and the runtime contracts.
Acceptance oracles are profile-aware. Existing projects and --strict retain
the human-authored oracle and hash-lock requirements. An explicit or
runtime-selected balanced/lightweight profile does not require
acceptance.yml; controlled requires it only when the capsule or caller adds
acceptance-oracle:
cdd-kit gate my-change --profile balanced
cdd-kit gate sensitive-change --profile controlled --require-acceptanceWithout --profile and without a matching current runtime run, gate keeps its
legacy behavior. Profile adoption is therefore opt-in and rollback-safe.
cdd-kit doctor
Inspects repo-level cdd-kit health. Default mode is read-only; --fix applies only the safe auto-remediations.
cdd-kit doctor
cdd-kit doctor --simple
cdd-kit doctor --strict
cdd-kit doctor --fix
cdd-kit doctor --json
cdd-kit doctor --provider codexChecks for missing .cdd/ policy files, provider guidance (CLAUDE.md, AGENTS.md, CODEX.md), context indexes, stale specs/context/* outputs, and contract summary metadata gaps. --strict treats warnings as errors. --json emits a machine-readable report for CI or wrapper scripts. --fix auto-runs context-scan for stale or missing indexes, backfills empty .cdd/model-policy.json role bindings, regenerates a stale code-map, and enables API conformance when an API contract and real source code are present (see below) — but deliberately does not run invasive repo upgrades for you.
--simple is the non-engineer view: instead of the full technical list it collapses every passing check into one line and leads with a one-word verdict plus a single "what to do next" (e.g. run cdd-kit doctor --fix, or you're ready — run /cdd-new). It honours --strict and the same exit codes, so it is safe in scripts too.
For Claude projects, doctor also reports whether the cdd-kit MCP server is registered with Claude Code (it runs claude mcp list). If it is not registered, agents never see the graph/index tools and silently fall back to Read. Severity is tiered on certainty: when claude is present and positively reports the server missing, that is a warning (it fails --strict) — agents are demonstrably degraded to the slow path, and doctor surfaces the exact claude mcp add --scope user cdd-kit -- cdd-kit mcp command to fix it. When the check cannot verify (no claude CLI on PATH, or mcp list errors — 3s timeout, best-effort) it stays informational so environments that don't use Claude Code are never penalised. The check is skipped entirely for non-Claude projects. Point CDD_CLAUDE_BIN at an alternate Claude CLI if needed.
doctor finally prints a chokepoint dashboard: for each enforcement mechanism — the graph-first hook, the contract-write hook, the pre-commit gate, and the OpenAPI sync gate — it reports live (armed) or dormant, with the one command to arm it. The kit's mechanisms are opt-in and dormant until installed, so a repo can carry all the machinery yet enforce none of it; this makes that state observable. A dormant chokepoint is reported as a warning, so it fails --strict — under strict mode you are asserting that enforcement is actually armed, and a repo that carries the machinery but enforces none of it should not pass. Plain doctor (non-strict) still exits 0 and simply lists what is dormant.
cdd-kit upgrade
Adds missing repo-level cdd-kit files after upgrading the npm package. It preserves existing contracts and guidance files; default mode is a dry run.
cdd-kit upgrade
cdd-kit upgrade --yes
cdd-kit upgrade --yes --migrate-changes
cdd-kit upgrade --yes --migrate-changes --enable-context-governance
cdd-kit upgrade --provider codex --yes
cdd-kit upgrade --provider both --yesUse this for old repos that already have contracts/ or specs/ but are missing new assets such as .cdd/context-policy.json, .cdd/model-policy.json, CODEX.md, or newer templates. Add --migrate-changes if you also want to upgrade existing specs/changes/<change-id>/ directories in the same run.
cdd-kit refresh
Complete sync after upgrading the npm package. Default mode is a dry run.
cdd-kit refresh
cdd-kit refresh --yes
cdd-kit refresh --yes --provider both
cdd-kit refresh --yes --no-templatesrefresh --yes runs the practical upgrade sequence:
cdd-kit update --yesfor global Claude agents and skills.cdd-kit upgrade --yesfor missing project files.- Force-refreshes kit-shipped
specs/templates/,tests/templates/,ci-templates/, and.github/workflows/with backup under.cdd/.refresh-backup/. - Re-installs the code-map hook if the project marker exists.
- Resyncs
.cdd/model-policy.jsonroles from installed agent frontmatter. - Regenerates
.cdd/code-map.yml.
After refresh --yes, register the MCP server:
claude mcp add --scope user cdd-kit -- cdd-kit mcpThe MCP tools are the recommended graph/code-map exploration interface for AI
agents. Claude Code CLI stores user-scope MCP servers in ~/.claude.json; a
manual mcpServers entry in ~/.claude/settings.json is not sufficient.
cdd-kit graph ... and cdd-kit index ... remain the fallback when MCP is not
available.
Run cdd-kit migrate --all separately when you need existing
specs/changes/* directories to gain new required artifacts.
cdd-kit gate <change-id>
The single quality gate for a change. Blocks merge if anything is missing or incomplete.
cdd-kit gate add-jwt-auth
cdd-kit gate add-jwt-auth --strict
cdd-kit gate add-jwt-auth --explain # plain-language reasons + a sentence to say to ClaudeChecks:
- All required artifacts exist (
change-request.md,change-classification.md,implementation-plan.md,test-plan.md,ci-gates.md,tasks.yml; new context-governed changes also requirecontext-manifest.md) - Each artifact has sufficient content and is not a stub.
change-classification.mdcontains a tier or risk marker.- Mechanical risk-tier floor.
change-request.mdis scanned for sensitive surfaces (auth, payments, migrations, concurrency, secrets, …) — and the change's git paths are scanned against the critical (tier-0) rules only, so a generic request whose work lives underauth/orpayments/is still caught. The gate scans the staged change (so an unrelated unstaged edit can't trip it; rename-aware on both sides; the path signal is dropped when a commit stages multiple change dirs), whileclassify-checkscans the whole worktree. The gate fails when the declared tier is weaker than the matched floor — the deterministic safety net under the AI classifier. Bypass one change withtier-floor-override: "<reason>"intasks.ymlfrontmatter: the reason must be at least 20 characters (a one-word "fix" does not bypass), it downgrades the violation to a warning, and every bypass is appended — with a timestamp, the matched floor, and the reason — toagent-log/audit.ymlso the weakening is never invisible. Tune or disable in.cdd/tier-policy.json. - Atomic
depends-onupstream changes are completed or archived before dependent work gates. - All contract validators pass.
- Test evidence. For implementation changes,
test-evidence.ymlmust exist with its required phases passed (collect, targeted, changed-area, plus any declared contract/quality/full), no waiver fields, and each run pointing at this change'stest-runs/. Generated bycdd-kit test run; opt out when a change has no testable surface viatest-evidence-not-applicable: "<reason>"intasks.ymlfrontmatter. After a migration window this is enforced — a warning for legacy changes, an error for context-governed changes or under--strict.
Advisory — required-agent evidence (ADR 0008). The gate also warns (never
errors, even under --strict) when an agent the classifier listed in
change-classification.md ## Required Agents left no non-stub
agent-log/<agent>.yml — a signal, for a no-human-review workflow, that a
required review (especially a judgment-only one like UI/UX or visual) left no
trace it ran. It is deliberately not a hard gate: an agent-log is post-hoc,
self-reported audit, and the harms that are mechanically checkable are already
caught by the validators / conformance / test-evidence layer regardless of
whether a reviewer agent ran. agent-log/*.yml stays optional. (The bug-fix
lane's bug-fix-engineer.yml requirement remains a hard error.)
--strict additionally:
- Treats any task with
status: pending(except IDs listed inarchive-tasks) as an error - Treats legacy changes missing
context-manifest.mdas errors
--explain (non-engineer mode) annotates each failure with a plain-language Why and a ready-to-paste Say this to Claude sentence, so a non-engineer never has to decode jargon like "tier floor" or "frontmatter" to know the next step. Without --explain, a failing run ends with a one-line pointer: Need help? Run: cdd-kit gate <id> --explain.
Pre-commit hook uses --strict by default (installed via cdd-kit install-hooks).
✓ gate passed for change: add-jwt-auth
✗ gate failed for change: feat-001
✗ change-classification.md: appears to be a stub (< 200 meaningful chars)
✗ 1 task(s) still pending (mark archive items in archive-tasks frontmatter; mark N/A items as status: skipped)
Need help? Run: cdd-kit gate feat-001 --explain for a plain-language explanation of each failure.With --explain:
✗ gate failed for change: feat-001
✗ tier floor violation: Authentication surface detected (matched: auth) requires tier 0 or stricter, but classification declared tier 3. …
Why: This change touches a sensitive area (for example login, payments, or security), so the system requires a stricter review level than the one it was filed under. "Tier" is just the risk level — a lower tier number means stricter checks.
Say this to Claude: "This change was flagged as higher risk than its current tier. Please re-classify it to the required stricter tier and bring the tests and evidence up to that level."cdd-kit metadata <change-id>
Generates two compact, machine-readable indexes for a tracked change, derived from its existing artifacts — so agents and MCP tools can read structured state instead of re-parsing long markdown:
change.yml— status, tier, lane, change types, required agents, required vs present optional artifacts, the context manifest's allowed-paths count, and dependencies.trace.yml— acceptance criteria → tests → required gates, plus the agent-log evidence pointers.
cdd-kit metadata add-jwt-auth # write change.yml + trace.yml
cdd-kit metadata add-jwt-auth --check # exit 1 if regenerating would change them (no write)
cdd-kit metadata --all # regenerate for every active (in-progress) change
cdd-kit metadata add-jwt-auth --json # machine-readable resultThese files are generated, never hand-authored, and are a derived index
only: the gate still treats the source artifacts as the source of truth, so a
missing or stale change.yml/trace.yml never affects the gate's pass/fail.
Each carries a generated-from map of per-source sha256 digests; when a source
drifts, cdd-kit gate prints a warn-only refresh nudge (only if the index was
already generated), and cdd-kit doctor reports it as a warning that
cdd-kit doctor --fix regenerates.
cdd-kit contract
Query and mutate the API contract by key instead of reading or hand-editing
the whole file (ADR 0004 — see docs/adr/0004-queryable-and-writable-contracts.md).
Subcommands:
cdd-kit contract query [term] # read: matching endpoint/schema slice
cdd-kit contract locate <symbol> # read: contract slices related to a code symbol
cdd-kit contract endpoint set ... # write: upsert one endpoint row
cdd-kit contract schema set <name> --field ... # write: upsert one schema sectioncdd-kit contract query [term]
Returns only the matching slice of the API contract — an endpoint, a schema, or a path/column filter — so an agent reads the relevant row instead of the whole contract file. With no term it lists the contract's keys.
cdd-kit contract locate <symbol>
Given a code symbol or file, returns the API-contract slices (schemas +
endpoints) related to it — the contract analog of cdd-kit test impact. It saves
the usual graph-query → read-file → guess-schema-name → contract-query round-trip
an agent would otherwise do by hand.
cdd-kit contract locate src/orders/service.ts # schemas/endpoints related to this file
cdd-kit contract locate CreateOrder --json # or a single symbol/schema nameThe bridge from code to contract is name overlap (a CreateOrder interface ↔
a CreateOrder schema) — the same honest, bounded heuristic the kit uses
elsewhere, never inference. The symbol is resolved in the code-map (best effort)
to harvest the file's declared type/class/function names as extra search terms,
and each located slice records matched_via (which term surfaced it). It still
works with no code-map, since the literal symbol is always one of the terms.
Exposed over MCP as cdd_contract_locate. Options: --contract, --inventory,
--map, --limit (default 20), --no-refresh, --json.
cdd-kit contract endpoint set / cdd-kit contract schema set <name>
Keyed, valid-by-construction writes: endpoint set upserts a single endpoint
row by (method, path) and schema set upserts a single ### Name schema
section from --field specs — each touches only that row/section instead of a
free-form edit of the contract file. This is the mutation the contract-write
PreToolUse hook routes an agent's contract edits through.
cdd-kit index
Query the machine-readable project index (.cdd/code-map.yml) before opening
source files — the token-cheap "find the thing" layer. (cdd-kit graph is the
richer relationship layer; see below.)
cdd-kit index query <term> # files, symbols, imports, line ranges for a term
cdd-kit index query "order export" # multi-word: tokenized, ranked by coverage
cdd-kit index query <term> --with-source # include the source slice for each hit
cdd-kit index impact <path-or-symbol> # indexed local imports and dependents of a fileMulti-word queries are tokenized. A query is split into tokens
(whitespace/comma separated, stopwords and 1-char tokens dropped) and scored by
how many tokens a symbol matches, so a natural-language task ("filter options
are empty") or a two-word query ("order export" → exportOrders) resolves in
one call instead of forcing the agent to retry one exact identifier at a time. A
single-word or exact query behaves exactly as before (byte-identical ranking), so
the gate's deterministic --check is unaffected.
Truncation is always visible: index query reports total_matches /
returned / truncated (and per-file match_count / matches_truncated) so a
result capped by --limit is never mistaken for the whole picture (P1-7). Exposed
over MCP as cdd_index_query.
cdd-kit test
Bounded test execution and structured evidence (ADR 0005). Runs narrow test
phases instead of broad suites, caps assistant-visible output, writes durable
artifacts, and records results in test-evidence.yml for the gate to validate.
cdd-kit test select <change-id> # choose bounded commands per ladder phase from test-plan.md
cdd-kit test select <change-id> --json # machine-readable selection (or needs-test-plan-update)
cdd-kit test impact src/auth/token.ts # which tests are affected by changing this file?
cdd-kit test impact src/auth/token.ts --depth 3 --json
# Run each phase with the command select returned (--command is required today);
# declare any conditional phases on the first run so the gate requires them:
cdd-kit test run <change-id> --phase collect --command "<collect cmd>" --required-phases collect,targeted,changed-area
cdd-kit test run <change-id> --phase targeted --command "<targeted cmd>"
cdd-kit test run <change-id> --phase changed-area --command "<changed-area cmd>"
cdd-kit test run <change-id> --phase full --command "<full cmd>" # final/CI smoke — run when the change needs a full gate, not every timetest run options: --phase <phase> (required), --command <cmd> (the command
from cdd-kit test select, currently required on every run; pytest commands get
bounded defaults -q --maxfail=1 --tb=short -ra plus JUnit XML), --run-id
<id>, --timeout <ms> (default 300000), --cwd <dir>, --required-phases
<csv> (recorded only when first creating evidence; the floor
collect,targeted,changed-area is always merged, so list any conditional phase
that must block the gate), and --json.
Each run writes specs/changes/<change-id>/test-runs/<run-id>/ (command.txt,
summary.json, stdout.log, stderr.log, and junit.xml when supported) and
updates test-evidence.yml. The ladder phases and the no-waiver policy live in
references/sdd-tdd-policy.md and each change's test-plan.md.
cdd-kit test impact <file> answers "if I change this file, which tests are
affected?" by walking the code-map's import graph: it reports test files that
transitively import the target (up to --depth, default 2) plus mirror-path test
files (src/foo.ts ↔ tests/foo.test.ts, foo_test.py). Every result carries a
reason (is-target / imports-target / transitive / mirror), so it never
guesses — it's a composition of facts the code-map already records, exposed over
MCP as cdd_test_impact to replace a manual grep. Options: --depth <n>,
--limit <n> (default 50), --map <path>, --no-refresh, --json.
cdd-kit classify-check
Advisory probe that prints the mechanical risk-tier floor for a change
before classification, so the classifier can be steered up front instead of
only being caught later by cdd-kit gate. The blocking enforcement lives in the
gate; this command never fails (exit 0).
cdd-kit classify-check add-jwt-auth # scan the change's change-request.md
cdd-kit classify-check --text "add stripe checkout" # scan inline intent
cdd-kit classify-check add-jwt-auth --json # machine-readableIt reads the same ground-truth source the gate enforces against
(change-request.md), reports the strictest matched tier and the matched
patterns, and points at .cdd/tier-policy.json for tuning.
cdd-kit manifest
Auto-generates a minimal context-manifest.md for a low-risk tier 4-5
micro-change, so a trivial edit does not need a hand-written manifest. The
generated Allowed Paths is the change's own directory plus the files the
change currently touches (from git status), on top of the three standard
defaults (specs/changes/<id>/, project-map.md, contracts-index.md).
cdd-kit manifest tweak-copy # generate (errors if a manifest already exists)
cdd-kit manifest tweak-copy --force # regenerate from the current touched files
cdd-kit manifest tweak-copy --json # machine-readable resultIt is deliberately scoped to tiers 4-5: a stricter (tier 0-3) change is refused,
because a critical/behavioral change should get a deliberately authored manifest
with per-agent work packets, not a rubber-stamped "whatever it touched is
allowed" boundary. An existing manifest is never overwritten without --force,
and the change must already have a tier set (tier: <0-5> in tasks.yml).
cdd-kit list
Lists all active changes in specs/changes/ with status and pending task count.
cdd-kit listActive changes:
add-jwt-auth [in-progress] (3 pending)
fix-export-timeout [gate-blocked]
old-experiment [abandoned]--json prints { "changes": [{ "id", "status", "pendingTasks" }] } for wrapper scripts.
cdd-kit archive <change-id>
Physically moves a completed change from specs/changes/ to specs/archive/<year>/.
cdd-kit archive add-jwt-auth
# ✓ Archived: specs/changes/add-jwt-auth → specs/archive/2026/add-jwt-auth
# ✓ Index updated: specs/archive/INDEX.mdWarns (but does not block) if tasks.yml has pending items or status: gate-blocked. Use after /cdd-close — the skill runs this automatically at the end.
--json prints { "changeId", "archivedTo", "year", "date", "warnings": [] } on success, { "changeId", "error" } with exit code 1 on failure.
cdd-kit abandon <change-id>
Marks a change as abandoned. Updates tasks.yml status to abandoned, records the reason in specs/archive/INDEX.md. The directory stays on disk for git history.
cdd-kit abandon add-jwt-auth --reason "using Auth0 instead"
# ✓ Change add-jwt-auth marked as abandoned.--json prints { "changeId", "status": "abandoned", "reason", "date" } on success, { "changeId", "error" } with exit code 1 on failure.
Machine-readable output (--json) and exit codes
Every lifecycle and query command supports --json for wrapper scripts and CI:
doctor, list, gate-adjacent checks (classify-check, validate on errors),
archive, abandon, index query/impact, graph query/impact/status/sync/context,
contract query/locate, test run/select/impact, metadata, bug suspects, detect-stack, and
context request/approve/reject/list/check.
Conventions, uniform across commands:
- stdout carries exactly one JSON object (pretty-printed); human chatter is
suppressed in JSON mode. Failures that have a payload print
{ ..., "error" }. - Exit code 0 — the command did what was asked (including legitimately empty results, e.g. zero changes / zero suspects).
- Exit code 1 — the command could not do what was asked: validation failed, the gate failed, a referenced change/file does not exist, or inputs were invalid. No other exit codes are used.
cdd-kit migrate <change-id> | --all
Upgrades pre-v2.0.0 change directories to the current format.
cdd-kit migrate add-jwt-auth # migrate one change
cdd-kit migrate --all # migrate all changes in specs/changes/
cdd-kit migrate --all --dry-run # preview without writing
cdd-kit migrate --all --enable-context-governanceWhat it upgrades:
tasks.yml: converts legacytasks.mdchecklist/frontmatter into structured YAML task recordschange-classification.md: detects old**Tier:** Tier Nformat and appends the new## Tier\n- Nsection so tier-based gate checks activateimplementation-plan.md: adds the execution-plan scaffold required before backend/frontend/test implementation agents continuecontext-manifest.md: adds a legacy manifest scaffold by default so old changes can use the same pre-read planning layer--enable-context-governance: explicitly addscontext-governance: v1and a context-governed manifest scaffold for pre-read planning
If you choose to emit agent-log/*.yml, keep files-read optional and concise:
files-read:
- contracts/api/api-contract.md
- src/server/routes/users.tsPaths should be repo-relative. Do not reconstruct this list after the fact;
use cdd-kit context check before invoking agents when read scope matters.
Run this after upgrading from v1.10 or earlier if you have mid-flight changes.
cdd-kit migrate --all
git add specs/changes/
git commit -m "chore: migrate changes to current cdd-kit format"cdd-kit context
Manage Context Expansion Requests (CERs) against a change's
context-manifest.md — how an agent asks for, and a human/policy grants, read
access beyond its work packet. Subcommands:
| subcommand | purpose |
|---|---|
| context request <id> <cer-id> | record a pending CER (or auto-approve a safe one) |
| context check <id> | preflight read paths against the manifest |
| context approve <id> <cer-id> | approve a pending CER (--all-pending for bulk) |
| context auto-approve <id> | resolve pending CERs against the auto-safe policy |
| context approve-interactive <id> | adjudicate each pending CER with a y/n/q prompt |
| context reject <id> <cer-id> | reject a pending CER (--all-pending for bulk) |
| context list <id> | list all CERs for a change (--json) |
cdd-kit context request <change-id> <request-id>
Records a pending Context Expansion Request in context-manifest.md.
cdd-kit context request add-jwt-auth CER-001 --path src/server/users.ts tests/users.test.ts --reason "paired implementation and regression coverage"Use this when an agent needs more context than its current work packet allows.
Auto-safe approval. When .cdd/context-policy.json sets
contextExpansion.mode: "auto-safe", paths that fall inside its
autoApprovePatterns (e.g. src/**, tests/**, contracts/**,
specs/changes/<current-change-id>/**) and are not forbidden are approved
immediately instead of being parked as pending — so a request that is entirely
inside the safe zones never stalls the session. Only the leftover (out-of-zone)
paths are recorded as a pending CER for human review. The forbidden baseline
always wins, and a repo with no policy file (or mode other than auto-safe)
keeps the manual pending-CER behavior.
cdd-kit context check <change-id>
Preflight-checks repo-relative read paths against context-manifest.md before
you invoke an agent.
cdd-kit context check add-todos-ui --path src/components/Sidebar.vue src/stores/todos.js src/views/DashboardView.vue
cdd-kit context check add-ci-gate --path contracts/ci/ci-gate-contract.md .github/workflows/contract-driven-gates.ymlThe check uses ## Allowed Paths, ## Approved Expansions, repo-relative path
rules, and the forbidden baseline in .cdd/context-policy.json. If the command
fails and the read is legitimate, update the manifest or record/approve a
Context Expansion Request before the agent reads the file.
cdd-kit context approve <change-id> <request-id>
Approves a pending Context Expansion Request in context-manifest.md and adds its requested_paths to ## Approved Expansions.
cdd-kit context approve add-jwt-auth CER-001
cdd-kit context approve add-jwt-auth --all-pending # bulk approve every pending requestThis keeps expansion history explicit while avoiding manual manifest editing.
cdd-kit context auto-approve <change-id>
Resolves already-pending CERs against the auto-safe policy: paths inside the
safe zones move to ## Approved Expansions, a request whose every path is safe
is marked approved, and a mixed request stays pending trimmed to just the
paths that still need a human. This is the unblock /cdd-resume runs before it
would otherwise stop on a pending CER. No-op unless the policy mode is
auto-safe.
cdd-kit context auto-approve add-jwt-authcdd-kit context approve-interactive <change-id>
Walks each pending CER one at a time with a plain-language tag per path (inside
an auto-safe zone / outside the usual safe zones / blocked by policy) and a
[y]es / [n]o-skip / [q]uit prompt — so a non-engineer can adjudicate without
hand-editing the manifest. Reads answers from stdin and stops cleanly on EOF
(it never hangs a non-interactive session).
cdd-kit context approve-interactive add-jwt-authcdd-kit context reject <change-id> <request-id>
Rejects a pending Context Expansion Request and records status: rejected in the manifest.
cdd-kit context reject add-jwt-auth CER-001
cdd-kit context reject add-jwt-auth --all-pending # bulk reject every pending requestcdd-kit context list <change-id>
Lists all Context Expansion Requests for a change.
cdd-kit context list add-jwt-auth
cdd-kit context list add-jwt-auth --jsoncdd-kit validate
Runs contract validation scripts.
cdd-kit validate # all validators
cdd-kit validate --contracts # API, CSS, data-shape (+ semantic + conformance checks)
cdd-kit validate --env # env contract
cdd-kit validate --ci # CI gate policy
cdd-kit validate --spec # spec traceability
cdd-kit validate --versions # contract frontmatter schema versions--contracts includes API conformance: a code-vs-contract check that parses
real backend routes and frontend call sites and fails on drift from
contracts/api/api-contract.md (e.g. the frontend calling an endpoint the
contract never declares). It is off until you enable it in .cdd/conformance.json
("enabled": true); cdd-kit init scaffolds a disabled config. You don't have to
edit JSON by hand: when an API contract and real source code are both present,
cdd-kit doctor flags that drift detection is off and cdd-kit doctor --fix turns
it on for you (and cdd-kit setup prints the same recommendation). See
docs/api-conformance.md. This is the mechanical net
for frontend/backend API drift in a workflow where no human reviews the contract
by hand.
cdd-kit openapi export
Projects contracts/api/api-contract.md into a minimal OpenAPI 3.1 skeleton for tooling (e.g. feeding openapi-typescript to generate a typed frontend client). The markdown contract stays the source of truth; the OpenAPI document is a one-way, regenerable projection.
cdd-kit openapi export # JSON to stdout
cdd-kit openapi export --yaml --out openapi.yaml # YAML to a file
cdd-kit openapi export --check --out openapi.json # sync gate: fail on driftIt derives paths (normalizing :id/{id}), path parameters, auth → bearer security, and success/error status codes. Free-form request/response schemas in the contract are marked x-cdd-unresolved rather than fabricated. Generating an actual client is left to your stack's generator in your own CI — this is the preventive complement to the detective conformance check above. See docs/openapi-export.md and docs/adr/0001-contract-to-openapi-export.md.
--check is the sync gate: it does not write, it verifies the committed artifact at --out still matches the contract and exits non-zero on drift, so CI fails when a contract edit forgets to regenerate the export (and the typed client downstream). To wire the consumer half, cdd-kit init scaffolds editable contract:client and contract:client:check npm scripts when a package.json is present — the generic contract→OpenAPI step is the kit's, the stack-specific codegen stays an editable script in your repo.
cdd-kit new <name>
Scaffolds an empty change directory. Normally you use /cdd-new (the Claude Code skill) instead, which runs this and then orchestrates all agents. Use cdd-kit new only if you want an empty scaffold without agent orchestration.
cdd-kit new add-user-auth
cdd-kit new add-user-auth --all # include optional templates too
cdd-kit new add-user-auth --force # overwrite existing directory
cdd-kit new add-user-api --depends-on add-user-db
cdd-kit new add-user-auth --skip-scanPrefer the default scaffold. --all is mainly for template inspection or
manual workflows; /cdd-new should create optional markdown only when
classification requires it or review evidence needs durable prose.
By default, cdd-kit new auto-runs cdd-kit context-scan when specs/context/ indexes are missing or stale. Use --skip-scan only if you intentionally want a bare scaffold without refreshing classifier indexes first.
For larger requests, split the
