contract-driven-delivery 2.1.2 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,193 @@
1
1
  # Changelog
2
2
 
3
+ ## [Unreleased]
4
+
5
+ _No unreleased changes yet._
6
+
7
+ ## [2.2.0] - 2026-06-02
8
+
9
+ Make enforcement live by default, add a mechanical risk-tier safety net under the
10
+ AI classifier, and give code indexing an opt-in background mode — the three gaps
11
+ that matter most for a fully automated, no-human-reviewer workflow.
12
+
13
+ ### Added
14
+
15
+ - **Arm enforcement chokepoints by default in `cdd-kit init`.** A fresh `init`
16
+ now wires the graph-first PreToolUse hook (Claude provider, advisory) and the
17
+ pre-commit gate hook, instead of shipping them dormant. In an automated
18
+ workflow with no human reviewer, dormant enforcement means the contracts and
19
+ docs only *look* like they prevent drift. Best-effort: a missing `.git` or
20
+ unusual `settings.json` downgrades to a warning, never a failed init. Opt out
21
+ with `cdd-kit init --no-arm`. `installHooks`/`installAgentHooks` gained a
22
+ `fromInit` mode so arming is non-fatal.
23
+ - **Mechanical risk-tier floor (`src/utils/tier-floor.ts`).** A deterministic
24
+ backstop under the (AI) classifier: `cdd-kit gate` scans `change-request.md`
25
+ for sensitive surfaces (auth, payments, migrations, concurrency, secrets, …)
26
+ and **fails** when the declared tier is weaker than the matched floor, so a
27
+ single mis-classification can no longer silently drop the required agents and
28
+ tests. Bypass per-change with `tier-floor-override: "<reason>"` in `tasks.yml`
29
+ frontmatter (downgrades to an audit warning). Policy lives in
30
+ `.cdd/tier-policy.json` (scaffolded, fully editable, `enabled:false` to
31
+ disable); built-in defaults apply when the file is absent so existing repos are
32
+ protected without a re-init.
33
+ - **`cdd-kit classify-check [change-id] | --text "<intent>"`** — advisory probe
34
+ that prints the mechanical tier floor *before* classification, so the
35
+ classifier can be steered up front rather than only caught by the gate.
36
+ Supports `--json`.
37
+ - **`cdd-kit code-map --watch`** — opt-in background auto-indexing. A debounced
38
+ (default 500 ms, `--debounce`) recursive watcher keeps the map fresh during
39
+ long-lived co-editing sessions, with a freshness-polling fallback where
40
+ recursive `fs.watch` is unavailable. Trigger-based indexing stays the default
41
+ for ephemeral CI/agent runs.
42
+ - **ADR 0003** (`docs/adr/0003-code-intelligence-indexing-strategy.md`):
43
+ evaluates LSP (Serena) vs tree-sitter incremental (CocoIndex) vs the kit's
44
+ native AST scanners, and the trigger-vs-background refresh question. Decision:
45
+ keep native AST (LSP does not translate to headless agents), keep trigger-based
46
+ as default, add the opt-in `--watch` above, and sequence per-file incremental
47
+ rebuild as the next step.
48
+
49
+ ### Added (mechanical chokepoints — prior unreleased work)
50
+
51
+ - **API conformance validator** (`validate_api_conformance.py`): parses real
52
+ backend route declarations and frontend HTTP call sites and diffs them against
53
+ `contracts/api/api-contract.md`. Catches frontend/backend API drift that the
54
+ markdown-only validators never could. Chained into `cdd-kit validate
55
+ --contracts`, so `cdd-kit gate` blocks on drift. Off until enabled in
56
+ `.cdd/conformance.json` (`"enabled": true`); a disabled config is scaffolded by
57
+ `cdd-kit init`. See `docs/api-conformance.md`.
58
+ - **`--with-source` / `withSource`** on `cdd-kit index query`, `cdd-kit graph
59
+ query`, and the `cdd_index_query` / `cdd_graph_query` MCP tools: returns the
60
+ matched symbol's code inline so the query replaces a follow-up `Read` instead
61
+ of preceding it. `--source-budget` caps total lines and flags truncated ranges.
62
+ - **`hooks/pre-tool-use-graph-first.sh`** (opt-in PreToolUse hook): steers agents
63
+ to `cdd-kit index query --with-source` before reading source files. Advisory by
64
+ default; `CDD_GRAPH_FIRST_STRICT=1` hard-blocks source reads when a code-map
65
+ exists.
66
+ - `cdd-kit doctor` reports whether API conformance is enabled, disabled, or
67
+ unconfigured (informational; never fails `--strict`).
68
+ - `cdd-kit doctor` reports whether the **cdd-kit MCP server is registered** with
69
+ Claude Code (runs `claude mcp list`). If it is not registered, agents never see
70
+ the graph/index tools and silently fall back to `Read`, so doctor surfaces the
71
+ `claude mcp add --scope user cdd-kit -- cdd-kit mcp` command to fix it.
72
+ Informational only (never fails `--strict`), best-effort with a 3s timeout
73
+ (never blocks on a slow/missing `claude` CLI), skipped for non-Claude and
74
+ non-cdd-kit projects. `CDD_CLAUDE_BIN` overrides the CLI path. Closes the gap
75
+ left by `--with-source`: the incentive to use the kit tools only helps if the
76
+ agent can see them.
77
+ - **`cdd-kit install-agent-hooks --graph-first advisory|strict`**: installs the
78
+ graph-first `PreToolUse` hook into `.claude/settings.json` (project-scoped) and
79
+ copies the script to `.claude/hooks/`, so steering agents to
80
+ `cdd-kit index query --with-source` before `Read` becomes an installed harness
81
+ chokepoint instead of manual settings wiring. Advisory by default; `strict`
82
+ writes `CDD_GRAPH_FIRST_STRICT=1`. Idempotent and preserves unrelated settings.
83
+ - **`cdd-kit openapi export`**: projects `contracts/api/api-contract.md` into a
84
+ minimal OpenAPI 3.1 skeleton (`--yaml`, `--out`) for tooling such as
85
+ `openapi-typescript`. One-way projection — the markdown contract stays the
86
+ source of truth. Derives paths/params/auth/status codes; marks free-form
87
+ request/response bodies as `x-cdd-unresolved` rather than fabricating schemas.
88
+ Per-stack client generation is intentionally left to the consumer repo; see
89
+ `docs/adr/0001-contract-to-openapi-export.md` and `docs/openapi-export.md`.
90
+ - **`cdd-kit openapi export --check`**: the OpenAPI sync gate. Instead of
91
+ writing, it verifies the committed artifact at `--out` still equals what the
92
+ contract produces and exits non-zero on drift — so CI fails when the contract
93
+ changes but the export was not regenerated. This is the kit-owned half of the
94
+ preventive chain (the consumer's typed-client codegen runs from an artifact
95
+ that can never be silently stale).
96
+ - **`cdd-kit init` now wires the consumer codegen seam**: when a `package.json`
97
+ is present it adds editable `contract:client` and `contract:client:check` npm
98
+ scripts (the latter is the `openapi export --check` gate), turning the
99
+ consumer half of the OpenAPI seam from a doc into a chokepoint. Additive,
100
+ idempotent, never clobbers existing scripts; `openapi-typescript` is an
101
+ editable default, not a hard dependency.
102
+ - **`cdd-kit doctor` chokepoint dashboard**: reports each enforcement chokepoint
103
+ (graph-first hook, pre-commit gate, OpenAPI sync gate) as `live` or `dormant`
104
+ with the one command to arm it. The kit's mechanisms are opt-in and dormant
105
+ until armed, so a repo could carry all the machinery yet enforce none of it —
106
+ this makes that observable. Advisory only (never fails `--strict`).
107
+
108
+ ### Changed
109
+
110
+ - `backend-engineer` and `frontend-engineer` prompts now prefer
111
+ `--with-source` queries and warn that endpoint changes/calls require a contract
112
+ update when conformance is enabled.
113
+
114
+ ### Fixed
115
+
116
+ - **graph-first hook now installs in the shape Claude Code executes.**
117
+ `install-agent-hooks` wrote the command directly on the `PreToolUse` matcher
118
+ group; Claude Code requires it nested under an inner `hooks: [{ type:
119
+ "command", … }]` array, so the chokepoint was silently dormant even though
120
+ install/init reported it armed. Re-running upgrades a legacy entry in place and
121
+ preserves unrelated handlers that share the matcher group.
122
+ - **tier floor scans the right path scope.** `cdd-kit gate` now scans the
123
+ **staged** change (rename-aware, both sides) instead of the whole worktree, so
124
+ an unrelated unstaged `auth/` edit can no longer trip the floor and reject a
125
+ low-risk commit; when a single commit stages more than one change directory the
126
+ path signal is dropped (source paths can't be attributed to one change) and
127
+ only the request text sets the floor. `cdd-kit classify-check` keeps
128
+ whole-worktree scope (its in-progress change is not yet committed).
129
+ - **tier-floor pattern accuracy.** Critical-surface patterns now match plural
130
+ directories (`payments/`, `migrations/`); the `token` pattern is qualified to
131
+ security contexts (`access`/`api`/`auth`/`session`/`bearer`/`refresh`/`csrf`/
132
+ `id`/`reset`) so frontend "design tokens" / `theme/tokens.ts` no longer trip
133
+ the secrets floor. The gate / `classify-check` `matched:` line now reports the
134
+ actual matched text (e.g. `session token`) instead of the raw regex pattern.
135
+ - **`cdd-kit doctor` detects a gate armed under a custom `core.hooksPath`** (or a
136
+ worktree/submodule), resolving the hooks dir via git instead of probing only
137
+ `.git/hooks/pre-commit` — no more reporting a live gate as dormant.
138
+ - **`cdd-kit code-map --watch` skips churn under ignored trees** (`node_modules`,
139
+ `dist`, `.git`, `.next`, coverage) before rebuilding, and adds an `error`
140
+ listener so fs-watch runtime errors (ENOSPC, permissions) degrade to polling
141
+ instead of crashing the watch. Edits to `.cdd/code-map-config.yml` still
142
+ trigger a rebuild even though it lives under the ignored `.cdd/` tree.
143
+ - **`cdd-kit gate` no longer passes changes whose artifacts are still unfilled
144
+ scaffolds.** The stub check counted "meaningful chars", but a template's own
145
+ instructional prose (900+ chars) cleared the threshold while every field was
146
+ still an `<id>` / `<date>` / `<change-id>` placeholder — so a change could pass
147
+ `--strict` with raw templates and zero real content. Gate now fails and names
148
+ the remaining placeholder tokens per artifact. The check is a closed allowlist
149
+ (`<id>` / `<date>` / `<change-id>`) anchored to the colon-led, line-final value
150
+ position the templates use (`change-id: <id>`, `# …: <change-id>`), so inline
151
+ XML/markup examples (`<id>123</id>`) and hyphenated custom elements
152
+ (`<my-element>`) are not false-flagged — and a file may carry both a real
153
+ placeholder and an XML example without the placeholder slipping through.
154
+ `context-manifest.md` is exempt (its `<...>` sub-sections are documented as
155
+ illustrative; it is enforced via Allowed Paths, not template fill-ins).
156
+ - **`cdd-kit validate` / `gate` no longer crash with `UnicodeDecodeError` on
157
+ non-UTF-8 Windows locales (e.g. cp950/zh-TW).** `validate_contract_versions.py`
158
+ read `git show` output and the validators wrote stdout using the locale codec,
159
+ spamming tracebacks and mojibaking em-dashes in contracts. The Python
160
+ validators are now spawned with `PYTHONUTF8=1` / `PYTHONIOENCODING=utf-8`, and
161
+ the git subprocesses decode as UTF-8 explicitly.
162
+ - **`cdd-kit openapi export` fails fast on a mis-tagged schema fence** instead of
163
+ silently dropping it: a `### Name` section under `## Schemas` that uses ` ```json `
164
+ (or any non-`json-schema` fence) now errors with the fix — including when a field
165
+ table is also present (the stray fence was previously ignored). A prose-only
166
+ section with no fence stays a valid Tier C contract and is left unresolved.
167
+ - **`cdd-kit openapi export --out <absolute-path>`** no longer ENOENTs on an
168
+ absolute path (it was concatenated onto cwd, e.g. `D:\repo\C:\Users\…`); paths
169
+ are resolved with `path.resolve`.
170
+
171
+ ### Added
172
+
173
+ - **`cdd-kit openapi export` typed schemas (ADR 0002)**: `## Schemas` sections
174
+ compile field tables (Tier A) and `json-schema` fenced blocks (Tier B) into
175
+ `components.schemas` with `$ref` resolution; the contract stub documents both
176
+ tiers.
177
+
178
+ ## [2.1.3] - 2026-05-29
179
+
180
+ Correct Claude Code MCP registration guidance.
181
+
182
+ ### Changed
183
+
184
+ - Install and upgrade guidance now recommends
185
+ `claude mcp add --scope user cdd-kit -- cdd-kit mcp`, which writes the server
186
+ to `~/.claude.json`.
187
+ - Documentation now warns that adding `mcpServers` to
188
+ `~/.claude/settings.json` alone is not sufficient for Claude Code CLI MCP
189
+ discovery.
190
+
3
191
  ## [2.1.2] - 2026-05-29
4
192
 
5
193
  Recommended MCP setup during install and upgrade.
package/README.md CHANGED
@@ -269,17 +269,34 @@ cdd-kit init --local-only # only scaffold project files
269
269
  cdd-kit init --provider codex # scaffold Codex-oriented project guidance
270
270
  cdd-kit init --provider both # scaffold Claude Code + Codex guidance
271
271
  cdd-kit init --force # overwrite existing project files
272
+ cdd-kit init --no-arm # scaffold without arming enforcement chokepoints
272
273
  ```
273
274
 
275
+ By default `init` **arms** the enforcement chokepoints so a fresh repo enforces
276
+ the workflow instead of carrying it dormant: the graph-first PreToolUse hook
277
+ (Claude provider, advisory) and the pre-commit gate hook are wired in place. This
278
+ matters most in a fully automated, no-human-reviewer workflow — dormant
279
+ enforcement means the contracts only *look* like they prevent drift. Arming is
280
+ best-effort (a missing `.git` becomes a warning, never a failed init); pass
281
+ `--no-arm` to skip it, and `cdd-kit doctor` reports the live/dormant status of
282
+ each chokepoint.
283
+
274
284
  Creates: `contracts/`, `specs/templates/`, provider guidance files (`CLAUDE.md`, `AGENTS.md`, and/or `CODEX.md`), `hooks/`
275
285
 
276
286
  `.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.
277
287
 
278
- Recommended: configure MCP-capable AI agents with `command: "cdd-kit"` and
279
- `args: ["mcp"]` after init. This exposes graph/code-map tools directly to the
280
- agent (`cdd_graph_context`, `cdd_graph_query`, `cdd_graph_impact`,
281
- `cdd_index_query`, `cdd_index_impact`) so project exploration does not depend on
282
- the agent remembering shell commands.
288
+ Recommended: register the cdd-kit MCP server with Claude Code after init:
289
+
290
+ ```bash
291
+ claude mcp add --scope user cdd-kit -- cdd-kit mcp
292
+ claude mcp list
293
+ ```
294
+
295
+ This writes the server to `~/.claude.json` and exposes graph/code-map tools
296
+ directly to the agent (`cdd_graph_context`, `cdd_graph_query`,
297
+ `cdd_graph_impact`, `cdd_index_query`, `cdd_index_impact`). Do not rely on
298
+ manually adding `mcpServers` to `~/.claude/settings.json`; that file is a Claude
299
+ Code UI settings format and is not the MCP registry read by the CLI.
283
300
 
284
301
  ---
285
302
 
@@ -313,9 +330,10 @@ cdd-kit migrate --all # add new per-change scaffolds such as implementation-p
313
330
  cdd-kit doctor --strict
314
331
  ```
315
332
 
316
- After syncing, configure MCP-capable agents with `command: "cdd-kit"` and
317
- `args: ["mcp"]`. This is the recommended way for agents to use the regenerated
318
- code graph and code-map; shell commands remain the fallback.
333
+ After syncing, register MCP-capable agents with
334
+ `claude mcp add --scope user cdd-kit -- cdd-kit mcp`. This is the recommended
335
+ way for agents to use the regenerated code graph and code-map; shell commands
336
+ remain the fallback.
319
337
 
320
338
  What gets updated:
321
339
 
@@ -333,6 +351,29 @@ place. Then run `cdd-kit migrate --all` so existing active change directories
333
351
  receive `implementation-plan.md`; fill required `design.md` with
334
352
  `spec-architect` before resuming the planner or implementation agents.
335
353
 
354
+ #### Upgrading to 2.2.0
355
+
356
+ 2.2.0 **arms enforcement chokepoints by default on a fresh `cdd-kit init`**, adds
357
+ the mechanical **tier floor**, `cdd-kit classify-check`, and `cdd-kit code-map
358
+ --watch`. A repo first set up with an older version keeps its chokepoints
359
+ *dormant* after a plain `npm`/`refresh` update — `cdd-kit doctor` will show them
360
+ as such. To bring an existing repo up to the 2.2.0 enforcement posture:
361
+
362
+ ```bash
363
+ npm install -g contract-driven-delivery # get 2.2.0
364
+ cdd-kit refresh --yes # sync agents/skills/templates/hooks/code-map
365
+ cdd-kit install-hooks # arm the pre-commit gate
366
+ cdd-kit install-agent-hooks --graph-first advisory # arm the graph-first hook (or: strict)
367
+ cdd-kit doctor # confirm both chokepoints report "live"
368
+ ```
369
+
370
+ The tier floor needs **no policy file** — built-in defaults apply when
371
+ `.cdd/tier-policy.json` is absent, so existing repos are protected without a
372
+ re-init. To customize or disable it, scaffold the policy with `cdd-kit upgrade
373
+ --yes` (writes an editable `.cdd/tier-policy.json`) and set rules or
374
+ `"enabled": false`. Bypass a single change with `tier-floor-override:
375
+ "<reason>"` in its `tasks.yml` frontmatter (recorded as an audit warning).
376
+
336
377
  If you do not want template overwrites, run the narrower path:
337
378
 
338
379
  ```bash
@@ -358,6 +399,10 @@ cdd-kit doctor --provider codex
358
399
 
359
400
  Checks 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` currently auto-runs `context-scan` for stale or missing indexes and backfills empty `.cdd/model-policy.json` role bindings, but deliberately does not run invasive repo upgrades for you.
360
401
 
402
+ 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`, so doctor surfaces the exact `claude mcp add --scope user cdd-kit -- cdd-kit mcp` command to fix it. This check is **informational only** — it never fails `--strict`, never blocks on a slow or missing `claude` CLI (3s timeout, best-effort), and is skipped for non-Claude projects. Point `CDD_CLAUDE_BIN` at an alternate Claude CLI if needed.
403
+
404
+ `doctor` finally prints a **chokepoint dashboard**: for each enforcement mechanism — the graph-first 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. Like the MCP and conformance lines, it is **advisory only** and never fails `--strict`.
405
+
361
406
  ---
362
407
 
363
408
  ### `cdd-kit upgrade`
@@ -399,10 +444,17 @@ cdd-kit refresh --yes --no-templates
399
444
  5. Resyncs `.cdd/model-policy.json` roles from installed agent frontmatter.
400
445
  6. Regenerates `.cdd/code-map.yml`.
401
446
 
402
- After `refresh --yes`, configure MCP-capable agents to run `cdd-kit mcp`.
447
+ After `refresh --yes`, register the MCP server:
448
+
449
+ ```bash
450
+ claude mcp add --scope user cdd-kit -- cdd-kit mcp
451
+ ```
452
+
403
453
  The MCP tools are the recommended graph/code-map exploration interface for AI
404
- agents; `cdd-kit graph ...` and `cdd-kit index ...` remain the fallback when MCP
405
- is not available.
454
+ agents. Claude Code CLI stores user-scope MCP servers in `~/.claude.json`; a
455
+ manual `mcpServers` entry in `~/.claude/settings.json` is not sufficient.
456
+ `cdd-kit graph ...` and `cdd-kit index ...` remain the fallback when MCP is not
457
+ available.
406
458
 
407
459
  Run `cdd-kit migrate --all` separately when you need existing
408
460
  `specs/changes/*` directories to gain new required artifacts.
@@ -422,6 +474,7 @@ Checks:
422
474
  - 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 require `context-manifest.md`)
