@sdd-method/sdd-cli 0.122.2 → 1.0.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 (68) hide show
  1. package/dist/index.d.ts.map +1 -1
  2. package/dist/index.js +2 -0
  3. package/dist/index.js.map +1 -1
  4. package/dist/lib/catalogue/aggregate.d.ts +26 -2
  5. package/dist/lib/catalogue/aggregate.d.ts.map +1 -1
  6. package/dist/lib/catalogue/aggregate.js +220 -12
  7. package/dist/lib/catalogue/aggregate.js.map +1 -1
  8. package/dist/lib/catalogue/build.d.ts.map +1 -1
  9. package/dist/lib/catalogue/build.js +24 -5
  10. package/dist/lib/catalogue/build.js.map +1 -1
  11. package/dist/lib/catalogue/builders/c4-external-systems.d.ts.map +1 -1
  12. package/dist/lib/catalogue/builders/c4-external-systems.js +27 -19
  13. package/dist/lib/catalogue/builders/c4-external-systems.js.map +1 -1
  14. package/dist/lib/catalogue/builders/contracts.d.ts.map +1 -1
  15. package/dist/lib/catalogue/builders/contracts.js +12 -4
  16. package/dist/lib/catalogue/builders/contracts.js.map +1 -1
  17. package/dist/lib/catalogue/builders/external-system-exemption.d.ts +10 -0
  18. package/dist/lib/catalogue/builders/external-system-exemption.d.ts.map +1 -1
  19. package/dist/lib/catalogue/builders/external-system-exemption.js +19 -3
  20. package/dist/lib/catalogue/builders/external-system-exemption.js.map +1 -1
  21. package/dist/lib/catalogue/builders/products.d.ts.map +1 -1
  22. package/dist/lib/catalogue/builders/products.js +0 -6
  23. package/dist/lib/catalogue/builders/products.js.map +1 -1
  24. package/dist/lib/catalogue/builders/service-contract-consumes.d.ts +12 -0
  25. package/dist/lib/catalogue/builders/service-contract-consumes.d.ts.map +1 -1
  26. package/dist/lib/catalogue/builders/service-contract-consumes.js +14 -1
  27. package/dist/lib/catalogue/builders/service-contract-consumes.js.map +1 -1
  28. package/dist/lib/catalogue/canonical-schema.yaml +78 -17
  29. package/dist/lib/catalogue/contract-id.d.ts +11 -0
  30. package/dist/lib/catalogue/contract-id.d.ts.map +1 -0
  31. package/dist/lib/catalogue/contract-id.js +49 -0
  32. package/dist/lib/catalogue/contract-id.js.map +1 -0
  33. package/dist/lib/catalogue/enum-validator.d.ts +16 -0
  34. package/dist/lib/catalogue/enum-validator.d.ts.map +1 -0
  35. package/dist/lib/catalogue/enum-validator.js +46 -0
  36. package/dist/lib/catalogue/enum-validator.js.map +1 -0
  37. package/dist/lib/catalogue/ext-id.d.ts +25 -0
  38. package/dist/lib/catalogue/ext-id.d.ts.map +1 -0
  39. package/dist/lib/catalogue/ext-id.js +76 -0
  40. package/dist/lib/catalogue/ext-id.js.map +1 -0
  41. package/dist/lib/catalogue/index.d.ts +1 -0
  42. package/dist/lib/catalogue/index.d.ts.map +1 -1
  43. package/dist/lib/catalogue/index.js +1 -0
  44. package/dist/lib/catalogue/index.js.map +1 -1
  45. package/dist/lib/catalogue/migration-map.d.ts +27 -0
  46. package/dist/lib/catalogue/migration-map.d.ts.map +1 -0
  47. package/dist/lib/catalogue/migration-map.js +114 -0
  48. package/dist/lib/catalogue/migration-map.js.map +1 -0
  49. package/dist/lib/catalogue/reverse-product-quality.js +3 -3
  50. package/dist/lib/catalogue/reverse-product-quality.js.map +1 -1
  51. package/dist/lib/catalogue/schema-compat.d.ts +1 -1
  52. package/dist/lib/catalogue/schema-compat.js +1 -1
  53. package/dist/lib/catalogue/validate.d.ts +2 -0
  54. package/dist/lib/catalogue/validate.d.ts.map +1 -1
  55. package/dist/lib/catalogue/validate.js +22 -5
  56. package/dist/lib/catalogue/validate.js.map +1 -1
  57. package/dist/lib/contracts-availability/index.d.ts +44 -0
  58. package/dist/lib/contracts-availability/index.d.ts.map +1 -0
  59. package/dist/lib/contracts-availability/index.js +267 -0
  60. package/dist/lib/contracts-availability/index.js.map +1 -0
  61. package/dist/verbs/catalogue.d.ts.map +1 -1
  62. package/dist/verbs/catalogue.js +12 -1
  63. package/dist/verbs/catalogue.js.map +1 -1
  64. package/dist/verbs/contracts.d.ts +3 -0
  65. package/dist/verbs/contracts.d.ts.map +1 -0
  66. package/dist/verbs/contracts.js +33 -0
  67. package/dist/verbs/contracts.js.map +1 -0
  68. package/package.json +1 -1
@@ -62,9 +62,72 @@
62
62
  # Builder contract: see docs/method/methods/catalogue-builder-specification.md.
63
63
  # Category taxonomy: see docs/method/methods/product-category-taxonomy.md.
64
64
 
65
- schema_version: "2.51.0"
65
+ schema_version: "3.0.0"
66
66
  schema_owner: "sdd-method"
67
67
  schema_status: "canonical"
