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
|
@@ -26,9 +26,11 @@ method does not invoke, ask `bmad-help`, which reads BMad's own documentation.
|
|
|
26
26
|
| Course correction | `bmad-correct-course` | `wdi-decision` |
|
|
27
27
|
|
|
28
28
|
**Everything below G5 left this table.** `SPEC.md`, the tickets, the code, and the code panel are produced
|
|
29
|
-
by `to-spec`, `to-tickets`, `implement`, `tdd`, and `code-review` — engines that are not BMad's
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
by `to-spec`, `to-tickets`, `implement`, `tdd`, and `code-review` — engines that are not BMad's. Three of
|
|
30
|
+
the five ship with `disable-model-invocation: true`; `wdi-method` strips it from the copies installed in
|
|
31
|
+
this repo and writes a guard line naming who may drive them, so **`wdi-build` and `wdi-autopilot` invoke
|
|
32
|
+
them directly** and an unattended iteration needs nobody. `wdi-build` owns that pipeline;
|
|
33
|
+
`bmad-guide.md` owns the reasoning.
|
|
32
34
|
|
|
33
35
|
**The three bold rows are why this method exists.** BMad stops at the promise and starts again at the
|
|
34
36
|
mechanism, and every behaviour in between had no author. Three consequences attach to those artifacts and
|
|
@@ -50,15 +52,43 @@ A Fast Path that turns out to touch an `FR` MUST stop and become a spec `S`, whi
|
|
|
50
52
|
|---|---|
|
|
51
53
|
| `bmad-advanced-elicitation` · `bmad-party-mode` | Thinking aids. They produce no artifact and MUST NOT be treated as authors |
|
|
52
54
|
| `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 |
|
|
55
|
+
| `bmad-qa-generate-e2e-tests` | Tests for a feature that **already exists**. `tdd` is test-first for work being built, so this has no replacement here and is NOT retired — but what it writes is a test, never a contract, and it MUST NOT be read as one |
|
|
56
|
+
| `bmad-checkpoint-preview` | A human reading aid over a change, the same class as `bmad-advanced-elicitation`. It MUST NOT be counted as the Step 3 panel: that one is a separate dispatch by a different agent |
|
|
53
57
|
| `bmad-help` | Questions about BMad itself. It MUST NOT be used to answer "where am I" — that is `wdi-help` |
|
|
54
58
|
|
|
55
59
|
## What is NOT USED, and MUST NOT be
|
|
56
60
|
|
|
61
|
+
**The criterion, and it binds every row below.** A BMad skill is retired only where this method has a
|
|
62
|
+
**named replacement** for what it produces. Without one it is not retired — it goes in the table above
|
|
63
|
+
instead, as something that may be used but MUST NOT author. Banning a capability with nothing in its
|
|
64
|
+
place is how a method gets worked around rather than followed.
|
|
65
|
+
|
|
66
|
+
### Retired at G5 — enforced by install and update
|
|
67
|
+
|
|
68
|
+
**This is enforced, not only stated.** `install` and `update` set `disable-model-invocation: true` on
|
|
69
|
+
every wrapper below and add a `Skill(<name>)` deny rule to `.claude/settings.json`, both re-applied on
|
|
70
|
+
every run because BMad's installer rewrites its own wrappers. A person typing `/bmad-build` still gets
|
|
71
|
+
it: the method retires a default, it does not confiscate a tool. The list lives in
|
|
72
|
+
`bin/wdi-method.js` as `BMAD_RETIRED_G5`, and a test fails when this table and that array disagree.
|
|
73
|
+
|
|
74
|
+
| Skill | Replaced by | Why |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| `bmad-spec` | `to-spec` | **Retired.** The contract below G5 is no longer BMad's. Its `_bmad/custom/*.toml` override is withdrawn and `update` removes any still installed |
|
|
77
|
+
| `bmad-build` · `bmad-build-auto` | `implement` · `wdi-autopilot` | **Retired.** `bmad-build` describes itself as implementing "any user intent, requirement, story, bug fix or change request" — the most inviting description in the repo's skill index, for the one thing this method owns most tightly. `bmad-build-auto` is an unattended loop, which is `wdi-autopilot`'s |
|
|
78
|
+
| `bmad-code-review` | `code-review` | **Retired.** The panel at Step 3 is a separate dispatch by a different agent; BMad's own review layers are the builder reviewing itself |
|
|
79
|
+
| `bmad-retrospective` | — | **Retired** with `RTR-` and `V19`. A frozen `RTR-` file stays where it is |
|
|
80
|
+
| `bmad-agent-dev` | `implement` | **Retired.** "Senior software engineer for story execution and code implementation" is `implement`'s sentence |
|
|
81
|
+
| `bmad-create-epics-and-stories` | `to-tickets` | **Retired**, and not merely by preference: the `epics` level between a spec and its tickets is **repealed in code** — `validate.py` reads a flat `tickets:` list. A skill whose only output is a shape nothing reads |
|
|
82
|
+
| `bmad-create-story` · `bmad-dev-story` · `bmad-dev-auto` · `bmad-quick-dev` | `implement` | **Retired.** BMad deprecated all four in favour of `bmad-build`, which is itself retired here. An alias to a retired skill is retired |
|
|
83
|
+
| `bmad-sprint-planning` · `bmad-sprint-status` | the ticket itself | **Retired.** The sprint route keeps status in a hand-edited file; this method reads status from the ticket — `bmad-guide.md` owns the reasoning |
|
|
84
|
+
|
|
85
|
+
### Not used for other reasons — not enforced, and not G5's
|
|
86
|
+
|
|
87
|
+
These are outside the enforced list above: nothing locks them, because nothing here replaces them and
|
|
88
|
+
none of them competes for G5's work.
|
|
89
|
+
|
|
57
90
|
| Skill | Why |
|
|
58
91
|
|---|---|
|
|
59
|
-
| `bmad-spec` · `bmad-build` · `bmad-build-auto` · `bmad-code-review` · `bmad-retrospective` | **Retired.** The engine layer below G5 is no longer BMad's. Their `_bmad/custom/*.toml` overrides are withdrawn and `update` removes any still installed |
|
|
60
|
-
| `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 the ticket itself — `bmad-guide.md` owns the reasoning |
|
|
61
|
-
| `bmad-create-story` · `bmad-dev-story` · `bmad-quick-dev` · `bmad-dev-auto` | Deprecated in BMad itself, and their replacements are retired too |
|
|
62
92
|
| `bmad-editorial-review*` · `bmad-review-*` | Shims onto `bmad-review` lenses. Ask for the lens, not the shim |
|
|
63
93
|
| `bmad-document-project` · `bmad-generate-project-context` | Forward to `bmad-project-context`. This repo's agent instructions are maintained by hand |
|
|
64
94
|
| Any skill named as a **gate condition** | A gate is passed by its checklist and its validators, never by a skill having run |
|
|
@@ -1490,7 +1490,8 @@ def custom_room_declared(c: Corpus, r: Result) -> None: # was V27
|
|
|
1490
1490
|
#
|
|
1491
1491
|
# The two rendered trees are DELIBERATELY absent from this list. They are regenerated by this
|
|
1492
1492
|
# script, so a product that declines to commit derived output is making a choice the method allows.
|
|
1493
|
-
COMMITTED_DIRS = (".constitution", ".control", ".what", ".how", "_bmad-output", ".work"
|
|
1493
|
+
COMMITTED_DIRS = (".constitution", ".control", ".what", ".how", "_bmad-output", ".work",
|
|
1494
|
+
".scratch")
|
|
1494
1495
|
|
|
1495
1496
|
# Probed inside each directory above, and named so that no honest pattern would ever mean to match
|
|
1496
1497
|
# it. The distinction this draws is the entire point of the check: `.work/upstream/` or
|
|
@@ -1548,6 +1549,76 @@ def corpus_in_git(c: Corpus, r: Result) -> None:
|
|
|
1548
1549
|
f"so no clone has what is in it")
|
|
1549
1550
|
|
|
1550
1551
|
|
|
1552
|
+
ENGINE_HOMES = (".claude", ".agents", ".agent", ".cursor", ".codex")
|
|
1553
|
+
ENGINE_FLAGGED = ("to-spec", "to-tickets", "implement")
|
|
1554
|
+
ENGINE_SKILLS = ENGINE_FLAGGED + ("tdd", "code-review", "domain-modeling")
|
|
1555
|
+
FLAG_RE = re.compile(r"^disable-model-invocation\s*:\s*true", re.M)
|
|
1556
|
+
|
|
1557
|
+
|
|
1558
|
+
def _engine_files(root: Path, name: str) -> list[Path]:
|
|
1559
|
+
"""Every copy of one engine, de-duplicated by what it resolves to.
|
|
1560
|
+
|
|
1561
|
+
`npx skills add` can symlink one SKILL.md into several platform folders, so the same file is
|
|
1562
|
+
reachable under `.claude/skills/` and `.agents/skills/` at once. Reporting it twice would make
|
|
1563
|
+
one finding read as two.
|
|
1564
|
+
"""
|
|
1565
|
+
seen: dict[Path, Path] = {}
|
|
1566
|
+
for home in ENGINE_HOMES:
|
|
1567
|
+
path = root / home / "skills" / name / "SKILL.md"
|
|
1568
|
+
if not path.is_file():
|
|
1569
|
+
continue
|
|
1570
|
+
try:
|
|
1571
|
+
seen.setdefault(path.resolve(), path)
|
|
1572
|
+
except OSError:
|
|
1573
|
+
seen.setdefault(path, path)
|
|
1574
|
+
return list(seen.values())
|
|
1575
|
+
|
|
1576
|
+
|
|
1577
|
+
def _frontmatter(text: str) -> str:
|
|
1578
|
+
m = FM.match(text)
|
|
1579
|
+
return m.group(1) if m else ""
|
|
1580
|
+
|
|
1581
|
+
|
|
1582
|
+
def engines_invocable(c: Corpus, r: Result) -> None:
|
|
1583
|
+
"""The three flagged engines MUST be invocable in the repo's own copies.
|
|
1584
|
+
|
|
1585
|
+
`to-spec`, `to-tickets` and `implement` ship with `disable-model-invocation: true`. Nothing
|
|
1586
|
+
outside the file lifts it — Claude Code's gate reads the frontmatter and consults no setting,
|
|
1587
|
+
and `skillOverrides` only ever tightens — so `wdi-method` strips the key from the copies the
|
|
1588
|
+
repo owns and writes one guard line in its place. That is what lets `wdi-build` invoke an engine
|
|
1589
|
+
and `wdi-autopilot` run an iteration with nobody watching.
|
|
1590
|
+
|
|
1591
|
+
Two things put the key back, both routine: `npx skills update`, which restores the author's file
|
|
1592
|
+
byte for byte, and a fresh `npx skills add`. Neither says anything, and the failure surfaces
|
|
1593
|
+
hours later as an unattended run that stalled at Phase 2 with no explanation. This is the check
|
|
1594
|
+
that turns that into a line of output.
|
|
1595
|
+
|
|
1596
|
+
Checked in the FRONTMATTER, not the file: the guard line is prose about the key, and matching
|
|
1597
|
+
the whole file would fail on the fix rather than on the defect.
|
|
1598
|
+
|
|
1599
|
+
A repo with no engines at all is SKIPPED, not failed. `--skip-engines-check` is a supported
|
|
1600
|
+
install — CI, and a repo that will never reach G5 — and a validator that is permanently red
|
|
1601
|
+
there is a validator that gets ignored everywhere else.
|
|
1602
|
+
"""
|
|
1603
|
+
installed = {name: _engine_files(c.root, name) for name in ENGINE_SKILLS}
|
|
1604
|
+
if not any(installed.values()):
|
|
1605
|
+
r.skip("engines-invocable", "no engines in this repo — G5 cannot run until they are "
|
|
1606
|
+
"installed (`npx skills@latest add mattpocock/skills`), and until then "
|
|
1607
|
+
"there is nothing here to check")
|
|
1608
|
+
return
|
|
1609
|
+
for name in ENGINE_SKILLS:
|
|
1610
|
+
if not installed[name]:
|
|
1611
|
+
r.fail("engines-invocable", name, "is not installed in this repo — G5 needs all six, and "
|
|
1612
|
+
"a user-level plugin does not count: its files are not this repo's to unlock")
|
|
1613
|
+
for name in ENGINE_FLAGGED:
|
|
1614
|
+
for path in installed[name]:
|
|
1615
|
+
if FLAG_RE.search(_frontmatter(path.read_text(encoding="utf-8", errors="replace"))):
|
|
1616
|
+
r.fail("engines-invocable", name,
|
|
1617
|
+
f"{path.relative_to(c.root).as_posix()} carries `disable-model-invocation` "
|
|
1618
|
+
f"again — no skill can invoke it, so wdi-build stops at Phase 2. `npx skills "
|
|
1619
|
+
f"update` restores it; `npx wdi-method engines --fix` strips it back out")
|
|
1620
|
+
|
|
1621
|
+
|
|
1551
1622
|
def id_allocated_once(c: Corpus, r: Result) -> None: # was V28
|
|
1552
1623
|
"""One id, one row — across every file the requirement registry is split into.
|
|
1553
1624
|
|
|
@@ -1582,7 +1653,7 @@ def run_checks(c: Corpus, asof: dt.date) -> Result:
|
|
|
1582
1653
|
# no two copies left to compare.
|
|
1583
1654
|
# V19 is REPEALED. It checked one line item — an `RTR-` file in .control/reports/ — and the
|
|
1584
1655
|
# retrospective it archived was the only thing spec size `L` ever decided. Both went together.
|
|
1585
|
-
for fn in (goal_has_fr, fr_has_uc, uc_scheduled, ticket_has_test, nfr_has_enforcer, refs_resolve, no_cycles, applied_dec_touches, locked_gate_passed, parallel_tickets_blocked, lc_registered, review_trace, chain_links, memlog_home, spec_names_release_prd, ticket_status_one_home, defect_root_cause, entity_one_writer, spec_after_g4, high_risk_named, mandate_accept, cites_resolve, container_built, custom_room_declared, corpus_in_git, id_allocated_once):
|
|
1656
|
+
for fn in (goal_has_fr, fr_has_uc, uc_scheduled, ticket_has_test, nfr_has_enforcer, refs_resolve, no_cycles, applied_dec_touches, locked_gate_passed, parallel_tickets_blocked, lc_registered, review_trace, chain_links, memlog_home, spec_names_release_prd, ticket_status_one_home, defect_root_cause, entity_one_writer, spec_after_g4, high_risk_named, mandate_accept, cites_resolve, container_built, custom_room_declared, corpus_in_git, engines_invocable, id_allocated_once):
|
|
1586
1657
|
fn(c, r)
|
|
1587
1658
|
plan_dates(c, r, asof)
|
|
1588
1659
|
return r
|
|
@@ -1785,7 +1856,7 @@ def gen_status(c: Corpus, rtm: dict, result: Result) -> dict:
|
|
|
1785
1856
|
per_spec.append({"spec": wid, "status": spec.get("status"),
|
|
1786
1857
|
"tickets_done": done, "tickets_total": len(items),
|
|
1787
1858
|
"work_progress": _pct(done, len(items))})
|
|
1788
|
-
applicable =
|
|
1859
|
+
applicable = 27 # goal-has-fr..id-allocated-once minus V10 and V19, both repealed
|
|
1789
1860
|
return {
|
|
1790
1861
|
"promise_progress": _pct(green, len(counted)),
|
|
1791
1862
|
"rtm_rows": {"green": green, "counted": len(counted),
|
|
@@ -1,186 +1,192 @@
|
|
|
1
|
-
---
|
|
2
|
-
status: Reference
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# The WDI Method — orientation
|
|
6
|
-
|
|
7
|
-
**Opened when:** you have never seen this method before, or you have and want the shape back in one reading.
|
|
8
|
-
|
|
9
|
-
This file **explains**. It does not bind — `../document/*-guide.md` does, and where the two disagree the guide
|
|
10
|
-
wins and the disagreement is a defect to report.
|
|
11
|
-
|
|
12
|
-
Five minutes. Four more files sit beside this one: `artifact-map.md` for *"where does this file go"*,
|
|
13
|
-
`mode-risk-map.md` for *"I set a `mode` and a `risk_accepted` — what changes?"*, `portability.md` for which
|
|
14
|
-
files are the method's and which are the product's, and `rationale.md` for *"why is it like this"* — open
|
|
15
|
-
that last one before changing a rule, so you know what you are about to break.
|
|
16
|
-
|
|
17
|
-
## What the method is
|
|
18
|
-
|
|
19
|
-
Two methods joined. **WDI** owns the flow, the gates, and the artifacts nobody else writes. **BMad** owns
|
|
20
|
-
the writing skills where it has one. Every BMad skill is invoked through a WDI wrapper, never directly: the
|
|
21
|
-
wrapper is what checks position, verifies the result against the guide, and lands the memlog.
|
|
22
|
-
|
|
23
|
-
The whole thing rests on one sentence:
|
|
24
|
-
|
|
25
|
-
> Owner time is spent at five points. Between them, the agents work alone.
|
|
26
|
-
|
|
27
|
-
## Five gates
|
|
28
|
-
|
|
29
|
-
A gate is named for **what is decided there**, never for the work before it.
|
|
30
|
-
|
|
31
|
-
| Gate | Decides | How often | Budget |
|
|
32
|
-
|---|---|---|---|
|
|
33
|
-
| **G1 Problem** | What the problem is, whose it is, why it earns work | once | 20' |
|
|
34
|
-
| **G2 Product** | What is built, and how it feels to use | once per PRD | 45' |
|
|
35
|
-
| **G3 Blueprint** | The whole portrait: which use cases, their entities, tables, endpoints, screens, and the invariants binding them | once per **product** | 45' |
|
|
36
|
-
| **G4 Component** | How one Product Component is built, and what the choice costs | once per **component** | 20–30' |
|
|
37
|
-
| **G5 Release** | Whether it is done and proven | once per spec | 10' |
|
|
38
|
-
|
|
39
|
-
**Only G4 can disappear.** At `mode: catalog` its session does not happen at all; the other four always run,
|
|
40
|
-
and what each decides never changes. What `mode` does shorten everywhere is the **checklist**: at `catalog`
|
|
41
|
-
only the ★ questions are required, at G1 and G5 as much as at G4. Sessions fixed, checklist elastic — that is
|
|
42
|
-
what lets the whole system be held in one head.
|
|
43
|
-
|
|
44
|
-
## Two settings, and they control different things
|
|
45
|
-
|
|
46
|
-
| Setting | Where | Controls |
|
|
47
|
-
|---|---|---|
|
|
48
|
-
| `mode` | globally in `index.yaml`, per component in `components.yaml` | **Document depth**, and only that |
|
|
49
|
-
| `risk_accepted` | per component | **Review intensity**, and only that |
|
|
50
|
-
|
|
51
|
-
`mode` takes `catalog` · `outline` · `guarded` · `deep`, and the default is `catalog`. A component at
|
|
52
|
-
`catalog` **skips G4 entirely** — its control moved to G3, where its use cases, tables, endpoints, screens,
|
|
53
|
-
domain model, and C4 were all approved.
|
|
54
|
-
|
|
55
|
-
`risk_accepted` takes `low` · `medium` · `high`, and its direction reads off the name: `high` means *"I
|
|
56
|
-
accept a lot of risk here"*, so its review is the lightest.
|
|
57
|
-
|
|
58
|
-
Keeping them apart is what lets one component be **thin on purpose and reviewed the hardest**. Why that
|
|
59
|
-
matters is in `rationale.md`; what each value demands is in `../document/delivery-flow-guide.md`.
|
|
60
|
-
|
|
61
|
-
## The run, first time through
|
|
62
|
-
|
|
63
|
-
| # | Step | Run | Gate |
|
|
64
|
-
|---|---|---|---|
|
|
65
|
-
| 0 | Set up | `wdi-init` intent `setup` — registry scaffolded, global `mode` set, existing documents reported, structure maps derived | — |
|
|
66
|
-
| 1 | Discovery and brief | `wdi-problem` | **G1** |
|
|
67
|
-
| 2 | PRD, one per initiative | `wdi-product` intent `prd` | **G2** |
|
|
68
|
-
| 2b | UX — only when the interface is a large part of the promise. **Before G2**, because G2 reads its `EXPERIENCE.md` | `wdi-ux` | with **G2** |
|
|
69
|
-
| 3 | Birth the components, set `mode` and `risk_accepted`, and land the waiting UX halves | `wdi-init` intent `component` | — (tail of G2) |
|
|
70
|
-
| 4 | Blueprint | `wdi-blueprint` intent `catalog`, then `platform` | **G3** |
|
|
71
|
-
| 5 | One component's depth | `wdi-component` — as deep as its `mode`; **skipped at `catalog`** | **G4** |
|
|
72
|
-
| 6 | Pick the work | `wdi-report` intent `estimate` — candidate tasks derived from `CAP`/`FR`; one row becomes one spec | — |
|
|
73
|
-
| 7 | Build | `wdi-build` — opens the spec, has the owner run `to-spec` and `to-tickets`, ships each ticket, closes the spec | **G5** |
|
|
74
|
-
|
|
75
|
-
After step 7 the next component enters at **step 5** (at `mode: catalog`, at step 6), not at the
|
|
76
|
-
beginning. Steps 0–4 happen once in the life of the product.
|
|
77
|
-
|
|
78
|
-
**What the human reads is one rendered page per gate**: `.what-rendered/_product-brief/brief.md` at G1,
|
|
79
|
-
`.what-rendered/_prd/<slug>/prd.md` at G2, `.how-rendered/blueprint.md` at G3,
|
|
80
|
-
`.how-rendered/<pc>/SDD-<pc>.md` at G4. The working documents under `.what/` and `.how/` point at the
|
|
81
|
-
registry instead of repeating it and are the AI's. `SPEC.md` and ticket files are **not read by humans**.
|
|
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
|
-
| `wdi-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
|
123
|
-
|
|
124
|
-
| `wdi-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
|
129
|
-
|
|
130
|
-
| `wdi-
|
|
131
|
-
| `wdi-
|
|
132
|
-
| `wdi-
|
|
133
|
-
| `wdi-
|
|
134
|
-
| `wdi-
|
|
135
|
-
| `wdi-
|
|
136
|
-
| `wdi-
|
|
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
|
-
| The
|
|
169
|
-
|
|
170
|
-
|
|
|
171
|
-
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
1
|
+
---
|
|
2
|
+
status: Reference
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# The WDI Method — orientation
|
|
6
|
+
|
|
7
|
+
**Opened when:** you have never seen this method before, or you have and want the shape back in one reading.
|
|
8
|
+
|
|
9
|
+
This file **explains**. It does not bind — `../document/*-guide.md` does, and where the two disagree the guide
|
|
10
|
+
wins and the disagreement is a defect to report.
|
|
11
|
+
|
|
12
|
+
Five minutes. Four more files sit beside this one: `artifact-map.md` for *"where does this file go"*,
|
|
13
|
+
`mode-risk-map.md` for *"I set a `mode` and a `risk_accepted` — what changes?"*, `portability.md` for which
|
|
14
|
+
files are the method's and which are the product's, and `rationale.md` for *"why is it like this"* — open
|
|
15
|
+
that last one before changing a rule, so you know what you are about to break.
|
|
16
|
+
|
|
17
|
+
## What the method is
|
|
18
|
+
|
|
19
|
+
Two methods joined. **WDI** owns the flow, the gates, and the artifacts nobody else writes. **BMad** owns
|
|
20
|
+
the writing skills where it has one. Every BMad skill is invoked through a WDI wrapper, never directly: the
|
|
21
|
+
wrapper is what checks position, verifies the result against the guide, and lands the memlog.
|
|
22
|
+
|
|
23
|
+
The whole thing rests on one sentence:
|
|
24
|
+
|
|
25
|
+
> Owner time is spent at five points. Between them, the agents work alone.
|
|
26
|
+
|
|
27
|
+
## Five gates
|
|
28
|
+
|
|
29
|
+
A gate is named for **what is decided there**, never for the work before it.
|
|
30
|
+
|
|
31
|
+
| Gate | Decides | How often | Budget |
|
|
32
|
+
|---|---|---|---|
|
|
33
|
+
| **G1 Problem** | What the problem is, whose it is, why it earns work | once | 20' |
|
|
34
|
+
| **G2 Product** | What is built, and how it feels to use | once per PRD | 45' |
|
|
35
|
+
| **G3 Blueprint** | The whole portrait: which use cases, their entities, tables, endpoints, screens, and the invariants binding them | once per **product** | 45' |
|
|
36
|
+
| **G4 Component** | How one Product Component is built, and what the choice costs | once per **component** | 20–30' |
|
|
37
|
+
| **G5 Release** | Whether it is done and proven | once per spec | 10' |
|
|
38
|
+
|
|
39
|
+
**Only G4 can disappear.** At `mode: catalog` its session does not happen at all; the other four always run,
|
|
40
|
+
and what each decides never changes. What `mode` does shorten everywhere is the **checklist**: at `catalog`
|
|
41
|
+
only the ★ questions are required, at G1 and G5 as much as at G4. Sessions fixed, checklist elastic — that is
|
|
42
|
+
what lets the whole system be held in one head.
|
|
43
|
+
|
|
44
|
+
## Two settings, and they control different things
|
|
45
|
+
|
|
46
|
+
| Setting | Where | Controls |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `mode` | globally in `index.yaml`, per component in `components.yaml` | **Document depth**, and only that |
|
|
49
|
+
| `risk_accepted` | per component | **Review intensity**, and only that |
|
|
50
|
+
|
|
51
|
+
`mode` takes `catalog` · `outline` · `guarded` · `deep`, and the default is `catalog`. A component at
|
|
52
|
+
`catalog` **skips G4 entirely** — its control moved to G3, where its use cases, tables, endpoints, screens,
|
|
53
|
+
domain model, and C4 were all approved.
|
|
54
|
+
|
|
55
|
+
`risk_accepted` takes `low` · `medium` · `high`, and its direction reads off the name: `high` means *"I
|
|
56
|
+
accept a lot of risk here"*, so its review is the lightest.
|
|
57
|
+
|
|
58
|
+
Keeping them apart is what lets one component be **thin on purpose and reviewed the hardest**. Why that
|
|
59
|
+
matters is in `rationale.md`; what each value demands is in `../document/delivery-flow-guide.md`.
|
|
60
|
+
|
|
61
|
+
## The run, first time through
|
|
62
|
+
|
|
63
|
+
| # | Step | Run | Gate |
|
|
64
|
+
|---|---|---|---|
|
|
65
|
+
| 0 | Set up | `wdi-init` intent `setup` — registry scaffolded, global `mode` set, existing documents reported, structure maps derived | — |
|
|
66
|
+
| 1 | Discovery and brief | `wdi-problem` | **G1** |
|
|
67
|
+
| 2 | PRD, one per initiative | `wdi-product` intent `prd` | **G2** |
|
|
68
|
+
| 2b | UX — only when the interface is a large part of the promise. **Before G2**, because G2 reads its `EXPERIENCE.md` | `wdi-ux` | with **G2** |
|
|
69
|
+
| 3 | Birth the components, set `mode` and `risk_accepted`, and land the waiting UX halves | `wdi-init` intent `component` | — (tail of G2) |
|
|
70
|
+
| 4 | Blueprint | `wdi-blueprint` intent `catalog`, then `platform` | **G3** |
|
|
71
|
+
| 5 | One component's depth | `wdi-component` — as deep as its `mode`; **skipped at `catalog`** | **G4** |
|
|
72
|
+
| 6 | Pick the work | `wdi-report` intent `estimate` — candidate tasks derived from `CAP`/`FR`; one row becomes one spec | — |
|
|
73
|
+
| 7 | Build | `wdi-build` — opens the spec, has the owner run `to-spec` and `to-tickets`, ships each ticket, closes the spec | **G5** |
|
|
74
|
+
|
|
75
|
+
After step 7 the next component enters at **step 5** (at `mode: catalog`, at step 6), not at the
|
|
76
|
+
beginning. Steps 0–4 happen once in the life of the product.
|
|
77
|
+
|
|
78
|
+
**What the human reads is one rendered page per gate**: `.what-rendered/_product-brief/brief.md` at G1,
|
|
79
|
+
`.what-rendered/_prd/<slug>/prd.md` at G2, `.how-rendered/blueprint.md` at G3,
|
|
80
|
+
`.how-rendered/<pc>/SDD-<pc>.md` at G4. The working documents under `.what/` and `.how/` point at the
|
|
81
|
+
registry instead of repeating it and are the AI's. `SPEC.md` and ticket files are **not read by humans**.
|
|
82
|
+
|
|
83
|
+
Six engines come from [mattpocock/skills](https://github.com/mattpocock/skills) — `to-spec`,
|
|
84
|
+
`to-tickets`, `implement`, `tdd`, `code-review`, and `domain-modeling` (that last one is G3's, invoked by
|
|
85
|
+
`wdi-blueprint`). They are installed **into the repo**, on any agent:
|
|
86
|
+
`npx skills@latest add mattpocock/skills`. A user-level plugin does not count, and the reason is
|
|
87
|
+
mechanical: three of the six ship with `disable-model-invocation: true`, nothing outside the file lifts
|
|
88
|
+
it, and a plugin's files are not the repo's to edit. `wdi-method` strips it from the repo's own copies so
|
|
89
|
+
`wdi-build` and `wdi-autopilot` can invoke them, and re-applies that on every update because
|
|
90
|
+
`npx skills update` restores the author's file.
|
|
91
|
+
|
|
92
|
+
You do NOT need `/setup-matt-pocock-skills`: the installer seeds `docs/agents/` already answered for this
|
|
93
|
+
method. G1–G4 run without the engines; `wdi-build` and the Fast Path do not.
|
|
94
|
+
|
|
95
|
+
## The run, every time after
|
|
96
|
+
|
|
97
|
+
| Situation | Run |
|
|
98
|
+
|---|---|
|
|
99
|
+
| The next component is being taken on | `wdi-init` intent `mode` or `risk` if either needs changing → `wdi-component` → **G4** → `wdi-build` → **G5** |
|
|
100
|
+
| That component is at `mode: catalog` | straight to `wdi-build`. G4 is skipped |
|
|
101
|
+
| A promise changes where a PRD already exists | `wdi-product` intent `update` — never a second PRD for the same area |
|
|
102
|
+
| A new initiative with a different reader | `wdi-product` intent `prd` → `wdi-init` intent `component` if it births components |
|
|
103
|
+
| A small fix touching no `FR`, `UC`, `AD-N`, or domain model | Fast Path: the owner runs `/implement` directly, with no wrapper. It **stops and becomes a spec `S`** the moment an `FR` is touched |
|
|
104
|
+
| A bug, a failing test, unexpected behaviour | `wdi-systematic-debugging`, **before** any fix is proposed |
|
|
105
|
+
| A planning assumption turned out void | `wdi-decision` — it wraps `bmad-correct-course`, proposes, and changes nothing itself |
|
|
106
|
+
| An estimate or a task list is needed | `wdi-report` intent `estimate` |
|
|
107
|
+
| `wdi-method update` printed an `upgrade` line | `wdi-upgrade`, before any other skill — it moves content into the new shape, never invents it, one commit |
|
|
108
|
+
| You do not know where you are | `wdi-help` |
|
|
109
|
+
|
|
110
|
+
## Eighteen skills
|
|
111
|
+
|
|
112
|
+
Named for the **gate they serve**, so *"which skill do I run"* is answered by *"which gate am I at"*.
|
|
113
|
+
|
|
114
|
+
**Moment-bound** — running them outside their point is wrong:
|
|
115
|
+
|
|
116
|
+
| Skill | Its moment |
|
|
117
|
+
|---|---|
|
|
118
|
+
| `wdi-init` intent `setup` | before G1, once per project |
|
|
119
|
+
| `wdi-problem` | G1 |
|
|
120
|
+
| `wdi-product` | G2 |
|
|
121
|
+
| `wdi-init` intent `component` | tail of G2, and whenever a new PRD births a component |
|
|
122
|
+
| `wdi-blueprint` | G3 |
|
|
123
|
+
| `wdi-component` | G4 |
|
|
124
|
+
| `wdi-build` | G5, one spec per run |
|
|
125
|
+
|
|
126
|
+
**Anytime** — run the moment the trigger appears, without waiting for a gate:
|
|
127
|
+
|
|
128
|
+
| Skill | Its trigger |
|
|
129
|
+
|---|---|
|
|
130
|
+
| `wdi-decision` | A decision worth remembering · a void assumption · an accepted decision to carry into documents |
|
|
131
|
+
| `wdi-question` | Something that cannot be decided now |
|
|
132
|
+
| `wdi-log` | A meeting finished, or a non-technical fact now binds |
|
|
133
|
+
| `wdi-help` | "Where am I, what next" |
|
|
134
|
+
| `wdi-explain-to-me` | "Brief me so I can decide this" — an open question, a defect, a design fork. Reads everything, writes nothing; the decision then goes to `wdi-decision` or `wdi-question` |
|
|
135
|
+
| `wdi-autopilot` | "Deliver every `FR` and do not ask me in between." A preflight the owner confirms becomes one `DEC-` of `type: mandate`; a loop then fires the skill, and it runs every other skill, decides what they would have asked, and writes each decision to one ledger the owner reviews in parallel |
|
|
136
|
+
| `wdi-upgrade` | `wdi-method update` just moved the method version, and the summary listed content still in the old shape. Moves it, never invents it; one commit |
|
|
137
|
+
| `wdi-reconcile` | Any time. Read-only — it reports, it never edits |
|
|
138
|
+
| `wdi-review` | Over any document, any time |
|
|
139
|
+
| `wdi-systematic-debugging` | A bug, a failed test, a failed build, unexpected behaviour |
|
|
140
|
+
| `wdi-report` | An estimate at the start · progress periodically · before a client update |
|
|
141
|
+
| `wdi-init` intents `mode` · `risk` · `structure` | Any time |
|
|
142
|
+
| `wdi-ux` | Any time after a PRD exists, if UX is being used |
|
|
143
|
+
|
|
144
|
+
## Who writes what — WDI and BMad
|
|
145
|
+
|
|
146
|
+
| Artifact | Written by | Wrapped in |
|
|
147
|
+
|---|---|---|
|
|
148
|
+
| Product brief | `bmad-product-brief` | `wdi-problem` |
|
|
149
|
+
| PRD | `bmad-prd` | `wdi-product` |
|
|
150
|
+
| UX | `bmad-ux` | `wdi-ux` |
|
|
151
|
+
| Spine + C4 | `bmad-architecture` | `wdi-blueprint` |
|
|
152
|
+
| **UC catalogue · actors · entities · business rules** | **nothing in BMad** | `wdi-blueprint` writes it itself |
|
|
153
|
+
| **SRS and all of `.what/<pc>/`** | **nothing in BMad** | `wdi-component` writes it itself |
|
|
154
|
+
| **SDD and all of `.how/<pc>/`** | **nothing in BMad** | `wdi-component` writes it itself |
|
|
155
|
+
| `SPEC.md` + tickets | `to-spec` · `to-tickets` — **not BMad's**, and the owner runs them | `wdi-build` |
|
|
156
|
+
| Code | `implement`, with `tdd` inside it — same | `wdi-build` |
|
|
157
|
+
| Code review | `code-review` — same | `wdi-build` |
|
|
158
|
+
| Document review | `bmad-review` | `wdi-review` |
|
|
159
|
+
| Course correction | `bmad-correct-course` | `wdi-decision` |
|
|
160
|
+
|
|
161
|
+
**The bold rows are why this method exists.** BMad stops at the promise and starts again at the mechanism,
|
|
162
|
+
and every behaviour in between had no author. Three consequences stick to those artifacts and are handled
|
|
163
|
+
deliberately: no `doc_standards` fires a review, no memlog is born on its own, and no template enforces
|
|
164
|
+
itself.
|
|
165
|
+
|
|
166
|
+
## Where things live
|
|
167
|
+
|
|
168
|
+
| The thing in your hand | Its folder |
|
|
169
|
+
|---|---|
|
|
170
|
+
| How we work — a rule, a guide, a template | `.constitution/` |
|
|
171
|
+
| What currently holds — a decision, a question, a registry, a map | `.control/` |
|
|
172
|
+
| What is promised — the brief, a PRD, a use case, a business rule | `.what/` |
|
|
173
|
+
| How it is built — the spine, C4, an inventory, an SDD, a contract | `.how/` |
|
|
174
|
+
| The complete page a human reads at a gate — regenerated, never edited | `.what-rendered/` · `.how-rendered/` |
|
|
175
|
+
| A skill run's working output | `_bmad-output/` |
|
|
176
|
+
| Scratch that empties when the task closes | `.work/` |
|
|
177
|
+
| The application | `src/` · `web/` |
|
|
178
|
+
|
|
179
|
+
The test that settles anything ambiguous: **is this file still correct after its spec has passed?** Yes →
|
|
180
|
+
the corpus. No → `_bmad-output/`. In doubt, `../document/corpus-guide.md`.
|
|
181
|
+
|
|
182
|
+
## Model choice
|
|
183
|
+
|
|
184
|
+
| Point | Model |
|
|
185
|
+
|---|---|
|
|
186
|
+
| Decisions — proposing a slicing, wording a `DEC-`, preparing a gate | `opus@high` |
|
|
187
|
+
| Writing, derivation, a review-fix pass | `sonnet@high` |
|
|
188
|
+
| Code review panel | Reviewers dispatched separately from the builder — the local Agent Rules govern CLI/model pairing |
|
|
189
|
+
|
|
190
|
+
In a derivation pass, quality comes from the input rather than the model. Running a "find the gap" lens with
|
|
191
|
+
the most careful model produces the most gaps, and each one becomes an open question — a cost nobody sees
|
|
192
|
+
until the question list has stopped being readable.
|
|
@@ -117,7 +117,7 @@ someone else performs. `../document/corpus-guide.md` holds the binding version o
|
|
|
117
117
|
| `wdi-blueprint` | `.what/<pc>/` § Actor Register + § UC Catalogue + `03-domain/domain-model.md` · `.what/business-rules.md` · `.control/product-glossary.md` · all of `.how/_platform/` except `design-system.md` |
|
|
118
118
|
| `wdi-component` | `.what/<pc>/` slots `02`–`05` · `.how/<pc>/` except `01-ux/` |
|
|
119
119
|
| `wdi-ux` | `EXPERIENCE.md` · `.how/<pc>/01-ux/` · `.how/_platform/design-system.md` |
|
|
120
|
-
| `wdi-build` | `specs.yaml` ·
|
|
120
|
+
| `wdi-build` | `specs.yaml` · `.scratch/<spec-id>-<slug>/` · `src/` · `web/` |
|
|
121
121
|
| `wdi-decision` | `.control/decisions/` · `decisions.yaml`, and at apply time whatever `touches` names — through each file's owner |
|
|
122
122
|
| `wdi-question` | `.control/questions/` |
|
|
123
123
|
| `wdi-log` | `.control/meetings/` · `.control/project-non-technical-log.md` |
|