wdi-method 0.6.7 → 0.6.8
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/README.md +33 -5
- package/bin/wdi-method.js +389 -26
- package/kit/.constitution/method/constitution.md +4 -1
- package/kit/.constitution/method/document/bmad-guide.md +10 -6
- package/kit/.constitution/method/document/bmad-skill-register.md +36 -6
- package/kit/.constitution/method/scripts/validate.py +74 -3
- package/kit/.constitution/method/why/README.md +192 -186
- package/kit/.constitution/method/why/artifact-map.md +1 -1
- package/kit/skills/wdi-autopilot/SKILL.md +383 -375
- package/kit/skills/wdi-blueprint/SKILL.md +3 -3
- package/kit/skills/wdi-build/SKILL.md +393 -371
- package/kit/skills/wdi-help/SKILL.md +111 -110
- package/kit/skills/wdi-init/SKILL.md +19 -1
- package/kit/skills/wdi-upgrade/SKILL.md +194 -187
- package/kit-overlay/constitution.md +4 -1
- package/package.json +1 -1
- package/scaffold/docs/agents/issue-tracker.md +56 -43
|
@@ -1,187 +1,194 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: wdi-upgrade
|
|
3
|
-
description: Use right after `wdi-method update` moved this repo to a newer method version. Finds every document and registry file still in the OLD shape, re-homes their content into the new one — registry rows out of prose, pointers where copies were, the rendered trees born — and verifies green. Runs once per version jump; safe to re-run.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# WDI Upgrade
|
|
7
|
-
|
|
8
|
-
`wdi-method update` does the mechanical half of a version jump: it overwrites the kit, renames files whose
|
|
9
|
-
content needs no judgment, seeds what is new, prunes what is retired. It stops exactly where a decision
|
|
10
|
-
about **content** begins — which PRD an `FR` belongs to, whether a sentence in the old brief was an
|
|
11
|
-
assumption or a constraint. Those are this skill's half.
|
|
12
|
-
|
|
13
|
-
**This skill's content is `.what/` and `.how/`** — the corpus a human reads. It does NOT cover
|
|
14
|
-
`.control/memlog/` or a registry row: an autopilot ledger's filename is `update`'s own mechanical rename
|
|
15
|
-
(the same way `waves.yaml` became `specs.yaml`), a stale mandate setting is a printed warning at `update`
|
|
16
|
-
time because overwriting it would be overwriting a value the owner already chose, and a ledger's internal
|
|
17
|
-
shape is healed by `wdi-autopilot` itself on its next run, because only it can read git and the registry to
|
|
18
|
-
know where that run actually stands. Route those three there; this skill's report would have nothing to say
|
|
19
|
-
about any of them.
|
|
20
|
-
|
|
21
|
-
**This is the one skill allowed to edit `brief.md`, `prd.md`, an SRS, an SDD, or a C4 file directly.**
|
|
22
|
-
Every other skill is forbidden, because a hand edit makes the memlog lie about how the document was
|
|
23
|
-
produced. An upgrade produces nothing: it moves sentences that already exist into the home the new
|
|
24
|
-
version gives them, word for word. The memlog stays true, and this skill's report is the record.
|
|
25
|
-
|
|
26
|
-
## Inputs
|
|
27
|
-
|
|
28
|
-
| Source | What it answers |
|
|
29
|
-
|---|---|
|
|
30
|
-
| `.control/wdi-method.yaml` | The version now installed — the shape everything below MUST end in |
|
|
31
|
-
| The `update` run's own output | The `upgrade` line lists what it detected as pending; start there |
|
|
32
|
-
| `.control/registry/` | What is already a row, so nothing is landed twice |
|
|
33
|
-
| `.what/_product-brief/brief.md` · `.what/_prd/*/prd.md` | The two documents whose shape changed most |
|
|
34
|
-
| `.what/<pc>/SRS-<pc>.md` · `.how/<pc>/SDD-<pc>.md` · `.how/_platform/c4-l2-containers.md` | The three that used to carry a copy of a registry table |
|
|
35
|
-
| `.constitution/method/document/templates/` | The target shape of every document above |
|
|
36
|
-
|
|
37
|
-
## Step 1 — Detect, and show the list before touching anything
|
|
38
|
-
|
|
39
|
-
Probe each item below; a probe is a file or heading that exists only in the old shape. List every hit
|
|
40
|
-
to the owner as a checklist, in the order below — it is a dependency order, and doing a later item
|
|
41
|
-
before an earlier one lands content in a file that the earlier item is about to change.
|
|
42
|
-
|
|
43
|
-
| # | Probe | Old shape | New home |
|
|
44
|
-
|---|---|---|---|
|
|
45
|
-
| 1 | `.control/registry/requirements.yaml` exists | one file for `BG` · `CAP` · `FR` · `NFR` · `UJ` | `goals.yaml` (`BG`) · `requirements-<slug>.yaml` per PRD (`CAP` · `FR` · `NFR` · `UJ`) |
|
|
46
|
-
| 2 | `specs.yaml` has `W<n>` ids, or `epics:` / `stories:` keys | pre-rename plan | re-cut through `wdi-build` — **not this skill**; report it and move on |
|
|
47
|
-
| 3 | `brief.md` has `## Executive Summary`, `## Vision`, `## Assumptions`, or `## Prerequisites`; or `## Goals` lists `BG-` statements | 14-section brief | 8 sections: `Why` merges Summary + Vision; Goals is a pointer, its rows in `goals.yaml`; Assumptions → `questions/assumptions.md`; Prerequisites → `questions/external.md` |
|
|
48
|
-
| 4 | any `prd.md` has a section **named** Document Purpose, Glossary, Non-Goals, Open Questions, or Assumptions Index — under whatever number that kit gave it — or `**Proof of done:**` under a feature | 12-section PRD with `FR` blocks | 7 sections; `FR`/`NFR` text → `requirements-<slug>.yaml`, the PRD keeps `Realizes:` ids; Glossary → `product-glossary.md`; §8/§9 → `questions/`; §1 becomes a delta |
|
|
49
|
-
| 5 | any `SRS-<pc>.md` `## UC Catalogue` has `\| UC-` rows | catalogue copied from `usecases.yaml` | one pointer line; the rows live in `usecases.yaml` |
|
|
50
|
-
| 6 | any `SDD-<pc>.md` `## Inherited Constraints` has a `Quoted rule` column, or `> ` blockquote lines under an `**AD-N — …**` heading, or the sentence `Quoted verbatim from` | `AD-N` text copied from the spine, in either of the two shapes SDDs were written in | ids only; the rendered SDD shows the text |
|
|
51
|
-
| 7 | `c4-l2-containers.md` has a `\| Container \| Product Components living in it \|` table | matrix copied from `components.yaml` | one pointer line |
|
|
52
|
-
| 8 | `.control/generated/brief.md`, `blueprint.md`, or `prd-*.md` exist | human pages in the machine folder | `.what-rendered/` · `.how-rendered/` — `render` clears the old ones |
|
|
53
|
-
| 9 | `.what-rendered/` or `.how-rendered/` absent | no reader's tree yet | born by `render` |
|
|
54
|
-
| 10 | any `.md` outside `.constitution/` cites `.control/generated/brief.md`, `blueprint.md`, or `prd-<slug>.md` | a pointer at a page that moved | `.what-rendered/_product-brief/brief.md` · `.how-rendered/blueprint.md` · `.what-rendered/_prd/<slug>/prd.md` — `cites-resolve` fails until it is repointed |
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
its
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
`
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
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
|
-
- You MUST NOT
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
1
|
+
---
|
|
2
|
+
name: wdi-upgrade
|
|
3
|
+
description: Use right after `wdi-method update` moved this repo to a newer method version. Finds every document and registry file still in the OLD shape, re-homes their content into the new one — registry rows out of prose, pointers where copies were, the rendered trees born — and verifies green. Runs once per version jump; safe to re-run.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# WDI Upgrade
|
|
7
|
+
|
|
8
|
+
`wdi-method update` does the mechanical half of a version jump: it overwrites the kit, renames files whose
|
|
9
|
+
content needs no judgment, seeds what is new, prunes what is retired. It stops exactly where a decision
|
|
10
|
+
about **content** begins — which PRD an `FR` belongs to, whether a sentence in the old brief was an
|
|
11
|
+
assumption or a constraint. Those are this skill's half.
|
|
12
|
+
|
|
13
|
+
**This skill's content is `.what/` and `.how/`** — the corpus a human reads. It does NOT cover
|
|
14
|
+
`.control/memlog/` or a registry row: an autopilot ledger's filename is `update`'s own mechanical rename
|
|
15
|
+
(the same way `waves.yaml` became `specs.yaml`), a stale mandate setting is a printed warning at `update`
|
|
16
|
+
time because overwriting it would be overwriting a value the owner already chose, and a ledger's internal
|
|
17
|
+
shape is healed by `wdi-autopilot` itself on its next run, because only it can read git and the registry to
|
|
18
|
+
know where that run actually stands. Route those three there; this skill's report would have nothing to say
|
|
19
|
+
about any of them.
|
|
20
|
+
|
|
21
|
+
**This is the one skill allowed to edit `brief.md`, `prd.md`, an SRS, an SDD, or a C4 file directly.**
|
|
22
|
+
Every other skill is forbidden, because a hand edit makes the memlog lie about how the document was
|
|
23
|
+
produced. An upgrade produces nothing: it moves sentences that already exist into the home the new
|
|
24
|
+
version gives them, word for word. The memlog stays true, and this skill's report is the record.
|
|
25
|
+
|
|
26
|
+
## Inputs
|
|
27
|
+
|
|
28
|
+
| Source | What it answers |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `.control/wdi-method.yaml` | The version now installed — the shape everything below MUST end in |
|
|
31
|
+
| The `update` run's own output | The `upgrade` line lists what it detected as pending; start there |
|
|
32
|
+
| `.control/registry/` | What is already a row, so nothing is landed twice |
|
|
33
|
+
| `.what/_product-brief/brief.md` · `.what/_prd/*/prd.md` | The two documents whose shape changed most |
|
|
34
|
+
| `.what/<pc>/SRS-<pc>.md` · `.how/<pc>/SDD-<pc>.md` · `.how/_platform/c4-l2-containers.md` | The three that used to carry a copy of a registry table |
|
|
35
|
+
| `.constitution/method/document/templates/` | The target shape of every document above |
|
|
36
|
+
|
|
37
|
+
## Step 1 — Detect, and show the list before touching anything
|
|
38
|
+
|
|
39
|
+
Probe each item below; a probe is a file or heading that exists only in the old shape. List every hit
|
|
40
|
+
to the owner as a checklist, in the order below — it is a dependency order, and doing a later item
|
|
41
|
+
before an earlier one lands content in a file that the earlier item is about to change.
|
|
42
|
+
|
|
43
|
+
| # | Probe | Old shape | New home |
|
|
44
|
+
|---|---|---|---|
|
|
45
|
+
| 1 | `.control/registry/requirements.yaml` exists | one file for `BG` · `CAP` · `FR` · `NFR` · `UJ` | `goals.yaml` (`BG`) · `requirements-<slug>.yaml` per PRD (`CAP` · `FR` · `NFR` · `UJ`) |
|
|
46
|
+
| 2 | `specs.yaml` has `W<n>` ids, or `epics:` / `stories:` keys | pre-rename plan | re-cut through `wdi-build` — **not this skill**; report it and move on |
|
|
47
|
+
| 3 | `brief.md` has `## Executive Summary`, `## Vision`, `## Assumptions`, or `## Prerequisites`; or `## Goals` lists `BG-` statements | 14-section brief | 8 sections: `Why` merges Summary + Vision; Goals is a pointer, its rows in `goals.yaml`; Assumptions → `questions/assumptions.md`; Prerequisites → `questions/external.md` |
|
|
48
|
+
| 4 | any `prd.md` has a section **named** Document Purpose, Glossary, Non-Goals, Open Questions, or Assumptions Index — under whatever number that kit gave it — or `**Proof of done:**` under a feature | 12-section PRD with `FR` blocks | 7 sections; `FR`/`NFR` text → `requirements-<slug>.yaml`, the PRD keeps `Realizes:` ids; Glossary → `product-glossary.md`; §8/§9 → `questions/`; §1 becomes a delta |
|
|
49
|
+
| 5 | any `SRS-<pc>.md` `## UC Catalogue` has `\| UC-` rows | catalogue copied from `usecases.yaml` | one pointer line; the rows live in `usecases.yaml` |
|
|
50
|
+
| 6 | any `SDD-<pc>.md` `## Inherited Constraints` has a `Quoted rule` column, or `> ` blockquote lines under an `**AD-N — …**` heading, or the sentence `Quoted verbatim from` | `AD-N` text copied from the spine, in either of the two shapes SDDs were written in | ids only; the rendered SDD shows the text |
|
|
51
|
+
| 7 | `c4-l2-containers.md` has a `\| Container \| Product Components living in it \|` table | matrix copied from `components.yaml` | one pointer line |
|
|
52
|
+
| 8 | `.control/generated/brief.md`, `blueprint.md`, or `prd-*.md` exist | human pages in the machine folder | `.what-rendered/` · `.how-rendered/` — `render` clears the old ones |
|
|
53
|
+
| 9 | `.what-rendered/` or `.how-rendered/` absent | no reader's tree yet | born by `render` |
|
|
54
|
+
| 10 | any `.md` outside `.constitution/` cites `.control/generated/brief.md`, `blueprint.md`, or `prd-<slug>.md` | a pointer at a page that moved | `.what-rendered/_product-brief/brief.md` · `.how-rendered/blueprint.md` · `.what-rendered/_prd/<slug>/prd.md` — `cites-resolve` fails until it is repointed |
|
|
55
|
+
| 11 | `docs/agents/issue-tracker.md` does not contain the words `seeded by ``wdi-method``` | the engines' config as `/setup-matt-pocock-skills` wrote it: everything in `.scratch/` with no registry behind it, `specs.yaml` never mentioned | the method's own answer. **`npx wdi-method engines --fix`** rewrites it and keeps the old text as `issue-tracker.md.bak`. Two of four live repos still had upstream's, which is why their tickets landed wherever the engine guessed |
|
|
56
|
+
| 12 | any `spec_folder` in `specs.yaml` is outside `.scratch/`, or its leaf does not begin with the spec's own id | spec folders under `_bmad-output/specs/`, leaf named freely — four repos wrote it four ways, one of them all four inside itself | `.scratch/<spec-id>-<slug>/`. Move the directory, rewrite the `spec_folder` row, then repoint every cite — `cites-resolve` is red until you do, and it is how you find them all |
|
|
57
|
+
|
|
58
|
+
Items 11 and 12 are the engines' half of a version jump, and they come FIRST when both are hit:
|
|
59
|
+
item 11 writes where a spec's files belong, item 12 moves them there. Doing 12 first means moving
|
|
60
|
+
folders to a location the engines have not been told about, and the next `to-tickets` writes to the old
|
|
61
|
+
one anyway.
|
|
62
|
+
|
|
63
|
+
Anything not in the list is not this skill's. A brief that already has `## Why` is done; skip it.
|
|
64
|
+
|
|
65
|
+
## Step 2 — Registry first
|
|
66
|
+
|
|
67
|
+
**1 — the requirement split.** A row written under an older kit carries `text:` where a newer one
|
|
68
|
+
carries `title:`; both are the short label, the renderer and `timeline.py` read either, and one MUST
|
|
69
|
+
NOT be copied into the other — that is two homes for one fact. Which PRD a row belongs to is read from
|
|
70
|
+
the rows before it is read from the prose. A `CAP` or `UJ` with a `prd:` field goes to `requirements-<that slug>.yaml`; an `FR`
|
|
71
|
+
follows its `capability:` to that CAP's file; an `NFR` follows its `component:` to the PRD whose CAPs
|
|
72
|
+
own that component — a `BG` is product-level and never decides an NFR's home on its own, so `goal:` is
|
|
73
|
+
only a tie-breaker when that component's CAPs span two PRDs. On a product with exactly **one** PRD every row belongs to that
|
|
74
|
+
PRD by construction — write them all to its file and skip the citation scan. Otherwise, only a row with
|
|
75
|
+
none of those fields falls back to the PRD whose prose cites its id — and an id cited by **two** PRDs
|
|
76
|
+
is reported, not placed. The citation scan still runs on every row as a cross-check: a row whose
|
|
77
|
+
structural home and citing PRD disagree is reported with both names. Write the row, unchanged, into
|
|
78
|
+
its file; `goals:` rows go to `goals.yaml`. A sentence moved into a YAML value keeps its punctuation
|
|
79
|
+
and its markup: when it holds `: ` or `#` or starts with a quote, wrap the value in double quotes or a
|
|
80
|
+
`>-` block — never trade a colon for a dash or strip `**` and backticks to make it a plain scalar. A row with no home is reported by id, not guessed: the
|
|
81
|
+
owner names it. When every row has moved, delete `requirements.yaml`; `id-allocated-once` fails if a
|
|
82
|
+
row was copied instead of moved.
|
|
83
|
+
|
|
84
|
+
Run `validate.py --check`. Green here means the registry is whole before any document starts pointing
|
|
85
|
+
at it.
|
|
86
|
+
|
|
87
|
+
## Step 3 — Documents, oldest gate first
|
|
88
|
+
|
|
89
|
+
**3 — brief.** Merge `## Executive Summary` and `## Vision` into one `## Why`, keeping every sentence
|
|
90
|
+
that says something the other did not. Each `BG-N` statement under `## Goals` MUST already be a row in
|
|
91
|
+
`goals.yaml` (Step 2); replace the list with the pointer line from the template. Each `## Assumptions`
|
|
92
|
+
item becomes a row in `.control/questions/assumptions.md` with `Whose: owner`; each `## Prerequisites`
|
|
93
|
+
item a row in `external.md` — **after** checking that no `OQ-` row already states it, because a brief
|
|
94
|
+
written under an earlier kit usually landed them already and a second row is a copy. A prerequisite
|
|
95
|
+
the brief itself marks satisfied is dropped, not landed as open. A `questions/` table written before
|
|
96
|
+
the `Whose` column existed (`| id | Assumption | Cost if wrong | Taken | By |`) gets the column added —
|
|
97
|
+
header and separator, and an empty cell on every existing row, which the validator counts as
|
|
98
|
+
`unstated`, which is what they are. The rows this skill lands say `owner`. `Cost if wrong` is `—` when
|
|
99
|
+
the source never stated one; it is not invented. An open question the source never marked blocking is
|
|
100
|
+
filed in `assumptions.md`, as the template's three tests say. Delete both sections, and say how many
|
|
101
|
+
items were already rows. Check `## Success Criteria` names one measurable
|
|
102
|
+
figure — if it does not, that is a finding for the owner, not a sentence for this skill to invent.
|
|
103
|
+
|
|
104
|
+
**4 — each PRD.** Sections are matched **by name, never by number**: the numbers moved between kits
|
|
105
|
+
(one kit numbers Non-Goals §5 and Open Questions §8; an older one numbers Non-Goals §7, MVP Scope §8,
|
|
106
|
+
Open Questions §10), so a step that says "delete §8" deletes MVP Scope on the wrong corpus. Delete
|
|
107
|
+
`Document Purpose`. Every `Glossary` term not yet in `.control/product-glossary.md` is added there,
|
|
108
|
+
verbatim; then delete `Glossary`. Every `Non-Goals` item MUST already be in the brief's Scope Out or
|
|
109
|
+
this PRD's `MVP Scope → Out of Scope` — if neither holds it, add it to the one it belongs to; then
|
|
110
|
+
delete `Non-Goals`. Every `Open Questions` and `Assumptions Index` item becomes a `questions/` row
|
|
111
|
+
(after the same already-a-row check as the brief's); delete both.
|
|
112
|
+
Under each feature, every `FR` block is folded into its row in `requirements-<slug>.yaml` (Step 2)
|
|
113
|
+
before the block goes: the block's description paragraph — the prose between the `#### FR-N` heading
|
|
114
|
+
and the first `**…:**` label — becomes the row's `statement:` when the row has none (the row's `title`
|
|
115
|
+
stays). **This is the one move with no validator behind it**, so count it: blocks with a paragraph
|
|
116
|
+
versus rows that now carry `statement:` MUST match, and Step 5 reports both numbers. A run that deletes
|
|
117
|
+
the blocks and lands zero statements has thrown the requirement's own sentence away; its `**Consequences (testable):**` bullets move verbatim to
|
|
118
|
+
`addendum.md` under `## Technical how — testable consequences per FR`, appended **after** the sections
|
|
119
|
+
already there, one `### FR-N — title` each,
|
|
120
|
+
because `prd-guide.md` repealed the double proof of done and that is where the technical restatement
|
|
121
|
+
lives now; its `**Proof of done:**` is compared with the row's `proof` — when they differ, the
|
|
122
|
+
**registry is kept** (it is the declared SSOT), the PRD's is dropped, and both texts are reported side
|
|
123
|
+
by side for the owner, never merged. Then the block becomes `**Realizes:** FR-a, FR-b, NFR-c`, and a
|
|
124
|
+
`**Functional Requirements:**` label left with nothing under it is deleted — the rendered page rebuilds
|
|
125
|
+
the blocks from the rows. When the deletions are done, **put the surviving `##` sections in the
|
|
126
|
+
template's order and renumber them** — moving a whole section is a move, not an edit, and a file whose
|
|
127
|
+
`## 6` sits above its `## 4` tells the AI reader the numbers lie. The order — 1 Why This Initiative · 2 Target User · 3 Features · 4 MVP Scope · 5 Success
|
|
128
|
+
Metrics · 6 Cross-Cutting NFRs · 7 Constraints and Guardrails — and the `###` beneath them to match
|
|
129
|
+
(`### 8.2` → `### 4.2`). Numbers are not sentences; leaving `## 4. Features` beside `## 8. MVP Scope`
|
|
130
|
+
tells the next reader two sections went missing. A `UJ-N` the prose names that has no row in any requirement file is
|
|
131
|
+
not given one — it is marked with an HTML comment where it stands and reported; `wdi-product`
|
|
132
|
+
allocates ids. A moved sentence that cites a section number (`§ 8`) of a section this step deletes
|
|
133
|
+
keeps the number — it is reported as wording for the owner, not repointed, because its new home is a
|
|
134
|
+
judgment. `## 1. Vision` becomes `## 1. Why This Initiative`: delete only the sentences
|
|
135
|
+
that also appear, word for word, in the brief's `Why`; what remains is left whole under an HTML comment
|
|
136
|
+
saying the new shape wants a delta, because deciding which paraphrases are copies is the owner's. On a
|
|
137
|
+
single-initiative product that is one line pointing at the brief — write it and say so.
|
|
138
|
+
|
|
139
|
+
**5 — each SRS.** Every `| UC-` row MUST already be in `usecases.yaml` with the same `critical`. A row
|
|
140
|
+
missing there is landed first. Then the table becomes the template's pointer line.
|
|
141
|
+
|
|
142
|
+
**6 — each SDD.** In `## Inherited Constraints`, drop the `Quoted rule` column; keep `AD` and `How it
|
|
143
|
+
lands here`. In the blockquote shape, drop the `> ` lines and the `Quoted verbatim from` sentence; keep
|
|
144
|
+
the `**AD-N — title**` heading and the landing prose under it, each heading on its own line. An `AD-N`
|
|
145
|
+
cited here that is not in the spine is a finding.
|
|
146
|
+
|
|
147
|
+
**7 — C4 L2.** Every PC listed in the table MUST have that container in its `containers:`. Then the
|
|
148
|
+
table becomes the pointer line.
|
|
149
|
+
|
|
150
|
+
**8 — pointers at the moved pages.** Every `.md` that cites `.control/generated/brief.md`,
|
|
151
|
+
`blueprint.md`, or `prd-<slug>.md` **and that `cites-resolve` reads** is repointed to the new path — a
|
|
152
|
+
path substitution, nothing else in the sentence changes. That includes a product's own scratch and
|
|
153
|
+
issue notes. It excludes what the validator excludes: `.control/memlog/`, `.control/decisions/`,
|
|
154
|
+
`.control/reports/`, `questions/answered.md`, and `_bmad-output/` — those describe the past, and a
|
|
155
|
+
path rewritten there falsifies a record; the installer's probe skips them for the same reason.
|
|
156
|
+
|
|
157
|
+
## Step 4 — Render, then validate
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
uv run .constitution/method/scripts/validate.py --generate
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
This writes every reader's page into `.what-rendered/` and `.how-rendered/`, and clears the human pages
|
|
164
|
+
that used to sit in `.control/generated/`. Then `--check` MUST be green. Every finding at this point is
|
|
165
|
+
either a row that moved wrong in Step 2 or a pointer that points at nothing — both are this skill's to
|
|
166
|
+
fix before it reports done.
|
|
167
|
+
|
|
168
|
+
## Step 5 — Report, and commit once
|
|
169
|
+
|
|
170
|
+
What moved, file by file · what was landed into the registry, by id · what could not be placed and
|
|
171
|
+
needs the owner · the rendered pages now waiting to be read, one per gate · validators green. Then
|
|
172
|
+
**one** commit: `chore(method): upgrade <from> → <to>`. Not one per document — the upgrade is one
|
|
173
|
+
event.
|
|
174
|
+
|
|
175
|
+
## Rules
|
|
176
|
+
|
|
177
|
+
- You MUST NOT change a sentence while moving it. Wording that reads wrong in its new home is a
|
|
178
|
+
finding for the owning skill, later.
|
|
179
|
+
- You MUST NOT invent a home. An `FR` no PRD cites, a Non-Goal neither boundary holds, an `AD-N` not
|
|
180
|
+
in the spine — each is reported by id and left where it was.
|
|
181
|
+
- You MUST NOT write your findings into the corpus. A registry file carries rows and nothing about
|
|
182
|
+
the upgrade that produced them; a gap in this skill goes in the Step 5 report. The one exception is
|
|
183
|
+
the HTML comment the steps above name, placed where the owner will read the document.
|
|
184
|
+
- You MUST NOT re-cut `specs.yaml`. That is `wdi-build`'s, where a human can see it.
|
|
185
|
+
- You MUST NOT touch `.control/decisions/` or `.control/reports/`. A frozen `DEC-` that cites `V26` or
|
|
186
|
+
`W3` is history; the alias rule in `corpus-guide.md` covers it.
|
|
187
|
+
- Re-running on an upgraded repo MUST find nothing and say so. Every probe in Step 1 is idempotent.
|
|
188
|
+
|
|
189
|
+
## Output
|
|
190
|
+
|
|
191
|
+
The Step 1 checklist with each item marked done · skipped (already new shape) · left for the owner, with
|
|
192
|
+
the id list for the last · the registry rows landed · **statements landed / FR blocks that had a
|
|
193
|
+
paragraph** · consequences moved · `questions/` rows added and rows found already present · proof-of-done
|
|
194
|
+
divergences, both texts · the path of every rendered page · the validator result · the commit.
|
|
@@ -25,10 +25,13 @@ The repo layout is governed by `corpus-guide.md` and mapped by
|
|
|
25
25
|
| `.how/` | How it is built |
|
|
26
26
|
| `.what-rendered/` · `.how-rendered/` | The two above, assembled for a human to read — one page per gate, at the mirror path. Regenerated by `validate.py`, never edited, never read by a skill |
|
|
27
27
|
| `_bmad-output/` | Run workspace; MUST be in git, not curated |
|
|
28
|
+
| `.scratch/` | One directory per effort: a spec's `SPEC.md` and its ticket files, and ad hoc work that has no `FR` yet. MUST be in git — the corpus cites into it by path |
|
|
28
29
|
| `.work/` | Scratch; MUST be in git, emptied when a task closes |
|
|
29
30
|
| *(application roots)* | Application code — named and mapped in `.control/structure-codebase.md` |
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
**One exception, and it is not corpus.** `docs/agents/issue-tracker.md` and `docs/agents/domain.md` are the ENGINES' config, and their path belongs to the engines' author — `to-spec`, `to-tickets`, `implement` and `triage` read those two files and nowhere else. What they SAY is this method's, and `wdi-method` seeds both already answered. Neither is corpus, neither is a rule, and nothing else MAY be added beside them.
|
|
33
|
+
|
|
34
|
+
Otherwise the method does not use a `docs/` layer for corpus or rules. A leftover `docs/`
|
|
32
35
|
folder is inventory to sort, not a second home.
|
|
33
36
|
|
|
34
37
|
## Article 4 — Lifecycle
|
package/package.json
CHANGED
|
@@ -1,43 +1,56 @@
|
|
|
1
|
-
# Issue tracker
|
|
2
|
-
|
|
3
|
-
Where issues live for this repo, and what `to-spec`, `to-tickets`, and `triage` read and write.
|
|
4
|
-
|
|
5
|
-
This file is seeded by `wdi-method`. It is the product's from here on: change the tracker whenever you
|
|
6
|
-
like, but keep the three invariants below, because `wdi-build` and the validators read them.
|
|
7
|
-
|
|
8
|
-
##
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
##
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
1
|
+
# Issue tracker
|
|
2
|
+
|
|
3
|
+
Where issues live for this repo, and what `to-spec`, `to-tickets`, and `triage` read and write.
|
|
4
|
+
|
|
5
|
+
This file is seeded by `wdi-method`. It is the product's from here on: change the tracker whenever you
|
|
6
|
+
like, but keep the three invariants below, because `wdi-build` and the validators read them.
|
|
7
|
+
|
|
8
|
+
## One root, and the registry is what tells the two apart
|
|
9
|
+
|
|
10
|
+
Everything lives under `.scratch/`, one directory per effort:
|
|
11
|
+
|
|
12
|
+
| | Owned by | Lives at |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| **A spec** — the work behind an `FR` | `wdi-build`, at G5 | `.scratch/<spec-id>-<slug>/SPEC.md` and `.scratch/<spec-id>-<slug>/issues/<NN>-<slug>.md`, with `spec_folder` in `.control/registry/specs.yaml` naming that directory |
|
|
15
|
+
| **Ad hoc work** — a quick bug report, a small idea, engineering-skill scratch | this file's convention | `.scratch/<slug>/` |
|
|
16
|
+
|
|
17
|
+
**The path no longer says which is which — the registry does.** An effort with a row in `specs.yaml`
|
|
18
|
+
is a spec and answers to G5; an effort with no row is ad hoc. That is deliberate: one root means the
|
|
19
|
+
engines need no case analysis and `to-tickets` publishes to the same place every time, and it puts the
|
|
20
|
+
distinction where something can actually check it.
|
|
21
|
+
|
|
22
|
+
`<spec-id>` is the id from `specs.yaml` — `.scratch/spec-3-checkout/`, never a bare slug. Left free,
|
|
23
|
+
that leaf gets written four different ways in four repos, and one repo managed all four inside itself:
|
|
24
|
+
a bare wave number, a `spec-` prefix with no number, a prefix with one, and a slug alone. Every one of
|
|
25
|
+
them was allowed, and none could be traced back to the row that owns it. The id in front is what makes
|
|
26
|
+
the folder answer to `specs.yaml`.
|
|
27
|
+
|
|
28
|
+
Ad hoc work that turns out to touch an `FR` **stops and becomes a spec** through `wdi-build` — the Fast
|
|
29
|
+
Path rule in `delivery-flow-guide.md` owns that boundary. It gains a row and a rename, not a second home.
|
|
30
|
+
|
|
31
|
+
## The three invariants
|
|
32
|
+
|
|
33
|
+
Whatever tracker this repo uses — local markdown, GitHub, GitLab, Jira — these MUST hold:
|
|
34
|
+
|
|
35
|
+
1. **One parent per spec, one issue per ticket.** A ticket is an issue, never a sub-task: only an issue
|
|
36
|
+
carries native blocking edges, and the frontier is read from them.
|
|
37
|
+
2. **Status lives on the ticket itself and nowhere else.** A `**Status:**` line near the top of the
|
|
38
|
+
ticket file, or `status:` in its frontmatter. `ticket-status-one-home` reads it there, and copying it
|
|
39
|
+
into `specs.yaml` is what that validator exists to refuse.
|
|
40
|
+
3. **Every ticket names what it `satisfies`** — the `UC` or `FR` behind it. Without it the chain
|
|
41
|
+
`FR → UC → ticket → test` breaks and the RTM cannot say which promise went green.
|
|
42
|
+
|
|
43
|
+
## Conventions — local markdown
|
|
44
|
+
|
|
45
|
+
- One effort per directory: `.scratch/<spec-id>-<slug>/` for a spec, `.scratch/<slug>/` for ad hoc work
|
|
46
|
+
- The spec, where the size calls for one, is `SPEC.md` in that directory
|
|
47
|
+
- One file per ticket at `<effort>/issues/<NN>-<slug>.md`, numbered from `01`, never a single
|
|
48
|
+
combined file
|
|
49
|
+
- Blocking edges as a `Blocked by: NN, NN` line near the top
|
|
50
|
+
- Comments append at the bottom under a `## Comments` heading
|
|
51
|
+
|
|
52
|
+
## Switching to a real tracker
|
|
53
|
+
|
|
54
|
+
Re-run `/setup-matt-pocock-skills` and pick it, then keep the three invariants above. The mapping WDI
|
|
55
|
+
Method expects is in `delivery-flow-guide.md` § *Mapping to a tracker*: parent issue is the spec, issue is
|
|
56
|
+
the ticket, Fix Version is the release, and the `CAP`/`FR` travel as labels.
|