contract-driven-delivery 2.0.20 → 2.1.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,92 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.1.0] - 2026-05-27
4
+
5
+ Native code graph and symptom-driven bug-fix workflow.
6
+
7
+ ### Added
8
+
9
+ - **Native cdd-kit code graph**: `cdd-kit code-map` now writes
10
+ `.cdd/code-graph.index.json`, a derived local graph cache with files, symbol
11
+ nodes, relationship edges, and unresolved references. It is gitignored,
12
+ regenerated with the code-map, stripped from the published package, and safe
13
+ to delete.
14
+ - **`cdd-kit graph`**: adds graph-first `status`, `query`, `impact`, `context`,
15
+ and `sync` commands. The default engine is the native cdd-kit graph; use
16
+ `--engine codemap` for the older code-map-only fallback or
17
+ `--engine codegraph` to require an external CodeGraph adapter.
18
+ - **Call/import/inheritance graph extraction** for the existing code-map language
19
+ surface: JS/TS/JSX/TSX/MJS/CJS, Vue script blocks, and Python.
20
+ - **`bug-fix-engineer` agent**: a write-capable implementation agent for
21
+ non-engineer symptom reports. It turns user-visible defects into graph-guided
22
+ hypotheses, reproduces when feasible, applies the smallest fix, and records
23
+ regression evidence.
24
+
25
+ ### Changed
26
+
27
+ - Agent and skill guidance now prefers `cdd-kit graph ...` before broad source
28
+ reads while retaining `cdd-kit index ...` and `.cdd/code-map.yml` as fallback
29
+ paths.
30
+ - `cdd-kit graph --engine codegraph` remains available as an explicit external
31
+ adapter, but external CodeGraph is no longer required or auto-selected by
32
+ default.
33
+
34
+ ## [2.0.21] - 2026-05-25
35
+
36
+ Kit review fixes plus large-project capability improvements. All additions are
37
+ opt-in and non-breaking; normal runs are byte-for-byte unchanged.
38
+
39
+ ### Added
40
+
41
+ - **`cdd-kit code-map --surface <subpath>`**: scopes the scan to a monorepo
42
+ subtree and names the map `.cdd/code-map.<slug>.yml`, queryable with
43
+ `cdd-kit index query <term> --map .cdd/code-map.<slug>.yml`, instead of forcing
44
+ one giant whole-repo map. A missing surface path now errors instead of
45
+ silently emitting an empty map.
46
+ - **`cdd-kit code-map --workers [n]`** (default off): parallelizes JS/TS/Vue
47
+ scanning across child processes. Output is deterministic regardless of chunk
48
+ distribution, and any worker failure falls back to in-process scanning, so
49
+ enabling workers can never make a run fail that would otherwise succeed.
50
+ - **Model class in dispatch badges**: `/cdd-new` and `/cdd-resume` now render
51
+ each agent badge as `[role · model]`, resolved at dispatch time from
52
+ `.cdd/model-policy.json`. Narration only — runtime model selection is unchanged.
53
+
54
+ ### Changed
55
+
56
+ - **JSON sidecar for `index query` / `index impact`**: `cdd-kit code-map` now
57
+ writes a parsed `.cdd/code-map.index.json` next to the map so queries skip the
58
+ slow `yaml.load` on large maps. The sidecar is a derived local cache —
59
+ gitignored, digest-validated against the map header, regenerated on every map
60
+ run, stripped from the published package, and never required (queries fall back
61
+ to the authoritative `.cdd/code-map.yml` on any absence or mismatch).
62
+ - **`typecheck` script** (`tsc --noEmit`) added and wired into `prepublishOnly`
63
+ so type errors cannot regress.
64
+ - Deduplicated `ensureGitignoreEntry` into `src/utils/gitignore.ts` as the single
65
+ source of truth.
66
+
67
+ ### Fixed
68
+
69
+ - **`cdd-kit doctor` no longer false-flags every agent**: doctor kept its own
70
+ divergent agent-lint check hard-coded to the old `### Required artifacts`
71
+ heading and flagged all agents after the heading was renamed to
72
+ `### Suggested artifacts`, while `cdd-kit lint-agents` reported clean. Both now
73
+ share `lintAgentContent` / `collectAgentViolations` so they cannot drift apart.
74
+ - **`cdd-kit doctor` now warns instead of silently passing** when `.claude/agents`
75
+ exists but cannot be read (permission/IO error), rather than reporting a clean
76
+ pass on an unscanned directory.
77
+ - **Python scanning is chunked** (`CDD_CODE_MAP_BATCH_SIZE`, default 400) so a
78
+ single subprocess timeout or buffer overflow on a large Python repo no longer
79
+ drops the structure of every `.py` file; completed chunks are preserved.
80
+ - Cleared pre-existing `tsc --noEmit` errors in `include-exclude.ts`,
81
+ `scanners/javascript.ts`, and `refresh.ts`.
82
+
83
+ ### Security
84
+
85
+ - The `--workers` / Python batch-list temp files are now created with
86
+ `crypto.randomBytes` names and mode `0600` to avoid predictable-name
87
+ symlink/race attacks in the shared tmp dir (CWE-377), and the scan worker spawn
88
+ is constrained by a language allowlist with an explicit no-shell invocation.
89
+
3
90
  ## [2.0.20] - 2026-05-15
