contract-driven-delivery 2.0.14 → 2.0.16
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 +37 -0
- package/README.md +1 -1
- package/assets/skills/cdd-close/SKILL.md +8 -3
- package/assets/skills/cdd-new/SKILL.md +16 -1
- package/assets/skills/contract-driven-delivery/SKILL.md +4 -1
- package/assets/skills/contract-driven-delivery/references/agent-log-protocol.md +24 -2
- package/assets/skills/contract-driven-delivery/templates/tasks.yml +1 -1
- package/dist/cli/index.js +29 -21
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.0.16] - 2026-05-06
|
|
4
|
+
|
|
5
|
+
New-change scaffold hardening so freshly opened proposals use the installed
|
|
6
|
+
kit version even when an existing project has stale templates on disk.
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
|
|
10
|
+
- **`cdd-kit new` stamps `tasks.yml` with the real change id**: new changes no
|
|
11
|
+
longer start with the `<change-id>` placeholder in the machine-validated task
|
|
12
|
+
metadata.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- **Fresh proposals ignore stale project templates**: regression coverage now
|
|
17
|
+
locks `cdd-kit new` to bundled package templates, so old
|
|
18
|
+
`specs/templates/*` files in a user repo cannot leak into a newly created
|
|
19
|
+
change.
|
|
20
|
+
- **Postinstall sync coverage includes workflow skills**: regression coverage
|
|
21
|
+
now verifies npm postinstall updates standalone skills such as `/cdd-new`,
|
|
22
|
+
keeping agent-log instructions aligned with the installed gate.
|
|
23
|
+
|
|
24
|
+
## [2.0.15] - 2026-05-06
|
|
25
|
+
|
|
26
|
+
Prompt guidance patch for agent-log evidence and closeout learning ownership.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- **Agent-log pointer guidance matches gate behavior**: `/cdd-new` and
|
|
31
|
+
`agent-log-protocol.md` now spell out that a pointer whose text before the
|
|
32
|
+
first `:` contains `/` is validated as a single repo-relative file path, so
|
|
33
|
+
agents avoid parenthetical path notes and slash-containing labels such as
|
|
34
|
+
`I/O:` or `WARNING/OVERDUE:`.
|
|
35
|
+
- **Durable learning ownership is explicit**: prompts now consistently say
|
|
36
|
+
general agents record evidence and findings only, while durable learning
|
|
37
|
+
promotion happens during `/cdd-close` Step 3 and targets `contracts/` or
|
|
38
|
+
project guidance (`CLAUDE.md`/`CODEX.md`).
|
|
39
|
+
|
|
3
40
|
## [2.0.14] - 2026-05-06
|
|
4
41
|
|
|
5
42
|
Operational hardening for real multi-agent CDD runs.
|
package/README.md
CHANGED
|
@@ -190,7 +190,7 @@ After the PR is merged:
|
|
|
190
190
|
**What happens:**
|
|
191
191
|
1. Runs `cdd-kit gate` to confirm the change still passes
|
|
192
192
|
2. Synthesizes `archive.md` — a permanent record of what changed, what tests were added, and what lessons were found
|
|
193
|
-
3.
|
|
193
|
+
3. Promotes only evidence-backed durable learnings to `contracts/` or project guidance (`CLAUDE.md`/`CODEX.md`). General agents record evidence and findings only; durable learning promotion happens during `/cdd-close` Step 3.
|
|
194
194
|
4. Runs `cdd-kit archive add-jwt-auth` — moves the change from `specs/changes/` to `specs/archive/2026/`
|
|
195
195
|
5. Reduces the active context that future Claude sessions need to load
|
|
196
196
|
|
|
@@ -10,7 +10,7 @@ description: Close and archive a completed change. Confirms all tasks are done,
|
|
|
10
10
|
A change is "done" when:
|
|
11
11
|
1. Gate has passed (`cdd-kit gate <change-id>` exits 0)
|
|
12
12
|
2. PR is merged (or change is abandoned)
|
|
13
|
-
3. Durable learnings have been promoted to hot sources: `contracts
|
|
13
|
+
3. Durable learnings have been promoted to hot sources: `contracts/` or project guidance (`CLAUDE.md`/`CODEX.md`)
|
|
14
14
|
|
|
15
15
|
This skill drives steps 2–3 and physically moves the change to `specs/archive/`.
|
|
16
16
|
|
|
@@ -58,7 +58,7 @@ Read `specs/changes/<change-id>/tasks.yml`.
|
|
|
58
58
|
|
|
59
59
|
Check section 7:
|
|
60
60
|
- `7.1 Archive change` — will be ticked after Step 4
|
|
61
|
-
- `7.2 Promote durable learnings to contracts or
|
|
61
|
+
- `7.2 Promote durable learnings to contracts or project guidance` — must be done NOW
|
|
62
62
|
|
|
63
63
|
If `7.2` is `[ ]`, proceed to Step 2.5. If already `[x]` or `[-]`, skip Steps 2.5 and 3.
|
|
64
64
|
|
|
@@ -92,6 +92,11 @@ This file records the close-out evidence, but Step 3 promotion must still be evi
|
|
|
92
92
|
|
|
93
93
|
## Step 3: Promote learnings (task 7.2)
|
|
94
94
|
|
|
95
|
+
General agents do not perform durable learning promotion during `/cdd-new`; they
|
|
96
|
+
only record evidence and findings in artifacts and `agent-log/*.yml`. Durable
|
|
97
|
+
learning promotion happens here, during `/cdd-close` Step 3, and main Claude
|
|
98
|
+
owns the final writes.
|
|
99
|
+
|
|
95
100
|
Read `specs/changes/<change-id>/archive.md` section `## Lessons Promoted to Standards` and cross-check every proposed lesson against agent-log, QA report, contract/test changes, or gate evidence from this change.
|
|
96
101
|
|
|
97
102
|
Classify each candidate:
|
|
@@ -132,7 +137,7 @@ If successful, set task `7.1` to `status: done` in tasks.yml (the file is now in
|
|
|
132
137
|
|
|
133
138
|
Change ID: <change-id>
|
|
134
139
|
Archived to: specs/archive/<year>/<change-id>/
|
|
135
|
-
Learnings promoted: <list what was added to contracts/CLAUDE.md/CODEX.md, or "none">
|
|
140
|
+
Learnings promoted: <list what was added to contracts/ or project guidance (CLAUDE.md/CODEX.md), or "none">
|
|
136
141
|
|
|
137
142
|
specs/changes/<change-id>/ has been removed from the active surface.
|
|
138
143
|
Token cost of future sessions reduced by ~<N> files.
|
|
@@ -96,6 +96,21 @@ inevitable re-classification when the agents discover the ambiguity.
|
|
|
96
96
|
|
|
97
97
|
**Rule**: After EVERY agent completes (whether it writes itself or you write for it), YOU must update the relevant `tasks.yml` task `status:` from `pending` to `done`.
|
|
98
98
|
|
|
99
|
+
**Agent-log pointer rule**: When you or an agent writes `artifacts[].pointer`,
|
|
100
|
+
follow `references/agent-log-protocol.md` exactly. If the text before the first
|
|
101
|
+
`:` contains `/`, `cdd-kit gate` treats that text as a repo-relative file path
|
|
102
|
+
and verifies that the file exists. Therefore each pointer may name only one
|
|
103
|
+
file, file pointers must not include parenthetical notes on the path, and
|
|
104
|
+
slash-containing labels such as `I/O:` or `WARNING/OVERDUE:` must not be used as
|
|
105
|
+
pointer prefixes. Put extra explanation in `notes` or a separate non-path
|
|
106
|
+
artifact pointer instead.
|
|
107
|
+
|
|
108
|
+
**Durable learning rule**: During `/cdd-new`, agents record evidence and
|
|
109
|
+
findings in artifacts and `agent-log/*.yml` only. Do not promote durable lessons
|
|
110
|
+
while the change is still active. Durable learning promotion happens only during
|
|
111
|
+
`/cdd-close` Step 3, where main Claude cross-checks evidence and writes approved
|
|
112
|
+
rules to `contracts/` or project guidance (`CLAUDE.md`/`CODEX.md`).
|
|
113
|
+
|
|
99
114
|
---
|
|
100
115
|
|
|
101
116
|
## Artifact opt-in policy
|
|
@@ -515,4 +530,4 @@ Please review the above items and re-run: cdd-kit gate <change-id>
|
|
|
515
530
|
|
|
516
531
|
The `/cdd-new` workflow is now complete. **Return to normal assistant mode immediately.** Answer any question the user asks — including questions unrelated to this change, new feature discussions, debugging help, or general conversation — without requiring them to use a specific command. The git commit shown in the report is a suggestion, not a required next step; do not wait for it before resuming normal behavior.
|
|
517
532
|
|
|
518
|
-
When the change is merged and ready to close, run `/cdd-close <change-id>` to promote learnings and archive the change directory.
|
|
533
|
+
When the change is merged and ready to close, run `/cdd-close <change-id>` to promote durable learnings to `contracts/` or project guidance (`CLAUDE.md`/`CODEX.md`) and archive the change directory.
|
|
@@ -57,7 +57,10 @@ Use this skill to turn software requests into traceable, testable, CI/CD-gated c
|
|
|
57
57
|
- Invoke ci-cd-gatekeeper to design and enforce the gate plan.
|
|
58
58
|
8. Archive and audit drift.
|
|
59
59
|
- Use `references/spec-drift-policy.md`.
|
|
60
|
-
-
|
|
60
|
+
- General agents record evidence and findings only; durable learning
|
|
61
|
+
promotion happens only during `/cdd-close` Step 3.
|
|
62
|
+
- Durable learnings must be promoted back to `contracts/` or project
|
|
63
|
+
guidance (`CLAUDE.md`/`CODEX.md`).
|
|
61
64
|
- `spec-drift-auditor` must run before every release to main and weekly during active multi-iteration development.
|
|
62
65
|
|
|
63
66
|
## Required gates by risk
|
|
@@ -75,6 +75,22 @@ Concrete pointers only. Allowed forms:
|
|
|
75
75
|
- `cdd-kit gate <id>: 0 errors`
|
|
76
76
|
- `contracts/api/api-contract.md#endpoints`
|
|
77
77
|
|
|
78
|
+
Gate path-existence rule: unless gate is run with `--lax`, any pointer whose
|
|
79
|
+
text before the first `:` contains `/` is treated as a repo-relative file path
|
|
80
|
+
and that file must exist. This makes path-like pointers useful, but it also
|
|
81
|
+
means:
|
|
82
|
+
|
|
83
|
+
- One pointer names one file only. Use separate `artifacts` items for multiple
|
|
84
|
+
files.
|
|
85
|
+
- Do not attach parenthetical notes to a file path, e.g. use
|
|
86
|
+
`src/api/users.ts:45-67`, not `src/api/users.ts (updated):45-67`.
|
|
87
|
+
- Do not start a pointer with slash-containing prose labels such as `I/O:` or
|
|
88
|
+
`WARNING/OVERDUE:`; gate will try to validate `I/O` or `WARNING/OVERDUE` as a
|
|
89
|
+
path. Write those labels in `notes` or after a non-path command/result
|
|
90
|
+
pointer.
|
|
91
|
+
- `n/a (<reason>)` is exempt from path validation and is allowed for genuinely
|
|
92
|
+
inapplicable required artifact types.
|
|
93
|
+
|
|
78
94
|
Never `verified`, `OK`, `done`, or unscoped prose.
|
|
79
95
|
|
|
80
96
|
#### `next-action`
|
|
@@ -133,7 +149,12 @@ verify each item:
|
|
|
133
149
|
- BAD: `{ type: tests-added, pointer: verified }`
|
|
134
150
|
- BAD: `{ type: files-changed, pointer: yes }`
|
|
135
151
|
- BAD: `{ type: contract, pointer: OK }`
|
|
152
|
+
- BAD: `{ type: files-changed, pointer: "src/api/users.ts (updated):45-67" }`
|
|
153
|
+
- BAD: `{ type: test-output, pointer: "I/O: warning reproduced" }`
|
|
154
|
+
- BAD: `{ type: test-output, pointer: "WARNING/OVERDUE: manual follow-up" }`
|
|
136
155
|
Reject any line whose pointer would not let a reviewer click through.
|
|
156
|
+
If the text before the first `:` contains `/`, confirm it is exactly one
|
|
157
|
+
existing repo-relative file path with no parenthetical note.
|
|
137
158
|
- [ ] **If `status: blocked`**, `next-action` is ≥ 10 chars, is NOT `none`,
|
|
138
159
|
`investigate further`, `tbd`, or `n/a`, and names the actual next step
|
|
139
160
|
a human can act on.
|
|
@@ -160,8 +181,9 @@ ship a known-bad log and rely on the gate to catch it.
|
|
|
160
181
|
`Allowed Paths` and `Approved Expansions`.
|
|
161
182
|
6. Any `artifacts` item is missing `type` or `pointer`, or the array is empty.
|
|
162
183
|
7. A required per-agent artifact `type` declared in the agent prompt is missing.
|
|
163
|
-
8.
|
|
164
|
-
not exist on disk; or any
|
|
184
|
+
8. Unless gate is run with `--lax`: any `artifacts` pointer whose text before
|
|
185
|
+
the first `:` contains `/` but does not exist on disk; or any
|
|
186
|
+
runtime-logged read not declared in `files-read`.
|
|
165
187
|
|
|
166
188
|
## Why this lives in references/
|
|
167
189
|
|
|
@@ -36,4 +36,4 @@ tasks:
|
|
|
36
36
|
- { id: "6.3", section: Verification, title: "Informational gates", status: pending }
|
|
37
37
|
- { id: "6.4", section: Verification, title: "Nightly/weekly/manual gates if required", status: pending }
|
|
38
38
|
- { id: "7.1", section: Archive, title: "Archive change", status: pending }
|
|
39
|
-
- { id: "7.2", section: Archive, title: "Promote durable learnings to contracts or
|
|
39
|
+
- { id: "7.2", section: Archive, title: "Promote durable learnings to contracts or project guidance", status: pending }
|
package/dist/cli/index.js
CHANGED
|
@@ -8678,7 +8678,7 @@ __export(migrate_exports, {
|
|
|
8678
8678
|
});
|
|
8679
8679
|
import { join as join18 } from "path";
|
|
8680
8680
|
import { cpSync as cpSync2, existsSync as existsSync15, mkdirSync as mkdirSync7, readdirSync as readdirSync8, readFileSync as readFileSync18, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync8 } from "fs";
|
|
8681
|
-
import
|
|
8681
|
+
import yaml2 from "js-yaml";
|
|
8682
8682
|
function backupChangeDir(cwd, changeId, sessionStamp) {
|
|
8683
8683
|
const backupRoot = join18(cwd, ".cdd", "migrate-backup", sessionStamp);
|
|
8684
8684
|
const backupDir2 = join18(backupRoot, changeId);
|
|
@@ -8854,7 +8854,7 @@ function migrateTasksFile(changeId, changeDir, enableContextGovernance, detected
|
|
|
8854
8854
|
out["section"] = r.section;
|
|
8855
8855
|
return out;
|
|
8856
8856
|
});
|
|
8857
|
-
const yamlOut =
|
|
8857
|
+
const yamlOut = yaml2.dump(data, { lineWidth: -1, noRefs: true });
|
|
8858
8858
|
pendingWrites.push({ path: newPath, content: yamlOut });
|
|
8859
8859
|
pendingDeletes.push({ path: legacyPath });
|
|
8860
8860
|
changed.push(`tasks.md -> tasks.yml (${tasksRows.length} task(s) migrated)`);
|
|
@@ -8922,7 +8922,7 @@ function migrateAgentLogs(changeDir, changed, pendingWrites, pendingDeletes) {
|
|
|
8922
8922
|
continue;
|
|
8923
8923
|
const raw = readFileSync18(fullPath, "utf8");
|
|
8924
8924
|
const parsed = parseLegacyAgentLog(raw);
|
|
8925
|
-
const yamlOut =
|
|
8925
|
+
const yamlOut = yaml2.dump(parsed, { lineWidth: -1, noRefs: true });
|
|
8926
8926
|
pendingWrites.push({ path: yamlFull, content: yamlOut });
|
|
8927
8927
|
pendingDeletes.push({ path: fullPath });
|
|
8928
8928
|
changed.push(`agent-log/${f} -> agent-log/${yamlName}`);
|
|
@@ -10146,7 +10146,7 @@ __export(archive_exports, {
|
|
|
10146
10146
|
});
|
|
10147
10147
|
import { join as join23 } from "path";
|
|
10148
10148
|
import { existsSync as existsSync19, mkdirSync as mkdirSync10, renameSync as renameSync2, readFileSync as readFileSync23, writeFileSync as writeFileSync11, appendFileSync, cpSync as cpSync3, rmSync as rmSync3 } from "fs";
|
|
10149
|
-
import
|
|
10149
|
+
import yaml3 from "js-yaml";
|
|
10150
10150
|
async function archive(changeId) {
|
|
10151
10151
|
const cwd = process.cwd();
|
|
10152
10152
|
const changeDir = join23(cwd, "specs", "changes", changeId);
|
|
@@ -10166,7 +10166,7 @@ async function archive(changeId) {
|
|
|
10166
10166
|
if (existsSync19(tasksPath)) {
|
|
10167
10167
|
try {
|
|
10168
10168
|
const raw = readFileSync23(tasksPath, "utf8");
|
|
10169
|
-
const data =
|
|
10169
|
+
const data = yaml3.load(raw);
|
|
10170
10170
|
if (data?.status === "gate-blocked") {
|
|
10171
10171
|
log.warn("tasks.yml has status: gate-blocked \u2014 archiving anyway (change was paused).");
|
|
10172
10172
|
}
|
|
@@ -10222,7 +10222,7 @@ __export(abandon_exports, {
|
|
|
10222
10222
|
});
|
|
10223
10223
|
import { join as join24 } from "path";
|
|
10224
10224
|
import { existsSync as existsSync20, readFileSync as readFileSync24, writeFileSync as writeFileSync12, appendFileSync as appendFileSync2, mkdirSync as mkdirSync11 } from "fs";
|
|
10225
|
-
import
|
|
10225
|
+
import yaml4 from "js-yaml";
|
|
10226
10226
|
async function abandon(changeId, opts) {
|
|
10227
10227
|
const cwd = process.cwd();
|
|
10228
10228
|
const changeDir = join24(cwd, "specs", "changes", changeId);
|
|
@@ -10233,12 +10233,12 @@ async function abandon(changeId, opts) {
|
|
|
10233
10233
|
}
|
|
10234
10234
|
if (existsSync20(tasksPath)) {
|
|
10235
10235
|
const raw = readFileSync24(tasksPath, "utf8");
|
|
10236
|
-
const data =
|
|
10236
|
+
const data = yaml4.load(raw) ?? {};
|
|
10237
10237
|
data["status"] = "abandoned";
|
|
10238
10238
|
if (!data["change-id"]) {
|
|
10239
10239
|
data["change-id"] = changeId;
|
|
10240
10240
|
}
|
|
10241
|
-
writeFileSync12(tasksPath,
|
|
10241
|
+
writeFileSync12(tasksPath, yaml4.dump(data, { lineWidth: -1, noRefs: true }), "utf8");
|
|
10242
10242
|
}
|
|
10243
10243
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
10244
10244
|
const archiveDir = join24(cwd, "specs", "archive");
|
|
@@ -10276,7 +10276,7 @@ __export(list_changes_exports, {
|
|
|
10276
10276
|
});
|
|
10277
10277
|
import { join as join25 } from "path";
|
|
10278
10278
|
import { existsSync as existsSync21, readdirSync as readdirSync13, readFileSync as readFileSync25 } from "fs";
|
|
10279
|
-
import
|
|
10279
|
+
import yaml5 from "js-yaml";
|
|
10280
10280
|
async function listChanges() {
|
|
10281
10281
|
const cwd = process.cwd();
|
|
10282
10282
|
const changesDir = join25(cwd, "specs", "changes");
|
|
@@ -10296,7 +10296,7 @@ async function listChanges() {
|
|
|
10296
10296
|
if (existsSync21(tasksPath)) {
|
|
10297
10297
|
try {
|
|
10298
10298
|
const raw = readFileSync25(tasksPath, "utf8");
|
|
10299
|
-
const data =
|
|
10299
|
+
const data = yaml5.load(raw);
|
|
10300
10300
|
if (data?.status)
|
|
10301
10301
|
status = data.status;
|
|
10302
10302
|
pending = (data?.tasks ?? []).filter((t) => t.status === "pending").length;
|
|
@@ -11104,7 +11104,6 @@ init_paths();
|
|
|
11104
11104
|
import { join as join9, relative as relative3 } from "path";
|
|
11105
11105
|
import { createHash as createHash4 } from "crypto";
|
|
11106
11106
|
import { existsSync as existsSync8, readFileSync as readFileSync8, readdirSync as readdirSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
11107
|
-
import yaml from "js-yaml";
|
|
11108
11107
|
init_logger();
|
|
11109
11108
|
init_context_scan();
|
|
11110
11109
|
init_digest();
|
|
@@ -11173,6 +11172,20 @@ function parseDependsOn(raw) {
|
|
|
11173
11172
|
return [];
|
|
11174
11173
|
return raw.split(",").map((item) => item.trim()).filter(Boolean);
|
|
11175
11174
|
}
|
|
11175
|
+
function applyScaffoldMetadata(tasksPath, changeId, dependencies) {
|
|
11176
|
+
if (!existsSync8(tasksPath))
|
|
11177
|
+
return;
|
|
11178
|
+
let raw = readFileSync8(tasksPath, "utf8");
|
|
11179
|
+
raw = raw.replace(/^change-id:\s*<change-id>\s*$/m, `change-id: ${changeId}`);
|
|
11180
|
+
if (dependencies.length > 0) {
|
|
11181
|
+
const dependsOn = [
|
|
11182
|
+
"depends-on:",
|
|
11183
|
+
...dependencies.map((dep) => ` - ${JSON.stringify(dep)}`)
|
|
11184
|
+
].join("\n");
|
|
11185
|
+
raw = raw.replace(/^depends-on:\s*\[\]\s*$/m, dependsOn);
|
|
11186
|
+
}
|
|
11187
|
+
writeFileSync4(tasksPath, raw, "utf8");
|
|
11188
|
+
}
|
|
11176
11189
|
async function newChange(name, opts) {
|
|
11177
11190
|
if (!SAFE_NAME.test(name)) {
|
|
11178
11191
|
log.error(`Invalid change name: "${name}". Use letters, numbers, hyphens, or underscores (max 64 chars).`);
|
|
@@ -11220,15 +11233,10 @@ async function newChange(name, opts) {
|
|
|
11220
11233
|
log.dim(tmpl);
|
|
11221
11234
|
written += 1;
|
|
11222
11235
|
}
|
|
11236
|
+
const tasksPath = join9(changeDir, "tasks.yml");
|
|
11237
|
+
applyScaffoldMetadata(tasksPath, name, dependencies);
|
|
11223
11238
|
if (dependencies.length > 0) {
|
|
11224
|
-
|
|
11225
|
-
if (existsSync8(tasksPath)) {
|
|
11226
|
-
const raw = readFileSync8(tasksPath, "utf8");
|
|
11227
|
-
const data = yaml.load(raw) ?? {};
|
|
11228
|
-
data["depends-on"] = dependencies;
|
|
11229
|
-
writeFileSync4(tasksPath, yaml.dump(data, { lineWidth: -1, noRefs: true }), "utf8");
|
|
11230
|
-
log.dim(`depends-on: ${dependencies.join(", ")}`);
|
|
11231
|
-
}
|
|
11239
|
+
log.dim(`depends-on: ${dependencies.join(", ")}`);
|
|
11232
11240
|
}
|
|
11233
11241
|
log.blank();
|
|
11234
11242
|
log.ok(`${written} template(s) created in specs/changes/${name}`);
|
|
@@ -11330,7 +11338,7 @@ init_logger();
|
|
|
11330
11338
|
import { existsSync as existsSync13, readFileSync as readFileSync16, readdirSync as readdirSync7 } from "fs";
|
|
11331
11339
|
import { homedir as homedir3 } from "os";
|
|
11332
11340
|
import { join as join16 } from "path";
|
|
11333
|
-
import
|
|
11341
|
+
import yaml from "js-yaml";
|
|
11334
11342
|
import picomatch2 from "picomatch";
|
|
11335
11343
|
|
|
11336
11344
|
// src/schemas/agent-log.schema.ts
|
|
@@ -11571,7 +11579,7 @@ function loadContextPolicy(cwd) {
|
|
|
11571
11579
|
function loadYamlFile(path) {
|
|
11572
11580
|
try {
|
|
11573
11581
|
const raw = readFileSync16(path, "utf8");
|
|
11574
|
-
return { data:
|
|
11582
|
+
return { data: yaml.load(raw, { schema: yaml.JSON_SCHEMA }), parseError: null };
|
|
11575
11583
|
} catch (err) {
|
|
11576
11584
|
return { data: null, parseError: err.message };
|
|
11577
11585
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "contract-driven-delivery",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.16",
|
|
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",
|