68
+ # Bump rationale (3.0.0 — BREAKING major, 2026-07-29, per M-ADR 0203): the 2.x line's
69
+ # five deferred breaks land as one audited cut, each a complete change-set in the
70
+ # M-ADR 0200 §4.1 sense. This entry records each break as its change-set lands:
71
+ # 1. `products.status` REMOVED (0203 §4.3): deprecated at 2.48.0 as a duplication of
72
+ # the strictly-more-expressive synthesis_quality/synthesis_band/last_assessed
73
+ # triplet; emitted the constant 'active' — outside its own documented vocabulary —
74
+ # on 208 of 208 measured rows across two estates. Zero consumers, verified at
75
+ # deprecation time and RE-VERIFIED at removal across builders, aggregator, and
76
+ # orchestration scripts (the same-named status columns on other tables are
77
+ # different columns and are untouched). Committed catalogues self-heal: the column
78
+ # disappears from products.csv on the first 3.0.0 rebuild; no migration map needed.
79
+ # 2. `c4_container_type` BOUND, legacy values removed (0203 §4.1, completing 0155):
80
+ # the enum binds into `c4_containers.column_enums` and a schema-driven bound-enum
81
+ # validator gives every binding hard-fail teeth (error-severity findings, same
82
+ # exit contract as a dangling internal FK, in build AND validate). The 2.x
83
+ # advisory WARN module is deleted per its own header. Exit gated on the pre-cut
84
+ # audit of every adopter's legacy c4_containers rows — per-row dispositions
85
+ # recorded per 0155's migration rule, not defaulted.
86
+ # 3. `c4_external_systems` row identity moves to the declared diagram entry id
87
+ # (0203 §4.2, completing 0189 §4.2): id = ext-{slug(entry id)}; the display-name
88
+ # slug era ends. The old→new map is DERIVED (name + declared_id are both in every
89
+ # 2.30.0+ catalogue): `sdd-cli catalogue migration-map` emits it, and the
90
+ # exemption loader consults it in the cut window — an authored
91
+ # external_system_exemption keyed by a mapped old id re-keys as regenerable, NOT
92
+ # drift (the F30 rule at schema scale); un-mapped old-form ids fail loudly with
93
+ # the map named. The migration's own fallout has a detector (measured pre-ship:
94
+ # 5 old ids deriving 2-3 conflicting new ids across one estate, because SDDs
95
+ # declared different entry ids for one external system — the 2.x name-slugs
96
+ # merged them silently): at aggregation, one display name held by several kept
97
+ # declared identities is a convention finding — converge the entry ids, or
98
+ # rename the labels apart; never a silent split. And its mirror (measured: 17
99
+ # integration SDDs declaring 17 different providers under ONE shared generic
100
+ # entry id): a same-id merge whose display names do not corroborate is a
101
+ # divergence finding naming every hidden referent — never a silent 17-into-1
102
+ # collapse. Both remedies are diagram edits (M-ADR 0189 §4.2's sanctioned
103
+ # opt-out), never catalogue edits.
104
+ # 4. Contract ids gain their KIND component (0203 §4.4 — the cut's acid test):
105
+ # id = {domain}-{stem}-{kind}, ending the kindless collision class with its
106
+ # measured permanent cost. Enumerated consumers all take ids by value and
107
+ # migrate with the FK — capability_contract, service_contract, repo_contract,
108
+ # feature_contract, including the two composite PKs embedding contract_id.
109
+ # Feeders re-keyed: the discoverer, the declared-external (D13) builder, and the
110
+ # M-ADR 0147 alias-resolved consumes builder (alias targets are authored copies
111
+ # of tool-minted ids — mapped targets re-key as regenerable, not drift; a 2.x
112
+ # cross-family collision maps to several ids and the author qualifies, loudly).
113
+ # The event-twin basename join is deliberately unaffected (it joins on
114
+ # schema-file basename); traceability + availability manifests reference by
115
+ # path, verified; the coverage predicate joins re-key by construction. Map:
116
+ # new id = old id + '-' + kind, emitted by `sdd-cli catalogue migration-map`.
117
+ # CROSS-SDD references get their own cut-window re-key AT AGGREGATION (the
118
+ # first rehearsal probe measured 170 dangling FKs: per-SDD maps are empty in
119
+ # SDDs owning no contracts, so their edge rows kept old kindless ids):
120
+ # schema-driven over every contracts.id FK, dangling values re-key with the
121
+ # composite-id component (regenerable, not drift), same-fact duplicates dedup,
122
+ # cross-family-ambiguous ids stay dangling loudly.
123
+ # 5. The documentation restatement rides the cut (0203 §4.5): the M-ADR 0157 parity
124
+ # table's 31 rows restated as well-formed claims with profile + tier columns
125
+ # (M-ADR 0196 §4.2/§4.3/§5.3 — authoring direction deliberately NOT ratified as a
126
+ # third axis on one instance); and the F2 claim correction — capability_contract's
127
+ # documented reverse derivation (here and at two metamodel locations) measured
128
+ # nonexistent (0 derived rows / 105 units) and corrected as a CLAIM: the edge is
129
+ # forward-one-directional, the derivation is not built.
130
+ # Breaking; SCHEMA_COMPAT "^3.0.0"; ships as CLI 1.0.0 (a schema major is a CLI major).
68
131
  # Bump rationale (2.50.0 — additive minor, 2026-07-27): adds `service_capability_exemption`,
69
132
  # the services-tier annotation catalogue M-ADR 0133 §4.2b named as future work when
70
133
  # `repo_capability_exemption` shipped. One FK to `services.id`, declared never derived, closed
@@ -477,18 +540,15 @@ enums:
477
540
  that must be running for the system to work — an application or a
478
541
  data store.
479
542
 