4
91
 
5
92
  Patch release for UTF-8 BOM handling in Claude agent metadata files.
package/README.md CHANGED
@@ -120,6 +120,7 @@ Machine-readable metadata such as future `change.yml` / `trace.yml` should follo
120
120
  CDD uses two agent classes on purpose:
121
121
 
122
122
  - `change-classifier`, `contract-reviewer`, `qa-reviewer`, `visual-reviewer`, `dependency-security-reviewer`, `ui-ux-reviewer`, `repo-context-scanner`, and `spec-drift-auditor` are read-only. They return analysis, verdicts, or optional handoff notes; main Claude writes the corresponding files.
123
+ - `bug-fix-engineer` is 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.
123
124
  - `implementation-planner`, `backend-engineer`, `frontend-engineer`, `e2e-resilience-engineer`, `monkey-test-engineer`, `stress-soak-engineer`, `ci-cd-gatekeeper`, `test-strategist`, and `spec-architect` are write-capable. They write their own owned artifacts directly: for example, `spec-architect` owns `design.md`, while `implementation-planner` owns `implementation-plan.md`.
124
125
 
125
126
  This split is deliberate:
@@ -671,6 +672,67 @@ surface: user-management
671
672
 
672
673
  The classifier should read these two files before proposing `context-manifest.md` allowed paths.
673
674
 
