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.
- package/CHANGELOG.md +129 -0
- package/NOTICE +7 -2
- package/README.md +16 -11
- package/bin/wdi-method.js +396 -87
- package/kit/.constitution/method/document/architecture-guide.md +217 -209
- package/kit/.constitution/method/document/bmad-skill-register.md +107 -104
- package/kit/.constitution/method/document/corpus-guide.md +522 -517
- package/kit/.constitution/method/document/decision-guide.md +236 -216
- package/kit/.constitution/method/document/delivery-flow-guide.md +20 -0
- package/kit/.constitution/method/document/prd-guide.md +245 -245
- package/kit/.constitution/method/document/templates/design-system.md +96 -66
- package/kit/.constitution/method/document/templates/experience.md +62 -0
- package/kit/.constitution/method/document/templates/structure-codebase.md +131 -129
- package/kit/.constitution/method/document/templates/ux.md +78 -76
- package/kit/.constitution/method/document/ux-guide.md +161 -115
- package/kit/.constitution/method/method-glossary.md +3 -0
- package/kit/.constitution/method/scripts/validate.py +3375 -3200
- package/kit/.constitution/method/structure-guide.md +204 -202
- package/kit/.constitution/method/why/README.md +1 -1
- package/kit/.constitution/method/why/artifact-map.md +158 -157
- package/kit/.constitution/method/why/portability.md +19 -2
- package/kit/skills/wdi-autopilot/SKILL.md +32 -19
- package/kit/skills/wdi-blueprint/SKILL.md +271 -264
- package/kit/skills/wdi-build/SKILL.md +28 -19
- package/kit/skills/wdi-component/SKILL.md +179 -174
- package/kit/skills/wdi-daily-autopilot/SKILL.md +24 -13
- package/kit/skills/wdi-daily-what-to-build/SKILL.md +9 -6
- package/kit/skills/wdi-daily-what-to-test/SKILL.md +2 -0
- package/kit/skills/wdi-decision/SKILL.md +206 -203
- package/kit/skills/wdi-explain-to-me/SKILL.md +2 -0
- package/kit/skills/wdi-help/SKILL.md +130 -125
- package/kit/skills/wdi-init/SKILL.md +10 -5
- package/kit/skills/wdi-problem/SKILL.md +114 -108
- package/kit/skills/wdi-product/SKILL.md +167 -162
- package/kit/skills/wdi-prune-or-archive/SKILL.md +2 -0
- package/kit/skills/wdi-reconcile/SKILL.md +170 -169
- package/kit/skills/wdi-upgrade/SKILL.md +234 -215
- package/kit/skills/wdi-ux/SKILL.md +187 -169
- package/kit-overlay/AGENTS.md +15 -2
- package/kit-overlay/portability.md +19 -2
- package/lib/platforms.mjs +420 -248
- package/package.json +1 -1
- package/scaffold/.control/registry/index.yaml +2 -1
|
@@ -1,517 +1,522 @@
|
|
|
1
|
-
---
|
|
2
|
-
status: Accepted
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Corpus Guide
|
|
6
|
-
|
|
7
|
-
**Loaded when:** deciding where a file lives, or creating a new file in the corpus
|
|
8
|
-
|
|
9
|
-
Four layers and one workspace. Every other guide describes one document; this one answers the question that
|
|
10
|
-
comes before all of them — **where does this belong?**
|
|
11
|
-
|
|
12
|
-
The quick answer for the thing actually in your hand is the "benda di tangan → folder" table in `AGENTS.md`.
|
|
13
|
-
It is deliberately there rather than here: it is needed at the moment someone would otherwise have to reason
|
|
14
|
-
about what `.what/` and `.how/` mean, and that moment comes before anyone thinks to open a guide. It MUST NOT
|
|
15
|
-
be copied into this file.
|
|
16
|
-
|
|
17
|
-
## The four layers
|
|
18
|
-
|
|
19
|
-
| Layer | Answers | Lifetime | Written by |
|
|
20
|
-
|---|---|---|---|
|
|
21
|
-
| `.constitution/` | How we work | Living, rarely changes | Us |
|
|
22
|
-
| `.control/` | What currently holds, and what has been decided | Living, changes often | Us + generators |
|
|
23
|
-
| `.what/` | What is promised | Living, amended | BMad class A + us |
|
|
24
|
-
| `.how/` | How it is built | Living, amended | BMad class A + us |
|
|
25
|
-
| `_bmad-output/` | Work in progress | Ends when the work does | BMad class B and C |
|
|
26
|
-
| `.what-rendered/` · `.how-rendered/` | The same promise and shape, **assembled for a human to read** | Regenerated on every `render`; never edited | `validate.py --generate`, and nobody else |
|
|
27
|
-
|
|
28
|
-
`.control/` is the value of `{project_knowledge}` in BMad's configuration. There is no `docs/`.
|
|
29
|
-
|
|
30
|
-
### Two audiences, two trees
|
|
31
|
-
|
|
32
|
-
`.what/` and `.how/` are the **working** trees: prose that cannot be a row, pointers to the registry for
|
|
33
|
-
everything that can. They are what an agent reads and what a skill writes. They are deliberately thin
|
|
34
|
-
for a human — `Goals` is one line, an `FR` is an id — because completeness is not their job.
|
|
35
|
-
|
|
36
|
-
`.what-rendered/` and `.how-rendered/` are the **reader's** trees. Every file in them sits at the mirror
|
|
37
|
-
path of the working document it projects — `.what-rendered/<pc>/SRS-<pc>.md` is
|
|
38
|
-
`.what/<pc>/SRS-<pc>.md` with every pointer opened: the goal statements, the UC rows, the
|
|
39
|
-
`AD-N` text, the open questions, all pulled in from their own homes. That is what a gate reads, and
|
|
40
|
-
what a client receives.
|
|
41
|
-
|
|
42
|
-
Three rules keep the two trees honest:
|
|
43
|
-
|
|
44
|
-
- **A skill MUST NOT read a `-rendered` file as input.** It is output. The working document and the
|
|
45
|
-
registry are the source, and a skill that read the projection would be reading its own echo — a
|
|
46
|
-
`kit-integrity` test fails when any `SKILL.md` lists one in its `Inputs`.
|
|
47
|
-
- **Nobody edits a `-rendered` file.** A defect seen there is a defect in the working document or the
|
|
48
|
-
registry, and that is where it is fixed. The next `render` overwrites the page.
|
|
49
|
-
- **Every gate reads one rendered page, and that page MUST answer the gate's seven questions.** G1
|
|
50
|
-
reads `.what-rendered/_product-brief/brief.md`; G2 `.what-rendered/_prd/<slug>/prd.md`; G3
|
|
51
|
-
`.how-rendered/blueprint.md`; G4 `.how-rendered/<pc>/SDD-<pc>.md`. A question that cannot be
|
|
52
|
-
answered from the page is a gap in the page, not a reason to open a working file.
|
|
53
|
-
|
|
54
|
-
## The placement test
|
|
55
|
-
|
|
56
|
-
One question decides everything: **is this file still correct after its spec has passed?**
|
|
57
|
-
|
|
58
|
-
Yes → the corpus. No → `_bmad-output/`.
|
|
59
|
-
|
|
60
|
-
`_bmad-output/` is committed but **not curated**. Committing it is what makes citation by path stable, so a
|
|
61
|
-
decision or a PRD MAY point into it.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
A
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
the
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
|
115
|
-
|
|
116
|
-
|
|
|
117
|
-
|
|
|
118
|
-
|
|
|
119
|
-
|
|
|
120
|
-
|
|
|
121
|
-
|
|
|
122
|
-
|
|
|
123
|
-
|
|
|
124
|
-
|
|
|
125
|
-
| `
|
|
126
|
-
| `
|
|
127
|
-
|
|
|
128
|
-
|
|
|
129
|
-
|
|
|
130
|
-
|
|
|
131
|
-
|
|
|
132
|
-
| The
|
|
133
|
-
|
|
|
134
|
-
|
|
|
135
|
-
|
|
|
136
|
-
|
|
|
137
|
-
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
|
162
|
-
|
|
163
|
-
|
|
|
164
|
-
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
|
196
|
-
|
|
197
|
-
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
(
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
`
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
|
268
|
-
|
|
269
|
-
|
|
|
270
|
-
|
|
|
271
|
-
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
the
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
**
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
**
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
from
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
|
406
|
-
|
|
407
|
-
| `
|
|
408
|
-
| `
|
|
409
|
-
| `
|
|
410
|
-
| `
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
|
427
|
-
|
|
428
|
-
| `.
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
|
449
|
-
|
|
450
|
-
| A
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
**
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
- A file
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
-
|
|
1
|
+
---
|
|
2
|
+
status: Accepted
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Corpus Guide
|
|
6
|
+
|
|
7
|
+
**Loaded when:** deciding where a file lives, or creating a new file in the corpus
|
|
8
|
+
|
|
9
|
+
Four layers and one workspace. Every other guide describes one document; this one answers the question that
|
|
10
|
+
comes before all of them — **where does this belong?**
|
|
11
|
+
|
|
12
|
+
The quick answer for the thing actually in your hand is the "benda di tangan → folder" table in `AGENTS.md`.
|
|
13
|
+
It is deliberately there rather than here: it is needed at the moment someone would otherwise have to reason
|
|
14
|
+
about what `.what/` and `.how/` mean, and that moment comes before anyone thinks to open a guide. It MUST NOT
|
|
15
|
+
be copied into this file.
|
|
16
|
+
|
|
17
|
+
## The four layers
|
|
18
|
+
|
|
19
|
+
| Layer | Answers | Lifetime | Written by |
|
|
20
|
+
|---|---|---|---|
|
|
21
|
+
| `.constitution/` | How we work | Living, rarely changes | Us |
|
|
22
|
+
| `.control/` | What currently holds, and what has been decided | Living, changes often | Us + generators |
|
|
23
|
+
| `.what/` | What is promised | Living, amended | BMad class A + us |
|
|
24
|
+
| `.how/` | How it is built | Living, amended | BMad class A + us |
|
|
25
|
+
| `_bmad-output/` | Work in progress | Ends when the work does | BMad class B and C |
|
|
26
|
+
| `.what-rendered/` · `.how-rendered/` | The same promise and shape, **assembled for a human to read** | Regenerated on every `render`; never edited | `validate.py --generate`, and nobody else |
|
|
27
|
+
|
|
28
|
+
`.control/` is the value of `{project_knowledge}` in BMad's configuration. There is no `docs/`.
|
|
29
|
+
|
|
30
|
+
### Two audiences, two trees
|
|
31
|
+
|
|
32
|
+
`.what/` and `.how/` are the **working** trees: prose that cannot be a row, pointers to the registry for
|
|
33
|
+
everything that can. They are what an agent reads and what a skill writes. They are deliberately thin
|
|
34
|
+
for a human — `Goals` is one line, an `FR` is an id — because completeness is not their job.
|
|
35
|
+
|
|
36
|
+
`.what-rendered/` and `.how-rendered/` are the **reader's** trees. Every file in them sits at the mirror
|
|
37
|
+
path of the working document it projects — `.what-rendered/<pc>/SRS-<pc>.md` is
|
|
38
|
+
`.what/<pc>/SRS-<pc>.md` with every pointer opened: the goal statements, the UC rows, the
|
|
39
|
+
`AD-N` text, the open questions, all pulled in from their own homes. That is what a gate reads, and
|
|
40
|
+
what a client receives.
|
|
41
|
+
|
|
42
|
+
Three rules keep the two trees honest:
|
|
43
|
+
|
|
44
|
+
- **A skill MUST NOT read a `-rendered` file as input.** It is output. The working document and the
|
|
45
|
+
registry are the source, and a skill that read the projection would be reading its own echo — a
|
|
46
|
+
`kit-integrity` test fails when any `SKILL.md` lists one in its `Inputs`.
|
|
47
|
+
- **Nobody edits a `-rendered` file.** A defect seen there is a defect in the working document or the
|
|
48
|
+
registry, and that is where it is fixed. The next `render` overwrites the page.
|
|
49
|
+
- **Every gate reads one rendered page, and that page MUST answer the gate's seven questions.** G1
|
|
50
|
+
reads `.what-rendered/_product-brief/brief.md`; G2 `.what-rendered/_prd/<slug>/prd.md`; G3
|
|
51
|
+
`.how-rendered/blueprint.md`; G4 `.how-rendered/<pc>/SDD-<pc>.md`. A question that cannot be
|
|
52
|
+
answered from the page is a gap in the page, not a reason to open a working file.
|
|
53
|
+
|
|
54
|
+
## The placement test
|
|
55
|
+
|
|
56
|
+
One question decides everything: **is this file still correct after its spec has passed?**
|
|
57
|
+
|
|
58
|
+
Yes → the corpus. No → `_bmad-output/`.
|
|
59
|
+
|
|
60
|
+
`_bmad-output/` is committed but **not curated**. Committing it is what makes citation by path stable, so a
|
|
61
|
+
decision or a PRD MAY point into it. One exception: once components exist, `.what/` and `.how/` MUST NOT
|
|
62
|
+
cite a UX run's `DESIGN.md`, `EXPERIENCE.md`, or `design-system.md` — the run has been distilled, and
|
|
63
|
+
`ux-guide.md` § Rules owns it. Research, brainstorming, forge, and PRFAQ reports are never promoted.
|
|
64
|
+
|
|
65
|
+
A run folder MUST NOT be deleted **while anything still needs it** — the `update` intents re-read the original
|
|
66
|
+
inputs in place. "Never deleted" is not the rule; the rule is a **retirement condition**, and it is below.
|
|
67
|
+
|
|
68
|
+
**What git ignores is not corpus.** A vendored upstream checkout kept for reading, a scratch download, a
|
|
69
|
+
build cache — if the product excludes it from git it is in no clone, nobody curates it, and the validators
|
|
70
|
+
do not read it. The other half of that rule is `corpus-in-git`: a folder the method itself keeps MUST NOT be
|
|
71
|
+
excluded, and the two lock together — material is either in git and checked, or ignored and not corpus. What
|
|
72
|
+
`.gitignore` MUST NOT be used for is quieting a finding about a file that really is this product's.
|
|
73
|
+
|
|
74
|
+
### A withdrawn promise STAYS in the registry
|
|
75
|
+
|
|
76
|
+
A `BG` · `CAP` · `FR` · `NFR` · `UC` the product stops promising is marked, never deleted:
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
- id: CAP-8
|
|
80
|
+
title: "Publish an order as a public page"
|
|
81
|
+
status: withdrawn
|
|
82
|
+
withdrawn_by: DEC-026
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Why the row stays.** One repo deleted two withdrawn capabilities and paid for it in twelve
|
|
86
|
+
`refs-resolve` findings: eight `DEC-` rows still named them in `serves:`, and six of those eight
|
|
87
|
+
genuinely served them at the time. The other repair — editing those decisions — is refused by the
|
|
88
|
+
section above: a `DEC-` is a record of what happened, and a retired name inside one is a fact about
|
|
89
|
+
the past.
|
|
90
|
+
|
|
91
|
+
**So a withdrawn row is read two ways, and both matter.** It is still **defined**: every old
|
|
92
|
+
reference resolves, and `id-allocated-once` still refuses the number to anything else — an id is
|
|
93
|
+
allocated once, withdrawal included. It is no longer **promised**: no `UC` is owed, no ticket, no RTM
|
|
94
|
+
row, and `promise_progress` is not dragged down by something nobody promises any more.
|
|
95
|
+
|
|
96
|
+
**Two rules keep it honest**, and `withdrawn-recorded` is what enforces both:
|
|
97
|
+
|
|
98
|
+
- `withdrawn_by` MUST name a `DEC-` that exists. Retiring an id is decision-worthy on this method's
|
|
99
|
+
own terms — the **ID chain** row under § *Landing that MUST be confirmed first* says so outright —
|
|
100
|
+
and without the pointer `withdrawn` is only a word that quiets a validator.
|
|
101
|
+
- A live row MUST NOT hang off a withdrawn one. An `FR` under a withdrawn `CAP` still promises
|
|
102
|
+
something whose capability nobody promises: withdraw it too, or move it under something live.
|
|
103
|
+
Withdrawal that takes half a chain with it silently is worse than the deletion it replaced, because
|
|
104
|
+
deletion at least went red.
|
|
105
|
+
|
|
106
|
+
`wdi-product` owns the edit, because it owns the row. The withdrawal itself goes through
|
|
107
|
+
`wdi-decision` first — the `DEC-` is what `withdrawn_by` points at.
|
|
108
|
+
|
|
109
|
+
## Who lands what
|
|
110
|
+
|
|
111
|
+
There is no separate placement skill. A skill lands the output of the layer **it owns**, and the landing is
|
|
112
|
+
part of producing it — never a follow-up someone else performs.
|
|
113
|
+
|
|
114
|
+
| Output | Permanent home | Owner |
|
|
115
|
+
|---|---|---|
|
|
116
|
+
| The spine | `.how/_platform/ARCHITECTURE-SPINE.md` | `wdi-blueprint` |
|
|
117
|
+
| C4 L1 · L2 · one L3 per container holding more than one PC | `.how/_platform/c4-l1-system-context.md` · `c4-l2-containers.md` · `c4-l3-<container>.md` | `wdi-blueprint` |
|
|
118
|
+
| each container in C4 L2 | a `container` entry in `components.yaml` | `wdi-blueprint` |
|
|
119
|
+
| **The three inventories** | `.how/_platform/inventory-db.md` · `inventory-api.md` · `inventory-screen.md` | `wdi-blueprint` |
|
|
120
|
+
| The error envelope, and anything else defined once for the product | `.how/_platform/cross-cutting.md` | `wdi-blueprint` |
|
|
121
|
+
| UC catalogue · Actor Register · domain model | `.what/<pc>/SRS-<pc>.md` · `03-domain/domain-model.md` | `wdi-blueprint` |
|
|
122
|
+
| Business rules binding more than one PC | `.what/business-rules.md` | `wdi-blueprint` |
|
|
123
|
+
| A domain term | `.control/product-glossary.md` | `wdi-blueprint` |
|
|
124
|
+
| Full UC flows · local rules · state machines · scenarios | `.what/<pc>/` slots `02`–`05` | `wdi-component` intent `behaviour` |
|
|
125
|
+
| The SDD and its slots `02`–`06` | `.how/<pc>/` | `wdi-component` intent `design` |
|
|
126
|
+
| each Boundary and Control object drawn | an `LC` in `components.yaml` | `wdi-component` intent `design` |
|
|
127
|
+
| Experience that holds for every component — `ux-guide.md` § *Product level* | `.what/experience.md` | `wdi-ux` |
|
|
128
|
+
| `EXPERIENCE.md` | `.what/<pc>/04-usecases/` | `wdi-ux` |
|
|
129
|
+
| `DESIGN.md` | `.how/<pc>/01-ux/` | `wdi-ux` |
|
|
130
|
+
| tokens, base components, and build patterns every component shares | `.how/_platform/design-system.md` | `wdi-ux` |
|
|
131
|
+
| each screen in `DESIGN.md` | an `LC` of type `ui-screen` in `components.yaml` | `wdi-ux` |
|
|
132
|
+
| The names of the tests a ticket went green on | the ticket's `tests` in `specs.yaml` | `wdi-build` |
|
|
133
|
+
| What the spec settled about the stack, the conventions, or the brownfield reality | merged into `.constitution/project/codebase-*-guide.md` | `wdi-build`, at spec close |
|
|
134
|
+
| A sprint change proposal | a `DEC-` of `type: course-correction` | `wdi-decision` |
|
|
135
|
+
| The registry rows and skeletons a new PC needs | `components.yaml` · `.what/<pc>/` · `.how/<pc>/` | `wdi-init` intent `component` |
|
|
136
|
+
| `platform_owns` — an entity no component's promise explains | `components.yaml`, plus its description in `cross-cutting.md` | `wdi-blueprint` |
|
|
137
|
+
| The two structure maps | `.control/structure-codebase.md` · `structure-document.md` | `wdi-init` intent `structure` |
|
|
138
|
+
| An open question | `.control/questions/` — one of four files | `wdi-question` |
|
|
139
|
+
| A decision | `.control/decisions/DEC-NNN-<slug>.md` | `wdi-decision` |
|
|
140
|
+
| Minutes · a non-technical fact | `.control/meetings/` · `.control/project-non-technical-log.md` | `wdi-log` |
|
|
141
|
+
|
|
142
|
+
- A skill MUST NOT write into a layer it does not own.
|
|
143
|
+
- Registry conversion is part of landing, not a follow-up. A screen that lands in `01-ux/` without its
|
|
144
|
+
`components.yaml` entry has been half-landed, and `lc-registered` catches it **at spec close** — which is the
|
|
145
|
+
right moment to be caught, and a bad moment to be surprised.
|
|
146
|
+
- Content MUST NOT be edited while it is being landed. If it has to change to fit its new home, that is a
|
|
147
|
+
separate act — say so and stop. Splitting one output across the homes its row names is not editing.
|
|
148
|
+
- The C4 set's target files already exist and are **living**. Their owner MUST amend, MUST NOT overwrite; when
|
|
149
|
+
the incoming set contradicts an annotation already there, it MUST stop and report the finding.
|
|
150
|
+
- Nothing MAY be landed into a spec that is already closed. The spec is reopened through `wdi-build`, or the
|
|
151
|
+
gap is recorded as an open question.
|
|
152
|
+
- An output with **no row** in this table MUST NOT be given a guessed home. It stays in `_bmad-output/`, and
|
|
153
|
+
`wdi-reconcile` reports it — an output with no home is a gap in the method, and MUST surface as one.
|
|
154
|
+
|
|
155
|
+
## Landing that MUST be confirmed first
|
|
156
|
+
|
|
157
|
+
Most landings are mechanical and MAY be done without asking. Some change what other people already agreed to,
|
|
158
|
+
and those MUST be put to the owner before the file is written — not reported afterwards. The line is drawn by
|
|
159
|
+
**what the landing can invalidate**, never by how much text moves:
|
|
160
|
+
|
|
161
|
+
| | Light — act, then report | Heavy — confirm, then act |
|
|
162
|
+
|---|---|---|
|
|
163
|
+
| Layer | Stays inside the layer the skill owns | Crosses into another layer's consequences |
|
|
164
|
+
| ID chain | No `BG`/`CAP`/`FR`/`NFR`/`UC`/`LC` id is born, renamed, or retired | Any of them is |
|
|
165
|
+
| Depth and risk | `mode` and `risk_accepted` unchanged | Either would have to change |
|
|
166
|
+
| Existing text | Adds, or replaces content the same skill wrote | Overwrites or contradicts what another skill or a human wrote |
|
|
167
|
+
| Registry | Adds the entry its own output requires | Removes or re-points an entry something else already cites |
|
|
168
|
+
|
|
169
|
+
Any one heavy row makes the whole landing heavy. When confirmation cannot be obtained now, the landing MUST
|
|
170
|
+
NOT be split into a light half that goes ahead — half-landed output looks distributed and is worse than output
|
|
171
|
+
that waited.
|
|
172
|
+
|
|
173
|
+
A skill MUST NOT lighten a landing by narrowing what it writes. Dropping the contentious half to stay under
|
|
174
|
+
the bar is the same change, made invisible.
|
|
175
|
+
|
|
176
|
+
## Product Component — the naming and proposal rule
|
|
177
|
+
|
|
178
|
+
This rule lives here, beside the definition, and **not inside a skill**. If it lived in one skill, the second
|
|
179
|
+
skill that needed it would copy it, and the two copies would drift.
|
|
180
|
+
|
|
181
|
+
> The name of a Product Component MUST be a surface a user could name. A name that states a layer, a service,
|
|
182
|
+
> or a pattern MUST be rejected at proposal time, not corrected later. Additions, changes, and removals MUST
|
|
183
|
+
> be presented separately, each with the `FR` behind it.
|
|
184
|
+
|
|
185
|
+
A PC MUST NOT be created because a folder would look tidy. A PC that no `FR` points at is a folder with
|
|
186
|
+
nothing inside it.
|
|
187
|
+
|
|
188
|
+
Birthing is cheap and retiring is not: retiring or renaming a PC that already carries an SRS goes through
|
|
189
|
+
`wdi-decision`, never through the skill that births one.
|
|
190
|
+
|
|
191
|
+
## Product Component, Logical Component, container, `_platform`
|
|
192
|
+
|
|
193
|
+
Four words that are easy to blur and MUST NOT be:
|
|
194
|
+
|
|
195
|
+
| Term | Is | Registered in |
|
|
196
|
+
|---|---|---|
|
|
197
|
+
| **Product Component** | A surface a user can name — what they came to do | `product_components` |
|
|
198
|
+
| **Logical Component** | A unit inside the build — a screen, a service, an adapter, an entity | `logical_components` |
|
|
199
|
+
| **Container** | Something that runs or ships on its own | `containers` |
|
|
200
|
+
| **`_platform`** | **Not a component at all** — the home for what belongs to no Product Component | `platform_owns`, and the `_platform/` folder |
|
|
201
|
+
|
|
202
|
+
PC and container are **crossing axes**, not a hierarchy: one PC MAY be delivered by several containers, and one
|
|
203
|
+
container MAY serve several PCs. An `LC` names its container in a `container:` field, which is what lets
|
|
204
|
+
`structure-codebase.md` be checked against the registry rather than trusted.
|
|
205
|
+
|
|
206
|
+
## `_platform` — what belongs to no Product Component
|
|
207
|
+
|
|
208
|
+
`_platform` is **not a Product Component**, and it MUST NOT be registered as one. It fails the naming test on
|
|
209
|
+
purpose: nobody came to the product to use "the platform". It therefore carries **no `mode`, no
|
|
210
|
+
`risk_accepted`, no SRS, no SDD, and no G4** — its documents are the spine, the C4 set, `cross-cutting.md`,
|
|
211
|
+
and the three inventories, and all of those exist at every `mode`.
|
|
212
|
+
|
|
213
|
+
What it does carry is **ownership**. `_platform` is a legitimate value in **every** position that asks
|
|
214
|
+
*"which component owns this"* — the `platform_owns:` list for domain entities, the owning-component column
|
|
215
|
+
of any inventory row, an `LC`'s `component:` field, and any such column a later artifact adds. One test,
|
|
216
|
+
one cost, everywhere; there is no per-artifact special case to negotiate, and a new kind of thing arriving
|
|
217
|
+
next year needs no new discussion.
|
|
218
|
+
|
|
219
|
+
The test, and both halves MUST hold:
|
|
220
|
+
|
|
221
|
+
> Something belongs to `_platform` when **no single Product Component's promise is the reason it exists**,
|
|
222
|
+
> *and* more than one component reads, writes, or depends on it.
|
|
223
|
+
|
|
224
|
+
Four kinds qualify today and the list is open: **data** (a product-wide setting, the trace of a shared
|
|
225
|
+
outbound channel) · **endpoint** (`/health`, `robots.txt` — plumbing no `FR` promises and none should) ·
|
|
226
|
+
**job** (a scheduled cleaner whose data belongs to a component but whose machinery does not) · **screen**
|
|
227
|
+
(none yet).
|
|
228
|
+
|
|
229
|
+
Failing either half, it belongs to a Product Component — and the component is found by asking which `FR`
|
|
230
|
+
would have to be withdrawn for the entity to stop being needed. Two examples of the trap:
|
|
231
|
+
|
|
232
|
+
| Entity | Looks platform-shaped | Actually |
|
|
233
|
+
|---|---|---|
|
|
234
|
+
| `activity_events` | product-wide telemetry, several components write it | **one component** — an `FR` promises somebody can SEE those counts, and withdrawing it is what would make the table unnecessary |
|
|
235
|
+
| `email_logs` | one component sends first | **`_platform`** — it is the trace of one outbound channel that order notifications and password recovery both use, and neither promise is why the channel exists |
|
|
236
|
+
|
|
237
|
+
**One guard, and it is what stops this becoming a drawer:** everything `_platform` owns — in any position —
|
|
238
|
+
MUST be described under `## Platform-owned` in `cross-cutting.md`, with its kind and the shape every toucher
|
|
239
|
+
obeys. A platform that owns something documents it. `entity-one-writer` checks it, and skips only while that section has not
|
|
240
|
+
been born at G3.
|
|
241
|
+
|
|
242
|
+
That guard is the whole reason `_platform` can be a general answer rather than an escape hatch: reaching for
|
|
243
|
+
it costs a row somebody has to write, so it stays cheaper to find the real owner when one exists.
|
|
244
|
+
|
|
245
|
+
`_platform` has no `FR`, so an `FR` that writes something platform-owned has nothing to point `defers_to` at,
|
|
246
|
+
and MUST NOT be asked for one. What replaces "one writer" there is **one documented shape**: it is written the
|
|
247
|
+
way `cross-cutting.md` says, and a component wanting it written differently is proposing a change to that file.
|
|
248
|
+
|
|
249
|
+
Platform ownership sits with `wdi-blueprint` intent `platform`, beside the rest of `_platform/`. `wdi-init`
|
|
250
|
+
intent `component` MAY name a candidate and MUST NOT claim one.
|
|
251
|
+
|
|
252
|
+
**A decision the pattern cannot derive lives in the artifact it governs.** An inventory row owned by
|
|
253
|
+
`_platform`, and a route that is a *state* of another screen rather than a screen of its own, are both
|
|
254
|
+
judgements — so both are declared in that inventory's own frontmatter (`platform_rows:` and `states:`) and
|
|
255
|
+
survive every re-derivation. Putting either outside the file means the next derivation silently deletes the
|
|
256
|
+
owner's decision.
|
|
257
|
+
|
|
258
|
+
## A derived fact has exactly one home
|
|
259
|
+
|
|
260
|
+
`why/rationale.md` has always carried this as principle 5 — *what can be derived is not written by hand.*
|
|
261
|
+
It was never written as a rule anywhere, and that file binds nothing by its own terms. So it bound nothing,
|
|
262
|
+
and only one field was ever actually protected: ticket status, by `ticket-status-one-home`.
|
|
263
|
+
|
|
264
|
+
**A document MUST NOT state a fact that a registry, a generated file, or git already holds.** It cites the
|
|
265
|
+
id and lets the reader follow it. The list is short and it is closed:
|
|
266
|
+
|
|
267
|
+
| Never stated in prose | Where it lives |
|
|
268
|
+
|---|---|
|
|
269
|
+
| `mode` · `risk_accepted` · `g4_passed` | `components.yaml` |
|
|
270
|
+
| Which `DEC-` bind this document — **including "none yet"** | `.control/generated/decisions.md` |
|
|
271
|
+
| A count of `UC`, `FR`, `CAP`, or containers | the registry that holds them |
|
|
272
|
+
| Which slots or files exist, and which are still empty | `.control/structure-document.md`, derived |
|
|
273
|
+
| Whether an `OQ-` is open or answered | `.control/questions/` |
|
|
274
|
+
| When the document last changed | git |
|
|
275
|
+
|
|
276
|
+
**The remedy is DELETION, never correction.** This is the part that costs a corpus real time to learn: a
|
|
277
|
+
restated fact that is corrected becomes a *second* stale fact, on a slower clock than the first. One SRS in a
|
|
278
|
+
real repo carried three claims about its own `mode` on one page — the value, a correction block below it
|
|
279
|
+
fixing an older value, and the slot list — and not one of the three was right. Correcting any of them would
|
|
280
|
+
have added a fourth. Deleting all three ends it.
|
|
281
|
+
|
|
282
|
+
A negative claim is the worst case and the easiest to miss, because it looks like diligence: *"No applied
|
|
283
|
+
`DEC-` binds this component yet"* is true the day it is written and silently false forever after.
|
|
284
|
+
|
|
285
|
+
**What is NOT a derived fact**, and MUST still be written where it belongs: a judgement the pattern cannot
|
|
286
|
+
recompute (the paragraph above owns that), an `AD-N` citation — the spine's `binds:` is authored, not
|
|
287
|
+
derived — and the *reason* something is the way it is, which no registry holds.
|
|
288
|
+
|
|
289
|
+
## A pass writes one artifact
|
|
290
|
+
|
|
291
|
+
When a skill is writing or updating an artifact, **that artifact is the pass.** Hunting the rest of the
|
|
292
|
+
corpus for things that disagree with it is not part of writing it, and MUST NOT be folded in: it is
|
|
293
|
+
`wdi-reconcile`'s job, it runs at a gate, and `wdi-review` § Stale is not a finding decides what is even
|
|
294
|
+
worth reporting when it does.
|
|
295
|
+
|
|
296
|
+
Where a contradiction surfaces anyway — and it will, because writing a document is how you notice — there
|
|
297
|
+
are exactly two outcomes:
|
|
298
|
+
|
|
299
|
+
| The other document is | Do |
|
|
300
|
+
|---|---|
|
|
301
|
+
| **Load-bearing wrong** — a reader would make the wrong repair | Say it in **one line** in the output, naming the file and the edit it needs |
|
|
302
|
+
| Anything else | Nothing. Not a line, not an `OQ-`, not a `DEC-` |
|
|
303
|
+
|
|
304
|
+
It MUST NOT become an open question, and it MUST NOT become a decision. A contradiction between two
|
|
305
|
+
documents is an **edit** waiting for whoever owns the file — never a thing to be adjudicated.
|
|
306
|
+
|
|
307
|
+
**This binds hardest at G1 and G2.** A brief is being formed; a PRD is being written. There is barely a
|
|
308
|
+
corpus to be consistent with yet, and a pass that spends its budget looking for one is spending it on
|
|
309
|
+
nothing.
|
|
310
|
+
|
|
311
|
+
## One decided change is one edit pass
|
|
312
|
+
|
|
313
|
+
Once the owner has decided, the chain is **applied**, not surveyed. The agent already knows what the
|
|
314
|
+
change reaches — `touches:` names it, the ownership table in this file names who lands each part, and the
|
|
315
|
+
RTM names the rows that move. It edits all of them in **one pass** and reports once.
|
|
316
|
+
|
|
317
|
+
What MUST NOT happen: checking one document, reporting, waiting, checking the next; re-deriving the same
|
|
318
|
+
relations in a later pass; or asking the owner to confirm the same decision at each file it touches. The
|
|
319
|
+
documents are split for reading, not to be walked one at a time — and walking them is where the time and
|
|
320
|
+
the tokens actually go.
|
|
321
|
+
|
|
322
|
+
## The corpus is written in the present tense
|
|
323
|
+
|
|
324
|
+
A design document states **what is true now**: the latest state of the design, and what still has to be
|
|
325
|
+
reached. It does not state how it got there. This governs `.what/<pc>/`, `.how/`, and
|
|
326
|
+
`.constitution/project/`.
|
|
327
|
+
|
|
328
|
+
### Two kinds of history, and only one is worth writing
|
|
329
|
+
|
|
330
|
+
Most history is not useful. What is useful is the current state — and the rare piece of history that
|
|
331
|
+
**stops the same mistake happening twice**. One question separates them:
|
|
332
|
+
|
|
333
|
+
> **Would someone about to make a change be saved by this line?**
|
|
334
|
+
|
|
335
|
+
| Kind | Example | Where it goes |
|
|
336
|
+
|---|---|---|
|
|
337
|
+
| **Business or technical** — the mistake could recur | *"Files are removed before the record, and that left a document pointing at a deleted image"* | A `DEC-`, `why/`, or `answered.md`. Rarely, and only when it earns it |
|
|
338
|
+
| **Document history** — a document said something else last week | *"This section was rewritten"* · *"withdrawn because a later pass found it wrong"* · *"this used to read X"* | **Nowhere.** git holds it, and git holds it better |
|
|
339
|
+
|
|
340
|
+
The second kind is what fills a corpus and buys nothing. It arrives as a correction block, a
|
|
341
|
+
`## Provenance` note, a document's own change log, a note about a conflict that has already been
|
|
342
|
+
**resolved**, or a *"considered and rejected"* aside about the method itself. All of it MUST NOT be
|
|
343
|
+
written in the three layers above.
|
|
344
|
+
|
|
345
|
+
**And no step demands the first kind either.** History is never a checklist item, never a gate condition,
|
|
346
|
+
and never a blocking finding. It is written when someone judges it worth writing, and skipping it is
|
|
347
|
+
**not** a gap — nothing in this method MAY report a missing history line as a defect. That is the whole
|
|
348
|
+
difference between a record and a ritual.
|
|
349
|
+
|
|
350
|
+
**A mid-flight change lands as if it had been there from the start.** An idea arriving during G5 is
|
|
351
|
+
written in the present tense — not appended, not annotated, not marked as late. The commit is that
|
|
352
|
+
record, and it is a better one than a paragraph.
|
|
353
|
+
|
|
354
|
+
**What this rule does NOT cut:**
|
|
355
|
+
|
|
356
|
+
- **The PRD's Revision History.** Its reader is outside the room, and `prd-guide.md` already demands the
|
|
357
|
+
business form of it: *state what the promise now is, not which section was edited.*
|
|
358
|
+
- **`.control/questions/answered.md`.** This is the clearest case of history that pays: it is what stops
|
|
359
|
+
the same question being asked again in three months.
|
|
360
|
+
- **`ratified_by:`** on a room guide — evidence the rule is real, not a record that it changed.
|
|
361
|
+
- **`why/`** and `.control/decisions/`, whose job is exactly the first kind.
|
|
362
|
+
- **`superseded`** pointing at its replacement. A reader following an old id needs the pointer.
|
|
363
|
+
|
|
364
|
+
Real cost of getting this wrong, from one repo: a codebase conventions guide — the file a developer opens
|
|
365
|
+
to learn how to write code here — spent a quarter of its length explaining when it had been filled, why it
|
|
366
|
+
was not a `DEC-`, and which alternative had been rejected. Not one line of that would save the next reader
|
|
367
|
+
from anything.
|
|
368
|
+
|
|
369
|
+
## Two axes inside `.what/`
|
|
370
|
+
|
|
371
|
+
| | `_prd/<initiative>/` | `<pc>/` |
|
|
372
|
+
|---|---|---|
|
|
373
|
+
| Slices by | **Initiative** — one functional area | **Space** — one Product Component |
|
|
374
|
+
| Answers | What is promised to a user | What this component can do |
|
|
375
|
+
| Written for | Outside readers — client, sponsor | People building the system |
|
|
376
|
+
|
|
377
|
+
Both are living. What separates them is **promise versus behaviour**, not lifetime. One functional area MAY
|
|
378
|
+
span several components, and one component MAY serve several PRDs, so neither can absorb the other.
|
|
379
|
+
|
|
380
|
+
**Time is not a folder axis.** Release lives in `CAP.target_release` and in `specs.yaml`.
|
|
381
|
+
|
|
382
|
+
## Slot numbering means two different things
|
|
383
|
+
|
|
384
|
+
| Layer | Slots | The number means |
|
|
385
|
+
|---|---|---|
|
|
386
|
+
| `.what/<pc>/` | `02-rules` · `03-domain` · `04-usecases` · `05-scenarios` | **Reading order** — its rules → the things → how it is used → its branches |
|
|
387
|
+
| `.how/<pc>/` | `01-ux` … `06-flows` | **ABCE classification** — Boundary, Control, Entity, behaviour. Not a reading order |
|
|
388
|
+
|
|
389
|
+
Reading one as the other is the most common misfiling in this corpus, and it is silent: the file lands in a
|
|
390
|
+
plausible-looking folder and is simply never found again.
|
|
391
|
+
|
|
392
|
+
`.what/<pc>/01-requirements/` is **repealed** — permanently empty, because `FR` live in the PRD and the SRS
|
|
393
|
+
cites them. `supplements/` beside either kernel is repealed with the `ANX-` concept.
|
|
394
|
+
|
|
395
|
+
## Splitting slots
|
|
396
|
+
|
|
397
|
+
- A slot MAY stay empty. Content SHOULD stay in the kernel until that file grows past roughly 400 lines — a
|
|
398
|
+
suggestion, not a threshold, and a file that is clearer split earlier MAY be split earlier.
|
|
399
|
+
- The first slot to be split SHOULD be `04-usecases/` — it is always the largest part.
|
|
400
|
+
- One use case with many branches MUST put its branches in `05-scenarios/` rather than growing its own file.
|
|
401
|
+
- The `Actor Register` MUST stay in the SRS kernel. It is the SSOT the SDD mirrors, and it is short.
|
|
402
|
+
|
|
403
|
+
## Document codes
|
|
404
|
+
|
|
405
|
+
| Code | Is |
|
|
406
|
+
|---|---|
|
|
407
|
+
| `BG-` `CAP-` `FR-` `NFR-` `UJ-` `UC-` | The traceability chain. `BG` from `goals.yaml`; `CAP`/`FR`/`NFR`/`UJ` from that initiative's `requirements-<slug>.yaml`; `UC` from `usecases.yaml` |
|
|
408
|
+
| `AD-` | An invariant in the architecture spine — a living rule, edited in place |
|
|
409
|
+
| `DEC-` | A decision — an event, frozen when `applied`, only superseded |
|
|
410
|
+
| `LC-` | A Logical Component |
|
|
411
|
+
| `OQ-` | An open question. `RTR-` was the archived retrospective and is **retired** — a frozen `RTR-` file stays where it is |
|
|
412
|
+
| `BUG-` `HOT-` | A defect · a hotfix |
|
|
413
|
+
| `NT-` | A non-technical fact |
|
|
414
|
+
|
|
415
|
+
**Retired, and MUST NOT be coined again:** `ADR-` (renamed to `DEC-` on 2026-08-18; the old prefix inside a
|
|
416
|
+
document frozen before that date is an alias for the same number) · `ANX-` (zero annexes were ever born) ·
|
|
417
|
+
`SCP-` (a course correction is a `DEC-`) · `BRS-`, `PFQ-`, `RES-` (exploration output is never promoted).
|
|
418
|
+
|
|
419
|
+
IDs are allocated **globally** and never restart per document, per component, or per release.
|
|
420
|
+
|
|
421
|
+
### A record of the past MUST NOT be rewritten to match the present
|
|
422
|
+
|
|
423
|
+
A retired name appearing in a document that **records what happened** is a fact about the past, not
|
|
424
|
+
drift, and a sweep MUST NOT rename it. Four kinds, and all four are legitimate:
|
|
425
|
+
|
|
426
|
+
| Where | What it says | Why it stays |
|
|
427
|
+
|---|---|---|
|
|
428
|
+
| `.control/decisions/DEC-*.md` — `Applied to`, `Temuan` | *"`wdi-apply` applied this on 2026-08-17"* | It did. Renaming it to today's skill claims a skill that did not exist then did the work |
|
|
429
|
+
| `.control/memlog/*.md` | Which skill ran, and what it decided while running | A run log. Rewriting it destroys the only account of how an artifact got that way |
|
|
430
|
+
| `.control/questions/answered.md` · `project-non-technical-log.md` | An answer, with its date and who gave it | Closed in place by rule; the wording is part of the record |
|
|
431
|
+
| `.what/` and `.how/` frozen before a rename | Prose that cites the old name | Frozen by decision. `ADR-NNN` there is a retired alias for `DEC-NNN` with the same number |
|
|
432
|
+
|
|
433
|
+
The test is one question: **does this sentence describe what happened, or state what holds?** Describes
|
|
434
|
+
→ leave it. States → sweep it.
|
|
435
|
+
|
|
436
|
+
That distinction is why a sweep can be run repeatedly without churn. Without it, every pass rewrites
|
|
437
|
+
the same three dozen historical files and the diff stops carrying information.
|
|
438
|
+
|
|
439
|
+
File naming that must survive every OS is governed by `structure-guide.md` and MUST NOT be restated here.
|
|
440
|
+
|
|
441
|
+
## `.constitution/project/` — this product's custom rules
|
|
442
|
+
|
|
443
|
+
The rest of `.constitution/` **belongs to the method**: it ships in the `wdi-method` package and is
|
|
444
|
+
**overwritten** on every `update`. This folder is the only one that is not. `update` seeds it once and
|
|
445
|
+
never writes over it again, and `promote` **skips it**, so a rule that names a client cannot reach the
|
|
446
|
+
public package.
|
|
447
|
+
|
|
448
|
+
| Goes here | Does not, and its home |
|
|
449
|
+
|---|---|
|
|
450
|
+
| A review policy a client requires | product / client name → `index.yaml` `product:` |
|
|
451
|
+
| A process rule that came from a contract | code conventions → `.constitution/project/codebase-*-guide.md` |
|
|
452
|
+
| A policy that differs from the method default | scope and ownership → `.constitution/project/constitution.md` Art. 1, 2, 5 |
|
|
453
|
+
| A prohibition specific to this domain | agent instructions → `AGENTS.md`, outside the marked block |
|
|
454
|
+
|
|
455
|
+
**A generic rule MUST NOT be moved here.** If it holds in any project it belongs to the package — fix
|
|
456
|
+
it there, then `promote`. Using this room to bypass the package is how a method stops being generic
|
|
457
|
+
with nobody deciding it, and **an empty room is a valid state**: filling it so that it gets used is the
|
|
458
|
+
very failure this rule prevents.
|
|
459
|
+
|
|
460
|
+
Frontmatter is required and **`custom-room-declared`** checks it: `scope: project` · a one-line `purpose:`. A file MAY
|
|
461
|
+
narrow or add with nothing further; to **contradict** a generic rule it MUST name that rule in
|
|
462
|
+
`overrides:` and carry `decision:` naming the `DEC-` that decided it. A method that can be contradicted
|
|
463
|
+
without a decision stops being trustworthy in the next repo.
|
|
464
|
+
|
|
465
|
+
**Whole files, not marked blocks.** `AGENTS.md` uses a marked block because it is one file;
|
|
466
|
+
`.constitution/` has fifty-odd, and blocks inside them would make `update` perform surgery in every
|
|
467
|
+
file — one broken marker and either the product's rule is erased or the generic rule freezes.
|
|
468
|
+
|
|
469
|
+
## Documents that predate the method
|
|
470
|
+
|
|
471
|
+
A repository that already had documentation keeps it in `_bmad-output/prior-knowledge/`. It follows the same
|
|
472
|
+
rules as the rest of `_bmad-output/`: committed, never curated, cited by path, never deleted.
|
|
473
|
+
|
|
474
|
+
The sorting happens once, at install, and the test is a single question: **is this file already the artifact
|
|
475
|
+
one corpus slot asks for, one file for one slot?** Yes → straight into that slot, carrying a provenance line
|
|
476
|
+
naming the gate that ratifies it. No → `prior-knowledge/`.
|
|
477
|
+
|
|
478
|
+
**A file in `prior-knowledge/` MUST NOT be copied into `.what/` or `.how/` afterwards.** It enters the corpus
|
|
479
|
+
only through the skill that owns the slot, which reads it as input. This is the rule the whole arrangement
|
|
480
|
+
exists for: moving a file is always cheaper than running the stage that should have produced it, so without a
|
|
481
|
+
rule the move always wins — and what lands then has no author, no input trail, and no gate behind it.
|
|
482
|
+
|
|
483
|
+
### Retiring `prior-knowledge/`, and the condition that makes it safe
|
|
484
|
+
|
|
485
|
+
A prior document is **input**, and input stops being needed once what it was read for is written down. Three
|
|
486
|
+
conditions, and **all three MUST hold** before the folder is deleted:
|
|
487
|
+
|
|
488
|
+
1. **Every promise it carried is mapped.** The old numbering has a complete old → new table, and that table
|
|
489
|
+
lives in the `addendum.md` beside the PRD it maps into — **not** in `prior-knowledge/`, precisely so the
|
|
490
|
+
source can be retired without taking the map with it.
|
|
491
|
+
2. **Every live citation into it has been re-pointed or dropped.** A glossary entry, a `risk_note`, an
|
|
492
|
+
`enforced_by` — anything that *states what holds*. Where the fact has a home in code or in `.control/`, the
|
|
493
|
+
citation points there instead.
|
|
494
|
+
3. **The retirement is recorded as a `DEC-`.** Deleting source material is expensive to reverse, and the
|
|
495
|
+
answer to *why is it gone* is not readable from the code.
|
|
496
|
+
|
|
497
|
+
**A citation left inside a record of the past is not condition 2's business.** A `DEC-`'s Trace naming the
|
|
498
|
+
document it was derived from, or a memlog naming what a run read, describes what happened — and the rule above
|
|
499
|
+
on records of the past applies. Those citations dangle by design, and `wdi-reconcile`'s Evidence check MUST NOT
|
|
500
|
+
report them: what makes it harmless is that the substance is already written into the document doing the
|
|
501
|
+
citing, so the path is provenance rather than a dependency.
|
|
502
|
+
|
|
503
|
+
**`.work/` is not governed by these three conditions.** Nothing there was ever authority, so there is no
|
|
504
|
+
promise to map and no citation to re-point, and deleting scratch needs no `DEC-`. `repo-guide.md` § `.work/`
|
|
505
|
+
owns its retirement: distil what lasts, then delete when the task closes. The two guides used to disagree
|
|
506
|
+
here, and a repo holding a month of committed scratch could read either as permission to keep it.
|
|
507
|
+
|
|
508
|
+
Two consequences that MUST be expected rather than discovered:
|
|
509
|
+
|
|
510
|
+
- Internal numbering inside a prior document — `FR-3`, `§7` — is **not** a corpus ID. A mapping table MAY be
|
|
511
|
+
written once, and it lives in `prior-knowledge/`, never in `.control/`.
|
|
512
|
+
- A file placed straight into a slot MUST lose any claim of authority it makes about itself. In the corpus,
|
|
513
|
+
authority comes from the layer and the gate.
|
|
514
|
+
|
|
515
|
+
## Rules
|
|
516
|
+
|
|
517
|
+
- A file MUST NOT be moved between layers by a skill that owns neither end. Anything else is a misplacement,
|
|
518
|
+
and MUST be reported rather than fixed.
|
|
519
|
+
- A fact MUST have exactly one home. When two documents state the same thing, one of them MUST become a
|
|
520
|
+
reference — and the copy being replaced MUST be deleted, not left as a courtesy.
|
|
521
|
+
- Solution shape MUST NOT appear in `.what/`. Promises MUST NOT appear first in `.how/`.
|
|
522
|
+
- Superseded artifacts are not deleted. Their status becomes `superseded` and points at the replacement.
|