480
- Staged enforcement: this enum is ADVISORY during the 2.x schema line.
481
- It is intentionally NOT bound via `c4_containers.column_enums` yet, so
482
- a non-canonical value does not fail the build. The legacy values
483
- `Infrastructure` and `External System` are recognised-but-deprecated:
484
- builders accept them and emit a `convention` finding (WARN) prompting
485
- migration. `External System` boxes belong in `c4_external_systems`
486
- (they are C4 L1 peer systems, not L2 containers); running
543
+ BOUND via `c4_containers.column_enums` since 3.0.0 (M-ADR 0203 §4.1,
544
+ completing 0155's staged enforcement): a non-member value hard-fails
545
+ build and validate. The 2.x-era legacy values are removed; their
546
+ migration rule (0155's own): `External System` boxes belong in
547
+ `c4_external_systems` (C4 L1 peer systems, not L2 containers); running
487
548
  infrastructure (broker, gateway, cache) retypes to Application or
488
549
  Data Store; pure deployment infrastructure (load balancer, DNS) leaves
489
550
  the container catalogue (it belongs in a C4 deployment diagram, which
490
- is not catalogued). The breaking removal of the legacy values and the
491
- column-enum binding land at the 3.0.0 major bump.
551
+ is not catalogued).
492
552
  values:
493
553
  - { value: Application, description: "A separately deployable/runnable application — a service, BFF, UI, consumer, worker, etc." }
494
554
  - { value: "Data Store", description: "A database or persistence layer (also covers running stores like a message broker when modelled as a container)." }
@@ -609,7 +669,6 @@ catalogues:
609
669
  - { name: profile, type: string, nullable: false, description: "platform-profile | application-product | integration-product | support-repo." }
610
670
  - { name: category, type: string, nullable: true, description: "Architectural classification per docs/method/methods/product-category-taxonomy.md. Values: platform-root | platform-subsystem | application-product | integration-provider | integration-umbrella | support-repo. Determines whether the Product gets a c4_systems row." }
611
671
  - { name: doc_path, type: string, nullable: false, description: "Path to _product/ directory, relative to docs/." }
612
- - { name: status, type: string, nullable: true, description: "⚠ DEPRECATED, inert, and scheduled for removal at 3.0.0 — do not consume it. Documented vocabulary is scaffolded | populated | reviewed; builders emit the constant 'active', which is not in that set, on 100% of rows (measured: 208 of 208 across two estates). Triaged in 2.47.0 and resolved as a DUPLICATION rather than a wiring gap: `status` and the synthesis_quality/synthesis_band/last_assessed triplet both express documentation maturity, and the triplet is strictly more expressive (0-10 score + band + assessment date) and is the one real data exists for. Wiring both would be two sources for one fact. So the triplet is wired (2.47.0) and this column is deprecated rather than repaired. Nothing consumes it — verified across the builders and the aggregator, where the same-named services.status is a different column. Removal is a breaking change and belongs with the 3.0.0 follow-on M-ADR 0155 already defers." }
613
672
  - { name: lifecycle, type: string, nullable: true, description: "planned | active | deprecated (default active when empty). Owner-declared product lifecycle from the SDD manifest's lifecycle: field (sdd-manifest-schema 1.1.0; `planned` added 1.9.0 / catalogue 2.47.0). `planned` = the product is real and intended but does not exist yet, which is the normal opening state of a forward-authored product — so a forward estate that has generated nothing should read `planned`, not the `active` the empty default implies. Distinct from status (documentation maturity): lifecycle is a fact about the PRODUCT, status about the DOCUMENT, and both can hold at once — a product can be reviewed AND deprecated, or planned AND thinly documented. Added in 2.22.0." }
614
673
  - { name: deprecated_date, type: date, nullable: true, description: "Date the deprecation decision took effect. Only meaningful when lifecycle=deprecated. From the manifest's deprecated_date:. Added in 2.22.0." }
615
674
  - { name: successor_sdd_id, type: string, nullable: true, description: "For deprecated products: sdd_id of the superseding SDD. Same vocabulary as sdd_id/source_sdd_id (NOT products.id). Soft reference — the aggregator orphan-checks it against contributing sdd_ids ([finding] orphan when unresolved), never a hard FK: the successor may live outside the aggregation scope. Added in 2.22.0." }
@@ -881,7 +940,7 @@ catalogues:
881
940
  - { column: service_id, references: services.id, nullable: true }
882
941
  - { column: source_repo_id, references: repositories.id, nullable: true }
883
942
  columns:
884
- - { name: id, type: string, nullable: false }
943
+ - { name: id, type: string, nullable: false, description: "{domain}-{stem}-{kind} — the kind component joined the id at schema 3.0.0 (M-ADR 0203 §4.4), ending the kindless collision class where one service published as two contract families (openapi + proto) minted one id (measured cost: 1 row + 2 edges permanently unrepresentable, plus legitimate shared-contract citation flagged as divergence). Mechanical migration: new id = old id + '-' + kind; `sdd-cli catalogue migration-map` emits the pairs, and authored alias targets (M-ADR 0147) re-key automatically during the cut window." }
885
944
  - { name: name, type: string, nullable: false, description: "Display name from info.title or artifact_id." }
886
945
  - { name: service_id, type: string, nullable: true, description: "Exposing service; resolved via primary_repo_id ↔ OpenAPI x-source-repo." }
887
946
  - { name: source_repo_id, type: string, nullable: true, description: "Repo owning the contract source. Distinct from exposing service's repo per M-ADR 0110 (sibling-repo pattern)." }
@@ -946,10 +1005,12 @@ catalogues:
946
1005
  - { name: system_id, type: string, nullable: false, description: "Owning C4 system (every container is in exactly one system)." }
947
1006
  - { name: domain_id, type: string, nullable: true, description: "Optional organisational domain tag (denormalised; not C4-structural)." }
948
1007
  - { name: service_id, type: string, nullable: true, description: "Matched by container name ↔ service name/repo where possible." }
949
- - { name: type, type: string, nullable: true, description: "Canonical C4 container kind — see enums.c4_container_type (Application | Data Store). Legacy values Infrastructure | External System are recognised-but-deprecated during 2.x (WARN); External System boxes belong in c4_external_systems. Per M-ADR 0155. Enum binding is advisory until 3.0.0." }
1008
+ - { name: type, type: string, nullable: true, description: "Canonical C4 container kind — bound to enums.c4_container_type (Application | Data Store) since 3.0.0, hard-fail (M-ADR 0203 §4.1 completing M-ADR 0155). The 2.x legacy values are removed: External System boxes belong in c4_external_systems; running infrastructure retypes; deployment infrastructure leaves the catalogue." }
950
1009
  - { name: technology, type: string, nullable: true }
951
1010
  - { name: description, type: string, nullable: true }
952
1011
  - { name: source_sdd_id, type: string, nullable: true, description: "Originating SDD slug. Populated by the aggregator per M-ADR 0134." }
1012
+ column_enums:
1013
+ type: enums.c4_container_type
953
1014
 
954
1015
  c4_components:
955
1016
  primary_key: id
@@ -984,11 +1045,11 @@ catalogues:
984
1045
  duplicate-PK rule); conflicting attributes on the same id surface as a