675
+ ### `cdd-kit code-map`
676
+
677
+ Scans source files into a deterministic structural index so agents read symbols
678
+ and line ranges instead of whole files.
679
+
680
+ ```bash
681
+ cdd-kit code-map # whole repo -> .cdd/code-map.yml
682
+ cdd-kit code-map --check # exit 1 if regenerating would change the map
683
+ cdd-kit code-map --surface packages/web # monorepo: scope + auto-name the map
684
+ cdd-kit code-map --workers # parallelize JS/TS/Vue scanning (default off)
685
+ ```
686
+
687
+ `--workers [n]` (default off; `n` defaults to CPU count − 1, capped at 16)
688
+ parallelizes the synchronous JS/TS/Vue parsing across child processes for large
689
+ repos. Output is byte-identical to a single-process run, and any worker failure
690
+ falls back to in-process scanning, so it can never make a run worse. Python is
691
+ already scanned in its own subprocess.
692
+
693
+ A JSON sidecar (`.cdd/code-map.<...>.index.json`) is written next to each map and
694
+ gitignored automatically; `cdd-kit index` reads it to skip re-parsing the YAML on
695
+ large maps, and falls back to the YAML whenever the sidecar is absent or stale.
696
+
697
+ ### `cdd-kit graph`
698
+
699
+ `cdd-kit graph` is the graph-first query layer. `cdd-kit code-map` also writes
700
+ `.cdd/code-graph.index.json`, a native cdd-kit graph of files, symbols, imports,
701
+ exports, calls, inheritance, and unresolved references. Graph queries use this
702
+ native graph by default. You can still delegate to external CodeGraph explicitly
703
+ with `--engine codegraph`.
704
+
705
+ ```bash
706
+ cdd-kit graph status
707
+ cdd-kit graph query OrderService
708
+ cdd-kit graph context "filter options are empty"
709
+ cdd-kit graph impact src/services/orders.ts --depth 2
710
+ ```
711
+
712
+ Use `--engine native` for the built-in graph, `--engine codemap` for the older
713
+ code-map-only fallback, `--engine codegraph` to require external CodeGraph, or
714
+ `CDD_CODEGRAPH_BIN=/path/to/codegraph` to point at a custom binary.
715
+
716
+ Large Python repos are scanned in chunks (`CDD_CODE_MAP_BATCH_SIZE`, default 400)
717
+ so one slow batch cannot drop the whole language. Raise
718
+ `CDD_CODE_MAP_TIMEOUT_MS` (default 30000) if a single batch still times out.
719
+
720
+ #### Monorepos: per-surface maps
721
+
722
+ `--surface <subpath>` scopes the scan to one package and names the map after it
723
+ (`packages/web` → `.cdd/code-map.packages-web.yml`). Paths inside that map are
724
+ relative to the surface root. Query a specific surface map with `--map`:
725
+
726
+ ```bash
727
+ cdd-kit code-map --surface packages/web
728
+ cdd-kit code-map --surface packages/api
729
+ cdd-kit index query OrderService --map .cdd/code-map.packages-api.yml
730
+ cdd-kit context-scan --surface packages/web # scope the project-map tree too
731
+ ```
732
+
733
+ This keeps each package's index small and token-cheap instead of indexing the
734
+ entire monorepo into one giant map.
735
+
674
736
  ---
675
737
 
676
738
  ## Migrating an Older Production Repo
