@sdd-method/sdd-cli 0.9.0 → 0.11.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 (182) hide show
  1. package/dist/index.d.ts.map +1 -1
  2. package/dist/index.js +3 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/lib/catalogue/aggregate.d.ts +39 -0
  5. package/dist/lib/catalogue/aggregate.d.ts.map +1 -0
  6. package/dist/lib/catalogue/aggregate.js +344 -0
  7. package/dist/lib/catalogue/aggregate.js.map +1 -0
  8. package/dist/lib/catalogue/aggregation-manifest-loader.d.ts +25 -0
  9. package/dist/lib/catalogue/aggregation-manifest-loader.d.ts.map +1 -0
  10. package/dist/lib/catalogue/aggregation-manifest-loader.js +111 -0
  11. package/dist/lib/catalogue/aggregation-manifest-loader.js.map +1 -0
  12. package/dist/lib/catalogue/build.d.ts +42 -0
  13. package/dist/lib/catalogue/build.d.ts.map +1 -0
  14. package/dist/lib/catalogue/build.js +373 -0
  15. package/dist/lib/catalogue/build.js.map +1 -0
  16. package/dist/lib/catalogue/builders/adr-supersedes.d.ts +14 -0
  17. package/dist/lib/catalogue/builders/adr-supersedes.d.ts.map +1 -0
  18. package/dist/lib/catalogue/builders/adr-supersedes.js +62 -0
  19. package/dist/lib/catalogue/builders/adr-supersedes.js.map +1 -0
  20. package/dist/lib/catalogue/builders/adrs.d.ts +27 -0
  21. package/dist/lib/catalogue/builders/adrs.d.ts.map +1 -0
  22. package/dist/lib/catalogue/builders/adrs.js +191 -0
  23. package/dist/lib/catalogue/builders/adrs.js.map +1 -0
  24. package/dist/lib/catalogue/builders/c4-containers.d.ts +16 -0
  25. package/dist/lib/catalogue/builders/c4-containers.d.ts.map +1 -0
  26. package/dist/lib/catalogue/builders/c4-containers.js +169 -0
  27. package/dist/lib/catalogue/builders/c4-containers.js.map +1 -0
  28. package/dist/lib/catalogue/builders/c4-systems.d.ts +10 -0
  29. package/dist/lib/catalogue/builders/c4-systems.d.ts.map +1 -0
  30. package/dist/lib/catalogue/builders/c4-systems.js +99 -0
  31. package/dist/lib/catalogue/builders/c4-systems.js.map +1 -0
  32. package/dist/lib/catalogue/builders/capabilities.d.ts +11 -0
  33. package/dist/lib/catalogue/builders/capabilities.d.ts.map +1 -0
  34. package/dist/lib/catalogue/builders/capabilities.js +173 -0
  35. package/dist/lib/catalogue/builders/capabilities.js.map +1 -0
  36. package/dist/lib/catalogue/builders/capability-edges.d.ts +27 -0
  37. package/dist/lib/catalogue/builders/capability-edges.d.ts.map +1 -0
  38. package/dist/lib/catalogue/builders/capability-edges.js +166 -0
  39. package/dist/lib/catalogue/builders/capability-edges.js.map +1 -0
  40. package/dist/lib/catalogue/builders/contracts.d.ts +15 -0
  41. package/dist/lib/catalogue/builders/contracts.d.ts.map +1 -0
  42. package/dist/lib/catalogue/builders/contracts.js +153 -0
  43. package/dist/lib/catalogue/builders/contracts.js.map +1 -0
  44. package/dist/lib/catalogue/builders/domains.d.ts +10 -0
  45. package/dist/lib/catalogue/builders/domains.d.ts.map +1 -0
  46. package/dist/lib/catalogue/builders/domains.js +93 -0
  47. package/dist/lib/catalogue/builders/domains.js.map +1 -0
  48. package/dist/lib/catalogue/builders/event-edges.d.ts +20 -0
  49. package/dist/lib/catalogue/builders/event-edges.d.ts.map +1 -0
  50. package/dist/lib/catalogue/builders/event-edges.js +112 -0
  51. package/dist/lib/catalogue/builders/event-edges.js.map +1 -0
  52. package/dist/lib/catalogue/builders/events.d.ts +26 -0
  53. package/dist/lib/catalogue/builders/events.d.ts.map +1 -0
  54. package/dist/lib/catalogue/builders/events.js +99 -0
  55. package/dist/lib/catalogue/builders/events.js.map +1 -0
  56. package/dist/lib/catalogue/builders/feature-groups.d.ts +10 -0
  57. package/dist/lib/catalogue/builders/feature-groups.d.ts.map +1 -0
  58. package/dist/lib/catalogue/builders/feature-groups.js +118 -0
  59. package/dist/lib/catalogue/builders/feature-groups.js.map +1 -0
  60. package/dist/lib/catalogue/builders/features.d.ts +35 -0
  61. package/dist/lib/catalogue/builders/features.d.ts.map +1 -0
  62. package/dist/lib/catalogue/builders/features.js +206 -0
  63. package/dist/lib/catalogue/builders/features.js.map +1 -0
  64. package/dist/lib/catalogue/builders/glossary-xref.d.ts +11 -0
  65. package/dist/lib/catalogue/builders/glossary-xref.d.ts.map +1 -0
  66. package/dist/lib/catalogue/builders/glossary-xref.js +107 -0
  67. package/dist/lib/catalogue/builders/glossary-xref.js.map +1 -0
  68. package/dist/lib/catalogue/builders/glossary.d.ts +14 -0
  69. package/dist/lib/catalogue/builders/glossary.d.ts.map +1 -0
  70. package/dist/lib/catalogue/builders/glossary.js +150 -0
  71. package/dist/lib/catalogue/builders/glossary.js.map +1 -0
  72. package/dist/lib/catalogue/builders/index.d.ts +57 -0
  73. package/dist/lib/catalogue/builders/index.d.ts.map +1 -0
  74. package/dist/lib/catalogue/builders/index.js +33 -0
  75. package/dist/lib/catalogue/builders/index.js.map +1 -0
  76. package/dist/lib/catalogue/builders/integrations.d.ts +12 -0
  77. package/dist/lib/catalogue/builders/integrations.d.ts.map +1 -0
  78. package/dist/lib/catalogue/builders/integrations.js +85 -0
  79. package/dist/lib/catalogue/builders/integrations.js.map +1 -0
  80. package/dist/lib/catalogue/builders/persona-journey-edges.d.ts +26 -0
  81. package/dist/lib/catalogue/builders/persona-journey-edges.d.ts.map +1 -0
  82. package/dist/lib/catalogue/builders/persona-journey-edges.js +133 -0
  83. package/dist/lib/catalogue/builders/persona-journey-edges.js.map +1 -0
  84. package/dist/lib/catalogue/builders/personas.d.ts +22 -0
  85. package/dist/lib/catalogue/builders/personas.d.ts.map +1 -0
  86. package/dist/lib/catalogue/builders/personas.js +150 -0
  87. package/dist/lib/catalogue/builders/personas.js.map +1 -0
  88. package/dist/lib/catalogue/builders/product-edges.d.ts +15 -0
  89. package/dist/lib/catalogue/builders/product-edges.d.ts.map +1 -0
  90. package/dist/lib/catalogue/builders/product-edges.js +97 -0
  91. package/dist/lib/catalogue/builders/product-edges.js.map +1 -0
  92. package/dist/lib/catalogue/builders/products.d.ts +26 -0
  93. package/dist/lib/catalogue/builders/products.d.ts.map +1 -0
  94. package/dist/lib/catalogue/builders/products.js +57 -0
  95. package/dist/lib/catalogue/builders/products.js.map +1 -0
  96. package/dist/lib/catalogue/builders/repo-edges.d.ts +18 -0
  97. package/dist/lib/catalogue/builders/repo-edges.d.ts.map +1 -0
  98. package/dist/lib/catalogue/builders/repo-edges.js +113 -0
  99. package/dist/lib/catalogue/builders/repo-edges.js.map +1 -0
  100. package/dist/lib/catalogue/builders/repositories.d.ts +78 -0
  101. package/dist/lib/catalogue/builders/repositories.d.ts.map +1 -0
  102. package/dist/lib/catalogue/builders/repositories.js +204 -0
  103. package/dist/lib/catalogue/builders/repositories.js.map +1 -0
  104. package/dist/lib/catalogue/builders/service-contract.d.ts +11 -0
  105. package/dist/lib/catalogue/builders/service-contract.d.ts.map +1 -0
  106. package/dist/lib/catalogue/builders/service-contract.js +53 -0
  107. package/dist/lib/catalogue/builders/service-contract.js.map +1 -0
  108. package/dist/lib/catalogue/builders/services.d.ts +15 -0
  109. package/dist/lib/catalogue/builders/services.d.ts.map +1 -0
  110. package/dist/lib/catalogue/builders/services.js +40 -0
  111. package/dist/lib/catalogue/builders/services.js.map +1 -0
  112. package/dist/lib/catalogue/builders/user-journeys.d.ts +24 -0
  113. package/dist/lib/catalogue/builders/user-journeys.d.ts.map +1 -0
  114. package/dist/lib/catalogue/builders/user-journeys.js +253 -0
  115. package/dist/lib/catalogue/builders/user-journeys.js.map +1 -0
  116. package/dist/lib/catalogue/canonical-schema.yaml +624 -0
  117. package/dist/lib/catalogue/cli-version.d.ts +10 -0
  118. package/dist/lib/catalogue/cli-version.d.ts.map +1 -0
  119. package/dist/lib/catalogue/cli-version.js +10 -0
  120. package/dist/lib/catalogue/cli-version.js.map +1 -0
  121. package/dist/lib/catalogue/csv-reader.d.ts +7 -0
  122. package/dist/lib/catalogue/csv-reader.d.ts.map +1 -0
  123. package/dist/lib/catalogue/csv-reader.js +97 -0
  124. package/dist/lib/catalogue/csv-reader.js.map +1 -0
  125. package/dist/lib/catalogue/csv-writer.d.ts +29 -0
  126. package/dist/lib/catalogue/csv-writer.d.ts.map +1 -0
  127. package/dist/lib/catalogue/csv-writer.js +55 -0
  128. package/dist/lib/catalogue/csv-writer.js.map +1 -0
  129. package/dist/lib/catalogue/findings.d.ts +27 -0
  130. package/dist/lib/catalogue/findings.d.ts.map +1 -0
  131. package/dist/lib/catalogue/findings.js +34 -0
  132. package/dist/lib/catalogue/findings.js.map +1 -0
  133. package/dist/lib/catalogue/fk-validator.d.ts +44 -0
  134. package/dist/lib/catalogue/fk-validator.d.ts.map +1 -0
  135. package/dist/lib/catalogue/fk-validator.js +90 -0
  136. package/dist/lib/catalogue/fk-validator.js.map +1 -0
  137. package/dist/lib/catalogue/index.d.ts +27 -0
  138. package/dist/lib/catalogue/index.d.ts.map +1 -0
  139. package/dist/lib/catalogue/index.js +18 -0
  140. package/dist/lib/catalogue/index.js.map +1 -0
  141. package/dist/lib/catalogue/manifest-loader.d.ts +47 -0
  142. package/dist/lib/catalogue/manifest-loader.d.ts.map +1 -0
  143. package/dist/lib/catalogue/manifest-loader.js +161 -0
  144. package/dist/lib/catalogue/manifest-loader.js.map +1 -0
  145. package/dist/lib/catalogue/schema-compat.d.ts +47 -0
  146. package/dist/lib/catalogue/schema-compat.d.ts.map +1 -0
  147. package/dist/lib/catalogue/schema-compat.js +52 -0
  148. package/dist/lib/catalogue/schema-compat.js.map +1 -0
  149. package/dist/lib/catalogue/schema-loader.d.ts +58 -0
  150. package/dist/lib/catalogue/schema-loader.d.ts.map +1 -0
  151. package/dist/lib/catalogue/schema-loader.js +86 -0
  152. package/dist/lib/catalogue/schema-loader.js.map +1 -0
  153. package/dist/lib/catalogue/traceability-loader.d.ts +56 -0
  154. package/dist/lib/catalogue/traceability-loader.d.ts.map +1 -0
  155. package/dist/lib/catalogue/traceability-loader.js +217 -0
  156. package/dist/lib/catalogue/traceability-loader.js.map +1 -0
  157. package/dist/lib/catalogue/validate.d.ts +16 -0
  158. package/dist/lib/catalogue/validate.d.ts.map +1 -0
  159. package/dist/lib/catalogue/validate.js +137 -0
  160. package/dist/lib/catalogue/validate.js.map +1 -0
  161. package/dist/lib/catalogue/version.d.ts +3 -0
  162. package/dist/lib/catalogue/version.d.ts.map +1 -0
  163. package/dist/lib/catalogue/version.js +18 -0
  164. package/dist/lib/catalogue/version.js.map +1 -0
  165. package/dist/lib/init/index.d.ts.map +1 -1
  166. package/dist/lib/init/index.js +6 -0
  167. package/dist/lib/init/index.js.map +1 -1
  168. package/dist/lib/mcp/build-info.d.ts +1 -1
  169. package/dist/lib/mcp/build-info.d.ts.map +1 -1
  170. package/dist/lib/mcp/build-info.js +1 -1
  171. package/dist/lib/mcp/build-info.js.map +1 -1
  172. package/dist/lib/repo-kind.d.ts +3 -3
  173. package/dist/lib/repo-kind.d.ts.map +1 -1
  174. package/dist/lib/repo-kind.js +4 -0
  175. package/dist/lib/repo-kind.js.map +1 -1
  176. package/dist/verbs/catalogue.d.ts +3 -0
  177. package/dist/verbs/catalogue.d.ts.map +1 -0
  178. package/dist/verbs/catalogue.js +60 -0
  179. package/dist/verbs/catalogue.js.map +1 -0
  180. package/package.json +3 -3
  181. package/scripts/copy-yaml-assets.mjs +38 -0
  182. package/scripts/sync-canonical-schema.sh +39 -0
