wdi-method 0.6.27 → 0.6.28

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.
@@ -1,231 +1,231 @@
1
- ---
2
- name: wdi-init
3
- description: Use for anything that must exist before work can start or continue — scaffolding the registries at install, birthing Product Components after G2, setting or changing a component's mode, setting or reviewing its risk_accepted, refreshing the two structure maps, and writing this product's inventory readers. Six intents. Never writes .what/ or .how/ content beyond a skeleton.
4
- ---
5
-
6
- # WDI Init
7
-
8
- Six intents, one skill, because all six answer the same question: **what has to exist before the
9
- next piece of work makes sense?** A registry row, a folder pair, a depth setting, a risk note, a map
10
- of where things are, a reader that can see this product's code.
11
-
12
- | Intent | Does | Precondition | How often |
13
- |---|---|---|---|
14
- | `setup` | Guide the global `mode` setting · scaffold the registries that are still empty · **report** the documents already present, read-only · derive the two structure maps · align the engines | before G1 | once per project |
15
- | `engines` | Run `npx wdi-method engines --fix`, then report what it changed: the flag stripped from `to-spec` · `to-tickets` · `implement` so `wdi-build` can invoke them, the retired BMad G5 wrappers locked out of model invocation and denied in `.claude/settings.json`, and `docs/agents/` repaired where it still carried upstream's answer | after every `wdi-method install` or `update` | each version jump, and any time `engines-invocable` is red |
16
- | `component` | Propose the slicing from the brief plus every PRD · birth what is accepted: registry row plus `SRS`/`SDD` skeletons · propose `mode`, `risk_accepted`, `risk_note`, `owns` | **G2 passed** | each time a component is born |
17
- | `mode` | Change `mode` — global in `index.yaml`, or one component in `components.yaml`. Guided | — | any time |
18
- | `risk` | Set or review one component's `risk_accepted`, with disclosure of what it touches | the component exists | any time, usually before G4 |
19
- | `structure` | Re-derive `.control/structure-codebase.md` and `structure-document.md` from the tree on disk | — | when folders change, and at spec close |
20
- | `readers` | Write `.constitution/project/inventory-readers.py` for **this** repo's stack, then prove it by running the engine | code exists | once, and again when the code's shape moves |
21
-
22
- ## Two boundaries
23
-
24
- - It **does not sort, move, or delete** an existing document. Intent `setup` reports what is there and
25
- stops. A file that predates the method enters the corpus only through the skill owning its slot —
26
- `corpus-guide.md` owns that rule.
27
- - Retiring or renaming a Product Component that already carries an SRS **is not its authority**. That
28
- goes through `wdi-decision`. Birthing is cheap; retiring is not.
29
-
30
- ## Intent `engines`
31
-
32
- One command does the work — `npx wdi-method engines --fix` — and this intent exists because the work is
33
- not the installer's to do unasked. Two of the three things it touches are files somebody else owns:
34
- `docs/agents/*.md` is the product's, and the engines' `SKILL.md` files are the author's. `install` and
35
- `update` do the two mechanical halves (the flag, the BMad lock) on every run; the config repair happens
36
- only here, knowingly, and the previous text is kept as `.bak`.
37
-
38
- Report, always, in this order: which engines are present and which are missing (all six are required —
39
- `to-spec` · `to-tickets` · `implement` · `tdd` · `code-review` · `domain-modeling`), which had the flag
40
- stripped, how many BMad wrappers were locked, and whether `docs/agents/issue-tracker.md` was upstream's
41
- or already the method's. If any engine is missing, say so and stop: `npx skills@latest add
42
- mattpocock/skills` is the owner's to run, and a user-level plugin does not count — its files cannot be
43
- unlocked.
44
-
45
- Then run `validate.py`. `engines-invocable` green is the proof, not the report.
46
-
47
- ## Intent `setup`
48
-
49
- 1. Read the tree. Report every document already present, by path, with one line on what it looks like.
50
- **Read-only.** You MUST NOT move one.
51
- 2. Scaffold the registry files that carry no rows yet. A file that already has rows MUST NOT be
52
- rewritten.
53
- 3. Put the global `mode` to the owner. The default is `catalog`; the four values and what each buys are
54
- in `delivery-flow-guide.md`, and MUST NOT be restated here.
55
- 4. Run intent `structure`.
56
-
57
- ## Intent `component`
58
-
59
- 1. Read the brief and **every** PRD. A slicing proposed from one PRD is a slicing of one PRD.
60
- 2. Propose the list. The naming rule and the presentation rule live in `corpus-guide.md` — a name that
61
- states a layer, a service, or a pattern MUST be rejected at proposal time, and additions, changes,
62
- and removals MUST be presented separately with the `FR` behind each.
63
- 3. The owner decides. You MUST NOT register a component the owner has not accepted.
64
- 4. For each accepted birth, write in one act:
65
- - the `product_components` row in `.control/registry/components.yaml`, carrying `owns:`
66
- - `.what/<pc>/SRS-<pc>.md` from `templates/srs.md`
67
- - `.how/<pc>/SDD-<pc>.md` from `templates/sdd.md`
68
- - the empty slots each kernel's guide names
69
- 5. Run the disclosure below, then propose `mode` and `risk_accepted` per component.
70
-
71
- Content SHOULD stay in the kernel until it grows past roughly 400 lines — a suggestion, not a threshold.
72
- The first slot to be split out SHOULD be `04-usecases/`; it is always the largest.
73
-
74
- **Logical Components are not born here.** An `LC` is born by the skill that draws it — `wdi-component`
75
- intent `design`, or `wdi-ux` for a screen — and `components.yaml` states the entry shape and the `type`
76
- → prose-home mapping in its own header. You MAY report an `LC` that looks wrong; you MUST NOT create
77
- one.
78
-
79
- **Neither is `platform_owns`.** An entity that no component's promise explains belongs to `_platform`,
80
- and `wdi-blueprint` intent `platform` registers it. You MUST name the candidate and the reason, and you
81
- MUST NOT claim it — and before naming one, you MUST apply the test in `corpus-guide.md`: ask which `FR`
82
- would have to be withdrawn for the entity to stop being needed. If that `FR` exists, the entity belongs
83
- to its component, however platform-shaped the table looks.
84
-
85
- ## Intents `mode` and `risk` — disclose, then propose
86
-
87
- `mode` controls **document depth** and nothing else. `risk_accepted` controls **review intensity** and
88
- nothing else. Their definitions live in `delivery-flow-guide.md`, and what the two chosen together cost is
89
- laid out cell by cell in `.constitution/method/why/mode-risk-map.md` — show it when the owner asks what a
90
- combination buys. What this skill owns is the conversation around changing them.
91
-
92
- **You do not judge. You disclose, then propose.** Read the `FR` that fall to the component, then name
93
- what it touches:
94
-
95
- - money moving
96
- - personal data
97
- - an irreversible action
98
- - a contractual promise to an outside party
99
- - a third-party integration that cannot be rolled back
100
-
101
- Only after that do you propose `mode` and `risk_accepted`.
102
-
103
- **Land whatever UX is waiting, in this same act.** A UX run at G2 leaves `EXPERIENCE.md` and `DESIGN.md`
104
- in `_bmad-output/ux/` because their paths contain `<pc>` and there was no `<pc>` yet. Birthing the
105
- components is the moment that ends. Landing goes through `wdi-ux` — it owns those two paths and no other
106
- skill MAY write them — but it is dispatched from here rather than left for the owner to remember. It is
107
- the only deferral left in the flow, and this is where it closes.
108
-
109
- **Containers MAY be registered here when they are genuinely already known** — an app, an API, a database
110
- the product plainly has. Then a screen `LC` gets its container the moment it is born and there is no debt
111
- at all. They MUST NOT be guessed to achieve that: `wdi-blueprint` intent `platform` owns the real answer
112
- at G3, and a container invented here is data C4 then has to unpick. Where you are unsure, leave them and
113
- let G3 fill both the containers and the empty `LC` rows in one act.
114
-
115
- Raising or lowering `mode` is **free and needs no justification** — it is a preference, and a preference
116
- does not have to be defended. Setting `mode: catalog` on a sensitive component requires nothing, as long
117
- as its review stays hard; that combination is the one the split exists to make sayable.
118
-
119
- Two things are not free:
120
-
121
- - **`risk_accepted: high` on a component that touches any of the five** requires a named acceptance in
122
- `risk_accepted_by` — **a person and a date is enough**, written here in `components.yaml` beside the
123
- risk itself rather than as a separate file. A `DEC-` id is still accepted and still has to resolve.
124
- `high-risk-named` checks this. On a component that touches none of them, `high` is free.
125
- - **An outside party who will demand the artifacts as a deliverable** — a regulator, an auditor, a
126
- client through a contract — puts the touched component at `mode: deep` and `risk_accepted: low`,
127
- whatever the global setting says. That floor MUST NOT be traded against a preference: the risk there
128
- is not the owner's alone to accept.
129
-
130
- > The control is not a veto, it is disclosure. The owner MAY choose fast anywhere, but never without
131
- > knowing what is being staked.
132
-
133
- **Lowering `mode` does not delete anything.** A file already written stops being required, and that is
134
- all. Deleting it throws away knowledge already paid for, and a lowered `mode` is a preference — not a
135
- statement that the content was wrong.
136
-
137
- **Raising `mode` on a component whose code already runs** produces an **as-built record**, not a design.
138
- `wdi-component` writes it, under the evidence labels `sdd-guide.md` owns.
139
-
140
- ## Intent `structure`
141
-
142
- The rules for what belongs in a map live in `.constitution/method/structure-guide.md`. This intent applies
143
- them; it MUST NOT restate them.
144
-
145
- 1. **Derive from the tree on disk**, honouring `.gitignore`. A map assembled from what the caller says
146
- is there is the failure this intent exists to prevent.
147
- 2. Classify each base folder. For the codebase map the only test is deployability — a **container** runs
148
- its own code or stores its own data, a **library** is imported by something else, anything else stays
149
- a line in the top-level tree or in a non-unit section. Size and importance MUST NOT decide it.
150
- Container headings MUST be **exactly the `built: true` containers** in `components.yaml`: every
151
- heading is a registered container, and a `built: false` one MUST NOT get a heading because no code of
152
- ours lives in it. The match is one-directional, and reading it both ways makes it unsatisfiable.
153
- 3. Draw the convention, not the contents. A shape that repeats MUST be written once with a placeholder.
154
- 4. Mark key files `★` by the four tests in the guide. Borderline files are left out.
155
- 5. Write from `templates/structure-codebase.md` and `templates/structure-document.md`. Template comments
156
- and the skeleton block MUST be deleted from the finished file.
157
- 6. Stamp `Verified` with the date and the commit SHA the tree was read at.
158
- 7. Report drift, unclaimed folders, and one-sided Product Components separately. This intent MUST NOT
159
- fix them.
160
-
161
- It MAY be run **read-only** — derive, report the drift, write nothing. That is the right mode when the
162
- caller is unsure: a map is cheap to check and expensive to get wrong.
163
-
164
- A hand-edited map MUST be treated as drift: re-derive, then say what the hand edit claimed that the tree
165
- does not support.
166
-
167
- ## Intent `readers`
168
-
169
- `inventory.py` is two halves. Comparing what was derived against the plan, reporting the gap, keeping
170
- the numbers stable — that is the same in every stack and belongs to the method. **Reading the code is
171
- not**, so the package ships a skeleton and no example: an example is a guess about somebody else's
172
- stack, and the whole point of deriving rather than assembling is that nothing is guessed.
173
-
174
- The file is `.constitution/project/inventory-readers.py`. All of it is the product's — `update` never
175
- writes over it and `promote` never publishes it — so there is no protected region inside it and
176
- nothing to merge.
177
-
178
- 1. **Read the repo before writing a line.** Where does the schema live, how are routes registered,
179
- how are screens declared. A stack you have not confirmed on disk MUST NOT be assumed from a
180
- filename or a dependency list.
181
- 2. Fill `derive_db`, `derive_api`, and `derive_screen`. The contract, the injected names, and the
182
- column order per kind are in the skeleton's own docstring and MUST NOT be restated here.
183
- 3. **Delete the `SKELETON = True` line.** While it stands the engine refuses to run, and that is
184
- deliberate: a skeleton returning nothing and a product owning nothing read identically.
185
- 4. **Prove it, and this step is not optional.** Run `uv run .constitution/method/scripts/inventory.py`,
186
- then open at least one file each reader claims to have read and confirm the rows match what is
187
- actually written there. A regex that returns plausible rows from the wrong place is the failure
188
- mode this intent invites, and running the engine is the only thing that catches it.
189
- 5. Whatever a pattern cannot read goes to `unread`. You MUST NOT widen a pattern until it stops
190
- reporting; an honest `unread` is worth more than a row nobody checked.
191
- 6. Report what each reader reads, in one line per kind, and what it deliberately does not.
192
-
193
- A kind this product genuinely does not have returns `Derived()` — a real answer. You MUST NOT return
194
- it to make the output quiet.
195
-
196
- The rows themselves are **not** yours to land. This intent produces the reader; `wdi-blueprint` intent
197
- `platform` owns the three inventories, and a plan-versus-code gap is its finding to route.
198
-
199
- ## Rendered Files Hygiene & Gitignore (Optional)
200
-
201
- The `.what-rendered/` and `.how-rendered/` directories contain generated human-facing presentations
202
- derived from canonical files in `.what/` and `.how/`. The method validator deliberately excludes them
203
- from `COMMITTED_DIRS`, allowing products to choose whether to commit them.
204
-
205
- If the maintainer prefers to keep the git tree clean of generated presentation files:
206
- 1. Untrack them from git: `git rm -r --cached .what-rendered/ .how-rendered/`
207
- 2. Add both folders to `.gitignore`:
208
- ```gitignore
209
- .what-rendered/
210
- .how-rendered/
211
- ```
212
- 3. Whenever a human-readable rendered view is needed, regenerate on demand:
213
- `uv run .constitution/method/scripts/validate.py --generate`
214
-
215
- ## Rules
216
-
217
- - You MUST NOT write `.what/` or `.how/` content beyond a skeleton and its frontmatter. Behaviour is
218
- `wdi-blueprint` and `wdi-component`; mechanism is `wdi-component`.
219
- - You MUST NOT write into `.constitution/method/`. Intent `readers` writes exactly one file in
220
- `.constitution/project/`, and nothing else there.
221
- - You MUST NOT fill `mode` or `risk_accepted` with a value the owner has not confirmed. Both are the
222
- owner's, and a proposal recorded as a decision is the one failure disclosure cannot survive.
223
- - You MUST NOT create a Product Component because a folder would look tidy. A PC no `FR` points at is a
224
- folder with nothing inside it.
225
- - You MUST NOT put database column types in `03-domain/`. That slot holds the conceptual domain model.
226
-
227
- ## Output
228
-
229
- Intent taken · what was scaffolded, proposed, or refreshed · for `component`, the slicing with the `FR`
230
- behind each row and what the owner accepted · for `mode` and `risk`, what was disclosed before the
231
- proposal · for `structure`, the drift found and what was left unfixed.
1
+ ---
2
+ name: wdi-init
3
+ description: Use for anything that must exist before work can start or continue — scaffolding the registries at install, birthing Product Components after G2, setting or changing a component's mode, setting or reviewing its risk_accepted, refreshing the two structure maps, repairing the engines after an install or update, and writing this product's inventory readers. Seven intents. Never writes .what/ or .how/ content beyond a skeleton.
4
+ ---
5
+
6
+ # WDI Init
7
+
8
+ Seven intents, one skill, because all seven answer the same question: **what has to exist before the
9
+ next piece of work makes sense?** A registry row, a folder pair, a depth setting, a risk note, a map
10
+ of where things are, a reader that can see this product's code.
11
+
12
+ | Intent | Does | Precondition | How often |
13
+ |---|---|---|---|
14
+ | `setup` | Guide the global `mode` setting · scaffold the registries that are still empty · **report** the documents already present, read-only · derive the two structure maps · align the engines | before G1 | once per project |
15
+ | `engines` | Run `npx wdi-method engines --fix`, then report what it changed: the flag stripped from `to-spec` · `to-tickets` · `implement` so `wdi-build` can invoke them, the retired BMad G5 wrappers locked out of model invocation and denied in `.claude/settings.json`, and `docs/agents/` repaired where it still carried upstream's answer | after every `wdi-method install` or `update` | each version jump, and any time `engines-invocable` is red |
16
+ | `component` | Propose the slicing from the brief plus every PRD · birth what is accepted: registry row plus `SRS`/`SDD` skeletons · propose `mode`, `risk_accepted`, `risk_note`, `owns` | **G2 passed** | each time a component is born |
17
+ | `mode` | Change `mode` — global in `index.yaml`, or one component in `components.yaml`. Guided | — | any time |
18
+ | `risk` | Set or review one component's `risk_accepted`, with disclosure of what it touches | the component exists | any time, usually before G4 |
19
+ | `structure` | Re-derive `.control/structure-codebase.md` and `structure-document.md` from the tree on disk | — | when folders change, and at spec close |
20
+ | `readers` | Write `.constitution/project/inventory-readers.py` for **this** repo's stack, then prove it by running the engine | code exists | once, and again when the code's shape moves |
21
+
22
+ ## Two boundaries
23
+
24
+ - It **does not sort, move, or delete** an existing document. Intent `setup` reports what is there and
25
+ stops. A file that predates the method enters the corpus only through the skill owning its slot —
26
+ `corpus-guide.md` owns that rule.
27
+ - Retiring or renaming a Product Component that already carries an SRS **is not its authority**. That
28
+ goes through `wdi-decision`. Birthing is cheap; retiring is not.
29
+
30
+ ## Intent `engines`
31
+
32
+ One command does the work — `npx wdi-method engines --fix` — and this intent exists because the work is
33
+ not the installer's to do unasked. Two of the three things it touches are files somebody else owns:
34
+ `docs/agents/*.md` is the product's, and the engines' `SKILL.md` files are the author's. `install` and
35
+ `update` do the two mechanical halves (the flag, the BMad lock) on every run; the config repair happens
36
+ only here, knowingly, and the previous text is kept as `.bak`.
37
+
38
+ Report, always, in this order: which engines are present and which are missing (all six are required —
39
+ `to-spec` · `to-tickets` · `implement` · `tdd` · `code-review` · `domain-modeling`), which had the flag
40
+ stripped, how many BMad wrappers were locked, and whether `docs/agents/issue-tracker.md` was upstream's
41
+ or already the method's. If any engine is missing, say so and stop: `npx skills@latest add
42
+ mattpocock/skills` is the owner's to run, and a user-level plugin does not count — its files cannot be
43
+ unlocked.
44
+
45
+ Then run `validate.py`. `engines-invocable` green is the proof, not the report.
46
+
47
+ ## Intent `setup`
48
+
49
+ 1. Read the tree. Report every document already present, by path, with one line on what it looks like.
50
+ **Read-only.** You MUST NOT move one.
51
+ 2. Scaffold the registry files that carry no rows yet. A file that already has rows MUST NOT be
52
+ rewritten.
53
+ 3. Put the global `mode` to the owner. The default is `catalog`; the four values and what each buys are
54
+ in `delivery-flow-guide.md`, and MUST NOT be restated here.
55
+ 4. Run intent `structure`.
56
+
57
+ ## Intent `component`
58
+
59
+ 1. Read the brief and **every** PRD. A slicing proposed from one PRD is a slicing of one PRD.
60
+ 2. Propose the list. The naming rule and the presentation rule live in `corpus-guide.md` — a name that
61
+ states a layer, a service, or a pattern MUST be rejected at proposal time, and additions, changes,
62
+ and removals MUST be presented separately with the `FR` behind each.
63
+ 3. The owner decides. You MUST NOT register a component the owner has not accepted.
64
+ 4. For each accepted birth, write in one act:
65
+ - the `product_components` row in `.control/registry/components.yaml`, carrying `owns:`
66
+ - `.what/<pc>/SRS-<pc>.md` from `templates/srs.md`
67
+ - `.how/<pc>/SDD-<pc>.md` from `templates/sdd.md`
68
+ - the empty slots each kernel's guide names
69
+ 5. Run the disclosure below, then propose `mode` and `risk_accepted` per component.
70
+
71
+ Content SHOULD stay in the kernel until it grows past roughly 400 lines — a suggestion, not a threshold.
72
+ The first slot to be split out SHOULD be `04-usecases/`; it is always the largest.
73
+
74
+ **Logical Components are not born here.** An `LC` is born by the skill that draws it — `wdi-component`
75
+ intent `design`, or `wdi-ux` for a screen — and `components.yaml` states the entry shape and the `type`
76
+ → prose-home mapping in its own header. You MAY report an `LC` that looks wrong; you MUST NOT create
77
+ one.
78
+
79
+ **Neither is `platform_owns`.** An entity that no component's promise explains belongs to `_platform`,
80
+ and `wdi-blueprint` intent `platform` registers it. You MUST name the candidate and the reason, and you
81
+ MUST NOT claim it — and before naming one, you MUST apply the test in `corpus-guide.md`: ask which `FR`
82
+ would have to be withdrawn for the entity to stop being needed. If that `FR` exists, the entity belongs
83
+ to its component, however platform-shaped the table looks.
84
+
85
+ ## Intents `mode` and `risk` — disclose, then propose
86
+
87
+ `mode` controls **document depth** and nothing else. `risk_accepted` controls **review intensity** and
88
+ nothing else. Their definitions live in `delivery-flow-guide.md`, and what the two chosen together cost is
89
+ laid out cell by cell in `.constitution/method/why/mode-risk-map.md` — show it when the owner asks what a
90
+ combination buys. What this skill owns is the conversation around changing them.
91
+
92
+ **You do not judge. You disclose, then propose.** Read the `FR` that fall to the component, then name
93
+ what it touches:
94
+
95
+ - money moving
96
+ - personal data
97
+ - an irreversible action
98
+ - a contractual promise to an outside party
99
+ - a third-party integration that cannot be rolled back
100
+
101
+ Only after that do you propose `mode` and `risk_accepted`.
102
+
103
+ **Land whatever UX is waiting, in this same act.** A UX run at G2 leaves `EXPERIENCE.md` and `DESIGN.md`
104
+ in `_bmad-output/ux/` because their paths contain `<pc>` and there was no `<pc>` yet. Birthing the
105
+ components is the moment that ends. Landing goes through `wdi-ux` — it owns those two paths and no other
106
+ skill MAY write them — but it is dispatched from here rather than left for the owner to remember. It is
107
+ the only deferral left in the flow, and this is where it closes.
108
+
109
+ **Containers MAY be registered here when they are genuinely already known** — an app, an API, a database
110
+ the product plainly has. Then a screen `LC` gets its container the moment it is born and there is no debt
111
+ at all. They MUST NOT be guessed to achieve that: `wdi-blueprint` intent `platform` owns the real answer
112
+ at G3, and a container invented here is data C4 then has to unpick. Where you are unsure, leave them and
113
+ let G3 fill both the containers and the empty `LC` rows in one act.
114
+
115
+ Raising or lowering `mode` is **free and needs no justification** — it is a preference, and a preference
116
+ does not have to be defended. Setting `mode: catalog` on a sensitive component requires nothing, as long
117
+ as its review stays hard; that combination is the one the split exists to make sayable.
118
+
119
+ Two things are not free:
120
+
121
+ - **`risk_accepted: high` on a component that touches any of the five** requires a named acceptance in
122
+ `risk_accepted_by` — **a person and a date is enough**, written here in `components.yaml` beside the
123
+ risk itself rather than as a separate file. A `DEC-` id is still accepted and still has to resolve.
124
+ `high-risk-named` checks this. On a component that touches none of them, `high` is free.
125
+ - **An outside party who will demand the artifacts as a deliverable** — a regulator, an auditor, a
126
+ client through a contract — puts the touched component at `mode: deep` and `risk_accepted: low`,
127
+ whatever the global setting says. That floor MUST NOT be traded against a preference: the risk there
128
+ is not the owner's alone to accept.
129
+
130
+ > The control is not a veto, it is disclosure. The owner MAY choose fast anywhere, but never without
131
+ > knowing what is being staked.
132
+
133
+ **Lowering `mode` does not delete anything.** A file already written stops being required, and that is
134
+ all. Deleting it throws away knowledge already paid for, and a lowered `mode` is a preference — not a
135
+ statement that the content was wrong.
136
+
137
+ **Raising `mode` on a component whose code already runs** produces an **as-built record**, not a design.
138
+ `wdi-component` writes it, under the evidence labels `sdd-guide.md` owns.
139
+
140
+ ## Intent `structure`
141
+
142
+ The rules for what belongs in a map live in `.constitution/method/structure-guide.md`. This intent applies
143
+ them; it MUST NOT restate them.
144
+
145
+ 1. **Derive from the tree on disk**, honouring `.gitignore`. A map assembled from what the caller says
146
+ is there is the failure this intent exists to prevent.
147
+ 2. Classify each base folder. For the codebase map the only test is deployability — a **container** runs
148
+ its own code or stores its own data, a **library** is imported by something else, anything else stays
149
+ a line in the top-level tree or in a non-unit section. Size and importance MUST NOT decide it.
150
+ Container headings MUST be **exactly the `built: true` containers** in `components.yaml`: every
151
+ heading is a registered container, and a `built: false` one MUST NOT get a heading because no code of
152
+ ours lives in it. The match is one-directional, and reading it both ways makes it unsatisfiable.
153
+ 3. Draw the convention, not the contents. A shape that repeats MUST be written once with a placeholder.
154
+ 4. Mark key files `★` by the four tests in the guide. Borderline files are left out.
155
+ 5. Write from `templates/structure-codebase.md` and `templates/structure-document.md`. Template comments
156
+ and the skeleton block MUST be deleted from the finished file.
157
+ 6. Stamp `Verified` with the date and the commit SHA the tree was read at.
158
+ 7. Report drift, unclaimed folders, and one-sided Product Components separately. This intent MUST NOT
159
+ fix them.
160
+
161
+ It MAY be run **read-only** — derive, report the drift, write nothing. That is the right mode when the
162
+ caller is unsure: a map is cheap to check and expensive to get wrong.
163
+
164
+ A hand-edited map MUST be treated as drift: re-derive, then say what the hand edit claimed that the tree
165
+ does not support.
166
+
167
+ ## Intent `readers`
168
+
169
+ `inventory.py` is two halves. Comparing what was derived against the plan, reporting the gap, keeping
170
+ the numbers stable — that is the same in every stack and belongs to the method. **Reading the code is
171
+ not**, so the package ships a skeleton and no example: an example is a guess about somebody else's
172
+ stack, and the whole point of deriving rather than assembling is that nothing is guessed.
173
+
174
+ The file is `.constitution/project/inventory-readers.py`. All of it is the product's — `update` never
175
+ writes over it and `promote` never publishes it — so there is no protected region inside it and
176
+ nothing to merge.
177
+
178
+ 1. **Read the repo before writing a line.** Where does the schema live, how are routes registered,
179
+ how are screens declared. A stack you have not confirmed on disk MUST NOT be assumed from a
180
+ filename or a dependency list.
181
+ 2. Fill `derive_db`, `derive_api`, and `derive_screen`. The contract, the injected names, and the
182
+ column order per kind are in the skeleton's own docstring and MUST NOT be restated here.
183
+ 3. **Delete the `SKELETON = True` line.** While it stands the engine refuses to run, and that is
184
+ deliberate: a skeleton returning nothing and a product owning nothing read identically.
185
+ 4. **Prove it, and this step is not optional.** Run `uv run .constitution/method/scripts/inventory.py`,
186
+ then open at least one file each reader claims to have read and confirm the rows match what is
187
+ actually written there. A regex that returns plausible rows from the wrong place is the failure
188
+ mode this intent invites, and running the engine is the only thing that catches it.
189
+ 5. Whatever a pattern cannot read goes to `unread`. You MUST NOT widen a pattern until it stops
190
+ reporting; an honest `unread` is worth more than a row nobody checked.
191
+ 6. Report what each reader reads, in one line per kind, and what it deliberately does not.
192
+
193
+ A kind this product genuinely does not have returns `Derived()` — a real answer. You MUST NOT return
194
+ it to make the output quiet.
195
+
196
+ The rows themselves are **not** yours to land. This intent produces the reader; `wdi-blueprint` intent
197
+ `platform` owns the three inventories, and a plan-versus-code gap is its finding to route.
198
+
199
+ ## Rendered Files Hygiene & Gitignore (Optional)
200
+
201
+ The `.what-rendered/` and `.how-rendered/` directories contain generated human-facing presentations
202
+ derived from canonical files in `.what/` and `.how/`. The method validator deliberately excludes them
203
+ from `COMMITTED_DIRS`, allowing products to choose whether to commit them.
204
+
205
+ If the maintainer prefers to keep the git tree clean of generated presentation files:
206
+ 1. Untrack them from git: `git rm -r --cached .what-rendered/ .how-rendered/`
207
+ 2. Add both folders to `.gitignore`:
208
+ ```gitignore
209
+ .what-rendered/
210
+ .how-rendered/
211
+ ```
212
+ 3. Whenever a human-readable rendered view is needed, regenerate on demand:
213
+ `uv run .constitution/method/scripts/validate.py --generate`
214
+
215
+ ## Rules
216
+
217
+ - You MUST NOT write `.what/` or `.how/` content beyond a skeleton and its frontmatter. Behaviour is
218
+ `wdi-blueprint` and `wdi-component`; mechanism is `wdi-component`.
219
+ - You MUST NOT write into `.constitution/method/`. Intent `readers` writes exactly one file in
220
+ `.constitution/project/`, and nothing else there.
221
+ - You MUST NOT fill `mode` or `risk_accepted` with a value the owner has not confirmed. Both are the
222
+ owner's, and a proposal recorded as a decision is the one failure disclosure cannot survive.
223
+ - You MUST NOT create a Product Component because a folder would look tidy. A PC no `FR` points at is a
224
+ folder with nothing inside it.
225
+ - You MUST NOT put database column types in `03-domain/`. That slot holds the conceptual domain model.
226
+
227
+ ## Output
228
+
229
+ Intent taken · what was scaffolded, proposed, or refreshed · for `component`, the slicing with the `FR`
230
+ behind each row and what the owner accepted · for `mode` and `risk`, what was disclosed before the
231
+ proposal · for `structure`, the drift found and what was left unfixed.
@@ -30,7 +30,7 @@ strictly preserving requirement traceability and RTM metadata in `.control/regis
30
30
 
31
31
  ### A. Interactive Mode (invoked bare: `/wdi-prune-or-archive`)
32
32
 
33
- 1. Find closed candidate specs: inspect `.scratch/` directly or run `python .constitution/method/scripts/lifecycle.py --dry-run`
33
+ 1. Find closed candidate specs: inspect `.scratch/` directly or run `uv run .constitution/method/scripts/lifecycle.py --dry-run`
34
34
  (or grep `specs.yaml` for `status:\s*closed` — MUST NOT dump the entire historical `specs.yaml` into context).
35
35
  2. Find all specs with `status: closed` whose directory currently resides under `.scratch/`:
36
36
  - If no closed specs reside in `.scratch/`: report that `.scratch/` is already clean of closed specs
@@ -135,7 +135,7 @@ derived from the other: one component MAY be thin on purpose and reviewed the ha
135
135
  `.constitution/method/document/delivery-flow-guide.md` owns both;
136
136
  `.constitution/method/why/rationale.md` says why they are separate.
137
137
 
138
- ## The five gates and the eighteen skills
138
+ ## The five gates and the twenty-two skills
139
139
 
140
140
  | Gate | Decides | Skill |
141
141
  |---|---|---|
@@ -145,15 +145,18 @@ derived from the other: one component MAY be thin on purpose and reviewed the ha
145
145
  | **G4 Component** | How one component is built — **skipped at `catalog`** | `wdi-component` |
146
146
  | **G5 Release** | Whether it is done and proven | `wdi-build` |
147
147
 
148
- Before G1 and at the tail of G2: `wdi-init`, five intents — `setup` · `component` · `mode` · `risk` ·
149
- `structure`.
148
+ Before G1 and at the tail of G2: `wdi-init`, seven intents — `setup` · `engines` · `component` · `mode` ·
149
+ `risk` · `structure` · `readers`.
150
150
 
151
151
  Any time: `wdi-decision` · `wdi-question` · `wdi-log` · `wdi-help` · `wdi-explain-to-me` · `wdi-reconcile` · `wdi-review` ·
152
- `wdi-report` · `wdi-systematic-debugging`.
152
+ `wdi-report` · `wdi-systematic-debugging` · `wdi-upgrade` (right after `wdi-method update`).
153
153
 
154
154
  When the owner asks for it: `wdi-autopilot` — one mandate the owner accepts, then every skill above runs
155
155
  unattended and every decision lands in one ledger. It is never the default next step.
156
156
 
157
+ The daily tier, started only when the owner types it: `wdi-daily-what-to-build` · `wdi-daily-autopilot` ·
158
+ `wdi-daily-what-to-test` · `wdi-prune-or-archive`. That is eighteen core skills and four daily ones.
159
+
157
160
  **No BMad skill is invoked directly.** Each has a wrapper, and the wrapper is what checks position,
158
161
  verifies the result, and lands the memlog.
159
162
 
@@ -29,7 +29,7 @@ Never a rule. When it disagrees with a guide, the guide wins and the disagreemen
29
29
 
30
30
  | File | Opened when |
31
31
  |---|---|
32
- | [`why/README.md`](why/README.md) | You want the whole shape in five minutes — five gates, two settings, eighteen skills, WDI ↔ BMad |
32
+ | [`why/README.md`](why/README.md) | You want the whole shape in five minutes — five gates, two settings, twenty-two skills (eighteen core, four daily tier), WDI ↔ BMad |
33
33
  | [`why/artifact-map.md`](why/artifact-map.md) | "Where does this file go", or "does this document exist at my `mode`" |
34
34
  | [`why/mode-risk-map.md`](why/mode-risk-map.md) | A `mode` and a `risk_accepted` are set and you want the two side by side — all twelve cells |
35
35
  | [`why/rationale.md`](why/rationale.md) | Before changing a rule, to know what you would break |
@@ -28,7 +28,7 @@ them only an *example* does — not a rule.
28
28
  | `templates/design-system.md` | The pointer to wherever this project keeps its tokens | Re-point at that project's token file |
29
29
  | `templates/oq.md` | One example of a bad question title | Cosmetic |
30
30
 
31
- Everything else — the five gates, the two fields, the eighteen skills, the templates, `validate.py`,
31
+ Everything else — the five gates, the two fields, the twenty-two skills, the templates, `validate.py`,
32
32
  `inventory.py`, `../method-glossary.md`, and the three files beside this one — carries without edit.
33
33
 
34
34
  One half-exception, and it is by design: `inventory.py` is the generic engine and carries whole, but
package/package.json CHANGED
@@ -1,7 +1,24 @@
1
1
  {
2
2
  "name": "wdi-method",
3
- "version": "0.6.27",
4
- "description": "WDI Method — software delivery method that wraps BMad",
3
+ "version": "0.6.28",
4
+ "description": "The review layer for AI coding agents: human review gates that check technical decisions before Claude Code, Cursor, or Codex write the code. Wraps BMad.",
5
+ "keywords": [
6
+ "bmad",
7
+ "bmad-method",
8
+ "ai-coding",
9
+ "coding-agents",
10
+ "claude-code",
11
+ "cursor",
12
+ "codex",
13
+ "spec-driven-development",
14
+ "software-delivery",
15
+ "code-review",
16
+ "ai-governance",
17
+ "agentic-workflow",
18
+ "c4-model",
19
+ "use-case",
20
+ "documentation"
21
+ ],
5
22
  "type": "module",
6
23
  "bin": {
7
24
  "wdi-method": "bin/wdi-method.js"
@@ -14,8 +31,14 @@
14
31
  "scaffold/",
15
32
  "README.md",
16
33
  "README.id.md",
34
+ "README.zh-CN.md",
17
35
  "README.ja.md",
18
- "README.zh.md",
36
+ "README.ko.md",
37
+ "README.es.md",
38
+ "README.de.md",
39
+ "README.fr.md",
40
+ "README.pt-BR.md",
41
+ "README.ru.md",
19
42
  "CHANGELOG.md",
20
43
  "LICENSE",
21
44
  "NOTICE",