@@ -0,0 +1,97 @@
1
+ ---
2
+ name: bug-fix-engineer
3
+ description: Investigate user-described defects, convert symptoms into reproducible root cause hypotheses, use graph/code-map context before source reads, implement the smallest safe fix, and add regression evidence.
4
+ tools: Read, Grep, Glob, Edit, MultiEdit, Bash
5
+ model: sonnet
6
+ ---
7
+
8
+ You are the bug fix engineer.
9
+
10
+ Users often report symptoms, not implementation locations: "the filter is empty", "a panel is covered", "the button does nothing", "the report disappeared". Treat the symptom as a clue, not as the root cause.
11
+
12
+ ## Code map (READ FIRST)
13
+
14
+ Before reading source, query the graph layer:
15
+
16
+ ```bash
17
+ cdd-kit graph context "<user symptom>"
18
+ cdd-kit graph query "<screen/component/api/store/filter term>"
19
+ cdd-kit graph impact "<candidate path or symbol>" --depth 2
20
+ ```
21
+
22
+ `cdd-kit graph ...` uses the native `.cdd/code-graph.index.json` generated by `cdd-kit code-map`. If graph commands are unavailable, use `cdd-kit index query ...` and `cdd-kit index impact ...` as the fallback.
23
+
24
+ Use graph/code-map output to pick the smallest useful source and test ranges. Do not start with broad repository search unless the context manifest permits it and targeted graph/index queries fail.
25
+
26
+ See `references/code-map-protocol.md` for the full graph/code-map protocol.
27
+
28
+ ## Investigation workflow
29
+
30
+ 1. Restate the symptom as observable behavior.
31
+ 2. Derive 2-5 concrete hypotheses with candidate files/symbols.
32
+ 3. Reproduce or create a failing check before editing whenever feasible.
33
+ 4. Inspect the target plus graph-reported imports, dependents, callers, callees, or fallback direct dependents.
34
+ 5. Fix the smallest root cause that explains the reproduced symptom.
35
+ 6. Add or update regression coverage near the failing behavior.
36
+ 7. Run the narrowest useful test first, then broaden only when risk justifies it.
37
+
38
+ For UI symptoms, verify relevant states: default, loading, empty, error, long text, permission/disabled, and the reported viewport if known. Capture screenshot or Playwright evidence when the defect is visual or layout-related.
39
+
40
+ For data/API symptoms, verify request parameters, response shape, empty/error handling, permissions, caching, and mapping from backend data to UI state.
41
+
42
+ ## Fix discipline
43
+
44
+ - Do not rewrite nearby code only because it is untidy.
45
+ - Do not change contracts unless the recorded expected behavior is wrong; route contract drift to contract-reviewer/spec-drift-auditor.
46
+ - If the reported symptom cannot be reproduced, add instrumentation or a targeted diagnostic path only when it is low-risk and removable.
47
+ - If multiple unrelated defects are discovered, fix only the one needed for the reported symptom and list the others as follow-up.
48
+
49
+ ## Read scope
50
+
51
+ Source of truth: `specs/changes/<change-id>/context-manifest.md` -> `## Allowed Paths`.
52
+ Read it first when a change id exists. Read only paths it lists or paths under `## Approved Expansions`. Use this boundary as pre-read discipline, not as post-run paperwork.
53
+
54
+ This agent commonly needs the screen/component file, state/store/query hook, API client or backend route, related tests, and visual/e2e fixtures. Those paths must appear in the manifest before you read them. When concrete paths are known, run `cdd-kit context check <change-id> --path ...` before reading them.
55
+
56
+ Need a path not listed? File a `## Context Expansion Requests` entry (see `specs/templates/context-manifest.md`) with `status: pending` and stop until the user approves via `cdd-kit context approve <change-id> <CER-id>`.
57
+
58
+ Forbidden by default (enforced by `.cdd/context-policy.json`): `specs/archive/`, sibling `specs/changes/*`, `assets/`, `node_modules/`, `dist/`, `build/`, `.git/`, `.claude/worktrees/`.
59
+
60
+ ## Handoff
61
+
62
+ Report the reproduced symptom, root cause, files changed, tests/evidence, and any residual risk in plain language suitable for a non-engineer.
63
+
64
+ ## Optional Handoff Evidence
65
+
66
+ If a short handoff note is useful, write or append to
67
+ `specs/changes/<change-id>/agent-log/<your-agent-name>.yml`. Optional fields
68
+ and field rules are defined once in
69
+ `references/agent-log-protocol.md` -- do not duplicate them in this prompt.
70
+
71
+ ### Suggested artifacts for this agent
72
+
73
+ `artifacts` is a YAML array of `{type, pointer}` items in your agent log
74
+ (see `references/agent-log-protocol.md` for the full schema and self-validation
75
+ checklist). Do NOT write top-level `files-changed:` / `tests-added:` keys -- those are `type` values, not log keys.
76
+
77
+ Recommended `type` values for this agent when you emit an optional agent log:
78
+
79
+ - `symptom`: user-visible defect being fixed
80
+ - `root-cause`: file/symbol and concise cause
81
+ - `files-changed`: source/test files modified
82
+ - `regression-evidence`: failing-then-passing test, screenshot, or reproduction command
83
+ - `residual-risk`: remaining risk or "none"
84
+
85
+ If you emit a log, copy this shape and replace each `<pointer>` with a
86
+ concrete pointer (path:line-range, test-id, URL, or pass/fail string):
87
+
88
+ ```yaml
89
+ artifacts:
90
+ - { type: symptom, pointer: "Filter options empty on Orders page" }
91
+ - { type: root-cause, pointer: "src/pages/Orders.tsx:42-68 mapped status_label instead of status" }
92
+ - { type: files-changed, pointer: "src/pages/Orders.tsx, test/orders-filter.test.ts" }
93
+ - { type: regression-evidence, pointer: "npm test -- --run test/orders-filter.test.ts: pass" }
94
+ - { type: residual-risk, pointer: "none" }
95
+ ```
96
+
97
+ If a recommended `type` does not apply to your run, either omit it or use `pointer: "n/a (<one-line reason>)"` so reviewers can tell the omission was intentional.
@@ -299,6 +299,6 @@ If a recommended `type` does not apply to your run, either omit it or use `point
299
299
  - Report/dashboard/data import/export change always requires data-shape boundary tests.
300
300
  - High-load, auto-refresh, queue, cache, report, or long-running job change requires stress or soak consideration.
301
301
  - Existing behavior changes require current behavior and regression scope.
302
- - Bug fixes require reproduction, root cause, failing test, and regression test whenever feasible.
302
+ - Bug fixes require reproduction, root cause, failing test, and regression test whenever feasible. If the user describes only a symptom and the code location is unknown, include `bug-fix-engineer` in `## Required Agents`.
303
303
  - Architecture review, non-obvious design decisions, module-boundary changes, data-flow changes, migration/rollback decisions, compatibility trade-offs, or operational-risk decisions require `spec-architect` to write `design.md` before `implementation-planner` runs.
