@sdd-method/sdd-cli 1.29.1 → 1.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/index.d.ts.map +1 -1
  2. package/dist/index.js +2 -0
  3. package/dist/index.js.map +1 -1
  4. package/dist/lib/catalogue/graph-run.d.ts +1 -28
  5. package/dist/lib/catalogue/graph-run.d.ts.map +1 -1
  6. package/dist/lib/catalogue/graph-run.js +3 -57
  7. package/dist/lib/catalogue/graph-run.js.map +1 -1
  8. package/dist/lib/catalogue/impact-run.d.ts +1 -1
  9. package/dist/lib/catalogue/impact-run.d.ts.map +1 -1
  10. package/dist/lib/catalogue/impact-run.js +1 -1
  11. package/dist/lib/catalogue/impact-run.js.map +1 -1
  12. package/dist/lib/catalogue/relationship-semantics.d.ts +29 -0
  13. package/dist/lib/catalogue/relationship-semantics.d.ts.map +1 -0
  14. package/dist/lib/catalogue/relationship-semantics.js +66 -0
  15. package/dist/lib/catalogue/relationship-semantics.js.map +1 -0
  16. package/dist/lib/pack/index.d.ts +1 -9
  17. package/dist/lib/pack/index.d.ts.map +1 -1
  18. package/dist/lib/pack/index.js +2 -53
  19. package/dist/lib/pack/index.js.map +1 -1
  20. package/dist/lib/pack/log.d.ts +6 -0
  21. package/dist/lib/pack/log.d.ts.map +1 -0
  22. package/dist/lib/pack/log.js +18 -0
  23. package/dist/lib/pack/log.js.map +1 -0
  24. package/dist/lib/pack/validate.d.ts +10 -0
  25. package/dist/lib/pack/validate.d.ts.map +1 -0
  26. package/dist/lib/pack/validate.js +49 -0
  27. package/dist/lib/pack/validate.js.map +1 -0
  28. package/dist/lib/snapshot/advance.d.ts +39 -0
  29. package/dist/lib/snapshot/advance.d.ts.map +1 -0
  30. package/dist/lib/snapshot/advance.js +253 -0
  31. package/dist/lib/snapshot/advance.js.map +1 -0
  32. package/dist/lib/snapshot/catalogue-diff.d.ts +21 -0
  33. package/dist/lib/snapshot/catalogue-diff.d.ts.map +1 -0
  34. package/dist/lib/snapshot/catalogue-diff.js +133 -0
  35. package/dist/lib/snapshot/catalogue-diff.js.map +1 -0
  36. package/dist/lib/snapshot/diff.d.ts +73 -0
  37. package/dist/lib/snapshot/diff.d.ts.map +1 -0
  38. package/dist/lib/snapshot/diff.js +177 -0
  39. package/dist/lib/snapshot/diff.js.map +1 -0
  40. package/dist/lib/snapshot/fold.d.ts +14 -0
  41. package/dist/lib/snapshot/fold.d.ts.map +1 -0
  42. package/dist/lib/snapshot/fold.js +106 -0
  43. package/dist/lib/snapshot/fold.js.map +1 -0
  44. package/dist/lib/snapshot/land.d.ts +21 -0
  45. package/dist/lib/snapshot/land.d.ts.map +1 -0
  46. package/dist/lib/snapshot/land.js +160 -0
  47. package/dist/lib/snapshot/land.js.map +1 -0
  48. package/dist/lib/snapshot/manifest.d.ts +59 -0
  49. package/dist/lib/snapshot/manifest.d.ts.map +1 -0
  50. package/dist/lib/snapshot/manifest.js +152 -0
  51. package/dist/lib/snapshot/manifest.js.map +1 -0
  52. package/dist/lib/snapshot/targets.d.ts +26 -0
  53. package/dist/lib/snapshot/targets.d.ts.map +1 -0
  54. package/dist/lib/snapshot/targets.js +121 -0
  55. package/dist/lib/snapshot/targets.js.map +1 -0
  56. package/dist/lib/snapshot/verify.d.ts +18 -0
  57. package/dist/lib/snapshot/verify.d.ts.map +1 -0
  58. package/dist/lib/snapshot/verify.js +82 -0
  59. package/dist/lib/snapshot/verify.js.map +1 -0
  60. package/dist/verbs/catalogue-verify.d.ts +6 -0
  61. package/dist/verbs/catalogue-verify.d.ts.map +1 -0
  62. package/dist/verbs/catalogue-verify.js +114 -0
  63. package/dist/verbs/catalogue-verify.js.map +1 -0
  64. package/dist/verbs/catalogue.d.ts.map +1 -1
  65. package/dist/verbs/catalogue.js +15 -90
  66. package/dist/verbs/catalogue.js.map +1 -1
  67. package/dist/verbs/pack-validate.d.ts +3 -0
  68. package/dist/verbs/pack-validate.d.ts.map +1 -0
  69. package/dist/verbs/pack-validate.js +17 -0
  70. package/dist/verbs/pack-validate.js.map +1 -0
  71. package/dist/verbs/pack.d.ts.map +1 -1
  72. package/dist/verbs/pack.js +3 -10
  73. package/dist/verbs/pack.js.map +1 -1
  74. package/dist/verbs/snapshot.d.ts +3 -0
  75. package/dist/verbs/snapshot.d.ts.map +1 -0
  76. package/dist/verbs/snapshot.js +119 -0
  77. package/dist/verbs/snapshot.js.map +1 -0
  78. package/dist/verify-bin.d.ts +3 -0
  79. package/dist/verify-bin.d.ts.map +1 -0
  80. package/dist/verify-bin.js +8 -0
  81. package/dist/verify-bin.js.map +1 -0
  82. package/dist/verify-program.d.ts +14 -0
  83. package/dist/verify-program.d.ts.map +1 -0
  84. package/dist/verify-program.js +115 -0
  85. package/dist/verify-program.js.map +1 -0
  86. package/package.json +3 -3
  87. package/scripts/build-verify-package.mjs +199 -0
  88. package/scripts/verify-acceptance.sh +178 -0
  89. package/dist/conformance-bin.d.ts +0 -3
  90. package/dist/conformance-bin.d.ts.map +0 -1
  91. package/dist/conformance-bin.js +0 -8
  92. package/dist/conformance-bin.js.map +0 -1
  93. package/dist/conformance-program.d.ts +0 -6
  94. package/dist/conformance-program.d.ts.map +0 -1
  95. package/dist/conformance-program.js +0 -59
  96. package/dist/conformance-program.js.map +0 -1
  97. package/scripts/build-conformance-package.mjs +0 -57
