wdi-method 0.6.30 → 0.6.32

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 (43) hide show
  1. package/CHANGELOG.md +129 -0
  2. package/NOTICE +7 -2
  3. package/README.md +16 -11
  4. package/bin/wdi-method.js +396 -87
  5. package/kit/.constitution/method/document/architecture-guide.md +217 -209
  6. package/kit/.constitution/method/document/bmad-skill-register.md +107 -104
  7. package/kit/.constitution/method/document/corpus-guide.md +522 -517
  8. package/kit/.constitution/method/document/decision-guide.md +236 -216
  9. package/kit/.constitution/method/document/delivery-flow-guide.md +20 -0
  10. package/kit/.constitution/method/document/prd-guide.md +245 -245
  11. package/kit/.constitution/method/document/templates/design-system.md +96 -66
  12. package/kit/.constitution/method/document/templates/experience.md +62 -0
  13. package/kit/.constitution/method/document/templates/structure-codebase.md +131 -129
  14. package/kit/.constitution/method/document/templates/ux.md +78 -76
  15. package/kit/.constitution/method/document/ux-guide.md +161 -115
  16. package/kit/.constitution/method/method-glossary.md +3 -0
  17. package/kit/.constitution/method/scripts/validate.py +3375 -3200
  18. package/kit/.constitution/method/structure-guide.md +204 -202
  19. package/kit/.constitution/method/why/README.md +1 -1
  20. package/kit/.constitution/method/why/artifact-map.md +158 -157
  21. package/kit/.constitution/method/why/portability.md +19 -2
  22. package/kit/skills/wdi-autopilot/SKILL.md +32 -19
  23. package/kit/skills/wdi-blueprint/SKILL.md +271 -264
  24. package/kit/skills/wdi-build/SKILL.md +28 -19
  25. package/kit/skills/wdi-component/SKILL.md +179 -174
  26. package/kit/skills/wdi-daily-autopilot/SKILL.md +24 -13
  27. package/kit/skills/wdi-daily-what-to-build/SKILL.md +9 -6
  28. package/kit/skills/wdi-daily-what-to-test/SKILL.md +2 -0
  29. package/kit/skills/wdi-decision/SKILL.md +206 -203
  30. package/kit/skills/wdi-explain-to-me/SKILL.md +2 -0
  31. package/kit/skills/wdi-help/SKILL.md +130 -125
  32. package/kit/skills/wdi-init/SKILL.md +10 -5
  33. package/kit/skills/wdi-problem/SKILL.md +114 -108
  34. package/kit/skills/wdi-product/SKILL.md +167 -162
  35. package/kit/skills/wdi-prune-or-archive/SKILL.md +2 -0
  36. package/kit/skills/wdi-reconcile/SKILL.md +170 -169
  37. package/kit/skills/wdi-upgrade/SKILL.md +234 -215
  38. package/kit/skills/wdi-ux/SKILL.md +187 -169
  39. package/kit-overlay/AGENTS.md +15 -2
  40. package/kit-overlay/portability.md +19 -2
  41. package/lib/platforms.mjs +420 -248
  42. package/package.json +1 -1
  43. package/scaffold/.control/registry/index.yaml +2 -1