304
304
  - Any implementation change requires `implementation-planner` before backend/frontend/test implementation agents. The planner turns decisions, contracts, and tests into the execution packet; implementation agents should not infer missing scope from chat history.
@@ -11,8 +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 index query "<symbol-or-file>"` or `Read .cdd/code-map.yml`.
15
- Before editing a chosen source file, run `cdd-kit index impact "<path-or-symbol>"` to identify indexed local imports and dependents.
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`.
15
+ 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
16
 
17
17
  The map is the size oracle. For each file you intend to read:
18
18
 
@@ -22,8 +22,8 @@ The map is the size oracle. For each file you intend to read:
22
22
  `interfaces:` / `types:` / `enums:`) `lines: A-B` field and
23
23
  `Read <path> offset:A limit:(B-A+1)`.
24
24
 
25
- Prefer `cdd-kit index query` because it auto-refreshes missing or stale maps
26
- before returning candidates. If you cannot run commands and `.cdd/code-map.yml`
25
+ Prefer `cdd-kit graph ...` because it uses the native code graph and falls
26
+ back to the auto-refreshing code-map path when forced. If you cannot run commands and `.cdd/code-map.yml`
27
27
  is missing or stale, avoid broad source reads and ask the harness/user to
28
28
  regenerate the map.
29
29
 
@@ -17,7 +17,7 @@ Do not approve based on claims. Approve based on commands, artifacts, screenshot
17
17
  - visual evidence provided for UI changes
18
18
  - stress/soak evidence provided when required
19
19
  - known risks and residual gaps documented
20
- - index discipline: agents should prefer `cdd-kit index query ...` or `.cdd/code-map.yml` before targeted source reads and run `cdd-kit index impact ...` before editing source. Treat source-first work as harness/process drift, not a merge-blocking QA finding unless it produced concrete quality risk.
20
+ - index discipline: agents should prefer `cdd-kit graph ...`, `cdd-kit index query ...`, or `.cdd/code-map.yml` before targeted source reads and run `cdd-kit graph impact ...` or `cdd-kit index impact ...` before editing source. Treat source-first work as harness/process drift, not a merge-blocking QA finding unless it produced concrete quality risk.
21
21
 
22
22
  ## Failure routing
23
23
 
@@ -9,6 +9,7 @@
9
9
  "qa-reviewer": "opus",
10
10
  "contract-reviewer": "sonnet",
11
11
  "test-strategist": "sonnet",
12
+ "bug-fix-engineer": "sonnet",
12
13
  "backend-engineer": "sonnet",
13
14
  "frontend-engineer": "sonnet",
14
15
  "ci-cd-gatekeeper": "sonnet",
