contract-driven-delivery 1.7.0 → 1.8.1

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.
Files changed (45) hide show
  1. package/assets/skills/cdd-init/SKILL.md +188 -0
  2. package/assets/skills/cdd-new/SKILL.md +162 -0
  3. package/dist/cli/index.js +20 -14
  4. package/package.json +1 -1
  5. /package/assets/{skill → skills/contract-driven-delivery}/SKILL.md +0 -0
  6. /package/assets/{skill → skills/contract-driven-delivery}/references/api-contract-standard.md +0 -0
  7. /package/assets/{skill → skills/contract-driven-delivery}/references/business-logic-standard.md +0 -0
  8. /package/assets/{skill → skills/contract-driven-delivery}/references/ci-cd-policy.md +0 -0
  9. /package/assets/{skill → skills/contract-driven-delivery}/references/css-contract-standard.md +0 -0
  10. /package/assets/{skill → skills/contract-driven-delivery}/references/data-contract-standard.md +0 -0
  11. /package/assets/{skill → skills/contract-driven-delivery}/references/e2e-standard.md +0 -0
  12. /package/assets/{skill → skills/contract-driven-delivery}/references/env-contract-standard.md +0 -0
  13. /package/assets/{skill → skills/contract-driven-delivery}/references/monkey-operation-standard.md +0 -0
  14. /package/assets/{skill → skills/contract-driven-delivery}/references/qa-gates.md +0 -0
  15. /package/assets/{skill → skills/contract-driven-delivery}/references/sdd-tdd-policy.md +0 -0
  16. /package/assets/{skill → skills/contract-driven-delivery}/references/spec-drift-policy.md +0 -0
  17. /package/assets/{skill → skills/contract-driven-delivery}/references/stress-soak-standard.md +0 -0
  18. /package/assets/{skill → skills/contract-driven-delivery}/references/visual-review-standard.md +0 -0
  19. /package/assets/{skill → skills/contract-driven-delivery}/references/workflow-router.md +0 -0
  20. /package/assets/{skill → skills/contract-driven-delivery}/scripts/detect_project_profile.py +0 -0
  21. /package/assets/{skill → skills/contract-driven-delivery}/scripts/generate_change_scaffold.py +0 -0
  22. /package/assets/{skill → skills/contract-driven-delivery}/scripts/validate_api_semantic.py +0 -0
  23. /package/assets/{skill → skills/contract-driven-delivery}/scripts/validate_ci_gates.py +0 -0
  24. /package/assets/{skill → skills/contract-driven-delivery}/scripts/validate_contract_versions.py +0 -0
  25. /package/assets/{skill → skills/contract-driven-delivery}/scripts/validate_contracts.py +0 -0
  26. /package/assets/{skill → skills/contract-driven-delivery}/scripts/validate_env_contract.py +0 -0
  27. /package/assets/{skill → skills/contract-driven-delivery}/scripts/validate_env_semantic.py +0 -0
  28. /package/assets/{skill → skills/contract-driven-delivery}/scripts/validate_spec_traceability.py +0 -0
  29. /package/assets/{skill → skills/contract-driven-delivery}/templates/archive.md +0 -0
  30. /package/assets/{skill → skills/contract-driven-delivery}/templates/change-classification.md +0 -0
  31. /package/assets/{skill → skills/contract-driven-delivery}/templates/change-request.md +0 -0
  32. /package/assets/{skill → skills/contract-driven-delivery}/templates/ci-gates.md +0 -0
  33. /package/assets/{skill → skills/contract-driven-delivery}/templates/contracts.md +0 -0
  34. /package/assets/{skill → skills/contract-driven-delivery}/templates/current-behavior.md +0 -0
  35. /package/assets/{skill → skills/contract-driven-delivery}/templates/design.md +0 -0
  36. /package/assets/{skill → skills/contract-driven-delivery}/templates/monkey-test-report.md +0 -0
  37. /package/assets/{skill → skills/contract-driven-delivery}/templates/project-profile.md +0 -0
  38. /package/assets/{skill → skills/contract-driven-delivery}/templates/proposal.md +0 -0
  39. /package/assets/{skill → skills/contract-driven-delivery}/templates/qa-report.md +0 -0
  40. /package/assets/{skill → skills/contract-driven-delivery}/templates/regression-report.md +0 -0
  41. /package/assets/{skill → skills/contract-driven-delivery}/templates/spec.md +0 -0
  42. /package/assets/{skill → skills/contract-driven-delivery}/templates/stress-soak-report.md +0 -0
  43. /package/assets/{skill → skills/contract-driven-delivery}/templates/tasks.md +0 -0
  44. /package/assets/{skill → skills/contract-driven-delivery}/templates/test-plan.md +0 -0
  45. /package/assets/{skill → skills/contract-driven-delivery}/templates/visual-review-report.md +0 -0
