contract-driven-delivery 2.0.0 → 2.0.2
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 +33 -0
- package/README.md +13 -0
- package/assets/CODEX.template.md +4 -4
- package/assets/agents/change-classifier.md +2 -1
- package/assets/agents/contract-reviewer.md +2 -1
- package/assets/agents/dependency-security-reviewer.md +2 -2
- package/assets/agents/qa-reviewer.md +2 -1
- package/assets/agents/repo-context-scanner.md +2 -2
- package/assets/agents/spec-drift-auditor.md +2 -2
- package/assets/agents/ui-ux-reviewer.md +2 -2
- package/assets/agents/visual-reviewer.md +2 -2
- package/bin/postinstall.js +20 -0
- package/dist/cli/index.js +62 -33
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.0.2] - 2026-04-30
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `npm postinstall` hook: after `npm install -g` or `npm update -g`, skills and
|
|
8
|
+
agents in `~/.claude/` are automatically synced to the newly installed version.
|
|
9
|
+
The sync is a no-op when `cdd-kit init` has never been run (safe for CI and
|
|
10
|
+
local dev installs of the package itself). A backup of any locally modified
|
|
11
|
+
files is created in `~/.claude/.cdd-kit-backup/<timestamp>/` before overwriting,
|
|
12
|
+
matching the existing `cdd-kit update --yes` behaviour.
|
|
13
|
+
- `cdd-kit update --postinstall` flag (internal): quiet mode that implies
|
|
14
|
+
`--yes`, locks provider to `claude`, and silently exits when the skill
|
|
15
|
+
directory is absent. Not intended for direct user invocation.
|
|
16
|
+
|
|
17
|
+
### Migration note
|
|
18
|
+
|
|
19
|
+
The first `npm update -g contract-driven-delivery` that brings in this version
|
|
20
|
+
will **not** auto-sync (the postinstall hook did not exist in the previously
|
|
21
|
+
installed version). Run `cdd-kit update --yes` once after this upgrade; all
|
|
22
|
+
subsequent upgrades will auto-sync.
|
|
23
|
+
|
|
24
|
+
## [2.0.1] - 2026-04-30
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- Clarified the agent ownership model in the public docs so read-only reviewers
|
|
29
|
+
and write-capable implementation agents have explicit, non-conflicting file
|
|
30
|
+
ownership rules.
|
|
31
|
+
- Aligned bundled prompts so read-only agents emit an `Agent Log` YAML block
|
|
32
|
+
for main Claude to persist, while write-capable agents continue writing their
|
|
33
|
+
own artifacts and `agent-log/*.yml` files.
|
|
34
|
+
- Synchronized package version metadata for the post-`2.0.0` publish path.
|
|
35
|
+
|
|
3
36
|
## [2.0.0] - 2026-04-30
|
|
4
37
|
|
|
5
38
|
### BREAKING: structured YAML for tasks and agent-log
|
package/README.md
CHANGED
|
@@ -99,6 +99,19 @@ 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
|
+
### Agent Ownership Model
|
|
103
|
+
|
|
104
|
+
CDD uses two agent classes on purpose:
|
|
105
|
+
|
|
106
|
+
- `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 an `Agent Log` YAML block; main Claude writes the corresponding files.
|
|
107
|
+
- `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 implementation artifacts and their own `agent-log/*.yml`.
|
|
108
|
+
|
|
109
|
+
This split is deliberate:
|
|
110
|
+
|
|
111
|
+
- Review and audit agents stay read-only so they do not silently change the thing they are supposed to assess.
|
|
112
|
+
- Implementation and planning agents write directly so large artifacts and code edits do not have to be relayed back through the main orchestrator, which reduces token waste and preserves clearer ownership.
|
|
113
|
+
- `tasks.yml` remains owned by main Claude so task state changes stay centralized even when multiple agents contribute files.
|
|
114
|
+
|
|
102
115
|
**You stay in control by:**
|
|
103
116
|
- Reviewing the `change-classification.md` before implementation starts
|
|
104
117
|
- Checking the `test-plan.md` to confirm the right test families are planned
|
package/assets/CODEX.template.md
CHANGED
|
@@ -18,12 +18,12 @@ Read `specs/changes/<change-id>/context-manifest.md` before using file-reading o
|
|
|
18
18
|
- Read only paths allowed by the manifest or approved expansions.
|
|
19
19
|
- Do not use broad repository search unless the manifest authorizes it.
|
|
20
20
|
- If more context is needed, stop and write a Context Expansion Request in the manifest.
|
|
21
|
-
- Record every file read through tools in the relevant `agent-log/*.
|
|
21
|
+
- Record every file read through tools in the relevant `agent-log/*.yml` under `files-read:`.
|
|
22
22
|
|
|
23
|
-
Required `agent-log/*.
|
|
23
|
+
Required `agent-log/*.yml` format:
|
|
24
24
|
|
|
25
|
-
```
|
|
26
|
-
|
|
25
|
+
```yaml
|
|
26
|
+
files-read:
|
|
27
27
|
- contracts/api/api-contract.md
|
|
28
28
|
- src/server/routes/users.ts
|
|
29
29
|
```
|
|
@@ -225,7 +225,8 @@ Note: `archive.md` is created during change close-out, not at classification tim
|
|
|
225
225
|
|
|
226
226
|
## Machine-Verifiable Evidence
|
|
227
227
|
|
|
228
|
-
After completing your task,
|
|
228
|
+
After completing your task, end your response with an `Agent Log` YAML block
|
|
229
|
+
for main Claude to write to
|
|
229
230
|
`specs/changes/<change-id>/agent-log/<your-agent-name>.yml`. Required fields,
|
|
230
231
|
field rules, and gate-enforcement behavior are defined once in
|
|
231
232
|
`references/agent-log-protocol.md` — do not duplicate them in this prompt.
|
|
@@ -63,7 +63,8 @@ approved / changes-required
|
|
|
63
63
|
|
|
64
64
|
## Machine-Verifiable Evidence
|
|
65
65
|
|
|
66
|
-
After completing your task,
|
|
66
|
+
After completing your task, end your response with an `Agent Log` YAML block
|
|
67
|
+
for main Claude to write to
|
|
67
68
|
`specs/changes/<change-id>/agent-log/<your-agent-name>.yml`. Required fields,
|
|
68
69
|
field rules, and gate-enforcement behavior are defined once in
|
|
69
70
|
`references/agent-log-protocol.md` — do not duplicate them in this prompt.
|
|
@@ -64,7 +64,8 @@ approved / changes-required / blocked
|
|
|
64
64
|
|
|
65
65
|
## Machine-Verifiable Evidence
|
|
66
66
|
|
|
67
|
-
After completing your task,
|
|
67
|
+
After completing your task, end your response with an `Agent Log` YAML block
|
|
68
|
+
for main Claude to write to
|
|
68
69
|
`specs/changes/<change-id>/agent-log/<your-agent-name>.yml`. Required fields,
|
|
69
70
|
field rules, and gate-enforcement behavior are defined once in
|
|
70
71
|
`references/agent-log-protocol.md` — do not duplicate them in this prompt.
|
|
@@ -74,4 +75,3 @@ field rules, and gate-enforcement behavior are defined once in
|
|
|
74
75
|
- `cve-findings`: count + severity buckets
|
|
75
76
|
- `license-issues`: list or "none"
|
|
76
77
|
- `lockfile-changes`: list of files
|
|
77
|
-
|
|
@@ -75,7 +75,8 @@ approved / blocked / approved-with-risk
|
|
|
75
75
|
|
|
76
76
|
## Machine-Verifiable Evidence
|
|
77
77
|
|
|
78
|
-
After completing your task,
|
|
78
|
+
After completing your task, end your response with an `Agent Log` YAML block
|
|
79
|
+
for main Claude to write to
|
|
79
80
|
`specs/changes/<change-id>/agent-log/<your-agent-name>.yml`. Required fields,
|
|
80
81
|
field rules, and gate-enforcement behavior are defined once in
|
|
81
82
|
`references/agent-log-protocol.md` — do not duplicate them in this prompt.
|
|
@@ -84,7 +84,8 @@ frontend / backend / fullstack / monorepo / library / tool
|
|
|
84
84
|
|
|
85
85
|
## Machine-Verifiable Evidence
|
|
86
86
|
|
|
87
|
-
After completing your task,
|
|
87
|
+
After completing your task, end your response with an `Agent Log` YAML block
|
|
88
|
+
for main Claude to write to
|
|
88
89
|
`specs/changes/<change-id>/agent-log/<your-agent-name>.yml`. Required fields,
|
|
89
90
|
field rules, and gate-enforcement behavior are defined once in
|
|
90
91
|
`references/agent-log-protocol.md` — do not duplicate them in this prompt.
|
|
@@ -93,4 +94,3 @@ field rules, and gate-enforcement behavior are defined once in
|
|
|
93
94
|
- `profile-path`: `project-profile.generated.md`
|
|
94
95
|
- `stack-detected`: from cdd-kit detect-stack
|
|
95
96
|
- `surfaces-flagged`: list of missing standardization surfaces
|
|
96
|
-
|
|
@@ -52,7 +52,8 @@ By default, do NOT read `specs/changes/` history. Only read historical change re
|
|
|
52
52
|
|
|
53
53
|
## Machine-Verifiable Evidence
|
|
54
54
|
|
|
55
|
-
After completing your task,
|
|
55
|
+
After completing your task, end your response with an `Agent Log` YAML block
|
|
56
|
+
for main Claude to write to
|
|
56
57
|
`specs/changes/<change-id>/agent-log/<your-agent-name>.yml`. Required fields,
|
|
57
58
|
field rules, and gate-enforcement behavior are defined once in
|
|
58
59
|
`references/agent-log-protocol.md` — do not duplicate them in this prompt.
|
|
@@ -62,4 +63,3 @@ field rules, and gate-enforcement behavior are defined once in
|
|
|
62
63
|
- `drift-items`: count + severity
|
|
63
64
|
- `drift-summary-path`: `specs/audits/<YYYY-MM-DD>-drift-audit.md`
|
|
64
65
|
- `next-audit-due`: ISO date
|
|
65
|
-
|
|
@@ -51,7 +51,8 @@ approved / changes-required
|
|
|
51
51
|
|
|
52
52
|
## Machine-Verifiable Evidence
|
|
53
53
|
|
|
54
|
-
After completing your task,
|
|
54
|
+
After completing your task, end your response with an `Agent Log` YAML block
|
|
55
|
+
for main Claude to write to
|
|
55
56
|
`specs/changes/<change-id>/agent-log/<your-agent-name>.yml`. Required fields,
|
|
56
57
|
field rules, and gate-enforcement behavior are defined once in
|
|
57
58
|
`references/agent-log-protocol.md` — do not duplicate them in this prompt.
|
|
@@ -61,4 +62,3 @@ field rules, and gate-enforcement behavior are defined once in
|
|
|
61
62
|
- `state-coverage`: list of `<screen>: empty/loading/error/success` matrix
|
|
62
63
|
- `copy-issues`: count + severity
|
|
63
64
|
- `accessibility-findings`: count + severity
|
|
64
|
-
|
|
@@ -53,7 +53,8 @@ approved / changes-required
|
|
|
53
53
|
|
|
54
54
|
## Machine-Verifiable Evidence
|
|
55
55
|
|
|
56
|
-
After completing your task,
|
|
56
|
+
After completing your task, end your response with an `Agent Log` YAML block
|
|
57
|
+
for main Claude to write to
|
|
57
58
|
`specs/changes/<change-id>/agent-log/<your-agent-name>.yml`. Required fields,
|
|
58
59
|
field rules, and gate-enforcement behavior are defined once in
|
|
59
60
|
`references/agent-log-protocol.md` — do not duplicate them in this prompt.
|
|
@@ -63,4 +64,3 @@ field rules, and gate-enforcement behavior are defined once in
|
|
|
63
64
|
- `diff-percentage`: per-screen
|
|
64
65
|
- `state-coverage`: matrix
|
|
65
66
|
- `tokens-violated`: list of CSS contract violations or "none"
|
|
66
|
-
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { join, dirname } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
const cliPath = join(__dirname, '..', 'dist', 'cli', 'index.js');
|
|
11
|
+
if (!existsSync(cliPath)) process.exit(0);
|
|
12
|
+
|
|
13
|
+
spawnSync(process.execPath, [cliPath, 'update', '--postinstall'], {
|
|
14
|
+
stdio: 'inherit',
|
|
15
|
+
timeout: 30_000,
|
|
16
|
+
});
|
|
17
|
+
process.exit(0);
|
|
18
|
+
} catch {
|
|
19
|
+
process.exit(0);
|
|
20
|
+
}
|
package/dist/cli/index.js
CHANGED
|
@@ -11673,7 +11673,16 @@ function backupDir(dir, backupDest) {
|
|
|
11673
11673
|
walk(dir, backupDest);
|
|
11674
11674
|
}
|
|
11675
11675
|
async function update(opts) {
|
|
11676
|
-
|
|
11676
|
+
if (opts.postinstall) {
|
|
11677
|
+
if (!existsSync5(join6(SKILLS_HOME, "contract-driven-delivery"))) {
|
|
11678
|
+
return;
|
|
11679
|
+
}
|
|
11680
|
+
opts.yes = true;
|
|
11681
|
+
opts.provider = "claude";
|
|
11682
|
+
}
|
|
11683
|
+
const quiet = !!opts.postinstall;
|
|
11684
|
+
if (!quiet)
|
|
11685
|
+
log.blank();
|
|
11677
11686
|
const cwd = process.cwd();
|
|
11678
11687
|
const requestedProvider = opts.provider ?? "auto";
|
|
11679
11688
|
if (!validateProviderOption(requestedProvider)) {
|
|
@@ -11689,28 +11698,32 @@ async function update(opts) {
|
|
|
11689
11698
|
const toAdd = toWrite.filter((e) => e.action === "add");
|
|
11690
11699
|
const toOver = toWrite.filter((e) => e.action === "overwrite");
|
|
11691
11700
|
const toSkip = [...agentDiff, ...skillDiff].filter((e) => e.action === "skip");
|
|
11692
|
-
|
|
11693
|
-
|
|
11694
|
-
|
|
11695
|
-
|
|
11696
|
-
|
|
11697
|
-
|
|
11698
|
-
|
|
11701
|
+
if (!quiet) {
|
|
11702
|
+
log.info(`Provider: ${provider}`);
|
|
11703
|
+
if (updateClaudeAssets) {
|
|
11704
|
+
log.info(`Dry-run diff \u2014 agents: ${AGENTS_HOME}`);
|
|
11705
|
+
log.info(`Dry-run diff \u2014 skill: ${skillDest}`);
|
|
11706
|
+
} else {
|
|
11707
|
+
log.info("Codex provider has no global cdd-kit assets to update.");
|
|
11708
|
+
log.info("Project files are preserved; run cdd-kit init --local-only --provider codex to add missing local guidance.");
|
|
11709
|
+
}
|
|
11710
|
+
log.blank();
|
|
11711
|
+
if (toAdd.length)
|
|
11712
|
+
log.info(` + ${toAdd.length} file(s) would be added`);
|
|
11713
|
+
if (toOver.length)
|
|
11714
|
+
log.warn(` ~ ${toOver.length} file(s) would be overwritten (user edits lost without backup)`);
|
|
11715
|
+
if (toSkip.length)
|
|
11716
|
+
log.dim(` ${toSkip.length} file(s) unchanged (skipped)`);
|
|
11699
11717
|
}
|
|
11700
|
-
log.blank();
|
|
11701
|
-
if (toAdd.length)
|
|
11702
|
-
log.info(` + ${toAdd.length} file(s) would be added`);
|
|
11703
|
-
if (toOver.length)
|
|
11704
|
-
log.warn(` ~ ${toOver.length} file(s) would be overwritten (user edits lost without backup)`);
|
|
11705
|
-
if (toSkip.length)
|
|
11706
|
-
log.dim(` ${toSkip.length} file(s) unchanged (skipped)`);
|
|
11707
11718
|
if (toWrite.length === 0) {
|
|
11708
|
-
|
|
11709
|
-
|
|
11710
|
-
|
|
11719
|
+
if (!quiet) {
|
|
11720
|
+
log.blank();
|
|
11721
|
+
log.ok("Already up to date \u2014 nothing to write.");
|
|
11722
|
+
log.blank();
|
|
11723
|
+
}
|
|
11711
11724
|
return;
|
|
11712
11725
|
}
|
|
11713
|
-
if (!opts.yes) {
|
|
11726
|
+
if (!quiet && !opts.yes) {
|
|
11714
11727
|
log.blank();
|
|
11715
11728
|
log.info("Run with --yes to apply changes. Example:");
|
|
11716
11729
|
log.dim(" cdd-kit update --yes");
|
|
@@ -11719,25 +11732,41 @@ async function update(opts) {
|
|
|
11719
11732
|
}
|
|
11720
11733
|
const timestamp2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
11721
11734
|
const backupRoot = join6(homedir2(), ".claude", ".cdd-kit-backup", timestamp2);
|
|
11722
|
-
|
|
11723
|
-
|
|
11735
|
+
if (!quiet) {
|
|
11736
|
+
log.blank();
|
|
11737
|
+
log.info(`Backing up to ${backupRoot} \u2026`);
|
|
11738
|
+
}
|
|
11724
11739
|
backupDir(AGENTS_HOME, join6(backupRoot, "agents"));
|
|
11725
11740
|
backupDir(skillDest, join6(backupRoot, "skill"));
|
|
11726
|
-
|
|
11727
|
-
|
|
11741
|
+
if (!quiet)
|
|
11742
|
+
log.ok(`Backup complete: ${backupRoot}`);
|
|
11743
|
+
if (!quiet)
|
|
11744
|
+
log.blank();
|
|
11745
|
+
let totalSynced = 0;
|
|
11728
11746
|
if (updateClaudeAssets) {
|
|
11729
|
-
|
|
11747
|
+
if (!quiet)
|
|
11748
|
+
log.info(`Updating agents \u2192 ${AGENTS_HOME}`);
|
|
11730
11749
|
const agentCount = applyDir(agentDiff);
|
|
11731
|
-
|
|
11732
|
-
|
|
11750
|
+
if (!quiet)
|
|
11751
|
+
log.ok(`${agentCount} agent file(s) updated.`);
|
|
11752
|
+
totalSynced += agentCount;
|
|
11753
|
+
if (!quiet)
|
|
11754
|
+
log.info(`Updating skill \u2192 ${skillDest}`);
|
|
11733
11755
|
const skillCount = applyDir(skillDiff);
|
|
11734
|
-
|
|
11756
|
+
if (!quiet)
|
|
11757
|
+
log.ok(`${skillCount} skill file(s) updated.`);
|
|
11758
|
+
totalSynced += skillCount;
|
|
11759
|
+
}
|
|
11760
|
+
if (quiet) {
|
|
11761
|
+
if (totalSynced > 0)
|
|
11762
|
+
log.ok(`cdd-kit: synced ${totalSynced} file(s) to ~/.claude/`);
|
|
11763
|
+
} else {
|
|
11764
|
+
log.blank();
|
|
11765
|
+
log.info("Project files (contracts/, specs/, tests/, ci/) were not changed.");
|
|
11766
|
+
log.ok("Update complete.");
|
|
11767
|
+
log.info(`Backup saved to: ${backupRoot}`);
|
|
11768
|
+
log.blank();
|
|
11735
11769
|
}
|
|
11736
|
-
log.blank();
|
|
11737
|
-
log.info("Project files (contracts/, specs/, tests/, ci/) were not changed.");
|
|
11738
|
-
log.ok("Update complete.");
|
|
11739
|
-
log.info(`Backup saved to: ${backupRoot}`);
|
|
11740
|
-
log.blank();
|
|
11741
11770
|
}
|
|
11742
11771
|
|
|
11743
11772
|
// src/commands/new-change.ts
|
|
@@ -12657,7 +12686,7 @@ program.command("init").description(
|
|
|
12657
12686
|
provider: opts.provider
|
|
12658
12687
|
})
|
|
12659
12688
|
);
|
|
12660
|
-
program.command("update").description("Update provider assets for the current project (does not overwrite project guidance files)").option("--yes", "Apply changes (default is dry-run)", false).option("--provider <provider>", "Provider adapter to update: auto, claude, codex, or both", "auto").action((opts) => update({ yes: opts.yes, provider: opts.provider }));
|
|
12689
|
+
program.command("update").description("Update provider assets for the current project (does not overwrite project guidance files)").option("--yes", "Apply changes (default is dry-run)", false).option("--provider <provider>", "Provider adapter to update: auto, claude, codex, or both", "auto").option("--postinstall", "Internal: invoked by npm postinstall; no-op if cdd has not been init-ed", false).action((opts) => update({ yes: opts.yes, provider: opts.provider, postinstall: opts.postinstall }));
|
|
12661
12690
|
program.command("doctor").description("Inspect cdd-kit repo health, provider guidance, and context index freshness").option("--strict", "Treat warnings as errors", false).option("--json", "Print a machine-readable health report", false).option("--provider <provider>", "Provider adapter to inspect: auto, claude, codex, or both", "auto").option("--fix", "Auto-resolve safe warnings (stale context indexes, missing role bindings)", false).action(async (opts) => {
|
|
12662
12691
|
const { doctor: doctor2 } = await Promise.resolve().then(() => (init_doctor(), doctor_exports));
|
|
12663
12692
|
await doctor2({ strict: opts.strict, json: opts.json, provider: opts.provider, fix: opts.fix });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "contract-driven-delivery",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
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",
|
|
@@ -40,7 +40,8 @@
|
|
|
40
40
|
"build": "node build.js",
|
|
41
41
|
"test": "vitest run",
|
|
42
42
|
"test:watch": "vitest",
|
|
43
|
-
"prepublishOnly": "node build.js && vitest run"
|
|
43
|
+
"prepublishOnly": "node build.js && vitest run",
|
|
44
|
+
"postinstall": "node bin/postinstall.js"
|
|
44
45
|
},
|
|
45
46
|
"engines": {
|
|
46
47
|
"node": ">=18.0.0"
|