wdi-method 0.3.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 (122) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +203 -0
  3. package/bin/wdi-method.js +906 -0
  4. package/kit/.constitution/README.md +66 -0
  5. package/kit/.constitution/codebase/brownfield-guide.md +18 -0
  6. package/kit/.constitution/codebase/conventions-guide.md +18 -0
  7. package/kit/.constitution/codebase/stack-guide.md +18 -0
  8. package/kit/.constitution/constitution.md +135 -0
  9. package/kit/.constitution/document/architecture-guide.md +209 -0
  10. package/kit/.constitution/document/bmad-guide.md +151 -0
  11. package/kit/.constitution/document/bmad-skill-register.md +71 -0
  12. package/kit/.constitution/document/brief-guide.md +94 -0
  13. package/kit/.constitution/document/corpus-guide.md +341 -0
  14. package/kit/.constitution/document/decision-guide.md +134 -0
  15. package/kit/.constitution/document/delivery-flow-guide.md +338 -0
  16. package/kit/.constitution/document/prd-guide.md +202 -0
  17. package/kit/.constitution/document/sdd-guide.md +206 -0
  18. package/kit/.constitution/document/srs-guide.md +147 -0
  19. package/kit/.constitution/document/templates/addendum.md +71 -0
  20. package/kit/.constitution/document/templates/architecture-spine.md +100 -0
  21. package/kit/.constitution/document/templates/brief.md +110 -0
  22. package/kit/.constitution/document/templates/c4.md +77 -0
  23. package/kit/.constitution/document/templates/contract.md +52 -0
  24. package/kit/.constitution/document/templates/cross-cutting.md +80 -0
  25. package/kit/.constitution/document/templates/decision.md +64 -0
  26. package/kit/.constitution/document/templates/design-system.md +67 -0
  27. package/kit/.constitution/document/templates/flow.md +51 -0
  28. package/kit/.constitution/document/templates/integration.md +69 -0
  29. package/kit/.constitution/document/templates/inventory.md +69 -0
  30. package/kit/.constitution/document/templates/lc.md +47 -0
  31. package/kit/.constitution/document/templates/lifecycle.md +52 -0
  32. package/kit/.constitution/document/templates/meeting.md +47 -0
  33. package/kit/.constitution/document/templates/model.md +55 -0
  34. package/kit/.constitution/document/templates/oq.md +45 -0
  35. package/kit/.constitution/document/templates/prd.md +226 -0
  36. package/kit/.constitution/document/templates/questions.md +75 -0
  37. package/kit/.constitution/document/templates/rtr.md +61 -0
  38. package/kit/.constitution/document/templates/rules.md +47 -0
  39. package/kit/.constitution/document/templates/scn.md +40 -0
  40. package/kit/.constitution/document/templates/sdd.md +146 -0
  41. package/kit/.constitution/document/templates/srs.md +149 -0
  42. package/kit/.constitution/document/templates/structure-codebase.md +129 -0
  43. package/kit/.constitution/document/templates/structure-document.md +90 -0
  44. package/kit/.constitution/document/templates/uc.md +69 -0
  45. package/kit/.constitution/document/templates/ux.md +77 -0
  46. package/kit/.constitution/document/ux-guide.md +99 -0
  47. package/kit/.constitution/language-guide.md +69 -0
  48. package/kit/.constitution/method/README.md +169 -0
  49. package/kit/.constitution/method/artifact-map.md +155 -0
  50. package/kit/.constitution/method/portability.md +91 -0
  51. package/kit/.constitution/method/rationale.md +246 -0
  52. package/kit/.constitution/method-glossary.md +169 -0
  53. package/kit/.constitution/project/README.md +68 -0
  54. package/kit/.constitution/repo-guide.md +97 -0
  55. package/kit/.constitution/scripts/inventory.py +527 -0
  56. package/kit/.constitution/scripts/timeline.py +665 -0
  57. package/kit/.constitution/scripts/validate.py +1579 -0
  58. package/kit/.constitution/structure-guide.md +202 -0
  59. package/kit/assets/bmad-custom/bmad-advanced-elicitation.toml +15 -0
  60. package/kit/assets/bmad-custom/bmad-architecture.toml +31 -0
  61. package/kit/assets/bmad-custom/bmad-build-auto.toml +10 -0
  62. package/kit/assets/bmad-custom/bmad-build.toml +52 -0
  63. package/kit/assets/bmad-custom/bmad-code-review.toml +12 -0
  64. package/kit/assets/bmad-custom/bmad-correct-course.toml +27 -0
  65. package/kit/assets/bmad-custom/bmad-deep-recon.toml +11 -0
  66. package/kit/assets/bmad-custom/bmad-prd.toml +42 -0
  67. package/kit/assets/bmad-custom/bmad-product-brief.toml +34 -0
  68. package/kit/assets/bmad-custom/bmad-retrospective.toml +9 -0
  69. package/kit/assets/bmad-custom/bmad-spec.toml +15 -0
  70. package/kit/assets/bmad-custom/bmad-ux.toml +19 -0
  71. package/kit/assets/bmad-custom/config.toml +6 -0
  72. package/kit/skills/wdi-blueprint/SKILL.md +203 -0
  73. package/kit/skills/wdi-build/SKILL.md +244 -0
  74. package/kit/skills/wdi-component/SKILL.md +172 -0
  75. package/kit/skills/wdi-decision/.gitkeep +0 -0
  76. package/kit/skills/wdi-decision/SKILL.md +183 -0
  77. package/kit/skills/wdi-help/.gitkeep +0 -0
  78. package/kit/skills/wdi-help/SKILL.md +98 -0
  79. package/kit/skills/wdi-init/SKILL.md +149 -0
  80. package/kit/skills/wdi-log/SKILL.md +107 -0
  81. package/kit/skills/wdi-problem/SKILL.md +90 -0
  82. package/kit/skills/wdi-product/SKILL.md +127 -0
  83. package/kit/skills/wdi-question/.gitkeep +0 -0
  84. package/kit/skills/wdi-question/SKILL.md +88 -0
  85. package/kit/skills/wdi-reconcile/.gitkeep +0 -0
  86. package/kit/skills/wdi-reconcile/SKILL.md +146 -0
  87. package/kit/skills/wdi-report/SKILL.md +205 -0
  88. package/kit/skills/wdi-review/SKILL.md +118 -0
  89. package/kit/skills/wdi-systematic-debugging/SKILL.md +193 -0
  90. package/kit/skills/wdi-systematic-debugging/references/condition-based-waiting.md +115 -0
  91. package/kit/skills/wdi-systematic-debugging/references/defense-in-depth.md +122 -0
  92. package/kit/skills/wdi-systematic-debugging/references/find-polluter.sh +72 -0
  93. package/kit/skills/wdi-systematic-debugging/references/root-cause-tracing.md +169 -0
  94. package/kit/skills/wdi-ux/SKILL.md +145 -0
  95. package/kit-overlay/AGENTS.md +196 -0
  96. package/kit-overlay/README.md +66 -0
  97. package/kit-overlay/constitution.md +135 -0
  98. package/kit-overlay/portability.md +91 -0
  99. package/kit-overlay/repo-guide.md +97 -0
  100. package/lib/agents-block.mjs +52 -0
  101. package/lib/identity.mjs +65 -0
  102. package/package.json +37 -0
  103. package/scaffold/.control/decisions/.gitkeep +0 -0
  104. package/scaffold/.control/generated/.gitkeep +2 -0
  105. package/scaffold/.control/meetings/.gitkeep +0 -0
  106. package/scaffold/.control/memlog/.gitkeep +0 -0
  107. package/scaffold/.control/product-glossary.md +21 -0
  108. package/scaffold/.control/project-non-technical-log.md +23 -0
  109. package/scaffold/.control/questions/answered.md +11 -0
  110. package/scaffold/.control/questions/assumptions.md +15 -0
  111. package/scaffold/.control/questions/blocking.md +21 -0
  112. package/scaffold/.control/questions/external.md +11 -0
  113. package/scaffold/.control/registry/components.yaml +21 -0
  114. package/scaffold/.control/registry/decisions.yaml +6 -0
  115. package/scaffold/.control/registry/defects.yaml +3 -0
  116. package/scaffold/.control/registry/index.yaml +46 -0
  117. package/scaffold/.control/registry/requirements.yaml +15 -0
  118. package/scaffold/.control/registry/risks.yaml +5 -0
  119. package/scaffold/.control/registry/usecases.yaml +6 -0
  120. package/scaffold/.control/registry/waves.yaml +5 -0
  121. package/scaffold/.control/structure-codebase.md +19 -0
  122. package/scaffold/.control/structure-document.md +25 -0
