@sdd-method/sdd-cli 1.29.2 → 1.31.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 (45) 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/snapshot/advance.d.ts +57 -0
  5. package/dist/lib/snapshot/advance.d.ts.map +1 -0
  6. package/dist/lib/snapshot/advance.js +347 -0
  7. package/dist/lib/snapshot/advance.js.map +1 -0
  8. package/dist/lib/snapshot/catalogue-diff.d.ts +27 -0
  9. package/dist/lib/snapshot/catalogue-diff.d.ts.map +1 -0
  10. package/dist/lib/snapshot/catalogue-diff.js +154 -0
  11. package/dist/lib/snapshot/catalogue-diff.js.map +1 -0
  12. package/dist/lib/snapshot/diff.d.ts +73 -0
  13. package/dist/lib/snapshot/diff.d.ts.map +1 -0
  14. package/dist/lib/snapshot/diff.js +177 -0
  15. package/dist/lib/snapshot/diff.js.map +1 -0
  16. package/dist/lib/snapshot/fold.d.ts +14 -0
  17. package/dist/lib/snapshot/fold.d.ts.map +1 -0
  18. package/dist/lib/snapshot/fold.js +106 -0
  19. package/dist/lib/snapshot/fold.js.map +1 -0
  20. package/dist/lib/snapshot/land.d.ts +21 -0
  21. package/dist/lib/snapshot/land.d.ts.map +1 -0
  22. package/dist/lib/snapshot/land.js +166 -0
  23. package/dist/lib/snapshot/land.js.map +1 -0
  24. package/dist/lib/snapshot/manifest.d.ts +63 -0
  25. package/dist/lib/snapshot/manifest.d.ts.map +1 -0
  26. package/dist/lib/snapshot/manifest.js +159 -0
  27. package/dist/lib/snapshot/manifest.js.map +1 -0
  28. package/dist/lib/snapshot/targets.d.ts +33 -0
  29. package/dist/lib/snapshot/targets.d.ts.map +1 -0
  30. package/dist/lib/snapshot/targets.js +147 -0
  31. package/dist/lib/snapshot/targets.js.map +1 -0
  32. package/dist/lib/snapshot/verify.d.ts +18 -0
  33. package/dist/lib/snapshot/verify.d.ts.map +1 -0
  34. package/dist/lib/snapshot/verify.js +85 -0
  35. package/dist/lib/snapshot/verify.js.map +1 -0
  36. package/dist/verbs/catalogue.d.ts.map +1 -1
  37. package/dist/verbs/catalogue.js +13 -0
  38. package/dist/verbs/catalogue.js.map +1 -1
  39. package/dist/verbs/snapshot.d.ts +9 -0
  40. package/dist/verbs/snapshot.d.ts.map +1 -0
  41. package/dist/verbs/snapshot.js +128 -0
  42. package/dist/verbs/snapshot.js.map +1 -0
  43. package/package.json +2 -2
  44. package/scripts/build-verify-package.mjs +23 -2
  45. package/scripts/verify-acceptance.sh +39 -2