@@ -0,0 +1,152 @@
1
+ // Implementation-set snapshot manifests (`<area>/<baseline-id>/snapshot.yaml`)
2
+ // and the file-level primitives the `snapshot` verbs share.
3
+ //
4
+ // The shape is the method's, not this module's: reverse/artifact-conventions.md
5
+ // "Implementation-Set Snapshots". Where the conventions REQUIRE a companion
6
+ // field (`carried_reason` beside `carried_from`, `reverification` beside
7
+ // `reverified_at`), readManifest refuses a manifest without it — a carried member
8
+ // with no reason cannot be told apart from an unrecorded removal.
9
+ import { createHash } from "node:crypto";
10
+ import { readdir, readFile, stat } from "node:fs/promises";
11
+ import { join, relative, sep } from "node:path";
12
+ import { parse } from "yaml";
13
+ export class SnapshotError extends Error {
14
+ }
15
+ const DATE = /^\d{4}-\d{2}-\d{2}$/;
16
+ export function isIsoDate(s) {
17
+ if (typeof s !== "string" || !DATE.test(s))
18
+ return false;
19
+ const d = new Date(`${s}T00:00:00Z`);
20
+ return !Number.isNaN(d.getTime()) && d.toISOString().slice(0, 10) === s;
21
+ }
22
+ /** `name-branch@rev` → { stem: "name-branch", revision: "rev" }. */
23
+ export function splitFolder(folder) {
24
+ const at = folder.lastIndexOf("@");
25
+ if (at <= 0 || at === folder.length - 1)
26
+ return null;
27
+ return { stem: folder.slice(0, at), revision: folder.slice(at + 1) };
28
+ }
29
+ /** Member folders (`*@*` directories) directly under a baseline directory. */
30
+ export async function memberFolders(baselineDir) {
31
+ const out = [];
32
+ for (const e of await readdir(baselineDir, { withFileTypes: true })) {
33
+ if (e.isDirectory() && splitFolder(e.name) !== null)
34
+ out.push(e.name);
35
+ }
36
+ return out.sort();
37
+ }
38
+ /** Dated baseline ids under an area, ascending. */
39
+ export async function baselineIds(areaRoot) {
40
+ const out = [];
41
+ for (const e of await readdir(areaRoot, { withFileTypes: true })) {
42
+ if (e.isDirectory() && isIsoDate(e.name))
43
+ out.push(e.name);
44
+ }
45
+ return out.sort();
46
+ }
47
+ export async function exists(p) {
48
+ try {
49
+ await stat(p);
50
+ return true;
51
+ }
52
+ catch {
53
+ return false;
54
+ }
55
+ }
56
+ export function manifestPath(areaRoot, id) {
57
+ return join(areaRoot, id, "snapshot.yaml");
58
+ }
59
+ export async function readManifest(areaRoot, id) {
60
+ const p = manifestPath(areaRoot, id);
61
+ if (!(await exists(p)))
62
+ throw new SnapshotError(`no manifest at ${p}`);
63
+ const raw = parse(await readFile(p, "utf8"));
64
+ if (raw === null || typeof raw !== "object")
65
+ throw new SnapshotError(`${p}: not a mapping`);
66
+ const problems = [];
67
+ if (raw.snapshot_id !== id)
68
+ problems.push(`snapshot_id '${String(raw.snapshot_id)}' does not match its folder '${id}'`);
69
+ if (!isIsoDate(raw.observed_at))
70
+ problems.push("observed_at must be YYYY-MM-DD");
71
+ if (typeof raw.implementation !== "string" || raw.implementation === "")
72
+ problems.push("implementation missing");
73
+ if (raw.prior_snapshot !== null && raw.prior_snapshot !== undefined && !isIsoDate(raw.prior_snapshot)) {
74
+ problems.push("prior_snapshot must be a baseline id or null");
75
+ }
76
+ if (!Array.isArray(raw.members))
77
+ problems.push("members must be a list");
78
+ // A hand-written revision of digits only (`50834756022`) parses as a NUMBER, and
79
+ // a strict comparison with the folder's string suffix then calls an unchanged
80
+ // member changed. Identity fields are strings, whatever YAML made of them.
81
+ for (const m of raw.members ?? []) {
82
+ if (m && typeof m === "object") {
83
+ for (const f of ["canonical_repo_key", "exported_folder_name", "source_revision"]) {
84
+ if (typeof m[f] === "number")
85
+ m[f] = String(m[f]);
86
+ }
87
+ }
88
+ }
89
+ for (const r of raw.members_removed ?? []) {
90
+ if (r && typeof r.last_revision === "number")
91
+ r.last_revision = String(r.last_revision);
92
+ }
93
+ for (const [i, m] of (raw.members ?? []).entries()) {
94
+ const at = `members[${i}] (${m?.canonical_repo_key ?? "?"})`;
95
+ if (!m?.canonical_repo_key || !m.exported_folder_name || !m.source_revision) {
96
+ problems.push(`${at}: canonical_repo_key, exported_folder_name and source_revision are required`);
97
+ }
98
+ if (m?.carried_from !== undefined && !m.carried_reason)
99
+ problems.push(`${at}: carried_from requires carried_reason`);
100
+ if (m?.reverified_at !== undefined && !m.reverification)
101
+ problems.push(`${at}: reverified_at requires reverification`);
102
+ }
103
+ for (const [i, r] of (raw.members_removed ?? []).entries()) {
104
+ if (!r?.canonical_repo_key || !r.last_revision || !r.reason) {
105
+ problems.push(`members_removed[${i}]: canonical_repo_key, last_revision and reason are required`);
106
+ }
107
+ }
108
+ if (problems.length > 0)
109
+ throw new SnapshotError(`${p}:\n - ${problems.join("\n - ")}`);
110
+ return raw;
111
+ }
112
+ /** Where a member's bytes live: its own baseline, or the one it was carried from. */
113
+ export function memberBytesDir(areaRoot, manifest, m) {
114
+ return join(areaRoot, m.carried_from ?? manifest.snapshot_id, m.exported_folder_name);
115
+ }
116
+ /** relative path → sha256 for every file under a directory. */
117
+ export async function hashTree(root) {
118
+ const out = new Map();
119
+ async function walk(dir) {
120
+ for (const e of await readdir(dir, { withFileTypes: true })) {
121
+ const full = join(dir, e.name);
122
+ if (e.isDirectory()) {
123
+ if (e.name === ".git")
124
+ continue;
125
+ await walk(full);
126
+ }
127
+ else if (e.isFile()) {
128
+ const h = createHash("sha256").update(await readFile(full)).digest("hex");
129
+ out.set(relative(root, full).split(sep).join("/"), h);
130
+ }
131
+ }
132
+ }
133
+ await walk(root);
134
+ return out;
135
+ }
136
+ export function diffTrees(before, after) {
137
+ const added = [];
138
+ const removed = [];
139
+ const modified = [];
140
+ for (const [p, h] of after) {
141
+ const b = before.get(p);
142
+ if (b === undefined)
143
+ added.push(p);
144
+ else if (b !== h)
145
+ modified.push(p);
146
+ }
147
+ for (const p of before.keys())
148
+ if (!after.has(p))
149
+ removed.push(p);
150
+ return { added: added.sort(), removed: removed.sort(), modified: modified.sort() };
151
+ }
152
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../src/lib/snapshot/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { type DeltaFinding } from "./diff.js";
2
+ type Writer = (s: string) => void;
3
+ export interface TargetsInputs {
4
+ sddPath: string;
5
+ areaRoot: string;
6
+ id: string;
7
+ }
8
+ export interface Target {
9
+ artefact: string;
10
+ grain: "file" | "repo";
11
+ cited: string;
12
+ }
13
+ /** Every text artefact of the SDD, excluding the method's own copies and generated catalogues. */
14
+ export declare function sddArtefacts(sddPath: string): Promise<Map<string, string>>;
15
+ /**
16
+ * `shared` holds paths that more than one member changed (`helm/values.yaml`,
17
+ * `src/main/resources/application.properties`): a citation of one of those names
18
+ * nobody in particular, so it is file grain only on a line that also names this
19
+ * member. Without that, a citation of another member's copy reads as precise.
20
+ */
21
+ export declare function routeFinding(f: Pick<DeltaFinding, "member" | "files">, artefacts: ReadonlyMap<string, string>, shared?: ReadonlySet<string>): Target[];
22
+ export declare function runSnapshotTargets(inputs: TargetsInputs, write: Writer): Promise<{
23
+ exitCode: number;
24
+ }>;
25
+ export {};
26
+ //# sourceMappingURL=targets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"targets.d.ts","sourceRoot":"","sources":["../../../src/lib/snapshot/targets.ts"],"names":[],"mappings":"AAeA,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzD,KAAK,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;AAElC,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,MAAM;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAMD,kGAAkG;AAClG,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAgBhF;AAMD;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,GAAG,OAAO,CAAC,EACzC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACtC,MAAM,GAAE,WAAW,CAAC,MAAM,CAAa,GACtC,MAAM,EAAE,CAkBV;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAoD5G"}
@@ -0,0 +1,121 @@
1
+ // `sdd-cli snapshot targets` — route each delta.yaml finding to the SDD
2
+ // artefacts it grounds, recording the GRAIN each route was found at:
3
+ //
4
+ // file — the artefact cites a changed file's path (feature-grounding style
5
+ // evidence citing `src/…`): the route is as precise as the citation;
6
+ // repo — the artefact only names the member's canonical_repo_key: the route
7
+ // reaches everything that repo grounds, and must not read as precise.
8
+ //
9
+ // Findings whose targets are already set are left alone (routing refined by
10
+ // hand is judgement). Findings nothing cites are listed as unroutable, never
11
+ // dropped. Writes back into delta.yaml preserving everything else in it.
12
+ import { readdir, readFile, stat, writeFile } from "node:fs/promises";
13
+ import { join, relative, sep } from "node:path";
14
+ import { parseDocument } from "yaml";
15
+ import { deltaPath } from "./diff.js";
16
+ import { SnapshotError, exists } from "./manifest.js";
17
+ const TEXT = /\.(md|ya?ml|json|txt|adoc|mermaid|puml|csv)$/i;
18
+ const SKIP_DIRS = new Set([".git", "node_modules", ".sdd", "catalogues"]);
19
+ const MAX_BYTES = 4 * 1024 * 1024;
20
+ /** Every text artefact of the SDD, excluding the method's own copies and generated catalogues. */
21
+ export async function sddArtefacts(sddPath) {
22
+ const out = new Map();
23
+ async function walk(dir) {
24
+ for (const e of await readdir(dir, { withFileTypes: true })) {
25
+ const full = join(dir, e.name);
26
+ const rel = relative(sddPath, full).split(sep).join("/");
27
+ if (e.isDirectory()) {
28
+ if (SKIP_DIRS.has(e.name) || rel === "docs/method")
29
+ continue;
30
+ await walk(full);
31
+ }
32
+ else if (e.isFile() && TEXT.test(e.name) && (await stat(full)).size <= MAX_BYTES) {
33
+ out.set(rel, await readFile(full, "utf8"));
34
+ }
35
+ }
36
+ }
37
+ await walk(sddPath);
38
+ return out;
39
+ }
40
+ // A path needs two segments to be a citation rather than a coincidence:
41
+ // `pom.xml` alone appears in every Java SDD.
42
+ const citable = (p) => p.includes("/");
43
+ /**
44
+ * `shared` holds paths that more than one member changed (`helm/values.yaml`,
45
+ * `src/main/resources/application.properties`): a citation of one of those names
46
+ * nobody in particular, so it is file grain only on a line that also names this
47
+ * member. Without that, a citation of another member's copy reads as precise.
48
+ */
49
+ export function routeFinding(f, artefacts, shared = new Set()) {
50
+ const targets = new Map();
51
+ const paths = [...f.files.added, ...f.files.removed, ...f.files.modified].filter(citable);
52
+ // The key alone, or in export-folder form (`<key>-master@<rev>`): a hyphen may
53
+ // follow it only as a branch suffix, so `tcu` never matches inside `tcu-collector`.
54
+ const keyRe = new RegExp(`(^|[^A-Za-z0-9_-])${f.member.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(-(master|main|develop|trunk)@|[^A-Za-z0-9_-]|$)`);
55
+ const cites = (text, p) => shared.has(p) ? text.split("\n").some((line) => line.includes(p) && keyRe.test(line)) : text.includes(p);
56
+ for (const [rel, text] of artefacts) {
57
+ const hit = paths.find((p) => cites(text, p));
58
+ if (hit)
59
+ targets.set(rel, { artefact: rel, grain: "file", cited: hit });
60
+ }
61
+ for (const [rel, text] of artefacts) {
62
+ if (!targets.has(rel) && keyRe.test(text))
63
+ targets.set(rel, { artefact: rel, grain: "repo", cited: f.member });
64
+ }
65
+ return [...targets.values()].sort((a, b) => (a.grain === b.grain ? a.artefact.localeCompare(b.artefact) : a.grain === "file" ? -1 : 1));
66
+ }
67
+ export async function runSnapshotTargets(inputs, write) {
68
+ const dp = deltaPath(inputs.areaRoot, inputs.id);
69
+ if (!(await exists(dp))) {
70
+ write(`REFUSED: no ${dp} — run snapshot diff first\n`);
71
+ return { exitCode: 1 };
72
+ }
73
+ try {
74
+ const doc = parseDocument(await readFile(dp, "utf8"));
75
+ const findings = doc.toJS().findings ?? [];
76
+ const artefacts = await sddArtefacts(inputs.sddPath);
77
+ const owners = new Map();
78
+ for (const f of findings) {
79
+ for (const p of [...(f.files?.added ?? []), ...(f.files?.removed ?? []), ...(f.files?.modified ?? [])]) {
80
+ if (!owners.has(p))
81
+ owners.set(p, new Set());
82
+ owners.get(p).add(f.member);
83
+ }
84
+ }
85
+ const shared = new Set([...owners].filter(([, m]) => m.size > 1).map(([p]) => p));
86
+ let routed = 0;
87
+ let kept = 0;
88
+ const unroutable = [];
89
+ const grains = { file: 0, repo: 0 };
90
+ for (const [i, f] of findings.entries()) {
91
+ if (Array.isArray(f.targets) && f.targets.length > 0) {
92
+ kept++;
93
+ continue;
94
+ }
95
+ const t = routeFinding(f, artefacts, shared);
96
+ if (t.length === 0) {
97
+ unroutable.push(f.id);
98
+ continue;
99
+ }
100
+ for (const x of t)
101
+ grains[x.grain]++;
102
+ doc.setIn(["findings", i, "targets"], doc.createNode(t));
103
+ routed++;
104
+ }
105
+ await writeFile(dp, doc.toString({ lineWidth: 0 }));
106
+ write(`${routed} finding(s) routed (${grains.file} file-grain, ${grains.repo} repo-grain target(s)); ${kept} already targeted, left alone; ` +
107
+ `${unroutable.length} unroutable${unroutable.length ? `: ${unroutable.join(", ")}` : ""}\n`);
108
+ if (grains.repo > 0) {
109
+ write("note: a repo-grain target reaches everything that repo grounds — narrow it by hand before re-reversing\n");
110
+ }
111
+ return { exitCode: 0 };
112
+ }
113
+ catch (e) {
114
+ if (e instanceof SnapshotError) {
115
+ write(`REFUSED: ${e.message}\n`);
116
+ return { exitCode: 1 };
117
+ }
118
+ throw e;
119
+ }
120
+ }
121
+ //# sourceMappingURL=targets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"targets.js","sourceRoot":"","sources":["../../../src/lib/snapshot/targets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ type Writer = (s: string) => void;
2
+ export interface Waiver {
3
+ who: string;
4
+ why: string;
5
+ date: string;
6
+ }
7
+ export interface VerifyInputs {
8
+ areaRoot: string;
9
+ id: string;
10
+ confirmed?: ReadonlyMap<string, string>;
11
+ waiver?: Partial<Waiver>;
12
+ today?: string;
13
+ }
14
+ export declare function runSnapshotVerify(inputs: VerifyInputs, write: Writer): Promise<{
15
+ exitCode: number;
16
+ }>;
17
+ export {};
18
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/lib/snapshot/verify.ts"],"names":[],"mappings":"AAoBA,KAAK,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;AAElC,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAoD1G"}
@@ -0,0 +1,82 @@
1
+ // `sdd-cli snapshot verify` — T0 provenance before the diff is trusted
2
+ // (delta-reverse.md §3).
3
+ //
4
+ // Two legs. LOCAL, checked here: each member folder exists, its `@revision`
5
+ // suffix matches source_revision, and where the export kept its `.git`, HEAD is
6
+ // that revision. CANONICAL — that the revision is a real commit on the canonical
7
+ // repo — cannot be proven from an export, so it is supplied: `--confirmed
8
+ // key=<how it was checked>` per member, or one recorded `--waiver` (who, why,
9
+ // date). A member with neither is "cannot assert", which FAILS: could-not-check
10
+ // is never silently checked. The result is written beside the baseline as
11
+ // provenance.yaml, so the waiver travels with the baseline it excuses.
12
+ import { execFile as execFileCb } from "node:child_process";
13
+ import { writeFile } from "node:fs/promises";
14
+ import { join } from "node:path";
15
+ import { promisify } from "node:util";
16
+ import { stringify } from "yaml";
17
+ import { SnapshotError, exists, isIsoDate, memberBytesDir, readManifest, splitFolder } from "./manifest.js";
18
+ const execFile = promisify(execFileCb);
19
+ export async function runSnapshotVerify(inputs, write) {
20
+ try {
21
+ const m = await readManifest(inputs.areaRoot, inputs.id);
22
+ const w = inputs.waiver;
23
+ if (w && (!w.who || !w.why || !isIsoDate(w.date))) {
24
+ throw new SnapshotError("--waiver needs who=…,why=…,date=YYYY-MM-DD — an unattributed waiver is a skip with a name on it");
25
+ }
26
+ const rows = [];
27
+ const failures = [];
28
+ for (const mem of m.members) {
29
+ const dir = memberBytesDir(inputs.areaRoot, m, mem);
30
+ let local = "ok";
31
+ if (!(await exists(dir)))
32
+ local = `FAIL: ${dir} does not exist`;
33
+ else if (splitFolder(mem.exported_folder_name)?.revision !== mem.source_revision) {
34
+ local = `FAIL: folder revision does not match source_revision ${mem.source_revision}`;
35
+ }
36
+ else if (await exists(join(dir, ".git"))) {
37
+ const head = (await execFile("git", ["-C", dir, "rev-parse", "HEAD"])).stdout.trim();
38
+ if (!head.startsWith(mem.source_revision))
39
+ local = `FAIL: .git HEAD ${head} is not ${mem.source_revision}`;
40
+ else
41
+ local = "ok (git HEAD matches)";
42
+ }
43
+ const how = inputs.confirmed?.get(mem.canonical_repo_key);
44
+ const canonical = how ? `confirmed: ${how}` : w ? "waived" : "CANNOT ASSERT";
45
+ if (local.startsWith("FAIL"))
46
+ failures.push(`${mem.canonical_repo_key}: ${local}`);
47
+ if (canonical === "CANNOT ASSERT")
48
+ failures.push(`${mem.canonical_repo_key}: canonical provenance not confirmed and no waiver`);
49
+ rows.push({ canonical_repo_key: mem.canonical_repo_key, local, canonical });
50
+ }
51
+ for (const k of inputs.confirmed?.keys() ?? []) {
52
+ if (!m.members.some((x) => x.canonical_repo_key === k))
53
+ throw new SnapshotError(`--confirmed ${k}: not a member of ${inputs.id}`);
54
+ }
55
+ const report = {
56
+ baseline: inputs.id,
57
+ verified_at: inputs.today ?? new Date().toISOString().slice(0, 10),
58
+ result: failures.length === 0 ? (w ? "pass-with-waiver" : "pass") : "fail",
59
+ ...(w ? { waiver: w } : {}),
60
+ members: rows,
61
+ };
62
+ await writeFile(join(inputs.areaRoot, inputs.id, "provenance.yaml"), stringify(report, { lineWidth: 0 }));
63
+ for (const r of rows)
64
+ write(`${r.canonical_repo_key}: local ${r.local}; canonical ${r.canonical}\n`);
65
+ if (w)
66
+ write(`WAIVER in force — ${w.who}, ${w.date}: ${w.why}\n`);
67
+ if (failures.length > 0) {
68
+ write(`FAIL: ${failures.length} problem(s); written to provenance.yaml\n`);
69
+ return { exitCode: 1 };
70
+ }
71
+ write(`${report.result}: ${rows.length} member(s)\n`);
72
+ return { exitCode: 0 };
73
+ }
74
+ catch (e) {
75
+ if (e instanceof SnapshotError) {
76
+ write(`REFUSED: ${e.message}\n`);
77
+ return { exitCode: 1 };
78
+ }
79
+ throw e;
80
+ }
81
+ }
82
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/lib/snapshot/verify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerCatalogueValidate(catalogue: Command): void;
3
+ export declare function registerCatalogueImpact(catalogue: Command): void;
4
+ export declare function registerCatalogueBaselineCheck(catalogue: Command): void;
5
+ export declare function registerCatalogueVersion(catalogue: Command): void;
6
+ //# sourceMappingURL=catalogue-verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalogue-verify.d.ts","sourceRoot":"","sources":["../../src/verbs/catalogue-verify.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYzC,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAmElE;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAuDhE;AAED,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAqCvE;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CASjE"}
@@ -0,0 +1,114 @@
1
+ // The read-only `catalogue` subcommands — validate (incl. --coverage), impact,
2
+ // baseline-check, version — split from `catalogue.ts` so a program can register
3
+ // them without importing the catalogue BUILD path. The verify-only CLI ships
4
+ // these and must not ship code that writes the derived model (M-ADR 0212 §4.3b).
5
+ // `registerCatalogue` calls each at its original position, so sdd-cli's
6
+ // `catalogue` surface and help order are unchanged.
7
+ //
8
+ // ⚠ Import each run* from its own module, NEVER from `../lib/catalogue/index.js`:
9
+ // that barrel re-exports the build and aggregate paths, and one convenience
10
+ // import from it would silently put authoring code back into the verify package.
11
+ import { runBaselineCheck } from "../lib/catalogue/baseline-check.js";
12
+ import { runCatalogueCoverage } from "../lib/catalogue/coverage-run.js";
13
+ import { runCatalogueImpact } from "../lib/catalogue/impact-run.js";
14
+ import { runCatalogueValidate } from "../lib/catalogue/validate.js";
15
+ import { runCatalogueVersion } from "../lib/catalogue/version.js";
16
+ export function registerCatalogueValidate(catalogue) {
17
+ catalogue
18
+ .command("validate")
19
+ .description("Re-run column-shape + FK validation against existing catalogues/ (no rebuild)")
20
+ .option("--sdd-path <path>", "Path to the SDD repo root (defaults to cwd)")
21
+ .option("--strict", "Treat findings as failures")
22
+ .option("--coverage", "Coverage mode: run the engine coverage predicates instead (same lines the gate scripts printed; exit 0 — gating stays the baseline's job)")
23
+ .option("--tier <tier>", "Coverage tier, explicit never inferred (member | aggregate; default member)")
24
+ .option("--catalogues-dir <dir>", "Coverage mode: catalogues directory relative to the SDD root (default catalogues)")
25
+ .action(async (opts) => {
26
+ if (opts.coverage === true) {
27
+ if (opts.tier !== undefined &&
28
+ opts.tier !== "member" &&
29
+ opts.tier !== "aggregate") {
30
+ process.stderr.write(`--tier must be 'member' or 'aggregate' (got: ${opts.tier})\n`);
31
+ process.exit(2);
32
+ }
33
+ const result = await runCatalogueCoverage({
34
+ ...(opts.sddPath !== undefined ? { sddPath: opts.sddPath } : {}),
35
+ ...(opts.cataloguesDir !== undefined
36
+ ? { cataloguesDir: opts.cataloguesDir }
37
+ : {}),
38
+ ...(opts.tier !== undefined
39
+ ? { tier: opts.tier }
40
+ : {}),
41
+ }, (s) => process.stdout.write(s));
42
+ if (result.exitCode !== 0)
43
+ process.exit(result.exitCode);
44
+ return;
45
+ }
46
+ const result = await runCatalogueValidate({
47
+ ...(opts.sddPath !== undefined ? { sddPath: opts.sddPath } : {}),
48
+ ...(opts.strict !== undefined ? { strict: opts.strict } : {}),
49
+ }, (s) => process.stdout.write(s));
50
+ if (result.exitCode !== 0)
51
+ process.exit(result.exitCode);
52
+ });
53
+ }
54
+ export function registerCatalogueImpact(catalogue) {
55
+ catalogue
56
+ .command("impact")
57
+ .description("Change-impact closure of a node (M-ADR 0206): each relationship is traversed per its declared impact-flow from the rubric-coverage-map — dependency edges reach their consumers, membership edges propagate part-to-whole only, xref/lineage records are inert — computed by recursive SQL on the embedded engine, with the co-directionality invariant asserted on every run")
58
+ .requiredOption("--of <node-id>", 'Node to compute impact of, in the projection\'s "<catalogue>/<id>" form (e.g. contracts/orders-api)')
59
+ .option("--sdd-path <path>", "Path to the SDD repo root (defaults to cwd)")
60
+ .option("--catalogues-dir <dir>", "Catalogues directory relative to the SDD root (default catalogues)")
61
+ .option("--tier <tier>", "Tier, explicit never inferred (member | aggregate; default member)")
62
+ .action(async (opts) => {
63
+ if (opts.tier !== undefined &&
64
+ opts.tier !== "member" &&
65
+ opts.tier !== "aggregate") {
66
+ process.stderr.write(`--tier must be 'member' or 'aggregate' (got: ${opts.tier})\n`);
67
+ process.exit(2);
68
+ }
69
+ const result = await runCatalogueImpact({
70
+ of: opts.of,
71
+ ...(opts.sddPath !== undefined ? { sddPath: opts.sddPath } : {}),
72
+ ...(opts.cataloguesDir !== undefined
73
+ ? { cataloguesDir: opts.cataloguesDir }
74
+ : {}),
75
+ ...(opts.tier !== undefined
76
+ ? { tier: opts.tier }
77
+ : {}),
78
+ }, (s) => process.stdout.write(s));
79
+ if (result.exitCode !== 0)
80
+ process.exit(result.exitCode);
81
+ });
82
+ }
83
+ export function registerCatalogueBaselineCheck(catalogue) {
84
+ catalogue
85
+ .command("baseline-check")
86
+ .description("Compare emitted findings against the repo's findings baseline BY IDENTITY (M-ADR 0132 §9) — a reworded finding reports as reworded, not as one closed and one new")
87
+ .option("--sdd-path <path>", "Path to the SDD repo root (defaults to cwd)")
88
+ .option("--findings <path>", "File of findings to compare (defaults to stdin, so it composes with `catalogue validate --coverage`)")
89
+ .option("--baseline <path>", "Baseline file (defaults to <sdd-path>/orchestration/catalogue-findings-baseline.txt)")
90
+ .action(async (opts) => {
91
+ const result = await runBaselineCheck({
92
+ ...(opts.sddPath !== undefined ? { sddPath: opts.sddPath } : {}),
93
+ ...(opts.findings !== undefined ? { findings: opts.findings } : {}),
94
+ ...(opts.baseline !== undefined ? { baseline: opts.baseline } : {}),
95
+ stdin: async () => {
96
+ const chunks = [];
97
+ for await (const c of process.stdin)
98
+ chunks.push(Buffer.from(c));
99
+ return Buffer.concat(chunks).toString("utf-8");
100
+ },
101
+ }, (s) => process.stdout.write(s));
102
+ if (result.exitCode !== 0)
103
+ process.exit(result.exitCode);
104
+ });
105
+ }
106
+ export function registerCatalogueVersion(catalogue) {
107
+ catalogue
108
+ .command("version")
109
+ .description("Print the catalogue schema version + sdd-cli version pin")
110
+ .action(async () => {
111
+ await runCatalogueVersion((s) => process.stdout.write(s));
112
+ });
113
+ }
114
+ //# sourceMappingURL=catalogue-verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalogue-verify.js","sourceRoot":"","sources":["../../src/verbs/catalogue-verify.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"catalogue.d.ts","sourceRoot":"","sources":["../../src/verbs/catalogue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8BzC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgTxD"}
1
+ {"version":3,"file":"catalogue.d.ts","sourceRoot":"","sources":["../../src/verbs/catalogue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkCzC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgKxD"}