985
1046
  `convention` finding.
986
1047
  columns:
987
- - { name: id, type: string, nullable: false, description: "Bare slug, e.g. ext-google-maps." }
1048
+ - { name: id, type: string, nullable: false, description: "ext-{slug(diagram entry id)} — derived from the DECLARED identity (the first argument of System_Ext/Container_Ext), not from the display name, since 3.0.0 (M-ADR 0203 §4.2 completing M-ADR 0189 §4.2). The 2.x name-slug ids map to these mechanically; `sdd-cli catalogue migration-map` emits the old→new map, and authored exemption files keyed by a mapped old id re-key automatically during the cut window (regenerable, not drift)." }
988
1049
  - { name: name, type: string, nullable: false, description: "Display name from the System_Ext label." }
989
1050
  - { name: technology, type: string, nullable: true, description: "Optional stack/protocol hint." }
990
1051
  - { name: description, type: string, nullable: true, description: "What the external system provides." }
991
- - { name: declared_id, type: string, nullable: true, description: "The diagram entry id of the first-seen declaration (M-ADR 0189 §4.2) — the declared identity the aggregator resolves against estate identifiers at adjudication. Added 2.30.0." }
1052
+ - { name: declared_id, type: string, nullable: true, description: "The diagram entry id of the first-seen declaration (M-ADR 0189 §4.2) — the declared identity the aggregator resolves against estate identifiers at adjudication, and the source of the row id since 3.0.0. Added 2.30.0." }
992
1053
  - { name: source_scope, type: string, nullable: true, description: "Scope of the first-seen declaration: l1 (context diagram) or l2 (container diagram — scope-relative per M-ADR 0189 §4.1). Added 2.30.0." }
993
1054
  - { name: source_sdd_id, type: string, nullable: true, description: "Originating SDD slug. Populated by the aggregator per M-ADR 0134." }
994
1055
 
@@ -1281,7 +1342,7 @@ catalogues:
1281
1342
 
1282
1343
  capability_contract:
1283
1344
  primary_key: id
1284
- description: "Edge: capability exposes or depends on contract. Forward: declared in traceability.contracts. Reverse: derived via service_contract ⋈ capability_service."
1345
+ description: "Edge: capability exposes or depends on contract. Forward-declared only (traceability.contracts). The reverse derivation this description long claimed (service_contract ⋈ capability_service) was measured nonexistent — 0 `source: derived` rows across 105 units, builder references neither catalogue — and the CLAIM was corrected at 3.0.0 (M-ADR 0203 §4.5 / F2, gap class absent-derivation per M-ADR 0196 §4.1). The edge is forward-one-directional until a decision builds a reverse source."
1285
1346
  foreign_keys:
1286
1347
  - { column: capability_id, references: capabilities.id, nullable: false }
1287
1348
  - { column: contract_id, references: contracts.id, nullable: false }
@@ -1289,7 +1350,7 @@ catalogues:
1289
1350
  - { name: id, type: string, nullable: false }
1290
1351
  - { name: capability_id, type: string, nullable: false }
1291
1352
  - { name: contract_id, type: string, nullable: false }
1292
- - { name: source, type: string, nullable: false, description: "declared (forward) | derived (reverse)." }
1353
+ - { name: source, type: string, nullable: false, description: "declared — the only emitted value. `derived` is reserved vocabulary: the reverse derivation it anticipated was never built (0 rows across 105 measured units) and the claim was corrected at 3.0.0 (M-ADR 0203 §4.5 / F2); the value re-enters if a decision builds a reverse source." }
1293
1354
 
1294
1355
  journey_feature:
1295
1356
  primary_key: id