@@ -0,0 +1,93 @@
1
+ // Domain discoverer — emits `domains.csv` rows from `docs/domains/<slug>/`.
2
+ //
3
+ // Per ADR 0134 and catalogue-builder-specification.md:
4
+ // - Domains are method-defined: each subdirectory under docs/domains/
5
+ // is one domain, named by its slug.
6
+ // - method_profile reflects the SDD's profile (the domain belongs to
7
+ // this SDD's method profile).
8
+ // - repo_count is computed by the build orchestrator after repositories
9
+ // are discovered, since this builder runs first.
10
+ import { readdir, readFile, stat } from "node:fs/promises";
11
+ import { join } from "node:path";
12
+ const DOMAINS_DIR_REL = join("docs", "domains");
13
+ export async function buildDomains(inputs) {
14
+ const domainsDir = join(inputs.sddPath, DOMAINS_DIR_REL);
15
+ let entries;
16
+ try {
17
+ entries = (await readdir(domainsDir, { withFileTypes: true }))
18
+ .filter((e) => e.isDirectory())
19
+ .map((e) => ({ name: e.name }));
20
+ }
21
+ catch (err) {
22
+ const code = err.code;
23
+ if (code === "ENOENT") {
24
+ inputs.findings.add("coverage", `${DOMAINS_DIR_REL}/ not found - emitting empty domains.csv`);
25
+ return [];
26
+ }
27
+ throw err;
28
+ }
29
+ const rows = [];
30
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
31
+ const slug = entry.name;
32
+ const description = await readDomainDescription(join(domainsDir, slug), inputs.findings, slug);
33
+ rows.push({
34
+ id: slug,
35
+ name: titleCase(slug),
36
+ description,
37
+ method_profile: inputs.manifest.profile,
38
+ reference_architecture_equivalent: "",
39
+ status: "active",
40
+ repo_count: 0, // populated by orchestrator after repositories build
41
+ source_sdd_id: "",
42
+ });
43
+ }
44
+ return rows;
45
+ }
46
+ /**
47
+ * Look for a one-line description in a domain README. Falls back to
48
+ * empty when no README or no usable first paragraph is present.
49
+ */
50
+ async function readDomainDescription(domainDir, findings, slug) {
51
+ const candidates = ["README.md", "README.markdown"];
52
+ for (const name of candidates) {
53
+ const path = join(domainDir, name);
54
+ try {
55
+ const s = await stat(path);
56
+ if (!s.isFile())
57
+ continue;
58
+ const text = await readFile(path, "utf-8");
59
+ const firstPara = extractFirstParagraph(text);
60
+ if (firstPara)
61
+ return firstPara.slice(0, 500);
62
+ }
63
+ catch (err) {
64
+ const code = err.code;
65
+ if (code !== "ENOENT")
66
+ throw err;
67
+ }
68
+ }
69
+ findings.add("coverage", `domain ${slug} has no README.md — description left empty`);
70
+ return "";
71
+ }
72
+ function extractFirstParagraph(markdown) {
73
+ // Strip an optional H1, then return the first non-empty paragraph
74
+ // (text up to the first blank line).
75
+ const lines = markdown.split(/\r?\n/);
76
+ let i = 0;
77
+ while (i < lines.length && (lines[i] === undefined || lines[i].trim() === "" || lines[i].startsWith("#"))) {
78
+ i++;
79
+ }
80
+ const para = [];
81
+ while (i < lines.length && lines[i].trim() !== "") {
82
+ para.push(lines[i].trim());
83
+ i++;
84
+ }
85
+ return para.join(" ").trim();
86
+ }
87
+ function titleCase(slug) {
88
+ return slug
89
+ .split("-")
90
+ .map((p) => (p.length === 0 ? p : p[0].toUpperCase() + p.slice(1)))
91
+ .join(" ");
92
+ }
93
+ //# sourceMappingURL=domains.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domains.js","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/domains.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { CatalogueRow } from "../csv-writer.js";
2
+ import type { FindingsLog } from "../findings.js";
3
+ import type { ParsedRepoConfig } from "./repositories.js";
4
+ import type { TraceabilityManifest } from "../traceability-loader.js";
5
+ export interface ServiceEventInputs {
6
+ readonly findings: FindingsLog;
7
+ readonly configs: readonly ParsedRepoConfig[];
8
+ readonly contractIdByPath: ReadonlyMap<string, string>;
9
+ readonly knownServiceIds: ReadonlySet<string>;
10
+ readonly knownEventIds: ReadonlySet<string>;
11
+ }
12
+ export interface CapabilityEventInputs {
13
+ readonly findings: FindingsLog;
14
+ readonly manifests: readonly TraceabilityManifest[];
15
+ readonly knownCapabilityIds: ReadonlySet<string>;
16
+ readonly knownEventIds: ReadonlySet<string>;
17
+ }
18
+ export declare function buildServiceEvent(inputs: ServiceEventInputs): CatalogueRow[];
19
+ export declare function buildCapabilityEvent(inputs: CapabilityEventInputs): CatalogueRow[];
20
+ //# sourceMappingURL=event-edges.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-edges.d.ts","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/event-edges.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEtE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC9C,QAAQ,CAAC,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvD,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC9C,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACpD,QAAQ,CAAC,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjD,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC7C;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,EAAE,CAiC5E;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,qBAAqB,GAC5B,YAAY,EAAE,CAuChB"}
@@ -0,0 +1,112 @@
1
+ // service_event + capability_event edge builders.
2
+ //
3
+ // service_event:
4
+ // - From repo-config `events.produces[].schema` (role=publishes)
5
+ // and `events.consumes[].schema` (role=consumes). Each schema is
6
+ // resolved against the contracts.avro index → event id.
7
+ // - `contracts.avro` is NOT a fallback for publishes — it's a
8
+ // build-time list (for code-gen / validation) that consumers
9
+ // commonly declare too. Only the events block is authoritative.
10
+ //
11
+ // capability_event:
12
+ // - From traceability `traceability.events[]` when present (forward
13
+ // method extension; not yet adopted in contextua-platform per the
14
+ // metamodel's "populated where specs adopt `## Related Events`" note).
15
+ // - Empty until adopters declare events under their traceability.
16
+ import { sep } from "node:path";
17
+ export function buildServiceEvent(inputs) {
18
+ const rows = [];
19
+ const seen = new Set();
20
+ const emit = (serviceId, eventId, role) => {
21
+ if (!inputs.knownServiceIds.has(serviceId))
22
+ return;
23
+ if (!inputs.knownEventIds.has(eventId))
24
+ return;
25
+ const id = `${serviceId}__${eventId}__${role}`;
26
+ if (seen.has(id))
27
+ return;
28
+ seen.add(id);
29
+ rows.push({ id, service_id: serviceId, event_id: eventId, role });
30
+ };
31
+ for (const cfg of inputs.configs) {
32
+ const events = cfg.data.events;
33
+ if (!events)
34
+ continue;
35
+ for (const entry of events.produces ?? []) {
36
+ if (!entry.schema)
37
+ continue;
38
+ const eid = resolveAvroPath(entry.schema, inputs.contractIdByPath);
39
+ if (eid !== undefined)
40
+ emit(cfg.repoId, eid, "publishes");
41
+ }
42
+ for (const entry of events.consumes ?? []) {
43
+ if (!entry.schema)
44
+ continue;
45
+ const eid = resolveAvroPath(entry.schema, inputs.contractIdByPath);
46
+ if (eid !== undefined)
47
+ emit(cfg.repoId, eid, "consumes");
48
+ }
49
+ }
50
+ return rows;
51
+ }
52
+ export function buildCapabilityEvent(inputs) {
53
+ const rows = [];
54
+ const seen = new Set();
55
+ for (const m of inputs.manifests) {
56
+ const capId = m.capability.id;
57
+ if (!inputs.knownCapabilityIds.has(capId))
58
+ continue;
59
+ // The traceability.events block is an aspirational forward extension;
60
+ // not all manifests declare it. When absent, this manifest contributes
61
+ // nothing to the edge.
62
+ const events = m.data
63
+ ?.traceability?.events;
64
+ if (!Array.isArray(events))
65
+ continue;
66
+ for (const entry of events) {
67
+ if (!entry || typeof entry !== "object")
68
+ continue;
69
+ const o = entry;
70
+ const eid = String(o["id"] ?? "").trim();
71
+ const role = String(o["role"] ?? "").trim();
72
+ if (eid === "" || (role !== "publishes" && role !== "consumes"))
73
+ continue;
74
+ if (!inputs.knownEventIds.has(eid)) {
75
+ inputs.findings.add("orphan", `${m.relPath}: capability_event references "${eid}" but no such event exists`);
76
+ continue;
77
+ }
78
+ const edgeId = `${capId}__${eid}__${role}`;
79
+ if (seen.has(edgeId))
80
+ continue;
81
+ seen.add(edgeId);
82
+ rows.push({
83
+ id: edgeId,
84
+ capability_id: capId,
85
+ event_id: eid,
86
+ role,
87
+ });
88
+ }
89
+ }
90
+ return rows;
91
+ }
92
+ function resolveAvroPath(schema, index) {
93
+ const cleaned = schema.replace(/^\/+/, "");
94
+ const full = `contracts/avro/${cleaned}`;
95
+ if (index.has(full))
96
+ return index.get(full);
97
+ if (index.has(cleaned))
98
+ return index.get(cleaned);
99
+ for (const [path, id] of index) {
100
+ const parts = path.split(sep);
101
+ if (parts.length >= 2 && parts.slice(-2).join("/") === cleaned)
102
+ return id;
103
+ }
104
+ const base = cleaned.split("/").slice(-1)[0] ?? cleaned;
105
+ for (const [path, id] of index) {
106
+ const parts = path.split(sep);
107
+ if ((parts[parts.length - 1] ?? "") === base)
108
+ return id;
109
+ }
110
+ return undefined;
111
+ }
112
+ //# sourceMappingURL=event-edges.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-edges.js","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/event-edges.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { CatalogueRow } from "../csv-writer.js";
2
+ import type { FindingsLog } from "../findings.js";
3
+ import type { ParsedRepoConfig } from "./repositories.js";
4
+ export interface EventsBuildInputs {
5
+ readonly findings: FindingsLog;
6
+ /** Contract rows where kind=event (avro). */
7
+ readonly avroContracts: readonly CatalogueRow[];
8
+ /** Map of contract spec_path → contract id, for repo-config schema-path resolution. */
9
+ readonly contractIdByPath: ReadonlyMap<string, string>;
10
+ /** Repo-config configs from the repositories builder. */
11
+ readonly configs: readonly ParsedRepoConfig[];
12
+ /** Service ids known to this build (so publisher_service_id only resolves to runtime services). */
13
+ readonly knownServiceIds: ReadonlySet<string>;
14
+ /** Domain ids known to this build (for domain_id fallback). */
15
+ readonly knownDomainIds: ReadonlySet<string>;
16
+ }
17
+ export interface PublisherIndex {
18
+ /** Map of contract id → repo (== service) id that publishes it, when one is declared. */
19
+ readonly publisherByContractId: ReadonlyMap<string, string>;
20
+ }
21
+ export interface EventsBuildResult {
22
+ readonly rows: CatalogueRow[];
23
+ readonly publisherIndex: PublisherIndex;
24
+ }
25
+ export declare function buildEvents(inputs: EventsBuildInputs): EventsBuildResult;
26
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/events.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,6CAA6C;IAC7C,QAAQ,CAAC,aAAa,EAAE,SAAS,YAAY,EAAE,CAAC;IAChD,uFAAuF;IACvF,QAAQ,CAAC,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvD,yDAAyD;IACzD,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC9C,mGAAmG;IACnG,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC9C,+DAA+D;IAC/D,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,cAAc;IAC7B,yFAAyF;IACzF,QAAQ,CAAC,qBAAqB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;CACzC;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CAkDxE"}
@@ -0,0 +1,99 @@
1
+ // Events discoverer — emits `events.csv` from avro contracts (kind=event).
2
+ //
3
+ // In the forward method, every avro `*.avsc` schema declares one event;
4
+ // the canonical builder treats events as 1:1 with avro contracts and
5
+ // reuses the contract's id as the event id.
6
+ //
7
+ // publisher_service_id derivation: ONLY events.produces is authoritative.
8
+ // `contracts.avro` is a build-time list (for code-gen / validation) and
9
+ // MUST NOT be inferred as a publish declaration — services that consume
10
+ // avro schemas commonly list them under contracts.avro too. If no
11
+ // service declares events.produces for a given schema, the event row
12
+ // emits with empty publisher_service_id.
13
+ //
14
+ // transport defaults to `nats` per ADR 0068 (Scaleway MnQ NATS for
15
+ // platform messaging). The schema's enum doesn't include "nats" today;
16
+ // the column is nullable string so any value is accepted.
17
+ import { sep } from "node:path";
18
+ export function buildEvents(inputs) {
19
+ // Build the publisher index from repo-config events.produces only.
20
+ // Earlier-encountered service wins on ties (deterministic per sorted
21
+ // config order from the repositories builder).
22
+ const publisherByContractId = new Map();
23
+ for (const cfg of inputs.configs) {
24
+ if (!inputs.knownServiceIds.has(cfg.repoId))
25
+ continue;
26
+ const events = cfg.data.events;
27
+ const produces = events?.produces ?? [];
28
+ for (const entry of produces) {
29
+ const schema = entry.schema;
30
+ if (!schema)
31
+ continue;
32
+ const id = resolveContractByPath(schema, "avro", inputs.contractIdByPath);
33
+ if (id === undefined)
34
+ continue;
35
+ if (!publisherByContractId.has(id)) {
36
+ publisherByContractId.set(id, cfg.repoId);
37
+ }
38
+ }
39
+ }
40
+ const rows = [];
41
+ for (const c of inputs.avroContracts) {
42
+ const id = String(c["id"]);
43
+ const specPath = String(c["spec_path"] ?? "");
44
+ const rawDomain = inferDomainFromAvroPath(specPath);
45
+ let domain = rawDomain;
46
+ if (rawDomain.startsWith("_")) {
47
+ // `_common`, `_shared`, etc. — cross-domain envelope schemas.
48
+ // Emit empty domain_id (events.domain_id is nullable per schema 1.4.0).
49
+ domain = "";
50
+ }
51
+ else if (rawDomain !== "" && !inputs.knownDomainIds.has(rawDomain)) {
52
+ inputs.findings.add("orphan", `event ${id}: schema is at ${specPath} but no docs/domains/${rawDomain}/ exists — emitting with empty domain_id`);
53
+ domain = "";
54
+ }
55
+ rows.push({
56
+ id,
57
+ name: String(c["name"] ?? id),
58
+ publisher_service_id: publisherByContractId.get(id) ?? "",
59
+ domain_id: domain,
60
+ transport: "nats",
61
+ schema_path: specPath,
62
+ version: String(c["version"] ?? ""),
63
+ source_sdd_id: "",
64
+ });
65
+ }
66
+ return { rows, publisherIndex: { publisherByContractId } };
67
+ }
68
+ function inferDomainFromAvroPath(relPath) {
69
+ // Layout: contracts/avro/<domain>/<file>.avsc
70
+ const parts = relPath.split(sep);
71
+ if (parts.length < 4)
72
+ return "";
73
+ return parts[2] ?? "";
74
+ }
75
+ function resolveContractByPath(schema, kind, index) {
76
+ const cleaned = schema.replace(/^\/+/, "");
77
+ // Repo-config event paths are relative to contracts/<kind>/.
78
+ const fullCandidate = `contracts/${kind}/${cleaned}`;
79
+ if (index.has(fullCandidate))
80
+ return index.get(fullCandidate);
81
+ if (index.has(cleaned))
82
+ return index.get(cleaned);
83
+ // Suffix fallback (last two segments).
84
+ for (const [path, id] of index) {
85
+ const parts = path.split(sep);
86
+ const last2 = parts.length >= 2 ? parts.slice(-2).join("/") : "";
87
+ if (last2 === cleaned)
88
+ return id;
89
+ }
90
+ // Basename fallback.
91
+ const base = cleaned.split("/").slice(-1)[0] ?? cleaned;
92
+ for (const [path, id] of index) {
93
+ const parts = path.split(sep);
94
+ if ((parts[parts.length - 1] ?? "") === base)
95
+ return id;
96
+ }
97
+ return undefined;
98
+ }
99
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { CatalogueRow } from "../csv-writer.js";
2
+ import type { FindingsLog } from "../findings.js";
3
+ export interface FeatureGroupsBuildInputs {
4
+ readonly sddPath: string;
5
+ readonly findings: FindingsLog;
6
+ /** Used to scope group ids when product-bound (typically the SDD's own product id). */
7
+ readonly productId: string;
8
+ }
9
+ export declare function buildFeatureGroups(inputs: FeatureGroupsBuildInputs): Promise<CatalogueRow[]>;
10
+ //# sourceMappingURL=feature-groups.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-groups.d.ts","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/feature-groups.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,uFAAuF;IACvF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAOD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,YAAY,EAAE,CAAC,CAkDzB"}
@@ -0,0 +1,118 @@
1
+ // FeatureGroups discoverer — emits `feature_groups.csv` rows from
2
+ // hierarchical `feature-tree.md` files.
3
+ //
4
+ // Per Q7.2 resolution (adopt-canonical-catalogue-builder.md §7.2),
5
+ // FeatureGroups are first-class entities. This builder parses pure
6
+ // markdown H2/H3 headings as the hierarchical structure:
7
+ // - H2 heading → top-level FeatureGroup (parent_group_id = "")
8
+ // - H3 heading → child FeatureGroup (parent_group_id = enclosing H2's id)
9
+ //
10
+ // ASCII-tree representations inside fenced code blocks are NOT parsed
11
+ // — those are an adopter authoring style that doesn't map cleanly to
12
+ // catalogue entities. Adopters wanting first-class groups format their
13
+ // feature trees with proper H2/H3 headings.
14
+ //
15
+ // Source paths checked (in order, first match wins):
16
+ // - <sddRoot>/feature-tree.md (typical for app-product SDDs)
17
+ // - <sddRoot>/docs/platform/feature-tree.md (typical for platform SDDs)
18
+ import { readFile } from "node:fs/promises";
19
+ import { join, relative } from "node:path";
20
+ const CANDIDATE_PATHS_REL = [
21
+ "feature-tree.md",
22
+ join("docs", "platform", "feature-tree.md"),
23
+ ];
24
+ export async function buildFeatureGroups(inputs) {
25
+ const featureTreePath = await firstExisting(inputs.sddPath, CANDIDATE_PATHS_REL);
26
+ if (!featureTreePath) {
27
+ return [];
28
+ }
29
+ const text = await readFile(featureTreePath, "utf-8");
30
+ const headings = extractHeadingsOutsideCodeFences(text);
31
+ const rows = [];
32
+ let currentH2Id = "";
33
+ for (const h of headings) {
34
+ if (h.level === 2) {
35
+ const id = `${inputs.productId}-group-${slugify(h.text)}`;
36
+ currentH2Id = id;
37
+ rows.push({
38
+ id,
39
+ name: h.text,
40
+ product_id: inputs.productId,
41
+ capability_id: "",
42
+ parent_group_id: "",
43
+ description: "",
44
+ source: "feature-tree-h2",
45
+ source_sdd_id: "",
46
+ });
47
+ }
48
+ else if (h.level === 3) {
49
+ if (currentH2Id === "") {
50
+ // H3 with no enclosing H2 — orphan; surface as finding but emit anyway.
51
+ inputs.findings.add("convention", `${relative(inputs.sddPath, featureTreePath)}: H3 "${h.text}" has no enclosing H2`);
52
+ }
53
+ const id = currentH2Id !== ""
54
+ ? `${currentH2Id}-${slugify(h.text)}`
55
+ : `${inputs.productId}-group-${slugify(h.text)}`;
56
+ rows.push({
57
+ id,
58
+ name: h.text,
59
+ product_id: inputs.productId,
60
+ capability_id: "",
61
+ parent_group_id: currentH2Id,
62
+ description: "",
63
+ source: "feature-tree-h3",
64
+ source_sdd_id: "",
65
+ });
66
+ }
67
+ }
68
+ return rows;
69
+ }
70
+ function extractHeadingsOutsideCodeFences(text) {
71
+ const out = [];
72
+ let inFence = false;
73
+ for (const rawLine of text.split(/\r?\n/)) {
74
+ const line = rawLine.trimEnd();
75
+ if (line.startsWith("```")) {
76
+ inFence = !inFence;
77
+ continue;
78
+ }
79
+ if (inFence)
80
+ continue;
81
+ const m = /^(#{2,3})\s+(.+?)\s*$/.exec(line);
82
+ if (!m || m[1] === undefined || m[2] === undefined)
83
+ continue;
84
+ const level = m[1].length === 2 ? 2 : 3;
85
+ const headingText = m[2]
86
+ .replace(/^[\d.]+\s*/, "") // strip leading "1.", "1.1", etc.
87
+ .replace(/\s*\[.+?\]\s*$/, "") // strip trailing "[Business]" / "[Enabler-Runway]" tags
88
+ .trim();
89
+ if (headingText === "")
90
+ continue;
91
+ out.push({ level, text: headingText });
92
+ }
93
+ return out;
94
+ }
95
+ function slugify(text) {
96
+ return text
97
+ .toLowerCase()
98
+ .replace(/&/g, " and ")
99
+ .replace(/[^a-z0-9]+/g, "-")
100
+ .replace(/^-+|-+$/g, "");
101
+ }
102
+ async function firstExisting(sddPath, candidates) {
103
+ for (const rel of candidates) {
104
+ const full = join(sddPath, rel);
105
+ try {
106
+ await readFile(full, "utf-8");
107
+ return full;
108
+ }
109
+ catch (err) {
110
+ const code = err.code;
111
+ if (code === "ENOENT")
112
+ continue;
113
+ throw err;
114
+ }
115
+ }
116
+ return null;
117
+ }
118
+ //# sourceMappingURL=feature-groups.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-groups.js","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/feature-groups.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { CatalogueRow } from "../csv-writer.js";
2
+ import type { FindingsLog } from "../findings.js";
3
+ import type { TraceabilityManifest } from "../traceability-loader.js";
4
+ export interface FeaturesBuildInputs {
5
+ readonly sddPath: string;
6
+ readonly findings: FindingsLog;
7
+ readonly manifests: readonly TraceabilityManifest[];
8
+ readonly knownCapabilityIds: ReadonlySet<string>;
9
+ /**
10
+ * SDD profile, used to opt in to app-product feature discovery at
11
+ * `features/<group>/<file>.md` (alongside the platform/domain
12
+ * convention). Per Step 4 of the canonical-builder Phase 2 plan.
13
+ */
14
+ readonly profile: string;
15
+ /**
16
+ * Product id for the SDD itself — used as the feature id prefix and
17
+ * `product_id` value when reading app-product features. Ignored for
18
+ * platform-profile SDDs.
19
+ */
20
+ readonly productId: string;
21
+ }
22
+ export interface FeaturesBuildResult {
23
+ readonly rows: CatalogueRow[];
24
+ /** Map of feature spec relative path → feature id (for capability_feature edge resolution). */
25
+ readonly idByPath: ReadonlyMap<string, string>;
26
+ /**
27
+ * Map of feature slug (filename stem) → feature id, for resolving
28
+ * bare-slug references in personas/journeys content. First-seen wins
29
+ * when the same slug appears under multiple capabilities; the orphan
30
+ * finding from the consumer side surfaces the (rare) collision.
31
+ */
32
+ readonly idBySlug: ReadonlyMap<string, string>;
33
+ }
34
+ export declare function buildFeatures(inputs: FeaturesBuildInputs): Promise<FeaturesBuildResult>;
35
+ //# sourceMappingURL=features.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../../../../src/lib/catalogue/builders/features.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEtE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACpD,QAAQ,CAAC,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjD;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC;IAC9B,+FAA+F;IAC/F,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChD;AAID,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAkG9B"}