@sdd-method/author-cli 0.0.0-stage → 0.1.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 (203) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +17 -0
  3. package/README.md +6 -2
  4. package/dist/author-bin.js +8 -0
  5. package/dist/author-program.js +99 -0
  6. package/dist/lib/adr-origin.js +59 -0
  7. package/dist/lib/agent-harness.js +37 -0
  8. package/dist/lib/api-surface/__fixtures__/serverless-repo/serverless/serverless.yml +18 -0
  9. package/dist/lib/api-surface/analyzers/library.js +95 -0
  10. package/dist/lib/api-surface/analyzers/serverless.js +336 -0
  11. package/dist/lib/api-surface/analyzers/spring.js +237 -0
  12. package/dist/lib/api-surface/analyzers/terraform.js +109 -0
  13. package/dist/lib/api-surface/detect.js +25 -0
  14. package/dist/lib/api-surface/emit.js +109 -0
  15. package/dist/lib/api-surface/file-set.js +43 -0
  16. package/dist/lib/api-surface/index.js +134 -0
  17. package/dist/lib/api-surface/types.js +17 -0
  18. package/dist/lib/briefing/index.js +13 -0
  19. package/dist/lib/briefing/render.js +132 -0
  20. package/dist/lib/briefing/variables.js +92 -0
  21. package/dist/lib/catalogue/application-archetype/vocabulary.js +177 -0
  22. package/dist/lib/catalogue/archetype/maps/android.yaml +66 -0
  23. package/dist/lib/catalogue/archetype/maps/swiftui.yaml +58 -0
  24. package/dist/lib/catalogue/archetype/maps/uikit.yaml +48 -0
  25. package/dist/lib/catalogue/archetype/maps/web-generic.yaml +86 -0
  26. package/dist/lib/catalogue/archetype/openui-archetype-vocabulary.yaml +46 -0
  27. package/dist/lib/catalogue/archetype/resolver.js +103 -0
  28. package/dist/lib/catalogue/archetype/wireframe.js +418 -0
  29. package/dist/lib/catalogue/baseline-check.js +151 -0
  30. package/dist/lib/catalogue/build.js +1502 -0
  31. package/dist/lib/catalogue/builders/adr-supersedes.js +103 -0
  32. package/dist/lib/catalogue/builders/adrs.js +222 -0
  33. package/dist/lib/catalogue/builders/application-conformance-coverage.js +47 -0
  34. package/dist/lib/catalogue/builders/application-data-plane-bindings.js +115 -0
  35. package/dist/lib/catalogue/builders/c4-components.js +229 -0
  36. package/dist/lib/catalogue/builders/c4-containers.js +240 -0
  37. package/dist/lib/catalogue/builders/c4-entity-rollups.js +87 -0
  38. package/dist/lib/catalogue/builders/c4-external-systems.js +194 -0
  39. package/dist/lib/catalogue/builders/c4-l1-candidates.js +107 -0
  40. package/dist/lib/catalogue/builders/c4-systems.js +98 -0
  41. package/dist/lib/catalogue/builders/capabilities.js +488 -0
  42. package/dist/lib/catalogue/builders/capability-domain-model.js +74 -0
  43. package/dist/lib/catalogue/builders/capability-edges.js +256 -0
  44. package/dist/lib/catalogue/builders/capability-spec-walker.js +99 -0
  45. package/dist/lib/catalogue/builders/capability-spec.js +348 -0
  46. package/dist/lib/catalogue/builders/container-dependency.js +183 -0
  47. package/dist/lib/catalogue/builders/contracts.js +402 -0
  48. package/dist/lib/catalogue/builders/data-items.js +344 -0
  49. package/dist/lib/catalogue/builders/data-store-mapping.js +113 -0
  50. package/dist/lib/catalogue/builders/domain-models.js +175 -0
  51. package/dist/lib/catalogue/builders/domains.js +119 -0
  52. package/dist/lib/catalogue/builders/edge-label-merge.js +19 -0
  53. package/dist/lib/catalogue/builders/entities-manifest.js +160 -0
  54. package/dist/lib/catalogue/builders/entities-mermaid.js +189 -0
  55. package/dist/lib/catalogue/builders/entity-persistence.js +102 -0
  56. package/dist/lib/catalogue/builders/entity-slug.js +47 -0
  57. package/dist/lib/catalogue/builders/event-catalog-walker.js +186 -0
  58. package/dist/lib/catalogue/builders/event-edges.js +327 -0
  59. package/dist/lib/catalogue/builders/events.js +168 -0
  60. package/dist/lib/catalogue/builders/evidence-class.js +43 -0
  61. package/dist/lib/catalogue/builders/evidence-target-repo.js +67 -0
  62. package/dist/lib/catalogue/builders/external-system-exemption.js +120 -0
  63. package/dist/lib/catalogue/builders/feature-contract.js +77 -0
  64. package/dist/lib/catalogue/builders/feature-domain-model.js +50 -0
  65. package/dist/lib/catalogue/builders/feature-grounding-walker.js +254 -0
  66. package/dist/lib/catalogue/builders/feature-grounding.js +391 -0
  67. package/dist/lib/catalogue/builders/feature-groups.js +63 -0
  68. package/dist/lib/catalogue/builders/feature-subscription-channels.js +228 -0
  69. package/dist/lib/catalogue/builders/feature-tree-walker.js +295 -0
  70. package/dist/lib/catalogue/builders/features.js +300 -0
  71. package/dist/lib/catalogue/builders/glossary-xref.js +378 -0
  72. package/dist/lib/catalogue/builders/glossary.js +204 -0
  73. package/dist/lib/catalogue/builders/implementations.js +214 -0
  74. package/dist/lib/catalogue/builders/index.js +64 -0
  75. package/dist/lib/catalogue/builders/integration-components.js +344 -0
  76. package/dist/lib/catalogue/builders/integrations.js +181 -0
  77. package/dist/lib/catalogue/builders/persona-c4system.js +149 -0
  78. package/dist/lib/catalogue/builders/persona-container.js +133 -0
  79. package/dist/lib/catalogue/builders/persona-journey-edges.js +133 -0
  80. package/dist/lib/catalogue/builders/personas.js +152 -0
  81. package/dist/lib/catalogue/builders/product-edges.js +106 -0
  82. package/dist/lib/catalogue/builders/product-platform-dependencies.js +405 -0
  83. package/dist/lib/catalogue/builders/products.js +162 -0
  84. package/dist/lib/catalogue/builders/quality-scores.js +635 -0
  85. package/dist/lib/catalogue/builders/repo-capability-exemption.js +61 -0
  86. package/dist/lib/catalogue/builders/repo-dependency.js +127 -0
  87. package/dist/lib/catalogue/builders/repo-edges.js +340 -0
  88. package/dist/lib/catalogue/builders/repositories.js +458 -0
  89. package/dist/lib/catalogue/builders/scaffolds.js +197 -0
  90. package/dist/lib/catalogue/builders/screen-tree.js +222 -0
  91. package/dist/lib/catalogue/builders/screens.js +396 -0
  92. package/dist/lib/catalogue/builders/service-capability-exemption.js +63 -0
  93. package/dist/lib/catalogue/builders/service-contract-consumes.js +186 -0
  94. package/dist/lib/catalogue/builders/service-contract.js +74 -0
  95. package/dist/lib/catalogue/builders/service-entity-tables.js +187 -0
  96. package/dist/lib/catalogue/builders/services.js +232 -0
  97. package/dist/lib/catalogue/builders/system-external-dependency.js +115 -0
  98. package/dist/lib/catalogue/builders/user-journeys.js +253 -0
  99. package/dist/lib/catalogue/canonical-schema.yaml +4117 -0
  100. package/dist/lib/catalogue/cli-version.js +10 -0
  101. package/dist/lib/catalogue/contract-id.js +49 -0
  102. package/dist/lib/catalogue/coverage-predicates.js +603 -0
  103. package/dist/lib/catalogue/coverage-render.js +552 -0
  104. package/dist/lib/catalogue/coverage-run.js +115 -0
  105. package/dist/lib/catalogue/csv-reader.js +97 -0
  106. package/dist/lib/catalogue/csv-writer.js +96 -0
  107. package/dist/lib/catalogue/data-plane-coherence.js +77 -0
  108. package/dist/lib/catalogue/ddl-generator.js +233 -0
  109. package/dist/lib/catalogue/dedupe-keyed-tables.js +0 -0
  110. package/dist/lib/catalogue/engine-validator.js +239 -0
  111. package/dist/lib/catalogue/ext-id.js +76 -0
  112. package/dist/lib/catalogue/feature-grounding-aliases-loader.js +65 -0
  113. package/dist/lib/catalogue/feature-repo-zero-resolution-summary.js +31 -0
  114. package/dist/lib/catalogue/finding-identity.js +183 -0
  115. package/dist/lib/catalogue/findings.js +46 -0
  116. package/dist/lib/catalogue/fk-validator.js +136 -0
  117. package/dist/lib/catalogue/freshness.js +70 -0
  118. package/dist/lib/catalogue/gate-checks.js +338 -0
  119. package/dist/lib/catalogue/graph-projection.js +346 -0
  120. package/dist/lib/catalogue/impact-run.js +228 -0
  121. package/dist/lib/catalogue/manifest-loader.js +435 -0
  122. package/dist/lib/catalogue/platform-scope.js +7 -0
  123. package/dist/lib/catalogue/population-checks.js +87 -0
  124. package/dist/lib/catalogue/relationship-semantics.js +66 -0
  125. package/dist/lib/catalogue/reverse-product-quality.js +99 -0
  126. package/dist/lib/catalogue/rubric-coverage-map.yaml +871 -0
  127. package/dist/lib/catalogue/runway-vocabulary-loader.js +56 -0
  128. package/dist/lib/catalogue/scaffold-delta.js +261 -0
  129. package/dist/lib/catalogue/schema-compat.js +52 -0
  130. package/dist/lib/catalogue/schema-loader.js +87 -0
  131. package/dist/lib/catalogue/scores-coverage.js +573 -0
  132. package/dist/lib/catalogue/screen-validation-loader.js +89 -0
  133. package/dist/lib/catalogue/service-architecture-parser.js +193 -0
  134. package/dist/lib/catalogue/service-contract-aliases-loader.js +109 -0
  135. package/dist/lib/catalogue/staleness-verdicts.js +345 -0
  136. package/dist/lib/catalogue/traceability-loader.js +350 -0
  137. package/dist/lib/catalogue/validate.js +200 -0
  138. package/dist/lib/catalogue/version.js +18 -0
  139. package/dist/lib/conformance/binding.js +70 -0
  140. package/dist/lib/conformance/finding.js +69 -0
  141. package/dist/lib/conformance/index.js +578 -0
  142. package/dist/lib/context-pull/index.js +191 -0
  143. package/dist/lib/context-pull/resolve.js +70 -0
  144. package/dist/lib/context-pull/retired-mcp-setup.js +7 -0
  145. package/dist/lib/contracts-availability/index.js +267 -0
  146. package/dist/lib/generate-briefing/index.js +77 -0
  147. package/dist/lib/list/discover.js +100 -0
  148. package/dist/lib/list/format.js +84 -0
  149. package/dist/lib/list/index.js +16 -0
  150. package/dist/lib/lock-file.js +437 -0
  151. package/dist/lib/pack/log.js +18 -0
  152. package/dist/lib/pack/schema.js +121 -0
  153. package/dist/lib/pack/seed.js +182 -0
  154. package/dist/lib/pack/validate.js +49 -0
  155. package/dist/lib/package-version.js +92 -0
  156. package/dist/lib/plan/index.js +69 -0
  157. package/dist/lib/plan/read-sdd.js +102 -0
  158. package/dist/lib/plan/render-template.js +84 -0
  159. package/dist/lib/repo-kind.js +129 -0
  160. package/dist/lib/scaffold/domain.js +234 -0
  161. package/dist/lib/scaffold/registry.js +136 -0
  162. package/dist/lib/scripts.js +7 -0
  163. package/dist/lib/sdd-index/repo-config.js +245 -0
  164. package/dist/lib/sdd-reader.js +91 -0
  165. package/dist/lib/snapshot/advance.js +454 -0
  166. package/dist/lib/snapshot/diff.js +190 -0
  167. package/dist/lib/snapshot/fold.js +208 -0
  168. package/dist/lib/snapshot/land.js +178 -0
  169. package/dist/lib/snapshot/manifest.js +206 -0
  170. package/dist/lib/snapshot/targets.js +169 -0
  171. package/dist/lib/snapshot/verify.js +91 -0
  172. package/dist/lib/sync/briefing-merge.js +106 -0
  173. package/dist/lib/sync/bundle-cache.js +109 -0
  174. package/dist/lib/sync/yaml-block-merge.js +120 -0
  175. package/dist/lib/validate/aggregate.js +51 -0
  176. package/dist/lib/validate/bundle-coherence.js +74 -0
  177. package/dist/lib/validate/dispatch.js +243 -0
  178. package/dist/lib/validate/index.js +110 -0
  179. package/dist/lib/validate/plan.js +54 -0
  180. package/dist/lib/validate/runner.js +85 -0
  181. package/dist/lib/validate/yaml-parse.js +112 -0
  182. package/dist/maintain-version.json +4 -0
  183. package/dist/verbs/api-surface.js +71 -0
  184. package/dist/verbs/catalogue-check.js +28 -0
  185. package/dist/verbs/catalogue-verify.js +114 -0
  186. package/dist/verbs/conformance.js +34 -0
  187. package/dist/verbs/context.js +39 -0
  188. package/dist/verbs/contracts.js +34 -0
  189. package/dist/verbs/generate-briefing.js +29 -0
  190. package/dist/verbs/list.js +45 -0
  191. package/dist/verbs/pack-validate.js +17 -0
  192. package/dist/verbs/path-option.js +25 -0
  193. package/dist/verbs/plan.js +42 -0
  194. package/dist/verbs/render.js +87 -0
  195. package/dist/verbs/scaffold.js +83 -0
  196. package/dist/verbs/snapshot.js +134 -0
  197. package/dist/verbs/validate.js +48 -0
  198. package/dist/verify-program.js +122 -0
  199. package/dist/verify-version.json +4 -0
  200. package/package.json +32 -4
  201. package/scripts/validate-app-dependencies.sh +664 -0
  202. package/scripts/validate-app-docs.sh +199 -0
  203. package/scripts/validate-integration-docs.sh +505 -0