@@ -38,6 +38,33 @@ def _is_all_caps(name: str) -> bool:
38
38
  return any(c.isalpha() for c in name)
39
39
 
40
40
 
41
+ def _expr_name(node: ast.AST) -> str | None:
42
+ if isinstance(node, ast.Name):
43
+ return node.id
44
+ if isinstance(node, ast.Attribute):
45
+ base = _expr_name(node.value)
46
+ return f"{base}.{node.attr}" if base else node.attr
47
+ if isinstance(node, ast.Call):
48
+ return _expr_name(node.func)
49
+ if isinstance(node, ast.Constant) and isinstance(node.value, str):
50
+ return node.value
51
+ return None
52
+
53
+
54
+ def _calls_in(node: ast.AST, caller: str) -> list[dict]:
55
+ calls: list[dict] = []
56
+ for sub in ast.walk(node):
57
+ if isinstance(sub, ast.Call):
58
+ callee = _expr_name(sub.func)
59
+ if callee:
60
+ calls.append({
61
+ "caller": caller,
62
+ "callee": callee,
63
+ "line": sub.lineno,
64
+ })
65
+ return calls
66
+
67
+
41
68
  def scan_file(abs_path: str, repo_root: str) -> dict:
42
69
  src = open(abs_path, encoding="utf-8").read()
43
70
  total_lines = len(src.splitlines()) if src else 0
@@ -70,6 +97,8 @@ def scan_file(abs_path: str, repo_root: str) -> dict:
70
97
  constants: list[dict] = []
71
98
  classes: list[dict] = []
72
99
  functions: list[dict] = []
100
+ calls: list[dict] = []
101
+ exports: list[dict] = []
73
102
 
74
103
  for node in ast.iter_child_nodes(tree):
75
104
  # ── imports ──────────────────────────────────────────────────────────
@@ -109,11 +138,16 @@ def scan_file(abs_path: str, repo_root: str) -> dict:
109
138
  "lines": [sub.lineno, sub.end_lineno],
110
139
  "async": isinstance(sub, ast.AsyncFunctionDef),
111
140
  })
141
+ calls.extend(_calls_in(sub, f"{node.name}.{sub.name}"))
112
142
  classes.append({
113
143
  "name": node.name,
114
144
  "lines": [node.lineno, node.end_lineno],
115
145
  "methods": methods,
146
+ "extends": [name for name in (_expr_name(base) for base in node.bases) if name],
147
+ "implements": [],
148
+ "exported": True,
116
149
  })
150
+ exports.append({"name": node.name, "kind": "class", "line": node.lineno})
117
151
 
118
152
  # ── functions ────────────────────────────────────────────────────────
119
153
  elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
@@ -128,7 +162,10 @@ def scan_file(abs_path: str, repo_root: str) -> dict:
128
162
  "lines": [node.lineno, node.end_lineno],
129
163
  "decorators": decos,
130
164
  "async": isinstance(node, ast.AsyncFunctionDef),
165
+ "exported": True,
131
166
  })
167
+ calls.extend(_calls_in(node, node.name))
168
+ exports.append({"name": node.name, "kind": "function", "line": node.lineno})
132
169
 
133
170
  return {
134
171
  "path": _rel_path(abs_path, repo_root),
@@ -137,6 +174,8 @@ def scan_file(abs_path: str, repo_root: str) -> dict:
137
174
  "constants": constants,
138
175
  "classes": classes,
139
176
  "functions": functions,
177
+ "calls": calls,
178
+ "exports": exports,
140
179
  "ok": True,
141
180
  }
142
181
 
@@ -115,7 +115,7 @@ inevitable re-classification when the agents discover the ambiguity.
115
115
  | Agent type | Who writes artifact files | Who writes optional handoff notes | Who updates tasks.yml |
116
116
  |------------|--------------------------|----------------------------------|----------------------|