@@ -0,0 +1,11 @@
1
+ import type { CatalogueRow } from "./csv-writer.js";
2
+ /** The 3.0.0 contract id: the kindless slug with its kind appended. */
3
+ export declare function contractIdWithKind(kindlessSlug: string, kind: string): string;
4
+ /**
5
+ * legacy (2.x, kindless) id → the 3.0.0 kind-suffixed ids it maps to, from
6
+ * built rows. More than one target means the id was a measured collision
7
+ * under 2.x (two families sharing one kindless slug) — the consumer decides
8
+ * which family is meant, loudly, never by guess.
9
+ */
10
+ export declare function buildLegacyContractIdMap(rows: readonly CatalogueRow[]): Map<string, string[]>;
11
+ //# sourceMappingURL=contract-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-id.d.ts","sourceRoot":"","sources":["../../../src/lib/catalogue/contract-id.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,SAAS,YAAY,EAAE,GAC5B,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAiBvB"}
@@ -0,0 +1,49 @@
1
+ // Contract row identity (schema 3.0.0) and the legacy-id migration map —
2
+ // M-ADR 0203 §4.4, the cut's acid test.
3
+ //
4
+ // From 3.0.0 a contract id carries its KIND component: `{domain}-{stem}-{kind}`
5
+ // (kind ∈ rest | graphql | rpc | event | authz). The kindless 2.x form made one
6
+ // measured collision class unrepresentable: a service published as two contract
7
+ // families (`calendar-service.yaml` + `calendar_service.proto`) minted one id,
8
+ // costing a live estate one row and two edges permanently, and mislabelling
9
+ // legitimate shared-contract citation as divergence.
10
+ //
11
+ // The map is mechanical in both directions: new id = `${old id}-${kind}`, from
12
+ // two columns every committed catalogue carries (`id`, `kind`). It ships via
13
+ // `sdd-cli catalogue migration-map`; the alias-file re-key (M-ADR 0147 targets
14
+ // are authored copies of tool-minted ids — regenerable, not drift, the same
15
+ // rule as external_system_exemption) consults the in-build form of it.
16
+ /** The 3.0.0 contract id: the kindless slug with its kind appended. */
17
+ export function contractIdWithKind(kindlessSlug, kind) {
18
+ return kindlessSlug === "" ? "" : `${kindlessSlug}-${kind}`;
19
+ }
20
+ /**
21
+ * legacy (2.x, kindless) id → the 3.0.0 kind-suffixed ids it maps to, from
22
+ * built rows. More than one target means the id was a measured collision
23
+ * under 2.x (two families sharing one kindless slug) — the consumer decides
24
+ * which family is meant, loudly, never by guess.
25
+ */
26
+ export function buildLegacyContractIdMap(rows) {
27
+ const map = new Map();
28
+ for (const row of rows) {
29
+ const id = String(row["id"] ?? "");
30
+ const kind = String(row["kind"] ?? "");
31
+ if (id === "" || kind === "" || !id.endsWith(`-${kind}`))
32
+ continue;
33
+ const legacy = id.slice(0, -(kind.length + 1));
34
+ if (legacy === "")
35
+ continue;
36
+ const ids = map.get(legacy);
37
+ if (ids) {
38
+ if (!ids.includes(id))
39
+ ids.push(id);
40
+ }
41
+ else {
42
+ map.set(legacy, [id]);
43
+ }
44
+ }
45
+ for (const ids of map.values())
46
+ ids.sort((a, b) => a.localeCompare(b));
47
+ return map;
48
+ }
49
+ //# sourceMappingURL=contract-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-id.js","sourceRoot":"","sources":["../../../src/lib/catalogue/contract-id.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,wCAAwC;AACxC,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,qDAAqD;AACrD,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAC7E,+EAA+E;AAC/E,4EAA4E;AAC5E,uEAAuE;AAIvE,uEAAuE;AACvE,MAAM,UAAU,kBAAkB,CAAC,YAAoB,EAAE,IAAY;IACnE,OAAO,YAAY,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,IAAI,EAAE,CAAC;AAC9D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CACtC,IAA6B;IAE7B,MAAM,GAAG,GAAG,IAAI,GAAG,EAAoB,CAAC;IACxC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACvC,IAAI,EAAE,KAAK,EAAE,IAAI,IAAI,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC;YAAE,SAAS;QACnE,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAC/C,IAAI,MAAM,KAAK,EAAE;YAAE,SAAS;QAC5B,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,GAAG,EAAE,CAAC;YACR,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE;QAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { CatalogueRow } from "./csv-writer.js";
2
+ import type { FindingsLog } from "./findings.js";
3
+ import type { CanonicalSchema } from "./schema-loader.js";
4
+ export interface EnumViolation {
5
+ readonly catalogue: string;
6
+ readonly column: string;
7
+ readonly rowPk: string;
8
+ readonly value: string;
9
+ readonly allowed: string;
10
+ }
11
+ export interface EnumValidationResult {
12
+ readonly pass: boolean;
13
+ readonly violations: readonly EnumViolation[];
14
+ }
15
+ export declare function validateColumnEnums(schema: CanonicalSchema, rowsByCatalogue: ReadonlyMap<string, readonly CatalogueRow[]>, findings: FindingsLog): EnumValidationResult;
16
+ //# sourceMappingURL=enum-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enum-validator.d.ts","sourceRoot":"","sources":["../../../src/lib/catalogue/enum-validator.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,CAAC;CAC/C;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,eAAe,EACvB,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC,EAC7D,QAAQ,EAAE,WAAW,GACpB,oBAAoB,CAmCtB"}
@@ -0,0 +1,46 @@
1
+ // Schema-driven enum validation — the `column_enums` FAIL path (M-ADR 0203
2
+ // §4.1, completing M-ADR 0155 §4.3's staged enforcement).
3
+ //
4
+ // Every catalogue column bound via `column_enums` must hold either an empty
5
+ // cell or a value in the bound enum's declared set. A violation is an
6
+ // error-severity finding: it fails build/validate by default, exactly like
7
+ // a dangling internal FK. This is the enforcement the 2.x advisory module
8
+ // (`advisory-container-type.ts`, deleted at 3.0.0 per its own header) was
9
+ // standing in for — and unlike that module it is schema-driven, so binding
10
+ // a further enum is a schema edit, not new validator code.
11
+ //
12
+ // Emptiness is deliberately NOT this validator's concern: nullability is a
13
+ // column property with its own semantics, and every current builder derives
14
+ // bound columns structurally. Validating non-empty values keeps the check
15
+ // exactly as wide as the enum binding itself.
16
+ //
17
+ // reads: the in-memory rows of every schema catalogue carrying a
18
+ // `column_enums` block (no filesystem access of its own).
19
+ export function validateColumnEnums(schema, rowsByCatalogue, findings) {
20
+ const violations = [];
21
+ for (const cat of schema.catalogues) {
22
+ for (const [column, enumRef] of Object.entries(cat.columnEnums)) {
23
+ const enumName = enumRef.replace(/^enums\./, "");
24
+ const enumDef = schema.enums[enumName];
25
+ if (!enumDef) {
26
+ // A binding that names no enum is a schema defect, not a data
27
+ // defect — but it must not validate as vacuously true (a false
28
+ // coverage claim is worse than none, M-ADR 0200 §4.3).
29
+ findings.add("convention", `${cat.name}.${column}: column_enums references unknown enum "${enumRef}" — nothing to validate against`, "error");
30
+ continue;
31
+ }
32
+ const allowedSet = new Set(enumDef.values.map((v) => v.value));
33
+ const allowed = enumDef.values.map((v) => v.value).join(" | ");
34
+ for (const row of rowsByCatalogue.get(cat.name) ?? []) {
35
+ const value = String(row[column] ?? "").trim();
36
+ if (value === "" || allowedSet.has(value))
37
+ continue;
38
+ const rowPk = String(row[cat.primaryKey] ?? "<no-pk>");
39
+ violations.push({ catalogue: cat.name, column, rowPk, value, allowed });
40
+ findings.add("divergence", `${cat.name}.${column}: row ${rowPk} value "${value}" is outside the bound enum ${enumName} (${allowed})`, "error");
41
+ }
42
+ }
43
+ }
44
+ return { pass: violations.length === 0, violations };
45
+ }
46
+ //# sourceMappingURL=enum-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enum-validator.js","sourceRoot":"","sources":["../../../src/lib/catalogue/enum-validator.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,0DAA0D;AAC1D,EAAE;AACF,4EAA4E;AAC5E,sEAAsE;AACtE,2EAA2E;AAC3E,0EAA0E;AAC1E,0EAA0E;AAC1E,2EAA2E;AAC3E,2DAA2D;AAC3D,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,0EAA0E;AAC1E,8CAA8C;AAC9C,EAAE;AACF,iEAAiE;AACjE,0DAA0D;AAmB1D,MAAM,UAAU,mBAAmB,CACjC,MAAuB,EACvB,eAA6D,EAC7D,QAAqB;IAErB,MAAM,UAAU,GAAoB,EAAE,CAAC;IAEvC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACpC,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAChE,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YACjD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACvC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,8DAA8D;gBAC9D,+DAA+D;gBAC/D,uDAAuD;gBACvD,QAAQ,CAAC,GAAG,CACV,YAAY,EACZ,GAAG,GAAG,CAAC,IAAI,IAAI,MAAM,2CAA2C,OAAO,iCAAiC,EACxG,OAAO,CACR,CAAC;gBACF,SAAS;YACX,CAAC;YACD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YAC/D,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/D,KAAK,MAAM,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;gBACtD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC/C,IAAI,KAAK,KAAK,EAAE,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;oBAAE,SAAS;gBACpD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,SAAS,CAAC,CAAC;gBACvD,UAAU,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;gBACxE,QAAQ,CAAC,GAAG,CACV,YAAY,EACZ,GAAG,GAAG,CAAC,IAAI,IAAI,MAAM,SAAS,KAAK,WAAW,KAAK,+BAA+B,QAAQ,KAAK,OAAO,GAAG,EACzG,OAAO,CACR,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;AACvD,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { CatalogueRow } from "./csv-writer.js";
2
+ /**
3
+ * Normalise a declared diagram entry id to slug form. Camel humps split
4
+ * BEFORE lowercasing (the F11a rule, matching the aggregator's resolver):
5
+ * most SDD ids are hyphenated, and `bvfmGatewayFramework` must derive the
6
+ * same identity the adjudicator resolves for it (`bvfm-gateway-framework`).
7
+ */
8
+ export declare function normaliseEntryId(entryId: string): string;
9
+ /** The 3.0.0 row id for a declared diagram entry id, or "" when the entry id normalises to nothing. */
10
+ export declare function extIdFromEntryId(entryId: string): string;
11
+ /**
12
+ * The 2.x row id for a display name — the pre-3.0.0 derivation, kept
13
+ * VERBATIM (including the parenthetical strip) so the migration map
14
+ * reproduces exactly the ids the old builder minted.
15
+ */
16
+ export declare function legacyExtIdFromName(name: string): string;
17
+ /**
18
+ * legacy (2.x, name-derived) id → the 3.0.0 ids it maps to, from built
19
+ * rows. Usually one; MORE than one means two distinct declared identities
20
+ * shared a display-name slug and were wrongly merged as one row under 2.x
21
+ * — the map surfaces the split rather than guessing (the consumer decides,
22
+ * loudly).
23
+ */
24
+ export declare function buildLegacyExtIdMap(rows: readonly CatalogueRow[]): Map<string, string[]>;
25
+ //# sourceMappingURL=ext-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ext-id.d.ts","sourceRoot":"","sources":["../../../src/lib/catalogue/ext-id.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMxD;AAED,uGAAuG;AACvG,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGxD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOxD;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,SAAS,YAAY,EAAE,GAC5B,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAgBvB"}
@@ -0,0 +1,76 @@
1
+ // External-system row identity (schema 3.0.0) and the legacy-id migration
2
+ // map — M-ADR 0203 §4.2, completing M-ADR 0189 §4.2.
3
+ //
4
+ // From 3.0.0 a `c4_external_systems` row id derives from the DECLARED
5
+ // diagram entry id (`System_Ext(<entry-id>, …)`), not from a slug of the
6
+ // display name. The declared id is the identity the aggregator resolves
7
+ // (M-ADR 0189 §4.2); keying the row on anything else meant the row's own
8
+ // PK was label-keyed evidence — the exact identity class 0189 measured
9
+ // false-positiving at 14 of 15.
10
+ //
11
+ // The 2.x name-slug ids remain derivable from data every 2.30.0+ catalogue
12
+ // carries (`name`), so the old→new map is a build artefact, not an authored
13
+ // migration: `sdd-cli catalogue migration-map` emits it, and the exemption
14
+ // loader consults it during the cut window (an authored exemption keyed by
15
+ // a mapped old id is regenerable, NOT drift — the F30 rule at schema scale).
16
+ /**
17
+ * Normalise a declared diagram entry id to slug form. Camel humps split
18
+ * BEFORE lowercasing (the F11a rule, matching the aggregator's resolver):
19
+ * most SDD ids are hyphenated, and `bvfmGatewayFramework` must derive the
20
+ * same identity the adjudicator resolves for it (`bvfm-gateway-framework`).
21
+ */
22
+ export function normaliseEntryId(entryId) {
23
+ return entryId
24
+ .replace(/([a-z0-9])([A-Z])/g, "$1-$2")
25
+ .toLowerCase()
26
+ .replace(/[^a-z0-9]+/g, "-")
27
+ .replace(/^-+|-+$/g, "");
28
+ }
29
+ /** The 3.0.0 row id for a declared diagram entry id, or "" when the entry id normalises to nothing. */
30
+ export function extIdFromEntryId(entryId) {
31
+ const slug = normaliseEntryId(entryId);
32
+ return slug === "" ? "" : `ext-${slug}`;
33
+ }
34
+ /**
35
+ * The 2.x row id for a display name — the pre-3.0.0 derivation, kept
36
+ * VERBATIM (including the parenthetical strip) so the migration map
37
+ * reproduces exactly the ids the old builder minted.
38
+ */
39
+ export function legacyExtIdFromName(name) {
40
+ const slug = name
41
+ .toLowerCase()
42
+ .replace(/\s*\([^)]+\)/g, "")
43
+ .replace(/[^a-z0-9]+/g, "-")
44
+ .replace(/^-+|-+$/g, "");
45
+ return slug === "" ? "" : `ext-${slug}`;
46
+ }
47
+ /**
48
+ * legacy (2.x, name-derived) id → the 3.0.0 ids it maps to, from built
49
+ * rows. Usually one; MORE than one means two distinct declared identities
50
+ * shared a display-name slug and were wrongly merged as one row under 2.x
51
+ * — the map surfaces the split rather than guessing (the consumer decides,
52
+ * loudly).
53
+ */
54
+ export function buildLegacyExtIdMap(rows) {
55
+ const map = new Map();
56
+ for (const row of rows) {
57
+ const legacy = legacyExtIdFromName(String(row["name"] ?? ""));
58
+ if (legacy === "")
59
+ continue;
60
+ const current = String(row["id"] ?? "");
61
+ if (current === "" || legacy === current)
62
+ continue;
63
+ const ids = map.get(legacy);
64
+ if (ids) {
65
+ if (!ids.includes(current))
66
+ ids.push(current);
67
+ }
68
+ else {
69
+ map.set(legacy, [current]);
70
+ }
71
+ }
72
+ for (const ids of map.values())
73
+ ids.sort((a, b) => a.localeCompare(b));
74
+ return map;
75
+ }
76
+ //# sourceMappingURL=ext-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ext-id.js","sourceRoot":"","sources":["../../../src/lib/catalogue/ext-id.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,qDAAqD;AACrD,EAAE;AACF,sEAAsE;AACtE,yEAAyE;AACzE,wEAAwE;AACxE,yEAAyE;AACzE,uEAAuE;AACvE,gCAAgC;AAChC,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,2EAA2E;AAC3E,2EAA2E;AAC3E,6EAA6E;AAI7E;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,OAAO,OAAO;SACX,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED,uGAAuG;AACvG,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACvC,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,IAAI,GAAG,IAAI;SACd,WAAW,EAAE;SACb,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC;SAC5B,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC3B,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC;AAC1C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAA6B;IAE7B,MAAM,GAAG,GAAG,IAAI,GAAG,EAAoB,CAAC;IACxC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC9D,IAAI,MAAM,KAAK,EAAE;YAAE,SAAS;QAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACxC,IAAI,OAAO,KAAK,EAAE,IAAI,MAAM,KAAK,OAAO;YAAE,SAAS;QACnD,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,GAAG,EAAE,CAAC;YACR,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE;QAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -9,6 +9,7 @@ export { runCatalogueBuild } from "./build.js";
9
9
  export type { BuildInputs, BuildResult } from "./build.js";
