@sdd-method/maintain-cli 0.8.0 → 0.10.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 (105) hide show
  1. package/dist/lib/agent-harness.js +2 -2
  2. package/dist/lib/behaviour-store/archive.js +28 -1
  3. package/dist/lib/behaviour-store/schema.js +85 -0
  4. package/dist/lib/briefing/index.js +1 -1
  5. package/dist/lib/briefing/render.js +1 -1
  6. package/dist/lib/briefing/variables.js +1 -1
  7. package/dist/lib/bundle.js +1 -1
  8. package/dist/lib/catalogue/aggregate.js +7 -7
  9. package/dist/lib/catalogue/application-archetype/vocabulary.js +2 -2
  10. package/dist/lib/catalogue/archetype/maps/android.yaml +2 -2
  11. package/dist/lib/catalogue/archetype/maps/swiftui.yaml +2 -2
  12. package/dist/lib/catalogue/archetype/maps/uikit.yaml +2 -2
  13. package/dist/lib/catalogue/archetype/maps/web-generic.yaml +2 -2
  14. package/dist/lib/catalogue/archetype/openui-archetype-vocabulary.yaml +3 -3
  15. package/dist/lib/catalogue/archetype/resolver.js +4 -4
  16. package/dist/lib/catalogue/archetype/wireframe.js +1 -1
  17. package/dist/lib/catalogue/build.js +36 -33
  18. package/dist/lib/catalogue/builders/adr-supersedes.js +3 -3
  19. package/dist/lib/catalogue/builders/adrs.js +3 -3
  20. package/dist/lib/catalogue/builders/c4-containers.js +2 -2
  21. package/dist/lib/catalogue/builders/c4-entity-rollups.js +1 -1
  22. package/dist/lib/catalogue/builders/c4-external-systems.js +2 -2
  23. package/dist/lib/catalogue/builders/c4-systems.js +1 -1
  24. package/dist/lib/catalogue/builders/capabilities.js +1 -1
  25. package/dist/lib/catalogue/builders/capability-domain-model.js +1 -1
  26. package/dist/lib/catalogue/builders/capability-spec-walker.js +2 -2
  27. package/dist/lib/catalogue/builders/capability-spec.js +4 -4
  28. package/dist/lib/catalogue/builders/contracts.js +3 -3
  29. package/dist/lib/catalogue/builders/data-store-mapping.js +2 -2
  30. package/dist/lib/catalogue/builders/domain-models.js +2 -2
  31. package/dist/lib/catalogue/builders/domains.js +3 -3
  32. package/dist/lib/catalogue/builders/entities-manifest.js +8 -8
  33. package/dist/lib/catalogue/builders/entities-mermaid.js +4 -4
  34. package/dist/lib/catalogue/builders/entity-persistence.js +1 -1
  35. package/dist/lib/catalogue/builders/entity-slug.js +3 -3
  36. package/dist/lib/catalogue/builders/event-catalog-walker.js +6 -6
  37. package/dist/lib/catalogue/builders/event-edges.js +6 -6
  38. package/dist/lib/catalogue/builders/events.js +3 -3
  39. package/dist/lib/catalogue/builders/evidence-class.js +1 -1
  40. package/dist/lib/catalogue/builders/feature-domain-model.js +1 -1
  41. package/dist/lib/catalogue/builders/feature-grounding-walker.js +2 -2
  42. package/dist/lib/catalogue/builders/feature-grounding.js +5 -5
  43. package/dist/lib/catalogue/builders/feature-subscription-channels.js +3 -3
  44. package/dist/lib/catalogue/builders/features.js +1 -1
  45. package/dist/lib/catalogue/builders/glossary-xref.js +4 -4
  46. package/dist/lib/catalogue/builders/integrations.js +4 -4
  47. package/dist/lib/catalogue/builders/persona-c4system.js +1 -1
  48. package/dist/lib/catalogue/builders/product-edges.js +1 -1
  49. package/dist/lib/catalogue/builders/product-platform-dependencies.js +2 -2
  50. package/dist/lib/catalogue/builders/products.js +5 -5
  51. package/dist/lib/catalogue/builders/repo-edges.js +12 -12
  52. package/dist/lib/catalogue/builders/repositories.js +11 -7
  53. package/dist/lib/catalogue/builders/requirements.js +110 -11
  54. package/dist/lib/catalogue/builders/screen-tree.js +6 -6
  55. package/dist/lib/catalogue/builders/screens.js +18 -18
  56. package/dist/lib/catalogue/builders/service-contract-consumes.js +1 -1
  57. package/dist/lib/catalogue/builders/service-entity-tables.js +3 -3
  58. package/dist/lib/catalogue/builders/services.js +5 -5
  59. package/dist/lib/catalogue/builders/system-external-dependency.js +2 -2
  60. package/dist/lib/catalogue/canonical-schema.yaml +138 -2
  61. package/dist/lib/catalogue/coverage-render.js +15 -15
  62. package/dist/lib/catalogue/csv-writer.js +1 -1
  63. package/dist/lib/catalogue/feature-grounding-aliases-loader.js +1 -1
  64. package/dist/lib/catalogue/findings.js +1 -1
  65. package/dist/lib/catalogue/fk-validator.js +2 -2
  66. package/dist/lib/catalogue/manifest-loader.js +3 -3
  67. package/dist/lib/catalogue/rubric-coverage-map.yaml +28 -0
  68. package/dist/lib/catalogue/schema-compat.js +2 -2
  69. package/dist/lib/catalogue/schema-loader.js +1 -1
  70. package/dist/lib/catalogue/screen-validation-loader.js +2 -2
  71. package/dist/lib/catalogue/service-architecture-parser.js +1 -1
  72. package/dist/lib/catalogue/traceability-loader.js +6 -4
  73. package/dist/lib/ci-binding/module.js +4 -2
  74. package/dist/lib/generate-briefing/index.js +2 -2
  75. package/dist/lib/hooks-seed/entries.js +1 -1
  76. package/dist/lib/metamodel/tql-subset-parser.js +280 -0
  77. package/dist/lib/pack/builder.js +2 -2
  78. package/dist/lib/pack/index.js +1 -1
  79. package/dist/lib/pack/leakage.js +1 -1
  80. package/dist/lib/pack/publish-transform.js +2 -2
  81. package/dist/lib/pack/schema.js +2 -2
  82. package/dist/lib/pack/seed.js +2 -2
  83. package/dist/lib/pack/validate.js +1 -1
  84. package/dist/lib/repo-kind.js +4 -12
  85. package/dist/lib/scaffold/archetype-behaviour.js +173 -0
  86. package/dist/lib/scaffold/registry.js +136 -0
  87. package/dist/lib/sync/adr-transitions.js +4 -2
  88. package/dist/lib/sync/briefing-merge.js +2 -2
  89. package/dist/lib/sync/bundle-cache.js +4 -4
  90. package/dist/lib/sync/index.js +39 -12
  91. package/dist/lib/sync/settings-merge.js +1 -1
  92. package/dist/lib/sync/yaml-block-merge.js +1 -1
  93. package/dist/lib/validate/archetype-citations.js +169 -0
  94. package/dist/lib/validate/behaviour-store.js +161 -6
  95. package/dist/lib/validate/dispatch.js +8 -1
  96. package/dist/maintain-program.js +2 -2
  97. package/dist/maintain-version.json +2 -2
  98. package/dist/verbs/list.js +1 -1
  99. package/dist/verbs/pack-build.js +2 -2
  100. package/dist/verbs/render.js +1 -1
  101. package/dist/verify-program.js +2 -2
  102. package/dist/verify-version.json +2 -2
  103. package/package.json +2 -2
  104. package/scripts/validate-app-dependencies.sh +1 -1
  105. package/scripts/validate-integration-docs.sh +1 -1