117
117
  | Read-only agents (no Edit tool): `change-classifier`, `contract-reviewer`, `qa-reviewer`, `visual-reviewer`, `dependency-security-reviewer`, `ui-ux-reviewer` | YOU (main Claude) | YOU, only when useful | YOU (main Claude) |
118
- | Write-capable agents (have Edit): `implementation-planner`, `backend-engineer`, `frontend-engineer`, `e2e-resilience-engineer`, `monkey-test-engineer`, `stress-soak-engineer`, `ci-cd-gatekeeper`, `test-strategist`, `spec-architect` | The agent itself | The agent itself, only when useful | YOU (main Claude) |
118
+ | Write-capable agents (have Edit): `implementation-planner`, `backend-engineer`, `bug-fix-engineer`, `frontend-engineer`, `e2e-resilience-engineer`, `monkey-test-engineer`, `stress-soak-engineer`, `ci-cd-gatekeeper`, `test-strategist`, `spec-architect` | The agent itself | The agent itself, only when useful | YOU (main Claude) |
119
119
 
120
120
  **Rule**: After EVERY agent completes (whether it writes itself or you write for it), YOU must update the relevant `tasks.yml` task `status:` from `pending` to `done`.
121
121
 
@@ -315,17 +315,26 @@ agent:
315
315
  ### Agent stage badges (UI v1)
316
316
 
317
317
  When you announce that you are about to invoke an agent, prefix the
318
- announcement with the matching emoji + role tag from the table below. This
319
- helps a non-engineer scanning the chat stream tell what stage they are in
318
+ announcement with the matching emoji + role tag from the table below, and
319
+ include the model class that agent runs on. This helps a non-engineer scanning
320
+ the chat stream tell what stage they are in AND which model is doing the work,
320
321
  without reading the full prompt. Use the badges only in your own narration to
321
322
  the user; do not put them inside the prompt sent to the agent.
322
323
 
324
+ The model class is not something you guess from the color. Read it at dispatch
325
+ time from `.cdd/model-policy.json` (`roles.<agent-name>`), which is the
326
+ authoritative source and is kept in sync with each agent's `model:` frontmatter
327
+ by `cdd-kit doctor`. Show that value (e.g. `opus`, `sonnet`, `haiku`) in the
328
+ badge so the user always sees the actual model, even after a project overrides
329
+ the defaults.
330
+
323
331
  | Stage | Agent | Badge |
324
332
  |---|---|---|
325
333
  | Decision | `change-classifier` | ? `[classifier]` |
326
334
  | Decision | `spec-architect` | ? `[architect]` |
327
335
  | Decision | `implementation-planner` | ? `[plan]` |
328
336
  | Implementation | `backend-engineer` | ? `[backend]` |
337
+ | Implementation | `bug-fix-engineer` | ? `[bug-fix]` |
329
338
  | Implementation | `frontend-engineer` | ? `[frontend]` |
330
339
  | Implementation | `ci-cd-gatekeeper` | ? `[ci-cd]` |
331
340
  | Implementation | `test-strategist` | ? `[test-plan]` |
@@ -348,8 +357,12 @@ Color semantics:
348
357
  - ? green: reviewing what was done (no code writes; just verdicts)
349
358
  - ??neutral: audits and scans (read-only background work)
350
359
 
351
- Format: emoji is followed by a single space, then the bracket-tag, then the
352
- human-readable narration.
360
+ Format: emoji is followed by a single space, then the bracket-tag with the
361
+ model class appended as `[role · model]`, then a single space, then the
362
+ human-readable narration. Resolve `model` from `.cdd/model-policy.json`
363
+ `roles.<agent-name>` (defaults: classifier / architect / plan / qa / drift =
364
+ `opus`; backend / bug-fix / frontend / ci-cd / test-plan / e2e / monkey / stress /
365
+ ui-ux / deps-sec = `sonnet`; visual / repo-scan = `haiku`).
353
366
 
354
367
  Examples:
355
368
 
@@ -360,9 +373,19 @@ Examples:
360
373
  ?? [stress] Tier 1 high-risk change ??running soak test for 30 min.