423
475
  - Each artifact has sufficient content and is not a stub.
424
476
  - `change-classification.md` contains a tier or risk marker.
477
+ - **Mechanical risk-tier floor.** `change-request.md` is 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 under `auth/` or `payments/` 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), while `classify-check` scans 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 with `tier-floor-override: "<reason>"` in `tasks.yml` frontmatter (becomes an audit warning); tune or disable in `.cdd/tier-policy.json`.
425
478
  - Atomic `depends-on` upstream changes are completed or archived before dependent work gates.
426
479
  - All contract validators pass.
427
480
 
@@ -441,6 +494,25 @@ Pre-commit hook uses `--strict` by default (installed via `cdd-kit install-hooks
441
494
 
442
495
  ---
443
496
 
497
+ ### `cdd-kit classify-check`
498
+
499
+ Advisory probe that prints the **mechanical risk-tier floor** for a change
500
+ *before* classification, so the classifier can be steered up front instead of
501
+ only being caught later by `cdd-kit gate`. The blocking enforcement lives in the
502
+ gate; this command never fails (exit 0).
503
+
504
+ ```bash
505
+ cdd-kit classify-check add-jwt-auth # scan the change's change-request.md
506
+ cdd-kit classify-check --text "add stripe checkout" # scan inline intent
507
+ cdd-kit classify-check add-jwt-auth --json # machine-readable
508
+ ```
509
+
510
+ It reads the same ground-truth source the gate enforces against
511
+ (`change-request.md`), reports the strictest matched tier and the matched
512
+ patterns, and points at `.cdd/tier-policy.json` for tuning.
513
+
514
+ ---
515
+
444
516
  ### `cdd-kit list`
445
517
 
446
518
  Lists all active changes in `specs/changes/` with status and pending task count.
@@ -592,13 +664,38 @@ Runs contract validation scripts.
592
664
 
593
665
  ```bash
594
666
  cdd-kit validate # all validators
595
- cdd-kit validate --contracts # API, CSS, data-shape (+ semantic checks)
667
+ cdd-kit validate --contracts # API, CSS, data-shape (+ semantic + conformance checks)
596
668
  cdd-kit validate --env # env contract
597
669
  cdd-kit validate --ci # CI gate policy
598
670
  cdd-kit validate --spec # spec traceability
599
671
  cdd-kit validate --versions # contract frontmatter schema versions
600
672
  ```
601
673
 
674
+ `--contracts` includes **API conformance**: a code-vs-contract check that parses
675
+ real backend routes and frontend call sites and fails on drift from
676
+ `contracts/api/api-contract.md` (e.g. the frontend calling an endpoint the
677
+ contract never declares). It is off until you enable it in `.cdd/conformance.json`
678
+ (`"enabled": true`); `cdd-kit init` scaffolds a disabled config. See
679
+ [docs/api-conformance.md](docs/api-conformance.md). This is the mechanical net
680
+ for frontend/backend API drift in a workflow where no human reviews the contract
681
+ by hand.
682
+
683
+ ---
684
+
685
+ ### `cdd-kit openapi export`
686
+
687
+ 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.
688
+
689
+ ```bash
690
+ cdd-kit openapi export # JSON to stdout
691
+ cdd-kit openapi export --yaml --out openapi.yaml # YAML to a file
692
+ cdd-kit openapi export --check --out openapi.json # sync gate: fail on drift
693
+ ```
694
+
695
+ It 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](docs/openapi-export.md) and [docs/adr/0001-contract-to-openapi-export.md](docs/adr/0001-contract-to-openapi-export.md).
696
+
697
+ `--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.
698
+
602
699
  ---
603
700
 
604
701
  ### `cdd-kit new <name>`
@@ -636,6 +733,22 @@ Idempotent. Preserves existing hook content. Bypass with `--no-verify` is possib
636
733
 
637
734
  ---
638
735
 
736
+ ### `cdd-kit install-agent-hooks`
737
+
738
+ Installs Claude Code **agent hooks** into the project's `.claude/settings.json`. Currently installs the graph-first `PreToolUse` hook, which steers agents to `cdd-kit index query --with-source` before reading source files — turning the hook from a documented file you wire by hand into an enforced harness chokepoint.
739
+
740
+ ```bash
741
+ cdd-kit install-agent-hooks # advisory (default)
742
+ cdd-kit install-agent-hooks --graph-first strict # hard-block source Reads when a code-map exists
743
+ ```
744
+
745
+ - **advisory** (default): reminds the agent to use the graph/index query first; does not block the `Read`.
746
+ - **strict**: writes `CDD_GRAPH_FIRST_STRICT=1` into the hook command so the hook blocks source-file `Read` when `.cdd/code-map.yml` exists.
747
+
748
+ Writes the hook script to `.claude/hooks/pre-tool-use-graph-first.sh` and a `PreToolUse` entry to `.claude/settings.json` (project-scoped, so it travels with the repo). Idempotent: re-running replaces the cdd-kit entry and switches mode cleanly, preserving every other setting and hook.
749
+
750
+ ---
751
+
639
752
  ### `cdd-kit detect-stack`
640
753
 
641
754
  Detects the project tech stack from lockfiles and config files.
@@ -697,8 +810,21 @@ cdd-kit code-map # whole repo -> .cdd/code-map.yml
697
810
  cdd-kit code-map --check # exit 1 if regenerating would change the map
698
811
  cdd-kit code-map --surface packages/web # monorepo: scope + auto-name the map
699
812
  cdd-kit code-map --workers # parallelize JS/TS/Vue scanning (default off)
813
+ cdd-kit code-map --watch # background: keep the map fresh as files change
814
+ cdd-kit code-map --watch --debounce 800 # coalesce change bursts within 800ms
700
815
  ```
701
816
 
817
+ Indexing is **trigger-based by default** — the map regenerates when a command
818
+ needs it (gate, `index query --refresh`, `doctor --fix`, the pre-commit code-map
819
+ hook). That is the right default for ephemeral CI containers and one-shot agent
820
+ runs. `--watch` is the opt-in **background** mode for long-lived co-editing
821
+ sessions: a debounced recursive watcher keeps the map fresh so queries stay cheap
822
+ and current, with a freshness-polling fallback where recursive `fs.watch` is
823
+ unavailable. See
824
+ [docs/adr/0003-code-intelligence-indexing-strategy.md](docs/adr/0003-code-intelligence-indexing-strategy.md)
825
+ for why the kit keeps native AST scanners instead of an LSP daemon, and the
826
+ incremental-rebuild roadmap.
827
+
702
828
  `--workers [n]` (default off; `n` defaults to CPU count − 1, capped at 16)
703
829
  parallelizes the synchronous JS/TS/Vue parsing across child processes for large
704
830
  repos. Output is byte-identical to a single-process run, and any worker failure
@@ -720,10 +846,22 @@ with `--engine codegraph`.
720
846
  ```bash
721
847
  cdd-kit graph status
722
848
  cdd-kit graph query OrderService
849
+ cdd-kit graph query OrderService --with-source # include code inline; no follow-up Read needed
723
850
  cdd-kit graph context "filter options are empty"
724
851
  cdd-kit graph impact src/services/orders.ts --depth 2
725
852
  ```
726
853
 
854
+ `--with-source` (also on `cdd-kit index query`, and `withSource: true` via MCP)
855
+ returns the matched symbol's code inline so the query *replaces* a `Read` rather
856
+ than preceding it — making the kit tool strictly cheaper than the built-in
857
+ `Read`. `--source-budget <n>` caps total lines returned; truncated ranges are
858
+ flagged so you can `Read` only those.
859
+
860
+ To make graph-first exploration a real chokepoint instead of a prompt
861
+ preference, wire the shipped `hooks/pre-tool-use-graph-first.sh` as a
862
+ `PreToolUse` hook on `Read` (advisory by default; `CDD_GRAPH_FIRST_STRICT=1`
863
+ hard-blocks source `Read`s when a code-map exists).
864
+
727
865
  Use `--engine native` for the built-in graph, `--engine codemap` for the older
728
866
  code-map-only fallback, `--engine codegraph` to require external CodeGraph, or
729
867
  `CDD_CODEGRAPH_BIN=/path/to/codegraph` to point at a custom binary.
@@ -731,19 +869,17 @@ code-map-only fallback, `--engine codegraph` to require external CodeGraph, or
731
869
  ### `cdd-kit mcp`
732
870
 
733
871
  `cdd-kit mcp` runs a stdio MCP server so agents can call the graph/index layer
734
- as tools instead of shelling out manually.
872
+ as tools instead of shelling out manually. Register it with Claude Code:
735
873
 
736
- ```json
737
- {
738
- "mcpServers": {
739
- "cdd-kit": {
740
- "command": "cdd-kit",
741
- "args": ["mcp"]
742
- }
743
- }
744
- }
874
+ ```bash
875
+ claude mcp add --scope user cdd-kit -- cdd-kit mcp
876
+ claude mcp list
745
877
  ```
746
878
 
879
+ Use the CLI command above so Claude Code writes the server to `~/.claude.json`.
880
+ Do not rely on manually editing `~/.claude/settings.json`; that file is not the
881
+ MCP registry read by the CLI.
882
+
747
883
  Exposed tools:
748
884
 
749
885
  - `cdd_graph_status`
@@ -819,7 +955,7 @@ Then choose one path per active change:
819
955
  ### Recommended rollout for production repos already burned by token overuse
820
956
 
821
957
  1. Run `cdd-kit refresh --yes` once per repo after updating the npm package.
822
- 2. Configure MCP-capable agents with `command: "cdd-kit"` and `args: ["mcp"]`.
958
+ 2. Register MCP-capable agents with `claude mcp add --scope user cdd-kit -- cdd-kit mcp`.
823
959
  3. Run `cdd-kit migrate --all` so existing active changes receive the current required artifact set.
824
960
  4. Review and fill `implementation-plan.md` before resuming implementation agents on active changes.
825
961
  5. Run `cdd-kit doctor --strict` in CI.
@@ -46,17 +46,16 @@ Run `cdd-kit detect-stack` to verify the detected tech stack.
46
46
 
47
47
  Configure MCP-capable agents to use the cdd-kit server:
48
48
 
49
- ```json
50
- {
51
- "mcpServers": {
52
- "cdd-kit": {
53
- "command": "cdd-kit",
54
- "args": ["mcp"]
55
- }
56
- }
57
- }
49
+ ```bash
50
+ claude mcp add --scope user cdd-kit -- cdd-kit mcp
51
+ claude mcp list
58
52
  ```
59
53
 
54
+ For Claude Code, use `claude mcp add` so the server is written to
55
+ `~/.claude.json`. Do not rely on manually adding `mcpServers` to
56
+ `~/.claude/settings.json`; that is a Claude Code UI settings format and is not
57
+ the MCP registry read by the CLI.
58
+
60
59
  Prefer these MCP tools before reading source files: `cdd_graph_context`,
61
60
  `cdd_graph_query`, `cdd_graph_impact`, `cdd_index_query`, and
62
61
  `cdd_index_impact`. They use `.cdd/code-map.yml` and
@@ -64,6 +63,19 @@ Prefer these MCP tools before reading source files: `cdd_graph_context`,
64
63
  available, use the equivalent CLI commands: `cdd-kit graph ...` and
65
64
  `cdd-kit index ...`.
66
65
 
66
+ Pass `withSource: true` (MCP) or `--with-source` (CLI) on `query` to get the
67
+ matched symbol's code inline. The query then replaces a follow-up `Read` instead
68
+ of preceding it — use a plain `Read` only for ranges the query did not return
69
+ (e.g. a range flagged as source-budget truncated).
70
+
71
+ ## API Conformance
72
+
73
+ If `.cdd/conformance.json` has `"enabled": true`, `cdd-kit validate --contracts`
74
+ (and `cdd-kit gate`) mechanically check real backend routes and frontend call
75
+ sites against `contracts/api/api-contract.md`. Do not add, rename, or call an
76
+ endpoint without updating the contract in the same change, or the gate will fail
77
+ on the drift. See `docs/api-conformance.md`.
78
+
67
79
  ## Context Governance
68
80
 
69
81
  For context-governed changes, read `specs/changes/<change-id>/context-manifest.md` before using file-reading or broad search tools.
@@ -15,17 +15,16 @@ This project uses Contract-Driven Delivery (CDD).
15
15
 
16
16
  Configure MCP-capable agents to use the cdd-kit server:
17
17
 
18
- ```json
19
- {
20
- "mcpServers": {
21
- "cdd-kit": {
22
- "command": "cdd-kit",
23
- "args": ["mcp"]
24
- }
25
- }
26
- }
18
+ ```bash
19
+ claude mcp add --scope user cdd-kit -- cdd-kit mcp
20
+ claude mcp list
27
21
  ```
28
22
 
23
+ For Claude Code, use `claude mcp add` so the server is written to
24
+ `~/.claude.json`. Do not rely on manually adding `mcpServers` to
25
+ `~/.claude/settings.json`; that is a Claude Code UI settings format and is not
26
+ the MCP registry read by the CLI.
27
+
29
28
  Prefer these MCP tools before reading source files: `cdd_graph_context`,
30
29
  `cdd_graph_query`, `cdd_graph_impact`, `cdd_index_query`, and
31
30
  `cdd_index_impact`. They use `.cdd/code-map.yml` and
@@ -11,7 +11,8 @@ Before editing production code, read `specs/changes/<change-id>/implementation-p
11
11
 
12
12
  ## Code map (READ FIRST)
13
13
 
14
- Before reading ANY source file (`.py`, `.js`, `.jsx`, `.mjs`, `.cjs`, `.ts`, `.tsx`, `.vue`), FIRST run `cdd-kit index query "<symbol-or-file>"` or `Read .cdd/code-map.yml`.
14
+ Before reading ANY source file (`.py`, `.js`, `.jsx`, `.mjs`, `.cjs`, `.ts`, `.tsx`, `.vue`), FIRST run `cdd-kit index query "<symbol-or-file>" --with-source` or `Read .cdd/code-map.yml`.
15
+ Prefer `--with-source`: it returns the matched symbol's code inline, so you do NOT need a separate `Read` for that range. Use a plain `Read` only when you need lines the query did not return (e.g. a range flagged as source-budget truncated).
15
16
  Before editing a chosen source file, run `cdd-kit index impact "<path-or-symbol>"` to identify indexed local imports and dependents.
16
17
 
17
18
  The map is the size oracle. For each file you intend to read:
@@ -31,6 +32,7 @@ See `references/code-map-protocol.md` for the full protocol.
31
32
 
32
33
  ## Rules
33
34
 
35
+ - Do not change API response shape or add/rename/remove endpoints without updating `contracts/api/api-contract.md` in the same change. If `.cdd/conformance.json` is enabled, `cdd-kit validate --contracts` (and the gate) will fail when a backend route is missing from the contract.
34
36
  - Do not change API response shape without contract updates.
35
37
  - Keep route/controller code thin.
36
38
  - Put business logic in service/domain layers.
@@ -11,7 +11,8 @@ Before editing, read `specs/changes/<change-id>/implementation-plan.md`, API con
11
11
 
12
12
  ## Code map (READ FIRST)
13
13
 
14
- Before reading ANY source file (`.py`, `.js`, `.jsx`, `.mjs`, `.cjs`, `.ts`, `.tsx`, `.vue`), FIRST run `cdd-kit graph query "<symbol-or-file>"`, `cdd-kit graph context "<task>"`, `cdd-kit index query "<symbol-or-file>"`, or `Read .cdd/code-map.yml`.
14
+ Before reading ANY source file (`.py`, `.js`, `.jsx`, `.mjs`, `.cjs`, `.ts`, `.tsx`, `.vue`), FIRST run `cdd-kit graph query "<symbol-or-file>" --with-source`, `cdd-kit graph context "<task>"`, `cdd-kit index query "<symbol-or-file>" --with-source`, or `Read .cdd/code-map.yml`.
15
+ Prefer `--with-source`: it returns the matched symbol's code inline, so you do NOT need a separate `Read` for that range. Use a plain `Read` only for lines the query did not return (e.g. a range flagged as source-budget truncated).
15
16
  Before editing a chosen source file, run `cdd-kit graph impact "<path-or-symbol>" --depth 2` or `cdd-kit index impact "<path-or-symbol>"` to identify imports, dependents, callers/callees when available, and likely affected scope.
16
17
 
17
18
  The map is the size oracle. For each file you intend to read:
@@ -31,7 +32,7 @@ See `references/code-map-protocol.md` for the full protocol.
31
32
 
32
33
  ## Rules
33
34
 
34
- - Do not assume backend response shape; use the API contract.
35
+ - Do not assume backend response shape; use the API contract. Do not call an endpoint (path + method) that is not in `contracts/api/api-contract.md`. If `.cdd/conformance.json` is enabled, `cdd-kit validate --contracts` (and the gate) will fail on frontend calls that drift from the contract.
35
36
  - Follow `implementation-plan.md` for scope, non-goals, required changes, and file-level plan.
36
37
  - Do not expand scope beyond the implementation plan unless a Context Expansion Request is approved and the plan is updated.
37
38
  - Do not hard-code visual tokens when token system exists.
@@ -0,0 +1,16 @@
1
+ {
2
+ "_README": "Code-vs-contract API conformance. Run via `cdd-kit validate --contracts` (and `cdd-kit gate`). Set enabled:true to mechanically catch frontend/backend drift against contracts/api/api-contract.md. See docs/api-conformance.md.",
3
+ "enabled": false,
4
+ "apiPrefixes": ["/api"],
5
+ "sourceRoots": [],
6
+ "backendGlobsExt": [".py", ".js", ".ts", ".mjs", ".cjs", ".go", ".java", ".php"],
7
+ "frontendGlobsExt": [".js", ".jsx", ".ts", ".tsx", ".mjs", ".vue", ".svelte"],
8
+ "excludeDirs": ["node_modules", "dist", "build", ".git", ".cdd", "coverage", "vendor", "__pycache__", ".next", ".nuxt"],
9
+ "ignorePaths": ["/health", "/metrics"],
10
+ "checks": {
11
+ "backendRouteNotInContract": "error",
12
+ "contractEndpointNotImplemented": "warning",
13
+ "frontendCallNotInContract": "error"
14
+ },
15
+ "strict": false
16
+ }