@@ -8,7 +8,7 @@
8
8
  // `docs/domains/{domain}/product/{capability}.traceability.yaml`.
9
9
  //
10
10
  // Schema reference: docs/method/methods/capability-traceability-manifest-template.yaml
11
- // in sdd-method (per ADR 0047 / capability-spec-template.md).
11
+ // in sdd-method (per M-ADR 0047 / capability-spec-template.md).
12
12
  import { readdir, readFile, stat } from "node:fs/promises";
13
13
  import { join, relative, sep } from "node:path";
14
14
  import { parse as parseYaml } from "yaml";
@@ -84,6 +84,8 @@ export async function loadTraceabilityManifests(opts) {
84
84
  }
85
85
  throw err;
86
86
  }
87
+ // A manifest dropped whole takes its capability's traceability with it, so
88
+ // each drop below is an error that fails the build (as for repo-configs).
87
89
  const manifests = [];
88
90
  for (const path of yamlPaths.sort()) {
89
91
  const text = await readFile(path, "utf-8");
@@ -92,18 +94,18 @@ export async function loadTraceabilityManifests(opts) {
92
94
  raw = parseYaml(text);
93
95
  }
94
96
  catch (err) {
95
- opts.findings.add("convention", `failed to parse YAML at ${relative(opts.sddPath, path)}: ${err.message}`);
97
+ opts.findings.add("convention", `failed to parse YAML at ${relative(opts.sddPath, path)}: ${err.message} — manifest dropped`, "error", relative(opts.sddPath, path));
96
98
  continue;
97
99
  }
98
100
  if (!raw || typeof raw !== "object") {
99
- opts.findings.add("convention", `${relative(opts.sddPath, path)}: not an object — skipped`);
101
+ opts.findings.add("convention", `${relative(opts.sddPath, path)}: not an object — manifest dropped`, "error", relative(opts.sddPath, path));
100
102
  continue;
101
103
  }
102
104
  const obj = raw;
103
105
  const cap = obj["capability"] ?? {};
104
106
  const capId = String(cap["id"] ?? "").trim();
105
107
  if (capId === "") {
106
- opts.findings.add("convention", `${relative(opts.sddPath, path)}: missing capability.id`);
108
+ opts.findings.add("convention", `${relative(opts.sddPath, path)}: missing capability.id — manifest dropped`, "error", relative(opts.sddPath, path));
107
109
  continue;
108
110
  }
109
111
  const relPath = relative(opts.sddPath, path);
@@ -144,8 +144,10 @@ export class MethodValidation {
144
144
  if (code !== 0 && !step.advisory) failed++
145
145
  lines.push(verdict.padEnd(8) + " exit " + code + " " + step.id + " (" + step.title + ")")
146
146
  if (code !== 0 || measuredNothing) {
147
- const out = (await ran.stdout()) + (await ran.stderr())
148
- lines.push(...out.trim().split("\n").slice(-6).map((l) => " " + l))
147
+ const out = ((await ran.stdout()) + (await ran.stderr())).trim().split("\n")
148
+ // Every failure line, then the step's last lines: a long report never hides a finding behind its tail.
149
+ const failures = out.filter((l) => /^\s*\[FAIL\] /.test(l))
150
+ lines.push(...[...failures, ...out.slice(-6).filter((l) => !failures.includes(l))].map((l) => " " + l))
149
151
  }
150
152
  }
151
153
  lines.push(failed === 0 ? "RESULT: PASS" : "RESULT: FAIL (" + failed + " failing step(s))")
@@ -6,7 +6,7 @@
6
6
  * source of truth).