@@ -0,0 +1,4117 @@
1
+ # GENERATED — DO NOT EDIT. This file is a projection of the authored model (M-ADR 0210 §4.6, flip 1):
2
+ # docs/method/foundations/schemas/catalogue-schema.tql (the type system; header carries the bump log)
3
+ # docs/method/foundations/schemas/catalogue-schema-meta.tql (what a type system cannot say)
4
+ # Regenerate: sdd-cli metamodel roundtrip --write
5
+ # Guard: sdd-cli metamodel roundtrip (any difference fails the build)
6
+ # Direction of truth: authored .tql -> this projection (round-trip gate) -> vendored copies (digest hook).
7
+ # Emitted by sdd-cli's YAML emitter with no line folding; the three header scalars are quoted for the
8
+ # textual readers downstream. The one deliberate difference from the authored form is schema_status:
9
+ # the authored form says canonical; a projection never does.
10
+ schema_version: "3.20.0"
11
+ schema_owner: "sdd-method"
12
+ schema_status: "generated"
13
+ enums:
14
+ quality_gate:
15
+ values:
16
+ - value: pass
17
+ description: Meets the rubric's pass threshold with no hard gate triggered.
18
+ - value: pass-with-waiver
19
+ description: A pass granted despite a known dimension shortfall, with the waiver RECORDED (granted_by + expires; see the scoring-registry guide). Passing for gate purposes, flagged for review purposes; an expired waiver reads as conditional. Adopted 2026-08-07, generalising the domain-architecture rubric's waiver machinery.
20
+ - value: conditional
21
+ description: Below threshold or carrying flags — remediation required, not a failure.
22
+ - value: fail
23
+ description: Below the fail threshold, or a hard gate triggered.
24
+ - value: unscored
25
+ description: "The entry exists but carries no assessment. Distinct from absent: an unscored row asserts that nothing has been judged, which is exactly the silence M-ADR 0205 §4.5's coverage instrument exists to make loud."
26
+ description: |
27
+ Gate verdict a rubric assessment records for a target, in `quality_scores.gate` (per M-ADR 0205 §4.5). The vocabulary all fifteen method-side gate registries declare.
28
+ DELIBERATELY NOT BOUND via `column_enums`, and the reason is measured rather than assumed — do not "fix" this by binding it. These values come from hand-authored score registries written by scoring runs, not from a method-mandated authoring surface, and one estate's `domain-architecture-scores.yaml` declared `pass-with-waiver` before the method did, and uses it — the extension was RULED INTO this vocabulary (2026-08-07); the next estate extension would meet the same choice, and binding would hard-fail a build over a deliberate, self-documented row. This follows the `products.synthesis_band` precedent — the other column fed from a rubric registry — where an out-of-vocabulary value is reported as a convention finding and the cell left EMPTY, rather than emitting a value no consumer can interpret. The builder names the file, the entry, the value and the remedy, which is better diagnosis than a generic enum violation could give. Contrast `service_type`, which IS bound: it comes from repo-config, an authoring surface the method mandates.
29
+ score_selection_method:
30
+ values:
31
+ - value: latest
32
+ description: Most recent review by scored_at. The default and, at 2026-08-06, the only value in use across either estate.
33
+ - value: human-selected
34
+ description: A human chose the effective review over the automatic pick.
35
+ - value: consensus
36
+ description: Effective score reconciled across several reviews.
37
+ - value: highest-severity
38
+ description: The most severe review wins — the conservative policy for gate-blocking rubrics.
39
+ description: |
40
+ How the effective review was chosen from a target's review history, in `quality_scores.selection_method` — the `selection_policy.method` field every gate registry carries. The catalogue models only the EFFECTIVE score (one row per target/rubric); this column makes the row say WHICH review it is rather than implying there was only one. Not bound, for the same registry-authored reason as `quality_gate`.
41
+ staleness_basis:
42
+ values:
43
+ - value: corpus_ref
44
+ description: The row carries the commit the assessment read — the precise anchor. Authored; introduced by the M-ADR 0205 §4.5 change-set, so absent from every score written before it.
45
+ - value: scored_at
46
+ description: No corpus_ref; staleness computed from the assessment date against the target's last content change, resolved through target_path. Correct but coarser — it cannot distinguish a re-commit that changed nothing from a real edit.
47
+ - value: none
48
+ description: Neither anchor available (no corpus_ref and no resolvable target_path). Staleness is UNKNOWN for this row and must be reported as unknown, never as fresh.
49
+ description: |
50
+ Which anchor a `quality_scores` row's staleness verdict can be computed from, in `quality_scores.staleness_basis`. This column exists because a staleness verdict whose basis is unstated is not a measurement — the basis-error class that produced six wrong figures in a single day of this method's own arc. The coverage predicate MUST NOT be able to emit a staleness claim without naming which of these it used.
51
+ scoring_form:
52
+ values:
53
+ - value: weighted
54
+ description: Weighted 1-5 dimensions rolled into a weighted_score against a pass threshold, with flags and hard gates. The forward house form; all fifteen method-side registries use it.
55
+ - value: banded
56
+ description: Dimensions summed to an integer total and mapped to a named band. The reverse family's form. Added in 3.3.0. The band vocabulary is PER-RUBRIC and deliberately unbound — see the band column.
57
+ description: |
58
+ The scoring shape a rubric uses, in `quality_scores.scoring_form`. Reserved by M-ADR 0205 §4.5 so the banded reverse family can arrive additively without reshaping rows.
59
+ Both forms are now declared. `banded` was added in 3.3.0 once the reverse family was modelled; before that it was deliberately absent so a premature banded row would fail loudly rather than pass against an unemitted value.
60
+ The two forms are NOT interchangeable and must not be averaged together — which is why they never share a score column. A weighted row carries `weighted_score` (1-5) and leaves `band`/`band_total` empty; a banded row carries `band` + `band_total` and leaves `weighted_score` empty. Any aggregate over `weighted_score` is therefore correct by construction rather than by the caller remembering to filter.
61
+ capability_service_role:
62
+ values:
63
+ - value: primary
64
+ description: Realises this capability.
65
+ - value: related
66
+ description: Participates in delivering this capability without being its primary realiser. Contributes; kept in repo_capability.
67
+ - value: dependency
68
+ description: This capability DEPENDS ON the service — the inverse direction of contribution. The relationship is real and catalogued here; it does NOT produce a repo_capability row.
69
+ - value: backend-gateway
70
+ description: Owned by ANOTHER domain and the sanctioned entry point into that domain's data for this capability — not merely a dependency, the door in. Expect it on cross-domain rows only. Contributes; kept in repo_capability.
71
+ description: |
72
+ The part a service plays in delivering ONE capability. A property of the capability↔service RELATIONSHIP, never of the service: the same service is legitimately `primary` for capabilities in its own domain and `backend-gateway` for capabilities elsewhere. Authored in the capability traceability manifest services[].role (see the capability-traceability-manifest-template). Bound in 3.8.0; the values and their meanings are the template's, unchanged. Consumers deriving "which repos realise this capability" MUST read this column or use repo_capability, which excludes `dependency` (M-ADR 0157 §4.3 as amended) — a repo_capability row is a contribution claim.
73
+ c4_system_kind:
74
+ values:
75
+ - value: platform
76
+ description: A platform-root system — the one system that identifies a platform (M-ADR 0208 §4.1; 'platform-ecosystem' is the long form, 1:1 with the root). Exactly one per PLATFORM; an organisation-tier aggregate legitimately carries one per constituent platform, keyed by platform_sdd_id (0208 §4.2). An invariant `subsystem` exists to protect — do not reuse `platform` for subsystem rows.
77
+ - value: subsystem
78
+ description: A promoted platform subsystem (M-ADR 0170 §4.2) — a separate deployable that is a peer System in the platform model, contained by the platform root on the same footing as application and integration (M-ADR 0208 §4.1). Added 2.28.0 per M-ADR 0133 §4.2c.
79
+ - value: application
80
+ description: An application-product system, consumes platform services and contracts.
81
+ - value: integration
82
+ description: An integration-provider system, bridges an external provider into the platform.
83
+ description: |
84
+ Architectural kind of a C4 system. Derived 1:1 from the originating SDD manifest's category — every architectural product (the only ones that get a c4_systems row) maps to exactly one of these four kinds. Non-architectural categories (integration-umbrella, support-repo) emit no c4_systems row — and the builder MUST say so with a coverage finding, never silently (M-ADR 0133 §4.2c). Mapping table:
85
+ platform-root → platform
86
+ platform-subsystem → subsystem
87
+ application-product → application
88
+ integration-provider → integration
89
+ c4_container_type:
90
+ values:
91
+ - value: Application
92
+ description: A separately deployable/runnable application — a service, BFF, UI, consumer, worker, etc.
93
+ - value: Data Store
94
+ description: A database or persistence layer (also covers running stores like a message broker when modelled as a container).
95
+ description: |
96
+ Canonical C4 container kind for `c4_containers.type`, aligned with c4model.com/abstractions (per M-ADR 0155). A C4 container is something that must be running for the system to work — an application or a data store.
97
+ BOUND via `c4_containers.column_enums` since 3.0.0 (M-ADR 0203 §4.1, completing 0155's staged enforcement): a non-member value hard-fails build and validate. The 2.x-era legacy values are removed; their migration rule (0155's own): `External System` boxes belong in `c4_external_systems` (C4 L1 peer systems, not L2 containers); running infrastructure (broker, gateway, cache) retypes to Application or Data Store; pure deployment infrastructure (load balancer, DNS) leaves the container catalogue (it belongs in a C4 deployment diagram, which is not catalogued).
98
+ service_type:
99
+ values:
100
+ - value: api_service
101
+ description: REST/GraphQL/RPC service exposing an API.
102
+ runtime: true
103
+ emits_service_row: true
104
+ - value: worker
105
+ description: Background event/queue processor.
106
+ runtime: true
107
+ emits_service_row: true
108
+ - value: gateway
109
+ description: Edge or API gateway (Zuplo, Apigee, etc.).
110
+ runtime: true
111
+ emits_service_row: true
112
+ - value: frontend
113
+ description: Web UI deployable (Vue, React, Svelte, etc.). Includes vertical-domain application frontends — the SDD profile distinguishes platform-frontends from app-frontends.
114
+ runtime: true
115
+ emits_service_row: true
116
+ - value: mobile
117
+ description: Mobile app deployable (iOS, Android).
118
+ runtime: true
119
+ emits_service_row: true
120
+ - value: library
121
+ description: Shared package shipped to consumers (npm, PyPI, Maven, etc.).
122
+ runtime: false
123
+ emits_service_row: false
124
+ - value: infrastructure
125
+ description: IaC, CI/CD, build tooling — not a runtime deployable.
126
+ runtime: false
127
+ emits_service_row: false
128
+ - value: documentation
129
+ description: Docs-only repo.
130
+ runtime: false
131
+ emits_service_row: false
132
+ - value: firmware
133
+ description: "Firmware that runs on a device: the application image, bootloader, loader, on-device plug-ins (M-ADR 0215). Runtime, but emits no service row — a device is not a node in the platform's service graph. Its tooling, test benches and libraries keep their own kinds."
134
+ runtime: true
135
+ emits_service_row: false
136
+ description: |
137
+ Type of repository, declared in `orchestration/repo-config/*.yaml` as `service_type` and surfaced in `repositories.component_type` and `services.component_type`. The canonical builder uses this to decide which repos are runtime services (api_service, worker, gateway, frontend, mobile) and which are non-runtime (library, infrastructure, documentation); firmware runs, but on a device, so it is runtime without a service row (M-ADR 0215) — service emission follows emits_service_row, not runtime. Whether a repo is a vertical-domain application is conveyed by its SDD manifest's `profile: application-product`, not by a service_type tag — this enum is strictly about runtime artefact shape (per resolution of adopt-canonical-catalogue-builder.md §7.1).
138
+ capability_exemption_reason:
139
+ values:
140
+ - value: infrastructure
141
+ description: Provisions or operates the estate; realises no product capability.
142
+ - value: build-tooling
143
+ description: Build, release, CI or repository-management machinery.
144
+ - value: test-scaffolding
145
+ description: Test helpers and fixtures with no runtime role.
146
+ - value: vendored
147
+ description: Third-party or forked code the SDD does not model.
148
+ - value: prototype
149
+ description: Exploratory; not part of the product model.
150
+ - value: archived
151
+ description: Retained for reference; no longer live.
152
+ description: |
153
+ Why a catalogued repository deliberately bears no capability, per M-ADR 0188 §4.2. Closed vocabulary: reason codes make exemptions countable and trendable (a growing `prototype` or `archived` population is itself an estate signal), where free text would bury them. Extensions are method-owned and proceed by ADR amendment, so that adopters cannot locally widen the exemption surface to silence findings.
154
+ ENFORCED, not advisory. The builder drops a `repo_capability_exemption` row whose reason is outside this vocabulary and emits a `convention` finding. The repository then resolves to nothing and is reported as an orphan — which is the point. If an unrecognised reason still exempted the repo, `reason: whatever` would be a universal silencer.
155
+ service_capability_exemption_reason:
156
+ values:
157
+ - value: platform-internal
158
+ description: Runs, but serves the platform's own operation rather than a product capability (e.g. an internal control-plane or ops service).
159
+ - value: deprecated
160
+ description: No longer live; retained for reference or wind-down.
161
+ description: |
162
+ Why a catalogued service deliberately bears no capability, per M-ADR 0133 §4.2b. Closed vocabulary — narrower than `capability_exemption_reason` by design: a repository can be exempt for six reasons (packaging, tooling, provenance), but a SERVICE, by definition, already runs something — the repository-tier distinctions that don't reproduce at the service tier (pure IaC, build tooling, test scaffolding, vendored code) fold into `platform-internal`, since a service that exists at all is doing platform-internal work if it isn't product-facing.
163
+ ENFORCED, not advisory. The builder drops a `service_capability_exemption` row whose reason is outside this vocabulary and emits a `convention` finding. The service then resolves to nothing and is reported per the coverage predicate's tier-scoped verdict set — which is the point.
164
+ external_system_exemption_reason:
165
+ values:
166
+ - value: third-party-saas
167
+ description: An operated vendor service the estate consumes (billing, auth, maps, email…).
168
+ - value: partner-system
169
+ description: Another organisation's system integrated across an agreed boundary.
170
+ - value: customer-system
171
+ description: A customer-owned system the estate serves or consumes.
172
+ - value: device-hardware
173
+ description: Physical devices or device fleets at the estate boundary.
174
+ - value: public-infrastructure
175
+ description: Public networks, registries, or services no party in the estate operates.
176
+ - value: estate-owned-unmodelled
177
+ description: "Operated by this estate but with no SDD or container home yet — the row is an accounted-for stand-in, and this population is the estate's modelling backlog, countable (F16, 2.32.0). Not an assertion of externality: an assertion of accountability for a boundary row."
178
+ - value: organisation-internal
179
+ description: Owned elsewhere in the same organisation, outside this estate's modelling boundary (F16, 2.32.0).
180
+ description: |
181
+ Why an external-system candidate is ACCOUNTED FOR at the estate boundary, per M-ADR 0189 §4.6 (WS15; wording corrected by F16, 2.32.0): five values assert another party owns the system, and two assert the estate/organisation owns it but it has no model home yet — forcing the latter through the former would demand a false reason, and a false reason is worse than silence. The adjudicator can prove a candidate internal; it cannot prove one accounted-for — that is an assertion the author is accountable for, in the shape M-ADR 0188 ratified for repositories. Closed vocabulary, method-owned, extended only by ADR amendment, so adopters cannot locally widen the exemption surface to silence the unverified-candidate coverage finding.
182
+ ENFORCED, not advisory: the builder drops a row whose reason is outside this vocabulary (convention finding) and the candidate stays unverified — which is the point. An unrecognised reason must not succeed at the one thing an exemption does.
183
+ scaffold_status:
184
+ values:
185
+ - value: open
186
+ description: The unit of work is in flight. `declared` items are a state, not a defect (M-ADR 0207 §4.2).
187
+ - value: closed
188
+ description: The author has recorded the unit of work as done. A `declared` item under a closed scaffold presumes the scaffold right — the work is incomplete — and is reported (M-ADR 0207 §4.3).
189
+ description: |
190
+ Lifecycle of a scaffold declaration, in `scaffolds.status`. AUTHORED in the manifest, copied by the builder: closing a scaffold is a recorded act of the unit of work finishing (M-ADR 0207 §4.3), not a computed consequence — the delta instrument reports a closed scaffold whose delta is not zero as a finding, it never closes one itself.
191
+ scaffold_item_kind:
192
+ values:
193
+ - value: entity
194
+ description: A node catalogue row the work will add (a service, capability, feature, screen, …). target_ref is the declared id in that catalogue's vocabulary.
195
+ - value: edge
196
+ description: An edge catalogue row the work will add. Endpoints are declared in edge_source_ref/edge_target_ref, mapped to the edge catalogue's FK columns in schema declaration order.
197
+ - value: contract
198
+ description: A contract artefact the work will introduce or amend. target_ref is the repo-relative spec path, matching `contracts.spec_path`.
199
+ description: |
200
+ The grain of a scaffold declaration item, in `scaffold_items.item_kind`. Declares which family of catalogue surface the item promises; `target_kind` names the specific catalogue.
201
+ scaffold_item_state:
202
+ values:
203
+ - value: declared
204
+ description: The target does not (yet) resolve in the built catalogues. Under an open scaffold this is the computable backlog; under a closed one it is a reported finding (M-ADR 0207 §4.2/§4.3).
205
+ - value: realised
206
+ description: The target resolves in the built catalogues. The declaration is met for this item.
207
+ description: |
208
+ Realisation state of a scaffold item, in `scaffold_items.state`. DERIVED by the builder's resolution pass against the same build's catalogue rows — never authored. The manifest declares intent; this column records whether the intent is realised in the corpus the build read. Staleness is deliberately NOT a value here: it is a coverage-time verdict against `scaffolds.corpus_ref` (M-ADR 0207 §4.6), because a git-derived value in a derived row would break rebuild determinism against unchanged authored inputs.
209
+ interaction_pattern:
210
+ values:
211
+ - value: event-stream-consume
212
+ description: Subscribe to and drain a broker / stream / feed the provider produces; the consumer drains a durable, ordered channel (Event-Driven / Polling Consumer over a Message Channel).
213
+ - value: webhook
214
+ description: Expose an endpoint the other side pushes events to as they occur (Event-Driven Consumer, HTTP push).
215
+ - value: socket-listen
216
+ description: Accept connection-oriented sessions the source initiates and read framed data (Channel Adapter, transport listener).
217
+ - value: poll
218
+ description: Periodically request current or incremental state from the source (Polling Consumer).
219
+ - value: request-response
220
+ description: Synchronous call-and-wait; the result returns in the same exchange (Request-Reply, synchronous).
221
+ - value: async-request
222
+ description: Submit a request; the result returns later via a separate channel, correlated by identifier (Request-Reply, asynchronous + Correlation Identifier).
223
+ - value: publish
224
+ description: Fire-and-forget write to a broker / queue / endpoint with no awaited response (Publish-Subscribe / fire-and-forget Message).
225
+ description: "How a capability's declared dependency on a service is coupled at RUNTIME — M-ADR 0171's closed interaction-pattern vocabulary (the union of its ingestion and invocation sets), reused on `capability_service.interaction_pattern` per M-ADR 0211 §4.1 and not widened. BOUND because the value comes from the traceability manifest, a method-mandated authoring surface (M-ADR 0210 §4.5). A NON-RUNTIME coupling — build-time code generation, a load-time singleton, packaging, an authoring sequence — leaves the column EMPTY and states its kind in the manifest's dependency_notes; that is T4's excluded-by-class case and reaches no band 5. An entry declares ONE coupling: two tokens in one entry is two entries. Measured at two estates before binding: 17 of 18 runtime couplings mapped onto exactly one token; none needed a token the vocabulary lacks."
226
+ event_participation:
227
+ values:
228
+ - value: publishes
229
+ description: The participant emits the event.
230
+ - value: consumes
231
+ description: The participant receives the event.
232
+ description: "The part a service, capability or feature plays toward an event, in `service_event.role`, `capability_event.role` and `feature_event.role`. `service_event.role` is also M-ADR 0206 §4.2's role-conditional impact flow (publishes → toward-target, consumes → toward-source). Bound at 3.9.0 (M-ADR 0210 §4.5): the values come from repo-config and derived edges, method-mandated surfaces; every row at both adopter estates' committed aggregates was in-vocabulary when bound."
233
+ contract_participation:
234
+ values:
235
+ - value: exposes
236
+ description: The service publishes the contract as its own surface.
237
+ - value: consumes
238
+ description: The service depends on a contract another service exposes.
239
+ description: The part a service plays toward a contract, in `service_contract.role`. Bound at 3.9.0 (M-ADR 0210 §4.5); one estate's rows were all `exposes`, the other's all `consumes` — the union is the vocabulary, and each estate's usage was in it.
240
+ consumption_role:
241
+ values:
242
+ - value: consumes
243
+ description: The product depends on / consumes the target.
244
+ description: "The part a product plays toward a capability or service it depends on, in `product_capability.role` and `product_service.role`. EXACTLY ONE VALUE, deliberately: every row at both estates carries `consumes`, and a column with one value is a population of one (M-ADR 0200 §4.10). Bound so the constant is DECLARED rather than accidental — a second value arriving is then a vocabulary decision with a finding, not a silent widening."
245
+ journey_participation:
246
+ values:
247
+ - value: primary
248
+ description: The persona the journey is designed around.
249
+ - value: handoff
250
+ description: A persona the journey passes to or from.
251
+ - value: supporting
252
+ description: A persona present in the journey without owning it.
253
+ description: "The kind of participation a persona has in a user journey, in `persona_journey.role` — the M-ADR 0210 worked example's `participation`. Bound at 3.9.0 (M-ADR 0210 §4.5): parsed from the persona spec's declared `Roles:` line, a method template surface; every row at both estates was in-vocabulary when bound."
254
+ model_notation:
255
+ values:
256
+ - value: mermaid-erd
257
+ description: M-ADR 0042's diagram grammar (data-model.mermaid.md) — the pre-Decision-1 form; migrates at the model's next requirements pass.
258
+ - value: typeql
259
+ description: The documented TypeQL subset of M-ADR 0210 §4.2 (data-model.tql) — the canonical form of every model authored from 2026-09-17 and of every migrated model.
260
+ description: "The notation a domain-model artefact is written in. Bound at 3.11.0 as the instrument of M-ADR 0210 §4.6 Decision 2: the builder derives it from the file, the metric line counts it, and a mermaid-erd row becomes an error at the first rebuild after the sunset 2027-03-31."
261
+ sdd_profile:
262
+ values:
263
+ - value: application-product
264
+ - value: integration-product
265
+ - value: platform-profile
266
+ - value: support-repo
267
+ description: "The SDD profile vocabulary (M-ADR 0135: one method, four profiles), as products/applications.profile and domains.method_profile carry it. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4)."
268
+ sdd_category:
269
+ values:
270
+ - value: application-product
271
+ - value: integration-provider
272
+ - value: integration-umbrella
273
+ - value: platform-root
274
+ - value: platform-subsystem
275
+ - value: support-repo
276
+ description: "The product category taxonomy (M-ADR 0131 / 0170): the architectural classification a products row carries. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4)."
277
+ product_lifecycle:
278
+ values:
279
+ - value: active
280
+ - value: planned
281
+ - value: deprecated
282
+ description: Product lifecycle (M-ADR 0201). Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
283
+ product_surface:
284
+ values:
285
+ - value: ui
286
+ - value: api
287
+ description: "M-ADR 0167: an application-product's surface trait. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4)."
288
+ product_packaging:
289
+ values:
290
+ - value: self-operated
291
+ - value: vendor-saas
292
+ description: "M-ADR 0175: the packaging axis. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4)."
293
+ domain_status:
294
+ values:
295
+ - value: active
296
+ - value: deferred
297
+ - value: absent
298
+ description: Domain lifecycle as domains.status carries it. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
299
+ invocation_pattern:
300
+ values:
301
+ - value: request-response
302
+ - value: async-request
303
+ - value: publish
304
+ description: M-ADR 0171's invocation half of the interaction vocabulary (the ingestion half is event-stream-consume | webhook | socket-listen | poll; both halves together are enums.interaction_pattern). Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
305
+ integration_component_resolution:
306
+ values:
307
+ - value: repository
308
+ - value: service
309
+ - value: undeclared
310
+ - value: unresolved
311
+ description: How an integration component's implementation was resolved. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
312
+ integration_component_declared_in:
313
+ values:
314
+ - value: component-manifest
315
+ - value: components-array
316
+ description: Where the component was declared in the integration manifest. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
317
+ confidence_level:
318
+ values:
319
+ - value: high
320
+ - value: medium
321
+ - value: low
322
+ description: Three-level confidence used by reverse-derived rows. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
323
+ capability_adr_confidence:
324
+ values:
325
+ - value: spec
326
+ - value: high
327
+ - value: medium
328
+ description: "capability_adr edge confidence: spec when the capability spec cites the ADR; high | medium when inferred. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4)."
329
+ glossary_xref_relation:
330
+ values:
331
+ - value: references
332
+ - value: supersedes
333
+ - value: alias-of
334
+ - value: conflicts-with
335
+ description: M-ADR 0158 glossary cross-reference relations. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
336
+ capability_source:
337
+ values:
338
+ - value: capability-spec
339
+ - value: capability-tree
340
+ - value: product-map
341
+ description: Which artefact a capabilities row was derived from. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
342
+ feature_source:
343
+ values:
344
+ - value: feature-spec
345
+ - value: feature-set
346
+ - value: feature-tree
347
+ - value: feature-grounding
348
+ - value: capability-spec
349
+ description: Which artefact a features row was derived from (M-ADR 0145). Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
350
+ artefact_maturity:
351
+ values:
352
+ - value: absent
353
+ - value: provisional
354
+ - value: working
355
+ - value: unknown
356
+ description: Maturity of a feature or screen as its grounding declares it. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
357
+ contract_kind:
358
+ values:
359
+ - value: rest
360
+ - value: event
361
+ - value: graphql
362
+ - value: rpc
363
+ - value: authz
364
+ description: Contract kind. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
365
+ contract_status:
366
+ values:
367
+ - value: active
368
+ - value: deprecated
369
+ description: Contract lifecycle status. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
370
+ contract_visibility:
371
+ values:
372
+ - value: public
373
+ - value: internal
374
+ - value: private
375
+ description: Contract visibility. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
376
+ contract_discovery:
377
+ values:
378
+ - value: discovered
379
+ - value: declared-external
380
+ description: Whether the contract was discovered in the SDD or declared as external. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
381
+ persistence_kind:
382
+ values:
383
+ - value: relational-table
384
+ - value: document-collection
385
+ - value: event-payload
386
+ - value: dto
387
+ - value: view
388
+ - value: other
389
+ description: M-ADR 0159 entity persistence kind. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
390
+ required_stability:
391
+ values:
392
+ - value: locked
393
+ - value: provisional
394
+ - value: unknown
395
+ description: "M-ADR 0204: the stability a consumer requires of a target; external | legacy live in target_locus, not here. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4)."
396
+ service_entity_relation:
397
+ values:
398
+ - value: owns
399
+ - value: reads
400
+ - value: writes
401
+ - value: references
402
+ description: How a service relates to a data-model entity. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
403
+ edge_source:
404
+ values:
405
+ - value: authored
406
+ - value: derived
407
+ description: Whether an edge row was authored in a manifest or derived by the builder. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
408
+ feature_contract_derivation_path:
409
+ values:
410
+ - value: cap-feature-cap-contract
411
+ - value: feature-service-service-contract
412
+ description: The join path a feature_contract row was derived through. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
413
+ subscription_channel_transport:
414
+ values:
415
+ - value: sse
416
+ - value: appsync-websocket
417
+ - value: pekko-ws
418
+ - value: mqtt
419
+ - value: webhook-push
420
+ - value: other
421
+ description: Transport of a feature subscription channel. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
422
+ capability_domain_model_source:
423
+ values:
424
+ - value: traceability-manifest
425
+ - value: inferred
426
+ description: "M-ADR 0142: whether the capability→domain-model edge was declared or inferred. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4)."
427
+ target_locus:
428
+ values:
429
+ - value: platform
430
+ - value: external
431
+ - value: legacy
432
+ description: "M-ADR 0204 §4.1: a statement about the dependency TARGET only. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4)."
433
+ dependency_contract_type:
434
+ values:
435
+ - value: openapi
436
+ - value: graphql
437
+ - value: grpc
438
+ - value: event
439
+ - value: event-stream
440
+ - value: stream
441
+ - value: rest
442
+ - value: other
443
+ description: Contract type of a platform dependency. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
444
+ data_plane_pattern:
445
+ values:
446
+ - value: own-store
447
+ - value: project
448
+ - value: retrieve
449
+ - value: stream-ingest
450
+ - value: publish
451
+ - value: generate
452
+ description: M-ADR 0193 / 0194 data-plane patterns, both sides. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
453
+ data_plane_direction:
454
+ values:
455
+ - value: inbound
456
+ - value: output
457
+ description: "M-ADR 0193 §4.7: the side of the data plane a binding is on. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4)."
458
+ data_plane_locality:
459
+ values:
460
+ - value: internal-platform
461
+ - value: internal-domain
462
+ - value: external-vendor
463
+ description: M-ADR 0193 locality of a data-plane binding's source. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
464
+ ui_component_kind:
465
+ values:
466
+ - value: element
467
+ - value: layout
468
+ - value: input
469
+ - value: display
470
+ - value: chart
471
+ - value: composite
472
+ - value: remote
473
+ - value: remote-iframe
474
+ - value: remote-webcomponent
475
+ description: M-ADR 0166 UI component kinds. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
476
+ conformance_target:
477
+ values:
478
+ - value: code-vs-contract
479
+ - value: binding-vs-reality
480
+ description: M-ADR 0194 conformance finding target. Bound at 3.13.0 from the column descriptions; measured against both reference estates before binding (M-ADR 0205 §4.4).
481
+ implementation_role:
482
+ values:
483
+ - value: as-is
484
+ description: The existing implementation.
485
+ - value: to-be
486
+ description: The target implementation the spec is migrating toward.
487
+ description: An implementation member's role against its spec (M-ADR 0181 §2.1). Bound at 3.13.0 on conformance_finding as conformance_role; renamed at 3.15.0, when implementation_members became its owner (M-ADR 0214 §4.2) — the values did not change.
488
+ implementation_lifecycle:
489
+ values:
490
+ - value: active
491
+ description: In service and the current implementation.
492
+ - value: planned
493
+ description: "Not yet built: the repository may not exist yet."
494
+ - value: deprecated
495
+ description: "Still running, scheduled for retirement (M-ADR 0214 §4.7: what some bindings called sunset)."
496
+ - value: migrating
497
+ description: Being moved onto, or off, while both sides run.
498
+ - value: legacy-active
499
+ description: The as-is implementation, still serving while a to-be replaces it.
500
+ - value: decommissioned
501
+ description: "Retired: no longer running."
502
+ description: An implementation member's lifecycle (M-ADR 0181 §2.1). Bound at 3.13.0 on conformance_finding as conformance_lifecycle; renamed at 3.15.0, when implementation_members became its owner (M-ADR 0214 §4.2) — the values did not change.
503
+ repo_scope:
504
+ values:
505
+ - value: component
506
+ description: "Part of what this SDD specifies: the SDD's artefact stack applies, and its capabilities or other services depend on it."
507
+ - value: support
508
+ description: "Supports a component without being one: its operational configuration, tooling, tests, collections, or a library it consumes."
509
+ description: Whether a mirrored repository is inside the scope of what its SDD specifies (M-ADR 0213). Deliberately neither a profile (profile is the SDD's) nor a role (role is M-ADR 0181's as-is | to-be); a repository's kind is component_type.
510
+ evidence_direction:
511
+ values:
512
+ - value: forward-authored
513
+ description: The spec came first and the code was built from it.
514
+ - value: seeding-reverse
515
+ description: A spec that never existed, recovered from pre-existing internal code.
516
+ - value: external-doc-reverse
517
+ description: The external surface a product consumes, grounded in a third party's published API or documentation.
518
+ - value: conformance-reverse
519
+ description: Own forward or maintained code, verified against its spec, with legitimate evolution fed back.
520
+ description: How an implementation member is evidenced (M-ADR 0180 §2.1; forward-authored added by M-ADR 0181 §2.1).
521
+ member_presence:
522
+ values:
523
+ - value: observed
524
+ description: Exported and observed in this baseline.
525
+ - value: carried
526
+ description: "Not re-exported: carried from an earlier baseline (carried_from), with its reason."
527
+ - value: removed
528
+ description: In the prior baseline and not in this one (members_removed), with its reason.
529
+ description: A snapshot member's presence in its baseline — the three states the snapshot conventions record (M-ADR 0214 §4.4).
530
+ conformance_disposition:
531
+ values:
532
+ - value: conformant
533
+ description: Code matches spec.
534
+ - value: conformant-open
535
+ description: "Both sides agree the item is deferred or absent: an open decision, not drift."
536
+ - value: code-defect
537
+ description: "The spec is authority: fix the code."
538
+ - value: spec-stale
539
+ description: "The code legitimately evolved: update the spec."
540
+ - value: divergence
541
+ description: "A genuine design question: triage, don't fail."
542
+ description: The triage outcome of a conformance-reverse delta (M-ADR 0180 §2.3). Bound so every file that records an outcome records one of these; the triage records are not yet catalogued (M-ADR 0214 §4.8).
543
+ delta_disposition:
544
+ values:
545
+ - value: capability-added
546
+ description: The code gained a capability the spec does not have.
547
+ - value: capability-removed
548
+ description: The code lost a capability the spec still has.
549
+ - value: spec-update
550
+ description: "The code legitimately evolved within a capability: the spec follows."
551
+ - value: refactor-only-no-spec-change
552
+ description: "The code changed and its behaviour did not: no spec change."
553
+ - value: ambiguous
554
+ description: "Cannot be classified from the delta alone: triage."
555
+ description: The classification of a delta-reverse finding between two snapshots (M-ADR 0180 §2.7). Bound so every file that records one records one of these; delta findings are not yet catalogued (M-ADR 0214 §4.8).
556
+ supply_verdict:
557
+ values:
558
+ - value: supported
559
+ description: The item reaches the canonical boundary from this integration.
560
+ - value: partial
561
+ description: It reaches it with a stated limitation (rate, scope, accuracy).
562
+ - value: source-absent
563
+ description: "The provider cannot supply it: nobody's work."
564
+ - value: gateway-gap
565
+ description: "The provider can and this integration does not: the integration's work."
566
+ - value: not-applicable
567
+ description: The item does not apply to this integration.
568
+ description: "What an integration states about a data item (M-ADR 0216 §4.2). unknown is NOT a member: it is the reading of no row."
569
+ supply_basis:
570
+ values:
571
+ - value: code
572
+ description: Read from the integration's code.
573
+ - value: grounded
574
+ description: Grounded in a vendor or source artefact.
575
+ - value: declared
576
+ description: Declared by the integration's own configuration.
577
+ - value: inferred
578
+ description: Inferred, with no artefact stating it.
579
+ description: The evidence class of a supply statement.
580
+ data_necessity:
581
+ values:
582
+ - value: required
583
+ description: The feature cannot work without it (or without one member of its alternative_group).
584
+ - value: enhances
585
+ description: The feature works without it, less well. Never decides coverage.
586
+ description: How a feature needs a data item.
587
+ support_verdict:
588
+ values:
589
+ - value: supported
590
+ description: Every requirement is met.
591
+ - value: partial
592
+ description: Every requirement is met or partly met, and one only partly.
593
+ - value: unknown
594
+ description: No requirement is unmet, and one is undecided because no supply row exists.
595
+ - value: unsupported
596
+ description: A requirement is unmet; limiting_item_id and limiting_reason name it.
597
+ - value: not-applicable
598
+ description: Every required item is not-applicable to this integration.
599
+ description: Whether one integration supports one feature at the canonical boundary (M-ADR 0216 §4.4).
600
+ limiting_reason:
601
+ values:
602
+ - value: source-absent
603
+ description: "The provider cannot supply the item: nobody's work."
604
+ - value: gateway-gap
605
+ description: "The integration does not supply what the provider has: the integration's work."
606
+ - value: no-canonical-home
607
+ description: "The platform has no canonical field for the item: platform contract work."
608
+ description: Why an unsupported feature is unsupported, and so whose work the gap is.
609
+ repo_dependency_kind:
610
+ values:
611
+ - value: library
612
+ description: Linked or packaged at build time.
613
+ - value: generated-from
614
+ description: Its content was produced from the other repository's templates.
615
+ description: How one repository depends on another's code (M-ADR 0217 §4.1).
616
+ catalogues:
617
+ domains:
618
+ primary_key: id
619
+ columns:
620
+ - name: id
621
+ type: string
622
+ nullable: false
623
+ description: Slug, e.g. identity, asset.
624
+ - name: name
625
+ type: string
626
+ nullable: false
627
+ description: Display name.
628
+ - name: description
629
+ type: string
630
+ nullable: false
631
+ - name: method_profile
632
+ type: string
633
+ nullable: false
634
+ description: platform-profile | application-product | integration-product.
635
+ - name: reference_architecture_equivalent
636
+ type: string
637
+ nullable: true
638
+ - name: status
639
+ type: string
640
+ nullable: false
641
+ description: active | deferred | absent. The builder emits 'active' for every discovered domain directory — a domain that exists on disk is active by definition; deferred/absent rows have no authoring source yet (would come from roadmap/archetype declarations, not discovery).
642
+ - name: repo_count
643
+ type: int
644
+ nullable: false
645
+ - name: source_sdd_id
646
+ type: string
647
+ nullable: true
648
+ description: Originating SDD slug. Populated by the aggregator at merge time per M-ADR 0134; left empty by per-SDD builders.
649
+ - name: platform_sdd_id
650
+ type: string
651
+ nullable: true
652
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
653
+ column_enums:
654
+ method_profile: enums.sdd_profile
655
+ status: enums.domain_status
656
+ products:
657
+ primary_key: id
658
+ columns:
659
+ - name: id
660
+ type: string
661
+ nullable: false
662
+ description: product_id slug.
663
+ - name: name
664
+ type: string
665
+ nullable: false
666
+ - name: domain_id
667
+ type: string
668
+ nullable: true
669
+ description: Owning capability domain. Populated for platform-profile products (platform-root, platform-subsystem). App and integration products do not have a primary domain — see M-ADR 0136.
670
+ - name: profile
671
+ type: string
672
+ nullable: false
673
+ description: platform-profile | application-product | integration-product | support-repo.
674
+ - name: category
675
+ type: string
676
+ nullable: true
677
+ description: "Architectural classification per docs/method/methods/standards/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."
678
+ - name: doc_path
679
+ type: string
680
+ nullable: false
681
+ description: Path to _product/ directory, relative to docs/.
682
+ - name: lifecycle
683
+ type: string
684
+ nullable: true
685
+ 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."
686
+ - name: deprecated_date
687
+ type: date
688
+ nullable: true
689
+ description: Date the deprecation decision took effect. Only meaningful when lifecycle=deprecated. From the manifest's deprecated_date:. Added in 2.22.0.
690
+ - name: successor_sdd_id
691
+ type: string
692
+ nullable: true
693
+ 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."
694
+ - name: exemplar
695
+ type: string
696
+ nullable: true
697
+ description: "`true` when this SDD is a reference exemplar — it demonstrates a profile shape rather than modelling a real product or provider relationship. Empty otherwise, which is the unmarked norm (absent in the manifest = a real SDD, no finding). From the manifest's `exemplar:` field (sdd-manifest-schema 1.8.0). PROFILE-AGNOSTIC, unlike surface/packaging/application_archetype which are application-product-only — the first exemplar cohort found was integration-products. DERIVED, not authorable: this column and `integrations.exemplar` both come from the one manifest field, so they cannot disagree; two independently authored copies could, which is the failure mode the trait exists to remove. No builder branches on it — it is emitted to be filterable and nothing consumes it, because an implicit exclusion inside a rollup is much harder to remove than to add. Added in 2.46.0."
698
+ - name: shared_library
699
+ type: string
700
+ nullable: true
701
+ description: "`true` when this SDD exists to provide code other SDDs build from or generate from (M-ADR 0217 §4.4). Empty otherwise, the unmarked norm. From the SDD manifest's `shared_library:` field. PROFILE-AGNOSTIC, like `exemplar`. DERIVED, not authorable: this column and its twin on the other catalogue come from the one manifest field, so they cannot disagree. No builder branches on it; a rollup filters on it. Added in 3.20.0."
702
+ - name: surface
703
+ type: string
704
+ nullable: true
705
+ description: "ui | api (empty for non-application-product). Application-product surface trait from the manifest's surface: field (M-ADR 0167, sdd-manifest-schema 1.2.0). Empty on non-application products. Added in 2.35.0."
706
+ - name: packaging
707
+ type: string
708
+ nullable: true
709
+ description: "vendor-saas | self-operated (empty for non-application-product). Application-product packaging trait from the manifest's packaging: field (M-ADR 0175, sdd-manifest-schema 1.7.0). `vendor-saas` marks a packaged-SaaS product — vendor-operated runtime (no own deployment evidence) and a vendor-versioned base capability set. Absent in the manifest resolves to `self-operated`, the unmarked norm. Per M-ADR 0175 §4 no builder may branch on this trait beyond evidence/deployment handling. Column position follows the M-ADR 0194 §3.1 canonical axis order (surface, packaging, application_archetype). Added in 2.41.0."
710
+ - name: application_archetype
711
+ type: string
712
+ nullable: true
713
+ description: "Application-product shape classification from the manifest's application_archetype: field (M-ADR 0191, sdd-manifest-schema 1.2.0). Resolved-enum over a tiered vocabulary (method: unclassified; reference-architecture bundle; adopter). Defaults to 'unclassified' for application-product (with a coverage finding), empty for other profiles. Distinct from the M-ADR 0173 domain archetype and M-ADR 0169 openui archetype. Added in 2.35.0."
714
+ - name: synthesis_quality
715
+ type: int
716
+ nullable: true
717
+ description: "DEPRECATED at 3.3.0, for removal at 4.0.0 — superseded by `quality_scores` (rubric_id `reverse-product-quality.product_synthesis_quality`). Score 0-10 from the product-synthesis rubric (reverse method only). WIRED in 2.47.0 from `orchestration/gate-registry/reverse-product-quality-scores.yaml` — the registry family at product granularity — via the SELF-PRODUCT rule: the unit whose `product_path` is '.' AND whose key equals the SDD's sdd_id. Both conditions are required; product_path alone admits synthetic gate fixtures, key-matching alone admits covered sub-products. Backfill only: it fills an empty cell and never overwrites an emitted value. Empty on a forward estate by design — a forward-authored product has no reverse rubric score, and residue-based authoring signals deliberately do NOT write here (see status)."
718
+ - name: synthesis_band
719
+ type: string
720
+ nullable: true
721
+ description: "DEPRECATED at 3.3.0, for removal at 4.0.0 — superseded by `quality_scores.band`, which is UNBOUND because the vocabulary is per-rubric. This column's closed set accepts only three of the SEVEN band values the reverse estate actually authors (measured 3.3.0: strong, working, weak, moderate, easy, hard, very-hard), silently emptying the rest. developing | working | strong — a CLOSED vocabulary; a band outside it is reported as a convention finding and the cell left empty rather than emitting a value no consumer can interpret. Wired in 2.47.0 alongside synthesis_quality."
722
+ - name: last_assessed
723
+ type: date
724
+ nullable: true
725
+ - name: highest_snapshot_impact
726
+ type: string
727
+ nullable: true
728
+ - name: repo_count
729
+ type: int
730
+ nullable: false
731
+ description: Number of repos mapped to this product.
732
+ - name: source_sdd_id
733
+ type: string
734
+ nullable: true
735
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
736
+ - name: platform_sdd_id
737
+ type: string
738
+ nullable: true
739
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
740
+ foreign_keys:
741
+ - column: domain_id
742
+ references: domains.id
743
+ nullable: true
744
+ column_enums:
745
+ profile: enums.sdd_profile
746
+ category: enums.sdd_category
747
+ lifecycle: enums.product_lifecycle
748
+ surface: enums.product_surface
749
+ packaging: enums.product_packaging
750
+ applications:
751
+ primary_key: id
752
+ columns:
753
+ - name: id
754
+ type: string
755
+ nullable: false
756
+ description: product_id slug.
757
+ - name: name
758
+ type: string
759
+ nullable: false
760
+ - name: domain_id
761
+ type: string
762
+ nullable: true
763
+ description: Owning capability domain. Populated for platform-profile products (platform-root, platform-subsystem). App and integration products do not have a primary domain — see M-ADR 0136.
764
+ - name: profile
765
+ type: string
766
+ nullable: false
767
+ description: platform-profile | application-product | integration-product | support-repo.
768
+ - name: category
769
+ type: string
770
+ nullable: true
771
+ description: "Architectural classification per docs/method/methods/standards/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."
772
+ - name: doc_path
773
+ type: string
774
+ nullable: false
775
+ description: Path to _product/ directory, relative to docs/.
776
+ - name: lifecycle
777
+ type: string
778
+ nullable: true
779
+ 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."
780
+ - name: deprecated_date
781
+ type: date
782
+ nullable: true
783
+ description: Date the deprecation decision took effect. Only meaningful when lifecycle=deprecated. From the manifest's deprecated_date:. Added in 2.22.0.
784
+ - name: successor_sdd_id
785
+ type: string
786
+ nullable: true
787
+ 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."
788
+ - name: exemplar
789
+ type: string
790
+ nullable: true
791
+ description: "`true` when this SDD is a reference exemplar — it demonstrates a profile shape rather than modelling a real product or provider relationship. Empty otherwise, which is the unmarked norm (absent in the manifest = a real SDD, no finding). From the manifest's `exemplar:` field (sdd-manifest-schema 1.8.0). PROFILE-AGNOSTIC, unlike surface/packaging/application_archetype which are application-product-only — the first exemplar cohort found was integration-products. DERIVED, not authorable: this column and `integrations.exemplar` both come from the one manifest field, so they cannot disagree; two independently authored copies could, which is the failure mode the trait exists to remove. No builder branches on it — it is emitted to be filterable and nothing consumes it, because an implicit exclusion inside a rollup is much harder to remove than to add. Added in 2.46.0."
792
+ - name: shared_library
793
+ type: string
794
+ nullable: true
795
+ description: "`true` when this SDD exists to provide code other SDDs build from or generate from (M-ADR 0217 §4.4). Empty otherwise, the unmarked norm. From the SDD manifest's `shared_library:` field. PROFILE-AGNOSTIC, like `exemplar`. DERIVED, not authorable: this column and its twin on the other catalogue come from the one manifest field, so they cannot disagree. No builder branches on it; a rollup filters on it. Added in 3.20.0."
796
+ - name: surface
797
+ type: string
798
+ nullable: true
799
+ description: "ui | api (empty for non-application-product). Application-product surface trait from the manifest's surface: field (M-ADR 0167, sdd-manifest-schema 1.2.0). Empty on non-application products. Added in 2.35.0."
800
+ - name: packaging
801
+ type: string
802
+ nullable: true
803
+ description: "vendor-saas | self-operated (empty for non-application-product). Application-product packaging trait from the manifest's packaging: field (M-ADR 0175, sdd-manifest-schema 1.7.0). `vendor-saas` marks a packaged-SaaS product — vendor-operated runtime (no own deployment evidence) and a vendor-versioned base capability set. Absent in the manifest resolves to `self-operated`, the unmarked norm. Per M-ADR 0175 §4 no builder may branch on this trait beyond evidence/deployment handling. Column position follows the M-ADR 0194 §3.1 canonical axis order (surface, packaging, application_archetype). Added in 2.41.0."
804
+ - name: application_archetype
805
+ type: string
806
+ nullable: true
807
+ description: "Application-product shape classification from the manifest's application_archetype: field (M-ADR 0191, sdd-manifest-schema 1.2.0). Resolved-enum over a tiered vocabulary (method: unclassified; reference-architecture bundle; adopter). Defaults to 'unclassified' for application-product (with a coverage finding), empty for other profiles. Distinct from the M-ADR 0173 domain archetype and M-ADR 0169 openui archetype. Added in 2.35.0."
808
+ - name: synthesis_quality
809
+ type: int
810
+ nullable: true
811
+ description: "DEPRECATED at 3.3.0, for removal at 4.0.0 — superseded by `quality_scores` (rubric_id `reverse-product-quality.product_synthesis_quality`). Score 0-10 from the product-synthesis rubric (reverse method only). WIRED in 2.47.0 from `orchestration/gate-registry/reverse-product-quality-scores.yaml` — the registry family at product granularity — via the SELF-PRODUCT rule: the unit whose `product_path` is '.' AND whose key equals the SDD's sdd_id. Both conditions are required; product_path alone admits synthetic gate fixtures, key-matching alone admits covered sub-products. Backfill only: it fills an empty cell and never overwrites an emitted value. Empty on a forward estate by design — a forward-authored product has no reverse rubric score, and residue-based authoring signals deliberately do NOT write here (see status)."
812
+ - name: synthesis_band
813
+ type: string
814
+ nullable: true
815
+ description: "DEPRECATED at 3.3.0, for removal at 4.0.0 — superseded by `quality_scores.band`, which is UNBOUND because the vocabulary is per-rubric. This column's closed set accepts only three of the SEVEN band values the reverse estate actually authors (measured 3.3.0: strong, working, weak, moderate, easy, hard, very-hard), silently emptying the rest. developing | working | strong — a CLOSED vocabulary; a band outside it is reported as a convention finding and the cell left empty rather than emitting a value no consumer can interpret. Wired in 2.47.0 alongside synthesis_quality."
816
+ - name: last_assessed
817
+ type: date
818
+ nullable: true
819
+ - name: highest_snapshot_impact
820
+ type: string
821
+ nullable: true
822
+ - name: repo_count
823
+ type: int
824
+ nullable: false
825
+ description: Number of repos mapped to this product.
826
+ - name: source_sdd_id
827
+ type: string
828
+ nullable: true
829
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
830
+ - name: platform_sdd_id
831
+ type: string
832
+ nullable: true
833
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
834
+ description: Filtered view of products where profile = application-product.
835
+ foreign_keys:
836
+ - column: domain_id
837
+ references: domains.id
838
+ nullable: true
839
+ column_enums:
840
+ profile: enums.sdd_profile
841
+ category: enums.sdd_category
842
+ lifecycle: enums.product_lifecycle
843
+ surface: enums.product_surface
844
+ packaging: enums.product_packaging
845
+ integrations:
846
+ primary_key: id
847
+ columns:
848
+ - name: id
849
+ type: string
850
+ nullable: false
851
+ description: Provider slug.
852
+ - name: name
853
+ type: string
854
+ nullable: false
855
+ - name: domain_id
856
+ type: string
857
+ nullable: true
858
+ description: Provider adapters are federation nodes, not capability-domain members. Left empty per M-ADR 0136.
859
+ - name: parent_product_id
860
+ type: string
861
+ nullable: true
862
+ description: Umbrella integration-product. Empty for an SDD's own row; set to the SDD's integrationId for sub-integration rows declared via integration-manifest.yaml `sub_integrations:` (per M-ADR 0144, schema 2.6.0).
863
+ - name: category
864
+ type: string
865
+ nullable: false
866
+ description: oem | device | fleet | camera | legacy | data-sharing | gateway-framework (extensible per ecosystem).
867
+ - name: doc_path
868
+ type: string
869
+ nullable: false
870
+ - name: repo_count
871
+ type: int
872
+ nullable: false
873
+ - name: ingestion_pattern
874
+ type: string
875
+ nullable: true
876
+ description: "Closed method-tier enum (event-stream-consume | webhook | socket-listen | poll) from the manifest's SDD-level `ingestionPattern` — HOW the integration acquires data (M-ADR 0171 §4.2). SCALAR: §9.3's multi-valued allowance was withdrawn in §10.5. Empty when undeclared or on an outbound-only integration. Empty on `sub_integrations` rows — the patterns are declared once at SDD level and are not per-provider. Added in 2.45.0."
877
+ - name: invocation_pattern
878
+ type: string
879
+ nullable: true
880
+ description: Closed method-tier enum (request-response | async-request | publish) from the manifest's SDD-level `invocationPattern` — HOW the integration invokes the provider (M-ADR 0171 §4.3). Scalar; empty when undeclared, on an inbound-only integration, or on a sub_integrations row. Added in 2.45.0.
881
+ - name: pattern_qualifier
882
+ type: string
883
+ nullable: true
884
+ description: Free-text sub-variant from `patternQualifier` where delivery semantics differ materially within a pattern (e.g. poll as a provider-issued ordered cursor vs a client-built window). Deliberately unconstrained — the method owns the pattern vocabulary, not every provider's delivery nuance. Added in 2.45.0.
885
+ - name: exemplar
886
+ type: string
887
+ nullable: true
888
+ description: "`true` when the emitting SDD is a reference exemplar (demonstrates a profile shape rather than modelling a real provider relationship); empty otherwise. Derived from the SDD manifest's `exemplar:` field (sdd-manifest-schema 1.8.0), same source as `products.exemplar` — neither column is independently authorable. Carried on `sub_integrations` rows too, INHERITED from the emitting SDD. That deliberately differs from `ingestion_pattern`/`invocation_pattern`, which are empty on sub rows, and the difference is the point: a pattern is a MECHANISM (how this integration acquires data), genuinely one per SDD, whereas `exemplar` is a REALITY STATUS that propagates to everything the SDD emits — if the SDD is a demonstration then every provider relationship it declares is a demonstration. Leaving sub rows empty would flag the umbrella and count its demonstration sub-providers as real, reproducing the rollup overcount this column exists to fix one level down. Do not normalise it to match the pattern columns. The trade accepted: a real SDD with one demonstration sub-provider is unexpressible — a state that should not exist. Added in 2.46.0."
889
+ - name: shared_library
890
+ type: string
891
+ nullable: true
892
+ description: "`true` when this SDD exists to provide code other SDDs build from or generate from (M-ADR 0217 §4.4). Empty otherwise, the unmarked norm. From the SDD manifest's `shared_library:` field. PROFILE-AGNOSTIC, like `exemplar`. DERIVED, not authorable: this column and its twin on the other catalogue come from the one manifest field, so they cannot disagree. No builder branches on it; a rollup filters on it. Added in 3.20.0."
893
+ - name: source_sdd_id
894
+ type: string
895
+ nullable: true
896
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
897
+ - name: platform_sdd_id
898
+ type: string
899
+ nullable: true
900
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
901
+ description: Granular provider adapters. Each row is either (a) an integration-product SDD's own row (one per SDD; parent_product_id empty), or (b) a manifest-declared sub-integration of a multi-provider monolith (parent_product_id = umbrella SDD's id). Per M-ADR 0144 (schema 2.6.0), sub-integrations are declared via the optional `sub_integrations:` array in `integration-manifest.yaml`.
902
+ foreign_keys:
903
+ - column: domain_id
904
+ references: domains.id
905
+ nullable: true
906
+ - column: parent_product_id
907
+ references: products.id
908
+ nullable: true
909
+ column_enums:
910
+ invocation_pattern: enums.invocation_pattern
911
+ integration_component:
912
+ primary_key: id
913
+ columns:
914
+ - name: id
915
+ type: string
916
+ nullable: false
917
+ description: "{integration_id}__{component_id}. A duplicate emits a divergence finding and is dropped — two components of one integration cannot share an id."
918
+ - name: integration_id
919
+ type: string
920
+ nullable: false
921
+ description: The integration-product declaring this component (this SDD's integrationId).
922
+ - name: component_id
923
+ type: string
924
+ nullable: false
925
+ description: The component's declared id, from `components[].id`. Unique within its manifest (a duplicate is dropped with a divergence finding). Names an INTERACTION SURFACE — commonly one provider feed — not necessarily a deployable; the optional `component_repo` carries the code linkage where one is asserted (M-ADR 0171 §10.2).
926
+ - name: component_repo
927
+ type: string
928
+ nullable: true
929
+ description: "OPTIONAL explicit code linkage from `components[].componentRepo` — the deployable (repositories.id / services.id) that realises this component. Empty is the normal case for a feed-level component: the tier is at interaction-surface granularity, not deployable granularity, and the method does not require a component to name a deployable (M-ADR 0171 §10.2). When declared it MUST resolve, since a declared link is a positive assertion the method can check. Added in 2.44.0."
930
+ - name: resolution
931
+ type: string
932
+ nullable: false
933
+ description: undeclared | repository | service | unresolved. `undeclared` = no `componentRepo` given (normal, no finding). `repository`/`service` = the declared linkage resolved. `unresolved` = declared but matched no repositories.id or services.id of this SDD, which carries a coverage finding. Re-based on `component_repo` in 2.44.0 — it previously described resolution of `component_id` itself.
934
+ - name: component_type
935
+ type: string
936
+ nullable: true
937
+ description: Optional adopter-defined framework-role label from `componentType` (e.g. the adopter's archetype name). NOT enumerated or validated by the method (M-ADR 0171 §9.1/§9.5) — it exists so an adopter's role→pattern mapping is traceable. Empty when unauthored.
938
+ - name: direction
939
+ type: string
940
+ nullable: true
941
+ description: "inbound | outbound | bidirectional, from `dataFlow.direction`. Determines which pattern field is meaningful: inbound → ingestion_pattern, outbound → invocation_pattern, internal components declare neither (M-ADR 0171 §9.1)."
942
+ - name: frequency
943
+ type: string
944
+ nullable: true
945
+ description: real-time | on-demand | batch, from `dataFlow.frequency`. Open string — adopters carry finer cadences in prose.
946
+ - name: transport
947
+ type: string
948
+ nullable: true
949
+ description: Concrete wire mechanism from `protocol.transport` (kafka | sns | sqs | kinesis | amqp | tcp | udp | https | grpc | ...). Open string. Insufficient alone to determine the pattern — https may be webhook, poll or request-response; direction + initiator disambiguate (M-ADR 0171 §9.2).
950
+ - name: format
951
+ type: string
952
+ nullable: true
953
+ description: Payload format from `protocol.format` (json | protobuf | binary | avro | ...). Open string.
954
+ - name: auth
955
+ type: string
956
+ nullable: true
957
+ description: Auth mechanism from `protocol.auth` (tls | sasl | oauth2 | api-key | mtls | none | ...). Open string — real estates carry vendor-specific grant variants here.
958
+ - name: ingestion_pattern
959
+ type: string
960
+ nullable: true
961
+ description: Closed method-tier enum (event-stream-consume | webhook | socket-listen | poll) from `components[].ingestionPattern`. Meaningful on inbound components; empty otherwise (M-ADR 0171 §4.2).
962
+ - name: invocation_pattern
963
+ type: string
964
+ nullable: true
965
+ description: Closed method-tier enum (request-response | async-request | publish) from `components[].invocationPattern`. Meaningful on outbound components; empty otherwise (M-ADR 0171 §4.3).
966
+ - name: pattern_qualifier
967
+ type: string
968
+ nullable: true
969
+ description: Free-text sub-variant from `patternQualifier` where delivery semantics differ materially within a pattern (e.g. poll as token-feed vs windowed). Deliberately unconstrained.
970
+ - name: primary_entities
971
+ type: string
972
+ nullable: true
973
+ description: Semicolon-joined `dataFlow.primaryEntities`. Adopter-tier entity names; joined rather than normalised because the tier is descriptive, not an FK surface.
974
+ - name: declared_in
975
+ type: string
976
+ nullable: false
977
+ description: "components-array | component-manifest — WHICH of M-ADR 0171 §9.1's two homes declared this component. Added in 2.49.0, when the second home became catalogued. Required because §10.1 states that any coverage reasoning MUST say which form it counts, and once one table holds both, a consumer cannot tell them apart: merging them without this recreates the reference-exemplar problem — well-formed rows that do not mean what a consumer assumes. Measured at the time of wiring: the array form was 15 components across 5 SDDs, the per-component form 86 across 21, and the two are DISJOINT (no id collision, no SDD using both). `resolution` also reads differently by form — for the array form `componentRepo` is an optional declaration (0 of 15 declared it); for the per-component form the containing `repos/<component>/` directory IS the repo, so linkage is structural rather than declared."
978
+ - name: source_sdd_id
979
+ type: string
980
+ nullable: true
981
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
982
+ - name: platform_sdd_id
983
+ type: string
984
+ nullable: true
985
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
986
+ description: |
987
+ Integration-product edge (M-ADR 0171 §9, catalogued per §10.1): one row per component declared in the SDD's `integration-manifest.yaml` `components:` array. A component is one of the integration's component code repos (M-ADR 0106) — an integration SDD is a one-to-many spec→code unit — and the tier is the source of truth for the interaction pattern, with the SDD-level `ingestionPattern`/`invocationPattern` as its aggregate (§9.3).
988
+ Built per-SDD, integration-product only (other profiles emit headers-only). A component id is unique within its manifest and names an **interaction surface** — commonly one provider feed — which is NOT necessarily a deployable (§10.2). The optional `component_repo` carries an explicit code linkage; when declared it MUST resolve to a `repositories.id` or `services.id` of the same SDD, and a declared-but-unresolvable linkage is a **coverage finding, not a load failure**. `resolution` records the outcome inline, including `undeclared` for the normal feed-level case, so a consumer filters on it rather than inferring from a join miss.
989
+ The method deliberately does NOT enumerate `component_type` — that is the adopter's own framework-role label (§9.1/§9.5), carried so an adopter's role→pattern mapping stays machine-traceable. `transport`/`format`/`auth` are open strings for the same reason: they describe the wire, and the portable semantic is the pattern. Added in schema 2.43.0.
990
+ foreign_keys:
991
+ - column: integration_id
992
+ references: integrations.id
993
+ nullable: false
994
+ column_enums:
995
+ invocation_pattern: enums.invocation_pattern
996
+ resolution: enums.integration_component_resolution
997
+ declared_in: enums.integration_component_declared_in
998
+ adrs:
999
+ primary_key: id
1000
+ columns:
1001
+ - name: id
1002
+ type: string
1003
+ nullable: false
1004
+ description: ADR id, e.g. ADR-0001 or {domain}-D001.
1005
+ - name: title
1006
+ type: string
1007
+ nullable: false
1008
+ - name: status
1009
+ type: string
1010
+ nullable: true
1011
+ description: Accepted | Proposed | Superseded | Deprecated | Deferred (forward) plus reverse-inferred | reverse-adapted (reverse).
1012
+ - name: domain_id
1013
+ type: string
1014
+ nullable: true
1015
+ description: "Domain slug for a domain-scoped ADR (docs/domains/<slug>/…); 'platform' for a platform-scoped ADR (docs/platform/adr/), whose owner has that domain by construction; EMPTY for a method-scoped ADR (docs/method/adr/, docs/method/platform-adr/) — method ADRs are cross-cutting governance and belong to no domain. Nullable since 3.10.0 (M-ADR 0136 §4.3 amendment): before it, method ADRs were pinned to 'platform' and dangled in every platform-root without a domain of that name. External for application- and integration-product SDDs since 3.17.0, as capabilities.domain_id is: an app or integration SDD files its own domain-scoped decisions under a platform-side domain (e.g. integrations) it does not declare, so its build logs an external finding naming the value, and the owning platform's aggregate validates it — and fails there if that platform declares no such domain."
1016
+ - name: decision_date
1017
+ type: date
1018
+ nullable: true
1019
+ - name: doc_path
1020
+ type: string
1021
+ nullable: false
1022
+ - name: superseded_by_id
1023
+ type: string
1024
+ nullable: true
1025
+ - name: inference_confidence
1026
+ type: string
1027
+ nullable: true
1028
+ description: high | medium | low (reverse-inferred ADRs only).
1029
+ - name: supersedes_raw
1030
+ type: string
1031
+ nullable: true
1032
+ description: Raw text from Supersedes bullet for later parsing.
1033
+ - name: source_sdd_id
1034
+ type: string
1035
+ nullable: true
1036
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1037
+ - name: platform_sdd_id
1038
+ type: string
1039
+ nullable: true
1040
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1041
+ foreign_keys:
1042
+ - column: domain_id
1043
+ references: domains.id
1044
+ nullable: true
1045
+ external_for_profiles:
1046
+ - application-product
1047
+ - integration-product
1048
+ - column: superseded_by_id
1049
+ references: adrs.id
1050
+ nullable: true
1051
+ column_enums:
1052
+ inference_confidence: enums.confidence_level
1053
+ glossary_items:
1054
+ primary_key: id
1055
+ columns:
1056
+ - name: id
1057
+ type: string
1058
+ nullable: false
1059
+ description: "Slug: {domain}-{term-slug} for uniqueness."
1060
+ - name: term
1061
+ type: string
1062
+ nullable: false
1063
+ - name: definition
1064
+ type: string
1065
+ nullable: false
1066
+ - name: owning_domain_id
1067
+ type: string
1068
+ nullable: true
1069
+ description: Null for platform-level terms.
1070
+ - name: canonical_term_id
1071
+ type: string
1072
+ nullable: true
1073
+ description: Set when this term is an alias for another.
1074
+ - name: aliases
1075
+ type: string
1076
+ nullable: true
1077
+ description: "';'-separated list."
1078
+ - name: evidence
1079
+ type: string
1080
+ nullable: true
1081
+ - name: notes
1082
+ type: string
1083
+ nullable: true
1084
+ - name: source_sdd_id
1085
+ type: string
1086
+ nullable: true
1087
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1088
+ - name: platform_sdd_id
1089
+ type: string
1090
+ nullable: true
1091
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1092
+ foreign_keys:
1093
+ - column: owning_domain_id
1094
+ references: domains.id
1095
+ nullable: true
1096
+ - column: canonical_term_id
1097
+ references: glossary_items.id
1098
+ nullable: true
1099
+ glossary_xref:
1100
+ primary_key: id
1101
+ columns:
1102
+ - name: id
1103
+ type: string
1104
+ nullable: false
1105
+ description: "Composite: {source_id}__{relation}__{target_id}."
1106
+ - name: source_id
1107
+ type: string
1108
+ nullable: false
1109
+ - name: target_id
1110
+ type: string
1111
+ nullable: false
1112
+ - name: relation
1113
+ type: string
1114
+ nullable: false
1115
+ description: alias-of | conflicts-with | references | supersedes (extended in schema 2.12.0 per M-ADR 0158).
1116
+ description: "Edge: cross-domain glossary relationships from glossary-alignment-manifest.yaml. Per M-ADR 0158, four walkers ingest into this catalogue: (a) forward declared pair-form {source, target} entries under aliases/conflicts, (b) reverse-method cross_domain_terms (emits references edges per referencer→owner), (c) reverse-method multi-domain conflicts (pair-wise expansion across domains[]), (d) forward-method supersedes (status: superseded entries with superseded_by back-link)."
1117
+ foreign_keys:
1118
+ - column: source_id
1119
+ references: glossary_items.id
1120
+ nullable: false
1121
+ - column: target_id
1122
+ references: glossary_items.id
1123
+ nullable: false
1124
+ column_enums:
1125
+ relation: enums.glossary_xref_relation
1126
+ entity_glossary:
1127
+ primary_key: id
1128
+ columns:
1129
+ - name: id
1130
+ type: string
1131
+ nullable: false
1132
+ description: "Composite: {domain_id}__{entity_name_slug}__{glossary_item_id}."
1133
+ - name: domain_id
1134
+ type: string
1135
+ nullable: false
1136
+ - name: entity_name
1137
+ type: string
1138
+ nullable: false
1139
+ - name: glossary_item_id
1140
+ type: string
1141
+ nullable: false
1142
+ - name: status
1143
+ type: string
1144
+ nullable: false
1145
+ description: aligned | matched_direct. Conflicting statuses within a domain resolve matched_direct > aligned with a divergence finding.
1146
+ - name: source_sdd_id
1147
+ type: string
1148
+ nullable: true
1149
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1150
+ - name: platform_sdd_id
1151
+ type: string
1152
+ nullable: true
1153
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1154
+ - name: entity_id
1155
+ type: string
1156
+ nullable: true
1157
+ description: The data-model entity this glossary mapping is about — an entities.id. The edge was always emitted per (domain, entity, glossary_term) and this end was missing from its keys (found at M-ADR 0210 flip 2; added at 3.9.0). Nullable until every builder populates it.
1158
+ description: "Edge: data-model entity → canonical glossary term. Added in schema 2.12.0 per M-ADR 0158. Source: glossary-alignment-manifest.yaml `models[].entities[]` with status ∈ {aligned, matched_direct} and non-empty glossary_term. PK derives from (domain, entity_name, glossary_item) so same-domain multi-diagram entries collapse to one row; cross-domain entries (e.g. platform-wide conceptual model + domain-specific model) emit one row per domain — legitimate cross-level cataloguing."
1159
+ foreign_keys:
1160
+ - column: domain_id
1161
+ references: domains.id
1162
+ nullable: false
1163
+ - column: glossary_item_id
1164
+ references: glossary_items.id
1165
+ nullable: false
1166
+ - column: entity_id
1167
+ references: entities.id
1168
+ nullable: true
1169
+ services:
1170
+ primary_key: id
1171
+ columns:
1172
+ - name: id
1173
+ type: string
1174
+ nullable: false
1175
+ description: Service id, derived from artifact_id where artifact_type=service.
1176
+ - name: name
1177
+ type: string
1178
+ nullable: false
1179
+ - name: product_id
1180
+ type: string
1181
+ nullable: false
1182
+ - name: domain_id
1183
+ type: string
1184
+ nullable: true
1185
+ description: Owning capability domain. Populated when the repo-config declared domain resolves to a docs/domains/<slug>/ in the local SDD; left empty otherwise per M-ADR 0136.
1186
+ - name: primary_repo_id
1187
+ type: string
1188
+ nullable: true
1189
+ description: Main contributing repo. Nullable when service spans repos. Per M-ADR 0197, a repository MAY declare a `services:` block naming more than one service it builds — every declared entry's primary_repo_id equals the declaring repository's id, so this column is m:n (several services legitimately sharing one repository), not the 1:1 identity it holds when no repository declares the block.
1190
+ - name: runtime_type
1191
+ type: string
1192
+ nullable: true
1193
+ description: serverless-framework | jvm-service | lambda | k8s | ...
1194
+ - name: language
1195
+ type: string
1196
+ nullable: true
1197
+ - name: component_type
1198
+ type: string
1199
+ nullable: true
1200
+ description: bff | api | consumer | ui | collector | processor | ...
1201
+ - name: status
1202
+ type: string
1203
+ nullable: true
1204
+ description: production-wired | non-production | library.
1205
+ - name: confidence
1206
+ type: string
1207
+ nullable: true
1208
+ description: high | medium | low (reverse-method classification).
1209
+ - name: context
1210
+ type: string
1211
+ nullable: true
1212
+ description: Bounded-context membership (per M-ADR 0170 §4.6). Free-form adopter label, orthogonal to domain_id. Not an FK. Carried for forward-parity; awaits a derivation source (e.g. from the service's contracts' x-context). Added in schema 2.19.0.
1213
+ - name: description
1214
+ type: string
1215
+ nullable: true
1216
+ - name: source_sdd_id
1217
+ type: string
1218
+ nullable: true
1219
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1220
+ - name: platform_sdd_id
1221
+ type: string
1222
+ nullable: true
1223
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1224
+ foreign_keys:
1225
+ - column: product_id
1226
+ references: products.id
1227
+ nullable: false
1228
+ - column: domain_id
1229
+ references: domains.id
1230
+ nullable: true
1231
+ - column: primary_repo_id
1232
+ references: repositories.id
1233
+ nullable: true
1234
+ column_enums:
1235
+ component_type: enums.service_type
1236
+ confidence: enums.confidence_level
1237
+ capabilities:
1238
+ primary_key: id
1239
+ columns:
1240
+ - name: id
1241
+ type: string
1242
+ nullable: false
1243
+ description: Capability slug.
1244
+ - name: name
1245
+ type: string
1246
+ nullable: false
1247
+ - name: domain_id
1248
+ type: string
1249
+ nullable: false
1250
+ - name: tree_category
1251
+ type: string
1252
+ nullable: true
1253
+ description: Top-level grouping when capability comes from a capability tree (reverse).
1254
+ - name: parent_capability_id
1255
+ type: string
1256
+ nullable: true
1257
+ - name: evidence_class
1258
+ type: string
1259
+ nullable: true
1260
+ description: Evidence class of the capability's claims, from `capability.evidence_class` in the traceability manifest. Free-form; conventional values code-reverse | vendor-doc | operational (M-ADR 0175). Empty when undeclared. Added in schema 2.20.0.
1261
+ - name: context
1262
+ type: string
1263
+ nullable: true
1264
+ description: Bounded-context membership from `capability.context` in the traceability manifest (per M-ADR 0170 §4.6) — completes the context dimension across screens/contracts/services/entities (2.19.0). Free-form adopter label, orthogonal to domain_id. Not an FK. Enables the screen↔capability context cross-check (convention finding, not FK). Empty when undeclared. Added in schema 2.21.0.
1265
+ - name: description
1266
+ type: string
1267
+ nullable: true
1268
+ - name: status
1269
+ type: string
1270
+ nullable: false
1271
+ description: "Capability LIFECYCLE phase — this column carries ONE axis and the reader may rely on that. active | planned | exploration | deprecated. Default 'active'. History, because the shape of the mistake is the useful part: the prior three-member set (active|planned|deprecated) could not express what estates authored, so 3.5.0 widened it to six on measured evidence — 44 of one estate's 78 manifests were outside it (exploration 26, placeholder 11, detailed-pre-lock 6, first-draft 1), each recurring value varying WITHIN a domain, which is the ruled discriminator for a genuine phase over an authoring convention. But 3.6.0 RETRACTED `placeholder` and `detailed-pre-lock`: per M-ADR 0201 §1 those are rungs on the SPEC-AUTHORING ladder (`placeholder | first-draft | detailed-pre-lock`, plus §4.1's `reverse-derived`), declared in each spec's own `**Status:**` header and gated there by the spec-lifecycle gate. Admitting them here made one column carry two orthogonal axes, so a reader could not tell whether `placeholder` described the capability or its document. **Where the other axis lives: the spec header. Do not re-import it here.** `exploration` stays and is NOT authoring vocabulary — it is absent from 0201's ladder, has M-ADR 0089's workflow and named gates behind it, and describes the capability rather than its spec; a capability declaring it must carry a populated `traceability.exploration` block, and one that does not is a loud contradiction (validate-traceability enforces this; measured 0 of 26 violations). ⚠ A rule this column deliberately does NOT carry: `placeholder`'s. The obvious one (no authored features) was MEASURED FALSE — 4 of 11 carried features, one of them 9 — and the deeper reason no rule fit is that `placeholder` was never making a claim about the capability at all. That unwritable rule was the first symptom of the axis error, before anyone had named it. ⚠ DELIBERATELY NOT BOUND via column_enums, and this is staged rather than permanent: binding carries hard-fail teeth, and at 3.5.0 one out-of-vocabulary row remains (forward estate, `first-draft`, n=1, referred to that estate; the reverse estate measures ZERO across 180 manifests). An out-of-vocabulary value is CARRIED, not emptied and not rejected, and is reported as a convention finding by validate-traceability — nullable stays false and no cell is ever emptied, so the empty-means-unauthored-or-rejected ambiguity of the products.synthesis_band / quality_scores.gate precedents does not arise here. Bind only once that count is ZERO at both estates; binding a set not proven to cover what estates author is how synthesis_band earned its deprecation. On drift and enforcement, stated with its confound rather than as a slogan: the enforced sibling `contracts.status` drifted 1.2% (2 of 172) while this unenforced field drifted 56% (44 of 78) at the SAME estate — but the other estate's copy of this same unenforced field drifted 0% of 180, so enforcement is not the only variable. The difference is authoring shape: the forward estate hand-authors per capability across 13 domains and explores vocabulary doing it, while the reverse estate's manifests come from one largely uniform extraction process. That uniformity is itself the phase-vs-convention discriminator firing — a value uniform across a whole estate is tracking the process that wrote it."
1272
+ - name: spec_path
1273
+ type: string
1274
+ nullable: true
1275
+ description: Path to capability spec file when one exists.
1276
+ - name: contract_provenance
1277
+ type: string
1278
+ nullable: true
1279
+ description: "How this capability's declared contract SET was produced, from `traceability.contracts.provenance`. hand-authored | reverse-extracted | generated — the vocabulary the method already ships for `authoring-mode`, reused deliberately so provenance has one vocabulary and not two. Empty means undeclared, and undeclared reads as `hand-authored` by convention. Added at 3.5.0. ⚠ STRICTLY ORTHOGONAL to the contract-set maturity ladder (`traceability.contracts.status`: planned | provisional | partial | complete | locked | none): provenance never constrains status and status never constrains provenance, and `reverse-extracted` + `complete` is the legitimate pair that motivated the field. Evidence: 2 reverse-estate manifests had written `reverse-extracted` INTO contracts.status, where it is invalid, because a complete reverse-derived contract surface had no way to say both true things at once and the author picked the provenance one. A rule here that constrained maturity would re-create exactly that defect. ⚠ Note the asymmetry this column exposes and does not fix: the maturity ladder it is orthogonal to has NO catalogue column at all — `traceability.contracts.status` is validator-enforced but uncatalogued, so it is queryable by no consumer. That is the authored-but-uncatalogued class (a block with no column has no automated reader, so nothing can notice when it is absent or wrong); this column is given one precisely so the provenance half does not join it. Giving the ladder a column is a candidate follow-on, not done here."
1280
+ - name: source
1281
+ type: string
1282
+ nullable: false
1283
+ description: capability-tree | product-map | capability-spec.
1284
+ - name: runway_classification
1285
+ type: string
1286
+ nullable: true
1287
+ description: Business | Enabler-Runway | Hybrid (forward declares; reverse nullable until backfilled).
1288
+ - name: data_subset
1289
+ type: string
1290
+ nullable: true
1291
+ description: Keying-axis marker for foundational-tier / synthesis-tier capabilities whose evidence is keyed by ownership boundary or data subset rather than app group. Populated from `capability.data_subset` in the traceability manifest. Empty for implementing-tier capabilities (those use app_group on per-evidence rows). See `docs/method/methods/reverse/rubrics/reverse-platform-evidence-quality.md` §`app_group:` → `data_subset:` rename. Added in schema 2.9.0.
1292
+ - name: slice_scope
1293
+ type: string
1294
+ nullable: true
1295
+ description: "Per-slice marker when one capability legitimately covers multiple app groups or data subsets (e.g. a compliance capability spanning several regulated-fleet sub-groups). Same capability_id may appear across multiple rows when sliced; row identity is then `(id, slice_scope)`. Empty when the capability is not sliced. Per-slice AC numbering convention: AC1-ACN unsuffixed for the first slice; subsequent slices use AC numbering suffixed by slice. See `docs/method/methods/reverse/rubrics/reverse-platform-evidence-quality.md` §`slice_scope:` and `docs/method/methods/capability-spec-template.md` Guideline 9. Added in schema 2.9.0."
1296
+ - name: source_sdd_id
1297
+ type: string
1298
+ nullable: true
1299
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1300
+ - name: platform_sdd_id
1301
+ type: string
1302
+ nullable: true
1303
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1304
+ foreign_keys:
1305
+ - column: domain_id
1306
+ references: domains.id
1307
+ nullable: false
1308
+ external_for_profiles:
1309
+ - application-product
1310
+ - integration-product
1311
+ - column: parent_capability_id
1312
+ references: capabilities.id
1313
+ nullable: true
1314
+ column_enums:
1315
+ source: enums.capability_source
1316
+ feature_groups:
1317
+ primary_key: id
1318
+ columns:
1319
+ - name: id
1320
+ type: string
1321
+ nullable: false
1322
+ description: "{product_id|capability_id}-group-{slug}[-{nested-slug}]."
1323
+ - name: name
1324
+ type: string
1325
+ nullable: false
1326
+ description: Display name from H2/H3 heading or authored.
1327
+ - name: product_id
1328
+ type: string
1329
+ nullable: true
1330
+ description: Owning product (when group is product-scoped).
1331
+ - name: capability_id
1332
+ type: string
1333
+ nullable: true
1334
+ description: Owning capability (when group is capability-scoped).
1335
+ - name: parent_group_id
1336
+ type: string
1337
+ nullable: true
1338
+ description: Self-reference for nested groups (H3 within H2).
1339
+ - name: description
1340
+ type: string
1341
+ nullable: true
1342
+ description: Authored description (when group has explicit metadata) or null when derived from heading only.
1343
+ - name: source
1344
+ type: string
1345
+ nullable: false
1346
+ description: feature-tree-h2 | feature-tree-h3 | feature-spec-explicit (when an authored feature spec declares group membership) | capability-spec-explicit.
1347
+ - name: source_sdd_id
1348
+ type: string
1349
+ nullable: true
1350
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1351
+ - name: platform_sdd_id
1352
+ type: string
1353
+ nullable: true
1354
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1355
+ description: |
1356
+ Hierarchical grouping for features. First-class entity per resolution of adopt-canonical-catalogue-builder.md §7.2 — replaces the previous reverse-only synthetic `feature-tree-group` rows in features.csv. Both forward and reverse can use feature_groups: forward application-product SDDs whose `feature-tree.md` has H2/H3 structure, reverse SDDs whose extracted feature trees are inherently hierarchical, and any SDD that promotes groups to first-class with authored metadata. Groups can nest via `parent_group_id`.
1357
+ foreign_keys:
1358
+ - column: product_id
1359
+ references: products.id
1360
+ nullable: true
1361
+ - column: capability_id
1362
+ references: capabilities.id
1363
+ nullable: true
1364
+ - column: parent_group_id
1365
+ references: feature_groups.id
1366
+ nullable: true
1367
+ features:
1368
+ primary_key: id
1369
+ columns:
1370
+ - name: id
1371
+ type: string
1372
+ nullable: false
1373
+ description: "{product_id|capability_id}-{feature-slug}."
1374
+ - name: name
1375
+ type: string
1376
+ nullable: false
1377
+ - name: product_id
1378
+ type: string
1379
+ nullable: true
1380
+ description: Owning product (null for capability-spec-sourced features).
1381
+ - name: capability_id
1382
+ type: string
1383
+ nullable: true
1384
+ - name: parent_group_id
1385
+ type: string
1386
+ nullable: true
1387
+ description: Owning feature_group (typical when feature comes from a hierarchical feature-tree.md). Use this OR parent_feature_id, not both.
1388
+ - name: parent_feature_id
1389
+ type: string
1390
+ nullable: true
1391
+ description: Self-reference for explicit feature nesting (rare — most hierarchies are group-based via parent_group_id).
1392
+ - name: description
1393
+ type: string
1394
+ nullable: true
1395
+ - name: maturity
1396
+ type: string
1397
+ nullable: true
1398
+ description: "Standard: working | provisional | unknown | absent. Ecosystem-specific values may be added with parser awareness."
1399
+ - name: status
1400
+ type: string
1401
+ nullable: false
1402
+ description: Default 'active'.
1403
+ - name: source
1404
+ type: string
1405
+ nullable: false
1406
+ description: "feature-tree | feature-set | capability-spec | feature-spec | feature-grounding. NOTE: feature-tree-group source removed in 1.3.0 — groups are now first-class in feature_groups.csv. As of schema 2.2.0, source: feature-tree is emitted by the canonical builder for rows derived from feature-tree.md bullets. As of schema 2.5.0, source: feature-grounding is emitted for rows derived from `docs/domains/<dom>/design/<capability>/feature-grounding.md` markdown tables (per M-ADR 0143). As of schema 2.7.0, source: capability-spec is emitted by the canonical builder for rows derived from `## Feature Grounding (code-path trace)` tables in `docs/domains/<dom>/product/<capability>.md` capability spec markdown (per M-ADR 0145). Feature-grounding and capability-spec rows are both capability-owned: product_id is empty; capability_id resolves from the file path."
1407
+ - name: runway
1408
+ type: string
1409
+ nullable: true
1410
+ description: Optional adopter-owned lifecycle / migration marker. Free string at method level — the schema declares no enum and ships no controlled vocabulary. Adopters MAY declare a per-SDD `feature-runway-vocabulary.yaml` at their SDD root; when present, the canonical builder validates captured values against it and emits a `convention` finding for unknown values. Empty when the adopter does not track migration state. Comparability across SDDs requires ecosystem-level vocabulary alignment as an explicit pre-step. Added in schema 2.2.0.
1411
+ - name: source_sdd_id
1412
+ type: string
1413
+ nullable: true
1414
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1415
+ - name: platform_sdd_id
1416
+ type: string
1417
+ nullable: true
1418
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1419
+ foreign_keys:
1420
+ - column: product_id
1421
+ references: products.id
1422
+ nullable: true
1423
+ - column: capability_id
1424
+ references: capabilities.id
1425
+ nullable: true
1426
+ - column: parent_group_id
1427
+ references: feature_groups.id
1428
+ nullable: true
1429
+ - column: parent_feature_id
1430
+ references: features.id
1431
+ nullable: true
1432
+ column_enums:
1433
+ source: enums.feature_source
1434
+ maturity: enums.artefact_maturity
1435
+ personas:
1436
+ primary_key: id
1437
+ columns:
1438
+ - name: id
1439
+ type: string
1440
+ nullable: false
1441
+ description: "{product_id}-{persona-slug}."
1442
+ - name: name
1443
+ type: string
1444
+ nullable: false
1445
+ - name: product_id
1446
+ type: string
1447
+ nullable: false
1448
+ - name: role
1449
+ type: string
1450
+ nullable: true
1451
+ - name: description
1452
+ type: string
1453
+ nullable: true
1454
+ - name: source_sdd_id
1455
+ type: string
1456
+ nullable: true
1457
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1458
+ - name: platform_sdd_id
1459
+ type: string
1460
+ nullable: true
1461
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1462
+ foreign_keys:
1463
+ - column: product_id
1464
+ references: products.id
1465
+ nullable: false
1466
+ user_journeys:
1467
+ primary_key: id
1468
+ columns:
1469
+ - name: id
1470
+ type: string
1471
+ nullable: false
1472
+ description: "{product_id}-{journey-slug}."
1473
+ - name: name
1474
+ type: string
1475
+ nullable: false
1476
+ - name: product_id
1477
+ type: string
1478
+ nullable: false
1479
+ - name: primary_persona
1480
+ type: string
1481
+ nullable: true
1482
+ description: Free-text. Supports 'X → Y (handoff)'.
1483
+ - name: supporting_personas
1484
+ type: string
1485
+ nullable: true
1486
+ - name: trigger
1487
+ type: string
1488
+ nullable: true
1489
+ - name: goal
1490
+ type: string
1491
+ nullable: true
1492
+ - name: source_sdd_id
1493
+ type: string
1494
+ nullable: true
1495
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1496
+ - name: platform_sdd_id
1497
+ type: string
1498
+ nullable: true
1499
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1500
+ foreign_keys:
1501
+ - column: product_id
1502
+ references: products.id
1503
+ nullable: false
1504
+ contracts:
1505
+ primary_key: id
1506
+ columns:
1507
+ - name: id
1508
+ type: string
1509
+ nullable: false
1510
+ 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."
1511
+ - name: name
1512
+ type: string
1513
+ nullable: false
1514
+ description: Display name from info.title or artifact_id.
1515
+ - name: service_id
1516
+ type: string
1517
+ nullable: true
1518
+ description: Exposing service; resolved via primary_repo_id ↔ OpenAPI x-source-repo.
1519
+ - name: source_repo_id
1520
+ type: string
1521
+ nullable: true
1522
+ description: Repo owning the contract source. Distinct from exposing service's repo per M-ADR 0110 (sibling-repo pattern).
1523
+ - name: kind
1524
+ type: string
1525
+ nullable: false
1526
+ description: rest | graphql | rpc | event | authz. rpc covers Proto/gRPC; event covers Avro schemas; authz covers authorization/policy schemas (SpiceDB .zed and equivalents), added because an adopter contract lock-in gate certified .zed schemas as contracts while no kind could represent them.
1527
+ - name: version
1528
+ type: string
1529
+ nullable: true
1530
+ - name: status
1531
+ type: string
1532
+ nullable: false
1533
+ description: active | deprecated. Default 'active'. As of 2.22.0 the builder wires 'deprecated' from BASELINE.md deprecation-runway entries (contracts.{openapi|proto|avro}[].status, matched on path == spec_path; per M-ADR 0073 §4.8) when a BASELINE.md exists at the SDD root.
1534
+ - name: spec_path
1535
+ type: string
1536
+ nullable: true
1537
+ - name: visibility
1538
+ type: string
1539
+ nullable: true
1540
+ description: public | private | internal.
1541
+ - name: context
1542
+ type: string
1543
+ nullable: true
1544
+ description: Bounded-context membership from OpenAPI `info.x-context` (per M-ADR 0170 §4.6). Free-form adopter label, orthogonal to the contract's domain folder. Not an FK. Empty when untagged. Added in schema 2.19.0.
1545
+ - name: evidence_class
1546
+ type: string
1547
+ nullable: true
1548
+ description: Evidence class of the contract surface, from OpenAPI `info.x-evidence-class` (document root accepted as fallback, exactly like x-context). Free-form; conventional values code-reverse | vendor-doc | operational (M-ADR 0175). Empty when untagged. Added in schema 2.20.0.
1549
+ - name: description
1550
+ type: string
1551
+ nullable: true
1552
+ - name: discovery
1553
+ type: string
1554
+ nullable: true
1555
+ description: discovered | declared-external. `discovered` (default) means the builder walked the spec file and parsed it, so title/version/context/evidence_class are trustworthy. `declared-external` means the row exists ONLY because a capability traceability manifest declared it with an explicit external marker and the file was never read — so those columns are necessarily EMPTY and their emptiness carries no information. A consumer that cannot tell the two apart will treat a declaration as a validated contract. Added in schema 2.51.0 (D13).
1556
+ - name: source_sdd_id
1557
+ type: string
1558
+ nullable: true
1559
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1560
+ - name: platform_sdd_id
1561
+ type: string
1562
+ nullable: true
1563
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1564
+ foreign_keys:
1565
+ - column: service_id
1566
+ references: services.id
1567
+ nullable: true
1568
+ - column: source_repo_id
1569
+ references: repositories.id
1570
+ nullable: true
1571
+ column_enums:
1572
+ kind: enums.contract_kind
1573
+ status: enums.contract_status
1574
+ visibility: enums.contract_visibility
1575
+ discovery: enums.contract_discovery
1576
+ events:
1577
+ primary_key: id
1578
+ columns:
1579
+ - name: id
1580
+ type: string
1581
+ nullable: false
1582
+ - name: name
1583
+ type: string
1584
+ nullable: false
1585
+ - name: publisher_service_id
1586
+ type: string
1587
+ nullable: true
1588
+ - name: domain_id
1589
+ type: string
1590
+ nullable: true
1591
+ - name: transport
1592
+ type: string
1593
+ nullable: true
1594
+ description: "Open string per M-ADR 0156. Recommended values: kafka | sns | sqs | kinesis | eventbridge | mongodb-change-stream | nats | activemq | rabbitmq | jms | other. Values outside the recommended set emit [finding] convention."
1595
+ - name: schema_path
1596
+ type: string
1597
+ nullable: true
1598
+ description: "Path to event schema (Avro .avsc or JSON-Schema .json/.schema.json). Nullable — leave empty for loosely-typed events (e.g. ActiveMQ JMS, NATS with payload_schema: {type: object}). Per M-ADR 0156."
1599
+ - name: version
1600
+ type: string
1601
+ nullable: true
1602
+ - name: evidence_class
1603
+ type: string
1604
+ nullable: true
1605
+ description: Evidence class of the event claim, from the per-event `evidence_class` key (alias `evidence-class`) in event-catalog.yaml, falling back to a file-level `evidence_class`/`evidence-class` top-level key in the same catalog YAML. Free-form; conventional values code-reverse | vendor-doc | operational (M-ADR 0175). Empty for avsc-only events and when undeclared. Added in schema 2.20.0.
1606
+ - name: source_sdd_id
1607
+ type: string
1608
+ nullable: true
1609
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1610
+ - name: platform_sdd_id
1611
+ type: string
1612
+ nullable: true
1613
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1614
+ description: "Asynchronous messages. Cross-domain events (e.g. shared envelopes) leave domain_id empty. Per M-ADR 0156 (multi-source ingestion, schema 2.12.0): forward-method canonical source is `contracts/avro/*.avsc` files; reverse-method canonical source is `docs/domains/{domain}/contracts/events/event-catalog.yaml`. YAML wins on name/domain/publisher/transport/consumers; avsc augments schema_path/version. Both paths run and merge by id slug."
1615
+ foreign_keys:
1616
+ - column: publisher_service_id
1617
+ references: services.id
1618
+ nullable: true
1619
+ - column: domain_id
1620
+ references: domains.id
1621
+ nullable: true
1622
+ c4_systems:
1623
+ primary_key: id
1624
+ columns:
1625
+ - name: id
1626
+ type: string
1627
+ nullable: false
1628
+ description: Typically {product_id}-system.
1629
+ - name: name
1630
+ type: string
1631
+ nullable: false
1632
+ - name: product_id
1633
+ type: string
1634
+ nullable: true
1635
+ description: "Owning product, when the system corresponds to one. Nullable: every product is a system, but not every system is a product (external/SaaS systems have no owning product). Architectural products only (per category taxonomy). Relaxed to nullable in schema 2.11.0."
1636
+ - name: kind
1637
+ type: string
1638
+ nullable: false
1639
+ description: platform | subsystem | application | integration. Derived 1:1 from manifest.category — see enums.c4_system_kind.
1640
+ - name: diagram_path
1641
+ type: string
1642
+ nullable: true
1643
+ description: Path to L1 mermaid/markdown. Nullable — row exists for any architectural Product even if no L1 diagram has been authored yet (visible coverage gap).
1644
+ - name: description
1645
+ type: string
1646
+ nullable: true
1647
+ - name: source_sdd_id
1648
+ type: string
1649
+ nullable: true
1650
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1651
+ - name: platform_sdd_id
1652
+ type: string
1653
+ nullable: true
1654
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1655
+ foreign_keys:
1656
+ - column: product_id
1657
+ references: products.id
1658
+ nullable: true
1659
+ column_enums:
1660
+ kind: enums.c4_system_kind
1661
+ c4_containers:
1662
+ primary_key: id
1663
+ columns:
1664
+ - name: id
1665
+ type: string
1666
+ nullable: false
1667
+ description: "{system_id}-{container-slug}."
1668
+ - name: name
1669
+ type: string
1670
+ nullable: false
1671
+ - name: system_id
1672
+ type: string
1673
+ nullable: false
1674
+ description: Owning C4 system (every container is in exactly one system).
1675
+ - name: domain_id
1676
+ type: string
1677
+ nullable: true
1678
+ description: Optional organisational domain tag (denormalised; not C4-structural).
1679
+ - name: service_id
1680
+ type: string
1681
+ nullable: true
1682
+ description: Matched by container name ↔ service name/repo where possible.
1683
+ - name: type
1684
+ type: string
1685
+ nullable: true
1686
+ 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."
1687
+ - name: technology
1688
+ type: string
1689
+ nullable: true
1690
+ - name: description
1691
+ type: string
1692
+ nullable: true
1693
+ - name: source_sdd_id
1694
+ type: string
1695
+ nullable: true
1696
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1697
+ - name: platform_sdd_id
1698
+ type: string
1699
+ nullable: true
1700
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1701
+ description: |
1702
+ C4 L2. Each container belongs to exactly one C4 system. `domain_id` is a denormalised organisational tag, not a C4-structural attribute — multi-domain ecosystems use it for filtering/reporting. `service_id` is the optional "may represent" link to a runtime service when the container is a deployable application.
1703
+ foreign_keys:
1704
+ - column: system_id
1705
+ references: c4_systems.id
1706
+ nullable: false
1707
+ - column: domain_id
1708
+ references: domains.id
1709
+ nullable: true
1710
+ - column: service_id
1711
+ references: services.id
1712
+ nullable: true
1713
+ column_enums:
1714
+ type: enums.c4_container_type
1715
+ c4_components:
1716
+ primary_key: id
1717
+ columns:
1718
+ - name: id
1719
+ type: string
1720
+ nullable: false
1721
+ description: "{container_id}-{component-slug}."
1722
+ - name: name
1723
+ type: string
1724
+ nullable: false
1725
+ - name: container_id
1726
+ type: string
1727
+ nullable: false
1728
+ description: Owning C4 container.
1729
+ - name: service_id
1730
+ type: string
1731
+ nullable: true
1732
+ description: "Denormalised: the service the parent container represents, when applicable."
1733
+ - name: path
1734
+ type: string
1735
+ nullable: true
1736
+ - name: responsibility
1737
+ type: string
1738
+ nullable: true
1739
+ - name: source_sdd_id
1740
+ type: string
1741
+ nullable: true
1742
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1743
+ - name: platform_sdd_id
1744
+ type: string
1745
+ nullable: true
1746
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1747
+ description: |
1748
+ C4 L3. Each component belongs to exactly one C4 container. `service_id` is denormalised from `c4_containers.service_id` for query convenience — populated when the parent container represents a runtime service.
1749
+ foreign_keys:
1750
+ - column: container_id
1751
+ references: c4_containers.id
1752
+ nullable: false
1753
+ - column: service_id
1754
+ references: services.id
1755
+ nullable: true
1756
+ c4_external_systems:
1757
+ primary_key: id
1758
+ columns:
1759
+ - name: id
1760
+ type: string
1761
+ nullable: false
1762
+ 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).
1763
+ - name: name
1764
+ type: string
1765
+ nullable: false
1766
+ description: Display name from the System_Ext label.
1767
+ - name: technology
1768
+ type: string
1769
+ nullable: true
1770
+ description: Optional stack/protocol hint.
1771
+ - name: description
1772
+ type: string
1773
+ nullable: true
1774
+ description: What the external system provides.
1775
+ - name: declared_id
1776
+ type: string
1777
+ nullable: true
1778
+ 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.
1779
+ - name: source_scope
1780
+ type: string
1781
+ nullable: true
1782
+ 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."
1783
+ - name: source_sdd_id
1784
+ type: string
1785
+ nullable: true
1786
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1787
+ - name: platform_sdd_id
1788
+ type: string
1789
+ nullable: true
1790
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1791
+ description: |
1792
+ C4 external software systems — peer systems at the L1 context level that the ecosystem integrates with but does not own (per M-ADR 0155). Rendered `System_Ext(...)` on L1/L2 diagrams. NOT a c4_container (external systems are not inside your system) and NOT a c4_system (they have no owning Product). External systems are inherently shared references: the same external system may be declared by multiple SDDs, so the aggregator dedups identical rows by PK rather than failing on duplicate (the one narrowly-scoped exception to M-ADR 0134's duplicate-PK rule); conflicting attributes on the same id surface as a `convention` finding.
1793
+ repositories:
1794
+ primary_key: id
1795
+ columns:
1796
+ - name: id
1797
+ type: string
1798
+ nullable: false
1799
+ description: canonical_repo_key.
1800
+ - name: name
1801
+ type: string
1802
+ nullable: false
1803
+ - name: domain_id
1804
+ type: string
1805
+ nullable: true
1806
+ description: Owning capability domain. Populated when the repo-config declared domain resolves to a docs/domains/<slug>/ in the local SDD; left empty otherwise per M-ADR 0136.
1807
+ - name: product_id
1808
+ type: string
1809
+ nullable: true
1810
+ - name: profile
1811
+ type: string
1812
+ nullable: false
1813
+ description: "DEPRECATED (removal at 4.0.0): not an SDD profile. The per-repo field reused sdd_profile's values to record only whether a mirrored repository is one of the SDD's own components or a supporting one — see repo_scope (M-ADR 0213)."
1814
+ - name: group
1815
+ type: string
1816
+ nullable: true
1817
+ - name: category
1818
+ type: string
1819
+ nullable: true
1820
+ - name: tier
1821
+ type: string
1822
+ nullable: true
1823
+ description: S1..S4 for support repos, else null.
1824
+ - name: component_type
1825
+ type: string
1826
+ nullable: true
1827
+ - name: files
1828
+ type: int
1829
+ nullable: true
1830
+ - name: code
1831
+ type: int
1832
+ nullable: true
1833
+ - name: comment
1834
+ type: int
1835
+ nullable: true
1836
+ - name: blank
1837
+ type: int
1838
+ nullable: true
1839
+ - name: total_lines
1840
+ type: int
1841
+ nullable: true
1842
+ - name: languages
1843
+ type: string
1844
+ nullable: true
1845
+ description: "';'-separated."
1846
+ - name: doc_path
1847
+ type: string
1848
+ nullable: false
1849
+ - name: source_sdd_id
1850
+ type: string
1851
+ nullable: true
1852
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1853
+ - name: platform_sdd_id
1854
+ type: string
1855
+ nullable: true
1856
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1857
+ - name: repo_scope
1858
+ type: string
1859
+ nullable: true
1860
+ description: "Whether the repository is inside the scope of what THIS SDD specifies, from its reverse-metadata.yaml (M-ADR 0213 §4.2): component (part of what the SDD specifies) or support (supports a component without being one). Empty for a repository with no reverse metadata. Its kind is component_type; the SDD's profile is products/applications.profile."
1861
+ foreign_keys:
1862
+ - column: domain_id
1863
+ references: domains.id
1864
+ nullable: true
1865
+ - column: product_id
1866
+ references: products.id
1867
+ nullable: true
1868
+ column_enums:
1869
+ component_type: enums.service_type
1870
+ repo_scope: enums.repo_scope
1871
+ domain_models:
1872
+ primary_key: id
1873
+ columns:
1874
+ - name: id
1875
+ type: string
1876
+ nullable: false
1877
+ description: "{domain_id}-data-model."
1878
+ - name: name
1879
+ type: string
1880
+ nullable: false
1881
+ - name: domain_id
1882
+ type: string
1883
+ nullable: false
1884
+ - name: doc_path
1885
+ type: string
1886
+ nullable: false
1887
+ description: Path to data-model.mermaid.md.
1888
+ - name: version
1889
+ type: string
1890
+ nullable: true
1891
+ description: Optional explicit version; null until the domain model is formally versioned (typically at first contract lock-in).
1892
+ - name: evidence_class
1893
+ type: string
1894
+ nullable: true
1895
+ description: Evidence class of the domain model, from a leading ```yaml fence in the data-model markdown carrying `evidence-class:` (documentation-reverse anchor convention). Free-form; conventional values code-reverse | vendor-doc | operational (M-ADR 0175). Empty when undeclared. Added in schema 2.20.0.
1896
+ - name: source_sdd_id
1897
+ type: string
1898
+ nullable: true
1899
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1900
+ - name: platform_sdd_id
1901
+ type: string
1902
+ nullable: true
1903
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1904
+ - name: notation
1905
+ type: string
1906
+ nullable: true
1907
+ description: "The notation the model artefact is written in — one of enums.model_notation (mermaid-erd | typeql), DERIVED by the builder from the file (data-model.mermaid.md → mermaid-erd; data-model.tql → typeql), never authored. The compliance instrument of M-ADR 0210 §4.6 Decision 2 (as amended): a mermaid-erd row is advisory until the sunset 2027-03-31 and an error after it. Added in 3.11.0."
1908
+ description: "Per-domain ER diagram modelling the domain's aggregates, entities, and domain events. Platform-profile only — application and integration profiles emit headers-only. Forward source: `traceability.domain_model.path` in capability traceability manifests. Reverse source: file-system scan of `docs/domains/*/architecture/data-model.mermaid.md`. Added in schema 2.4.0; see M-ADR 0142."
1909
+ foreign_keys:
1910
+ - column: domain_id
1911
+ references: domains.id
1912
+ nullable: false
1913
+ column_enums:
1914
+ notation: enums.model_notation
1915
+ entities:
1916
+ primary_key: id
1917
+ columns:
1918
+ - name: id
1919
+ type: string
1920
+ nullable: false
1921
+ description: "Slugged PK: {domain_id}-{entitySlug(name)}. For manifest-sourced rows with domain=platform-wide, the leading domain segment is empty (`-{entitySlug(name)}`) and the row carries a [finding] convention."
1922
+ - name: name
1923
+ type: string
1924
+ nullable: false
1925
+ description: Entity name as authored. Preserves the original case/style (UPPER_SNAKE_CASE, PascalCase, lowercase camelCase all observed in the wild).
1926
+ - name: domain_id
1927
+ type: string
1928
+ nullable: true
1929
+ description: Owning domain. Nullable when the source is a non-canonical domain hint such as `platform-wide`; the walker emits a finding in that case.
1930
+ - name: source_domain_model_id
1931
+ type: string
1932
+ nullable: true
1933
+ description: FK to domain_models.csv — the file the entity was extracted from. Populated by the reverse-method walker (Mermaid parse); empty when authored only via the forward-method manifest.
1934
+ - name: persistence_kind
1935
+ type: string
1936
+ nullable: true
1937
+ description: "Open string; recommended values: relational-table | document-collection | event-payload | dto | view | other. Values outside the recommended set fire `[finding] convention`."
1938
+ - name: context
1939
+ type: string
1940
+ nullable: true
1941
+ description: Bounded-context membership (per M-ADR 0170 §4.6). Free-form adopter label, orthogonal to domain_id. Not an FK. Carried for forward-parity; awaits a derivation source (Mermaid ER has no per-entity slot — populate via a sidecar classification or owning-service derivation). Added in schema 2.19.0.
1942
+ - name: glossary_term
1943
+ type: string
1944
+ nullable: true
1945
+ description: FK to glossary_items.id when the entity name resolves to a canonical glossary term (by entity-aware slug). Drives entity_glossary edge emission.
1946
+ - name: notes
1947
+ type: string
1948
+ nullable: true
1949
+ description: Free-form notes preserved from the authoring source. Carries `status=...`, `superseded_by=...`, and column count for diagnostic value.
1950
+ - name: evidence_class
1951
+ type: string
1952
+ nullable: true
1953
+ description: Evidence class inherited from the owning domain model's file-level declaration (the leading ```yaml fence's `evidence-class:` in data-model markdown). Free-form; conventional values code-reverse | vendor-doc | operational (M-ADR 0175). Empty when the source file declares none, and for manifest-sourced rows (the glossary-alignment manifest has no evidence slot). Added in schema 2.20.0.
1954
+ - name: source_sdd_id
1955
+ type: string
1956
+ nullable: true
1957
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
1958
+ - name: platform_sdd_id
1959
+ type: string
1960
+ nullable: true
1961
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
1962
+ description: "Data-model entity (a structural realisation of a concept inside a domain's data model). Distinct from glossary_items (vocabulary-level) and from domain_models (file-level). Added in schema 2.13.0 per M-ADR 0159. Forward source: `models[].entities[]` in glossary-alignment-manifest.yaml. Reverse source: `EntityName { ... }` declarations inside `erDiagram` fences in `docs/domains/{domain}/architecture/data-model.mermaid.md`. PK uses an entity-aware slug that normalises across UPPER_SNAKE and PascalCase authoring styles."
1963
+ foreign_keys:
1964
+ - column: domain_id
1965
+ references: domains.id
1966
+ nullable: true
1967
+ - column: source_domain_model_id
1968
+ references: domain_models.id
1969
+ nullable: true
1970
+ - column: glossary_term
1971
+ references: glossary_items.id
1972
+ nullable: true
1973
+ column_enums:
1974
+ persistence_kind: enums.persistence_kind
1975
+ repo_capability:
1976
+ primary_key: id
1977
+ columns:
1978
+ - name: id
1979
+ type: string
1980
+ nullable: false
1981
+ - name: repo_id
1982
+ type: string
1983
+ nullable: false
1984
+ - name: capability_id
1985
+ type: string
1986
+ nullable: false
1987
+ description: "Edge: repo contributes to capability. Forward-declared via repo-config `capabilities[]` (M-ADR 0188 §6.1) or the legacy multi-purpose `additional_context[]`; reverse-derived via capability_service ⋈ services.primary_repo_id and capability_feature ⋈ feature_repo."
1988
+ foreign_keys:
1989
+ - column: repo_id
1990
+ references: repositories.id
1991
+ nullable: false
1992
+ - column: capability_id
1993
+ references: capabilities.id
1994
+ nullable: false
1995
+ repo_capability_exemption:
1996
+ primary_key: id
1997
+ columns:
1998
+ - name: id
1999
+ type: string
2000
+ nullable: false
2001
+ - name: repo_id
2002
+ type: string
2003
+ nullable: false
2004
+ - name: reason
2005
+ type: string
2006
+ nullable: false
2007
+ - name: note
2008
+ type: string
2009
+ nullable: false
2010
+ description: Mandatory, non-empty. The reason code makes exemptions countable; the note makes them reviewable. A row with an empty note is dropped with a `convention` finding.
2011
+ description: |
2012
+ A repository's declared, reasoned statement that it bears no product capability (M-ADR 0188 §4.3). Emitted from the repo-config `capability_exemption:` block.
2013
+ This is deliberately a catalogue row rather than an inert YAML aside. An exemption is a modelling assertion and belongs in the model: it is then queryable at the aggregate tier, reviewable in the same surface as the capabilities it stands in for, and countable — so that a reviewer watching the exemption population grow can see it happen. Never net exemptions off against orphans in a metric.
2014
+ The invariant it participates in (M-ADR 0188 §4.1): every `repositories` row must resolve, either by carrying a `repo_capability` edge or by declaring an exemption here. A row satisfying both is a declaration conflict, reported as a `divergence` finding.
2015
+ foreign_keys:
2016
+ - column: repo_id
2017
+ references: repositories.id
2018
+ nullable: false
2019
+ column_enums:
2020
+ reason: enums.capability_exemption_reason
2021
+ service_capability_exemption:
2022
+ primary_key: id
2023
+ columns:
2024
+ - name: id
2025
+ type: string
2026
+ nullable: false
2027
+ - name: service_id
2028
+ type: string
2029
+ nullable: false
2030
+ - name: reason
2031
+ type: string
2032
+ nullable: false
2033
+ - name: note
2034
+ type: string
2035
+ nullable: false
2036
+ description: Mandatory, non-empty. The reason code makes exemptions countable; the note makes them reviewable. A row with an empty note is dropped with a `convention` finding.
2037
+ description: |
2038
+ A service's declared, reasoned statement that it bears no product capability (M-ADR 0133 §4.2b). The services-tier equivalent of `repo_capability_exemption`, one tier down: `repo_capability_exemption` exists because M-ADR 0197 gave a repository a `services:` block, so a repository resolving under M-ADR 0188 no longer implies its services do. Emitted from the repo-config `service_capability_exemption:` block, keyed to the repo's own default/primary service id — a declared, non-primary `services:` entry has no per-entry authoring surface yet (M-ADR 0197 §4.7, design-only) and cannot be exempted through this block.
2039
+ Two reasons only (`enums.service_capability_exemption_reason`): `platform-internal` and `deprecated`. Narrower than the repository vocabulary by design — a service, by definition, already runs something, so the repository-tier packaging/tooling/provenance distinctions don't reproduce here.
2040
+ The invariant it participates in: every catalogued `services` row must resolve, either by carrying a `capability_service` edge or by declaring an exemption here — checked by a coverage predicate whose verdict set is tier-scoped (member tier cannot assert an unclaimed service is genuinely orphaned, only that it is unresolved locally; a cross-SDD claim on the service may exist in a sibling SDD's own capability_service.csv, invisible to this SDD's own build).
2041
+ foreign_keys:
2042
+ - column: service_id
2043
+ references: services.id
2044
+ nullable: false
2045
+ column_enums:
2046
+ reason: enums.service_capability_exemption_reason
2047
+ external_system_exemption:
2048
+ primary_key: id
2049
+ columns:
2050
+ - name: id
2051
+ type: string
2052
+ nullable: false
2053
+ description: Equals external_system_id (one assertion per candidate).
2054
+ - name: external_system_id
2055
+ type: string
2056
+ nullable: false
2057
+ - name: reason
2058
+ type: string
2059
+ nullable: false
2060
+ - name: note
2061
+ type: string
2062
+ nullable: false
2063
+ description: Mandatory, non-empty. The reason makes exemptions countable; the note makes them reviewable (M-ADR 0188 §4.2 pattern).
2064
+ description: |
2065
+ A declared, reasoned assertion that an external-system candidate is GENUINELY external (M-ADR 0189 §4.6 / WS15). Annotation catalogue (M-ADR 0133 §4.2b): one FK, declared never derived, closed reason enum. Sourced from `orchestration/external-system-exemptions.yaml`.
2066
+ The invariant it completes: c4_external_systems was the one catalogue family with no coverage predicate — a candidate producing no adjudication outcome was silent, and that silence hid a 28% dependency -graph distortion (ledger L4). Every candidate now either resolves at adjudication, or carries an exemption here, or is reported unverified. An exemption retires only the unverified finding — never an adjudication outcome (a converted candidate's exemption is a contradiction, reported and dropped). Shared entities may be exempted by multiple SDDs: identical rows dedup at aggregation (same exception class as c4_external_systems); conflicting rows keep first-seen with a convention finding.
2067
+ foreign_keys:
2068
+ - column: external_system_id
2069
+ references: c4_external_systems.id
2070
+ nullable: false
2071
+ column_enums:
2072
+ reason: enums.external_system_exemption_reason
2073
+ repo_contract:
2074
+ primary_key: id
2075
+ columns:
2076
+ - name: id
2077
+ type: string
2078
+ nullable: false
2079
+ - name: repo_id
2080
+ type: string
2081
+ nullable: false
2082
+ - name: contract_id
2083
+ type: string
2084
+ nullable: false
2085
+ description: "Edge: repo is bound to a contract — implements or consumes; the source (contributes_to.artifact_type=contract-surface) does not distinguish, so this description asserts no direction (M-ADR 0211 §1). From contributes_to.artifact_type=contract-surface. Per M-ADR 0147 service-architecture external interfaces are a contract-consumes source; contract_id is external_for_profiles app/integration because their repos reference platform-resident (or platform-held BFF) contracts — resolved at aggregation, staying internal for platform-profile."
2086
+ foreign_keys:
2087
+ - column: repo_id
2088
+ references: repositories.id
2089
+ nullable: false
2090
+ - column: contract_id
2091
+ references: contracts.id
2092
+ nullable: false
2093
+ external_for_profiles:
2094
+ - application-product
2095
+ - integration-product
2096
+ product_capability:
2097
+ primary_key: id
2098
+ columns:
2099
+ - name: id
2100
+ type: string
2101
+ nullable: false
2102
+ - name: product_id
2103
+ type: string
2104
+ nullable: false
2105
+ - name: capability_id
2106
+ type: string
2107
+ nullable: false
2108
+ - name: role
2109
+ type: string
2110
+ nullable: false
2111
+ description: consumes.
2112
+ - name: notes
2113
+ type: string
2114
+ nullable: true
2115
+ description: "Edge: product depends on / consumes capability. Forward sources from app-platform-dependencies.yaml. capability_id is external because the consuming product (an application-product SDD) references a capability owned by the platform SDD."
2116
+ foreign_keys:
2117
+ - column: product_id
2118
+ references: products.id
2119
+ nullable: false
2120
+ - column: capability_id
2121
+ references: capabilities.id
2122
+ nullable: false
2123
+ external: true
2124
+ column_enums:
2125
+ role: enums.consumption_role
2126
+ product_service:
2127
+ primary_key: id
2128
+ columns:
2129
+ - name: id
2130
+ type: string
2131
+ nullable: false
2132
+ - name: product_id
2133
+ type: string
2134
+ nullable: false
2135
+ - name: service_id
2136
+ type: string
2137
+ nullable: false
2138
+ - name: role
2139
+ type: string
2140
+ nullable: false
2141
+ description: consumes.
2142
+ - name: required_stability
2143
+ type: string
2144
+ nullable: true
2145
+ description: "provisional | locked | unknown. The consuming SDD's expectation of contract stability, carried verbatim from app-platform-dependencies.yaml. Not a bound enum: an out-of-vocabulary value is carried, not rejected, and is reported by validate-app-dependencies.sh."
2146
+ description: "Edge: product depends on / consumes service. Forward sources from app-platform-dependencies.yaml. service_id is external because the consuming product (an application-product SDD) references a service owned by the platform SDD."
2147
+ foreign_keys:
2148
+ - column: product_id
2149
+ references: products.id
2150
+ nullable: false
2151
+ - column: service_id
2152
+ references: services.id
2153
+ nullable: false
2154
+ external: true
2155
+ column_enums:
2156
+ role: enums.consumption_role
2157
+ required_stability: enums.required_stability
2158
+ service_contract:
2159
+ primary_key: id
2160
+ columns:
2161
+ - name: id
2162
+ type: string
2163
+ nullable: false
2164
+ description: "{service_id}__{contract_id}__{role}."
2165
+ - name: service_id
2166
+ type: string
2167
+ nullable: false
2168
+ - name: contract_id
2169
+ type: string
2170
+ nullable: false
2171
+ - name: role
2172
+ type: string
2173
+ nullable: false
2174
+ description: exposes | consumes.
2175
+ description: "Edge: service exposes or consumes contract. Both FKs are external (per M-ADR 0147): federated SDDs that walk per-repo service-architecture tables emit consumes rows where service_id resolves to the platform-root catalogue's services.csv (post-aggregation) and contract_id resolves to the platform-root contracts.csv. Internal builds (e.g. connect-mono) still optimistically validate locally. Schema 2.8.0."
2176
+ foreign_keys:
2177
+ - column: service_id
2178
+ references: services.id
2179
+ nullable: false
2180
+ external: true
2181
+ - column: contract_id
2182
+ references: contracts.id
2183
+ nullable: false
2184
+ external: true
2185
+ column_enums:
2186
+ role: enums.contract_participation
2187
+ service_event:
2188
+ primary_key: id
2189
+ columns:
2190
+ - name: id
2191
+ type: string
2192
+ nullable: false
2193
+ description: "{service_id}__{event_id}__{role}."
2194
+ - name: service_id
2195
+ type: string
2196
+ nullable: false
2197
+ - name: event_id
2198
+ type: string
2199
+ nullable: false
2200
+ - name: role
2201
+ type: string
2202
+ nullable: false
2203
+ description: publishes | consumes.
2204
+ description: "Edge: service publishes or consumes event."
2205
+ foreign_keys:
2206
+ - column: service_id
2207
+ references: services.id
2208
+ nullable: false
2209
+ - column: event_id
2210
+ references: events.id
2211
+ nullable: false
2212
+ column_enums:
2213
+ role: enums.event_participation
2214
+ service_entity:
2215
+ primary_key: id
2216
+ columns:
2217
+ - name: id
2218
+ type: string
2219
+ nullable: false
2220
+ description: "Composite PK: {service_id}__{entity_id}__{relation}."
2221
+ - name: service_id
2222
+ type: string
2223
+ nullable: false
2224
+ - name: entity_id
2225
+ type: string
2226
+ nullable: false
2227
+ - name: relation
2228
+ type: string
2229
+ nullable: false
2230
+ description: "Open string; recommended values: owns | reads | writes | references. Data Store Mapping table source emits `owns`. Values outside the recommended set fire `[finding] convention`."
2231
+ - name: evidence_path
2232
+ type: string
2233
+ nullable: true
2234
+ description: Source markdown path or feature-grounding row that produced the edge. Audit aid.
2235
+ - name: source_sdd_id
2236
+ type: string
2237
+ nullable: true
2238
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
2239
+ - name: platform_sdd_id
2240
+ type: string
2241
+ nullable: true
2242
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
2243
+ description: "Edge: service touches data-model entity. Added in schema 2.13.0 per M-ADR 0159. Primary source: per-domain `## Data Store Mapping` markdown table in `docs/domains/{domain}/architecture/data-model.mermaid.md` (relation=owns). Optional forward source (Phase 5 deferred): `entities:` block in `orchestration/repo-config/<repo>.yaml`. Service names resolve via heuristic (slug-of-name; trailing-id-segment) with optional adopter-authored alias map at `docs/platform/reference/service-name-aliases.yaml`."
2244
+ foreign_keys:
2245
+ - column: service_id
2246
+ references: services.id
2247
+ nullable: false
2248
+ - column: entity_id
2249
+ references: entities.id
2250
+ nullable: false
2251
+ column_enums:
2252
+ relation: enums.service_entity_relation
2253
+ capability_feature:
2254
+ primary_key: id
2255
+ columns:
2256
+ - name: id
2257
+ type: string
2258
+ nullable: false
2259
+ - name: capability_id
2260
+ type: string
2261
+ nullable: false
2262
+ - name: feature_id
2263
+ type: string
2264
+ nullable: false
2265
+ description: "Edge: capability decomposes into features. Forward: traceability.runway.enables. Reverse: parsed from spec Feature Grounding."
2266
+ foreign_keys:
2267
+ - column: capability_id
2268
+ references: capabilities.id
2269
+ nullable: false
2270
+ - column: feature_id
2271
+ references: features.id
2272
+ nullable: false
2273
+ capability_service:
2274
+ primary_key: id
2275
+ columns:
2276
+ - name: id
2277
+ type: string
2278
+ nullable: false
2279
+ - name: capability_id
2280
+ type: string
2281
+ nullable: false
2282
+ - name: service_id
2283
+ type: string
2284
+ nullable: false
2285
+ - name: role
2286
+ type: string
2287
+ nullable: true
2288
+ description: "The part the service plays in delivering THIS capability — a property of the relationship, not of the service (capability-traceability-manifest-template). Closed enum, see enums.capability_service_role. Nullable: legacy rows may carry no role; the enum validator checks values, not presence. `dependency` rows are excluded from repo_capability Path X (M-ADR 0157 §4.3 as amended). Enum bound in 3.8.0."
2289
+ - name: contract_id
2290
+ type: string
2291
+ nullable: true
2292
+ description: "The contract this dependency is against — a contracts.id declared as `contract:` on the services[] entry (M-ADR 0211 §4.1). External FK on the pattern of feature_contract: resolved at aggregation. Empty when the entry declares none; a `dependency`-role entry that reaches T4 band 5 carries it."
2293
+ - name: interaction_pattern
2294
+ type: string
2295
+ nullable: true
2296
+ description: How the capability is coupled to the service at runtime — one of enums.interaction_pattern (M-ADR 0171 vocabulary, bound), from `interaction_pattern:` on the services[] entry. EMPTY for a non-runtime coupling (build-time, load-time, packaging, sequencing), whose kind the manifest states in dependency_notes; that entry is excluded by class from T4's dependency set and does not reach band 5.
2297
+ - name: qualifier
2298
+ type: string
2299
+ nullable: true
2300
+ description: Free-text qualifier on the interaction pattern per M-ADR 0171 §4.4 (e.g. idempotent, batched, cached, proxy, an auth scheme, a protocol version) — never a new pattern token. From `qualifier:` on the services[] entry.
2301
+ - name: evidence_ref
2302
+ type: string
2303
+ nullable: true
2304
+ description: Where the coupling is evidenced — a path or anchor in the SDD, from `evidence:` on the services[] entry. Prose about the coupling stays in dependency_notes; this is the pointer a reviewer follows.
2305
+ description: |
2306
+ Edge: capability is realised by services. Sourced from the capability traceability manifest services[] block. service_id is an external FK (schema 2.29.0, F4): a traceability entry marked `owner_sdd:` declares a cross-SDD reference (e.g. the service moved to a sibling SDD at an M-ADR 0170 §4.2 carve) — the per-SDD builder emits the edge, logs it `[finding] external`, and aggregation validates it hard against the owning sibling's rows. An UNMARKED id that does not resolve locally is NOT emitted — it stays a member-tier orphan finding (or convention, when it names a known external system).
2307
+ foreign_keys:
2308
+ - column: capability_id
2309
+ references: capabilities.id
2310
+ nullable: false
2311
+ - column: service_id
2312
+ references: services.id
2313
+ nullable: false
2314
+ external: true
2315
+ - column: contract_id
2316
+ references: contracts.id
2317
+ nullable: true
2318
+ external: true
2319
+ column_enums:
2320
+ role: enums.capability_service_role
2321
+ interaction_pattern: enums.interaction_pattern
2322
+ capability_event:
2323
+ primary_key: id
2324
+ columns:
2325
+ - name: id
2326
+ type: string
2327
+ nullable: false
2328
+ - name: capability_id
2329
+ type: string
2330
+ nullable: false
2331
+ - name: event_id
2332
+ type: string
2333
+ nullable: false
2334
+ - name: role
2335
+ type: string
2336
+ nullable: false
2337
+ description: publishes | consumes.
2338
+ - name: source
2339
+ type: string
2340
+ nullable: false
2341
+ description: authored | derived. `authored` rows come from a traceability declaration (shape A or shape B); `derived` rows come from `capability_service ⋈ service_event` and represent associative coupling, not ownership. Schema 2.14.0 per M-ADR 0160.
2342
+ description: "Edge: capability publishes or consumes event. Schema 2.14.0 (per M-ADR 0160) multi-source ingestion: (1) forward shape A — `traceability.events[{id, role}]` (legacy aspirational shape, unauthored across observed adopters); (2) forward shape B — `traceability.contracts.published_events[]` / `consumed_events[]` with `{event, status, notes}` (the observed forward-method shape; event name slug-resolves against events.csv); (3) derived — `capability_service ⋈ service_event` join (zero authoring; associative not authoritative). Authored rows win on PK conflict with derived. The `source` column distinguishes the two so governance queries can filter to authoritative ownership. The earlier `## Related Events` capability-spec heading is retired (no adopter authored it; the template never carried the section)."
2343
+ foreign_keys:
2344
+ - column: capability_id
2345
+ references: capabilities.id
2346
+ nullable: false
2347
+ - column: event_id
2348
+ references: events.id
2349
+ nullable: false
2350
+ column_enums:
2351
+ role: enums.event_participation
2352
+ source: enums.edge_source
2353
+ capability_contract:
2354
+ primary_key: id
2355
+ columns:
2356
+ - name: id
2357
+ type: string
2358
+ nullable: false
2359
+ - name: capability_id
2360
+ type: string
2361
+ nullable: false
2362
+ - name: contract_id
2363
+ type: string
2364
+ nullable: false
2365
+ - name: source
2366
+ type: string
2367
+ nullable: false
2368
+ 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."
2369
+ description: "Edge: capability is bound to a contract. Whether the capability exposes or depends on it is not stated by the source (traceability.contracts), so this description asserts no direction (M-ADR 0211 §1). Forward-declared only. 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."
2370
+ foreign_keys:
2371
+ - column: capability_id
2372
+ references: capabilities.id
2373
+ nullable: false
2374
+ - column: contract_id
2375
+ references: contracts.id
2376
+ nullable: false
2377
+ journey_feature:
2378
+ primary_key: id
2379
+ columns:
2380
+ - name: id
2381
+ type: string
2382
+ nullable: false
2383
+ - name: journey_id
2384
+ type: string
2385
+ nullable: false
2386
+ - name: feature_id
2387
+ type: string
2388
+ nullable: false
2389
+ description: "Edge: journey touches features. Parsed from Related features bullet."
2390
+ foreign_keys:
2391
+ - column: journey_id
2392
+ references: user_journeys.id
2393
+ nullable: false
2394
+ - column: feature_id
2395
+ references: features.id
2396
+ nullable: false
2397
+ persona_feature:
2398
+ primary_key: id
2399
+ columns:
2400
+ - name: id
2401
+ type: string
2402
+ nullable: false
2403
+ - name: persona_id
2404
+ type: string
2405
+ nullable: false
2406
+ - name: feature_id
2407
+ type: string
2408
+ nullable: false
2409
+ description: "Edge: persona uses features. Parsed from Related features bullet."
2410
+ foreign_keys:
2411
+ - column: persona_id
2412
+ references: personas.id
2413
+ nullable: false
2414
+ - column: feature_id
2415
+ references: features.id
2416
+ nullable: false
2417
+ feature_service:
2418
+ primary_key: id
2419
+ columns:
2420
+ - name: id
2421
+ type: string
2422
+ nullable: false
2423
+ - name: feature_id
2424
+ type: string
2425
+ nullable: false
2426
+ - name: service_id
2427
+ type: string
2428
+ nullable: false
2429
+ description: "Edge: feature is implemented by service. Parsed from Feature Services table in feature-tree.md."
2430
+ foreign_keys:
2431
+ - column: feature_id
2432
+ references: features.id
2433
+ nullable: false
2434
+ - column: service_id
2435
+ references: services.id
2436
+ nullable: false
2437
+ feature_event:
2438
+ primary_key: id
2439
+ columns:
2440
+ - name: id
2441
+ type: string
2442
+ nullable: false
2443
+ - name: feature_id
2444
+ type: string
2445
+ nullable: false
2446
+ - name: event_id
2447
+ type: string
2448
+ nullable: false
2449
+ - name: role
2450
+ type: string
2451
+ nullable: false
2452
+ description: publishes | consumes — mirrors the role on the source service_event row.
2453
+ - name: source
2454
+ type: string
2455
+ nullable: false
2456
+ description: Always `derived` (schema 2.15.0). The column is retained for symmetry with `capability_event.source` and to keep the door open for an authored shape if one surfaces; today every row is derived.
2457
+ description: "Edge: feature publishes or consumes event. Derived only — emitted from the `feature_service ⋈ service_event` join, mirroring M-ADR 0160's capability_event derived path one rung lower in the capability/feature/service hierarchy. Every row carries `source=derived`; there is no authored shape (the authored signal lives at the service level via `service_event`, which the feature inherits through `feature_service`). PK is `{feature_id}__{event_id}__{role}` so the same feature can carry both publishes + consumes rows for the same event without collision. Schema 2.15.0 per M-ADR 0161."
2458
+ foreign_keys:
2459
+ - column: feature_id
2460
+ references: features.id
2461
+ nullable: false
2462
+ - column: event_id
2463
+ references: events.id
2464
+ nullable: false
2465
+ column_enums:
2466
+ role: enums.event_participation
2467
+ feature_repo:
2468
+ primary_key: id
2469
+ columns:
2470
+ - name: id
2471
+ type: string
2472
+ nullable: false
2473
+ - name: feature_id
2474
+ type: string
2475
+ nullable: false
2476
+ - name: repo_id
2477
+ type: string
2478
+ nullable: false
2479
+ description: "Edge: feature is implemented in repo. From contributes_to.artifact_type=feature-set."
2480
+ foreign_keys:
2481
+ - column: feature_id
2482
+ references: features.id
2483
+ nullable: false
2484
+ - column: repo_id
2485
+ references: repositories.id
2486
+ nullable: false
2487
+ feature_contract:
2488
+ primary_key: id
2489
+ columns:
2490
+ - name: id
2491
+ type: string
2492
+ nullable: false
2493
+ description: "{feature_id}__{contract_id}."
2494
+ - name: feature_id
2495
+ type: string
2496
+ nullable: false
2497
+ - name: contract_id
2498
+ type: string
2499
+ nullable: false
2500
+ - name: derivation_path
2501
+ type: string
2502
+ nullable: true
2503
+ description: cap-feature-cap-contract | feature-service-service-contract. Diagnostic only — records which join path produced the row.
2504
+ description: "Edge: feature is exposed via contract. Derived — forward: capability_feature ⋈ capability_contract (on capability_id); reverse: feature_service ⋈ service_contract (on service_id). Both join paths are run and merged; duplicate (feature_id, contract_id) pairs are deduplicated. contract_id is external for app/integration profiles where contracts live in the platform SDD. Added in schema 2.3.0."
2505
+ foreign_keys:
2506
+ - column: feature_id
2507
+ references: features.id
2508
+ nullable: false
2509
+ - column: contract_id
2510
+ references: contracts.id
2511
+ nullable: false
2512
+ external: true
2513
+ column_enums:
2514
+ derivation_path: enums.feature_contract_derivation_path
2515
+ feature_subscription_channels:
2516
+ primary_key: id
2517
+ columns:
2518
+ - name: id
2519
+ type: string
2520
+ nullable: false
2521
+ description: "{feature_id}__{channel_name}."
2522
+ - name: feature_id
2523
+ type: string
2524
+ nullable: false
2525
+ - name: channel_name
2526
+ type: string
2527
+ nullable: false
2528
+ description: Channel identifier (kebab-case slug, namespaced as the source evidence carries it — e.g. `customer.<customerId>.tracking-points` for AppSync subscription channels).
2529
+ - name: transport
2530
+ type: string
2531
+ nullable: false
2532
+ description: "Delivery protocol: `appsync-websocket | pekko-ws | mqtt | sse | webhook-push | other`. The `other` value is escape-valve; adopters using it SHOULD record the actual transport in evidence."
2533
+ - name: evidence
2534
+ type: string
2535
+ nullable: true
2536
+ description: Evidence-file citation (`<sub-repo>/<path>:<line>`) anchoring the channel declaration. Mirrors the citation pattern used elsewhere in evidence yamls.
2537
+ - name: payload_ref
2538
+ type: string
2539
+ nullable: true
2540
+ description: Optional reference to a payload-contract event (`{event-name}` in the `events` catalogue) when the channel carries a contract-shaped payload. Empty when the payload is channel-private.
2541
+ - name: source_sdd_id
2542
+ type: string
2543
+ nullable: true
2544
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
2545
+ - name: platform_sdd_id
2546
+ type: string
2547
+ nullable: true
2548
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
2549
+ description: "Edge: feature delivers async push via a named channel/topic. Peer of `graphql_operations:` in the per-feature evidence shape — `graphql_operations:` carries the GraphQL operation names declared in the schema (Queries / Mutations / Subscriptions); `feature_subscription_channels` rows carry the channel/topic layer that physically delivers the push events (AppSync WebSocket endpoints, Pekko WS channels, MQTT topics, server-sent-event streams). Per resolved decision §1 of `content/plans/v0-9-0-cohort-sweep-derived-bundle.md`: a single GraphQL Subscription operation may listen on multiple channels; one channel may be consumed by multiple operations — modelling as a separate edge catalogue (not as a feature column) accommodates the many-to-many. Built per-SDD from `reverse-evidence/feature-grounding-evidence.yaml` `subscription_channels:` entries on each feature. Added in schema 2.9.0."
2550
+ foreign_keys:
2551
+ - column: feature_id
2552
+ references: features.id
2553
+ nullable: false
2554
+ column_enums:
2555
+ transport: enums.subscription_channel_transport
2556
+ capability_domain_model:
2557
+ primary_key: id
2558
+ columns:
2559
+ - name: id
2560
+ type: string
2561
+ nullable: false
2562
+ description: "{capability_id}__{domain_model_id}."
2563
+ - name: capability_id
2564
+ type: string
2565
+ nullable: false
2566
+ - name: domain_model_id
2567
+ type: string
2568
+ nullable: false
2569
+ - name: source
2570
+ type: string
2571
+ nullable: false
2572
+ description: traceability-manifest | inferred.
2573
+ description: "Edge: capability references a domain model. Forward: declared in `traceability.domain_model` field of the capability traceability manifest. Reverse: inferred via capability → domain → domain_model. Platform-profile only. Added in schema 2.4.0; see M-ADR 0142."
2574
+ foreign_keys:
2575
+ - column: capability_id
2576
+ references: capabilities.id
2577
+ nullable: false
2578
+ - column: domain_model_id
2579
+ references: domain_models.id
2580
+ nullable: false
2581
+ column_enums:
2582
+ source: enums.capability_domain_model_source
2583
+ feature_domain_model:
2584
+ primary_key: id
2585
+ columns:
2586
+ - name: id
2587
+ type: string
2588
+ nullable: false
2589
+ description: "{feature_id}__{domain_model_id}."
2590
+ - name: feature_id
2591
+ type: string
2592
+ nullable: false
2593
+ - name: domain_model_id
2594
+ type: string
2595
+ nullable: false
2596
+ - name: derivation_path
2597
+ type: string
2598
+ nullable: true
2599
+ description: cap-feature-cap-domain-model. Diagnostic only.
2600
+ description: "Edge: feature operates on a domain model. Derived from capability_feature ⋈ capability_domain_model (on capability_id). Platform-profile only. Orphan features (no capability link) get no row. Added in schema 2.4.0; see M-ADR 0142."
2601
+ foreign_keys:
2602
+ - column: feature_id
2603
+ references: features.id
2604
+ nullable: false
2605
+ - column: domain_model_id
2606
+ references: domain_models.id
2607
+ nullable: false
2608
+ persona_journey:
2609
+ primary_key: id
2610
+ columns:
2611
+ - name: id
2612
+ type: string
2613
+ nullable: false
2614
+ - name: persona_id
2615
+ type: string
2616
+ nullable: false
2617
+ - name: journey_id
2618
+ type: string
2619
+ nullable: false
2620
+ - name: role
2621
+ type: string
2622
+ nullable: false
2623
+ description: primary | handoff | supporting.
2624
+ description: "Edge: persona participates in journey. Roles: primary | handoff | supporting."
2625
+ foreign_keys:
2626
+ - column: persona_id
2627
+ references: personas.id
2628
+ nullable: false
2629
+ - column: journey_id
2630
+ references: user_journeys.id
2631
+ nullable: false
2632
+ column_enums:
2633
+ role: enums.journey_participation
2634
+ persona_c4system:
2635
+ primary_key: id
2636
+ columns:
2637
+ - name: id
2638
+ type: string
2639
+ nullable: false
2640
+ description: "{persona_id}__{c4_system_id}."
2641
+ - name: persona_id
2642
+ type: string
2643
+ nullable: false
2644
+ - name: c4_system_id
2645
+ type: string
2646
+ nullable: false
2647
+ - name: interaction
2648
+ type: string
2649
+ nullable: true
2650
+ description: Optional interaction label from the Rel(...) line, e.g. 'Web browser' / 'Mobile app'.
2651
+ description: "Edge: persona (C4 Person) uses a C4 system. Captures the L1 context 'Person uses System' relationship, extracted from Person(...) macros on the L1 context diagram and matched to personas rows. Per M-ADR 0155. Added in schema 2.10.0."
2652
+ foreign_keys:
2653
+ - column: persona_id
2654
+ references: personas.id
2655
+ nullable: false
2656
+ - column: c4_system_id
2657
+ references: c4_systems.id
2658
+ nullable: false
2659
+ persona_container:
2660
+ primary_key: id
2661
+ columns:
2662
+ - name: id
2663
+ type: string
2664
+ nullable: false
2665
+ description: "{persona_id}__{container_id}."
2666
+ - name: persona_id
2667
+ type: string
2668
+ nullable: false
2669
+ - name: container_id
2670
+ type: string
2671
+ nullable: false
2672
+ - name: interaction
2673
+ type: string
2674
+ nullable: true
2675
+ description: Optional interaction label from the Rel(...) line. May hold multiple '; '-joined labels (F25).
2676
+ description: |
2677
+ Edge: a persona uses a C4 container — the L2-granularity companion to persona_c4system (M-ADR 0189 F26 §3, ratified 2026-07-10). Eleven of one estate's L2 diagrams and the bulk of another's 81 unroutable Rels drew Person→Container relationships that had no catalogue and, until F26, no finding. Harvested at member tier from Rel(...) lines whose endpoints resolve to a file-local Person and a local container (either direction; the row is normalised persona→container). A Person that matches no persona row is a coverage finding, never a silent skip. Both authoring directions feed from the same diagram surface (M-ADR 0157 parity). Added in schema 2.34.0.
2678
+ foreign_keys:
2679
+ - column: persona_id
2680
+ references: personas.id
2681
+ nullable: false
2682
+ - column: container_id
2683
+ references: c4_containers.id
2684
+ nullable: false
2685
+ system_external_dependency:
2686
+ primary_key: id
2687
+ columns:
2688
+ - name: id
2689
+ type: string
2690
+ nullable: false
2691
+ description: "{c4_system_id}__{external_system_id}."
2692
+ - name: c4_system_id
2693
+ type: string
2694
+ nullable: false
2695
+ - name: external_system_id
2696
+ type: string
2697
+ nullable: false
2698
+ - name: interaction
2699
+ type: string
2700
+ nullable: true
2701
+ description: Optional integration label/protocol from the Rel(...) line. May hold multiple '; '-joined labels when one pair is declared with distinct labels (F25, 2.33.2).
2702
+ - name: from_container_id
2703
+ type: string
2704
+ nullable: true
2705
+ description: The Rel's non-external endpoint resolved to a local container at member tier, when it is one (F17, 2.33.0) — the datum that lets adjudication rewrite this edge onto container_dependency instead of destroying it. Empty when the endpoint is the system itself or unresolvable.
2706
+ description: "Edge: a C4 system integrates with an external software system. Captures the L1 context 'System integrates with External System' relationship, extracted from System_Ext(...) + Rel(...) on L1/L2 diagrams. Per M-ADR 0155. Container-level external dependencies are out of scope (system-level only). Added in schema 2.10.0. From 2.30.0 (M-ADR 0189 §4.4): edges whose external endpoint the aggregator adjudicates as an INTERNAL system are rewritten onto system_system_dependency and removed from this catalogue."
2707
+ foreign_keys:
2708
+ - column: c4_system_id
2709
+ references: c4_systems.id
2710
+ nullable: false
2711
+ - column: external_system_id
2712
+ references: c4_external_systems.id
2713
+ nullable: false
2714
+ - column: from_container_id
2715
+ references: c4_containers.id
2716
+ nullable: true
2717
+ container_dependency:
2718
+ primary_key: id
2719
+ columns:
2720
+ - name: id
2721
+ type: string
2722
+ nullable: false
2723
+ description: "{from_container_id}__{to_container_id}."
2724
+ - name: from_container_id
2725
+ type: string
2726
+ nullable: false
2727
+ - name: to_container_id
2728
+ type: string
2729
+ nullable: false
2730
+ - name: interaction
2731
+ type: string
2732
+ nullable: true
2733
+ description: Label carried over from the originating Rel(...) line.
2734
+ - name: source_sdd_id
2735
+ type: string
2736
+ nullable: true
2737
+ description: SDD whose diagram declared the originating reference. Member-emitted rows set it directly (F19); adjudication-derived rows are stamped by the aggregator.
2738
+ - name: platform_sdd_id
2739
+ type: string
2740
+ nullable: true
2741
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
2742
+ description: |
2743
+ Edge: a C4 container depends on another INTERNAL container (adopter finding F17 — F6 exactly one tier down: "no edge for internal" at L2). Derived by the aggregator at adjudication: an external-system candidate that resolves to an internal container was never external — each of its dependency edges whose member-resolved `from_container_id` is known is rewritten here, and a candidate with no remaining edges is dropped (it was a phantom duplicate of the container). A candidate with unconvertible edges is kept with the tier-contradiction finding, so no edge is ever destroyed to make a build quieter — the measured cost that stopped an adopter remediating 22 contradictions was eight real edges. ALSO emitted at member tier (F19, 2.33.1): the C4-correct authoring — Rel(container_a, container_b) between two Container(...) nodes — emits its edge directly; adjudication merges into a catalogue that already has content rather than being its only source, so the metamodel no longer rewards mis-declaration over correct authoring. Added in schema 2.33.0.
2744
+ foreign_keys:
2745
+ - column: from_container_id
2746
+ references: c4_containers.id
2747
+ nullable: false
2748
+ - column: to_container_id
2749
+ references: c4_containers.id
2750
+ nullable: false
2751
+ system_system_dependency:
2752
+ primary_key: id
2753
+ columns:
2754
+ - name: id
2755
+ type: string
2756
+ nullable: false
2757
+ description: "{from_system_id}__{to_system_id}."
2758
+ - name: from_system_id
2759
+ type: string
2760
+ nullable: false
2761
+ - name: to_system_id
2762
+ type: string
2763
+ nullable: false
2764
+ - name: interaction
2765
+ type: string
2766
+ nullable: true
2767
+ description: Optional label/protocol carried over from the originating Rel(...) line.
2768
+ - name: source_sdd_id
2769
+ type: string
2770
+ nullable: true
2771
+ description: SDD whose diagram declared the originating reference. Populated by the aggregator.
2772
+ - name: platform_sdd_id
2773
+ type: string
2774
+ nullable: true
2775
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
2776
+ description: |
2777
+ Edge: a C4 system depends on another INTERNAL system (M-ADR 0189 §4.3). Derived by the aggregator at adjudication (§4.4): an external-system candidate whose declared identity resolves to an internal system was never external — its Rel(...) dependency edges are rewritten onto this catalogue and the candidate row is dropped. Not emitted at member tier (a member cannot see sibling systems); headers-only there, like cross_sdd_platform_capability. Both authoring directions feed it from the same diagram surface (M-ADR 0157 parity). Added in schema 2.30.0.
2778
+ foreign_keys:
2779
+ - column: from_system_id
2780
+ references: c4_systems.id
2781
+ nullable: false
2782
+ - column: to_system_id
2783
+ references: c4_systems.id
2784
+ nullable: false
2785
+ c4_container_entity:
2786
+ primary_key: id
2787
+ columns:
2788
+ - name: id
2789
+ type: string
2790
+ nullable: false
2791
+ description: "Composite PK: {container_id}__{entity_id}."
2792
+ - name: container_id
2793
+ type: string
2794
+ nullable: false
2795
+ - name: entity_id
2796
+ type: string
2797
+ nullable: false
2798
+ - name: relation
2799
+ type: string
2800
+ nullable: false
2801
+ description: Inherits from upstream service_entity.relation when derived.
2802
+ - name: source_sdd_id
2803
+ type: string
2804
+ nullable: true
2805
+ - name: platform_sdd_id
2806
+ type: string
2807
+ nullable: true
2808
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
2809
+ description: "Derived edge: C4 container is responsible for data-model entity. Added in schema 2.13.0 per M-ADR 0159 §4.8. Pure transitive derivation: `service_entity ⋈ c4_containers.service_id`. Only the subset of containers with `service_id` populated contribute edges (per M-ADR 0155 the container ↔ service cardinality is o-or-1; data-store containers and infra-umbrella containers without a service mapping legitimately emit no rows)."
2810
+ foreign_keys:
2811
+ - column: container_id
2812
+ references: c4_containers.id
2813
+ nullable: false
2814
+ - column: entity_id
2815
+ references: entities.id
2816
+ nullable: false
2817
+ c4_system_entity:
2818
+ primary_key: id
2819
+ columns:
2820
+ - name: id
2821
+ type: string
2822
+ nullable: false
2823
+ description: "Composite PK: {system_id}__{entity_id}."
2824
+ - name: system_id
2825
+ type: string
2826
+ nullable: false
2827
+ - name: entity_id
2828
+ type: string
2829
+ nullable: false
2830
+ - name: container_count
2831
+ type: integer
2832
+ nullable: false
2833
+ description: Number of the system's containers that touch this entity. Aggregated from c4_container_entity.
2834
+ - name: source_sdd_id
2835
+ type: string
2836
+ nullable: true
2837
+ - name: platform_sdd_id
2838
+ type: string
2839
+ nullable: true
2840
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
2841
+ description: "Derived edge: C4 system is responsible for data-model entity. Added in schema 2.13.0 per M-ADR 0159 §4.8. Pure aggregation roll-up: `c4_container_entity ⋈ c4_containers.system_id`, with container_count recording how many of the system's containers touch the entity (governance signal for cross-container concerns)."
2842
+ foreign_keys:
2843
+ - column: system_id
2844
+ references: c4_systems.id
2845
+ nullable: false
2846
+ - column: entity_id
2847
+ references: entities.id
2848
+ nullable: false
2849
+ capability_adr:
2850
+ primary_key: id
2851
+ columns:
2852
+ - name: id
2853
+ type: string
2854
+ nullable: false
2855
+ - name: capability_id
2856
+ type: string
2857
+ nullable: false
2858
+ - name: adr_id
2859
+ type: string
2860
+ nullable: false
2861
+ - name: confidence
2862
+ type: string
2863
+ nullable: false
2864
+ description: spec | high | medium.
2865
+ description: "Edge: ADR informs capability. Forward: declared in capability spec Architecture Decisions. Reverse: same plus heuristic match supplements with confidence."
2866
+ foreign_keys:
2867
+ - column: capability_id
2868
+ references: capabilities.id
2869
+ nullable: false
2870
+ - column: adr_id
2871
+ references: adrs.id
2872
+ nullable: false
2873
+ column_enums:
2874
+ confidence: enums.capability_adr_confidence
2875
+ adr_supersedes:
2876
+ primary_key: id
2877
+ columns:
2878
+ - name: id
2879
+ type: string
2880
+ nullable: false
2881
+ - name: superseding_adr_id
2882
+ type: string
2883
+ nullable: false
2884
+ - name: superseded_adr_id
2885
+ type: string
2886
+ nullable: false
2887
+ description: "Edge: superseding ADR → superseded ADR. Parsed from Supersedes bullets where prose references a known ADR id."
2888
+ foreign_keys:
2889
+ - column: superseding_adr_id
2890
+ references: adrs.id
2891
+ nullable: false
2892
+ - column: superseded_adr_id
2893
+ references: adrs.id
2894
+ nullable: false
2895
+ product_platform_dependencies:
2896
+ primary_key: id
2897
+ columns:
2898
+ - name: id
2899
+ type: string
2900
+ nullable: false
2901
+ description: "{product_id}__{target_capability_id}__{target_service_id}, EXCEPT for async shared-stream rows (M-ADR 0192) where there is no realiser service: the third component falls back to the stream contract_path, i.e. {product_id}__{target_capability_id}__{contract_path}. For OFF-PLATFORM rows (M-ADR 0204, target_locus external|legacy) there is no platform capability either: id = {product_id}__{target_locus}__{target_external_system_id}, falling back to contract_path as the third component when no external-system id is named. This keeps the PK stable and collision-free when a product depends on the same capability via two distinct streams."
2902
+ - name: product_id
2903
+ type: string
2904
+ nullable: false
2905
+ description: Consuming product (this SDD's product id).
2906
+ - name: target_capability_id
2907
+ type: string
2908
+ nullable: true
2909
+ description: "Capability the consuming product depends on. Resolves at aggregation against a sibling SDD's capabilities.id; external by definition. Conditionally nullable (M-ADR 0204 §4.3): EMPTY when target_locus is external|legacy — there is no platform capability to name on an off-platform row, and demanding a value is what put a product's own feature slug in this column. A platform-locus row still requires it."
2910
+ - name: target_locus
2911
+ type: string
2912
+ nullable: true
2913
+ description: platform | external | legacy (M-ADR 0204; closed enum, absent/empty = platform). A statement about the TARGET only — never about the consuming product, and never a stability, lifecycle or quality claim. platform rows behave exactly as before this column existed. external/legacy rows carry empty target_capability_id and target_service_id and name their target in target_external_system_id; they skip platform resolution and the F18 realiser-join, with every skip named.
2914
+ - name: target_external_system_id
2915
+ type: string
2916
+ nullable: true
2917
+ description: "For target_locus external|legacy rows only: the M-ADR 0189 external-system entry id the dependency targets (authored in the source file's service_id slot; the builder routes it here so the FK columns stay clean). Deliberately NOT a declared FK: corroboration against c4_external_systems is WARNING-severity at aggregation (M-ADR 0204 §4.2), because the C4 surface may legitimately lag discovery, and a declared FK can only fail."
2918
+ - name: target_service_id
2919
+ type: string
2920
+ nullable: true
2921
+ description: "Service identifier the consuming product depends on. Resolves at aggregation against a sibling SDD's services.id; external by definition. The join key the aggregator uses to derive cross_sdd_platform_capability for SYNCHRONOUS dependencies. Conditionally nullable (M-ADR 0192): for an async shared-stream dependency (contract_type in the async set — `event`/`event-stream`/`stream`) there is no single realiser service, so this is empty and the dependency binds to the stream contract_path + target_capability_id instead. A synchronous contract_type still requires it. Made nullable in schema 2.36.0."
2922
+ - name: target_domain
2923
+ type: string
2924
+ nullable: true
2925
+ description: Domain hint as declared in the consuming SDD's evidence (free-form; reviewer-facing annotation). May be a comma-separated list when the target spans multiple domains.
2926
+ - name: contract_type
2927
+ type: string
2928
+ nullable: true
2929
+ description: rest | graphql | openapi | grpc | event | event-stream | stream | other. Optional; reflects what the consuming SDD declares. The async set (`event`/`event-stream`/`stream`) marks a shared-stream subscription that binds to a stream contract rather than a realiser service (M-ADR 0192) — such rows skip the F18 synchronous realiser-join at aggregation.
2930
+ - name: required_stability
2931
+ type: string
2932
+ nullable: true
2933
+ description: "provisional | locked | unknown. Optional; the consuming SDD's expectation of contract stability — and only that: where the target lives and what lifecycle its implementation is in are separate concerns that do not belong in this field. Not a bound enum: an out-of-vocabulary value is carried, not rejected, and is reported by validate-app-dependencies.sh."
2934
+ - name: contract_path
2935
+ type: string
2936
+ nullable: true
2937
+ description: Path to the contract file the dependency is against, as declared in the consuming SDD's evidence. External — resolution happens at aggregation if it happens at all.
2938
+ - name: consumed_by_services
2939
+ type: string
2940
+ nullable: true
2941
+ description: Comma-separated list of service names within the consuming product that consume the dependency. Free-text; not FK-validated (services are within-product and resolution is owner-side concern).
2942
+ - name: source_sdd_id
2943
+ type: string
2944
+ nullable: true
2945
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
2946
+ - name: platform_sdd_id
2947
+ type: string
2948
+ nullable: true
2949
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
2950
+ description: |
2951
+ Per-SDD edge: an application-side or integration-side SDD declares that its product depends on a platform-side capability + service pair. Built from `reverse-evidence/feature-grounding-evidence.yaml` `platform_dependencies:` block (product-level — the cohort source shape carries product-scoped dependency rows with a `consumed_by:` list naming which services within the consuming product depend on the target). Each row records one (consuming product, target capability, target service) triple. The aggregator then joins these rows against platform-side `capability_service` to emit `cross_sdd_platform_capability` edges at aggregation time. Cross- SDD references (target_capability_id, target_service_id) are external — they're not expected to resolve in the per-SDD build, only at aggregation. Added in schema 2.9.0; see `content/plans/v0-9-0-cohort-sweep-derived-bundle.md` §"Cross-SDD platform-capability-edge".
2952
+ foreign_keys:
2953
+ - column: product_id
2954
+ references: products.id
2955
+ nullable: false
2956
+ - column: target_capability_id
2957
+ references: capabilities.id
2958
+ nullable: true
2959
+ external: true
2960
+ - column: target_service_id
2961
+ references: services.id
2962
+ nullable: true
2963
+ external: true
2964
+ column_enums:
2965
+ required_stability: enums.required_stability
2966
+ target_locus: enums.target_locus
2967
+ contract_type: enums.dependency_contract_type
2968
+ cross_sdd_platform_capability:
2969
+ primary_key: id
2970
+ columns:
2971
+ - name: id
2972
+ type: string
2973
+ nullable: false
2974
+ description: "{consuming_sdd_id}__{consuming_product_id}__{platform_sdd_id}__{platform_capability_id}__{service_id}. Composite encoding so the same (consuming product, platform capability) pair can appear once per resolving service when a product depends on multiple services owned by the same capability."
2975
+ - name: consuming_sdd_id
2976
+ type: string
2977
+ nullable: false
2978
+ description: SDD slug of the consuming side (application-product or integration-product SDD).
2979
+ - name: consuming_product_id
2980
+ type: string
2981
+ nullable: false
2982
+ description: Product in the consuming SDD that declares the platform_dependencies entry.
2983
+ - name: platform_sdd_id
2984
+ type: string
2985
+ nullable: false
2986
+ description: SDD slug of the platform side that owns the resolved capability.
2987
+ - name: platform_capability_id
2988
+ type: string
2989
+ nullable: false
2990
+ description: Capability in the platform SDD whose capability_service includes the resolved service.
2991
+ - name: service_id
2992
+ type: string
2993
+ nullable: false
2994
+ description: Service identifier the consuming SDD references and the platform SDD owns. The join key.
2995
+ description: |
2996
+ Federated edge: an application-side or integration-side SDD's `product_platform_dependencies` reference resolves against a platform-side SDD's capability spec via the platform capability's `capability_service` roster. Surfaces ecosystem-wide platform- consumer relationships at product → capability granularity. Built **only at aggregation time** — `sdd-cli catalogue aggregate` joins each consuming SDD's `product_platform_dependencies` rows against every other SDD's `capability_service` rows on `target_service_id == service_id`, emitting one row per resolved (consuming-product, platform-capability) pair. Per-SDD builders emit nothing for this catalogue; the aggregator owns it entirely. A platform-dependency whose target_service_id doesn't resolve to any platform-side capability_service row is logged as an `orphan` finding and produces no row. Cross-SDD references are external by definition. Added in schema 2.9.0; see `content/plans/v0-9-0-cohort-sweep-derived-bundle.md` §"Cross-SDD platform-capability-edge" and M-ADR 0134.
2997
+ foreign_keys:
2998
+ - column: consuming_product_id
2999
+ references: products.id
3000
+ nullable: false
3001
+ external: true
3002
+ - column: platform_capability_id
3003
+ references: capabilities.id
3004
+ nullable: false
3005
+ external: true
3006
+ - column: service_id
3007
+ references: services.id
3008
+ nullable: false
3009
+ external: true
3010
+ application_data_plane_bindings:
3011
+ primary_key: id
3012
+ columns:
3013
+ - name: id
3014
+ type: string
3015
+ nullable: false
3016
+ description: "{product_id}__{pattern}__{locality}__{target} (empty components collapse to blanks). A duplicate emits a divergence finding and is dropped. `direction` is NOT a component — it is derived from `pattern`, so it adds nothing to identity."
3017
+ - name: product_id
3018
+ type: string
3019
+ nullable: false
3020
+ description: The application-product declaring this binding (this SDD's product id).
3021
+ - name: pattern
3022
+ type: string
3023
+ nullable: false
3024
+ description: "Closed method-tier enum: retrieve | own-store | stream-ingest | project (inbound, data-sourcing) | generate | publish (output-side, per M-ADR 0193 §4.7). How the data relates to the service (§4.1)."
3025
+ - name: direction
3026
+ type: string
3027
+ nullable: false
3028
+ description: "inbound | output. DERIVED from `pattern` by a single method-tier mapping — not authored, and not a manifest field, so it cannot disagree with `pattern`. Materialises the output-side sub-set §4.7 declares (generate/publish => output; everything else => inbound). Exists because three §4.7 rules branch on direction: platform-dep reconciliation is inbound-only, the archetype WARN must compare like with like, and the M-ADR 0187 convergence reasoning differs by direction. Added in 2.40.0."
3029
+ - name: locality
3030
+ type: string
3031
+ nullable: true
3032
+ description: "Closed enum: internal-platform | internal-domain | external-vendor. Where the other end sits. REQUIRED on the inbound data-sourcing patterns (retrieve/stream-ingest/project); may be empty for own-store (a self-binding with no other end) and for the output-side patterns (generate/publish), which may carry one but do not require it (M-ADR 0193 §4.7)."
3033
+ - name: transport
3034
+ type: string
3035
+ nullable: true
3036
+ description: Open string — the wire (rest | graphql | grpc | appsync | kinesis | kafka | eventhub | cdc | ...). Values outside the recommended set emit a convention finding.
3037
+ - name: runtime
3038
+ type: string
3039
+ nullable: true
3040
+ description: Free adopter-tier field — backend-compute runtime (e.g. java | node). Only on compute-bearing patterns (stream-ingest | project | generate — `generate` is compute-bearing per M-ADR 0193 §4.7); empty otherwise. A runtime on retrieve/own-store/publish is malformed and FAILs at manifest load.
3041
+ - name: target
3042
+ type: string
3043
+ nullable: true
3044
+ description: Free adopter-tier field — the specific counterpart (a platform service id, an upstream domain service, a named vendor). Instance identity; keeps locality a small class enum.
3045
+ - name: notes
3046
+ type: string
3047
+ nullable: true
3048
+ description: Optional free-text annotation.
3049
+ - name: source_sdd_id
3050
+ type: string
3051
+ nullable: true
3052
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3053
+ - name: platform_sdd_id
3054
+ type: string
3055
+ nullable: true
3056
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
3057
+ description: |
3058
+ Application-product edge (M-ADR 0193): one row per declared data-plane binding — a typed way the service sources, holds, produces or exposes data. The data-plane is a COMPOSITION of these bindings, a second axis orthogonal to `application_archetype` (0191). Built per-SDD from the manifest's `data_plane.bindings` block (application-product only; other profiles emit headers-only). The `pattern` vocabulary splits by DIRECTION (§4.7): an INBOUND data-sourcing sub-set (retrieve | own-store | stream-ingest | project) and an OUTPUT-side sub-set (generate | publish), materialised as the derived `direction` column. An INBOUND binding whose `target` is a platform capability/service reconciles with `product_platform_dependencies` — a `retrieve@internal` binding is a synchronous platform dependency and a `stream-ingest@internal` binding is the M-ADR 0192 `contract_type: event` async dependency; the genuinely new inbound rows are `own-store` (a self-binding) and any `external-vendor` binding. OUTPUT-side rows do NOT participate in that reconciliation (§4.7 rule 1): `publish` is a contract the service PROVIDES, not one it consumes, so it has no inbound counterpart to cross-check — consumers must filter on `direction` before reconciling, which is what the column is for. The archetype-default-vs-declared WARN keys on the bare `pattern` token and so spans both directions (§4.7 rule 2). Added in schema 2.37.0; `direction` added in 2.40.0.
3059
+ foreign_keys:
3060
+ - column: product_id
3061
+ references: products.id
3062
+ nullable: false
3063
+ column_enums:
3064
+ pattern: enums.data_plane_pattern
3065
+ direction: enums.data_plane_direction
3066
+ locality: enums.data_plane_locality
3067
+ application_data_plane_deviations:
3068
+ primary_key: id
3069
+ columns:
3070
+ - name: id
3071
+ type: string
3072
+ nullable: false
3073
+ description: "{product_id}__{expectation}. A duplicate emits a divergence finding and is dropped."
3074
+ - name: product_id
3075
+ type: string
3076
+ nullable: false
3077
+ description: The application-product declaring this deviation (this SDD's product id).
3078
+ - name: expectation
3079
+ type: string
3080
+ nullable: false
3081
+ description: The bare data-plane pattern token the product diverges from (retrieve | own-store | stream-ingest | project | generate | publish). Must match the WARN's pattern key. Spans both directions per M-ADR 0193 §4.7 rule 2.
3082
+ - name: rationale
3083
+ type: string
3084
+ nullable: false
3085
+ description: Why the deviation is correct. Non-empty (enforced at manifest load).
3086
+ - name: source_sdd_id
3087
+ type: string
3088
+ nullable: true
3089
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3090
+ - name: platform_sdd_id
3091
+ type: string
3092
+ nullable: true
3093
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
3094
+ description: |
3095
+ Application-product annotation (M-ADR 0191 §4.3 overlay): one row per declared departure from the archetype's default data-plane composition. Built per-SDD from the manifest's `data_plane.deviations` block so the overlay WARN — which runs at AGGREGATION tier, where the reference- architecture bundle (and its `expected_bindings`) resolves — can suppress a mismatch it is told is sanctioned variance. The `expectation` value is the **bare pattern token** (`retrieve` | `own-store` | `stream-ingest` | `project` | `generate` | `publish`) that the product knowingly diverges from; it must match the pattern the WARN keys on. The token set spans both directions — the WARN keys on the bare pattern, so an output-side expectation is deviated exactly like an inbound one (M-ADR 0193 §4.7 rule 2). Added in schema 2.38.0; output-side tokens documented in 2.40.0.
3096
+ foreign_keys:
3097
+ - column: product_id
3098
+ references: products.id
3099
+ nullable: false
3100
+ column_enums:
3101
+ expectation: enums.data_plane_pattern
3102
+ application_conformance_coverage:
3103
+ primary_key: id
3104
+ columns:
3105
+ - name: id
3106
+ type: string
3107
+ nullable: false
3108
+ description: "{product_id}__{tag}. A duplicate emits a divergence finding and is dropped."
3109
+ - name: product_id
3110
+ type: string
3111
+ nullable: false
3112
+ description: The application-product declaring this coverage (this SDD's product id).
3113
+ - name: tag
3114
+ type: string
3115
+ nullable: false
3116
+ description: The conformance-expectation tag (opaque; matches an archetype's `conformance` tag in the reference-architecture vocabulary).
3117
+ - name: status
3118
+ type: string
3119
+ nullable: false
3120
+ description: covered (the product's suite exercises it) | deviated (deliberately not covered, with a rationale).
3121
+ - name: rationale
3122
+ type: string
3123
+ nullable: true
3124
+ description: Why the tag is deviated. Present (non-empty) only when status=deviated.
3125
+ - name: source_sdd_id
3126
+ type: string
3127
+ nullable: true
3128
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3129
+ - name: platform_sdd_id
3130
+ type: string
3131
+ nullable: true
3132
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
3133
+ description: |
3134
+ Application-product annotation (M-ADR 0191 §4.3 overlay, second element — WS4): one row per conformance tag the product asserts about its archetype's conformance expectations. Built per-SDD from the manifest's `conformance` block so the AGGREGATION-tier conformance GATE can read it. `status=covered` means the product's own conformance suite exercises the tag; `status=deviated` means the product declares (with a rationale) that it deliberately does not. At aggregation, an archetype-expected conformance tag that is neither covered nor deviated raises a deviation-visible WARN. The method gates the DECLARATION — it does not run the adopter's conformance suite. Added in schema 2.39.0.
3135
+ foreign_keys:
3136
+ - column: product_id
3137
+ references: products.id
3138
+ nullable: false
3139
+ screens:
3140
+ primary_key: id
3141
+ columns:
3142
+ - name: id
3143
+ type: string
3144
+ nullable: false
3145
+ description: "Slugged PK: {product_id}-{screen-slug}."
3146
+ - name: name
3147
+ type: string
3148
+ nullable: false
3149
+ description: Screen slug / display name.
3150
+ - name: product_id
3151
+ type: string
3152
+ nullable: false
3153
+ description: Owning application-product.
3154
+ - name: route
3155
+ type: string
3156
+ nullable: true
3157
+ description: Route path the screen is mounted at, when applicable.
3158
+ - name: status
3159
+ type: string
3160
+ nullable: true
3161
+ description: Maturity marker; uses the standard working | provisional | unknown | absent vocabulary (per M-ADR 0165) where applicable.
3162
+ - name: source
3163
+ type: string
3164
+ nullable: false
3165
+ description: screen-spec (forward) | screen-extraction (reverse).
3166
+ - name: domain
3167
+ type: string
3168
+ nullable: true
3169
+ description: Authored owning-domain hint from frontmatter `domain:` (a docs/domains/<domain>/ slug). Organisational grouping for multi-domain (platform-profile) SDDs; the authoritative screen->domain relationship is still derived via realises -> feature -> capability.domain_id (screen_feature). Empty when unauthored.
3170
+ - name: group
3171
+ type: string
3172
+ nullable: true
3173
+ description: Authored sub-grouping hint from frontmatter `group:` — a finer organisational axis within (or orthogonal to) domain, e.g. shell | shell-embed | identity. Free-form adopter label; not an FK. Empty when unauthored.
3174
+ - name: context
3175
+ type: string
3176
+ nullable: true
3177
+ description: Bounded-context membership from frontmatter `context:` (per M-ADR 0170 §4.6). Free-form adopter label, orthogonal to domain/group — the consumed bounded context for a surface that spans several. Not an FK. Empty when unauthored. Added in schema 2.19.0.
3178
+ - name: evidence_class
3179
+ type: string
3180
+ nullable: true
3181
+ description: "Evidence class of the screen's claims, from frontmatter `evidence_class:` (alias `evidence-class:`). Free-form; conventional values code-reverse | vendor-doc | operational (M-ADR 0175). Empty when undeclared. Completes the evidence-class dimension for the packaged-SaaS case: a packaged-SaaS SDD catalogues the vendor's STANDARD screens (documentation-reversed from vendor publications, `vendor-doc`) alongside the organisation's CUSTOMISED screens (code-reversed, `code-reverse`) per M-ADR 0175 §3.1 — without this column the two are indistinguishable, and doc-derived UI claims masquerade as code-verified. Orthogonal to `source` (`screen-spec` | `screen-extraction`), which records the authoring DIRECTION, not the evidence's strength: a `screen-extraction` screen can be either class, since a vendor's documented UI is extracted-but-not-code-verified. Added in schema 2.42.0."
3182
+ - name: source_sdd_id
3183
+ type: string
3184
+ nullable: true
3185
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3186
+ - name: platform_sdd_id
3187
+ type: string
3188
+ nullable: true
3189
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
3190
+ description: "UI screen specified in the OpenUI Lang grammar (per M-ADR 0166). One row per screen / coherent screen group. Application-product profile (other profiles emit headers-only). Source: authored `screens/*.md` (frontmatter + ```openui-lang block); the reverse toolkit produces these from a router + component-tree projection."
3191
+ foreign_keys:
3192
+ - column: product_id
3193
+ references: products.id
3194
+ nullable: false
3195
+ column_enums:
3196
+ status: enums.artefact_maturity
3197
+ ui_components:
3198
+ primary_key: id
3199
+ columns:
3200
+ - name: id
3201
+ type: string
3202
+ nullable: false
3203
+ description: "Slugged PK: {product_id}-{component-slug}."
3204
+ - name: name
3205
+ type: string
3206
+ nullable: false
3207
+ description: Component identifier as used in the grammar.
3208
+ - name: product_id
3209
+ type: string
3210
+ nullable: false
3211
+ description: Owning application-product.
3212
+ - name: kind
3213
+ type: string
3214
+ nullable: true
3215
+ description: "Optional classification: layout | display | input | chart | element | composite | remote | remote-iframe | remote-webcomponent. A `remote*` kind marks a micro-frontend federation seam (M-ADR 0166 §4.7)."
3216
+ - name: source
3217
+ type: string
3218
+ nullable: false
3219
+ description: screen-spec (forward) | design-system-import (reverse).
3220
+ - name: source_sdd_id
3221
+ type: string
3222
+ nullable: true
3223
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3224
+ - name: platform_sdd_id
3225
+ type: string
3226
+ nullable: true
3227
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
3228
+ description: "An entry in the adopter-owned component registry that screens compose against (per M-ADR 0166) — the UI-structure contract. A screen composes registry components but never defines one. Application-product profile. Source: components referenced across the SDD's screen-spec ```openui-lang blocks (registry projection); the reverse toolkit discovers the authoritative registry from the design-system import surface."
3229
+ foreign_keys:
3230
+ - column: product_id
3231
+ references: products.id
3232
+ nullable: false
3233
+ column_enums:
3234
+ kind: enums.ui_component_kind
3235
+ screen_component:
3236
+ primary_key: id
3237
+ columns:
3238
+ - name: id
3239
+ type: string
3240
+ nullable: false
3241
+ description: "Composite PK: {screen_id}__{component_id}."
3242
+ - name: screen_id
3243
+ type: string
3244
+ nullable: false
3245
+ - name: component_id
3246
+ type: string
3247
+ nullable: false
3248
+ - name: source_sdd_id
3249
+ type: string
3250
+ nullable: true
3251
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3252
+ - name: platform_sdd_id
3253
+ type: string
3254
+ nullable: true
3255
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
3256
+ description: "Edge: screen composes a UI component. Parsed from the screen-spec ```openui-lang block's component references (per M-ADR 0166)."
3257
+ foreign_keys:
3258
+ - column: screen_id
3259
+ references: screens.id
3260
+ nullable: false
3261
+ - column: component_id
3262
+ references: ui_components.id
3263
+ nullable: false
3264
+ screen_feature:
3265
+ primary_key: id
3266
+ columns:
3267
+ - name: id
3268
+ type: string
3269
+ nullable: false
3270
+ description: "Composite PK: {screen_id}__{feature_id}. For app/integration builds the feature_id may be a bare realises slug until the aggregator resolves it to the platform feature id (then the PK is regenerated)."
3271
+ - name: screen_id
3272
+ type: string
3273
+ nullable: false
3274
+ - name: feature_id
3275
+ type: string
3276
+ nullable: false
3277
+ - name: source_sdd_id
3278
+ type: string
3279
+ nullable: true
3280
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3281
+ - name: platform_sdd_id
3282
+ type: string
3283
+ nullable: true
3284
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
3285
+ description: "Edge: screen realises a feature (traceability). Forward: `realises:` frontmatter on the screen-spec. Reverse: route → feature mapping. Per M-ADR 0166."
3286
+ foreign_keys:
3287
+ - column: screen_id
3288
+ references: screens.id
3289
+ nullable: false
3290
+ - column: feature_id
3291
+ references: features.id
3292
+ nullable: false
3293
+ external_for_profiles:
3294
+ - application-product
3295
+ - integration-product
3296
+ persona_screen:
3297
+ primary_key: id
3298
+ columns:
3299
+ - name: id
3300
+ type: string
3301
+ nullable: false
3302
+ description: "Composite PK: {persona_id}__{screen_id}."
3303
+ - name: persona_id
3304
+ type: string
3305
+ nullable: false
3306
+ - name: screen_id
3307
+ type: string
3308
+ nullable: false
3309
+ - name: source_sdd_id
3310
+ type: string
3311
+ nullable: true
3312
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3313
+ - name: platform_sdd_id
3314
+ type: string
3315
+ nullable: true
3316
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
3317
+ description: "Edge: persona can access a screen. Forward: `persona_access:` frontmatter. Reverse: route persona-access guards, permission/feature-flag config, or a host shell's per-persona menu (where the backend pre-filters visible screens). Per M-ADR 0166."
3318
+ foreign_keys:
3319
+ - column: persona_id
3320
+ references: personas.id
3321
+ nullable: false
3322
+ - column: screen_id
3323
+ references: screens.id
3324
+ nullable: false
3325
+ screen_action:
3326
+ primary_key: id
3327
+ columns:
3328
+ - name: id
3329
+ type: string
3330
+ nullable: false
3331
+ description: "Composite PK: {screen_id}__{action-slug}."
3332
+ - name: screen_id
3333
+ type: string
3334
+ nullable: false
3335
+ - name: action
3336
+ type: string
3337
+ nullable: false
3338
+ description: Declared action label emitted by the screen.
3339
+ - name: event_id
3340
+ type: string
3341
+ nullable: true
3342
+ description: Catalogued event the action maps to (per M-ADR 0156). External-capable; empty when the action does not resolve to a domain event.
3343
+ - name: source_sdd_id
3344
+ type: string
3345
+ nullable: true
3346
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3347
+ - name: platform_sdd_id
3348
+ type: string
3349
+ nullable: true
3350
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
3351
+ description: "Edge: screen emits an action, optionally resolved to a catalogued event. The behavioural MFE seam — inter-bundle communication as a catalogued contract, not an ad-hoc string. Forward: `action=` declarations in the ```openui-lang block. Reverse: emitted custom-event / event-bus wiring. event_id is external-capable (the event may live in the platform SDD). Per M-ADR 0166 + M-ADR 0156."
3352
+ foreign_keys:
3353
+ - column: screen_id
3354
+ references: screens.id
3355
+ nullable: false
3356
+ - column: event_id
3357
+ references: events.id
3358
+ nullable: true
3359
+ external: true
3360
+ conformance_finding:
3361
+ primary_key: id
3362
+ columns:
3363
+ - name: id
3364
+ type: string
3365
+ nullable: false
3366
+ description: Check id (unique within the SDD; source_sdd_id disambiguates across the federation).
3367
+ - name: check_id
3368
+ type: string
3369
+ nullable: false
3370
+ - name: target
3371
+ type: string
3372
+ nullable: false
3373
+ description: code-vs-contract | binding-vs-reality (M-ADR 0180 §2.5).
3374
+ - name: implementation_repo
3375
+ type: string
3376
+ nullable: true
3377
+ description: The implementation member the check is about (M-ADR 0181). Empty when checks were not binding-derived.
3378
+ - name: role
3379
+ type: string
3380
+ nullable: true
3381
+ description: as-is | to-be (M-ADR 0181). Empty when not binding-derived.
3382
+ - name: lifecycle
3383
+ type: string
3384
+ nullable: true
3385
+ description: planned | migrating | active | legacy-active | deprecated | decommissioned (M-ADR 0181).
3386
+ - name: declared
3387
+ type: number
3388
+ nullable: false
3389
+ description: Count of the declared surface (spec/binding/contract).
3390
+ - name: observed
3391
+ type: number
3392
+ nullable: false
3393
+ description: Count of the observed surface (code).
3394
+ - name: matched
3395
+ type: number
3396
+ nullable: false
3397
+ - name: conformance_pct
3398
+ type: number
3399
+ nullable: false
3400
+ description: matched / denom * 100 (denom per the check).
3401
+ - name: declared_not_observed
3402
+ type: number
3403
+ nullable: false
3404
+ description: "Count declared but not observed (candidate: spec-stale / unimplemented / dangling)."
3405
+ - name: observed_not_declared
3406
+ type: number
3407
+ nullable: false
3408
+ description: "Count observed but not declared (candidate: binding-stale / code-defect)."
3409
+ - name: needs_triage
3410
+ type: boolean
3411
+ nullable: false
3412
+ description: True when any asymmetry exists. Triage, not auto-fail (M-ADR 0180 §2.3).
3413
+ - name: run_date
3414
+ type: string
3415
+ nullable: false
3416
+ description: ISO date of the conformance run — the snapshot stamp enabling trend over time.
3417
+ - name: source_sdd_id
3418
+ type: string
3419
+ nullable: true
3420
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3421
+ - name: platform_sdd_id
3422
+ type: string
3423
+ nullable: true
3424
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
3425
+ description: "Conformance-reverse drift summary, one row per check (method M-ADR 0180). NOT produced by `catalogue build` (it reads the spec repo) — produced by `sdd-cli conformance --emit-finding` (which has the code repo) and federated here by the aggregator. Each row is a run-dated snapshot of declared-vs-observed drift for an implementation member (M-ADR 0181 role/lifecycle), so estate-wide conformance is queryable (aggregate union) and trendable (snapshot diff across runs/commits). Verdicts are PROVISIONAL — disposition (code-defect | spec-stale | divergence) is triage, recorded elsewhere. No enforced FK on implementation_repo: the code repo is frequently cross-repo and not in this SDD's repositories.csv. Added in schema 2.25.0."
3426
+ column_enums:
3427
+ target: enums.conformance_target
3428
+ role: enums.implementation_role
3429
+ lifecycle: enums.implementation_lifecycle
3430
+ quality_scores:
3431
+ primary_key: id
3432
+ columns:
3433
+ - name: id
3434
+ type: string
3435
+ nullable: false
3436
+ description: "PK: {rubric_id}__{target_kind}__{target_ref}. Composite in one slug because the natural key is a triple and the rest of this schema keys on a single `id`."
3437
+ - name: rubric_id
3438
+ type: string
3439
+ nullable: false
3440
+ description: The rubric that produced the assessment, e.g. adr-quality, contract-quality. From the registry's `registry_type` when declared, else the filename stem minus `-scores`. A `registry_type` disagreeing with its filename is a convention finding, never a silent preference.
3441
+ - name: scoring_form
3442
+ type: string
3443
+ nullable: false
3444
+ description: Scoring shape — see the scoring_form enum. `weighted` for every row the current builder emits.
3445
+ - name: target_kind
3446
+ type: string
3447
+ nullable: false
3448
+ description: "What kind of thing was scored: adr | contract | c4_diagram | capability | domain | feature | product | repository | persona | screen | glossary | integration | user_story | work_order | strategic_doc. Polymorphic because scored units span catalogue entities and non-catalogued artefacts (M-ADR 0205 §4.5)."
3449
+ - name: target_ref
3450
+ type: string
3451
+ nullable: false
3452
+ description: Identifier of the scored target, in the vocabulary of its kind. For ADRs this is the prefix-stripped catalogue id (M-ADR 0186 §4.4), matching `adrs.id`.
3453
+ - name: target_path
3454
+ type: string
3455
+ nullable: true
3456
+ description: Repo-relative path to the scored artefact, from the entry's `file_path` where authored (7 of 15 registry shapes carry it). Doubles as the resolution anchor for `scored_at`-basis staleness — which is why its absence downgrades a row's staleness_basis to `none` rather than being cosmetic. Empty when the registry does not author it.
3457
+ - name: gate
3458
+ type: string
3459
+ nullable: true
3460
+ description: Verdict — see the quality_gate enum, which is deliberately UNBOUND. An out-of-vocabulary value leaves this cell EMPTY and raises a convention finding naming the file, entry and value (the products.synthesis_band precedent). Empty therefore means either unauthored or out-of-vocabulary, and the finding distinguishes them.
3461
+ - name: weighted_score
3462
+ type: number
3463
+ nullable: true
3464
+ description: The rubric's rolled-up weighted score. Empty for an unscored entry — which is a real state the registries author deliberately, not a gap.
3465
+ - name: score_denominator
3466
+ type: number
3467
+ nullable: true
3468
+ description: Denominator the weighted_score was computed against, where the rubric records one (contract-quality does). Present so a score is never reported without its basis.
3469
+ - name: band
3470
+ type: string
3471
+ nullable: true
3472
+ description: "Named band for a `banded` row; empty for a weighted one. DELIBERATELY UNBOUND, and for the same reason `dimension_key` is not normalised: the vocabulary belongs to the rubric, not to the method. Measured across the reverse estate at 3.3.0 — `reverseability` uses easy | moderate | hard | very-hard (a DIFFICULTY scale, where a higher band is worse), while `repo_doc_quality`, `product_synthesis_quality`, `reverse_platform_evidence_quality` and `artifact_quality` use strong | working (a QUALITY scale). One closed enum over both would assert that `hard` and `working` are comparable, which they are not. A consumer comparing bands must therefore group by rubric_id first."
3473
+ - name: band_total
3474
+ type: int
3475
+ nullable: true
3476
+ description: "Integer total a `banded` rubric summed its dimensions to, before mapping to `band`; empty for a weighted row. Kept SEPARATE from weighted_score rather than sharing it: the scales are incompatible (a banded total ranges 0-13 against a weighted 1-5), and a single column holding both would make any average over it silently wrong. Separation makes an aggregate over weighted_score correct by construction rather than by the caller remembering to filter on scoring_form."
3477
+ - name: scored_at
3478
+ type: date
3479
+ nullable: true
3480
+ description: "Date of the effective assessment, from `scored_at` (the forward house form's field name — NOT `assessed_at`, which is the reverse family's file-level field). Date-typed: per the M-ADR 0205 §4.1 engine's TRY_CAST semantics, a prose value here is reported as a type nonconformance rather than aborting the load or being smoothed away — the `adrs.decision_date` case, which reverse practice already exercises."
3481
+ - name: corpus_ref
3482
+ type: string
3483
+ nullable: true
3484
+ description: "The commit the assessment read — the precise staleness anchor. NEW AUTHORING introduced by this change-set: no score written before it carries one, so this column is empty across both estates at introduction and fills forward as registries are rewritten. The reverse family already has the idea under a different name (`snapshot.source_revision`)."
3485
+ - name: staleness_basis
3486
+ type: string
3487
+ nullable: false
3488
+ description: Which anchor this row's staleness can be computed from — see the staleness_basis enum. Emitted by the builder, never authored. Exists so no consumer can state a staleness verdict without its basis.
3489
+ - name: review_run_id
3490
+ type: string
3491
+ nullable: true
3492
+ description: Identifier of the effective review run. Empty in the flat dialect, which records no run ids.
3493
+ - name: selection_method
3494
+ type: string
3495
+ nullable: true
3496
+ description: "How the effective review was chosen — see the score_selection_method enum. Empty in the flat dialect, which carries no selection_policy: absence means 'the only review', not 'policy unknown'."
3497
+ - name: scorer_provider
3498
+ type: string
3499
+ nullable: true
3500
+ description: Provider of the scoring agent (e.g. anthropic), from `current.scorer.provider`. Every score in this method is agent-produced, so which agent produced a judgment is part of the judgment, not metadata about it.
3501
+ - name: scorer_tool
3502
+ type: string
3503
+ nullable: true
3504
+ description: Tool the scoring agent ran in, from `current.scorer.tool`.
3505
+ - name: scorer_model
3506
+ type: string
3507
+ nullable: true
3508
+ description: Model that produced the assessment, from `current.scorer.model`. In the flat dialect the whole provenance block collapses to a free-text `scored_by:`, which lands here — so a value like 'intent-quality-review — rfms-connector-library' is expected and correct for flat-dialect rows, not a parse defect.
3509
+ - name: scorer_model_family
3510
+ type: string
3511
+ nullable: true
3512
+ description: Optional grouping field from `current.scorer.model_family`.
3513
+ - name: scorer_prompt_version
3514
+ type: string
3515
+ nullable: true
3516
+ description: Optional prompt-wrapper version from `current.scorer.prompt_version` — the input that makes a score reproducible.
3517
+ - name: flag_count
3518
+ type: int
3519
+ nullable: false
3520
+ description: "Number of heuristic flags raised. Normalises two authored dialects: `flags: {name: bool}` (count the true ones) and `flags_raised: [names]` (count the list). A per-flag child catalogue is deliberately NOT built — it arrives when a named query needs to filter by flag name, not by accretion."
3521
+ - name: hard_gate_triggered
3522
+ type: boolean
3523
+ nullable: false
3524
+ description: "Whether any hard gate fired. Normalises `hard_gates: {triggered, reasons}` and `hard_gates_triggered: [reasons]`."
3525
+ - name: required_actions_count
3526
+ type: int
3527
+ nullable: false
3528
+ description: Number of remediation actions the assessment recorded.
3529
+ - name: sdd_id
3530
+ type: string
3531
+ nullable: true
3532
+ description: SDD whose gate-registry authored this row. Soft FK to products.id — nullable because a registry can score targets in an SDD that emits no product row.
3533
+ - name: source_sdd_id
3534
+ type: string
3535
+ nullable: true
3536
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134; left empty by per-SDD builders.
3537
+ - name: platform_sdd_id
3538
+ type: string
3539
+ nullable: true
3540
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
3541
+ description: |
3542
+ Rubric assessment of a target artefact, one row per (target, rubric), per M-ADR 0205 §4.5. Source: `orchestration/gate-registry/<rubric>-scores.yaml` — the authored surface stays YAML because a score is a judgment, authored where it asserts intent; these rows are DERIVED and never edited.
3543
+ Models the EFFECTIVE score only — `current`, as chosen by the registry's `selection_policy`. The authored `reviews[]` history is deliberately not catalogued: variable-length history in a fixed-grain catalogue would give two answers to "what is the score". `review_run_id` and `selection_method` make each row name which review it is.
3544
+ THE BUILDER MUST READ TWO AUTHORED DIALECTS. All fifteen method-side templates specify a nested shape (`selection_policy` / `current` / `reviews`), but the live forward-estate data is overwhelmingly FLAT — `gate`/`weighted_score`/`scored_at`/`scored_by`/`scores`/`flags` directly on the entry. Measured 2026-08-06: reading only the template shape would catalogue 6 entries out of 204. The templates were modernised; the data was not migrated, and both are legitimate.
3545
+ `rubric_id` comes from the file's `registry_type` when declared, else the filename stem minus `-scores` — NEVER the container key, which is unreliable (4 of 10 forward registries drift from the method template) and non-unique (`domains` names both domain-architecture and intent-quality; `capabilities` names both feature-grounding and traceability-manifest).
3546
+ Scope: the weighted house form only. The banded reverse family is additive later via `scoring_form` (see that enum).
3547
+ foreign_keys:
3548
+ - column: sdd_id
3549
+ references: products.id
3550
+ nullable: true
3551
+ quality_score_dimensions:
3552
+ primary_key: id
3553
+ columns:
3554
+ - name: id
3555
+ type: string
3556
+ nullable: false
3557
+ description: "PK: {quality_score_id}__{dimension_key}."
3558
+ - name: quality_score_id
3559
+ type: string
3560
+ nullable: false
3561
+ description: The assessment this dimension belongs to.
3562
+ - name: rubric_id
3563
+ type: string
3564
+ nullable: false
3565
+ description: Denormalised from the parent so per-rubric dimension queries need no join.
3566
+ - name: target_kind
3567
+ type: string
3568
+ nullable: false
3569
+ description: Denormalised from the parent.
3570
+ - name: target_ref
3571
+ type: string
3572
+ nullable: false
3573
+ description: Denormalised from the parent.
3574
+ - name: dimension_key
3575
+ type: string
3576
+ nullable: false
3577
+ description: "The rubric's own dimension identifier, verbatim — `A1` where the rubric uses codes, `definition_precision` where it uses names. NOT normalised into a method-wide vocabulary: the key is how the rubric and its registry refer to the dimension, and rewriting it here would make the row untraceable to the rubric that produced it."
3578
+ - name: dimension_score
3579
+ type: number
3580
+ nullable: true
3581
+ description: Score on that dimension. Empty for an unscored entry (the templates author explicit nulls).
3582
+ - name: dimension_weight
3583
+ type: number
3584
+ nullable: true
3585
+ description: "Weight the rubric assigns the dimension, where discoverable. Usually EMPTY: weights live in the rubric document and the registry header comment, not per entry — so this column is honest about the fact that a weighted_score cannot currently be recomputed from these rows alone."
3586
+ - name: source_sdd_id
3587
+ type: string
3588
+ nullable: true
3589
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3590
+ - name: platform_sdd_id
3591
+ type: string
3592
+ nullable: true
3593
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
3594
+ description: |
3595
+ One row per (target, rubric, dimension) — the per-dimension detail behind a `quality_scores` row, per M-ADR 0205 §4.5.
3596
+ A child catalogue rather than columns, and this is forced rather than stylistic: the fifteen rubrics carry FIFTEEN DISJOINT dimension vocabularies (`A1`-`A8`, `C1`-`C8`, `G1`-`G7`, `T1`-`T7`, `D1`-`D6`, `S1`-`S6`, `I1`-`I6`, plus five fully-named sets such as `definition_precision` and `intent_fidelity`) — 45 distinct keys measured in one estate alone. No fixed column set can hold them; serialised JSON in a cell would be unjoinable and break the relational metamodel; generic `d1..d8` columns would be lossy and re-create the positional-index failure class. A child table is what this metamodel already does for every one-to-many, and it joins natively on the M-ADR 0205 §4.1 engine.
3597
+ foreign_keys:
3598
+ - column: quality_score_id
3599
+ references: quality_scores.id
3600
+ nullable: false
3601
+ scaffolds:
3602
+ primary_key: id
3603
+ columns:
3604
+ - name: id
3605
+ type: string
3606
+ nullable: false
3607
+ description: "PK: the manifest's declared unit id (kebab-case slug). Unique per SDD; the aggregator namespaces cross-SDD ids exactly as for every other catalogue."
3608
+ - name: name
3609
+ type: string
3610
+ nullable: false
3611
+ description: Human-readable name of the unit of work, from the manifest.
3612
+ - name: status
3613
+ type: string
3614
+ nullable: false
3615
+ description: Authored lifecycle — see the scaffold_status enum. `closed` is a recorded act of the author (M-ADR 0207 §4.3); the delta instrument reports a closed scaffold whose delta is not zero, it never closes one.
3616
+ - name: source_path
3617
+ type: string
3618
+ nullable: false
3619
+ description: Repo-relative path of the manifest this row derives from, e.g. orchestration/scaffolds/payments-settlement.yaml.
3620
+ - name: corpus_ref
3621
+ type: string
3622
+ nullable: false
3623
+ description: "The commit the scaffold was declared against — the staleness anchor, mirroring quality_scores.corpus_ref (M-ADR 0207 §4.6: one staleness idiom, not two). Required: a manifest without one fails validation rather than emitting an unanchorable row."
3624
+ - name: manifest_schema
3625
+ type: string
3626
+ nullable: false
3627
+ description: The scaffold manifest format version the file declared (scaffold_schema field), so format evolution is diffable and a future migration can state its denominator.
3628
+ - name: sdd_id
3629
+ type: string
3630
+ nullable: true
3631
+ description: SDD whose manifest authored this row. Soft FK to products.id — nullable because a scaffold can be declared in an SDD that emits no product row.
3632
+ - name: source_sdd_id
3633
+ type: string
3634
+ nullable: true
3635
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134; left empty by per-SDD builders.
3636
+ - name: platform_sdd_id
3637
+ type: string
3638
+ nullable: true
3639
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
3640
+ description: |
3641
+ Forward scaffold declaration, one row per unit of work, per M-ADR 0207 §4.1. Source: `orchestration/scaffolds/*.yaml` — the authored surface stays YAML because a scaffold is a declaration of intent, authored where the work is scoped; these rows are DERIVED and never edited (M-ADR 0205 §4.0 governs unchanged).
3642
+ The scaffold states the catalogue shape a unit of work will comprise — its items are `scaffold_items` rows — and the declared-vs-derived delta against the built catalogues is the unit's definition of done: delta zero (structural) AND every realised artefact score-current (content, via `quality_scores`), per M-ADR 0207 §4.5. The unit is the change-set's declared delta; estate-level scaffold totality is an explicit non-goal (M-ADR 0207 §4.4), so an estate region no scaffold covers produces no finding.
3643
+ `corpus_ref` is REQUIRED — a scaffold without an anchor cannot carry a staleness verdict, and M-ADR 0207 §4.6 makes the anchor part of the declaration, not an optional refinement. Staleness itself is computed at coverage time (the scores idiom), never stored here.
3644
+ foreign_keys:
3645
+ - column: sdd_id
3646
+ references: products.id
3647
+ nullable: true
3648
+ column_enums:
3649
+ status: enums.scaffold_status
3650
+ scaffold_items:
3651
+ primary_key: id
3652
+ columns:
3653
+ - name: id
3654
+ type: string
3655
+ nullable: false
3656
+ description: "PK: {scaffold_id}__{item_kind}__{target_kind}__{target_ref}. Composite in one slug because the natural key is a quadruple and the rest of this schema keys on a single `id`."
3657
+ - name: scaffold_id
3658
+ type: string
3659
+ nullable: false
3660
+ description: The scaffold this item belongs to.
3661
+ - name: item_kind
3662
+ type: string
3663
+ nullable: false
3664
+ description: Grain of the declaration — see the scaffold_item_kind enum.
3665
+ - name: target_kind
3666
+ type: string
3667
+ nullable: false
3668
+ description: Catalogue the target should appear in, in the schema's own catalogue vocabulary. Validated against the schema by the builder; unknown values are convention findings carrying file, item and value.
3669
+ - name: target_ref
3670
+ type: string
3671
+ nullable: false
3672
+ description: "Identifier of the declared target in the vocabulary of its catalogue: the declared id for entity items, the repo-relative spec path for contract items (matching contracts.spec_path), the builder-computed {source}__{target} endpoint slug for edge items."
3673
+ - name: edge_source_ref
3674
+ type: string
3675
+ nullable: true
3676
+ description: "For edge items: the declared source endpoint, in the vocabulary of the edge catalogue's first FK column (schema declaration order). Empty for entity and contract items."
3677
+ - name: edge_target_ref
3678
+ type: string
3679
+ nullable: true
3680
+ description: "For edge items: the declared target endpoint, second FK column. Empty for entity and contract items."
3681
+ - name: state
3682
+ type: string
3683
+ nullable: false
3684
+ description: Resolution verdict — see the scaffold_item_state enum. Derived, never authored; recomputed on every build, so realisation flips rows exactly when the target lands.
3685
+ - name: source_sdd_id
3686
+ type: string
3687
+ nullable: true
3688
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3689
+ - name: platform_sdd_id
3690
+ type: string
3691
+ nullable: true
3692
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4 (preserve-if-set, fill rule by pull path); left empty by per-SDD builders. Added in 3.7.0.
3693
+ description: |
3694
+ One declared item of a scaffold — an entity, edge, or contract the unit of work promises — per M-ADR 0207 §4.1. Derived from the manifest's item list; `state` is the builder's resolution verdict against the same build's catalogue rows.
3695
+ THE POLYMORPHIC TARGET DECLARES NO FOREIGN KEY, by design (the quality_scores.target_ref precedent, taken further): a scaffold exists to reference targets BEFORE they exist. FK truth here is CONDITIONAL ON STATE — a `declared` item's (target_kind, target_ref) MUST NOT resolve in the built catalogues, a `realised` item's MUST — and the builder's resolution pass is what enforces it: it computes `state` FROM resolution, so a disagreement between state and resolution cannot be emitted by a conforming builder. The M-ADR 0207 §4.8 delta instrument re-derives the same verdict on the engine as its self-check.
3696
+ `target_kind` is the CATALOGUE NAME the target should appear in (services, capabilities, repo_contract, contracts, …) — bound to the schema's own catalogue list by the builder: an unknown target_kind is a loud convention finding, never a silently-dropped item (M-ADR 0207 §4.1). For `edge` items the endpoints are declared in edge_source_ref/edge_target_ref, mapped to the edge catalogue's FK columns in schema declaration order; target_ref then carries the builder-computed endpoint slug so the PK stays single-column.
3697
+ foreign_keys:
3698
+ - column: scaffold_id
3699
+ references: scaffolds.id
3700
+ nullable: false
3701
+ column_enums:
3702
+ item_kind: enums.scaffold_item_kind
3703
+ state: enums.scaffold_item_state
3704
+ implementations:
3705
+ primary_key: id
3706
+ columns:
3707
+ - name: id
3708
+ type: string
3709
+ nullable: false
3710
+ description: The binding's implementation key — the same value every snapshot manifest of this implementation carries as implementation.
3711
+ - name: name
3712
+ type: string
3713
+ nullable: false
3714
+ description: The binding's name key, else the id.
3715
+ - name: spec
3716
+ type: string
3717
+ nullable: false
3718
+ description: The spec this implementation implements — the binding's spec key.
3719
+ - name: snapshot_area
3720
+ type: string
3721
+ nullable: true
3722
+ description: Store-relative path of this implementation's snapshot area (M-ADR 0214 §4.4), from the binding. Empty when the implementation has none.
3723
+ - name: doc_path
3724
+ type: string
3725
+ nullable: false
3726
+ description: Path of the binding file, relative to the SDD root.
3727
+ - name: source_sdd_id
3728
+ type: string
3729
+ nullable: true
3730
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3731
+ - name: platform_sdd_id
3732
+ type: string
3733
+ nullable: true
3734
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4.
3735
+ description: "An implementation of this SDD's spec: the durable system identity whose snapshots are its versions (M-ADR 0181 §2.5, M-ADR 0214 §4.1). One row per .sdd/implementation-binding.yaml that names its implementation; a binding without an implementation key emits nothing and a finding, because there is no identity to key on."
3736
+ implementation_members:
3737
+ primary_key: id
3738
+ columns:
3739
+ - name: id
3740
+ type: string
3741
+ nullable: false
3742
+ description: <implementation_id>::<repo_key>.
3743
+ - name: implementation_id
3744
+ type: string
3745
+ nullable: false
3746
+ - name: repo_id
3747
+ type: string
3748
+ nullable: true
3749
+ description: The member's repository when it resolves in this SDD's repositories. Empty for a planned member whose repository does not exist yet; a member of any other lifecycle that does not resolve is a builder finding.
3750
+ - name: repo_key
3751
+ type: string
3752
+ nullable: false
3753
+ description: The repository the binding names (its member repo key), resolved or not.
3754
+ - name: role
3755
+ type: string
3756
+ nullable: true
3757
+ - name: lifecycle
3758
+ type: string
3759
+ nullable: true
3760
+ - name: evidence_direction
3761
+ type: string
3762
+ nullable: true
3763
+ description: How this member is evidenced (M-ADR 0180 §2.1, placed on the member by M-ADR 0181 §2.1). Empty when the binding does not say.
3764
+ - name: source_sdd_id
3765
+ type: string
3766
+ nullable: true
3767
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3768
+ - name: platform_sdd_id
3769
+ type: string
3770
+ nullable: true
3771
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4.
3772
+ description: "Edge: a repository is a member of an implementation, with the member's role, lifecycle and evidence direction (M-ADR 0181 §2.1, M-ADR 0214 §4.2). Role and lifecycle live here once: repo_capability, repo_contract and feature_repo resolve their repository to this row rather than copying them (M-ADR 0214 §4.3). Membership is independent of the repository's repo_scope (M-ADR 0213): a shared library under conformance checks is a support member."
3773
+ foreign_keys:
3774
+ - column: implementation_id
3775
+ references: implementations.id
3776
+ nullable: false
3777
+ - column: repo_id
3778
+ references: repositories.id
3779
+ nullable: true
3780
+ column_enums:
3781
+ role: enums.implementation_role
3782
+ lifecycle: enums.implementation_lifecycle
3783
+ evidence_direction: enums.evidence_direction
3784
+ snapshots:
3785
+ primary_key: id
3786
+ columns:
3787
+ - name: id
3788
+ type: string
3789
+ nullable: false
3790
+ description: <implementation_id>@<baseline_id>.
3791
+ - name: implementation_id
3792
+ type: string
3793
+ nullable: false
3794
+ - name: baseline_id
3795
+ type: string
3796
+ nullable: false
3797
+ description: The observation date (YYYY-MM-DD) — the baseline folder and the manifest's snapshot_id.
3798
+ - name: prior_snapshot_id
3799
+ type: string
3800
+ nullable: true
3801
+ description: The snapshot this one was diffed from — <implementation_id>@<prior_snapshot>. Empty for the first.
3802
+ - name: credential_scan_result
3803
+ type: string
3804
+ nullable: true
3805
+ description: The manifest's credential_scan.result (clean, or what was found). Empty when no scan is recorded.
3806
+ - name: source_sdd_id
3807
+ type: string
3808
+ nullable: true
3809
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3810
+ - name: platform_sdd_id
3811
+ type: string
3812
+ nullable: true
3813
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4.
3814
+ description: One implementation's member set pinned at one observation (M-ADR 0181 §2.5, M-ADR 0214 §4.4). One row per dated baseline in the implementation's snapshot area whose snapshot.yaml names the same implementation. Needs the snapshot store root (build --snapshot-store or SDD_SNAPSHOT_STORE); without it the catalogue is empty and the build says so.
3815
+ foreign_keys:
3816
+ - column: implementation_id
3817
+ references: implementations.id
3818
+ nullable: false
3819
+ - column: prior_snapshot_id
3820
+ references: snapshots.id
3821
+ nullable: true
3822
+ snapshot_members:
3823
+ primary_key: id
3824
+ columns:
3825
+ - name: id
3826
+ type: string
3827
+ nullable: false
3828
+ description: <snapshot_id>::<repo_key>.
3829
+ - name: snapshot_id
3830
+ type: string
3831
+ nullable: false
3832
+ - name: repo_id
3833
+ type: string
3834
+ nullable: true
3835
+ description: The member's repository when it resolves in this SDD's repositories; empty otherwise (a removed member's repository may be gone).
3836
+ - name: repo_key
3837
+ type: string
3838
+ nullable: false
3839
+ description: The manifest's canonical_repo_key.
3840
+ - name: source_revision
3841
+ type: string
3842
+ nullable: false
3843
+ description: The revision observed (for a removed member, its last revision).
3844
+ - name: observed_at
3845
+ type: string
3846
+ nullable: true
3847
+ description: "The member's own observation date: the baseline's for an observed member, the earlier one for a carried member, the last observed for a removed one."
3848
+ - name: presence
3849
+ type: string
3850
+ nullable: false
3851
+ - name: source_sdd_id
3852
+ type: string
3853
+ nullable: true
3854
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3855
+ - name: platform_sdd_id
3856
+ type: string
3857
+ nullable: true
3858
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator per M-ADR 0208 §4.4.
3859
+ description: "Edge: a repository at one revision in one snapshot, with its presence — observed in this baseline, carried from an earlier one, or removed since the prior (M-ADR 0214 §4.4)."
3860
+ foreign_keys:
3861
+ - column: snapshot_id
3862
+ references: snapshots.id
3863
+ nullable: false
3864
+ - column: repo_id
3865
+ references: repositories.id
3866
+ nullable: true
3867
+ column_enums:
3868
+ presence: enums.member_presence
3869
+ data_items:
3870
+ primary_key: id
3871
+ columns:
3872
+ - name: id
3873
+ type: string
3874
+ nullable: false
3875
+ description: di.<category>.<name>, e.g. di.motion.speed.
3876
+ - name: name
3877
+ type: string
3878
+ nullable: false
3879
+ - name: category
3880
+ type: string
3881
+ nullable: false
3882
+ description: Open grouping (motion, behaviour, tyre, energy, …).
3883
+ - name: canonical_field
3884
+ type: string
3885
+ nullable: true
3886
+ description: The integration-facing canonical contract field that carries the item. EMPTY means the platform has no canonical home for it, and coverage reads every requirement on it as unmet (no-canonical-home).
3887
+ - name: description
3888
+ type: string
3889
+ nullable: true
3890
+ - name: source_sdd_id
3891
+ type: string
3892
+ nullable: true
3893
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3894
+ - name: platform_sdd_id
3895
+ type: string
3896
+ nullable: true
3897
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator (M-ADR 0208 §4.4).
3898
+ description: "A unit of data an integration may supply and a feature may need, at the canonical boundary (M-ADR 0216 §4.1). Platform-owned, like events. Not a wire signal: payload grammar stays adopter territory."
3899
+ integration_data_item:
3900
+ primary_key: id
3901
+ columns:
3902
+ - name: id
3903
+ type: string
3904
+ nullable: false
3905
+ description: <integration_id>::<data_item_id>::<evidence_ref>.
3906
+ - name: integration_id
3907
+ type: string
3908
+ nullable: false
3909
+ - name: data_item_id
3910
+ type: string
3911
+ nullable: false
3912
+ - name: verdict
3913
+ type: string
3914
+ nullable: false
3915
+ description: Bound to supply_verdict. A mapping-table row is supported, or partial when its Notes begin with partial; the Data Items Not Supplied section carries the rest.
3916
+ - name: basis
3917
+ type: string
3918
+ nullable: true
3919
+ description: "Bound to supply_basis: the evidence class of the statement."
3920
+ - name: evidence_ref
3921
+ type: string
3922
+ nullable: false
3923
+ description: Path and line of the statement.
3924
+ - name: checked_at
3925
+ type: string
3926
+ nullable: true
3927
+ description: "The governing Checked: line of the section, verbatim (a date, or a source revision). Reported for age; never read as a verdict."
3928
+ - name: source_sdd_id
3929
+ type: string
3930
+ nullable: true
3931
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3932
+ - name: platform_sdd_id
3933
+ type: string
3934
+ nullable: true
3935
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator (M-ADR 0208 §4.4).
3936
+ description: "Supply: what one integration states about one data item, from its feature-grounding (M-ADR 0216 §4.2). Several rows per item are normal (one per evidence_ref); coverage reads the best. No row reads unknown, and unknown is never written."
3937
+ foreign_keys:
3938
+ - column: integration_id
3939
+ references: integrations.id
3940
+ nullable: false
3941
+ - column: data_item_id
3942
+ references: data_items.id
3943
+ nullable: false
3944
+ external_for_profiles:
3945
+ - application-product
3946
+ - integration-product
3947
+ column_enums:
3948
+ verdict: enums.supply_verdict
3949
+ basis: enums.supply_basis
3950
+ feature_data_requirement:
3951
+ primary_key: id
3952
+ columns:
3953
+ - name: id
3954
+ type: string
3955
+ nullable: false
3956
+ description: <feature_id>::<data_item_id>.
3957
+ - name: feature_id
3958
+ type: string
3959
+ nullable: false
3960
+ - name: data_item_id
3961
+ type: string
3962
+ nullable: false
3963
+ - name: necessity
3964
+ type: string
3965
+ nullable: false
3966
+ description: Bound to data_necessity.
3967
+ - name: alternative_group
3968
+ type: string
3969
+ nullable: true
3970
+ description: "Empty, or a label: required rows sharing a label are satisfied by any one of them."
3971
+ - name: basis_ref
3972
+ type: string
3973
+ nullable: true
3974
+ description: Where the need is stated (path and line).
3975
+ - name: source_sdd_id
3976
+ type: string
3977
+ nullable: true
3978
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
3979
+ - name: platform_sdd_id
3980
+ type: string
3981
+ nullable: true
3982
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator (M-ADR 0208 §4.4).
3983
+ description: "Demand: a data item one feature needs, from the feature spec's Data Requirements table (M-ADR 0216 §4.3). Feature grain only: a capability's need is the union of its features'."
3984
+ foreign_keys:
3985
+ - column: feature_id
3986
+ references: features.id
3987
+ nullable: false
3988
+ - column: data_item_id
3989
+ references: data_items.id
3990
+ nullable: false
3991
+ external_for_profiles:
3992
+ - application-product
3993
+ - integration-product
3994
+ column_enums:
3995
+ necessity: enums.data_necessity
3996
+ feature_integration_support:
3997
+ primary_key: id
3998
+ columns:
3999
+ - name: id
4000
+ type: string
4001
+ nullable: false
4002
+ description: <feature_id>::<integration_id>.
4003
+ - name: feature_id
4004
+ type: string
4005
+ nullable: false
4006
+ - name: integration_id
4007
+ type: string
4008
+ nullable: false
4009
+ - name: verdict
4010
+ type: string
4011
+ nullable: false
4012
+ description: "Bound to support_verdict. Each requirement is decided first (an alternative_group is unmet only when every member is); the feature takes the worst: unsupported > unknown > partial > supported. not-applicable only when every required item is."
4013
+ - name: limiting_item_id
4014
+ type: string
4015
+ nullable: true
4016
+ description: "For unsupported: the deciding requirement's item. Empty otherwise."
4017
+ - name: limiting_reason
4018
+ type: string
4019
+ nullable: true
4020
+ description: "For unsupported: bound to limiting_reason. Empty otherwise."
4021
+ - name: source_sdd_id
4022
+ type: string
4023
+ nullable: true
4024
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
4025
+ - name: platform_sdd_id
4026
+ type: string
4027
+ nullable: true
4028
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator (M-ADR 0208 §4.4).
4029
+ description: "Coverage: whether one integration can support one feature, DERIVED at aggregation from supply and demand (M-ADR 0216 §4.4); empty in a member build. SUPPORTED MEANS THE ITEMS REACH THE CANONICAL BOUNDARY, NOT THAT THE FEATURE WORKS END TO END: routing past that boundary is not checked."
4030
+ foreign_keys:
4031
+ - column: feature_id
4032
+ references: features.id
4033
+ nullable: false
4034
+ - column: integration_id
4035
+ references: integrations.id
4036
+ nullable: false
4037
+ - column: limiting_item_id
4038
+ references: data_items.id
4039
+ nullable: true
4040
+ column_enums:
4041
+ verdict: enums.support_verdict
4042
+ limiting_reason: enums.limiting_reason
4043
+ evidence_target_repo:
4044
+ primary_key: id
4045
+ columns:
4046
+ - name: id
4047
+ type: string
4048
+ nullable: false
4049
+ description: <evidence_path>::<repo_id>.
4050
+ - name: evidence_path
4051
+ type: string
4052
+ nullable: false
4053
+ description: The evidence file, relative to the SDD root.
4054
+ - name: repo_id
4055
+ type: string
4056
+ nullable: false
4057
+ description: The repository the evidence concerns. Another SDD's by definition, so external at build; it must resolve at aggregation.
4058
+ - name: source_sdd_id
4059
+ type: string
4060
+ nullable: true
4061
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
4062
+ - name: platform_sdd_id
4063
+ type: string
4064
+ nullable: true
4065
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator (M-ADR 0208 §4.4).
4066
+ description: "A reverse evidence file names a repository another SDD owns, through its top-level target_repo (M-ADR 0214 §4.10). A reference, never a claim: the repository is described by exactly one SDD, elsewhere."
4067
+ foreign_keys:
4068
+ - column: repo_id
4069
+ references: repositories.id
4070
+ nullable: false
4071
+ external: true
4072
+ repo_dependency:
4073
+ primary_key: id
4074
+ columns:
4075
+ - name: id
4076
+ type: string
4077
+ nullable: false
4078
+ description: <from_repo_id>__<to_repo_id>__<kind>.
4079
+ - name: from_repo_id
4080
+ type: string
4081
+ nullable: false
4082
+ description: The dependent repository; one of this SDD's own.
4083
+ - name: to_repo_id
4084
+ type: string
4085
+ nullable: false
4086
+ description: The repository depended on, in this SDD or another. External at build; it must resolve at aggregation, and is never renamed or guessed to make it resolve.
4087
+ - name: kind
4088
+ type: string
4089
+ nullable: false
4090
+ description: Bound to repo_dependency_kind.
4091
+ - name: version
4092
+ type: string
4093
+ nullable: true
4094
+ description: The version or reference depended on, where the source states one; empty otherwise. The declared source wins over the derived one.
4095
+ - name: declared_in
4096
+ type: string
4097
+ nullable: false
4098
+ description: The file the row came from, relative to the SDD root; the declared source when both name the dependency.
4099
+ - name: source_sdd_id
4100
+ type: string
4101
+ nullable: true
4102
+ description: Originating SDD slug. Populated by the aggregator per M-ADR 0134.
4103
+ - name: platform_sdd_id
4104
+ type: string
4105
+ nullable: true
4106
+ description: The platform this row belongs to — sdd_id of its platform-root. Stamped by the aggregator (M-ADR 0208 §4.4).
4107
+ description: "Edge: a repository depends on another repository's code without either being a running service — a library linked at build time, or a template family it was generated from (M-ADR 0217). The depended-on repository may belong to another SDD, which describes it; this row only references it."
4108
+ foreign_keys:
4109
+ - column: from_repo_id
4110
+ references: repositories.id
4111
+ nullable: false
4112
+ - column: to_repo_id
4113
+ references: repositories.id
4114
+ nullable: false
4115
+ external: true
4116
+ column_enums:
4117
+ kind: enums.repo_dependency_kind