10
10
  export { runCatalogueAggregate } from "./aggregate.js";
11
11
  export type { AggregateInputs, AggregateResult } from "./aggregate.js";
12
+ export { runCatalogueMigrationMap } from "./migration-map.js";
12
13
  export { runCatalogueValidate } from "./validate.js";
13
14
  export type { ValidateInputs, ValidateResult } from "./validate.js";
14
15
  export { runCatalogueVersion } from "./version.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/catalogue/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAChF,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,eAAe,EACf,YAAY,EACZ,SAAS,EACT,aAAa,EACb,OAAO,EACP,YAAY,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,UAAU,GACX,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACrE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/catalogue/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAChF,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,eAAe,EACf,YAAY,EACZ,SAAS,EACT,aAAa,EACb,OAAO,EACP,YAAY,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,UAAU,GACX,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACrE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
@@ -7,6 +7,7 @@
7
7
  */
8
8
  export { runCatalogueBuild } from "./build.js";
9
9
  export { runCatalogueAggregate } from "./aggregate.js";
10
+ export { runCatalogueMigrationMap } from "./migration-map.js";
10
11
  export { runCatalogueValidate } from "./validate.js";
11
12
  export { runCatalogueVersion } from "./version.js";
12
13
  export { SCHEMA_COMPAT, formatSchemaVersionMismatch } from "./schema-compat.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/catalogue/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAEhF,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAS5B,OAAO,EACL,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,UAAU,GACX,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAErE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/catalogue/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAEhF,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAS5B,OAAO,EACL,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,UAAU,GACX,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAErE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,27 @@