361
374
  ```
362
375
 
376
+ Model-labeled examples (the model class sits inside the bracket tag):
377
+
378
+ ```
379
+ 🟣 [classifier · opus] Reading the request and project map.
380
+ 🔵 [backend · sonnet] Implementing the JWT issuance endpoint, failing tests first.
381
+ ⚫ [repo-scan · haiku] Indexing the repository structure. (read-only)
382
+ ```
383
+
363
384
  These badges are pure narration. They MUST NOT be sent inside the agent's
364
385
  prompt; the agent's behavior is defined by the agent prompt files in
365
- `.claude/agents/<name>.md`, not by this badge.
386
+ `.claude/agents/<name>.md`, not by this badge. The model label is for the
387
+ user's visibility only — it does not change which model the runtime selects
388
+ (that is governed by the agent's `model:` frontmatter).
366
389
 
367
390
  ---
368
391
 
@@ -407,6 +430,8 @@ prompt; the agent's behavior is defined by the agent prompt files in
407
430
  - YOU tick: `4.1` and/or `4.3` based on scope
408
431
  - Note: `tasks.yml` items 3.1??.2 (unit/contract/integration tests) are written by `backend-engineer` and/or `frontend-engineer` in TDD fashion ??failing tests first, implementation second. Items 3.3??.5 are written by dedicated test engineers (Tier 0?? only or when classifier explicitly requires them).
409
432
 
433
+ 6a. **`bug-fix-engineer`** (write-capable) ??for symptom-driven bug fixes where the user reports behavior but not the code location. Use this instead of backend/frontend as the first implementation agent when root cause is unknown; it may route the final implementation to backend/frontend scope after graph-guided investigation.
434
+
410
435
  7. **`frontend-engineer`** (write-capable) ??if the change touches UI, components, or client-side behavior. Writes implementation directly; may write an optional handoff note.
411
436
  - YOU tick: `4.2`
412
437
 
@@ -93,7 +93,7 @@ Ask the user: "Continue from <next-agent>? (yes/no)"
93
93
 
94
94
  ## Step 3: Continue the flow
95
95
 
96
- If user confirms, resume from the next agent in the Tier sequence (refer to `/cdd-new` Step 3 for the agent order, and `/cdd-new` "Agent stage badges" for the colored badges to use in your narration).
96
+ If user confirms, resume from the next agent in the Tier sequence (refer to `/cdd-new` Step 3 for the agent order, and `/cdd-new` "Agent stage badges" for the colored badges — including the per-agent model class read from `.cdd/model-policy.json` — to use in your narration).
97
97
 
98
98
  **Critical**: Inject this block at the start of every agent prompt:
99
99
 
@@ -7,9 +7,22 @@ when `cdd-kit init --hooks` is installed. `cdd-kit gate` does not enforce
7
7
  index hygiene; use `cdd-kit code-map --check`, `cdd-kit doctor --fix`, or the
8
8
  auto-refreshing `cdd-kit index ...` commands for that job.
9
9
 
10
- ## Preferred workflow: query before reading
10
+ ## Preferred workflow: graph/query before reading
11
11
 
12
- Before reading source, run a targeted query:
12
+ Before reading source, use the graph layer when available:
13
+
14
+ ```bash
15
+ cdd-kit graph context "fix login redirect bug"
16
+ cdd-kit graph query "AuthService"
17
+ cdd-kit graph impact "src/services/auth.ts" --depth 2
18
+ ```
19
+
20
+ `cdd-kit graph ...` uses the native `.cdd/code-graph.index.json` by default.
21
+ Use `cdd-kit graph status` to see graph freshness and node/edge counts. External
22
+ CodeGraph remains available with `--engine codegraph` when a project wants that
23
+ adapter explicitly.
24
+
25
+ If graph commands are not available, run a targeted code-map query:
13
26
 
14
27
  ```bash
15
28
  cdd-kit index query "AuthService"