contract-driven-delivery 2.0.12 → 2.0.14
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 +46 -0
- package/README.md +39 -1
- package/assets/CLAUDE.template.md +16 -0
- package/assets/CODEX.template.md +15 -0
- package/assets/agents/backend-engineer.md +1 -1
- package/assets/agents/change-classifier.md +1 -1
- package/assets/agents/ci-cd-gatekeeper.md +9 -1
- package/assets/agents/contract-reviewer.md +1 -1
- package/assets/agents/dependency-security-reviewer.md +5 -1
- package/assets/agents/e2e-resilience-engineer.md +1 -1
- package/assets/agents/frontend-engineer.md +8 -1
- package/assets/agents/monkey-test-engineer.md +7 -1
- package/assets/agents/qa-reviewer.md +9 -1
- package/assets/agents/repo-context-scanner.md +1 -1
- package/assets/agents/spec-architect.md +1 -1
- package/assets/agents/spec-drift-auditor.md +1 -1
- package/assets/agents/stress-soak-engineer.md +1 -1
- package/assets/agents/test-strategist.md +1 -1
- package/assets/agents/ui-ux-reviewer.md +1 -1
- package/assets/agents/visual-reviewer.md +1 -1
- package/assets/cdd/model-policy.json +17 -17
- package/assets/skills/cdd-new/SKILL.md +42 -10
- package/assets/skills/cdd-resume/SKILL.md +2 -2
- package/assets/skills/contract-driven-delivery/SKILL.md +5 -0
- package/assets/skills/contract-driven-delivery/references/agent-log-protocol.md +38 -10
- package/assets/skills/contract-driven-delivery/templates/agent-log.example.yml +1 -1
- package/assets/skills/contract-driven-delivery/templates/change-classification.md +3 -1
- package/assets/skills/contract-driven-delivery/templates/qa-report.md +4 -0
- package/assets/specs-templates/context-manifest.md +2 -0
- package/assets/specs-templates/qa-report.md +4 -0
- package/dist/cli/index.js +137 -22
- package/docs/machine-readable-change-design.md +137 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.0.14] - 2026-05-06
|
|
4
|
+
|
|
5
|
+
Operational hardening for real multi-agent CDD runs.
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Context read preflight**: `cdd-kit context check <change-id> --path ...`
|
|
10
|
+
validates expected agent reads against `Allowed Paths`, approved expansions,
|
|
11
|
+
repo-relative path rules, and the forbidden-path baseline before agent work.
|
|
12
|
+
- **Pre-existing failure tracking**: QA templates and reviewer prompts now
|
|
13
|
+
require baseline evidence, scope rationale, owner, and follow-up when an
|
|
14
|
+
existing failing test is excluded from the current gate.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **Agent-log YAML is more resilient**: gate keeps YAML timestamps as strings
|
|
19
|
+
and accepts `done` / `approved` as completion aliases while still documenting
|
|
20
|
+
`complete` as canonical.
|
|
21
|
+
- **Model policy is provider-neutral**: role bindings now use model classes
|
|
22
|
+
(`opus`, `sonnet`, `haiku`) instead of provider release IDs.
|
|
23
|
+
- **Agent orchestration guidance is stricter**: `/cdd-new` now requires
|
|
24
|
+
closeout after each agent, including agent-log verification and immediate
|
|
25
|
+
`tasks.yml` updates before the next agent is invoked.
|
|
26
|
+
- **Migration review guidance is sharper**: MySQL ENUM contraction and
|
|
27
|
+
`ALGORITHM=COPY` DDL are explicitly treated as high risk on large tables.
|
|
28
|
+
|
|
29
|
+
## [2.0.13] - 2026-05-05
|
|
30
|
+
|
|
31
|
+
Documentation and release-prep patch focused on keeping CDD low-friction.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- **Clarified workflow lanes**: README now distinguishes full tracked CDD
|
|
36
|
+
changes from maintenance / micro-change work, so typo fixes, formatting,
|
|
37
|
+
lint-only changes, and tiny local repairs do not imply proposal-level
|
|
38
|
+
ceremony.
|
|
39
|
+
- **Documented future machine-readable metadata direction**:
|
|
40
|
+
`docs/machine-readable-change-design.md` defines `change.yml` and
|
|
41
|
+
`trace.yml` as generated metadata for reducing markdown parsing and token
|
|
42
|
+
use, not as new manually-authored forms.
|
|
43
|
+
- **Synced skill/protocol docs with implementation**: `/cdd-new` now reflects
|
|
44
|
+
that `context-manifest.md` is required and that `cdd-kit new` auto-runs
|
|
45
|
+
`context-scan` when indexes are missing or stale; the agent-log protocol now
|
|
46
|
+
reflects that gate enforces per-agent artifact types when prompt files are
|
|
47
|
+
installed.
|
|
48
|
+
|
|
3
49
|
## [2.0.12] - 2026-05-04
|
|
4
50
|
|
|
5
51
|
Tiny patch — closes the last line-ending hole.
|
package/README.md
CHANGED
|
@@ -99,6 +99,21 @@ or
|
|
|
99
99
|
8. `cdd-kit gate <change-id>` runs automatically to confirm all artifacts are complete
|
|
100
100
|
9. Claude reports a summary and the suggested git commit
|
|
101
101
|
|
|
102
|
+
### Workflow Lanes: Avoiding Ceremony for Small Fixes
|
|
103
|
+
|
|
104
|
+
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.
|
|
105
|
+
|
|
106
|
+
Use a lightweight maintenance lane for small corrections where the intent is already obvious:
|
|
107
|
+
|
|
108
|
+
| Lane | Examples | Required record |
|
|
109
|
+
|---|---|---|
|
|
110
|
+
| 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 |
|
|
111
|
+
| tracked CDD change | behavior changes, contract updates, API/data/env/security/CI changes, cross-module refactors, high-risk bug fixes | `specs/changes/<id>/`, `tasks.yml`, `context-manifest.md`, agent logs, and `cdd-kit gate` |
|
|
112
|
+
|
|
113
|
+
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.
|
|
114
|
+
|
|
115
|
+
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.
|
|
116
|
+
|
|
102
117
|
### Agent Ownership Model
|
|
103
118
|
|
|
104
119
|
CDD uses two agent classes on purpose:
|
|
@@ -237,6 +252,8 @@ cdd-kit init --force # overwrite existing project files
|
|
|
237
252
|
|
|
238
253
|
Creates: `contracts/`, `specs/templates/`, provider guidance files (`CLAUDE.md`, `AGENTS.md`, and/or `CODEX.md`), `hooks/`
|
|
239
254
|
|
|
255
|
+
`.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.
|
|
256
|
+
|
|
240
257
|
---
|
|
241
258
|
|
|
242
259
|
### `cdd-kit update`
|
|
@@ -301,7 +318,7 @@ Checks:
|
|
|
301
318
|
- All required artifacts exist (`change-request.md`, `change-classification.md`, `test-plan.md`, `ci-gates.md`, `tasks.yml`; new context-governed changes also require `context-manifest.md`)
|
|
302
319
|
- Each artifact has sufficient content (not a stub): change-classification ≥ 200 chars, test-plan ≥ 200, ci-gates ≥ 150, others ≥ 100
|
|
303
320
|
- `change-classification.md` contains a tier or risk marker
|
|
304
|
-
- `agent-log/*.yml` files all have
|
|
321
|
+
- `agent-log/*.yml` files all have a completed status (`complete`, with `done` and `approved` accepted as compatibility aliases) and are not blocked
|
|
305
322
|
- For context-governed changes, `agent-log/*.yml` files include a structured `files-read:` list and those repo-relative paths are audited against `context-manifest.md` and `.cdd/context-policy.json`
|
|
306
323
|
- Atomic `depends-on` upstream changes are completed or archived before dependent work gates
|
|
307
324
|
- Tier 0–1 changes have `e2e-resilience-engineer`, `monkey-test-engineer`, and `stress-soak-engineer` logs
|
|
@@ -396,6 +413,9 @@ files-read:
|
|
|
396
413
|
```
|
|
397
414
|
|
|
398
415
|
Paths must be repo-relative. Absolute paths and `..` parent traversal are rejected.
|
|
416
|
+
If a logged read is legitimate but gate says it is unauthorized, add that path
|
|
417
|
+
to `context-manifest.md` `## Allowed Paths` or approve a Context Expansion
|
|
418
|
+
Request. Do not remove it from `files-read`; that list is the audit trail.
|
|
399
419
|
|
|
400
420
|
Run this after upgrading from v1.10 or earlier if you have mid-flight changes.
|
|
401
421
|
|
|
@@ -419,6 +439,24 @@ Use this when an agent needs more context than its current work packet allows.
|
|
|
419
439
|
|
|
420
440
|
---
|
|
421
441
|
|
|
442
|
+
### `cdd-kit context check <change-id>`
|
|
443
|
+
|
|
444
|
+
Preflight-checks repo-relative read paths against `context-manifest.md` before
|
|
445
|
+
you invoke an agent.
|
|
446
|
+
|
|
447
|
+
```bash
|
|
448
|
+
cdd-kit context check add-todos-ui --path src/components/Sidebar.vue src/stores/todos.js src/views/DashboardView.vue
|
|
449
|
+
cdd-kit context check add-ci-gate --path contracts/ci/ci-gate-contract.md .github/workflows/contract-driven-gates.yml
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
The check uses the same authorization model as `cdd-kit gate`: `## Allowed
|
|
453
|
+
Paths`, `## Approved Expansions`, repo-relative path rules, and the forbidden
|
|
454
|
+
baseline in `.cdd/context-policy.json`. If the command fails and the read is
|
|
455
|
+
legitimate, update the manifest or record/approve a Context Expansion Request
|
|
456
|
+
before the agent reads the file.
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
422
460
|
### `cdd-kit context approve <change-id> <request-id>`
|
|
423
461
|
|
|
424
462
|
Approves a pending Context Expansion Request in `context-manifest.md` and adds its `requested_paths` to `## Approved Expansions`.
|
|
@@ -33,6 +33,7 @@ This repository follows the Contract-Driven Delivery workflow.
|
|
|
33
33
|
| `cdd-kit list` | show all active changes and their status |
|
|
34
34
|
| `cdd-kit gate <id>` | verify a change is gate-ready (run before PR) |
|
|
35
35
|
| `cdd-kit gate <id> --strict` | full gate with pending-task enforcement (pre-commit default) |
|
|
36
|
+
| `cdd-kit context check <id> --path <paths...>` | preflight expected agent reads against `context-manifest.md` before invoking the agent |
|
|
36
37
|
| `cdd-kit archive <id>` | physically move a completed change to `specs/archive/<year>/` |
|
|
37
38
|
| `cdd-kit abandon <id> --reason <text>` | mark a change as abandoned; preserves directory for git history |
|
|
38
39
|
| `cdd-kit migrate <id> \| --all` | upgrade pre-v1.11 change directories to new format (frontmatter + tier format) |
|
|
@@ -46,7 +47,22 @@ Run `cdd-kit detect-stack` to verify the detected tech stack.
|
|
|
46
47
|
For context-governed changes, read `specs/changes/<change-id>/context-manifest.md` before using file-reading or broad search tools.
|
|
47
48
|
|
|
48
49
|
- Read only paths allowed by the manifest or approved expansions.
|
|
50
|
+
- Before invoking an agent with known concrete reads, run
|
|
51
|
+
`cdd-kit context check <change-id> --path <paths...>`. If it fails and the
|
|
52
|
+
reads are legitimate, expand `Allowed Paths` or approve a Context Expansion
|
|
53
|
+
Request before the agent reads the files.
|
|
49
54
|
- If more context is needed, stop and write a Context Expansion Request in the manifest (`cdd-kit context request`).
|
|
50
55
|
- The full agent-log format (including `files-read:` schema) is defined in
|
|
51
56
|
`~/.claude/skills/contract-driven-delivery/references/agent-log-protocol.md`.
|
|
52
57
|
Read that once; do not paraphrase it elsewhere.
|
|
58
|
+
|
|
59
|
+
## CDD Operational Notes
|
|
60
|
+
|
|
61
|
+
- After each agent returns, verify its agent-log exists, tick the related
|
|
62
|
+
`tasks.yml` items immediately, and only then move to the next agent.
|
|
63
|
+
- Pre-existing test failures may be excluded from the current gate only when
|
|
64
|
+
`qa-report.md` records the failing test, baseline evidence, why it is outside
|
|
65
|
+
scope, owner, and follow-up.
|
|
66
|
+
- For MySQL migrations, treat ENUM contraction and any DDL requiring
|
|
67
|
+
`ALGORITHM=COPY` as high risk on large tables; require row-count/runtime
|
|
68
|
+
estimate, online migration or maintenance window, and rollback plan.
|
package/assets/CODEX.template.md
CHANGED
|
@@ -16,6 +16,10 @@ This project uses Contract-Driven Delivery (CDD).
|
|
|
16
16
|
Read `specs/changes/<change-id>/context-manifest.md` before using file-reading or search tools.
|
|
17
17
|
|
|
18
18
|
- Read only paths allowed by the manifest or approved expansions.
|
|
19
|
+
- Before invoking an agent with known concrete reads, run
|
|
20
|
+
`cdd-kit context check <change-id> --path <paths...>`. If it fails and the
|
|
21
|
+
reads are legitimate, expand `Allowed Paths` or approve a Context Expansion
|
|
22
|
+
Request before the agent reads the files.
|
|
19
23
|
- Do not use broad repository search unless the manifest authorizes it.
|
|
20
24
|
- If more context is needed, stop and write a Context Expansion Request in the manifest.
|
|
21
25
|
- Record every file read through tools in the relevant `agent-log/*.yml` under `files-read:`.
|
|
@@ -37,3 +41,14 @@ Every entry must be a repo-relative path. Do not omit files, use absolute paths,
|
|
|
37
41
|
- Cold: `specs/archive/`.
|
|
38
42
|
|
|
39
43
|
Cold historical data is evidence, not current requirements.
|
|
44
|
+
|
|
45
|
+
## Operational Notes
|
|
46
|
+
|
|
47
|
+
- After each agent returns, verify its agent-log exists, tick the related
|
|
48
|
+
`tasks.yml` items immediately, and only then move to the next agent.
|
|
49
|
+
- Pre-existing test failures may be excluded from the current gate only when
|
|
50
|
+
`qa-report.md` records the failing test, baseline evidence, why it is outside
|
|
51
|
+
scope, owner, and follow-up.
|
|
52
|
+
- For MySQL migrations, treat ENUM contraction and any DDL requiring
|
|
53
|
+
`ALGORITHM=COPY` as high risk on large tables; require row-count/runtime
|
|
54
|
+
estimate, online migration or maintenance window, and rollback plan.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: backend-engineer
|
|
3
3
|
description: Implement backend changes only after specs, contracts, tests, and CI gates are defined; maintain thin controllers, service boundaries, validation, and error handling.
|
|
4
4
|
tools: Read, Grep, Glob, Edit, MultiEdit, Bash
|
|
5
|
-
model:
|
|
5
|
+
model: sonnet
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the backend engineer.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: change-classifier
|
|
3
3
|
description: Classify incoming requests into change types and decide required artifacts, contracts, tests, and review gates before implementation.
|
|
4
4
|
tools: Read, Grep, Glob
|
|
5
|
-
model:
|
|
5
|
+
model: opus
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the change classifier for Contract-Driven Delivery.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: ci-cd-gatekeeper
|
|
3
3
|
description: Enforce CI/CD as a required delivery artifact; design and implement required, informational, nightly, weekly, and manual gates with promotion policy.
|
|
4
4
|
tools: Read, Grep, Glob, Edit, MultiEdit, Bash
|
|
5
|
-
model:
|
|
5
|
+
model: sonnet
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the CI/CD gatekeeper.
|
|
@@ -61,6 +61,14 @@ mergeable / blocked / informational-risk
|
|
|
61
61
|
Source of truth: `specs/changes/<change-id>/context-manifest.md` → `## Allowed Paths`.
|
|
62
62
|
Read it first (your prompt header has `CURRENT_CHANGE_ID`). Read only paths it lists or paths under `## Approved Expansions`. `cdd-kit gate` validates `files-read:` against this list and rejects unauthorized paths.
|
|
63
63
|
|
|
64
|
+
This agent commonly needs CI contracts and workflow definitions, for example
|
|
65
|
+
`contracts/ci/ci-gate-contract.md`, `ci/`, `ci-templates/`,
|
|
66
|
+
`github-workflows/`, or project `.github/workflows/`. Those paths must appear
|
|
67
|
+
in the manifest before you read them; if they are legitimate scope, expand the
|
|
68
|
+
manifest rather than omitting them from `files-read`.
|
|
69
|
+
When concrete paths are known, run `cdd-kit context check <change-id> --path ...`
|
|
70
|
+
before reading them.
|
|
71
|
+
|
|
64
72
|
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>`.
|
|
65
73
|
|
|
66
74
|
Forbidden by default (enforced by `.cdd/context-policy.json`): `specs/archive/`, sibling `specs/changes/*`, `assets/`, `node_modules/`, `dist/`, `build/`, `.git/`, `.claude/worktrees/`.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: contract-reviewer
|
|
3
3
|
description: Review and maintain API, CSS/UI, env, data-shape, business-rule, and CI/CD contracts for every change. Dependency and migration contracts are recorded here at contract level only; the active audit lives in dependency-security-reviewer.
|
|
4
4
|
tools: Read, Grep, Glob
|
|
5
|
-
model:
|
|
5
|
+
model: sonnet
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the contract reviewer.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: dependency-security-reviewer
|
|
3
3
|
description: Reviews dependency CVE risk, license compliance (GPL/AGPL copyleft vs proprietary), lockfile changes, and database migrations whenever lockfiles, dependency manifests, or database migrations are touched.
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
|
-
model:
|
|
5
|
+
model: sonnet
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the dependency and migration safety reviewer.
|
|
@@ -25,6 +25,10 @@ For any change that adds, removes, or upgrades a package:
|
|
|
25
25
|
For any change that adds or modifies a database migration:
|
|
26
26
|
|
|
27
27
|
- Verify the migration can run without a full-table exclusive lock on large tables (prefer `ADD COLUMN ... DEFAULT NULL`, online DDL, or batched backfills).
|
|
28
|
+
- For MySQL, treat ENUM contraction, column type changes, and any DDL requiring
|
|
29
|
+
`ALGORITHM=COPY` as high risk because it rewrites the table. For tables above
|
|
30
|
+
500k rows, block unless there is an explicit online migration, maintenance
|
|
31
|
+
window, rollback path, and row-count/runtime estimate.
|
|
28
32
|
- Verify a rollback path exists: either a `down` migration or an explicit documented rollback procedure.
|
|
29
33
|
- Verify backfill operations are safe under concurrent writes (idempotent, does not corrupt existing rows).
|
|
30
34
|
- Flag irreversible operations (column drops, type coercions, constraint additions on large tables) as high-risk.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: e2e-resilience-engineer
|
|
3
3
|
description: Design and implement E2E, browser-behavior, failure-injection, data-boundary, and resilience tests for production-like user journeys.
|
|
4
4
|
tools: Read, Grep, Glob, Edit, MultiEdit, Bash
|
|
5
|
-
model:
|
|
5
|
+
model: sonnet
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the E2E and resilience engineer.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: frontend-engineer
|
|
3
3
|
description: Implement frontend changes under API, CSS, UI/UX, accessibility, E2E, and visual review contracts.
|
|
4
4
|
tools: Read, Grep, Glob, Edit, MultiEdit, Bash
|
|
5
|
-
model:
|
|
5
|
+
model: sonnet
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the frontend engineer.
|
|
@@ -51,6 +51,13 @@ See `references/code-map-protocol.md` for the full protocol.
|
|
|
51
51
|
Source of truth: `specs/changes/<change-id>/context-manifest.md` → `## Allowed Paths`.
|
|
52
52
|
Read it first (your prompt header has `CURRENT_CHANGE_ID`). Read only paths it lists or paths under `## Approved Expansions`. `cdd-kit gate` validates `files-read:` against this list and rejects unauthorized paths.
|
|
53
53
|
|
|
54
|
+
This agent commonly needs exact component, store, route, and view files (for
|
|
55
|
+
example `src/components/...`, `src/stores/...`, `src/views/...`). Those paths
|
|
56
|
+
must appear in the manifest before you read them; if they are legitimate scope,
|
|
57
|
+
expand the manifest rather than omitting them from `files-read`.
|
|
58
|
+
When concrete paths are known, run `cdd-kit context check <change-id> --path ...`
|
|
59
|
+
before reading them.
|
|
60
|
+
|
|
54
61
|
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>`.
|
|
55
62
|
|
|
56
63
|
Forbidden by default (enforced by `.cdd/context-policy.json`): `specs/archive/`, sibling `specs/changes/*`, `assets/`, `node_modules/`, `dist/`, `build/`, `.git/`, `.claude/worktrees/`.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: monkey-test-engineer
|
|
3
3
|
description: Design preventive specs and structured exploratory tests for invalid user operations, adversarial inputs, malformed data, rapid UI actions, and production misuse. Not random fuzzing -- every monkey scenario is mapped to a known failure mode or hardening goal.
|
|
4
4
|
tools: Read, Grep, Glob, Edit, MultiEdit, Bash
|
|
5
|
-
model:
|
|
5
|
+
model: sonnet
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the monkey operation engineer.
|
|
@@ -29,6 +29,12 @@ Before implementation, ensure the spec says what should happen for:
|
|
|
29
29
|
|
|
30
30
|
Use fuzz payloads, Playwright action sequences, property-based tests, and targeted randomization where useful. Every monkey test must assert a safe outcome, not merely that the app does not crash.
|
|
31
31
|
|
|
32
|
+
If an existing monkey/fuzz test already fails before your change, do not hide
|
|
33
|
+
or rewrite that failure to make the current gate look green. Record the test
|
|
34
|
+
id, seed/input, baseline commit or prior evidence, and whether this change
|
|
35
|
+
touched the failing surface. Mark it as a follow-up when it is outside this
|
|
36
|
+
change's scope; keep new or regressed failures blocking.
|
|
37
|
+
|
|
32
38
|
## Tools
|
|
33
39
|
|
|
34
40
|
- Property-based — fast-check (JS/TS), hypothesis (Python), proptest (Rust) for state machine invariants.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: qa-reviewer
|
|
3
3
|
description: Execute quality gates, verify evidence, route failures back to the correct agent, and decide release readiness.
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
|
-
model:
|
|
5
|
+
model: opus
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the QA reviewer.
|
|
@@ -46,6 +46,10 @@ Invoke `spec-drift-auditor` at the following points (do not wait for issues to s
|
|
|
46
46
|
- `approved-with-risk` — only when (a) the residual risk is documented in qa-report.md, (b) an owner is assigned, (c) a follow-up issue exists with a date.
|
|
47
47
|
- `blocked` — any required gate failing, any contract claim unverified, any UI change without visual evidence.
|
|
48
48
|
- Sign-off — single reviewer for low/medium risk; two reviewers (qa-reviewer + spec-architect) for high/critical.
|
|
49
|
+
- Pre-existing failures may be excluded from this change's gate only when the
|
|
50
|
+
report includes the failing test id, baseline commit or prior evidence,
|
|
51
|
+
reason it is outside the current scope, owner, and follow-up date. Without
|
|
52
|
+
that record, treat the failure as blocking.
|
|
49
53
|
|
|
50
54
|
## Output
|
|
51
55
|
|
|
@@ -61,6 +65,10 @@ Invoke `spec-drift-auditor` at the following points (do not wait for issues to s
|
|
|
61
65
|
## Failures
|
|
62
66
|
...
|
|
63
67
|
|
|
68
|
+
## Pre-existing Failures Excluded From This Gate
|
|
69
|
+
| failure/test | baseline evidence | why outside scope | owner/follow-up |
|
|
70
|
+
|---|---|---|---|
|
|
71
|
+
|
|
64
72
|
## Fixback Routing
|
|
65
73
|
...
|
|
66
74
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: repo-context-scanner
|
|
3
3
|
description: Scan a repository and summarize its project profile, commands, contracts, tests, CI/CD, and missing standardization surfaces.
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
|
-
model:
|
|
5
|
+
model: haiku
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the repository context scanner.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: spec-architect
|
|
3
3
|
description: Evaluate architectural impact, compatibility, data flow, module boundaries, and whether a change requires ADR-like design decisions. Author ADRs when required.
|
|
4
4
|
tools: Read, Grep, Glob, Edit, MultiEdit
|
|
5
|
-
model:
|
|
5
|
+
model: opus
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the architecture reviewer.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: spec-drift-auditor
|
|
3
3
|
description: Audit drift between live contracts, implementation code, tests, and CI gates. Does NOT read historical specs/changes — contracts/ is the single source of truth.
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
|
-
model:
|
|
5
|
+
model: opus
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the spec drift auditor.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: stress-soak-engineer
|
|
3
3
|
description: Design stress, load, soak, and long-running stability tests for reporting systems, queues, caches, auto-refresh, and data-heavy features.
|
|
4
4
|
tools: Read, Grep, Glob, Edit, MultiEdit, Bash
|
|
5
|
-
model:
|
|
5
|
+
model: sonnet
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the stress and soak engineer.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: test-strategist
|
|
3
3
|
description: Convert specs and acceptance criteria into TDD-oriented test plans covering unit, contract, integration, E2E, resilience, monkey, stress, and soak tests.
|
|
4
4
|
tools: Read, Grep, Glob, Edit, Write
|
|
5
|
-
model:
|
|
5
|
+
model: sonnet
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the test strategist.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: ui-ux-reviewer
|
|
3
3
|
description: Review interaction design, information hierarchy, copy, accessibility, empty/error/loading state semantics, and user journey quality. Does not cover pixel-level visuals or CSS -- those go to visual-reviewer.
|
|
4
4
|
tools: Read, Grep, Glob
|
|
5
|
-
model:
|
|
5
|
+
model: sonnet
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the UI/UX reviewer.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: visual-reviewer
|
|
3
3
|
description: Review pixel-level visual output, layout, responsive viewport behavior, screenshot diffs, CSS contract compliance, and component visual state coverage. Does not cover interaction or copy -- those go to ui-ux-reviewer.
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
|
-
model:
|
|
5
|
+
model: haiku
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the visual reviewer.
|
|
@@ -3,22 +3,22 @@
|
|
|
3
3
|
"generated_at": null,
|
|
4
4
|
"schema-version": "0.2.0",
|
|
5
5
|
"roles": {
|
|
6
|
-
"change-classifier": "
|
|
7
|
-
"spec-architect": "
|
|
8
|
-
"qa-reviewer": "
|
|
9
|
-
"contract-reviewer": "
|
|
10
|
-
"test-strategist": "
|
|
11
|
-
"backend-engineer": "
|
|
12
|
-
"frontend-engineer": "
|
|
13
|
-
"ci-cd-gatekeeper": "
|
|
14
|
-
"e2e-resilience-engineer": "
|
|
15
|
-
"monkey-test-engineer": "
|
|
16
|
-
"stress-soak-engineer": "
|
|
17
|
-
"ui-ux-reviewer": "
|
|
18
|
-
"visual-reviewer": "
|
|
19
|
-
"dependency-security-reviewer": "
|
|
20
|
-
"spec-drift-auditor": "
|
|
21
|
-
"repo-context-scanner": "
|
|
6
|
+
"change-classifier": "opus",
|
|
7
|
+
"spec-architect": "opus",
|
|
8
|
+
"qa-reviewer": "opus",
|
|
9
|
+
"contract-reviewer": "sonnet",
|
|
10
|
+
"test-strategist": "sonnet",
|
|
11
|
+
"backend-engineer": "sonnet",
|
|
12
|
+
"frontend-engineer": "sonnet",
|
|
13
|
+
"ci-cd-gatekeeper": "sonnet",
|
|
14
|
+
"e2e-resilience-engineer": "sonnet",
|
|
15
|
+
"monkey-test-engineer": "sonnet",
|
|
16
|
+
"stress-soak-engineer": "sonnet",
|
|
17
|
+
"ui-ux-reviewer": "sonnet",
|
|
18
|
+
"visual-reviewer": "haiku",
|
|
19
|
+
"dependency-security-reviewer": "sonnet",
|
|
20
|
+
"spec-drift-auditor": "opus",
|
|
21
|
+
"repo-context-scanner": "haiku"
|
|
22
22
|
},
|
|
23
|
-
"_notes": "Roles map agent name -> model
|
|
23
|
+
"_notes": "Roles map agent name -> model class (opus, sonnet, haiku), not provider release IDs. Provider adapters may map these classes to concrete Claude or Codex model names. Override per-project as needed. cdd-kit doctor warns when an installed agent's frontmatter `model:` does not match this policy."
|
|
24
24
|
}
|
|
@@ -106,7 +106,7 @@ Note: `archive.md` is created during `/cdd-close`, not during `/cdd-new` — it
|
|
|
106
106
|
|
|
107
107
|
If the classifier marks an artifact as `no` or leaves it blank, **do not create the file** — even if a review agent could contribute to it.
|
|
108
108
|
|
|
109
|
-
The
|
|
109
|
+
The 6 always-required artifacts are: `change-request.md`, `change-classification.md`, `test-plan.md`, `ci-gates.md`, `tasks.yml`, and `context-manifest.md`.
|
|
110
110
|
|
|
111
111
|
## Step 1: Generate change-id, scaffold, and scan context
|
|
112
112
|
|
|
@@ -122,17 +122,19 @@ Create the scaffold with the CLI so every provider gets the same templates:
|
|
|
122
122
|
cdd-kit new <change-id>
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
```bash
|
|
128
|
-
cdd-kit context-scan
|
|
129
|
-
```
|
|
125
|
+
`cdd-kit new` auto-runs `cdd-kit context-scan` when `specs/context/` indexes are missing or stale. Do not run a second scan unless the command warned that context-scan failed, or you intentionally used `--skip-scan`.
|
|
130
126
|
|
|
131
127
|
Verify these files exist:
|
|
132
128
|
- `specs/changes/<change-id>/context-manifest.md`
|
|
133
129
|
- `specs/context/project-map.md`
|
|
134
130
|
- `specs/context/contracts-index.md`
|
|
135
131
|
|
|
132
|
+
If either context index is still missing, run:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
cdd-kit context-scan
|
|
136
|
+
```
|
|
137
|
+
|
|
136
138
|
Do not use broad search or ad hoc reads to classify the change before `context-scan` has completed.
|
|
137
139
|
|
|
138
140
|
The generated scaffold contains the artifacts listed in the table below. **All
|
|
@@ -166,7 +168,9 @@ Do not authorize the classifier to read `contracts/`, `src/`, `tests/`, or broad
|
|
|
166
168
|
|
|
167
169
|
The classifier must include a `## Context Manifest Draft` section with:
|
|
168
170
|
- affected surfaces
|
|
169
|
-
- allowed paths for each required agent work packet
|
|
171
|
+
- allowed paths for each required agent work packet; this must be the union of
|
|
172
|
+
every file/directory agents are expected to read, including component/store/view
|
|
173
|
+
files for frontend work and CI contracts/workflows for CI work
|
|
170
174
|
- required contracts
|
|
171
175
|
- required tests
|
|
172
176
|
- any context expansion requests that must be approved before implementation
|
|
@@ -235,6 +239,27 @@ Change directory: specs/changes/<change-id>/
|
|
|
235
239
|
```
|
|
236
240
|
This ensures the agent's Read scope restriction points to the correct directory.
|
|
237
241
|
|
|
242
|
+
Before invoking an agent, preflight any concrete paths you already expect that
|
|
243
|
+
agent to read:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
cdd-kit context check <change-id> --path <repo-relative path> [more paths...]
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
If the check fails and the paths are legitimate work scope, update
|
|
250
|
+
`context-manifest.md` `## Allowed Paths` or approve a Context Expansion Request
|
|
251
|
+
before the agent reads them. This catches common late gate failures such as UI
|
|
252
|
+
components/stores/views or CI workflow files missing from the manifest.
|
|
253
|
+
|
|
254
|
+
After every agent returns, complete the closeout before starting the next
|
|
255
|
+
agent:
|
|
256
|
+
- confirm its `agent-log/<agent>.yml` exists or write it for read-only agents
|
|
257
|
+
- confirm the log has a completed status (`complete`, `done`, or `approved`) or
|
|
258
|
+
halt on `blocked`
|
|
259
|
+
- tick the owned `tasks.yml` items immediately
|
|
260
|
+
- record incidental/pre-existing findings in the appropriate report instead of
|
|
261
|
+
silently fixing unrelated scope
|
|
262
|
+
|
|
238
263
|
### Agent stage badges (UI v1)
|
|
239
264
|
|
|
240
265
|
When you announce that you are about to invoke an agent, prefix the
|
|
@@ -263,9 +288,9 @@ the user; do not put them inside the prompt sent to the agent.
|
|
|
263
288
|
| Audit | `repo-context-scanner` | ⚫ `[repo-scan]` |
|
|
264
289
|
|
|
265
290
|
Color semantics:
|
|
266
|
-
- 🟣 purple: deciding what we will do (heavy model, opus
|
|
267
|
-
- 🔵 blue: writing code (sonnet
|
|
268
|
-
- 🟡 yellow: planning tests (sonnet
|
|
291
|
+
- 🟣 purple: deciding what we will do (heavy model, `opus`)
|
|
292
|
+
- 🔵 blue: writing code (`sonnet` implementation)
|
|
293
|
+
- 🟡 yellow: planning tests (`sonnet`)
|
|
269
294
|
- 🟠 orange: heavy testing — only appears for Tier 0–1, signals high-risk scope
|
|
270
295
|
- 🟢 green: reviewing what was done (no code writes; just verdicts)
|
|
271
296
|
- ⚫ neutral: audits and scans (read-only background work)
|
|
@@ -364,6 +389,13 @@ All agents from Tier 2–3, plus insert these after `frontend-engineer` / `backe
|
|
|
364
389
|
- Skip an agent only if the classifier explicitly marks its surface as "not affected"
|
|
365
390
|
- If backend-only with no UI: skip `frontend-engineer`, `ui-ux-reviewer`, `visual-reviewer`
|
|
366
391
|
- If UI-only with no backend: skip `backend-engineer`
|
|
392
|
+
- If a required or informational test has pre-existing failures unrelated to
|
|
393
|
+
this change, do not count them as this change's pass/fail result. Record the
|
|
394
|
+
failing test id, baseline commit or prior evidence, owner, and follow-up in
|
|
395
|
+
`qa-report.md`; QA may only approve this as `approved-with-risk`.
|
|
396
|
+
- If implementation uncovers unrelated old bugs, fix only those needed to meet
|
|
397
|
+
this change's acceptance criteria or to avoid a new safety/security risk.
|
|
398
|
+
Otherwise record them as follow-up with evidence and owner.
|
|
367
399
|
|
|
368
400
|
**Resuming from blocked**: After the user resolves the blocking issue, re-invoke the blocked agent (do not restart from Step 1). Continue with the remaining agents in their original order.
|
|
369
401
|
|
|
@@ -98,7 +98,7 @@ Read only paths allowed by the context manifest and approved expansions.
|
|
|
98
98
|
If more context is needed, stop and output a Context Expansion Request instead of reading outside the manifest.
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
Do NOT re-run agents that already have a `status: complete`
|
|
101
|
+
Do NOT re-run agents that already have a completed agent-log (`status: complete`, `done`, or `approved`).
|
|
102
102
|
|
|
103
103
|
Continue until all required agents are done, then run `cdd-kit gate <change-id>`.
|
|
104
104
|
|
|
@@ -106,7 +106,7 @@ Continue until all required agents are done, then run `cdd-kit gate <change-id>`
|
|
|
106
106
|
|
|
107
107
|
## Rules
|
|
108
108
|
|
|
109
|
-
- Never re-run an agent that already has `status: complete` in its agent-log
|
|
109
|
+
- Never re-run an agent that already has `status: complete`, `done`, or `approved` in its agent-log
|
|
110
110
|
- Never start from Step 1 of `/cdd-new` — only resume from the next pending agent
|
|
111
111
|
- Never use broad search to reconstruct state; resume from `tasks.yml`, `context-manifest.md`, and `agent-log/`
|
|
112
112
|
- Never continue past pending Context Expansion Requests
|
|
@@ -41,6 +41,11 @@ Use this skill to turn software requests into traceable, testable, CI/CD-gated c
|
|
|
41
41
|
- Each engineer must read the matching standard before authoring tests: e2e-resilience-engineer → references/e2e-standard.md, monkey-test-engineer → references/monkey-operation-standard.md, stress-soak-engineer → references/stress-soak-standard.md.
|
|
42
42
|
6. Implement through the right role.
|
|
43
43
|
- Backend/frontend work must follow contracts and tests.
|
|
44
|
+
- Before invoking an agent with known concrete read paths, run
|
|
45
|
+
`cdd-kit context check <change-id> --path <paths...>` and expand the
|
|
46
|
+
manifest before the agent reads legitimate missing paths.
|
|
47
|
+
- After each agent finishes, verify its agent-log exists and tick the
|
|
48
|
+
related `tasks.yml` items before starting the next agent.
|
|
44
49
|
- UI changes require UI/UX and visual review.
|
|
45
50
|
- Invoke ui-ux-reviewer for interaction, copy, accessibility, and information hierarchy review whenever UI changes.
|
|
46
51
|
- Invoke visual-reviewer for layout, responsive, CSS contract, and screenshot diff review whenever UI changes.
|
|
@@ -24,7 +24,7 @@ The file is pure YAML (no markdown wrapping, no checklist).
|
|
|
24
24
|
```yaml
|
|
25
25
|
change-id: <id>
|
|
26
26
|
agent: <agent-name>
|
|
27
|
-
timestamp: <ISO 8601
|
|
27
|
+
timestamp: "<ISO 8601 date-time, e.g. 2026-04-27T14:30:00Z>"
|
|
28
28
|
status: complete # complete | needs-review | blocked
|
|
29
29
|
files-read:
|
|
30
30
|
- <repo-relative path>
|
|
@@ -42,8 +42,8 @@ notes: <optional free-form>
|
|
|
42
42
|
|---|---|---|
|
|
43
43
|
| `change-id` | yes | must equal the parent change directory name |
|
|
44
44
|
| `agent` | yes | canonical agent name (matches the agent's filename) |
|
|
45
|
-
| `timestamp` | yes | ISO 8601
|
|
46
|
-
| `status` | yes |
|
|
45
|
+
| `timestamp` | yes | ISO 8601 date-time string; quote it to avoid YAML timestamp coercion in non-cdd tools. UTC `Z` is preferred; numeric offsets such as `+08:00` are accepted. |
|
|
46
|
+
| `status` | yes | canonical values are `complete` \| `needs-review` \| `blocked`; `done` and `approved` are accepted by gate as compatibility aliases for `complete` |
|
|
47
47
|
| `files-read` | conditional | required for context-governed changes (see below) |
|
|
48
48
|
| `artifacts` | yes | array of `{type, pointer}` objects, ≥ 1 item |
|
|
49
49
|
| `next-action` | yes | when `status: blocked`, ≥ 10 chars and not `none` |
|
|
@@ -60,6 +60,12 @@ files-read:
|
|
|
60
60
|
- specs/changes/<change-id>/
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
+
If `cdd-kit gate` reports `read unauthorized path`, do not delete that
|
|
64
|
+
`files-read` entry to silence the gate. If the read was legitimate work scope,
|
|
65
|
+
add the repo-relative path to `context-manifest.md` under `## Allowed Paths` or
|
|
66
|
+
approve a Context Expansion Request. `files-read` is the audit trail; the
|
|
67
|
+
manifest is the authorization boundary.
|
|
68
|
+
|
|
63
69
|
#### `artifacts`
|
|
64
70
|
|
|
65
71
|
Concrete pointers only. Allowed forms:
|
|
@@ -77,12 +83,27 @@ When `status: blocked`, this must be ≥ 10 chars, must not be `none`, `tbd`,
|
|
|
77
83
|
`investigate further`, or `n/a`, and must name the actual next step a human
|
|
78
84
|
can act on. When `status: complete`, `none` is acceptable.
|
|
79
85
|
|
|
86
|
+
#### `status`
|
|
87
|
+
|
|
88
|
+
Use `status: complete` for a finished agent-log. `tasks.yml` task entries use
|
|
89
|
+
`status: done`, and review language may say "approved", but agent-log
|
|
90
|
+
completion is canonically `complete`. `cdd-kit gate` accepts `done` and
|
|
91
|
+
`approved` as compatibility aliases so these common mix-ups do not block
|
|
92
|
+
delivery.
|
|
93
|
+
|
|
80
94
|
## Per-agent additional artifact requirements
|
|
81
95
|
|
|
82
96
|
Each agent prompt lists its own `### Required artifacts for this agent`. The
|
|
83
|
-
gate
|
|
84
|
-
|
|
85
|
-
agent
|
|
97
|
+
gate enforces the declared artifact `type` values when the corresponding agent
|
|
98
|
+
prompt file is installed in `.claude/agents/` or `~/.claude/agents/`. This keeps
|
|
99
|
+
agent prompts, evidence logs, and gate behavior aligned without duplicating the
|
|
100
|
+
full protocol in every prompt.
|
|
101
|
+
|
|
102
|
+
If you add a required artifact type in an agent prompt, also update tests that
|
|
103
|
+
exercise `cdd-kit gate` for that agent. Agents may emit
|
|
104
|
+
`pointer: "n/a (<reason>)"` when a declared type is genuinely inapplicable; the
|
|
105
|
+
type must still be present so reviewers can tell that the omission was
|
|
106
|
+
intentional.
|
|
86
107
|
|
|
87
108
|
## Self-validation before submitting your response
|
|
88
109
|
|
|
@@ -97,8 +118,13 @@ verify each item:
|
|
|
97
118
|
- [ ] **All required keys exist**: `change-id`, `agent`, `timestamp`,
|
|
98
119
|
`status`, `artifacts`, `next-action` (plus `files-read` for
|
|
99
120
|
context-governed changes).
|
|
100
|
-
- [ ] **`
|
|
101
|
-
|
|
121
|
+
- [ ] **`timestamp` is quoted** and uses ISO 8601 date-time form. Prefer
|
|
122
|
+
UTC `Z`, e.g. `timestamp: "2026-04-27T14:30:00Z"`. Numeric offsets
|
|
123
|
+
such as `timestamp: "2026-05-05T00:00:00+08:00"` are valid.
|
|
124
|
+
- [ ] **`status` is one of**: `complete`, `needs-review`, `blocked`.
|
|
125
|
+
Prefer `complete` for finished logs; `done` and `approved` are accepted
|
|
126
|
+
only as compatibility aliases. Do not use `OK`, `pending`, `wip`, or
|
|
127
|
+
anything else.
|
|
102
128
|
- [ ] **Every `artifacts` item is a `{type, pointer}` mapping** with a
|
|
103
129
|
concrete pointer:
|
|
104
130
|
- GOOD: `{ type: tests-added, pointer: "tests/foo.test.ts::should reject empty body" }`
|
|
@@ -130,9 +156,11 @@ ship a known-bad log and rely on the gate to catch it.
|
|
|
130
156
|
3. `status` is missing or has an unknown value.
|
|
131
157
|
4. `status: blocked` without a concrete `next-action`.
|
|
132
158
|
5. `files-read` is missing for a context-governed change, or contains an
|
|
133
|
-
absolute path / `..` segment / forbidden path
|
|
159
|
+
absolute path / `..` segment / forbidden path / path outside manifest
|
|
160
|
+
`Allowed Paths` and `Approved Expansions`.
|
|
134
161
|
6. Any `artifacts` item is missing `type` or `pointer`, or the array is empty.
|
|
135
|
-
7.
|
|
162
|
+
7. A required per-agent artifact `type` declared in the agent prompt is missing.
|
|
163
|
+
8. With `--strict`: any `artifacts` pointer that looks like a path but does
|
|
136
164
|
not exist on disk; or any runtime-logged read not declared in `files-read`.
|
|
137
165
|
|
|
138
166
|
## Why this lives in references/
|
|
@@ -75,7 +75,9 @@ Always required: change-request.md, change-classification.md, test-plan.md, ci-g
|
|
|
75
75
|
-
|
|
76
76
|
|
|
77
77
|
### Allowed Paths
|
|
78
|
-
<!-- Union of ALL paths any agent will read. Add change-specific paths below the defaults.
|
|
78
|
+
<!-- Union of ALL paths any agent will read. Add change-specific paths below the defaults.
|
|
79
|
+
Include component/store/view files for frontend work and CI contracts/workflows for CI work
|
|
80
|
+
when those files are legitimate work scope. Gate compares agent-log files-read against this list. -->
|
|
79
81
|
- specs/changes/<change-id>/
|
|
80
82
|
- specs/context/project-map.md
|
|
81
83
|
- specs/context/contracts-index.md
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
|
|
19
19
|
## Known Risks
|
|
20
20
|
|
|
21
|
+
## Pre-existing Failures Excluded From This Gate
|
|
22
|
+
| failure/test | baseline evidence | why outside scope | owner/follow-up |
|
|
23
|
+
|---|---|---|---|
|
|
24
|
+
|
|
21
25
|
## Failures and Fixback Routing
|
|
22
26
|
| failure | evidence | owner | required fix |
|
|
23
27
|
|---|---|---|---|
|
|
@@ -10,6 +10,8 @@ and is automatically applied by `cdd-kit gate` — do not duplicate it here.
|
|
|
10
10
|
## Allowed Paths
|
|
11
11
|
<!-- UNION of all repo-relative paths (or globs) any agent may read for this change.
|
|
12
12
|
cdd-kit gate validates every agent's files-read log against this list.
|
|
13
|
+
If an agent legitimately read a path, add that path here; do not remove it
|
|
14
|
+
from files-read just to pass gate.
|
|
13
15
|
Be specific — wide globs (e.g. src/) defeat read-scope governance.
|
|
14
16
|
Always include the three defaults below; add change-specific paths beneath them. -->
|
|
15
17
|
- specs/changes/<change-id>/
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
|
|
19
19
|
## Known Risks
|
|
20
20
|
|
|
21
|
+
## Pre-existing Failures Excluded From This Gate
|
|
22
|
+
| failure/test | baseline evidence | why outside scope | owner/follow-up |
|
|
23
|
+
|---|---|---|---|
|
|
24
|
+
|
|
21
25
|
## Failures and Fixback Routing
|
|
22
26
|
| failure | evidence | owner | required fix |
|
|
23
27
|
|---|---|---|---|
|
package/dist/cli/index.js
CHANGED
|
@@ -9881,22 +9881,22 @@ async function attemptAutoFixes(cwd, report) {
|
|
|
9881
9881
|
const merged = {
|
|
9882
9882
|
...existing,
|
|
9883
9883
|
roles: {
|
|
9884
|
-
"change-classifier": "
|
|
9885
|
-
"spec-architect": "
|
|
9886
|
-
"qa-reviewer": "
|
|
9887
|
-
"contract-reviewer": "
|
|
9888
|
-
"test-strategist": "
|
|
9889
|
-
"backend-engineer": "
|
|
9890
|
-
"frontend-engineer": "
|
|
9891
|
-
"ci-cd-gatekeeper": "
|
|
9892
|
-
"e2e-resilience-engineer": "
|
|
9893
|
-
"monkey-test-engineer": "
|
|
9894
|
-
"stress-soak-engineer": "
|
|
9895
|
-
"ui-ux-reviewer": "
|
|
9896
|
-
"visual-reviewer": "
|
|
9897
|
-
"dependency-security-reviewer": "
|
|
9898
|
-
"spec-drift-auditor": "
|
|
9899
|
-
"repo-context-scanner": "
|
|
9884
|
+
"change-classifier": "opus",
|
|
9885
|
+
"spec-architect": "opus",
|
|
9886
|
+
"qa-reviewer": "opus",
|
|
9887
|
+
"contract-reviewer": "sonnet",
|
|
9888
|
+
"test-strategist": "sonnet",
|
|
9889
|
+
"backend-engineer": "sonnet",
|
|
9890
|
+
"frontend-engineer": "sonnet",
|
|
9891
|
+
"ci-cd-gatekeeper": "sonnet",
|
|
9892
|
+
"e2e-resilience-engineer": "sonnet",
|
|
9893
|
+
"monkey-test-engineer": "sonnet",
|
|
9894
|
+
"stress-soak-engineer": "sonnet",
|
|
9895
|
+
"ui-ux-reviewer": "sonnet",
|
|
9896
|
+
"visual-reviewer": "haiku",
|
|
9897
|
+
"dependency-security-reviewer": "sonnet",
|
|
9898
|
+
"spec-drift-auditor": "opus",
|
|
9899
|
+
"repo-context-scanner": "haiku"
|
|
9900
9900
|
}
|
|
9901
9901
|
};
|
|
9902
9902
|
const { writeFileSync: writeFileSync14 } = await import("fs");
|
|
@@ -10321,6 +10321,7 @@ var context_exports = {};
|
|
|
10321
10321
|
__export(context_exports, {
|
|
10322
10322
|
approveAllPending: () => approveAllPending,
|
|
10323
10323
|
approveContextExpansion: () => approveContextExpansion,
|
|
10324
|
+
checkContextPaths: () => checkContextPaths,
|
|
10324
10325
|
listContextExpansions: () => listContextExpansions,
|
|
10325
10326
|
rejectAllPending: () => rejectAllPending,
|
|
10326
10327
|
rejectContextExpansion: () => rejectContextExpansion,
|
|
@@ -10328,6 +10329,7 @@ __export(context_exports, {
|
|
|
10328
10329
|
});
|
|
10329
10330
|
import { existsSync as existsSync22, readFileSync as readFileSync26, writeFileSync as writeFileSync13 } from "fs";
|
|
10330
10331
|
import { join as join26 } from "path";
|
|
10332
|
+
import picomatch3 from "picomatch";
|
|
10331
10333
|
function normalizePath(path) {
|
|
10332
10334
|
return path.replace(/\\/g, "/").replace(/^\.\//, "").trim();
|
|
10333
10335
|
}
|
|
@@ -10356,9 +10358,57 @@ function writeManifest(changeId, content) {
|
|
|
10356
10358
|
`, "utf8");
|
|
10357
10359
|
}
|
|
10358
10360
|
function sectionBody(content, heading) {
|
|
10359
|
-
const match = content.match(new RegExp(`## ${heading}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`));
|
|
10361
|
+
const match = stripHtmlComments2(content).match(new RegExp(`## ${heading}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`));
|
|
10360
10362
|
return match?.[1] ?? "";
|
|
10361
10363
|
}
|
|
10364
|
+
function stripHtmlComments2(text) {
|
|
10365
|
+
return text.replace(/<!--[\s\S]*?-->/g, "");
|
|
10366
|
+
}
|
|
10367
|
+
function parseListSection2(content, heading) {
|
|
10368
|
+
return sectionBody(content, heading).split(/\r?\n/).map((line) => line.replace(/^\s*-\s*/, "").trim()).filter((item) => item && item !== "-" && item.toLowerCase() !== "none").map(normalizePath);
|
|
10369
|
+
}
|
|
10370
|
+
function pathMatches2(relPath, patterns, currentChangeId) {
|
|
10371
|
+
const normalized = normalizePath(relPath);
|
|
10372
|
+
return patterns.some((rawPattern) => {
|
|
10373
|
+
const pattern = normalizePath(rawPattern).replace(/\/+$/, "");
|
|
10374
|
+
if (!pattern)
|
|
10375
|
+
return false;
|
|
10376
|
+
if (pattern === "specs/changes/*" && currentChangeId) {
|
|
10377
|
+
const current = `specs/changes/${currentChangeId}`;
|
|
10378
|
+
if (normalized === current || normalized.startsWith(`${current}/`))
|
|
10379
|
+
return false;
|
|
10380
|
+
return normalized.startsWith("specs/changes/");
|
|
10381
|
+
}
|
|
10382
|
+
if (/[*?[{]/.test(pattern)) {
|
|
10383
|
+
if (picomatch3.isMatch(normalized, pattern, { dot: true, nocase: false }))
|
|
10384
|
+
return true;
|
|
10385
|
+
if (pattern.endsWith("/**")) {
|
|
10386
|
+
const base = pattern.slice(0, -3);
|
|
10387
|
+
if (normalized === base)
|
|
10388
|
+
return true;
|
|
10389
|
+
}
|
|
10390
|
+
return false;
|
|
10391
|
+
}
|
|
10392
|
+
return normalized === pattern || normalized.startsWith(`${pattern}/`);
|
|
10393
|
+
});
|
|
10394
|
+
}
|
|
10395
|
+
function loadContextPolicy2() {
|
|
10396
|
+
const policyPath = join26(process.cwd(), ".cdd", "context-policy.json");
|
|
10397
|
+
if (!existsSync22(policyPath))
|
|
10398
|
+
return { forbiddenPaths: DEFAULT_FORBIDDEN_PATHS };
|
|
10399
|
+
try {
|
|
10400
|
+
const custom = JSON.parse(readFileSync26(policyPath, "utf8"));
|
|
10401
|
+
return {
|
|
10402
|
+
forbiddenPaths: Array.from(/* @__PURE__ */ new Set([
|
|
10403
|
+
...DEFAULT_FORBIDDEN_PATHS,
|
|
10404
|
+
...custom.forbiddenPaths ?? []
|
|
10405
|
+
]))
|
|
10406
|
+
};
|
|
10407
|
+
} catch {
|
|
10408
|
+
log.warn("could not parse .cdd/context-policy.json; using default context policy");
|
|
10409
|
+
return { forbiddenPaths: DEFAULT_FORBIDDEN_PATHS };
|
|
10410
|
+
}
|
|
10411
|
+
}
|
|
10362
10412
|
function parseRequests(content) {
|
|
10363
10413
|
const body = sectionBody(content, "Context Expansion Requests");
|
|
10364
10414
|
if (!body.trim())
|
|
@@ -10496,6 +10546,47 @@ async function listContextExpansions(changeId, json = false) {
|
|
|
10496
10546
|
log.dim(` ${path}`);
|
|
10497
10547
|
}
|
|
10498
10548
|
}
|
|
10549
|
+
async function checkContextPaths(changeId, paths, json = false) {
|
|
10550
|
+
if (paths.length === 0) {
|
|
10551
|
+
log.error("at least one --path value is required");
|
|
10552
|
+
process.exit(1);
|
|
10553
|
+
}
|
|
10554
|
+
const content = readManifest(changeId);
|
|
10555
|
+
const allowedPaths = parseListSection2(content, "Allowed Paths");
|
|
10556
|
+
const approvedExpansions = parseListSection2(content, "Approved Expansions");
|
|
10557
|
+
const policy = loadContextPolicy2();
|
|
10558
|
+
const normalizedPaths = [...new Set(paths.map(normalizePath).filter(Boolean))];
|
|
10559
|
+
const results = normalizedPaths.map((path) => {
|
|
10560
|
+
const validationError = validateRepoRelativePath(path);
|
|
10561
|
+
const forbidden = !validationError && pathMatches2(path, policy.forbiddenPaths, changeId);
|
|
10562
|
+
const authorized = !validationError && !forbidden && (pathMatches2(path, allowedPaths) || pathMatches2(path, approvedExpansions));
|
|
10563
|
+
let reason = "authorized";
|
|
10564
|
+
if (validationError)
|
|
10565
|
+
reason = validationError;
|
|
10566
|
+
else if (forbidden)
|
|
10567
|
+
reason = "forbidden by .cdd/context-policy.json baseline";
|
|
10568
|
+
else if (!authorized)
|
|
10569
|
+
reason = "not in context-manifest Allowed Paths or Approved Expansions";
|
|
10570
|
+
return { path, authorized, reason };
|
|
10571
|
+
});
|
|
10572
|
+
if (json) {
|
|
10573
|
+
console.log(JSON.stringify({ changeId, results }, null, 2));
|
|
10574
|
+
} else {
|
|
10575
|
+
for (const result of results) {
|
|
10576
|
+
if (result.authorized)
|
|
10577
|
+
log.ok(`authorized: ${result.path}`);
|
|
10578
|
+
else
|
|
10579
|
+
log.error(`unauthorized: ${result.path} (${result.reason})`);
|
|
10580
|
+
}
|
|
10581
|
+
const unauthorized = results.filter((r) => !r.authorized).map((r) => r.path);
|
|
10582
|
+
if (unauthorized.length > 0) {
|
|
10583
|
+
log.info(`If these reads are legitimate, add them to specs/changes/${changeId}/context-manifest.md Allowed Paths or request expansion:`);
|
|
10584
|
+
log.info(` cdd-kit context request ${changeId} CER-<id> --path ${unauthorized.join(" ")} --reason "<why needed>"`);
|
|
10585
|
+
}
|
|
10586
|
+
}
|
|
10587
|
+
if (results.some((result) => !result.authorized))
|
|
10588
|
+
process.exit(1);
|
|
10589
|
+
}
|
|
10499
10590
|
function applyApproval(content, request) {
|
|
10500
10591
|
for (const path of request.paths) {
|
|
10501
10592
|
const validationError = validateRepoRelativePath(path);
|
|
@@ -10569,10 +10660,21 @@ async function rejectAllPending(changeId) {
|
|
|
10569
10660
|
writeManifest(changeId, content);
|
|
10570
10661
|
log.ok(`rejected ${pending.length} pending context expansion request(s) for ${changeId}`);
|
|
10571
10662
|
}
|
|
10663
|
+
var DEFAULT_FORBIDDEN_PATHS;
|
|
10572
10664
|
var init_context = __esm({
|
|
10573
10665
|
"src/commands/context.ts"() {
|
|
10574
10666
|
"use strict";
|
|
10575
10667
|
init_logger();
|
|
10668
|
+
DEFAULT_FORBIDDEN_PATHS = [
|
|
10669
|
+
".claude/worktrees/**",
|
|
10670
|
+
".git/**",
|
|
10671
|
+
"node_modules/**",
|
|
10672
|
+
"dist/**",
|
|
10673
|
+
"build/**",
|
|
10674
|
+
"assets/**",
|
|
10675
|
+
"specs/archive/**",
|
|
10676
|
+
"specs/changes/*"
|
|
10677
|
+
];
|
|
10576
10678
|
}
|
|
10577
10679
|
});
|
|
10578
10680
|
|
|
@@ -11243,7 +11345,7 @@ var agentLogSchema = {
|
|
|
11243
11345
|
"change-id": { type: "string", pattern: "^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$" },
|
|
11244
11346
|
timestamp: { type: "string", format: "date-time" },
|
|
11245
11347
|
agent: { type: "string", minLength: 1 },
|
|
11246
|
-
status: { type: "string", enum: ["complete", "needs-review", "blocked"] },
|
|
11348
|
+
status: { type: "string", enum: ["complete", "done", "approved", "needs-review", "blocked"] },
|
|
11247
11349
|
"files-read": { type: "array", items: { type: "string", minLength: 1 } },
|
|
11248
11350
|
artifacts: {
|
|
11249
11351
|
type: "array",
|
|
@@ -11469,7 +11571,7 @@ function loadContextPolicy(cwd) {
|
|
|
11469
11571
|
function loadYamlFile(path) {
|
|
11470
11572
|
try {
|
|
11471
11573
|
const raw = readFileSync16(path, "utf8");
|
|
11472
|
-
return { data: yaml2.load(raw), parseError: null };
|
|
11574
|
+
return { data: yaml2.load(raw, { schema: yaml2.JSON_SCHEMA }), parseError: null };
|
|
11473
11575
|
} catch (err) {
|
|
11474
11576
|
return { data: null, parseError: err.message };
|
|
11475
11577
|
}
|
|
@@ -11786,9 +11888,18 @@ async function gate(changeId, opts = {}) {
|
|
|
11786
11888
|
let statusReported = false;
|
|
11787
11889
|
if (!ok) {
|
|
11788
11890
|
for (const e of validateAgentLog.errors ?? []) {
|
|
11789
|
-
if (e.keyword === "required" && e.params.missingProperty === "status"
|
|
11891
|
+
if (e.keyword === "required" && e.params.missingProperty === "status") {
|
|
11790
11892
|
if (!statusReported) {
|
|
11791
|
-
errors.push(`agent-log/${f}: missing
|
|
11893
|
+
errors.push(`agent-log/${f}: missing required "status:" line (expected complete | needs-review | blocked; aliases accepted: done, approved)`);
|
|
11894
|
+
statusReported = true;
|
|
11895
|
+
}
|
|
11896
|
+
continue;
|
|
11897
|
+
}
|
|
11898
|
+
if (e.instancePath === "/status" && e.keyword === "enum") {
|
|
11899
|
+
if (!statusReported) {
|
|
11900
|
+
const rawStatus = data.status;
|
|
11901
|
+
const shownStatus = typeof rawStatus === "string" ? rawStatus : JSON.stringify(rawStatus);
|
|
11902
|
+
errors.push(`agent-log/${f}: invalid "status:" value ${shownStatus ?? "<missing>"} (expected complete | needs-review | blocked; aliases accepted: done, approved)`);
|
|
11792
11903
|
statusReported = true;
|
|
11793
11904
|
}
|
|
11794
11905
|
continue;
|
|
@@ -11837,7 +11948,7 @@ async function gate(changeId, opts = {}) {
|
|
|
11837
11948
|
errors.push(`agent-log/${f}: read forbidden path -> ${p}`);
|
|
11838
11949
|
}
|
|
11839
11950
|
if (hasManifest && allowedPaths.length > 0 && !pathMatches(p, allowedPaths) && !pathMatches(p, approvedExpansions)) {
|
|
11840
|
-
errors.push(`agent-log/${f}: read unauthorized path -> ${p} (not in
|
|
11951
|
+
errors.push(`agent-log/${f}: read unauthorized path -> ${p} (not in context-manifest Allowed Paths or Approved Expansions; if legitimate, add it to the manifest instead of deleting it from files-read)`);
|
|
11841
11952
|
}
|
|
11842
11953
|
}
|
|
11843
11954
|
const runtimeLog = join16(cwd, ".cdd", "runtime", `${changeId}-files-read.jsonl`);
|
|
@@ -12140,4 +12251,8 @@ context.command("list <change-id>").description("List Context Expansion Requests
|
|
|
12140
12251
|
const { listContextExpansions: listContextExpansions2 } = await Promise.resolve().then(() => (init_context(), context_exports));
|
|
12141
12252
|
await listContextExpansions2(changeId, opts.json);
|
|
12142
12253
|
});
|
|
12254
|
+
context.command("check <change-id>").description("Preflight-check repo-relative read paths against context-manifest Allowed Paths").requiredOption("--path <paths...>", "Repo-relative path(s) an agent is expected to read").option("--json", "Print machine-readable JSON", false).action(async (changeId, opts) => {
|
|
12255
|
+
const { checkContextPaths: checkContextPaths2 } = await Promise.resolve().then(() => (init_context(), context_exports));
|
|
12256
|
+
await checkContextPaths2(changeId, opts.path, opts.json);
|
|
12257
|
+
});
|
|
12143
12258
|
program.parse();
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# Machine-Readable Change Metadata Design
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
`change.yml` and `trace.yml` should reduce markdown parsing and repeated agent
|
|
6
|
+
reads. They must not become new forms humans must fill out before making small
|
|
7
|
+
fixes.
|
|
8
|
+
|
|
9
|
+
The design principle is:
|
|
10
|
+
|
|
11
|
+
- Humans write normal change artifacts only when a tracked CDD change is useful.
|
|
12
|
+
- Tools derive machine-readable state from existing artifacts whenever possible.
|
|
13
|
+
- Missing machine-readable files should be fixable by regeneration, not by
|
|
14
|
+
forcing a user through extra ceremony.
|
|
15
|
+
|
|
16
|
+
## Workflow Lanes
|
|
17
|
+
|
|
18
|
+
| lane | when to use | metadata expectation |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| maintenance / micro-change | typo fixes, docs cleanup, formatting, lint-only fixes, tiny local test repair | no `specs/changes/<id>/` required |
|
|
21
|
+
| tracked CDD change | behavior, contract, API, data, env, security, CI/CD, cross-module, or release-risk work | `change.yml` and `trace.yml` generated under `specs/changes/<id>/` |
|
|
22
|
+
|
|
23
|
+
The kit should not enforce "every hot file edit needs a change id" by default.
|
|
24
|
+
Teams that want that policy can add a repo-local hook or CI wrapper, but it
|
|
25
|
+
should not be the baseline behavior.
|
|
26
|
+
|
|
27
|
+
## `change.yml`
|
|
28
|
+
|
|
29
|
+
Purpose: a compact state index for one tracked change.
|
|
30
|
+
|
|
31
|
+
Source of truth:
|
|
32
|
+
|
|
33
|
+
- `tasks.yml` for status, tier, dependencies, and task state.
|
|
34
|
+
- `change-classification.md` for change type, agents, and acceptance criteria.
|
|
35
|
+
- `context-manifest.md` for read scope.
|
|
36
|
+
- `agent-log/*.yml` for evidence and agent completion.
|
|
37
|
+
|
|
38
|
+
Generated shape:
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
change-id: add-jwt-auth
|
|
42
|
+
status: in-progress
|
|
43
|
+
tier: 2
|
|
44
|
+
lane: tracked
|
|
45
|
+
types:
|
|
46
|
+
primary: feature-enhancement
|
|
47
|
+
secondary: [api-only-change]
|
|
48
|
+
required-agents:
|
|
49
|
+
- change-classifier
|
|
50
|
+
- test-strategist
|
|
51
|
+
- backend-engineer
|
|
52
|
+
- contract-reviewer
|
|
53
|
+
- qa-reviewer
|
|
54
|
+
artifacts:
|
|
55
|
+
required:
|
|
56
|
+
- change-request.md
|
|
57
|
+
- change-classification.md
|
|
58
|
+
- test-plan.md
|
|
59
|
+
- ci-gates.md
|
|
60
|
+
- tasks.yml
|
|
61
|
+
- context-manifest.md
|
|
62
|
+
optional: []
|
|
63
|
+
context:
|
|
64
|
+
manifest: specs/changes/add-jwt-auth/context-manifest.md
|
|
65
|
+
allowed-paths-count: 8
|
|
66
|
+
dependencies: []
|
|
67
|
+
generated-from:
|
|
68
|
+
tasks.yml: sha256:<digest>
|
|
69
|
+
change-classification.md: sha256:<digest>
|
|
70
|
+
context-manifest.md: sha256:<digest>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Rules:
|
|
74
|
+
|
|
75
|
+
- `change.yml` is generated by the CLI, not hand-authored.
|
|
76
|
+
- If it is absent, agents may fall back to existing markdown/YAML artifacts.
|
|
77
|
+
- `cdd-kit doctor --fix` is the right place to regenerate stale metadata.
|
|
78
|
+
- `cdd-kit gate` may warn on stale metadata, but should not fail only because
|
|
79
|
+
`change.yml` is missing unless a repo opts into strict metadata mode.
|
|
80
|
+
|
|
81
|
+
## `trace.yml`
|
|
82
|
+
|
|
83
|
+
Purpose: a compact traceability graph from acceptance criteria to evidence.
|
|
84
|
+
|
|
85
|
+
Source of truth:
|
|
86
|
+
|
|
87
|
+
- Acceptance criteria from `change-classification.md`.
|
|
88
|
+
- Test mapping from `test-plan.md`.
|
|
89
|
+
- CI gates from `ci-gates.md`.
|
|
90
|
+
- Evidence pointers from `agent-log/*.yml`.
|
|
91
|
+
|
|
92
|
+
Generated shape:
|
|
93
|
+
|
|
94
|
+
```yaml
|
|
95
|
+
change-id: add-jwt-auth
|
|
96
|
+
criteria:
|
|
97
|
+
- id: AC-1
|
|
98
|
+
text: Users can log in with a valid JWT.
|
|
99
|
+
tests:
|
|
100
|
+
- family: integration
|
|
101
|
+
path: tests/auth/login.test.ts
|
|
102
|
+
name: accepts valid token
|
|
103
|
+
gates:
|
|
104
|
+
- unit
|
|
105
|
+
- contract
|
|
106
|
+
evidence:
|
|
107
|
+
- agent: backend-engineer
|
|
108
|
+
type: tests-added
|
|
109
|
+
pointer: tests/auth/login.test.ts::accepts valid token
|
|
110
|
+
- agent: qa-reviewer
|
|
111
|
+
type: qa-verdict
|
|
112
|
+
pointer: specs/changes/add-jwt-auth/agent-log/qa-reviewer.yml
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Rules:
|
|
116
|
+
|
|
117
|
+
- `trace.yml` is generated from existing evidence.
|
|
118
|
+
- It should help reviewers and agents avoid rereading long markdown files.
|
|
119
|
+
- Missing evidence should point back to the existing artifact that needs work;
|
|
120
|
+
it should not introduce a new place to manually duplicate the same content.
|
|
121
|
+
|
|
122
|
+
## CLI Direction
|
|
123
|
+
|
|
124
|
+
Useful future commands:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
cdd-kit metadata <change-id> # regenerate change.yml and trace.yml
|
|
128
|
+
cdd-kit metadata <change-id> --check
|
|
129
|
+
cdd-kit doctor --fix # regenerate stale metadata for active changes
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Default gate behavior should stay low-friction:
|
|
133
|
+
|
|
134
|
+
- Warn when generated metadata is stale or absent.
|
|
135
|
+
- Fail only when source artifacts themselves are invalid.
|
|
136
|
+
- Add a repo opt-in for strict metadata enforcement later if teams ask for it.
|
|
137
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "contract-driven-delivery",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.14",
|
|
4
4
|
"description": "Contract-driven delivery kit for AI coding agents with deterministic context indexes, manifest-backed read-scope governance, and orchestrated contracts-first delivery.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"contract-driven",
|