7
7
  *
8
8
  * Replaces the v0.3.0 `generate-claude-md` verb whose rich-content
9
- * output diverges from the ADR 0148 thin-pointer shape.
9
+ * output diverges from the M-ADR 0148 thin-pointer shape.
10
10
  */
11
11
  import { access } from "node:fs/promises";
12
12
  import { join } from "node:path";
@@ -36,7 +36,7 @@ export async function runGenerateBriefing(opts, stdout = (line) => process.stdou
36
36
  // graceful skip downstream.
37
37
  const templatesPresent = await fileExists(join(opts.targetDir, BRIEFING_TEMPLATE_ROOT, "agent-instructions.md.hbs"));
38
38
  if (!templatesPresent) {
39
- stdout(fail(`Briefing templates not found under ${BRIEFING_TEMPLATE_ROOT}/ — sync against a baseline that ships ADR 0148 templates first.`));
39
+ stdout(fail(`Briefing templates not found under ${BRIEFING_TEMPLATE_ROOT}/ — sync against a baseline that ships M-ADR 0148 templates first.`));
40
40
  return { exitCode: 1 };
41
41
  }
42
42
  const result = await syncBriefingFiles({
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Builders for the method-managed hook matchers per ADR 0129 §4.2.
2
+ * Builders for the method-managed hook matchers per M-ADR 0129 §4.2.
3
3
  *
4
4
  * Every command carries the METHOD_MANAGED_SENTINEL suffix so the
5
5
  * merge path can identify it on refresh. Adopter-added hooks under
@@ -0,0 +1,280 @@
1
+ // The documented TypeQL subset — PARSER (M-ADR 0210 §4.2).
2
+ //
3
+ // This module reads the authored form of a fact-based model and nothing else: it knows
4
+ // the subset's grammar and refuses, with a located error, anything outside it. It knows
5
+ // nothing about catalogues, YAML or projections — that is `schema-projection.ts`. The split
6
+ // is deliberate: a store extending the subset extends the parser; the method's projection
7
+ // is one consumer of the parsed model among possible others.
8
+ //
9
+ // Fail-closed (M-ADR 0200 §4.3): a construct the parser does not recognise is a ParseError,
10
+ // never a skip. The five blindnesses measured in the prototype this replaces — `@values`,
11
+ // an `@card` form outside the subset, a role with two players, a value-type/family
12
+ // contradiction, a content change that must be visible — are each refused here or made
13
+ // visible to the projection, and the round-trip gate proves that with mutation controls
14
+ // before every verdict.
15
+ //
16
+ // Grammar (one declaration per line; `#` outside a string literal starts a comment):
17
+ // define
18
+ // attribute <label>, value <string|integer|double|boolean|date|datetime>;
19
+ // entity <label>[, owns <attr> [@key] [@card(1..1)|@card(0..1)|@card(0..)]][, plays <rel>:<role> [...]] ...;
20
+ // relation <label>[, relates <role> [@card(1..1)|@card(0..1)|@card(0..)]][, owns ...][, plays ...] ...;
21
+ // Meta rows (the second file):
22
+ // insert $m isa <meta-type>, has <key> <"string"|int|true|false>[, has ...];
23
+ export class ParseError extends Error {
24
+ constructor(message) {
25
+ super(message);
26
+ this.name = "ParseError";
27
+ }
28
+ }
29
+ export const VALUE_TYPES = new Set(["string", "integer", "double", "boolean", "date", "datetime"]);
30
+ export const META_TYPES = new Set([
31
+ "schema-meta",
32
+ "catalogue-meta",
33
+ "column-meta",
34
+ "fk-meta",
35
+ "column-enum-meta",
36
+ "enum-meta",
37
+ "enum-value-meta",
38
+ "enum-value-property",
39
+ "coverage-meta",
40
+ "relationship-meta",
41
+ "vocabulary-meta",
42
+ "rule-meta",
43
+ ]);
44
+ /** Meta keys whose values are lists (repeated `has` on one row). */
45
+ const LIST_KEYS = new Set(["m-external-for-profile", "m-reads"]);
46
+ function unlit(s, where) {
47
+ let out = "";
48
+ for (let i = 0; i < s.length; i++) {
49
+ const c = s[i];
50
+ if (c === "\\" && i + 1 < s.length) {
51
+ const n = s[i + 1];
52
+ const map = { n: "\n", t: "\t", '"': '"', "\\": "\\" };
53
+ const r = map[n];
54
+ if (r === undefined)
55
+ throw new ParseError(`${where}: bad escape \\${n}`);
56
+ out += r;
57
+ i++;
58
+ }
59
+ else {
60
+ out += c;
61
+ }
62
+ }
63
+ return out;
64
+ }
65
+ /** A `#` outside a string literal starts a comment. */
66
+ export function stripComment(line) {
67
+ let out = "";
68
+ let q = false;
69
+ for (let i = 0; i < line.length; i++) {
70
+ const c = line[i];
71
+ if (c === '"' && (i === 0 || line[i - 1] !== "\\"))
72
+ q = !q;
73
+ if (c === "#" && !q)
74
+ break;
75
+ out += c;
76
+ }
77
+ return out.trim();
78
+ }
79
+ const CARD_RE = /^@card\((\d+)\.\.(\d*)\)$/;
80
+ function parseAnnotations(tokens, where) {
81
+ let key = false;
82
+ let required = false;
83
+ let multi = false;
84
+ let optional = false;
85
+ for (const t of tokens) {
86
+ if (t === "@key") {
87
+ key = true;
88
+ }
89
+ else if (t.startsWith("@card(")) {
90
+ const m = CARD_RE.exec(t);
91
+ if (!m)
92
+ throw new ParseError(`${where}: unparseable cardinality ${JSON.stringify(t)}`);
93
+ const lo = m[1];
94
+ const hi = m[2];
95
+ if (lo === "1" && hi === "1")
96
+ required = true;
97
+ else if (lo === "0" && hi === "")
98
+ multi = true;
99
+ else if (lo === "0" && hi === "1")
100
+ optional = true;
101
+ else
102
+ throw new ParseError(`${where}: cardinality ${t} cannot be projected onto the catalogue schema (only @card(1..1), @card(0..1) or @card(0..) are in the subset)`);
103
+ }
104
+ else if (t.startsWith("@values")) {
105
+ throw new ParseError(`${where}: @values(...) is not admitted in this projection — vocabularies bind through column_enums meta rows or a recorded absence (M-ADR 0210 §4.5)`);
106
+ }
107
+ else {
108
+ throw new ParseError(`${where}: unknown token ${JSON.stringify(t)}`);
109
+ }
110
+ }
111
+ return { key, required, multi, optional };
112
+ }
113
+ function splitClauses(body, where) {
114
+ // refuse before the naive split can be fooled by a comma inside the parenthesis
115
+ if (body.includes("@values")) {
116
+ throw new ParseError(`${where}: @values(...) is not admitted in this projection (M-ADR 0210 §4.5)`);
117
+ }
118
+ return body.split(",").map((c) => c.trim());
119
+ }
120
+ const ATTR_RE = /^attribute ([a-z][a-z0-9-]*), value ([a-z]+)$/;
121
+ const TYPE_RE = /^(entity|relation) ([a-z][a-z0-9-]*)(?:, (.*))?$/;
122
+ /** Parse the type-system file. `fileLabel` names the file in error locations. */
123
+ export function parseTypes(text, fileLabel = "catalogue-schema.tql", options = {}) {
124
+ const singlePlayer = options.singlePlayer ?? true;
125
+ const attrs = new Map();
126
+ const entities = new Map();
127
+ const relations = new Map();
128
+ const seen = new Set();
129
+ const lines = text.split(/\r?\n/);
130
+ for (let ln = 1; ln <= lines.length; ln++) {
131
+ let line = stripComment(lines[ln - 1]);
132
+ if (line === "" || line === "define")
133
+ continue;
134
+ const where = `${fileLabel}:${ln}`;
135
+ if (!line.endsWith(";"))
136
+ throw new ParseError(`${where}: declaration must end with ';' — one declaration per line`);
137
+ line = line.slice(0, -1);
138
+ const am = ATTR_RE.exec(line);
139
+ if (am) {
140
+ const lab = am[1];
141
+ const vt = am[2];
142
+ if (!VALUE_TYPES.has(vt))
143
+ throw new ParseError(`${where}: unknown value type ${JSON.stringify(vt)}`);
144
+ if (seen.has(lab))
145
+ throw new ParseError(`${where}: duplicate declaration of ${JSON.stringify(lab)}`);
146
+ seen.add(lab);
147
+ attrs.set(lab, vt);
148
+ continue;
149
+ }
150
+ const tm = TYPE_RE.exec(line);
151
+ if (!tm)
152
+ throw new ParseError(`${where}: not in the subset: ${JSON.stringify(line.slice(0, 100))}`);
153
+ const kind = tm[1];
154
+ const lab = tm[2];
155
+ const body = tm[3];
156
+ if (seen.has(lab))
157
+ throw new ParseError(`${where}: duplicate declaration of ${JSON.stringify(lab)}`);
158
+ seen.add(lab);
159
+ const decl = { owns: new Map(), plays: new Map(), relates: new Map() };
160
+ for (const clause of body !== undefined ? splitClauses(body, where) : []) {
161
+ const w = clause.split(/\s+/).filter((x) => x !== "");
162
+ if (w.length === 0)
163
+ throw new ParseError(`${where}: empty clause`);
164
+ const head = w[0];
165
+ if (head === "owns") {
166
+ if (w.length < 2)
167
+ throw new ParseError(`${where}: owns without attribute`);
168
+ if (decl.owns.has(w[1]))
169
+ throw new ParseError(`${where}: ${lab} owns ${w[1]} twice`);
170
+ decl.owns.set(w[1], parseAnnotations(w.slice(2), where));
171
+ }
172
+ else if (head === "plays") {
173
+ if (w.length < 2 || !w[1].includes(":"))
174
+ throw new ParseError(`${where}: plays needs <relation>:<role>`);
175
+ if (decl.plays.has(w[1]))
176
+ throw new ParseError(`${where}: ${lab} plays ${w[1]} twice`);
177
+ decl.plays.set(w[1], parseAnnotations(w.slice(2), where));
178
+ }
179
+ else if (head === "relates") {
180
+ if (kind !== "relation")
181
+ throw new ParseError(`${where}: only a relation relates`);
182
+ if (w.length < 2)
183
+ throw new ParseError(`${where}: relates without role`);
184
+ if (decl.relates.has(w[1]))
185
+ throw new ParseError(`${where}: ${lab} relates ${w[1]} twice`);
186
+ decl.relates.set(w[1], parseAnnotations(w.slice(2), where));
187
+ }
188
+ else {
189
+ throw new ParseError(`${where}: unknown clause ${JSON.stringify(head)}`);
190
+ }
191
+ }
192
+ (kind === "entity" ? entities : relations).set(lab, decl);
193
+ }
194
+ // every owned attribute must be declared; every role must exist; a role has at most ONE player
195
+ const playersAll = new Map();
196
+ for (const [lab, d] of [...entities, ...relations]) {
197
+ for (const a of d.owns.keys()) {
198
+ if (!attrs.has(a))
199
+ throw new ParseError(`${lab} owns undeclared attribute ${JSON.stringify(a)}`);
200
+ }
201
+ for (const rr of d.plays.keys()) {
202
+ const idx = rr.indexOf(":");
203
+ const rel = rr.slice(0, idx);
204
+ const role = rr.slice(idx + 1);
205
+ const r = relations.get(rel);
206
+ if (!r)
207
+ throw new ParseError(`${lab} plays role of undeclared relation ${JSON.stringify(rel)}`);
208
+ if (!r.relates.has(role))
209
+ throw new ParseError(`${lab} plays undeclared role ${JSON.stringify(rr)}`);
210
+ const list = playersAll.get(rr) ?? [];
211
+ list.push(lab);
212
+ playersAll.set(rr, list);
213
+ }
214
+ }
215
+ const players = new Map();
216
+ for (const [rr, ps] of playersAll) {
217
+ if (ps.length > 1 && !singlePlayer)
218
+ continue;
219
+ if (ps.length > 1) {
220
+ throw new ParseError(`role ${rr} has ${ps.length} players (${ps.join(", ")}); the projection can carry exactly one and refuses to pick`);
221
+ }
222
+ players.set(rr, ps[0]);
223
+ }
224
+ return { attrs, entities, relations, players, playersAll };
225
+ }
226
+ const ROW_RE = /^insert \$m isa ([a-z][a-z0-9-]*), (.*);$/;
227
+ const TOK_RE = /has ([a-z][a-z0-9-]*) ("(?:[^"\\]|\\.)*"|-?\d+|true|false)/y;
228
+ export function parseMeta(text, fileLabel = "catalogue-schema-meta.tql", options = {}) {
229
+ const metaTypes = options.metaTypes ?? META_TYPES;
230
+ const rows = new Map();
231
+ const lines = text.split(/\r?\n/);
232
+ for (let ln = 1; ln <= lines.length; ln++) {
233
+ const line = stripComment(lines[ln - 1]);
234
+ if (line === "")
235
+ continue;
236
+ const where = `${fileLabel}:${ln}`;
237
+ const m = ROW_RE.exec(line);
238
+ if (!m)
239
+ throw new ParseError(`${where}: not in the subset: ${JSON.stringify(line.slice(0, 100))}`);
240
+ const typ = m[1];
241
+ const body = m[2];
242
+ if (!metaTypes.has(typ))
243
+ throw new ParseError(`${where}: unknown meta type ${JSON.stringify(typ)}`);
244
+ const acc = new Map();
245
+ let i = 0;
246
+ for (;;) {
247
+ TOK_RE.lastIndex = i;
248
+ const t = TOK_RE.exec(body);
249
+ if (!t)
250
+ throw new ParseError(`${where}: meta row body not in the subset at offset ${i}: ${JSON.stringify(body.slice(i, i + 60))}`);
251
+ const k = t[1];
252
+ const v = t[2];
253
+ let val;
254
+ if (v.startsWith('"'))
255
+ val = unlit(v.slice(1, -1), where);
256
+ else if (v === "true" || v === "false")
257
+ val = v === "true";
258
+ else
259
+ val = Number.parseInt(v, 10);
260
+ const list = acc.get(k) ?? [];
261
+ list.push(val);
262
+ acc.set(k, list);
263
+ i = TOK_RE.lastIndex;
264
+ if (i === body.length)
265
+ break;
266
+ if (body.startsWith(", ", i))
267
+ i += 2;
268
+ else
269
+ throw new ParseError(`${where}: expected ', has ...' at offset ${i}: ${JSON.stringify(body.slice(i, i + 40))}`);
270
+ }
271
+ const row = {};
272
+ for (const [k, vs] of acc)
273
+ row[k] = LIST_KEYS.has(k) ? vs : vs[0];
274
+ const list = rows.get(typ) ?? [];
275
+ list.push(row);
276
+ rows.set(typ, list);
277
+ }
278
+ return rows;
279
+ }
280
+ //# sourceMappingURL=tql-subset-parser.js.map
@@ -40,7 +40,7 @@ export async function buildPack(opts) {
40
40
  await mkdir(dirname(dest), { recursive: true });
41
41
  await copyFile(src, dest);
42
42
  }
43
- // 3b. Publish transform (ADR 0183/0184) — method-baseline builds only.
43
+ // 3b. Publish transform (M-ADR 0183/0184) — method-baseline builds only.
44
44
  // Produces the point-in-time / producer-agnostic published payload and
45
45
  // fails closed on any published-surface leak, before anything is hashed
46
46
  // or tarred. Non-Accepted ADRs are dropped from the payload.
@@ -224,7 +224,7 @@ function renderManifest(ctx) {
224
224
  lines.push(`source_commit: "${ctx.sourceCommit}"`);
225
225
  lines.push(`generated_at_utc: "${generatedAt}"`);
226
226
  lines.push(``);
227
- lines.push(`# Bundle topology (per ADR 0151 §4)`);
227
+ lines.push(`# Bundle topology (per M-ADR 0151 §4)`);
228
228
  lines.push(`is_forward_base: false`);
229
229
  lines.push(`produced_by_adopter: "${sourceRepo}"`);
230
230
  if (ctx.seed.forwardBase) {
@@ -34,7 +34,7 @@ export async function runPackBuild(opts, stdout = (s) => process.stdout.write(s)
34
34
  stdout(info(`Seed loaded: ${seed.scope} v${seed.version}`));
35
35
  stdout(info(seed.forwardBase
36
36
  ? `Forward base: ${seed.forwardBase.bundle} >= ${seed.forwardBase.minimumVersion}`
37
- : "Forward base: none (profile-agnostic pack, ADR 0176 §4.6)"));
37
+ : "Forward base: none (profile-agnostic pack, M-ADR 0176 §4.6)"));
38
38
  stdout(info(`Managed paths declared: ${seed.managedPaths.length}`));
39
39
  // Origin-prefix implies the publish transform: the ADR rename lives inside it,
40
40
  // so the flag would be a silent no-op otherwise.
@@ -3,7 +3,7 @@ import { join } from "node:path";
3
3
  export async function checkLeakage(opts) {
4
4
  const violations = [];
5
5
  // 1. Disjointness with the forward base. Profile-agnostic packs
6
- // (no forward_base, ADR 0176 §4.6) compare against an explicitly
6
+ // (no forward_base, M-ADR 0176 §4.6) compare against an explicitly
7
7
  // supplied MANAGED_PATHS.txt when given; with neither declared nor
8
8
  // supplied, the forward-base half of the check is skipped (the
9
9
  // forbidden-paths half below still runs).
@@ -3,7 +3,7 @@ import { join } from "node:path";
3
3
  import { ORIGIN_PREFIX_SRC, originPrefixForNumber, originPrefixForPath, } from "../adr-origin.js";
4
4
  export { originPrefixForNumber };
5
5
  /**
6
- * Publish transform (sdd-method ADR 0183 / 0184). Produces the point-in-time,
6
+ * Publish transform (sdd-method M-ADR 0183 / 0184). Produces the point-in-time,
7
7
  * producer-agnostic *published* form of method markdown by subtraction from the
8
8
  * canon, and gates the result with a fail-closed deny-class lint.
9
9
  *
@@ -16,7 +16,7 @@ export { originPrefixForNumber };
16
16
  * Enabled only for method-baseline builds (BuildOptions.publishTransform);
17
17
  * adopter-pack builds are unaffected.
18
18
  */
19
- // Header fields stripped on publish (ADR 0184 — adr-metadata-schema.md).
19
+ // Header fields stripped on publish (M-ADR 0184 — adr-metadata-schema.md).
20
20
  const STRIPPED_FIELDS = [
21
21
  "Status History",
22
22
  "Acceptance Rationale",
@@ -26,7 +26,7 @@ export const PackSeedSchema = z.object({
26
26
  scope: z
27
27
  .string()
28
28
  .regex(/^[a-z0-9-]+$/, "scope must be lower-kebab-case slug"),
29
- // Optional per ADR 0176 §4.6: absent = profile-agnostic pack.
29
+ // Optional per M-ADR 0176 §4.6: absent = profile-agnostic pack.
30
30
  forwardBase: z
31
31
  .object({
32
32
  bundle: z.enum(KNOWN_FORWARD_BASES),
@@ -66,7 +66,7 @@ export const PackSeedSchema = z.object({
66
66
  .array(z.string().min(1))
67
67
  .min(1, "managed_paths must have at least one entry"),
68
68
  forbiddenPaths: z.array(z.string()).optional(),
69
- // ADR 0176 §4.3: scaffold-source path prefixes; each must cover at
69
+ // M-ADR 0176 §4.3: scaffold-source path prefixes; each must cover at
70
70
  // least one managed_paths entry (checked in the superRefine below).
71
71
  scaffoldSourcePaths: z.array(z.string().min(1)).optional(),
72
72
  requiresPack: z
@@ -2,7 +2,7 @@ import { readFile } from "node:fs/promises";
2
2
  import { dirname, isAbsolute, resolve } from "node:path";
3
3
  import { parse as parseYaml } from "yaml";
4
4
  /**
5
- * Adopter pack seed file. Per ADR 0151 + context-pack-seed-schema.yaml.
5
+ * Adopter pack seed file. Per M-ADR 0151 + context-pack-seed-schema.yaml.
6
6
  *
7
7
  * Loaded by `sdd-cli pack build` and `sdd-cli pack validate` from
8
8
  * `orchestration/distribution/{pack-name}-seed.yaml` in adopter repos.
@@ -120,7 +120,7 @@ async function loadSeedRecursive(absPath, visited) {
120
120
  const seed = {
121
121
  version: asString(own.version, "version", absPath),
122
122
  scope: asString(own.scope, "scope", absPath),
123
- // forward_base optional per ADR 0176 §4.6 (profile-agnostic packs omit it)
123
+ // forward_base optional per M-ADR 0176 §4.6 (profile-agnostic packs omit it)
124
124
  ...(own.forward_base && {
125
125
  forwardBase: {
126
126
  bundle: asString(own.forward_base.bundle, "forward_base.bundle", absPath),
@@ -36,7 +36,7 @@ export async function runPackValidate(opts, stdout = (s) => process.stdout.write
36
36
  stdout(pass(`Seed valid: ${seed.scope} v${seed.version}`));
37
37
  stdout(info(seed.forwardBase
38
38
  ? `Forward base: ${seed.forwardBase.bundle} >= ${seed.forwardBase.minimumVersion}`
39
- : "Forward base: none (profile-agnostic pack, ADR 0176 §4.6)"));
39
+ : "Forward base: none (profile-agnostic pack, M-ADR 0176 §4.6)"));
40
40
  if (seed.scaffoldSourcePaths) {
41
41
  stdout(info(`Scaffold-source prefixes: ${seed.scaffoldSourcePaths.join(", ")}`));
42
42
  }
@@ -2,7 +2,7 @@ import { readFile, writeFile } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
  /**
4
4
  * Forward-base bundles set `.sdd-repo-kind` and qualify as the base
5
- * layer that additive extensions can compose on top of (per ADR 0135).
5
+ * layer that additive extensions can compose on top of (per M-ADR 0135).
6
6
  * The legacy self-contained `reverse-baseline` is retained as a
7
7
  * forward base for compat with adopters who haven't migrated to the
8
8
  * `reverse-extension-baseline` additive shape yet.
@@ -14,13 +14,6 @@ const FORWARD_BASE_BUNDLES = new Set([
14
14
  "reverse-baseline",
15
15
  ]);
16
16
  export const REPO_KIND_FILE = ".sdd-repo-kind";
17
- /**
18
- * Legacy marker filename from the pre-rebrand era. Read-only fallback during
19
- * the rebrand transition: `readRepoKind` accepts either filename; `sync`
20
- * auto-migrates legacy → canonical. New writes always use `REPO_KIND_FILE`.
21
- * Drop after one minor-version overlap.
22
- */
23
- export const LEGACY_REPO_KIND_FILE = ".iteraitive-repo-kind";
24
17
  const PROFILE_BY_REPO_KIND = {
25
18
  "platform-product": "platform",
26
19
  "application-product": "application",
@@ -59,7 +52,7 @@ export function repoKindFromProfile(profile) {
59
52
  /**
60
53
  * Returns the profile a bundle authoritatively claims, or null for
61
54
  * additive bundles that don't claim a profile of their own. Accepts
62
- * arbitrary strings (adopter pack names per ADR 0151) and returns null
55
+ * arbitrary strings (adopter pack names per M-ADR 0151) and returns null
63
56
  * for any name not in the closed sdd-method bundle set.
64
57
  */
65
58
  export function profileFromBundleName(name) {
@@ -73,7 +66,7 @@ export function bundleNameFromProfile(profile) {
73
66
  /**
74
67
  * Forward-base bundles set `.sdd-repo-kind` and qualify as the base
75
68
  * layer that additive extensions compose on top of. Additive bundles
76
- * (sdd-method's `reverse-extension-baseline` and ADR 0151 adopter
69
+ * (sdd-method's `reverse-extension-baseline` and M-ADR 0151 adopter
77
70
  * packs) return false. Accepts arbitrary strings; unknown names return
78
71
  * false.
79
72
  */
@@ -103,8 +96,7 @@ export function isBundleName(value) {
103
96
  return ALL_BUNDLE_NAMES.has(value);
104
97
  }
105
98
  export async function readRepoKind(repoRoot) {
106
- // Canonical first; fall back to legacy marker during the rebrand transition.
107
- for (const filename of [REPO_KIND_FILE, LEGACY_REPO_KIND_FILE]) {
99
+ for (const filename of [REPO_KIND_FILE]) {
108
100
  const path = join(repoRoot, filename);
109
101
  let raw;
110
102
  try {