@@ -0,0 +1,154 @@
1
+ // `sdd-cli catalogue diff` — the catalogue consequence of a snapshot update,
2
+ // attributed at FILE grain (reverse-snapshot-delta step 10).
3
+ //
4
+ // It BUILDS both sides itself, in this one process: BEFORE from `git archive
5
+ // <ref>` of the SDD, AFTER from the working tree, each into a temporary output
6
+ // directory. Committed catalogues are never read — they are as old as their last
7
+ // build — and one process means one CLI, so a CLI change between the builds
8
+ // cannot appear as changed rows. Nothing is written into the SDD, its catalogues
9
+ // or its .git.
10
+ //
11
+ // Attribution is at file grain because catalogue rows carry no source-file
12
+ // provenance, so "every row names a finding" is not checkable:
13
+ // - every SDD source file changed since <ref> must appear in some finding's
14
+ // targets (the pin bookkeeping `snapshot advance` writes is exempt), through
15
+ // a PRECISE target: grain `file`, grain `confirmed` (narrowed by hand), or a
16
+ // plain string written by hand. A file reached only through a `repo`-grain
17
+ // target is attributed BY MENTION ONLY, and fails: a repo-grain target names
18
+ // every artefact that mentions the member, so in a component-heavy SDD it
19
+ // covers almost any edit and the check would pass by construction. Narrowing
20
+ // is bounded by the files actually edited, not by the targets routed;
21
+ // - catalogue rows that changed while NO file changed (bookkeeping included)
22
+ // are unattributed by construction — the builder moved, not the snapshot.
23
+ // Exit 1 on any unattributed change.
24
+ import { execFile as execFileCb } from "node:child_process";
25
+ import { mkdir, mkdtemp, readdir, readFile, rm } from "node:fs/promises";
26
+ import { tmpdir } from "node:os";
27
+ import { join } from "node:path";
28
+ import { promisify } from "node:util";
29
+ import { parse } from "yaml";
30
+ import { runCatalogueBuild } from "../catalogue/build.js";
31
+ const execFile = promisify(execFileCb);
32
+ const EXEMPT = [/^catalogues\//, /^repos\/[^/]+\/reverse-(history|metadata)\.yaml$/];
33
+ async function git(cwd, args) {
34
+ return (await execFile("git", ["-C", cwd, ...args], { maxBuffer: 64 * 1024 * 1024 })).stdout;
35
+ }
36
+ /** Every file changed since `ref`, tracked or untracked. */
37
+ export async function changedFiles(sddPath, ref) {
38
+ const tracked = (await git(sddPath, ["diff", "--name-only", ref, "--"])).split("\n");
39
+ const untracked = (await git(sddPath, ["ls-files", "--others", "--exclude-standard"])).split("\n");
40
+ return [...new Set([...tracked, ...untracked].filter((p) => p !== ""))].sort();
41
+ }
42
+ /** The changed files that must be attributed: minus catalogues and advance's pin bookkeeping. */
43
+ export async function changedSourceFiles(sddPath, ref) {
44
+ return (await changedFiles(sddPath, ref)).filter((p) => !EXEMPT.some((re) => re.test(p)));
45
+ }
46
+ /** Every target, and whether it is precise (file / confirmed grain, or hand-written) or a repo-grain mention. */
47
+ export function targetSet(delta) {
48
+ const findings = delta?.findings ?? [];
49
+ const out = new Map();
50
+ for (const f of findings) {
51
+ for (const t of f.targets ?? []) {
52
+ let artefact = null;
53
+ let precise = true;
54
+ if (typeof t === "string")
55
+ artefact = t;
56
+ else if (t && typeof t === "object" && typeof t.artefact === "string") {
57
+ artefact = t.artefact;
58
+ precise = t.grain !== "repo";
59
+ }
60
+ if (artefact !== null)
61
+ out.set(artefact, (out.get(artefact) ?? false) || precise);
62
+ }
63
+ }
64
+ return [...out].map(([artefact, precise]) => ({ artefact, precise }));
65
+ }
66
+ /** "precise" | "mention" | null — how, if at all, a changed file is attributed. */
67
+ export function attributed(file, targets) {
68
+ const hits = targets.filter((t) => t.artefact === file || (t.artefact.endsWith("/") && file.startsWith(t.artefact)));
69
+ if (hits.length === 0)
70
+ return null;
71
+ return hits.some((t) => t.precise) ? "precise" : "mention";
72
+ }
73
+ async function rowSets(dir) {
74
+ const out = new Map();
75
+ for (const f of await readdir(dir)) {
76
+ if (!f.endsWith(".csv"))
77
+ continue;
78
+ const lines = (await readFile(join(dir, f), "utf8")).split("\n").filter((l) => l !== "");
79
+ out.set(f.replace(/\.csv$/, ""), lines.slice(1));
80
+ }
81
+ return out;
82
+ }
83
+ export function rowDelta(before, after) {
84
+ const count = new Map();
85
+ for (const r of before)
86
+ count.set(r, (count.get(r) ?? 0) + 1);
87
+ let added = 0;
88
+ for (const r of after) {
89
+ const c = count.get(r) ?? 0;
90
+ if (c > 0)
91
+ count.set(r, c - 1);
92
+ else
93
+ added++;
94
+ }
95
+ let removed = 0;
96
+ for (const c of count.values())
97
+ removed += c;
98
+ return { added, removed };
99
+ }
100
+ export async function runCatalogueDiff(inputs, write) {
101
+ const { sddPath, from } = inputs;
102
+ const delta = parse(await readFile(inputs.attribute, "utf8"));
103
+ const targets = targetSet(delta);
104
+ const work = await mkdtemp(join(tmpdir(), "sdd-cli-catalogue-diff-"));
105
+ try {
106
+ await git(sddPath, ["rev-parse", "--verify", `${from}^{commit}`]);
107
+ const beforeTree = join(work, "before-tree");
108
+ await mkdir(beforeTree);
109
+ await execFile("git", ["-C", sddPath, "archive", "-o", join(work, "before.tar"), from]);
110
+ await execFile("tar", ["-xf", join(work, "before.tar"), "-C", beforeTree]);
111
+ const sink = () => { };
112
+ const b = await runCatalogueBuild({ sddPath: beforeTree, outDir: join(work, "before") }, sink);
113
+ const a = await runCatalogueBuild({ sddPath, outDir: join(work, "after") }, sink);
114
+ write(`built both sides in one process (schema ${a.schemaVersion}); before exit ${b.exitCode}, after exit ${a.exitCode}\n`);
115
+ const before = await rowSets(join(work, "before"));
116
+ const after = await rowSets(join(work, "after"));
117
+ const changedCatalogues = [];
118
+ for (const name of [...new Set([...before.keys(), ...after.keys()])].sort()) {
119
+ const d = rowDelta(before.get(name) ?? [], after.get(name) ?? []);
120
+ if (d.added + d.removed > 0)
121
+ changedCatalogues.push([name, d]);
122
+ }
123
+ const all = (await changedFiles(sddPath, from)).filter((p) => !p.startsWith("catalogues/"));
124
+ const files = all.filter((p) => !EXEMPT.some((re) => re.test(p)));
125
+ const unattributed = files.filter((f) => attributed(f, targets) === null);
126
+ const byMention = files.filter((f) => attributed(f, targets) === "mention");
127
+ write(`\nsource files changed since ${from}: ${files.length} — ${files.length - unattributed.length - byMention.length} attributed precisely, ` +
128
+ `${byMention.length} by mention only, ${unattributed.length} unattributed\n`);
129
+ for (const f of byMention)
130
+ write(` BY MENTION ONLY ${f} — narrow the target that names it (grain: confirmed) or record the finding it belongs to\n`);
131
+ for (const f of unattributed)
132
+ write(` UNATTRIBUTED ${f}\n`);
133
+ write(`\ncatalogues with changed rows: ${changedCatalogues.length}\n`);
134
+ for (const [name, d] of changedCatalogues)
135
+ write(` ${name}: +${d.added} -${d.removed}\n`);
136
+ let failed = unattributed.length > 0 || byMention.length > 0;
137
+ // Exempt files (the pin bookkeeping) are excused from attribution, not from
138
+ // feeding catalogues: they count here, or advance's own edits look like drift.
139
+ if (all.length === 0 && changedCatalogues.length > 0) {
140
+ write("\nUNATTRIBUTED: catalogue rows changed while no file did — that is the builder, not the snapshot\n");
141
+ failed = true;
142
+ }
143
+ if (failed) {
144
+ write("\nFAIL: each unattributed change is an unrecorded finding or an unintended edit — resolve which\n");
145
+ return { exitCode: 1 };
146
+ }
147
+ write("\nPASS: every changed source file is a precise target of some finding\n");
148
+ return { exitCode: 0 };
149
+ }
150
+ finally {
151
+ await rm(work, { recursive: true, force: true });
152
+ }
153
+ }
154
+ //# sourceMappingURL=catalogue-diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalogue-diff.js","sourceRoot":"","sources":["../../../src/lib/snapshot/catalogue-diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { type SnapshotManifest } from "./manifest.js";
2
+ type Writer = (s: string) => void;
3
+ export interface DiffInputs {
4
+ areaRoot: string;
5
+ to: string;
6
+ from?: string;
7
+ }
8
+ /**
9
+ * A deliberately coarse, documented path classifier. It groups files so each
10
+ * finding is reviewable; it does not decide what a change means (that is
11
+ * classification, which is judgement). First match wins.
12
+ */
13
+ export declare const EVIDENCE_CLASSES: ReadonlyArray<readonly [string, RegExp]>;
14
+ export declare function evidenceClass(path: string): string;
15
+ export interface DeltaFinding {
16
+ id: string;
17
+ member: string;
18
+ evidence_class: string;
19
+ status: "proposed" | "noted" | "closed";
20
+ classification: string | null;
21
+ spec_impact: string | null;
22
+ summary: string;
23
+ files: {
24
+ added: string[];
25
+ removed: string[];
26
+ modified: string[];
27
+ };
28
+ targets: unknown[];
29
+ }
30
+ export interface DeltaYaml {
31
+ implementation: string;
32
+ from_snapshot: string;
33
+ to_snapshot: string;
34
+ members_changed: Array<{
35
+ canonical_repo_key: string;
36
+ from_revision: string;
37
+ to_revision: string;
38
+ files: {
39
+ added: number;
40
+ removed: number;
41
+ modified: number;
42
+ };
43
+ }>;
44
+ members_added: Array<{
45
+ canonical_repo_key: string;
46
+ to_revision: string;
47
+ }>;
48
+ members_removed: Array<{
49
+ canonical_repo_key: string;
50
+ last_revision: string;
51
+ reason: string;
52
+ }>;
53
+ members_carried: Array<{
54
+ canonical_repo_key: string;
55
+ carried_from: string;
56
+ carried_reason: string;
57
+ }>;
58
+ members_unchanged: number;
59
+ disposition: string | null;
60
+ impact: string | null;
61
+ findings: DeltaFinding[];
62
+ open_questions: unknown[];
63
+ }
64
+ export declare function deltaPath(areaRoot: string, id: string): string;
65
+ /** Findings that already carry judgement — the reason diff will not rewrite. */
66
+ export declare function judgedFindings(existing: unknown): string[];
67
+ export declare function runSnapshotDiff(inputs: DiffInputs, write: Writer): Promise<{
68
+ exitCode: number;
69
+ }>;
70
+ export declare function snapshotDiff(inputs: DiffInputs): Promise<DeltaYaml>;
71
+ export declare function computeDelta(areaRoot: string, t0: SnapshotManifest, t1: SnapshotManifest): Promise<DeltaYaml>;
72
+ export {};
73
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../../src/lib/snapshot/diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,177 @@
1
+ // `sdd-cli snapshot diff` — the member and file delta between two baselines,
2
+ // written as delta.yaml's skeleton (delta-reverse.md §4 and §6).
3
+ //
4
+ // Members are classified from the two MANIFESTS, never the folder trees: a
5
+ // carried member is absent from T1's tree and present in the set, and a tree
6
+ // diff calls it removed. A prior member that T1's manifest neither lists nor
7
+ // records in members_removed is refused — the manifest is incomplete.
8
+ //
9
+ // Findings are one per changed member × evidence class, at `status: proposed`,
10
+ // with classification / spec_impact / targets left for judgement. Once any
11
+ // finding carries judgement, diff refuses to rewrite the file.
12
+ import { readFile, writeFile } from "node:fs/promises";
13
+ import { join } from "node:path";
14
+ import { parse, stringify } from "yaml";
15
+ import { SnapshotError, diffTrees, exists, hashTree, memberBytesDir, readManifest, } from "./manifest.js";
16
+ /**
17
+ * A deliberately coarse, documented path classifier. It groups files so each
18
+ * finding is reviewable; it does not decide what a change means (that is
19
+ * classification, which is judgement). First match wins.
20
+ */
21
+ export const EVIDENCE_CLASSES = [
22
+ ["contracts", /\.(avsc|proto|graphql|wsdl|xsd)$|(^|\/)(openapi|swagger|asyncapi)[^/]*\.(ya?ml|json)$/i],
23
+ ["tests", /(^|\/)(test|tests|__tests__|spec|it|e2e)\/|\.(test|spec)\.[a-z]+$|Tests?\.[a-z]+$/i],
24
+ ["infrastructure", /\.(tf|tfvars|bicep)$|(^|\/)(helm|charts|k8s|kubernetes|deploy|deployment|terraform)\//i],
25
+ ["build", /(^|\/)(pom\.xml|build\.gradle(\.kts)?|settings\.gradle(\.kts)?|package\.json|package-lock\.json|yarn\.lock|pnpm-lock\.yaml|go\.mod|go\.sum|Cargo\.toml|Dockerfile[^/]*|Makefile|\.csproj|.*\.sln)$|(^|\/)\.(github|gitlab-ci|circleci)|Jenkinsfile$|bitbucket-pipelines\.yml$/i],
26
+ ["configuration", /\.(ya?ml|properties|json|toml|ini|conf|env|config)$/i],
27
+ ["documentation", /\.(md|adoc|rst|txt)$/i],
28
+ ["source", /./],
29
+ ];
30
+ export function evidenceClass(path) {
31
+ for (const [name, re] of EVIDENCE_CLASSES)
32
+ if (re.test(path))
33
+ return name;
34
+ return "source";
35
+ }
36
+ export function deltaPath(areaRoot, id) {
37
+ return join(areaRoot, id, "delta.yaml");
38
+ }
39
+ /** Findings that already carry judgement — the reason diff will not rewrite. */
40
+ export function judgedFindings(existing) {
41
+ const findings = existing?.findings;
42
+ if (!Array.isArray(findings))
43
+ return [];
44
+ return findings.flatMap((f, i) => {
45
+ const x = f;
46
+ const judged = (x.status !== undefined && x.status !== "proposed") ||
47
+ (x.classification !== undefined && x.classification !== null) ||
48
+ (x.spec_impact !== undefined && x.spec_impact !== null);
49
+ return judged ? [String(x.id ?? `findings[${i}]`)] : [];
50
+ });
51
+ }
52
+ export async function runSnapshotDiff(inputs, write) {
53
+ try {
54
+ const d = await snapshotDiff(inputs);
55
+ write(`${d.from_snapshot} → ${d.to_snapshot}: ${d.members_changed.length} changed, ${d.members_unchanged} unchanged, ` +
56
+ `${d.members_added.length} added, ${d.members_removed.length} removed, ${d.members_carried.length} carried; ` +
57
+ `${d.findings.length} finding(s) at status proposed → ${deltaPath(inputs.areaRoot, inputs.to)}\n`);
58
+ return { exitCode: 0 };
59
+ }
60
+ catch (e) {
61
+ if (e instanceof SnapshotError) {
62
+ write(`REFUSED: ${e.message}\n`);
63
+ return { exitCode: 1 };
64
+ }
65
+ throw e;
66
+ }
67
+ }
68
+ export async function snapshotDiff(inputs) {
69
+ const { areaRoot, to } = inputs;
70
+ const t1 = await readManifest(areaRoot, to);
71
+ const fromId = inputs.from ?? t1.prior_snapshot;
72
+ if (!fromId)
73
+ throw new SnapshotError(`${to} has no prior_snapshot; pass --from`);
74
+ const t0 = await readManifest(areaRoot, fromId);
75
+ const out = deltaPath(areaRoot, to);
76
+ if (await exists(out)) {
77
+ const judged = judgedFindings(parse(await readFile(out, "utf8")));
78
+ if (judged.length > 0) {
79
+ throw new SnapshotError(`${out} already holds judgement on ${judged.length} finding(s) (${judged.slice(0, 5).join(", ")}${judged.length > 5 ? ", …" : ""}) — diff will not overwrite it`);
80
+ }
81
+ }
82
+ const delta = await computeDelta(areaRoot, t0, t1);
83
+ const header = "# Snapshot delta -- reverse/workflows/delta-reverse.md §6. Skeleton written by `sdd-cli snapshot diff`;\n" +
84
+ "# classification, spec_impact and targets are judgement (steps 5-6). Once any is set, diff will not rewrite this file.\n";
85
+ await writeFile(out, header + stringify(delta, { lineWidth: 0 }));
86
+ return delta;
87
+ }
88
+ export async function computeDelta(areaRoot, t0, t1) {
89
+ const t0ByKey = new Map(t0.members.map((m) => [m.canonical_repo_key, m]));
90
+ const t1Keys = new Set(t1.members.map((m) => m.canonical_repo_key));
91
+ const removedKeys = new Set((t1.members_removed ?? []).map((r) => r.canonical_repo_key));
92
+ const unaccounted = t0.members.filter((m) => !t1Keys.has(m.canonical_repo_key) && !removedKeys.has(m.canonical_repo_key));
93
+ if (unaccounted.length > 0) {
94
+ throw new SnapshotError(`${t1.snapshot_id}'s manifest does not account for ${unaccounted.map((m) => m.canonical_repo_key).join(", ")} from ${t0.snapshot_id} — ` +
95
+ "each must be a member (carried or re-observed) or in members_removed[]");
96
+ }
97
+ const delta = {
98
+ implementation: t1.implementation,
99
+ from_snapshot: t0.snapshot_id,
100
+ to_snapshot: t1.snapshot_id,
101
+ members_changed: [],
102
+ members_added: [],
103
+ members_removed: (t1.members_removed ?? []).map((r) => ({ canonical_repo_key: r.canonical_repo_key, last_revision: r.last_revision, reason: r.reason })),
104
+ members_carried: [],
105
+ members_unchanged: 0,
106
+ disposition: null,
107
+ impact: null,
108
+ findings: [],
109
+ open_questions: [],
110
+ };
111
+ for (const m of t1.members) {
112
+ const p = t0ByKey.get(m.canonical_repo_key);
113
+ if (!p) {
114
+ delta.members_added.push({ canonical_repo_key: m.canonical_repo_key, to_revision: m.source_revision });
115
+ // A new member gets the full seeding sequence, not a delta — but what the
116
+ // seeding writes must still trace to a finding, so it gets one.
117
+ delta.findings.push(memberFinding(m.canonical_repo_key, "member-added", `new member at ${m.source_revision}: seed it (full sequence), then target what it grounds`));
118
+ continue;
119
+ }
120
+ if (m.carried_from !== undefined) {
121
+ delta.members_carried.push({ canonical_repo_key: m.canonical_repo_key, carried_from: m.carried_from, carried_reason: m.carried_reason ?? "" });
122
+ delta.members_unchanged++;
123
+ continue;
124
+ }
125
+ if (p.source_revision === m.source_revision) {
126
+ delta.members_unchanged++;
127
+ continue;
128
+ }
129
+ const files = diffTrees(await hashTree(memberBytesDir(areaRoot, t0, p)), await hashTree(memberBytesDir(areaRoot, t1, m)));
130
+ delta.members_changed.push({
131
+ canonical_repo_key: m.canonical_repo_key,
132
+ from_revision: p.source_revision,
133
+ to_revision: m.source_revision,
134
+ files: { added: files.added.length, removed: files.removed.length, modified: files.modified.length },
135
+ });
136
+ const byClass = new Map();
137
+ for (const kind of ["added", "removed", "modified"]) {
138
+ for (const f of files[kind]) {
139
+ const c = evidenceClass(f);
140
+ if (!byClass.has(c))
141
+ byClass.set(c, { added: [], removed: [], modified: [] });
142
+ byClass.get(c)[kind].push(f);
143
+ }
144
+ }
145
+ for (const [c, fs] of [...byClass].sort(([a], [b]) => a.localeCompare(b))) {
146
+ delta.findings.push({
147
+ id: `${m.canonical_repo_key}.${c}`,
148
+ member: m.canonical_repo_key,
149
+ evidence_class: c,
150
+ status: "proposed",
151
+ classification: null,
152
+ spec_impact: null,
153
+ summary: `${fs.added.length} added, ${fs.removed.length} removed, ${fs.modified.length} modified ${c} file(s)`,
154
+ files: fs,
155
+ targets: [],
156
+ });
157
+ }
158
+ }
159
+ for (const r of t1.members_removed ?? []) {
160
+ delta.findings.push(memberFinding(r.canonical_repo_key, "member-removed", `left the set (${r.reason}); a removed member is not a removed capability until you have checked where the capability went`));
161
+ }
162
+ return delta;
163
+ }
164
+ function memberFinding(member, kind, summary) {
165
+ return {
166
+ id: `${member}.${kind}`,
167
+ member,
168
+ evidence_class: kind,
169
+ status: "proposed",
170
+ classification: null,
171
+ spec_impact: null,
172
+ summary,
173
+ files: { added: [], removed: [], modified: [] },
174
+ targets: [],
175
+ };
176
+ }
177
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../../src/lib/snapshot/diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ type Writer = (s: string) => void;
2
+ export interface FoldInputs {
3
+ areaRoot: string;
4
+ id?: string;
5
+ implementation?: string;
6
+ keys?: ReadonlyMap<string, string>;
7
+ scanRoots?: readonly string[];
8
+ today?: string;
9
+ }
10
+ export declare function runSnapshotFold(inputs: FoldInputs, write: Writer): Promise<{
11
+ exitCode: number;
12
+ }>;
13
+ export {};
14
+ //# sourceMappingURL=fold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../../../src/lib/snapshot/fold.ts"],"names":[],"mappings":"AAwBA,KAAK,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;AAElC,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAmCD,wBAAsB,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAyDtG"}
@@ -0,0 +1,106 @@
1
+ // `sdd-cli snapshot fold` — move a flat `source/<repo>@<rev>/` area into its
2
+ // first dated baseline (delta-reverse.md §1), once per area.
3
+ //
4
+ // Then it LISTS every reference to the old paths it can find under the scan
5
+ // roots — relative and absolute alike, since citations use both and a search
6
+ // for one form misses the other. The list is a print, not a control: nothing
7
+ // fails if a reference is left, so the report says so. Scan the whole estate,
8
+ // not only the owning SDD — other SDDs cite this area's baselines.
9
+ import { mkdir, readdir, readFile, rename, stat, writeFile } from "node:fs/promises";
10
+ import { join, relative, sep } from "node:path";
11
+ import { stringify } from "yaml";
12
+ import { SnapshotError, baselineIds, exists, isIsoDate, manifestPath, memberFolders, splitFolder, } from "./manifest.js";
13
+ const SKIP = new Set([".git", "node_modules"]);
14
+ const TEXT = /\.(md|ya?ml|json|txt|adoc|csv|properties|toml)$/i;
15
+ async function references(root, folders, id) {
16
+ const out = [];
17
+ async function walk(dir) {
18
+ let entries;
19
+ try {
20
+ entries = await readdir(dir, { withFileTypes: true });
21
+ }
22
+ catch {
23
+ return;
24
+ }
25
+ for (const e of entries) {
26
+ const full = join(dir, e.name);
27
+ if (e.isDirectory()) {
28
+ if (!SKIP.has(e.name) && !isIsoDate(e.name))
29
+ await walk(full);
30
+ }
31
+ else if (e.isFile() && TEXT.test(e.name) && (await stat(full)).size <= 4 * 1024 * 1024) {
32
+ const lines = (await readFile(full, "utf8")).split("\n");
33
+ lines.forEach((line, i) => {
34
+ for (const f of folders) {
35
+ if (line.includes(f) && !line.includes(`${id}/${f}`)) {
36
+ out.push(`${relative(root, full).split(sep).join("/")}:${i + 1}: ${f}`);
37
+ break;
38
+ }
39
+ }
40
+ });
41
+ }
42
+ }
43
+ }
44
+ await walk(root);
45
+ return out;
46
+ }
47
+ export async function runSnapshotFold(inputs, write) {
48
+ try {
49
+ const { areaRoot, id } = inputs;
50
+ const today = inputs.today ?? new Date().toISOString().slice(0, 10);
51
+ if (id === undefined)
52
+ throw new SnapshotError("--id is required: the date the flat exports were OBSERVED");
53
+ if (!isIsoDate(id) || id > today)
54
+ throw new SnapshotError(`--id '${id}' is not a past or present YYYY-MM-DD date`);
55
+ if (!inputs.implementation)
56
+ throw new SnapshotError("--implementation is required: the durable system identity (M-ADR 0181 §2.5)");
57
+ const existing = await baselineIds(areaRoot);
58
+ for (const b of existing) {
59
+ if (await exists(manifestPath(areaRoot, b)))
60
+ throw new SnapshotError(`${areaRoot} is already folded (baseline ${b} has a manifest)`);
61
+ }
62
+ const folders = await memberFolders(areaRoot);
63
+ if (folders.length === 0)
64
+ throw new SnapshotError(`no flat <repo>@<revision>/ folders directly under ${areaRoot}`);
65
+ const members = folders.map((f) => {
66
+ const { stem, revision } = splitFolder(f);
67
+ return {
68
+ canonical_repo_key: inputs.keys?.get(f) ?? stem.replace(/-(master|main|develop|trunk)$/, ""),
69
+ exported_folder_name: f,
70
+ source_revision: revision,
71
+ };
72
+ });
73
+ const target = join(areaRoot, id);
74
+ if (await exists(target))
75
+ throw new SnapshotError(`${target} already exists`);
76
+ await mkdir(target);
77
+ for (const f of folders)
78
+ await rename(join(areaRoot, f), join(target, f));
79
+ const manifest = { snapshot_id: id, observed_at: id, implementation: inputs.implementation, prior_snapshot: null, members };
80
+ await writeFile(manifestPath(areaRoot, id), "# Implementation-set snapshot (baseline) -- written by `sdd-cli snapshot fold`.\n" + stringify(manifest, { lineWidth: 0 }));
81
+ write(`folded ${folders.length} member(s) into ${target}\n`);
82
+ const roots = inputs.scanRoots ?? [];
83
+ if (roots.length === 0) {
84
+ write("WARNING: no --scan roots given, so no references were listed. Every citation of the old paths is now stale.\n");
85
+ return { exitCode: 0 };
86
+ }
87
+ let n = 0;
88
+ for (const r of roots) {
89
+ for (const hit of await references(r, folders, id)) {
90
+ write(` ${r}/${hit}\n`);
91
+ n++;
92
+ }
93
+ }
94
+ write(`${n} line(s) still cite a pre-fold path. This list is a print, not a control: nothing fails if one is left — ` +
95
+ "re-point each (reverse-metadata source_path first) and check it resolves on disk.\n");
96
+ return { exitCode: 0 };
97
+ }
98
+ catch (e) {
99
+ if (e instanceof SnapshotError) {
100
+ write(`REFUSED: ${e.message}\n`);
101
+ return { exitCode: 1 };
102
+ }
103
+ throw e;
104
+ }
105
+ }
106
+ //# sourceMappingURL=fold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fold.js","sourceRoot":"","sources":["../../../src/lib/snapshot/fold.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { type CredentialScan, type SnapshotManifest } from "./manifest.js";
2
+ type Writer = (s: string) => void;
3
+ export interface LandInputs {
4
+ areaRoot: string;
5
+ id?: string;
6
+ prior?: string;
7
+ implementation?: string;
8
+ memberDates?: ReadonlyMap<string, string>;
9
+ carried?: ReadonlyMap<string, string>;
10
+ removed?: ReadonlyMap<string, string>;
11
+ keys?: ReadonlyMap<string, string>;
12
+ credentialScan?: Partial<CredentialScan>;
13
+ notes?: string;
14
+ today?: string;
15
+ }
16
+ export declare function runSnapshotLand(inputs: LandInputs, write: Writer): Promise<{
17
+ exitCode: number;
18
+ }>;
19
+ export declare function land(inputs: LandInputs, write: Writer): Promise<SnapshotManifest>;
20
+ export {};
21
+ //# sourceMappingURL=land.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"land.d.ts","sourceRoot":"","sources":["../../../src/lib/snapshot/land.ts"],"names":[],"mappings":"AAiBA,OAAO,EACL,KAAK,cAAc,EAGnB,KAAK,gBAAgB,EAYtB,MAAM,eAAe,CAAC;AAEvB,KAAK,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;AAElC,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,OAAO,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,OAAO,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,cAAc,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,wBAAsB,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAYtG;AAED,wBAAsB,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAwIvF"}