@@ -0,0 +1,188 @@
1
+ ---
2
+ name: cdd-init
3
+ description: Initialize contract-driven delivery for a project. Handles both brand-new projects (no specs/ directory) and brownfield adoption (existing codebase). Run once per project before using /cdd-new.
4
+ ---
5
+
6
+ # cdd-init — Project Initialization
7
+
8
+ ## Overview
9
+
10
+ This skill sets up the contract-driven delivery system for a project. It auto-detects whether this is a new project or brownfield adoption and follows the appropriate path.
11
+
12
+ **File creation rule**: Scanning agents (repo-context-scanner, spec-drift-auditor) only READ and REPORT — they have no write tools. After receiving their report, YOU (main Claude) create all files using Edit/Write.
13
+
14
+ ---
15
+
16
+ ## Step 1: Detect project type
17
+
18
+ Run from the repository root:
19
+
20
+ ```
21
+ cdd-kit detect-stack
22
+ ```
23
+
24
+ Then check whether `specs/` directory already exists in the repo root.
25
+
26
+ - `specs/` does **NOT** exist → **New Project** → follow Section A
27
+ - `specs/` **already exists** → **Brownfield Adoption** → follow Section B
28
+
29
+ ---
30
+
31
+ ## Section A: New Project
32
+
33
+ ### A1. Initialize scaffold
34
+
35
+ ```
36
+ cdd-kit init
37
+ cdd-kit install-hooks
38
+ ```
39
+
40
+ ### A2. Scan project baseline
41
+
42
+ Invoke `repo-context-scanner` agent. Ask it to report (NOT write):
43
+ - Tech stack and build commands
44
+ - Existing API endpoints (routes, controllers)
45
+ - Existing env variables in use
46
+ - Existing data models or report shapes
47
+
48
+ The agent returns its findings as text. YOU then write `specs/project-profile.md` from its output.
49
+
50
+ ### A3. Create stub contracts (YOU write these)
51
+
52
+ Based on the scanner's findings, create stub files in `contracts/`:
53
+
54
+ | Surface found | File to create |
55
+ |---------------|---------------|
56
+ | API endpoints | `contracts/api.md` |
57
+ | Env variables | `contracts/env.md` |
58
+ | Data/report shapes | `contracts/data.md` (skip if none) |
59
+
60
+ Each file must have frontmatter:
61
+ ```
62
+ ---
63
+ schema-version: 0.1.0
64
+ status: draft
65
+ last-changed: <today's date>
66
+ ---
67
+ ```
68
+
69
+ Use column formats from `.claude/skills/contract-driven-delivery/references/api-contract-standard.md` and `env-contract-standard.md`.
70
+
71
+ **0.x contracts are informational only — `cdd-kit gate` does not enforce them until bumped to 1.0.0.**
72
+
73
+ ### A4. Report to user
74
+
75
+ ```
76
+ ## cdd-init complete (new project)
77
+
78
+ Stack detected: <stack>
79
+ Files created:
80
+ - specs/project-profile.md
81
+ - contracts/api.md (draft, v0.1.0)
82
+ - contracts/env.md (draft, v0.1.0)
83
+ Hook installed: .git/hooks/pre-commit
84
+
85
+ Next step: /cdd-new <describe your first feature or change>
86
+ ```
87
+
88
+ ---
89
+
90
+ ## Section B: Brownfield Adoption
91
+
92
+ ### B1. Initialize scaffold (non-destructive)
93
+
94
+ ```
95
+ cdd-kit init
96
+ cdd-kit install-hooks
97
+ ```
98
+
99
+ `cdd-kit init` will not overwrite existing files.
100
+
101
+ ### B2. Scan existing project
102
+
103
+ Invoke `repo-context-scanner` agent. Ask it to report (NOT write):
104
+ - Tech stack and commands
105
+ - All existing API endpoints with method + path
106
+ - All existing env variables (name, where used, whether secret)
107
+ - Existing data models or shared data shapes
108
+ - Existing tests and CI/CD setup
109
+ - Gaps vs cdd-kit expectations
110
+
111
+ The agent returns findings as text. YOU write `specs/project-profile.md` from its output.
112
+
113
+ ### B3. Reverse-engineer draft contracts (YOU write these)
114
+
115
+ Based on the scanner's findings, create or update draft contracts:
116
+
117
+ **`contracts/api.md`** — list all discovered endpoints:
118
+ ```
119
+ ---
120
+ schema-version: 0.1.0
121
+ status: draft
122
+ last-changed: <today>
123
+ ---
124
+ | Method | Path | Auth | Request | Response |
125
+ |--------|------|------|---------|----------|
126
+ | ... | ... | ... | ... | ... |
127
+ ```
128
+
129
+ **`contracts/env.md`** — list all discovered env variables:
130
+ ```
131
+ ---
132
+ schema-version: 0.1.0
133
+ status: draft
134
+ last-changed: <today>
135
+ ---
136
+ | Name | Required | Default | Secret |
137
+ |------|----------|---------|--------|
138
+ | ... | ... | ... | ... |
139
+ ```
140
+
141
+ **`contracts/data.md`** — only if significant data shapes exist.
142
+
143
+ Rules:
144
+ - Document what EXISTS — do not prescribe what should exist
145
+ - Mark uncertain fields with `<!-- verify -->`
146
+ - Do NOT bump above 0.x during init
147
+ - Do NOT delete or overwrite existing `contracts/` files — append sections
148
+
149
+ ### B4. Run gap analysis
150
+
151
+ Invoke `spec-drift-auditor` agent. Ask it to report (NOT write):
152
+ 1. What is already in place (contracts, tests, CI gates)
153
+ 2. What is missing and at what priority
154
+ 3. Recommended first tracked change to close the highest-risk gap
155
+
156
+ ### B5. Report to user
157
+
158
+ ```
159
+ ## cdd-init complete (brownfield adoption)
160
+
161
+ Stack detected: <stack>
162
+ Contracts reverse-engineered (all at v0.1.0 draft):
163
+ - contracts/api.md — <N> endpoints documented
164
+ - contracts/env.md — <N> variables documented
165
+ Hook installed: .git/hooks/pre-commit
166
+
167
+ Gap report:
168
+ ### Existing (found)
169
+ - ...
170
+
171
+ ### Missing (needs work)
172
+ - ...
173
+
174
+ ### Recommended first tracked change
175
+ - ...
176
+
177
+ Next step: /cdd-new <describe the gap or feature to address first>
178
+ ```
179
+
180
+ ---
181
+
182
+ ## Rules
183
+
184
+ - Never delete existing files
185
+ - Never bump any contract version above 0.x during init
186
+ - Gate enforcement starts only after contracts reach 1.0.0
187
+ - Scanning agents only report — YOU (main Claude) write all files
188
+ - If `cdd-kit init` fails: `npm install -g contract-driven-delivery@latest`
@@ -0,0 +1,162 @@
1
+ ---
2
+ name: cdd-new
3
+ description: Start a new tracked change. Scaffolds all required artifacts, classifies the change by risk tier, commissions the right agents in order, and runs cdd-kit gate. Args: <change description in natural language>
4
+ ---
5
+
6
+ # cdd-new — New Change Request
7
+
8
+ ## Input
9
+
10
+ The skill argument is the user's change description in natural language (e.g., "add JWT authentication to the API" or "redesign the dashboard homepage").
11
+
12
+ If no description is provided, ask the user: "Please describe the change you want to make."
13
+
14
+ ---
15
+
16
+ ## Step 1: Generate change-id and scaffold
17
+
18
+ Derive a `change-id` from the description:
19
+ - kebab-case, max 5 words
20
+ - examples: `add-jwt-auth`, `redesign-dashboard-home`, `fix-order-export-timeout`
21
+
22
+ Check that `specs/changes/<change-id>/` does not already exist. If it does, append `-2` (or next available suffix).
23
+
24
+ Run the scaffold generator:
25
+
26
+ ```
27
+ python .claude/skills/contract-driven-delivery/scripts/generate_change_scaffold.py <change-id>
28
+ ```
29
+
30
+ If the script is unavailable, manually create `specs/changes/<change-id>/` and copy these template files:
31
+
32
+ | Source | Destination |
33
+ |--------|-------------|
34
+ | `.claude/skills/contract-driven-delivery/templates/change-request.md` | `specs/changes/<change-id>/change-request.md` |
35
+ | `.claude/skills/contract-driven-delivery/templates/change-classification.md` | `specs/changes/<change-id>/change-classification.md` |
36
+ | `.claude/skills/contract-driven-delivery/templates/test-plan.md` | `specs/changes/<change-id>/test-plan.md` |
37
+ | `.claude/skills/contract-driven-delivery/templates/ci-gates.md` | `specs/changes/<change-id>/ci-gates.md` |
38
+ | `.claude/skills/contract-driven-delivery/templates/tasks.md` | `specs/changes/<change-id>/tasks.md` |
39
+
40
+ Fill in `change-request.md`:
41
+ - `## Original Request` → the user's exact description
42
+ - `## Business / User Goal` → infer from context
43
+ - `## Requested Delivery Date / Priority` → "as soon as possible" if not specified
44
+
45
+ ---
46
+
47
+ ## Step 2: Classify the change
48
+
49
+ Invoke `change-classifier` agent with:
50
+ - The user's change description
51
+ - The project profile at `specs/project-profile.md` (if it exists)
52
+ - The existing contracts in `contracts/` (if any)
53
+
54
+ The classifier must write a complete `specs/changes/<change-id>/change-classification.md` including:
55
+ - Risk tier (Tier 0–5, or low / medium / high / critical)
56
+ - Affected surfaces (API, UI, env, data, CI)
57
+ - List of required agents
58
+
59
+ Wait for `change-classification.md` to be written before continuing.
60
+
61
+ ---
62
+
63
+ ## Step 3: Read the tier and commission agents
64
+
65
+ Read `change-classification.md` to determine the tier. Then invoke agents **in the exact order below**, waiting for each to complete its `specs/changes/<change-id>/agent-log/<agent-name>.md` before proceeding.
66
+
67
+ ### Tier 4–5 (low risk: docs, prompts, config-only, no behavior change)
68
+
69
+ 1. `contract-reviewer` — confirm no contracts are touched or all touched ones are already updated
70
+ 2. `qa-reviewer` — confirm release readiness
71
+
72
+ ### Tier 2–3 (normal: feature, enhancement, bug fix with behavior change)
73
+
74
+ 1. `contract-reviewer` — update or create contracts in `contracts/` before any implementation starts
75
+ 2. `test-strategist` — author `specs/changes/<change-id>/test-plan.md`
76
+ 3. `spec-architect` — only if the classifier flagged an architectural boundary or cross-module impact
77
+ 4. `backend-engineer` — if the change touches server, API, data, or business logic
78
+ 5. `frontend-engineer` — if the change touches UI, components, or client-side behavior
79
+ 6. `ui-ux-reviewer` — if any UI change (run alongside or after frontend-engineer)
80
+ 7. `visual-reviewer` — if any UI change (run after ui-ux-reviewer)
81
+ 8. `dependency-security-reviewer` — if the change touches lockfiles, package manifests, or DB migrations
82
+ 9. `ci-cd-gatekeeper` — update `specs/changes/<change-id>/ci-gates.md`
83
+ 10. `qa-reviewer` — release readiness decision
84
+
85
+ ### Tier 0–1 (high risk: production data, concurrency, queues, large queries, auth, payments, exports)
86
+
87
+ All agents from Tier 2–3, plus insert these after `frontend-engineer` / `backend-engineer`:
88
+
89
+ - `e2e-resilience-engineer` — E2E, failure-injection, data-boundary tests
90
+ - `monkey-test-engineer` — adversarial input, fuzz, rapid-UI-action tests
91
+ - `stress-soak-engineer` — load, soak, and long-running stability tests
92
+
93
+ **Agent commission rules**:
94
+ - Skip an agent only if the classifier explicitly marks its surface as "not affected"
95
+ - If any agent sets `status: blocked` in its log, halt immediately and report the agent's `next-action` to the user — do not proceed to subsequent agents
96
+ - If the change is UI-only with no backend, skip `backend-engineer`; if backend-only with no UI, skip `frontend-engineer`, `ui-ux-reviewer`, `visual-reviewer`
97
+
98
+ ---
99
+
100
+ ## Step 4: Run the gate
101
+
102
+ After all required agents have completed:
103
+
104
+ ```
105
+ cdd-kit gate <change-id>
106
+ ```
107
+
108
+ **If gate passes**: proceed to Step 5.
109
+
110
+ **If gate fails**:
111
+ 1. Read the gate error output carefully
112
+ 2. Identify which artifact is missing, stub, or invalid
113
+ 3. Re-invoke the specific agent responsible for that artifact with the exact fix required
114
+ 4. Re-run `cdd-kit gate <change-id>`
115
+ 5. Repeat until gate passes (max 3 iterations; if still failing after 3, report to user)
116
+
117
+ ---
118
+
119
+ ## Step 5: Report to user
120
+
121
+ Output a final summary:
122
+
123
+ ```
124
+ ## /cdd-new complete
125
+
126
+ Change ID: <change-id>
127
+ Risk tier: <tier>
128
+ Agents invoked: <list in order>
129
+ Gate: PASSED
130
+
131
+ All artifacts written to: specs/changes/<change-id>/
132
+
133
+ Next step:
134
+ git add specs/changes/<change-id>/
135
+ git add <any implementation files changed>
136
+ git commit -m "feat(<change-id>): <one-line description>"
137
+ ```
138
+
139
+ If gate did not pass after 3 iterations:
140
+
141
+ ```
142
+ ## /cdd-new — gate blocked
143
+
144
+ Change ID: <change-id>
145
+ Gate failed after 3 attempts.
146
+
147
+ Blocking items:
148
+ - <item 1>
149
+ - <item 2>
150
+
151
+ Please review the above items and re-run: cdd-kit gate <change-id>
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Rules
157
+
158
+ - Never start implementation (backend/frontend-engineer) before `contract-reviewer` has completed for Tier 0–3 changes
159
+ - Never skip `test-plan.md` for Tier 0–3 changes
160
+ - Never skip `ci-gates.md` for any implementation change
161
+ - Every agent must write its `agent-log/<name>.md` — the gate will reject changes missing it
162
+ - `qa-reviewer` always runs last and makes the release-readiness decision
package/dist/cli/index.js CHANGED
@@ -6,7 +6,7 @@ import { Command } from "commander";
6
6
 
7
7
  // src/commands/init.ts
8
8
  import { join as join4 } from "path";
9
- import { rmSync, readFileSync as readFileSync2, writeFileSync, existsSync as existsSync3 } from "fs";
9
+ import { rmSync, readFileSync as readFileSync2, writeFileSync, existsSync as existsSync3, readdirSync as readdirSync2 } from "fs";
10
10
 
11
11
  // src/utils/paths.ts
12
12
  import { join, dirname } from "path";
@@ -20,7 +20,8 @@ var AGENTS_HOME = join(CLAUDE_HOME, "agents");
20
20
  var SKILLS_HOME = join(CLAUDE_HOME, "skills");
21
21
  var ASSET = {
22
22
  agents: join(ASSETS_DIR, "agents"),
23
- skill: join(ASSETS_DIR, "skill"),
23
+ skills: join(ASSETS_DIR, "skills"),
24
+ skill: join(ASSETS_DIR, "skills", "contract-driven-delivery"),
24
25
  contracts: join(ASSETS_DIR, "contracts"),
25
26
  specsTemplates: join(ASSETS_DIR, "specs-templates"),
26
27
  testsTemplates: join(ASSETS_DIR, "tests-templates"),
@@ -283,11 +284,16 @@ async function init(opts) {
283
284
  const { count: agentCount, created: agentCreated } = copyDirTracked(ASSET.agents, AGENTS_HOME, { overwrite: true });
284
285
  track(agentCreated);
285
286
  log.ok(`${agentCount} agent file(s) installed.`);
286
- const skillDest = join4(SKILLS_HOME, "contract-driven-delivery");
287
- log.info(`Installing skill \u2192 ${skillDest}`);
288
- const { count: skillCount, created: skillCreated } = copyDirTracked(ASSET.skill, skillDest, { overwrite: true });
289
- track(skillCreated);
290
- log.ok(`${skillCount} skill file(s) installed.`);
287
+ const skillDirs = readdirSync2(ASSET.skills, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
288
+ let totalSkillFiles = 0;
289
+ for (const skillName of skillDirs) {
290
+ const skillDest = join4(SKILLS_HOME, skillName);
291
+ log.info(`Installing skill \u2192 ${skillDest}`);
292
+ const { count, created } = copyDirTracked(join4(ASSET.skills, skillName), skillDest, { overwrite: true });
293
+ track(created);
294
+ totalSkillFiles += count;
295
+ }
296
+ log.ok(`${totalSkillFiles} skill file(s) installed (${skillDirs.length} skills).`);
291
297
  log.blank();
292
298
  }
293
299
  if (!opts.globalOnly) {
@@ -384,7 +390,7 @@ async function init(opts) {
384
390
 
385
391
  // src/commands/update.ts
386
392
  import { join as join5 } from "path";
387
- import { existsSync as existsSync4, mkdirSync as mkdirSync2, readdirSync as readdirSync2, copyFileSync as copyFileSync2, readFileSync as readFileSync3 } from "fs";
393
+ import { existsSync as existsSync4, mkdirSync as mkdirSync2, readdirSync as readdirSync3, copyFileSync as copyFileSync2, readFileSync as readFileSync3 } from "fs";
388
394
  import { createHash } from "crypto";
389
395
  import { homedir as homedir2 } from "os";
390
396
  function fileHash(filePath) {
@@ -396,7 +402,7 @@ function diffDir(src, dest) {
396
402
  if (!existsSync4(src))
397
403
  return entries;
398
404
  function walk(currentSrc, currentDest) {
399
- const items = readdirSync2(currentSrc, { withFileTypes: true });
405
+ const items = readdirSync3(currentSrc, { withFileTypes: true });
400
406
  for (const item of items) {
401
407
  const srcPath = join5(currentSrc, item.name);
402
408
  const destPath = join5(currentDest, item.name);
@@ -432,7 +438,7 @@ function backupDir(dir, backupDest) {
432
438
  return;
433
439
  mkdirSync2(backupDest, { recursive: true });
434
440
  function walk(src, dst) {
435
- const items = readdirSync2(src, { withFileTypes: true });
441
+ const items = readdirSync3(src, { withFileTypes: true });
436
442
  for (const item of items) {
437
443
  const s = join5(src, item.name);
438
444
  const d = join5(dst, item.name);
@@ -499,7 +505,7 @@ async function update(opts) {
499
505
 
500
506
  // src/commands/new-change.ts
501
507
  import { join as join6 } from "path";
502
- import { existsSync as existsSync5, readdirSync as readdirSync3 } from "fs";
508
+ import { existsSync as existsSync5, readdirSync as readdirSync4 } from "fs";
503
509
  var REQUIRED_TEMPLATES = [
504
510
  "change-request.md",
505
511
  "change-classification.md",
@@ -509,7 +515,7 @@ var REQUIRED_TEMPLATES = [
509
515
  ];
510
516
  function listOptional() {
511
517
  try {
512
- const all = readdirSync3(ASSET.specsTemplates).filter((f) => f.endsWith(".md"));
518
+ const all = readdirSync4(ASSET.specsTemplates).filter((f) => f.endsWith(".md"));
513
519
  return all.filter((f) => !REQUIRED_TEMPLATES.includes(f));
514
520
  } catch {
515
521
  return [];
@@ -641,7 +647,7 @@ async function validate(opts) {
641
647
  }
642
648
 
643
649
  // src/commands/gate.ts
644
- import { existsSync as existsSync7, readFileSync as readFileSync4, readdirSync as readdirSync4 } from "fs";
650
+ import { existsSync as existsSync7, readFileSync as readFileSync4, readdirSync as readdirSync5 } from "fs";
645
651
  import { join as join8 } from "path";
646
652
  import { spawnSync as spawnSync2 } from "child_process";
647
653
  var REQUIRED_FILES = [
@@ -685,7 +691,7 @@ async function gate(changeId) {
685
691
  }
686
692
  const agentLogDir = join8(changeDir, "agent-log");
687
693
  if (existsSync7(agentLogDir)) {
688
- const logFiles = readdirSync4(agentLogDir).filter((f) => f.endsWith(".md"));
694
+ const logFiles = readdirSync5(agentLogDir).filter((f) => f.endsWith(".md"));
689
695
  for (const f of logFiles) {
690
696
  const content = readFileSync4(join8(agentLogDir, f), "utf8");
691
697
  const statusMatch = content.match(/^\s*-\s*status:\s*(complete|needs-review|blocked)\s*$/m);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contract-driven-delivery",
3
- "version": "1.7.0",
3
+ "version": "1.8.1",
4
4
  "description": "Contract-driven delivery kit CLI — spec-first, test-first AI-assisted delivery for brownfield systems",
5
5
  "keywords": [
6
6
  "contract-driven",