@@ -1,209 +1,217 @@
1
- ---
2
- status: Accepted
3
- ---
4
-
5
- # Architecture Guide
6
-
7
- **Loaded when:** writing or changing the architecture spine, an `AD-N`, or the C4 set
8
-
9
- The spine holds the invariants that stop separately built components from diverging. It is not a design
10
- document — one component's design is its `SDD-<pc>.md`. If a statement only affects one component, it does
11
- not belong here.
12
-
13
- The spine, the C4 set, `cross-cutting.md`, and the three inventories are all **G3 Blueprint** output, written
14
- by `wdi-blueprint` intent `platform`. All of them exist at every `mode`, including `catalog`: they belong to
15
- the blueprint, and the blueprint is not touched by the depth knob.
16
-
17
- ## Home
18
-
19
- `.how/_platform/ARCHITECTURE-SPINE.md` — a file directly in `_platform/`. The `architecture/` sub-folder is
20
- **repealed**; one file does not earn a folder, and the extra level made the spine harder to find than the
21
- things it constrains.
22
-
23
- ## Invariants only
24
-
25
- An entry earns a place when breaking it in one component would break another. Everything else is a **seed**:
26
- useful as a starting point, not binding.
27
-
28
- | Kind of statement | Spine? |
29
- |---|---|
30
- | "Every service authenticates through the same token format" | Yes — invariant |
31
- | "Money is stored as integer minor units, never float" | Yes — invariant |
32
- | "We use version 11 of our database and version 1.23 of our language" | No — seed. It informs, it does not forbid |
33
- | "The repo is laid out as one folder per deployable" | No — seed, and `structure-codebase.md` describes it |
34
- | "The member portal caches its dashboard for 60 seconds" | No — one component's design |
35
-
36
- Stack, tree shape, and data shapes are seeds and MUST be marked as such. Writing them as contracts makes the
37
- spine wrong the first time anything is upgraded, and a spine that is wrong in a visible place stops being
38
- read in the places where it is right.
39
-
40
- ## Every `AD-N` carries three things
41
-
42
- | Field | States |
43
- |---|---|
44
- | **Binds** | Which components or containers this holds for. "All" is a valid answer and MUST be written, not left blank |
45
- | **Prevents** | The concrete failure this exists to stop. Written as the thing going wrong, not as a principle |
46
- | **Rule** | One sentence, quotable, checkable. If a reviewer cannot tell whether code obeys it, it is not a rule yet |
47
-
48
- An `AD-N` with no **Prevents** is a preference. Preferences belong in
49
- `.constitution/project/codebase-conventions-guide.md`, where nothing has to justify itself.
50
-
51
- ## The spine stops being touched every ticket
52
-
53
- This is the change that ends the tax that was being paid before the information existed.
54
-
55
- - **The spine holds invariants and nothing else.** It changes only when an `AD-N` is born or reversed, and
56
- both are decision events. For a mid-sized product: once at the start, around 6–10 `AD-N`, then almost
57
- never.
58
- - **A ticket MUST NOT touch the spine.** A ticket that contradicts an `AD-N` **stops** and opens a `DEC-` —
59
- the one case where recording a decision is still mandatory.
60
- - **Editing an `AD-N` MUST NOT quietly reverse it.** A reversal is a decision, and it goes through
61
- `wdi-decision` first.
62
- - **An inventory is not the spine.** The three inventories are living registers, derived from code once code
63
- exists. A plan-versus-reality difference is a validator finding, not a spine amendment.
64
-
65
- ## `AD-N` versus `DEC-NNN`
66
-
67
- `AD-N` is a **living rule**, edited in place as understanding improves. `DEC-NNN` is a **decision event**,
68
- never edited once `applied`, only superseded.
69
-
70
- An `AD-N` usually has a `DEC-` behind it: the invariant is what people obey, the decision record is why it
71
- exists and what it cost. The full comparison is in `decision-guide.md` and MUST NOT be restated here.
72
-
73
- The spine MUST NOT name a decision's alternatives or its cost. Those live in the `DEC-` behind it; repeating
74
- them here creates a second version that will drift.
75
-
76
- ## The C4 set, and what else a run produces
77
-
78
- `bmad-architecture` runs at **initiative** altitude for the spine. Anything else the run produces at feature
79
- altitude — a deck, a fuller solution document — is a **rendering**, not the spine, and the two MUST NOT be
80
- confused:
81
-
82
- | Rendering | Has a slot | What follows |
83
- |---|---|---|
84
- | The **C4 set** — L1, L2, and one L3 per `built: true` container **holding more than one Product Component** | Yes: `.how/_platform/c4-l1-system-context.md` · `c4-l2-containers.md` · `c4-l3-<container>.md` | `wdi-blueprint` lands it, amending rather than overwriting. Once landed it is corpus, and `c4-l2-containers.md` **owns** the container list. The next section owns what a container *is* |
85
- | Deck, solution document, anything else | No | Stays in the run folder, cited by path, never promoted |
86
-
87
- **Placement is what makes a C4 binding, and only for what its level owns.** Before placement it is one run's
88
- drawing; after, it is the corpus's description of the system. The spine still wins on any invariant, because
89
- the C4 set describes and the spine forbids. A C4 file MUST NOT be used to justify a rule; a rule that matters
90
- belongs in an `AD-N`.
91
-
92
- The C4 set is **living**. It is amended when a container is added or changed — it MUST NOT be regenerated from
93
- scratch, which would drop the annotations three specs of amendment put there.
94
-
95
- ## What counts as a container, and what does not
96
-
97
- Two questions, and **both MUST be yes**:
98
-
99
- 1. **Does it run its own code or store its own data?** Its own process, its own browser page, its own
100
- engine — not a folder inside another container's process.
101
- 2. **Can it be replaced without rebuilding another container?** It has its own build or publish path.
102
-
103
- **Shipping two containers in one release does not merge them.** One atomic deploy swapping a binary and
104
- two browser bundles together is a deployment choice, and a deployment choice MUST NOT be read as an
105
- architectural one. The failure this guards against is the quiet one: a browser bundle with its own
106
- JavaScript filed as "static assets" of the web server, carrying real behaviour with no row, no owner, and
107
- no NFR. Handwritten HTML that runs **no** code of its own is content the web server delivers; the moment
108
- it carries a script, it passes question 1.
109
-
110
- ### `built` — the one boolean, and its four consequences
111
-
112
- A container is inside the boundary whether or not we wrote it. `built:` records which:
113
-
114
- | | `built: true` | `built: false` |
115
- |---|---|---|
116
- | An L3 | Yes, where it holds more than one PC | **Never.** No box inside it is ours to draw |
117
- | An `LC` naming it as `container` | Yes | **Never** |
118
- | A heading in `structure-codebase.md` | **Required** | **Never** — no code of ours lives there |
119
- | Listed in a PC's `containers:` | Yes | **Never** — see the matrix below |
120
-
121
- `container-built` checks all four. This is what makes the class settled rather than re-argued: a database and a web
122
- server are containers, they carry NFRs, and they still produce no design artifact of ours.
123
-
124
- **What IS ours about a `built: false` container MUST have a home outside the C4 set** — its configuration
125
- and any invariant it enforces belong in an `AD-N` or in `cross-cutting.md`. A rule surviving only as a
126
- note beside a C4 box is a rule nobody can find.
127
-
128
- ### External system — outside the boundary
129
-
130
- **The line is who deploys the runtime.** We deploy it, whoever wrote it → container. Someone else
131
- runs it and we call it or configure it through their control plane → external system.
132
-
133
- An external system appears at **C4 L1 and nowhere else**. It MUST NOT be registered in `containers`,
134
- MUST NOT be an `LC`'s `container`, and MUST NOT get a heading in the codebase map. What the product
135
- depends on it for lives in `cross-cutting.md` or an integration contract.
136
-
137
- ### The PC × container matrix
138
-
139
- A PC and a container cross, so neither list implies the other — and the crossing is what a builder needs
140
- first: *which container does this promise live in, and is it more than one?*
141
-
142
- - The **SSOT is each PC's `containers:`** in `components.yaml`; C4 L2 renders it, and `container-built` fails when the
143
- two disagree.
144
- - Complete at **G3** for every PC. It is blueprint content, so `mode` does not touch it.
145
- - A PC MUST list every `built: true` container it lives in. Listing only the main one is the error the
146
- matrix exists to catch.
147
-
148
- ### Which C4 files exist, and when
149
-
150
- `artifact-map.md` owns the schedule: all three at **G3**, at every `mode`. Two conditions belong here.
151
-
152
- **L2 MUST be complete** — every container, plus the matrix. **L3 exists once per `built: true` container
153
- holding more than one PC**; a one-PC container needs none because the matrix already places it.
154
-
155
- **Not one of the three waits for a spec.** Which container a PC lives in cannot be discovered by a spec,
156
- because a spec picks its tickets from that answer — a spec forced to invent it answers a G3 question with
157
- a fraction of G3's information.
158
-
159
- ## Cross-cutting
160
-
161
- `.how/_platform/cross-cutting.md` holds what is defined once for the whole product, the error envelope first
162
- among them. Every contract references it rather than restating it.
163
-
164
- A rule that belongs there MUST NOT also be written as an `AD-N` unless breaking it in one component breaks
165
- another. One fact, one home.
166
-
167
- **The platform MAY own things, and owning one costs a row here.** `_platform` is a legitimate owner in every
168
- position that asks which component owns something — a domain entity through `platform_owns`, an inventory row,
169
- an `LC`. Whatever it owns MUST be described under `## Platform-owned` in this file: what it is, its kind, why
170
- no component's promise explains it, who touches it, and the shape every toucher obeys. `entity-one-writer` checks that second
171
- half, because a platform that owns something without documenting it has taken ownership without taking
172
- responsibility.
173
-
174
- Four kinds qualify today — data, endpoint, job, screen — and the list is open. What is **not** open is the
175
- test, and `corpus-guide.md` owns it: no single component's promise explains it, **and** more than one
176
- component depends on it. Failing either half, it belongs to a component.
177
-
178
- `_platform` is **not** a Product Component — `corpus-guide.md` owns that distinction and the test for when an
179
- entity legitimately belongs here. It has no `mode` and no `risk_accepted`: the documents in this folder exist
180
- at every mode.
181
-
182
- ## Binding order
183
-
184
- Spine first, then the SDD, then the spec's contract. An `SDD-<pc>.md` written before the spine will be rewritten,
185
- because the constraints it was supposed to inherit did not exist yet. A `SPEC.md` written before the SDD has
186
- nothing to project. `AD` ids MUST stay stable so downstream artifacts can cite them.
187
-
188
- ## Inheritance downward
189
-
190
- From `mode: guarded` up, every `AD-N` that reaches a component MUST appear in that component's SDD under
191
- **Inherited Constraints**, quoted rather than paraphrased. Below `guarded` the quoting is not written, and the
192
- spine still binds — an invariant does not stop holding because a document is thin.
193
-
194
- ## Review is manual here
195
-
196
- `bmad-architecture` excludes the spine from `doc_standards` deliberately — the spine is terse by design and
197
- prose polish softens rules that need to stay rigid. Two consequences:
198
-
199
- - This guide is installed as `persistent_facts`, not `doc_standards`.
200
- - `bmad-review` over the spine MUST be invoked through `wdi-review` before G3 closes.
201
-
202
- ## Rules
203
-
204
- - The spine MUST stay short enough to be read in one sitting. An `AD-N` nobody remembers is not an invariant,
205
- it is a document.
206
- - An `AD-N` MUST NOT be added because something feels important. The test is only ever: does breaking this in
207
- one place break another?
208
- - Structure statements MUST be marked as seeds, and MUST NOT be checked as if they were rules.
209
- - Memlog goes to `.control/memlog/spine.md` via `--path`, never beside the spine.
1
+ ---
2
+ status: Accepted
3
+ ---
4
+
5
+ # Architecture Guide
6
+
7
+ **Loaded when:** writing or changing the architecture spine, an `AD-N`, or the C4 set
8
+
9
+ The spine holds the invariants that stop separately built components from diverging. It is not a design
10
+ document — one component's design is its `SDD-<pc>.md`. If a statement only affects one component, it does
11
+ not belong here.
12
+
13
+ The spine, the C4 set, `cross-cutting.md`, and the three inventories are all **G3 Blueprint** output, written
14
+ by `wdi-blueprint` intent `platform`. All of them exist at every `mode`, including `catalog`: they belong to
15
+ the blueprint, and the blueprint is not touched by the depth knob.
16
+
17
+ ## Home
18
+
19
+ `.how/_platform/ARCHITECTURE-SPINE.md` — a file directly in `_platform/`. The `architecture/` sub-folder is
20
+ **repealed**; one file does not earn a folder, and the extra level made the spine harder to find than the
21
+ things it constrains.
22
+
23
+ ## Invariants only
24
+
25
+ An entry earns a place when breaking it in one component would break another. Everything else is a **seed**:
26
+ useful as a starting point, not binding.
27
+
28
+ | Kind of statement | Spine? |
29
+ |---|---|
30
+ | "Every service authenticates through the same token format" | Yes — invariant |
31
+ | "Money is stored as integer minor units, never float" | Yes — invariant |
32
+ | "We use version 11 of our database and version 1.23 of our language" | No — seed. It informs, it does not forbid |
33
+ | "The repo is laid out as one folder per deployable" | No — seed, and `structure-codebase.md` describes it |
34
+ | "The member portal caches its dashboard for 60 seconds" | No — one component's design |
35
+
36
+ Stack, tree shape, and data shapes are seeds and MUST be marked as such. Writing them as contracts makes the
37
+ spine wrong the first time anything is upgraded, and a spine that is wrong in a visible place stops being
38
+ read in the places where it is right.
39
+
40
+ ## Every `AD-N` carries three things
41
+
42
+ | Field | States |
43
+ |---|---|
44
+ | **Binds** | Which components or containers this holds for. "All" is a valid answer and MUST be written, not left blank |
45
+ | **Prevents** | The concrete failure this exists to stop. Written as the thing going wrong, not as a principle |
46
+ | **Rule** | One sentence, quotable, checkable. If a reviewer cannot tell whether code obeys it, it is not a rule yet |
47
+
48
+ An `AD-N` with no **Prevents** is a preference. Preferences belong in
49
+ `.constitution/project/codebase-conventions-guide.md`, where nothing has to justify itself.
50
+
51
+ ## The spine stops being touched every ticket
52
+
53
+ This is the change that ends the tax that was being paid before the information existed.
54
+
55
+ - **The spine holds invariants and nothing else.** It changes only when an `AD-N` is born or reversed, and
56
+ both are decision events. For a mid-sized product: once at the start, around 6–10 `AD-N`, then almost
57
+ never.
58
+ - **A ticket MUST NOT touch the spine.** A ticket that contradicts an `AD-N` **stops** and opens a `DEC-` —
59
+ the one case where recording a decision is still mandatory.
60
+ - **Editing an `AD-N` MUST NOT quietly reverse it.** A reversal is a decision, and it goes through
61
+ `wdi-decision` first.
62
+ - **An inventory is not the spine.** The three inventories are living registers, derived from code once code
63
+ exists. A plan-versus-reality difference is a validator finding, not a spine amendment.
64
+
65
+ ## `AD-N` versus `DEC-NNN`
66
+
67
+ `AD-N` is a **living rule**, edited in place as understanding improves. `DEC-NNN` is a **decision event**,
68
+ never edited once `applied`, only superseded.
69
+
70
+ An `AD-N` usually has a `DEC-` behind it: the invariant is what people obey, the decision record is why it
71
+ exists and what it cost. The full comparison is in `decision-guide.md` and MUST NOT be restated here.
72
+
73
+ The spine MUST NOT name a decision's alternatives or its cost. Those live in the `DEC-` behind it; repeating
74
+ them here creates a second version that will drift.
75
+
76
+ ## The C4 set, and what else a run produces
77
+
78
+ `bmad-architecture` runs at **initiative** altitude for the spine. Anything else the run produces at feature
79
+ altitude — a deck, a fuller solution document — is a **rendering**, not the spine, and the two MUST NOT be
80
+ confused:
81
+
82
+ | Rendering | Has a slot | What follows |
83
+ |---|---|---|
84
+ | The **C4 set** — L1, L2, and one L3 per `built: true` container **holding more than one Product Component** | Yes: `.how/_platform/c4-l1-system-context.md` · `c4-l2-containers.md` · `c4-l3-<container>.md` | `wdi-blueprint` lands it, amending rather than overwriting. Once landed it is corpus, and `c4-l2-containers.md` **owns** the container list. The next section owns what a container *is* |
85
+ | Deck, solution document, anything else | No | Stays in the run folder, cited by path, never promoted |
86
+
87
+ **Placement is what makes a C4 binding, and only for what its level owns.** Before placement it is one run's
88
+ drawing; after, it is the corpus's description of the system. The spine still wins on any invariant, because
89
+ the C4 set describes and the spine forbids. A C4 file MUST NOT be used to justify a rule; a rule that matters
90
+ belongs in an `AD-N`.
91
+
92
+ The C4 set is **living**. It is amended when a container is added or changed — it MUST NOT be regenerated from
93
+ scratch, which would drop the annotations three specs of amendment put there.
94
+
95
+ ## What counts as a container, and what does not
96
+
97
+ Two questions, and **both MUST be yes**:
98
+
99
+ 1. **Does it run its own code or store its own data?** Its own process, its own browser page, its own
100
+ engine — not a folder inside another container's process.
101
+ 2. **Can it be replaced without rebuilding another container?** It has its own build or publish path.
102
+
103
+ **Shipping two containers in one release does not merge them.** One atomic deploy swapping a binary and
104
+ two browser bundles together is a deployment choice, and a deployment choice MUST NOT be read as an
105
+ architectural one. The failure this guards against is the quiet one: a browser bundle with its own
106
+ JavaScript filed as "static assets" of the web server, carrying real behaviour with no row, no owner, and
107
+ no NFR. Handwritten HTML that runs **no** code of its own is content the web server delivers; the moment
108
+ it carries a script, it passes question 1.
109
+
110
+ ### `built` — the one boolean, and its four consequences
111
+
112
+ A container is inside the boundary whether or not we wrote it. `built:` records which:
113
+
114
+ | | `built: true` | `built: false` |
115
+ |---|---|---|
116
+ | An L3 | Yes, where it holds more than one PC | **Never.** No box inside it is ours to draw |
117
+ | An `LC` naming it as `container` | Yes | **Never** |
118
+ | A heading in `structure-codebase.md` | **Required** — in the code map of the repo that holds its code | **Never** — no code of ours lives there |
119
+ | Listed in a PC's `containers:` | Yes | **Never** — see the matrix below |
120
+
121
+ `container-built` checks all four.
122
+
123
+ **A product split across repositories adds one field, `repo:`, and only where it is true.** A
124
+ `built: true` container whose code lives in ANOTHER repository names it there. It stays registered,
125
+ stays in C4 L2, and keeps every consequence above — except that its heading belongs to that repository's
126
+ code map, not this one's, and `container-built` refuses one here. Absent `repo:` means this repository,
127
+ so a single-repo product writes nothing and sees no change. `repo:` MUST NOT name this repository —
128
+ `container-built` compares it with the `origin` remote, and reports that it could not when there is none —
129
+ and MUST NOT appear on a `built: false` container: nobody writes that container's code anywhere. This is what makes the class settled rather than re-argued: a database and a web
130
+ server are containers, they carry NFRs, and they still produce no design artifact of ours.
131
+
132
+ **What IS ours about a `built: false` container MUST have a home outside the C4 set** — its configuration
133
+ and any invariant it enforces belong in an `AD-N` or in `cross-cutting.md`. A rule surviving only as a
134
+ note beside a C4 box is a rule nobody can find.
135
+
136
+ ### External system — outside the boundary
137
+
138
+ **The line is who deploys the runtime.** We deploy it, whoever wrote it → container. Someone else
139
+ runs it and we call it or configure it through their control plane → external system.
140
+
141
+ An external system appears at **C4 L1 and nowhere else**. It MUST NOT be registered in `containers`,
142
+ MUST NOT be an `LC`'s `container`, and MUST NOT get a heading in the codebase map. What the product
143
+ depends on it for lives in `cross-cutting.md` or an integration contract.
144
+
145
+ ### The PC × container matrix
146
+
147
+ A PC and a container cross, so neither list implies the other — and the crossing is what a builder needs
148
+ first: *which container does this promise live in, and is it more than one?*
149
+
150
+ - The **SSOT is each PC's `containers:`** in `components.yaml`; C4 L2 renders it, and `container-built` fails when the
151
+ two disagree.
152
+ - Complete at **G3** for every PC. It is blueprint content, so `mode` does not touch it.
153
+ - A PC MUST list every `built: true` container it lives in. Listing only the main one is the error the
154
+ matrix exists to catch.
155
+
156
+ ### Which C4 files exist, and when
157
+
158
+ `artifact-map.md` owns the schedule: all three at **G3**, at every `mode`. Two conditions belong here.
159
+
160
+ **L2 MUST be complete** — every container, plus the matrix. **L3 exists once per `built: true` container
161
+ holding more than one PC**; a one-PC container needs none because the matrix already places it.
162
+
163
+ **Not one of the three waits for a spec.** Which container a PC lives in cannot be discovered by a spec,
164
+ because a spec picks its tickets from that answer — a spec forced to invent it answers a G3 question with
165
+ a fraction of G3's information.
166
+
167
+ ## Cross-cutting
168
+
169
+ `.how/_platform/cross-cutting.md` holds what is defined once for the whole product, the error envelope first
170
+ among them. Every contract references it rather than restating it.
171
+
172
+ A rule that belongs there MUST NOT also be written as an `AD-N` unless breaking it in one component breaks
173
+ another. One fact, one home.
174
+
175
+ **The platform MAY own things, and owning one costs a row here.** `_platform` is a legitimate owner in every
176
+ position that asks which component owns something — a domain entity through `platform_owns`, an inventory row,
177
+ an `LC`. Whatever it owns MUST be described under `## Platform-owned` in this file: what it is, its kind, why
178
+ no component's promise explains it, who touches it, and the shape every toucher obeys. `entity-one-writer` checks that second
179
+ half, because a platform that owns something without documenting it has taken ownership without taking
180
+ responsibility.
181
+
182
+ Four kinds qualify today — data, endpoint, job, screen — and the list is open. What is **not** open is the
183
+ test, and `corpus-guide.md` owns it: no single component's promise explains it, **and** more than one
184
+ component depends on it. Failing either half, it belongs to a component.
185
+
186
+ `_platform` is **not** a Product Component — `corpus-guide.md` owns that distinction and the test for when an
187
+ entity legitimately belongs here. It has no `mode` and no `risk_accepted`: the documents in this folder exist
188
+ at every mode.
189
+
190
+ ## Binding order
191
+
192
+ Spine first, then the SDD, then the spec's contract. An `SDD-<pc>.md` written before the spine will be rewritten,
193
+ because the constraints it was supposed to inherit did not exist yet. A `SPEC.md` written before the SDD has
194
+ nothing to project. `AD` ids MUST stay stable so downstream artifacts can cite them.
195
+
196
+ ## Inheritance downward
197
+
198
+ From `mode: guarded` up, every `AD-N` that reaches a component MUST appear in that component's SDD under
199
+ **Inherited Constraints**, quoted rather than paraphrased. Below `guarded` the quoting is not written, and the
200
+ spine still binds — an invariant does not stop holding because a document is thin.
201
+
202
+ ## Review is manual here
203
+
204
+ `bmad-architecture` excludes the spine from `doc_standards` deliberately — the spine is terse by design and
205
+ prose polish softens rules that need to stay rigid. Two consequences:
206
+
207
+ - This guide is installed as `persistent_facts`, not `doc_standards`.
208
+ - `bmad-review` over the spine MUST be invoked through `wdi-review` before G3 closes.
209
+
210
+ ## Rules
211
+
212
+ - The spine MUST stay short enough to be read in one sitting. An `AD-N` nobody remembers is not an invariant,
213
+ it is a document.
214
+ - An `AD-N` MUST NOT be added because something feels important. The test is only ever: does breaking this in
215
+ one place break another?
216
+ - Structure statements MUST be marked as seeds, and MUST NOT be checked as if they were rules.
217
+ - Memlog goes to `.control/memlog/spine.md` via `--path`, never beside the spine.