@@ -0,0 +1,71 @@
1
+ ---
2
+ status: Accepted
3
+ ---
4
+
5
+ # BMad Skill Register
6
+
7
+ **Loaded when:** deciding which BMad skill a piece of work needs, or checking what one writes
8
+
9
+ This used to be the full catalogue of all 59 installed BMad skills. **That catalogue is retired.** It was a
10
+ copy of somebody else's inventory, it went stale on every BMad update, and nothing in this method read more
11
+ than a dozen of its rows. What binds is the division of labour below; for anything about a BMad skill this
12
+ method does not invoke, ask `bmad-help`, which reads BMad's own documentation.
13
+
14
+ ## Who writes what
15
+
16
+ | Artifact | Written by | Wrapped in |
17
+ |---|---|---|
18
+ | Product brief | `bmad-product-brief` | `wdi-problem` |
19
+ | PRD | `bmad-prd` | `wdi-product` |
20
+ | UX — `EXPERIENCE.md` + `DESIGN.md` | `bmad-ux` | `wdi-ux` |
21
+ | Architecture spine + the C4 set | `bmad-architecture` | `wdi-blueprint` intent `platform` |
22
+ | **UC catalogue · actors · entities · business rules** | **nothing in BMad** | `wdi-blueprint` writes it itself |
23
+ | **SRS and all of `.what/<pc>/`** | **nothing in BMad** | `wdi-component` writes it itself |
24
+ | **SDD and all of `.how/<pc>/`** | **nothing in BMad** | `wdi-component` writes it itself |
25
+ | `SPEC.md` + `stories.yaml` | `bmad-spec` | `wdi-build` |
26
+ | Code | `bmad-build` · `bmad-build-auto` | `wdi-build` |
27
+ | Retrospective | `bmad-retrospective` | `wdi-build` |
28
+ | Document review | `bmad-review` | `wdi-review` |
29
+ | Course correction | `bmad-correct-course` | `wdi-decision` |
30
+
31
+ **The three bold rows are why this method exists.** BMad stops at the promise and starts again at the
32
+ mechanism, and every behaviour in between had no author. Three consequences attach to those artifacts and
33
+ MUST be handled deliberately rather than discovered: no `doc_standards` fires a review, no memlog is born on
34
+ its own, and no template enforces itself.
35
+
36
+ ## No BMad skill is invoked directly
37
+
38
+ Every one above has a wrapper, and the wrapper is what checks position, verifies the result against the
39
+ guide, and lands the memlog. Routing past it produces an artifact nothing verifies.
40
+
41
+ **One exception, and it is narrow:** `bmad-build` MAY be invoked directly on the Fast Path. A Fast Path that
42
+ turns out to touch an `FR` MUST stop and become a wave `S`, which puts it back inside `wdi-build`.
43
+
44
+ ## What is available but writes nothing
45
+
46
+ | Skill | Use |
47
+ |---|---|
48
+ | `bmad-advanced-elicitation` · `bmad-party-mode` | Thinking aids. They produce no artifact and MUST NOT be treated as authors |
49
+ | `bmad-deep-recon` | Research, before a brief rests on outside data. Its output stays in `_bmad-output/` permanently and MUST NOT be folded into the brief |
50
+ | `bmad-code-review` | The two-reviewer panel over code, dispatched by `wdi-build`. Not for documents |
51
+ | `bmad-help` | Questions about BMad itself. It MUST NOT be used to answer "where am I" — that is `wdi-help` |
52
+
53
+ ## What is NOT USED, and MUST NOT be
54
+
55
+ | Skill | Why |
56
+ |---|---|
57
+ | `bmad-create-epics-and-stories` · `bmad-sprint-planning` · `bmad-sprint-status` | They belong to the sprint route, which keeps status in a hand-edited file. This method reads status from story-file frontmatter — `bmad-guide.md` owns the reasoning |
58
+ | `bmad-create-story` · `bmad-dev-story` · `bmad-quick-dev` · `bmad-dev-auto` | Deprecated in BMad itself; `bmad-build` and `bmad-build-auto` replace them |
59
+ | `bmad-editorial-review*` · `bmad-review-*` | Shims onto `bmad-review` lenses. Ask for the lens, not the shim |
60
+ | `bmad-document-project` · `bmad-generate-project-context` | Forward to `bmad-project-context`. This repo's agent instructions are maintained by hand |
61
+ | Any skill named as a **gate condition** | A gate is passed by its checklist and its validators, never by a skill having run |
62
+
63
+ ## The class that decides where output lands
64
+
65
+ `bmad-guide.md` owns the class definitions; what matters here is that **class B** exists because some skills
66
+ write several things at once that belong to different layers. `bmad-ux` is the case: `EXPERIENCE.md` is a
67
+ promise and `DESIGN.md` is a build detail, and no configuration can send them to two places. Its output
68
+ lands in a neutral folder first, and `wdi-ux` places it.
69
+
70
+ Which skill lands which output is the ownership table in `corpus-guide.md`, and it MUST NOT be duplicated
71
+ here.
@@ -0,0 +1,94 @@
1
+ ---
2
+ status: Accepted
3
+ ---
4
+
5
+ # Brief Guide
6
+
7
+ **Loaded when:** writing, updating, or validating the product brief
8
+
9
+ The brief is the G1 artifact. It answers WHY — what problem exists, whose it is, and why it is worth
10
+ building. Its shape lives in `templates/brief.md`; the rules that shape MUST obey live here.
11
+
12
+ ## Home and life cycle
13
+
14
+ - The brief MUST live at `.what/_product-brief/brief.md`, with `addendum.md` beside it. Both
15
+ filenames are fixed by `bmad-product-brief` and MUST NOT be expected to change; only the folder is
16
+ configurable.
17
+ - One brief per product, spanning every release. A second product MUST get its own repository — the
18
+ singleton is what makes "what did we set out to solve" answerable at all.
19
+ - The brief is amended, never re-run into a second folder. `run_folder_pattern` is a constant for
20
+ exactly this reason.
21
+ - The memlog MUST be written to `.control/memlog/brief.md` via `memlog.py --path`. `--workspace`
22
+ MUST NOT be used — it would drop a `.memlog.md` inside `.what/`, and no memlog belongs in the
23
+ corpus.
24
+
25
+ ## Required sections
26
+
27
+ `templates/brief.md` carries the shape. Its preamble invites dropping sections that do not earn
28
+ their place; that invitation MUST NOT be applied to the eight below. Everything else in the template
29
+ MAY be dropped.
30
+
31
+ | Section | Why it cannot be dropped |
32
+ |---|---|
33
+ | The Problem | The gate decides on this. Without it there is nothing to approve |
34
+ | Who This Serves | Names who the problem belongs to |
35
+ | Goals | `BG-N` is the first link of the traceability chain; without it the chain has no root |
36
+ | Success Criteria | The measure that makes "done" checkable |
37
+ | Scope In / Scope Out | The boundary the PRD is later held against |
38
+ | Constraints | What design MUST NOT trade away |
39
+ | Assumptions | What the brief would be wrong without |
40
+ | Prerequisites | What blocks work before it starts |
41
+
42
+ ## Decision rules
43
+
44
+ - The brief MUST name exactly one problem, one **primary** user, and one measure of success. Other
45
+ users and stakeholders are listed as secondary, not ranked away. If the primary cannot be chosen,
46
+ discovery is not finished and the gate MUST NOT open.
47
+ - Every user and stakeholder who touches the product MUST appear in the table, including those who
48
+ never open it — whoever pays for it, approves it, or is accountable for it.
49
+ - Goals MUST be numbered `BG-1`, `BG-2`, … and MUST NOT be numbered `G1`, `G2` — `G1`–`G5` name the
50
+ five gates. `BG` IDs are cited downstream and MUST stay stable once written.
51
+ - Scope Out MUST be written as items. Leaving it to be inferred from absence defeats its only
52
+ purpose, which is naming what someone will otherwise assume is coming.
53
+ - Per-release MVP scope belongs to the PRD, not here. This section states the product boundary.
54
+
55
+ ## The three product-level sections
56
+
57
+ BMad has no home for these; they exist because of that gap, and each has a rule about where it goes
58
+ when it stops being a statement.
59
+
60
+ | Section | Boundary | When it moves |
61
+ |---|---|---|
62
+ | Constraints | What is fixed before design starts. Technical constraints that only shape implementation belong in `addendum.md` | A constraint that emerges from a design decision becomes `AD-N` in the spine and MUST NOT be appended here later |
63
+ | Assumptions | What is believed but unverified, stated so it could be proven false | An assumption that starts to wobble MUST become a row in `.control/registry/risks.yaml` with an owner |
64
+ | Prerequisites | What MUST exist or be granted before work can start | Any prerequisite not yet satisfied MUST have a row in `.control/questions/external.md` naming who is being waited on and by when |
65
+
66
+ An assumption nobody would act differently about is not worth listing.
67
+
68
+ ## No Product Component list
69
+
70
+ The brief MUST NOT carry one, and MUST NOT fill `product_components`. The slicing is born at the
71
+ **tail of G2** through `wdi-init` intent `component`, which reads the brief and every PRD and
72
+ registers what the owner accepts. A list written at G1 is guessed before there is anything to guess
73
+ from, and every later gate inherits the guess.
74
+
75
+ ## Raw material
76
+
77
+ - Research, brainstorming, forge, and PRFAQ output MUST stay in `_bmad-output/`. It MUST NOT be
78
+ folded into the brief, and MUST NOT be promoted into `.what/`.
79
+ - A `DEC-` or the PRD cites it by path instead. `_bmad-output/` is committed, so the path is stable.
80
+ - Those run folders MUST NOT be deleted **while an `update` intent still needs them** — it re-reads the
81
+ original inputs. Once what they were read for is written down, they are retired under the three conditions
82
+ in `corpus-guide.md`, and that retirement is a `DEC-`. "Never deleted" was never the rule; needing them
83
+ was.
84
+
85
+ ## Passing G1
86
+
87
+ - Dying cheap is a pass. A brief concluding the idea is not worth building is a valid G1 outcome,
88
+ and the most profitable one.
89
+ - The brief MUST have been through `bmad-review` lenses structure + prose before it reaches the
90
+ gate. Gate time is for deciding, not for catching mistakes. This one fires on its own — it is the
91
+ *Polish* step of `bmad-product-brief`, driven by `doc_standards`, and nobody invokes it. Verifying
92
+ that it actually ran is check 9 in `wdi-problem`.
93
+ - Invoke through `wdi-problem`, not `bmad-product-brief` directly — the wrapper is what checks the
94
+ rules on this page.
@@ -0,0 +1,341 @@
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
+
27
+ `.control/` is the value of `{project_knowledge}` in BMad's configuration. There is no `docs/`.
28
+
29
+ ## The placement test
30
+
31
+ One question decides everything: **is this file still correct after its wave has passed?**
32
+
33
+ Yes → the corpus. No → `_bmad-output/`.
34
+
35
+ `_bmad-output/` is committed but **not curated**. Committing it is what makes citation by path stable, so a
36
+ decision or a PRD MAY point into it. Research, brainstorming, forge, and PRFAQ reports are never promoted.
37
+
38
+ A run folder MUST NOT be deleted **while anything still needs it** — the `update` intents re-read the original
39
+ inputs in place. "Never deleted" is not the rule; the rule is a **retirement condition**, and it is below.
40
+
41
+ ## Who lands what
42
+
43
+ There is no separate placement skill. A skill lands the output of the layer **it owns**, and the landing is
44
+ part of producing it — never a follow-up someone else performs.
45
+
46
+ | Output | Permanent home | Owner |
47
+ |---|---|---|
48
+ | The spine | `.how/_platform/ARCHITECTURE-SPINE.md` | `wdi-blueprint` |
49
+ | 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` |
50
+ | each container in C4 L2 | a `container` entry in `components.yaml` | `wdi-blueprint` |
51
+ | **The three inventories** | `.how/_platform/inventory-db.md` · `inventory-api.md` · `inventory-screen.md` | `wdi-blueprint` |
52
+ | The error envelope, and anything else defined once for the product | `.how/_platform/cross-cutting.md` | `wdi-blueprint` |
53
+ | UC catalogue · Actor Register · domain model | `.what/<pc>/SRS-<pc>.md` · `03-domain/domain-model.md` | `wdi-blueprint` |
54
+ | Business rules binding more than one PC | `.what/business-rules.md` | `wdi-blueprint` |
55
+ | A domain term | `.control/product-glossary.md` | `wdi-blueprint` |
56
+ | Full UC flows · local rules · state machines · scenarios | `.what/<pc>/` slots `02`–`05` | `wdi-component` intent `behaviour` |
57
+ | The SDD and its slots `02`–`06` | `.how/<pc>/` | `wdi-component` intent `design` |
58
+ | each Boundary and Control object drawn | an `LC` in `components.yaml` | `wdi-component` intent `design` |
59
+ | `EXPERIENCE.md` | `.what/<pc>/04-usecases/` | `wdi-ux` |
60
+ | `DESIGN.md` | `.how/<pc>/01-ux/` | `wdi-ux` |
61
+ | tokens and base components | `.how/_platform/design-system.md` | `wdi-ux` |
62
+ | each screen in `DESIGN.md` | an `LC` of type `ui-screen` in `components.yaml` | `wdi-ux` |
63
+ | `RETROSPECTIVE.md` | `RTR-<wave>.md` in `.control/reports/` | `wdi-build`, at wave close |
64
+ | `test-summary.md` | test names → `waves.yaml` | `wdi-build` |
65
+ | `stack.md` · `conventions.md` · `brownfield.md` | merged into `.constitution/codebase/*-guide.md` | `wdi-build`, at wave close |
66
+ | A sprint change proposal | a `DEC-` of `type: course-correction` | `wdi-decision` |
67
+ | The registry rows and skeletons a new PC needs | `components.yaml` · `.what/<pc>/` · `.how/<pc>/` | `wdi-init` intent `component` |
68
+ | `platform_owns` — an entity no component's promise explains | `components.yaml`, plus its description in `cross-cutting.md` | `wdi-blueprint` |
69
+ | The two structure maps | `.control/structure-codebase.md` · `structure-document.md` | `wdi-init` intent `structure` |
70
+ | An open question | `.control/questions/` — one of four files | `wdi-question` |
71
+ | A decision | `.control/decisions/DEC-NNN-<slug>.md` | `wdi-decision` |
72
+ | Minutes · a non-technical fact | `.control/meetings/` · `.control/project-non-technical-log.md` | `wdi-log` |
73
+
74
+ - A skill MUST NOT write into a layer it does not own.
75
+ - Registry conversion is part of landing, not a follow-up. A screen that lands in `01-ux/` without its
76
+ `components.yaml` entry has been half-landed, and V12 catches it **at wave close** — which is the
77
+ right moment to be caught, and a bad moment to be surprised.
78
+ - Content MUST NOT be edited while it is being landed. If it has to change to fit its new home, that is a
79
+ separate act — say so and stop. Splitting one output across the homes its row names is not editing.
80
+ - The C4 set's target files already exist and are **living**. Their owner MUST amend, MUST NOT overwrite; when
81
+ the incoming set contradicts an annotation already there, it MUST stop and report the finding.
82
+ - Nothing MAY be landed into a wave that is already closed. The wave is reopened through `wdi-build`, or the
83
+ gap is recorded as an open question.
84
+ - An output with **no row** in this table MUST NOT be given a guessed home. It stays in `_bmad-output/`, and
85
+ `wdi-reconcile` reports it — an output with no home is a gap in the method, and MUST surface as one.
86
+
87
+ ## Landing that MUST be confirmed first
88
+
89
+ Most landings are mechanical and MAY be done without asking. Some change what other people already agreed to,
90
+ and those MUST be put to the owner before the file is written — not reported afterwards. The line is drawn by
91
+ **what the landing can invalidate**, never by how much text moves:
92
+
93
+ | | Light — act, then report | Heavy — confirm, then act |
94
+ |---|---|---|
95
+ | Layer | Stays inside the layer the skill owns | Crosses into another layer's consequences |
96
+ | ID chain | No `BG`/`CAP`/`FR`/`NFR`/`UC`/`LC` id is born, renamed, or retired | Any of them is |
97
+ | Depth and risk | `mode` and `risk_accepted` unchanged | Either would have to change |
98
+ | Existing text | Adds, or replaces content the same skill wrote | Overwrites or contradicts what another skill or a human wrote |
99
+ | Registry | Adds the entry its own output requires | Removes or re-points an entry something else already cites |
100
+
101
+ Any one heavy row makes the whole landing heavy. When confirmation cannot be obtained now, the landing MUST
102
+ NOT be split into a light half that goes ahead — half-landed output looks distributed and is worse than output
103
+ that waited.
104
+
105
+ A skill MUST NOT lighten a landing by narrowing what it writes. Dropping the contentious half to stay under
106
+ the bar is the same change, made invisible.
107
+
108
+ ## Product Component — the naming and proposal rule
109
+
110
+ This rule lives here, beside the definition, and **not inside a skill**. If it lived in one skill, the second
111
+ skill that needed it would copy it, and the two copies would drift.
112
+
113
+ > The name of a Product Component MUST be a surface a user could name. A name that states a layer, a service,
114
+ > or a pattern MUST be rejected at proposal time, not corrected later. Additions, changes, and removals MUST
115
+ > be presented separately, each with the `FR` behind it.
116
+
117
+ A PC MUST NOT be created because a folder would look tidy. A PC that no `FR` points at is a folder with
118
+ nothing inside it.
119
+
120
+ Birthing is cheap and retiring is not: retiring or renaming a PC that already carries an SRS goes through
121
+ `wdi-decision`, never through the skill that births one.
122
+
123
+ ## Product Component, Logical Component, container, `_platform`
124
+
125
+ Four words that are easy to blur and MUST NOT be:
126
+
127
+ | Term | Is | Registered in |
128
+ |---|---|---|
129
+ | **Product Component** | A surface a user can name — what they came to do | `product_components` |
130
+ | **Logical Component** | A unit inside the build — a screen, a service, an adapter, an entity | `logical_components` |
131
+ | **Container** | Something that runs or ships on its own | `containers` |
132
+ | **`_platform`** | **Not a component at all** — the home for what belongs to no Product Component | `platform_owns`, and the `_platform/` folder |
133
+
134
+ PC and container are **crossing axes**, not a hierarchy: one PC MAY be delivered by several containers, and one
135
+ container MAY serve several PCs. An `LC` names its container in a `container:` field, which is what lets
136
+ `structure-codebase.md` be checked against the registry rather than trusted.
137
+
138
+ ## `_platform` — what belongs to no Product Component
139
+
140
+ `_platform` is **not a Product Component**, and it MUST NOT be registered as one. It fails the naming test on
141
+ purpose: nobody came to the product to use "the platform". It therefore carries **no `mode`, no
142
+ `risk_accepted`, no SRS, no SDD, and no G4** — its documents are the spine, the C4 set, `cross-cutting.md`,
143
+ and the three inventories, and all of those exist at every `mode`.
144
+
145
+ What it does carry is **ownership**. `_platform` is a legitimate value in **every** position that asks
146
+ *"which component owns this"* — the `platform_owns:` list for domain entities, the owning-component column
147
+ of any inventory row, an `LC`'s `component:` field, and any such column a later artifact adds. One test,
148
+ one cost, everywhere; there is no per-artifact special case to negotiate, and a new kind of thing arriving
149
+ next year needs no new discussion.
150
+
151
+ The test, and both halves MUST hold:
152
+
153
+ > Something belongs to `_platform` when **no single Product Component's promise is the reason it exists**,
154
+ > *and* more than one component reads, writes, or depends on it.
155
+
156
+ Four kinds qualify today and the list is open: **data** (a product-wide setting, the trace of a shared
157
+ outbound channel) · **endpoint** (`/health`, `robots.txt` — plumbing no `FR` promises and none should) ·
158
+ **job** (a scheduled cleaner whose data belongs to a component but whose machinery does not) · **screen**
159
+ (none yet).
160
+
161
+ Failing either half, it belongs to a Product Component — and the component is found by asking which `FR`
162
+ would have to be withdrawn for the entity to stop being needed. Two examples of the trap, both real:
163
+
164
+ | Entity | Looks platform-shaped | Actually |
165
+ |---|---|---|
166
+ | `member_activity_events` | member-wide telemetry, several components write it | **`referral`** — `FR-65` promises a Sponsor sees the login and click counts of their downline. One `FR` explains it |
167
+ | `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 |
168
+
169
+ **One guard, and it is what stops this becoming a drawer:** everything `_platform` owns — in any position —
170
+ MUST be described under `## Milik platform` in `cross-cutting.md`, with its kind and the shape every toucher
171
+ obeys. A platform that owns something documents it. V21 checks it, and skips only while that section has not
172
+ been born at G3.
173
+
174
+ That guard is the whole reason `_platform` can be a general answer rather than an escape hatch: reaching for
175
+ it costs a row somebody has to write, so it stays cheaper to find the real owner when one exists.
176
+
177
+ `_platform` has no `FR`, so an `FR` that writes something platform-owned has nothing to point `defers_to` at,
178
+ and MUST NOT be asked for one. What replaces "one writer" there is **one documented shape**: it is written the
179
+ way `cross-cutting.md` says, and a component wanting it written differently is proposing a change to that file.
180
+
181
+ Platform ownership sits with `wdi-blueprint` intent `platform`, beside the rest of `_platform/`. `wdi-init`
182
+ intent `component` MAY name a candidate and MUST NOT claim one.
183
+
184
+ **A decision the pattern cannot derive lives in the artifact it governs.** An inventory row owned by
185
+ `_platform`, and a route that is a *state* of another screen rather than a screen of its own, are both
186
+ judgements — so both are declared in that inventory's own frontmatter (`platform_rows:` and `states:`) and
187
+ survive every re-derivation. Putting either outside the file means the next derivation silently deletes the
188
+ owner's decision.
189
+
190
+ ## Two axes inside `.what/`
191
+
192
+ | | `_prd/<initiative>/` | `<pc>/` |
193
+ |---|---|---|
194
+ | Slices by | **Initiative** — one functional area | **Space** — one Product Component |
195
+ | Answers | What is promised to a user | What this component can do |
196
+ | Written for | Outside readers — client, sponsor | People building the system |
197
+
198
+ Both are living. What separates them is **promise versus behaviour**, not lifetime. One functional area MAY
199
+ span several components, and one component MAY serve several PRDs, so neither can absorb the other.
200
+
201
+ **Time is not a folder axis.** Release lives in `CAP.target_release` and in `waves.yaml`.
202
+
203
+ ## Slot numbering means two different things
204
+
205
+ | Layer | Slots | The number means |
206
+ |---|---|---|
207
+ | `.what/<pc>/` | `02-rules` · `03-domain` · `04-usecases` · `05-scenarios` | **Reading order** — its rules → the things → how it is used → its branches |
208
+ | `.how/<pc>/` | `01-ux` … `06-flows` | **ABCE classification** — Boundary, Control, Entity, behaviour. Not a reading order |
209
+
210
+ Reading one as the other is the most common misfiling in this corpus, and it is silent: the file lands in a
211
+ plausible-looking folder and is simply never found again.
212
+
213
+ `.what/<pc>/01-requirements/` is **repealed** — permanently empty, because `FR` live in the PRD and the SRS
214
+ cites them. `supplements/` beside either kernel is repealed with the `ANX-` concept.
215
+
216
+ ## Splitting slots
217
+
218
+ - A slot MAY stay empty. Content SHOULD stay in the kernel until that file grows past roughly 400 lines — a
219
+ suggestion, not a threshold, and a file that is clearer split earlier MAY be split earlier.
220
+ - The first slot to be split SHOULD be `04-usecases/` — it is always the largest part.
221
+ - One use case with many branches MUST put its branches in `05-scenarios/` rather than growing its own file.
222
+ - The `Actor Register` MUST stay in the SRS kernel. It is the SSOT the SDD mirrors, and it is short.
223
+
224
+ ## Document codes
225
+
226
+ | Code | Is |
227
+ |---|---|
228
+ | `BG-` `CAP-` `FR-` `NFR-` `UJ-` `UC-` | The traceability chain, allocated from `requirements.yaml` and `usecases.yaml` |
229
+ | `AD-` | An invariant in the architecture spine — a living rule, edited in place |
230
+ | `DEC-` | A decision — an event, frozen when `applied`, only superseded |
231
+ | `LC-` | A Logical Component |
232
+ | `OQ-` `RTR-` | An open question · an archived retrospective |
233
+ | `BUG-` `HOT-` | A defect · a hotfix |
234
+ | `NT-` | A non-technical fact |
235
+
236
+ **Retired, and MUST NOT be coined again:** `ADR-` (renamed to `DEC-` on 2026-08-18; the old prefix inside a
237
+ document frozen before that date is an alias for the same number) · `ANX-` (zero annexes were ever born) ·
238
+ `SCP-` (a course correction is a `DEC-`) · `BRS-`, `PFQ-`, `RES-` (exploration output is never promoted).
239
+
240
+ IDs are allocated **globally** and never restart per document, per component, or per release.
241
+
242
+ ### A record of the past MUST NOT be rewritten to match the present
243
+
244
+ A retired name appearing in a document that **records what happened** is a fact about the past, not
245
+ drift, and a sweep MUST NOT rename it. Four kinds, and all four are legitimate:
246
+
247
+ | Where | What it says | Why it stays |
248
+ |---|---|---|
249
+ | `.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 |
250
+ | `.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 |
251
+ | `.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 |
252
+ | `.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 |
253
+
254
+ The test is one question: **does this sentence describe what happened, or state what holds?** Describes
255
+ → leave it. States → sweep it.
256
+
257
+ That distinction is why a sweep can be run repeatedly without churn. Without it, every pass rewrites
258
+ the same three dozen historical files and the diff stops carrying information.
259
+
260
+ File naming that must survive every OS is governed by `structure-guide.md` and MUST NOT be restated here.
261
+
262
+ ## `.constitution/project/` — this product's custom rules
263
+
264
+ The rest of `.constitution/` **belongs to the method**: it ships in the `wdi-method` package and is
265
+ **overwritten** on every `update`. This folder is the only one that is not. `update` seeds it once and
266
+ never writes over it again, and `promote` **skips it**, so a rule that names a client cannot reach the
267
+ public package.
268
+
269
+ | Goes here | Does not, and its home |
270
+ |---|---|
271
+ | A review policy a client requires | product / client name → `index.yaml` `product:` |
272
+ | A process rule that came from a contract | code conventions → `codebase/*-guide.md` |
273
+ | A policy that differs from the method default | scope and ownership → `constitution.md` Art. 1, 2, 5 |
274
+ | A prohibition specific to this domain | agent instructions → `AGENTS.md`, outside the marked block |
275
+
276
+ **A generic rule MUST NOT be moved here.** If it holds in any project it belongs to the package — fix
277
+ it there, then `promote`. Using this room to bypass the package is how a method stops being generic
278
+ with nobody deciding it, and **an empty room is a valid state**: filling it so that it gets used is the
279
+ very failure this rule prevents.
280
+
281
+ Frontmatter is required and **V27** checks it: `scope: project` · a one-line `purpose:`. A file MAY
282
+ narrow or add with nothing further; to **contradict** a generic rule it MUST name that rule in
283
+ `overrides:` and carry `decision:` naming the `DEC-` that decided it. A method that can be contradicted
284
+ without a decision stops being trustworthy in the next repo.
285
+
286
+ **Whole files, not marked blocks.** `AGENTS.md` uses a marked block because it is one file;
287
+ `.constitution/` has fifty-odd, and blocks inside them would make `update` perform surgery in every
288
+ file — one broken marker and either the product's rule is erased or the generic rule freezes.
289
+
290
+ ## Documents that predate the method
291
+
292
+ A repository that already had documentation keeps it in `_bmad-output/prior-knowledge/`. It follows the same
293
+ rules as the rest of `_bmad-output/`: committed, never curated, cited by path, never deleted.
294
+
295
+ The sorting happens once, at install, and the test is a single question: **is this file already the artifact
296
+ one corpus slot asks for, one file for one slot?** Yes → straight into that slot, carrying a provenance line
297
+ naming the gate that ratifies it. No → `prior-knowledge/`.
298
+
299
+ **A file in `prior-knowledge/` MUST NOT be copied into `.what/` or `.how/` afterwards.** It enters the corpus
300
+ only through the skill that owns the slot, which reads it as input. This is the rule the whole arrangement
301
+ exists for: moving a file is always cheaper than running the stage that should have produced it, so without a
302
+ rule the move always wins — and what lands then has no author, no input trail, and no gate behind it.
303
+
304
+ ### Retiring `prior-knowledge/`, and the condition that makes it safe
305
+
306
+ A prior document is **input**, and input stops being needed once what it was read for is written down. Three
307
+ conditions, and **all three MUST hold** before the folder is deleted:
308
+
309
+ 1. **Every promise it carried is mapped.** The old numbering has a complete old → new table, and that table
310
+ lives in the `addendum.md` beside the PRD it maps into — **not** in `prior-knowledge/`, precisely so the
311
+ source can be retired without taking the map with it.
312
+ 2. **Every live citation into it has been re-pointed or dropped.** A glossary entry, a `risk_note`, an
313
+ `enforced_by` — anything that *states what holds*. Where the fact has a home in code or in `.control/`, the
314
+ citation points there instead.
315
+ 3. **The retirement is recorded as a `DEC-`.** Deleting source material is expensive to reverse, and the
316
+ answer to *why is it gone* is not readable from the code.
317
+
318
+ **A citation left inside a record of the past is not condition 2's business.** A `DEC-`'s Trace naming the
319
+ document it was derived from, or a memlog naming what a run read, describes what happened — and the rule above
320
+ on records of the past applies. Those citations dangle by design, and `wdi-reconcile`'s Evidence check MUST NOT
321
+ report them: what makes it harmless is that the substance is already written into the document doing the
322
+ citing, so the path is provenance rather than a dependency.
323
+
324
+ The same three conditions govern `.work/`, with one difference: nothing there was ever authority, so condition
325
+ 1 is usually already met.
326
+
327
+ Two consequences that MUST be expected rather than discovered:
328
+
329
+ - Internal numbering inside a prior document — `FR-3`, `§7` — is **not** a corpus ID. A mapping table MAY be
330
+ written once, and it lives in `prior-knowledge/`, never in `.control/`.
331
+ - A file placed straight into a slot MUST lose any claim of authority it makes about itself. In the corpus,
332
+ authority comes from the layer and the gate.
333
+
334
+ ## Rules
335
+
336
+ - A file MUST NOT be moved between layers by a skill that owns neither end. Anything else is a misplacement,
337
+ and MUST be reported rather than fixed.
338
+ - A fact MUST have exactly one home. When two documents state the same thing, one of them MUST become a
339
+ reference — and the copy being replaced MUST be deleted, not left as a courtesy.
340
+ - Solution shape MUST NOT appear in `.what/`. Promises MUST NOT appear first in `.how/`.
341
+ - Superseded artifacts are not deleted. Their status becomes `superseded` and points at the replacement.
@@ -0,0 +1,134 @@
1
+ ---
2
+ status: Accepted
3
+ ---
4
+
5
+ # Decision Guide
6
+
7
+ **Loaded when:** opening, accepting, or applying a `DEC-`
8
+
9
+ A `DEC-` records a decision worth remembering. The old name was ADR — *Architecture Decision Record*
10
+ — and the word "Architecture" forced the wrong question at the moment of writing: *"is this
11
+ architectural?"*. That question throws away the decisions most worth keeping, the ones that sound
12
+ small: *"the filter works like this"*, *"this list is sorted that way"*.
13
+
14
+ ## One test decides whether to record
15
+
16
+ > **If someone asks in three months why it is like this, is the answer readable from the code?**
17
+
18
+ Yes → it MUST NOT be recorded. No → it is recorded.
19
+
20
+ **Recording is not mandatory, and a decision nobody recorded is normal rather than negligence.** It
21
+ MUST NOT be logged as debt, raised as a finding, or backfilled later from memory. Without this
22
+ sentence, "not mandatory" is read as "mandatory but allowed to be late".
23
+
24
+ One case remains mandatory: a decision that **contradicts or changes an `AD-N`** MUST be recorded
25
+ before the work that depends on it. That is the only one.
26
+
27
+ ## `AD-N` and `DEC-NNN` are not the same thing
28
+
29
+ | | `AD-N` | `DEC-NNN` |
30
+ |---|---|---|
31
+ | Is | A **living rule** in `ARCHITECTURE-SPINE.md` | A **decision event** |
32
+ | Lives in | The spine | `.control/decisions/` |
33
+ | Changes by | Being edited in place | Never, once `applied` — a new `DEC-` supersedes it |
34
+ | Answers | What is forbidden from now on | What was chosen, and what it cost |
35
+
36
+ An `AD-N` usually has a `DEC-` behind it. Neither MUST be written in place of the other, and one MUST
37
+ NOT be converted into the other.
38
+
39
+ ## Shape — three sections, and no more required
40
+
41
+ | Section | States | Required |
42
+ |---|---|---|
43
+ | **Decision** | One sentence, present tense, quotable into a rule | always |
44
+ | **Why** | The context that forced it, in a few lines | always |
45
+ | **Cost** | What becomes harder. A decision with only benefits was not thought through | always |
46
+ | Alternatives | What else was considered, and why each lost | see below |
47
+ | Reversal trigger | The observable condition that makes revisiting this correct | see below |
48
+ | Trace | Where it came from, and what it landed in | see below |
49
+
50
+ The last three MUST be present when the decision reaches a Product Component whose `risk_accepted`
51
+ is `low` in `components.yaml`. Everywhere else they are optional, and an empty one MUST be dropped
52
+ rather than left as a heading with nothing under it.
53
+
54
+ **A `DEC-` MUST NOT hold an open question.** Those belong to `.control/questions/`.
55
+
56
+ ## Frontmatter
57
+
58
+ | Field | Rule |
59
+ |---|---|
60
+ | `id` | `DEC-NNN`, allocated from `.control/registry/decisions.yaml`, globally. MUST NOT restart per component or per release |
61
+ | `status` | `draft` · `accepted` · `applied` · `superseded` · `rejected` |
62
+ | `touches` | Empty at `draft`. Filled **when the decision is applied**, with the files it actually changed |
63
+ | `type` | Free text, and optional. Written when it is useful — `risk-acceptance`, `course-correction` |
64
+ | `supersedes` · `superseded_by` | Both sides of a supersession MUST exist |
65
+
66
+ **There is no `layer:` and no `component:`.** Both were classifications demanded before anything was
67
+ known, and both were guessed as often as they were derived. `touches:` replaces them, and it is filled
68
+ from what happened rather than from what was predicted.
69
+
70
+ The filename is `DEC-NNN-<slug>.md`. It MUST NOT carry a component name — a decision that turns out to
71
+ reach a second component would otherwise need renaming, and the rename breaks every link to it.
72
+ Filenames MUST obey the cross-OS naming rules in `structure-guide.md`.
73
+
74
+ ## Status — and why `applied` exists
75
+
76
+ `draft` → `accepted` → `applied`. A change of mind after that produces a **new** `DEC-`.
77
+
78
+ | Status | Means |
79
+ |---|---|
80
+ | `draft` | Being argued. It changes nothing, and that is the point — proposing is cheap |
81
+ | `accepted` | Ratified by the Product Owner. MAY still be corrected in place |
82
+ | `applied` | The documents it governs now say it. **Frozen from here** |
83
+ | `superseded` | Replaced. Names its replacement, and the replacement names it |
84
+ | `rejected` | Seriously considered and turned down. A real status, and it MUST be used — it is what stops the same argument being had twice |
85
+
86
+ **Applying is what freezes a decision, not accepting.** From `applied` onward nothing in the file MUST
87
+ be touched — not the Decision, not the Cost, not a typo in the Why. Documents cite it, and editing it
88
+ destroys the only evidence of what they were changed to match.
89
+
90
+ Before that, an `accepted` `DEC-` MAY be corrected in place. Nothing has been built on it, so there is
91
+ no divergent record to preserve. The correction MUST be recorded in the memlog.
92
+
93
+ An agent MUST NOT accept its own `DEC-`. When work is blocked waiting on one, the block is reported,
94
+ never resolved by self-approval.
95
+
96
+ ## Finding a decision
97
+
98
+ `.control/generated/decisions.md` carries a flat table of every `DEC-` with its status and what it
99
+ touches. It is generated, and MUST NOT be written by hand.
100
+
101
+ Searching the memlog for decisions is **retired**. The memlog is a run log again — the record of *why*
102
+ while an artifact was written, and a source when writing a `DEC-`, never an index of them.
103
+
104
+ ## Where decisions come from
105
+
106
+ | Trigger | Route |
107
+ |---|---|
108
+ | A meeting reached one | `wdi-log` intent `meeting` writes the minutes; the decision still needs its own `DEC-` |
109
+ | An open question was answered | `wdi-question` closes it; the answer becomes a `DEC-` when it binds |
110
+ | `wdi-systematic-debugging` found a root cause in the design | A `DEC-`. It MUST NOT be absorbed as a code patch |
111
+ | A planning assumption turned out to be void | `wdi-decision`, which wraps `bmad-correct-course`. The result is a `DEC-` of `type: course-correction` |
112
+ | A story contradicts an `AD-N` | The story stops. This is the one mandatory case |
113
+ | `wdi-reconcile` found two documents disagreeing with no clear winner | That is a decision, not drift |
114
+
115
+ Minutes MUST NOT be treated as a decision record. They say what was discussed; a `DEC-` says what was
116
+ chosen and what it cost.
117
+
118
+ **`SCP-` is retired.** A course correction is a decision, and it is a `DEC-` with
119
+ `type: course-correction`. No second code names the same thing.
120
+
121
+ ## Rules
122
+
123
+ - A `DEC-` MUST be opened **before** the code that depends on it, never written afterwards to explain
124
+ code that already exists.
125
+ - The applying pass MUST NOT improvise. When an `accepted` `DEC-` does not say clearly what a document
126
+ has to change, the decision is incomplete and is sent back.
127
+ - Applying MUST NOT widen beyond what the decision says. A neighbouring paragraph that now looks wrong
128
+ is a finding to report.
129
+ - V8 checks that every `applied` `DEC-` names a non-empty `touches`. It MUST NOT check that a decision
130
+ serves an `FR` or `NFR` — *"the filter works like this"* serves none, and it is exactly the kind of
131
+ decision this guide exists to keep.
132
+ - `ADR-NNN` written inside a document frozen before 2026-08-18 is a **retired alias** for `DEC-NNN`
133
+ with the same number. It MUST NOT be read as a second, missing record, and those documents MUST NOT
134
+ be rewritten to change the prefix.