1
+ export interface MigrationMapInputs {
2
+ /** SDD repo root (defaults to cwd). */
3
+ readonly sddPath?: string;
4
+ }
5
+ export interface ExtIdMapEntry {
6
+ readonly oldId: string;
7
+ readonly newId: string;
8
+ readonly name: string;
9
+ }
10
+ export interface ContractIdMapEntry {
11
+ readonly oldId: string;
12
+ readonly newId: string;
13
+ readonly kind: string;
14
+ readonly specPath: string;
15
+ }
16
+ export interface MigrationMapResult {
17
+ readonly exitCode: number;
18
+ readonly extIdEntries: readonly ExtIdMapEntry[];
19
+ /** Rows whose new id could not be derived (no declared_id in a pre-2.30.0 catalogue). */
20
+ readonly underivable: readonly string[];
21
+ readonly contractEntries: readonly ContractIdMapEntry[];
22
+ /** Contract ids ALREADY ending in their -kind suffix — either an already-migrated 3.0.0 catalogue or a stem genuinely ending in the kind token; the reader decides from spec_path. */
23
+ readonly contractAmbiguous: readonly ContractIdMapEntry[];
24
+ }
25
+ export type Writer = (s: string) => void;
26
+ export declare function runCatalogueMigrationMap(inputs: MigrationMapInputs, write: Writer): Promise<MigrationMapResult>;
27
+ //# sourceMappingURL=migration-map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-map.d.ts","sourceRoot":"","sources":["../../../src/lib/catalogue/migration-map.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,kBAAkB;IACjC,uCAAuC;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,SAAS,aAAa,EAAE,CAAC;IAChD,yFAAyF;IACzF,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACxD,sLAAsL;IACtL,QAAQ,CAAC,iBAAiB,EAAE,SAAS,kBAAkB,EAAE,CAAC;CAC3D;AAED,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;AAEzC,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,kBAAkB,EAC1B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,kBAAkB,CAAC,CA8F7B"}
@@ -0,0 +1,114 @@
1
+ // `sdd-cli catalogue migration-map` — emit the 2.x → 3.0.0 id migration
2
+ // map from an existing catalogues/ directory (M-ADR 0203 §4.2, §4.4).
3
+ //
4
+ // The two 3.0.0 id migrations (external-system ids, contract ids) are
5
+ // mechanical functions of data every 2.30.0+ catalogue already carries, so
6
+ // the map is DERIVED, never authored: run this against a committed 2.x
7
+ // catalogue (before migrating) and the pairs come out. Downstream
8
+ // consumers: authored exemption + alias files (re-keyed automatically
9
+ // during the cut window), findings baselines (regenerate), external
10
+ // tooling (this output ships with the release notes), and the D3
11
+ // rehearsal's pre-stated figures, which derive from exactly this output.
12
+ //
13
+ // Count and list, always (M-ADR 0200 §4.3).
14
+ //
15
+ // reads: catalogues/c4_external_systems.csv, catalogues/contracts.csv
16
+ import { join, resolve } from "node:path";
17
+ import { readCatalogueCsv } from "./csv-reader.js";
18
+ import { contractIdWithKind } from "./contract-id.js";
19
+ import { extIdFromEntryId, legacyExtIdFromName } from "./ext-id.js";
20
+ export async function runCatalogueMigrationMap(inputs, write) {
21
+ const sddPath = resolve(inputs.sddPath ?? process.cwd());
22
+ const filePath = join(sddPath, "catalogues", "c4_external_systems.csv");
23
+ let parsed;
24
+ try {
25
+ parsed = await readCatalogueCsv(filePath);
26
+ }
27
+ catch (err) {
28
+ if (err.code === "ENOENT") {
29
+ throw new Error(`catalogues/c4_external_systems.csv not found under ${sddPath}\n` +
30
+ ` Run against an SDD repo with built catalogues (2.30.0+ carries declared_id).`);
31
+ }
32
+ throw err;
33
+ }
34
+ const entries = [];
35
+ const underivable = [];
36
+ for (const row of parsed.rows) {
37
+ const name = String(row["name"] ?? "");
38
+ const declaredId = String(row["declared_id"] ?? "").trim();
39
+ const oldId = legacyExtIdFromName(name);
40
+ if (declaredId === "") {
41
+ // Pre-2.30.0 row: the declared identity is not in the catalogue, only
42
+ // in the diagrams — a rebuild derives it. Reported, never guessed.
43
+ underivable.push(String(row["id"] ?? "<no-id>"));
44
+ continue;
45
+ }
46
+ const newId = extIdFromEntryId(declaredId);
47
+ if (oldId === "" || newId === "" || oldId === newId)
48
+ continue;
49
+ entries.push({ oldId, newId, name });
50
+ }
51
+ entries.sort((a, b) => a.oldId.localeCompare(b.oldId) || a.newId.localeCompare(b.newId));
52
+ write(`ext-id migration map (2.x name-slug → 3.0.0 declared-identity): ${entries.length} pair(s)\n`);
53
+ if (entries.length > 0) {
54
+ write(`old_id,new_id,name\n`);
55
+ for (const e of entries)
56
+ write(`${e.oldId},${e.newId},${csvCell(e.name)}\n`);
57
+ }
58
+ if (underivable.length > 0) {
59
+ write(`\nunderivable (${underivable.length}) — rows carry no declared_id (pre-2.30.0 catalogue); rebuild to derive identity from the diagrams:\n`);
60
+ for (const id of underivable)
61
+ write(` ${id}\n`);
62
+ }
63
+ // ── contract ids (M-ADR 0203 §4.4): new id = `${old id}-${kind}` ──
64
+ const contractsPath = join(sddPath, "catalogues", "contracts.csv");
65
+ const contractEntries = [];
66
+ const contractAmbiguous = [];
67
+ let contracts;
68
+ try {
69
+ contracts = await readCatalogueCsv(contractsPath);
70
+ }
71
+ catch (err) {
72
+ if (err.code !== "ENOENT")
73
+ throw err;
74
+ contracts = null;
75
+ }
76
+ if (contracts !== null) {
77
+ for (const row of contracts.rows) {
78
+ const id = String(row["id"] ?? "");
79
+ const kind = String(row["kind"] ?? "");
80
+ const specPath = String(row["spec_path"] ?? "");
81
+ if (id === "" || kind === "")
82
+ continue;
83
+ if (id.endsWith(`-${kind}`)) {
84
+ // Already kind-suffixed: an already-migrated 3.0.0 row, or a 2.x
85
+ // stem that genuinely ends in the kind token. Not decidable from
86
+ // the catalogue alone — listed, never guessed.
87
+ contractAmbiguous.push({ oldId: id, newId: contractIdWithKind(id, kind), kind, specPath });
88
+ continue;
89
+ }
90
+ contractEntries.push({ oldId: id, newId: contractIdWithKind(id, kind), kind, specPath });
91
+ }
92
+ contractEntries.sort((a, b) => a.oldId.localeCompare(b.oldId));
93
+ contractAmbiguous.sort((a, b) => a.oldId.localeCompare(b.oldId));
94
+ write(`\ncontract-id migration map (2.x kindless → 3.0.0 kind-suffixed): ${contractEntries.length} pair(s)\n`);
95
+ if (contractEntries.length > 0) {
96
+ write(`old_id,new_id,kind\n`);
97
+ for (const e of contractEntries)
98
+ write(`${e.oldId},${e.newId},${e.kind}\n`);
99
+ }
100
+ if (contractAmbiguous.length > 0) {
101
+ write(`\nalready kind-suffixed (${contractAmbiguous.length}) — either an already-migrated catalogue or a stem ending in the kind token; decide from spec_path:\n`);
102
+ for (const e of contractAmbiguous)
103
+ write(` ${e.oldId} (${e.kind}; ${e.specPath})\n`);
104
+ }
105
+ }
106
+ else {
107
+ write(`\ncatalogues/contracts.csv not found — contract-id map skipped\n`);
108
+ }
109
+ return { exitCode: 0, extIdEntries: entries, underivable, contractEntries, contractAmbiguous };
110
+ }
111
+ function csvCell(s) {
112
+ return /[",\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
113
+ }
114
+ //# sourceMappingURL=migration-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-map.js","sourceRoot":"","sources":["../../../src/lib/catalogue/migration-map.ts"],"names":[],"mappings":"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"}