wdi-method 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +203 -0
- package/bin/wdi-method.js +906 -0
- package/kit/.constitution/README.md +66 -0
- package/kit/.constitution/codebase/brownfield-guide.md +18 -0
- package/kit/.constitution/codebase/conventions-guide.md +18 -0
- package/kit/.constitution/codebase/stack-guide.md +18 -0
- package/kit/.constitution/constitution.md +135 -0
- package/kit/.constitution/document/architecture-guide.md +209 -0
- package/kit/.constitution/document/bmad-guide.md +151 -0
- package/kit/.constitution/document/bmad-skill-register.md +71 -0
- package/kit/.constitution/document/brief-guide.md +94 -0
- package/kit/.constitution/document/corpus-guide.md +341 -0
- package/kit/.constitution/document/decision-guide.md +134 -0
- package/kit/.constitution/document/delivery-flow-guide.md +338 -0
- package/kit/.constitution/document/prd-guide.md +202 -0
- package/kit/.constitution/document/sdd-guide.md +206 -0
- package/kit/.constitution/document/srs-guide.md +147 -0
- package/kit/.constitution/document/templates/addendum.md +71 -0
- package/kit/.constitution/document/templates/architecture-spine.md +100 -0
- package/kit/.constitution/document/templates/brief.md +110 -0
- package/kit/.constitution/document/templates/c4.md +77 -0
- package/kit/.constitution/document/templates/contract.md +52 -0
- package/kit/.constitution/document/templates/cross-cutting.md +80 -0
- package/kit/.constitution/document/templates/decision.md +64 -0
- package/kit/.constitution/document/templates/design-system.md +67 -0
- package/kit/.constitution/document/templates/flow.md +51 -0
- package/kit/.constitution/document/templates/integration.md +69 -0
- package/kit/.constitution/document/templates/inventory.md +69 -0
- package/kit/.constitution/document/templates/lc.md +47 -0
- package/kit/.constitution/document/templates/lifecycle.md +52 -0
- package/kit/.constitution/document/templates/meeting.md +47 -0
- package/kit/.constitution/document/templates/model.md +55 -0
- package/kit/.constitution/document/templates/oq.md +45 -0
- package/kit/.constitution/document/templates/prd.md +226 -0
- package/kit/.constitution/document/templates/questions.md +75 -0
- package/kit/.constitution/document/templates/rtr.md +61 -0
- package/kit/.constitution/document/templates/rules.md +47 -0
- package/kit/.constitution/document/templates/scn.md +40 -0
- package/kit/.constitution/document/templates/sdd.md +146 -0
- package/kit/.constitution/document/templates/srs.md +149 -0
- package/kit/.constitution/document/templates/structure-codebase.md +129 -0
- package/kit/.constitution/document/templates/structure-document.md +90 -0
- package/kit/.constitution/document/templates/uc.md +69 -0
- package/kit/.constitution/document/templates/ux.md +77 -0
- package/kit/.constitution/document/ux-guide.md +99 -0
- package/kit/.constitution/language-guide.md +69 -0
- package/kit/.constitution/method/README.md +169 -0
- package/kit/.constitution/method/artifact-map.md +155 -0
- package/kit/.constitution/method/portability.md +91 -0
- package/kit/.constitution/method/rationale.md +246 -0
- package/kit/.constitution/method-glossary.md +169 -0
- package/kit/.constitution/project/README.md +68 -0
- package/kit/.constitution/repo-guide.md +97 -0
- package/kit/.constitution/scripts/inventory.py +527 -0
- package/kit/.constitution/scripts/timeline.py +665 -0
- package/kit/.constitution/scripts/validate.py +1579 -0
- package/kit/.constitution/structure-guide.md +202 -0
- package/kit/assets/bmad-custom/bmad-advanced-elicitation.toml +15 -0
- package/kit/assets/bmad-custom/bmad-architecture.toml +31 -0
- package/kit/assets/bmad-custom/bmad-build-auto.toml +10 -0
- package/kit/assets/bmad-custom/bmad-build.toml +52 -0
- package/kit/assets/bmad-custom/bmad-code-review.toml +12 -0
- package/kit/assets/bmad-custom/bmad-correct-course.toml +27 -0
- package/kit/assets/bmad-custom/bmad-deep-recon.toml +11 -0
- package/kit/assets/bmad-custom/bmad-prd.toml +42 -0
- package/kit/assets/bmad-custom/bmad-product-brief.toml +34 -0
- package/kit/assets/bmad-custom/bmad-retrospective.toml +9 -0
- package/kit/assets/bmad-custom/bmad-spec.toml +15 -0
- package/kit/assets/bmad-custom/bmad-ux.toml +19 -0
- package/kit/assets/bmad-custom/config.toml +6 -0
- package/kit/skills/wdi-blueprint/SKILL.md +203 -0
- package/kit/skills/wdi-build/SKILL.md +244 -0
- package/kit/skills/wdi-component/SKILL.md +172 -0
- package/kit/skills/wdi-decision/.gitkeep +0 -0
- package/kit/skills/wdi-decision/SKILL.md +183 -0
- package/kit/skills/wdi-help/.gitkeep +0 -0
- package/kit/skills/wdi-help/SKILL.md +98 -0
- package/kit/skills/wdi-init/SKILL.md +149 -0
- package/kit/skills/wdi-log/SKILL.md +107 -0
- package/kit/skills/wdi-problem/SKILL.md +90 -0
- package/kit/skills/wdi-product/SKILL.md +127 -0
- package/kit/skills/wdi-question/.gitkeep +0 -0
- package/kit/skills/wdi-question/SKILL.md +88 -0
- package/kit/skills/wdi-reconcile/.gitkeep +0 -0
- package/kit/skills/wdi-reconcile/SKILL.md +146 -0
- package/kit/skills/wdi-report/SKILL.md +205 -0
- package/kit/skills/wdi-review/SKILL.md +118 -0
- package/kit/skills/wdi-systematic-debugging/SKILL.md +193 -0
- package/kit/skills/wdi-systematic-debugging/references/condition-based-waiting.md +115 -0
- package/kit/skills/wdi-systematic-debugging/references/defense-in-depth.md +122 -0
- package/kit/skills/wdi-systematic-debugging/references/find-polluter.sh +72 -0
- package/kit/skills/wdi-systematic-debugging/references/root-cause-tracing.md +169 -0
- package/kit/skills/wdi-ux/SKILL.md +145 -0
- package/kit-overlay/AGENTS.md +196 -0
- package/kit-overlay/README.md +66 -0
- package/kit-overlay/constitution.md +135 -0
- package/kit-overlay/portability.md +91 -0
- package/kit-overlay/repo-guide.md +97 -0
- package/lib/agents-block.mjs +52 -0
- package/lib/identity.mjs +65 -0
- package/package.json +37 -0
- package/scaffold/.control/decisions/.gitkeep +0 -0
- package/scaffold/.control/generated/.gitkeep +2 -0
- package/scaffold/.control/meetings/.gitkeep +0 -0
- package/scaffold/.control/memlog/.gitkeep +0 -0
- package/scaffold/.control/product-glossary.md +21 -0
- package/scaffold/.control/project-non-technical-log.md +23 -0
- package/scaffold/.control/questions/answered.md +11 -0
- package/scaffold/.control/questions/assumptions.md +15 -0
- package/scaffold/.control/questions/blocking.md +21 -0
- package/scaffold/.control/questions/external.md +11 -0
- package/scaffold/.control/registry/components.yaml +21 -0
- package/scaffold/.control/registry/decisions.yaml +6 -0
- package/scaffold/.control/registry/defects.yaml +3 -0
- package/scaffold/.control/registry/index.yaml +46 -0
- package/scaffold/.control/registry/requirements.yaml +15 -0
- package/scaffold/.control/registry/risks.yaml +5 -0
- package/scaffold/.control/registry/usecases.yaml +6 -0
- package/scaffold/.control/registry/waves.yaml +5 -0
- package/scaffold/.control/structure-codebase.md +19 -0
- package/scaffold/.control/structure-document.md +25 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wdi-product
|
|
3
|
+
description: Use at G2 Product — when a PRD is created or an existing promise changes. Two intents, prd and update. Checks position, dispatches bmad-prd, verifies the result against prd-guide.md, and lands the memlog. Never writes the PRD itself.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# WDI Product
|
|
7
|
+
|
|
8
|
+
G2 decides **what is built, and how it feels to use.** `bmad-prd` writes the PRD.
|
|
9
|
+
|
|
10
|
+
This wrapper exists because `bmad-prd` was the only writer of a primary artifact in this method with no WDI
|
|
11
|
+
wrapper at all — so nothing checked its position, nothing verified its result against the guide, and nothing
|
|
12
|
+
landed its memlog where the next run would read it. Those three gaps were paid for at G2 every time.
|
|
13
|
+
|
|
14
|
+
You MUST NOT write or edit `prd.md` yourself. If a check fails, name what is missing and re-dispatch.
|
|
15
|
+
|
|
16
|
+
| Intent | When |
|
|
17
|
+
|---|---|
|
|
18
|
+
| `prd` | A functional area a reader would not think to look for in an existing PRD |
|
|
19
|
+
| `update` | Anything else — the default, and by a wide margin |
|
|
20
|
+
|
|
21
|
+
## Inputs
|
|
22
|
+
|
|
23
|
+
| Source | What it answers |
|
|
24
|
+
|---|---|
|
|
25
|
+
| `.what/_product-brief/brief.md` | The problem, the primary user, the boundary the PRD MUST respect |
|
|
26
|
+
| `.what/_prd/*/prd.md` | Which initiatives already have a PRD, and what each already promises |
|
|
27
|
+
| `.control/registry/requirements.yaml` | The next `CAP`/`FR`/`NFR`/`UJ` ids, allocated globally |
|
|
28
|
+
| `.control/decisions/` | `applied` decisions the PRD MUST already reflect |
|
|
29
|
+
| `.constitution/document/prd-guide.md` | The rules the result is checked against |
|
|
30
|
+
| `.control/product-glossary.md` | Terms already fixed |
|
|
31
|
+
|
|
32
|
+
## Step 1 — Position, and `update` is the default
|
|
33
|
+
|
|
34
|
+
The decision this skill exists for. The test is the **reader**, not the calendar:
|
|
35
|
+
|
|
36
|
+
> Would someone looking for this promise open an existing document?
|
|
37
|
+
|
|
38
|
+
Yes → `update`, however large the change. No → `prd`. A PRD MUST NOT be split because it grew long, and a
|
|
39
|
+
release is never a reason on its own. `prd-guide.md` owns the full table.
|
|
40
|
+
|
|
41
|
+
Three asks that are not this skill:
|
|
42
|
+
|
|
43
|
+
| Ask | Route |
|
|
44
|
+
|---|---|
|
|
45
|
+
| The problem itself has changed | `wdi-problem` — a re-cut plan under a wrong problem is wasted work |
|
|
46
|
+
| Only the **wording** of an `FR` is wrong, while the promise is the same | The skill already at work fixes it directly. See below |
|
|
47
|
+
| A planning assumption turned out to be void | `wdi-decision`, which wraps `bmad-correct-course` |
|
|
48
|
+
|
|
49
|
+
## Step 2 — Wording is not a promise
|
|
50
|
+
|
|
51
|
+
The split that ended three corrections in "reported but not fixed". `prd-guide.md` owns it; what this skill
|
|
52
|
+
owns is refusing to run for the wrong half.
|
|
53
|
+
|
|
54
|
+
| What changed | Who does it |
|
|
55
|
+
|---|---|
|
|
56
|
+
| A wrong cross-reference, a retired term, a word inconsistent with an `applied` decision — **the promise is the same** | Whichever skill is already at work. Memlog records it; **one** Revision History row per pass, never one per correction |
|
|
57
|
+
| Scope, the proof of done, an `FR` retired or born | This skill, intent `update` |
|
|
58
|
+
|
|
59
|
+
You MUST NOT accept a wording correction as an `update` run. Doing so puts a trivial fix behind a gate, and
|
|
60
|
+
that is exactly how the three earlier ones were dropped.
|
|
61
|
+
|
|
62
|
+
## Step 3 — Dispatch
|
|
63
|
+
|
|
64
|
+
Invoke `bmad-prd` with the detected intent, scoped to **one initiative**. Do not restate the rules to it —
|
|
65
|
+
they arrive through `persistent_facts` and `doc_standards` in `_bmad/custom/bmad-prd.toml`.
|
|
66
|
+
|
|
67
|
+
Name the brief and, for `update`, the existing PRD and every `applied` decision that reaches it. The skill
|
|
68
|
+
globs its own default locations, which this project redirects.
|
|
69
|
+
|
|
70
|
+
## Step 4 — Verify
|
|
71
|
+
|
|
72
|
+
| # | Check | Fails when |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| 1 | Home | Anything outside `.what/_prd/<initiative>/`, or a folder still named `ISI-slug-inisiatif` |
|
|
75
|
+
| 2 | Ids allocated from the registry | `FR-1` restarted, or an id invented in prose |
|
|
76
|
+
| 3 | Every `FR` names its `capability`; every `NFR` names its `goal` | V15 has nothing to check |
|
|
77
|
+
| 4 | Every `FR` has **exactly one** proof of done, in business language | Zero, or a second technical restatement beside it |
|
|
78
|
+
| 5 | Every `NFR` names `enforced_by` | An `NFR` nothing enforces is decoration (V5) |
|
|
79
|
+
| 6 | Cross-Cutting NFRs and Constraints both present | An absent section reads as "not checked" |
|
|
80
|
+
| 7 | No solution shape | A framework, a table, or a transport named in `prd.md` rather than in `addendum.md` |
|
|
81
|
+
| 8 | One Revision History row for this run, written for someone not in the room | Zero rows, several rows, or a row that says "Updated §4.2" |
|
|
82
|
+
| 9 | Memlog at `.control/memlog/prd-<slug>.md`, slug matching the folder | A `.memlog.md` appeared inside `.what/` — `--workspace` was used |
|
|
83
|
+
| 10 | `bmad-review` ran through `doc_standards` on `prd.md` and `addendum.md` | It did not fire |
|
|
84
|
+
|
|
85
|
+
Check 9 MUST be fixed immediately rather than reported. V16 rejects a memlog inside the corpus.
|
|
86
|
+
|
|
87
|
+
## Step 5 — `owns:`, and the collision it prevents
|
|
88
|
+
|
|
89
|
+
A new or changed `FR` that claims write authority over a domain entity MUST be checked against `owns:` in
|
|
90
|
+
`components.yaml`. An entity has exactly one owning Product Component; an `FR` from another PRD that needs to
|
|
91
|
+
change it MUST point at the owner's `FR` rather than promising to write it itself. V21 checks this, and the
|
|
92
|
+
collision has already happened once for real.
|
|
93
|
+
|
|
94
|
+
Report a collision. You MUST NOT resolve it by widening one PRD's claim.
|
|
95
|
+
|
|
96
|
+
## Step 6 — Impact
|
|
97
|
+
|
|
98
|
+
A changed promise changes what other documents can still claim. Check, and **report** — never edit.
|
|
99
|
+
|
|
100
|
+
| Found | Where it goes |
|
|
101
|
+
|---|---|
|
|
102
|
+
| A `UC` realising an `FR` whose promise moved | `wdi-component` intent `behaviour`, or `wdi-blueprint` when the catalogue line itself changes |
|
|
103
|
+
| A blueprint inventory row with nothing promising it any more | `wdi-blueprint` |
|
|
104
|
+
| A contradiction with an `applied` decision | `wdi-decision` — a new `DEC-`, never an edit to one already applied |
|
|
105
|
+
| A component born by this initiative | `wdi-init` intent `component` |
|
|
106
|
+
|
|
107
|
+
Then run the change-control matrix in `delivery-flow-guide.md` and **report** which gates reopen. You MUST
|
|
108
|
+
NOT reopen one yourself.
|
|
109
|
+
|
|
110
|
+
## Rules
|
|
111
|
+
|
|
112
|
+
- You MUST NOT write a second PRD for an area that already has one. The reader test decides, and its answer
|
|
113
|
+
is `update` far more often than it feels.
|
|
114
|
+
- You MUST NOT open G2 on a PRD that has not been through check 10. Gate time is for deciding, not
|
|
115
|
+
proofreading.
|
|
116
|
+
- The gate reads `prd.md` and `EXPERIENCE.md` together. A PRD that passes while the experience side is
|
|
117
|
+
missing has answered half of what G2 decides.
|
|
118
|
+
- Every unresolved `[ASSUMPTION]` MUST be filed through `wdi-question` before the gate opens.
|
|
119
|
+
- You MUST NOT raise `status:`. Status is a stage; the `reviewed:` block is an event, and `wdi-review` writes
|
|
120
|
+
it.
|
|
121
|
+
- When the PRD cannot promise what was asked, say so and stop. Route to `wdi-problem`; do not quietly narrow
|
|
122
|
+
the ask.
|
|
123
|
+
|
|
124
|
+
## Output
|
|
125
|
+
|
|
126
|
+
Intent dispatched · what the promise now is in one line · the result of all ten checks naming the failures ·
|
|
127
|
+
the `owns:` check · impact found and where it was routed · the gates the matrix names · open questions filed.
|
|
File without changes
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wdi-question
|
|
3
|
+
description: Use when something cannot be decided now and must not be silently assumed. Files it into one of four lists in .control/questions/ by what the reader has to do about it, and closes it in place when the answer arrives.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# WDI Question
|
|
7
|
+
|
|
8
|
+
Free of stage and free of role. The purpose is narrow: make sure an unresolved thing is written down
|
|
9
|
+
where it will be seen, instead of becoming an assumption nobody remembers making.
|
|
10
|
+
|
|
11
|
+
The old single list reached `OQ-146` and stopped being readable. It is now four files in
|
|
12
|
+
`.control/questions/`, split by **what the reader has to do about it** — not by subject, and not by
|
|
13
|
+
severity.
|
|
14
|
+
|
|
15
|
+
| File | Holds | Read when |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| `blocking.md` | Holds a gate. Target ≤3 per Product Component | Every gate |
|
|
18
|
+
| `assumptions.md` | An assumption the agent took itself. One line: the assumption plus the cost of being wrong | Swept once per gate; MAY be skipped |
|
|
19
|
+
| `external.md` | Waiting on a file, an action, or a credential from outside. Owner and `by_when` required | Before go-live — **not** at a design gate |
|
|
20
|
+
| `answered.md` | Archive. Closed in place, never deleted | Almost never; only to stop a question being reopened |
|
|
21
|
+
|
|
22
|
+
**Only `blocking.md` holds a gate.** `external.md` holds go-live; `assumptions.md` holds nothing.
|
|
23
|
+
|
|
24
|
+
## The default class is `assumptions.md`
|
|
25
|
+
|
|
26
|
+
A question is filed there unless it passes one of three tests. One is enough:
|
|
27
|
+
|
|
28
|
+
1. It touches money, personal data, or a legal obligation.
|
|
29
|
+
2. It changes the wording of an `FR`'s promise.
|
|
30
|
+
3. Answering it wrong forces a rewrite of more than one Product Component.
|
|
31
|
+
|
|
32
|
+
Failing all three, you MUST take the answer yourself and record it as one line — the assumption, and
|
|
33
|
+
what it costs if it is wrong.
|
|
34
|
+
|
|
35
|
+
**You MUST NOT register a question as blocking "to be safe."** That habit is what produced 146 ids and
|
|
36
|
+
a list nobody read, and the cost is paid at every gate afterwards.
|
|
37
|
+
|
|
38
|
+
## One batch, per gate, already ranked
|
|
39
|
+
|
|
40
|
+
Inside a single working pass you do **not** ask. You collect. The batch is delivered once, at the gate,
|
|
41
|
+
ranked, and it MUST NOT be dribbled out as each question surfaces.
|
|
42
|
+
|
|
43
|
+
A healthy batch on `mode: catalog`: **≤3 blocking questions, plus ≤15 one-line assumptions.** A batch
|
|
44
|
+
larger than that is a signal about the pass, not about the corpus — say so rather than delivering it
|
|
45
|
+
as a list.
|
|
46
|
+
|
|
47
|
+
When N agents ran in parallel, their questions arrive as **one** ranked batch, never as N reports.
|
|
48
|
+
|
|
49
|
+
## Registering
|
|
50
|
+
|
|
51
|
+
| Field | Rule |
|
|
52
|
+
|---|---|
|
|
53
|
+
| Question | One sentence, answerable. "How should referrals work?" is a topic, not a question |
|
|
54
|
+
| Blocks | What cannot proceed — a gate, an `FR`, a story, or nothing |
|
|
55
|
+
| Owner | Who can answer. A question with no owner is a wish |
|
|
56
|
+
| By when | The moment it must be answered, usually a gate |
|
|
57
|
+
|
|
58
|
+
Ids stay `OQ-`, allocated from the highest ever used including closed ones. An id MUST NOT be reused.
|
|
59
|
+
|
|
60
|
+
A question whose discussion outgrows one line gets `.control/questions/OQ-NNN-<slug>.md` in the same
|
|
61
|
+
folder, from `templates/oq.md`, and the list keeps a one-line pointer. The old home
|
|
62
|
+
`.control/supplements/` is gone.
|
|
63
|
+
|
|
64
|
+
## Closing
|
|
65
|
+
|
|
66
|
+
An answered question is closed **in place** — the answer written beside it with the date and who
|
|
67
|
+
answered — then moved to `answered.md`. You MUST NOT delete the entry.
|
|
68
|
+
|
|
69
|
+
If the answer amounts to a decision that is expensive to reverse, the closure MUST route to
|
|
70
|
+
`wdi-decision`. This list records that an answer arrived; a `DEC-` records what was chosen and what it
|
|
71
|
+
cost.
|
|
72
|
+
|
|
73
|
+
## Rules
|
|
74
|
+
|
|
75
|
+
- You MUST NOT answer the question yourself when the owner is the client or a stakeholder. Drafting a
|
|
76
|
+
proposed answer for them to confirm is useful; recording it as settled is not.
|
|
77
|
+
- An `[ASSUMPTION]` tag left in a PRD, an SRS, or an SDD MUST be filed here before that document
|
|
78
|
+
passes its gate. That is precisely the failure this skill exists to prevent.
|
|
79
|
+
- A question past its "by when" MUST be raised, not silently carried forward. Carried forward twice is
|
|
80
|
+
a signal that either the owner is wrong or the question is not real.
|
|
81
|
+
- A row MUST move between files when its class changes, and MUST NOT be copied into a second one. An
|
|
82
|
+
assumption that turns out to touch money moves to `blocking.md`; it does not appear in both.
|
|
83
|
+
- Terms MUST match `.control/product-glossary.md`.
|
|
84
|
+
|
|
85
|
+
## Output
|
|
86
|
+
|
|
87
|
+
Which file each question landed in, the blocking ones ranked, the assumptions as one-line rows, and
|
|
88
|
+
anything routed on to `wdi-decision`.
|
|
File without changes
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wdi-reconcile
|
|
3
|
+
description: Use before a gate, or after a batch of changes, to find drift between .what, .how, and .control — against each other and against the rules in .constitution. Scoped to what the gates already passed have actually produced, and to what each component's mode actually demands. Read-only — it reports, it never edits.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# WDI Reconcile
|
|
7
|
+
|
|
8
|
+
Documents drift apart quietly. An SRS gets amended while its SDD does not; a `DEC-` is accepted and never
|
|
9
|
+
applied; a story ships behaviour the use case never described. None of this shows up as an error, which is
|
|
10
|
+
why it needs a pass that looks for it on purpose.
|
|
11
|
+
|
|
12
|
+
This skill is **read-only**. It MUST NOT edit anything. Its output is a report, and every fix it
|
|
13
|
+
recommends is performed by another skill.
|
|
14
|
+
|
|
15
|
+
## Step 1 — Scope by gate, then by `mode`
|
|
16
|
+
|
|
17
|
+
Two filters, and skipping either produces a report that is red where the plan says it should be.
|
|
18
|
+
|
|
19
|
+
**By gate.** The corpus is built gate by gate, so most of it is legitimately absent most of the time.
|
|
20
|
+
Establish which gate the work stands at — `wdi-help` answers that — and check only what has been passed.
|
|
21
|
+
|
|
22
|
+
| Gate passed | In scope |
|
|
23
|
+
|---|---|
|
|
24
|
+
| G1 | `brief.md` |
|
|
25
|
+
| G2 | + every `_prd/<initiative>/`, UX output wherever it currently sits, `product_components` with `mode` and `risk_accepted` |
|
|
26
|
+
| G3 | + every `.what/<pc>/` § UC Catalogue and § Actor Register, `domain-model.md`, `business-rules.md`, the spine, the C4 set, `containers`, the three inventories |
|
|
27
|
+
| G4 | + whatever each component's `mode` demands in `.what/<pc>/` and `.how/<pc>/` |
|
|
28
|
+
| G5 | + `SPEC.md`, `waves.yaml`, story files, tests, `defects.yaml`, RTM rows |
|
|
29
|
+
|
|
30
|
+
**By `mode`.** An artifact a component's `mode` does not demand MUST NOT be reported as missing. A
|
|
31
|
+
component at `catalog` has an SDD skeleton and no depth, and that is a **finished** state — G4 is skipped
|
|
32
|
+
there. Reporting it as a gap is the failure that would make this pass unusable at the setting most
|
|
33
|
+
projects run.
|
|
34
|
+
|
|
35
|
+
An artifact a **later** gate produces MUST NOT be reported as missing either. That is not drift, it is
|
|
36
|
+
the plan. The corpus running ahead of the code is likewise normal and deliberate.
|
|
37
|
+
|
|
38
|
+
A narrower scope MAY be asked for — one Product Component, one initiative, one layer. State the scope
|
|
39
|
+
in one line before checking, and say what it excluded.
|
|
40
|
+
|
|
41
|
+
## Step 2 — Run the validators first
|
|
42
|
+
|
|
43
|
+
Run `uv run .constitution/scripts/validate.py`, and `uv run .constitution/scripts/inventory.py` when code
|
|
44
|
+
exists. V1–V24 answer everything that can be **counted**, and you MUST NOT re-derive by reading what they
|
|
45
|
+
already report. Carry their findings as they came, then spend the reading on what no validator can see.
|
|
46
|
+
|
|
47
|
+
`.control/generated/` is their output and MUST NOT be read as an independent source. When it is
|
|
48
|
+
missing or stale, say so and name `validate.py --generate` rather than working around it.
|
|
49
|
+
|
|
50
|
+
## Step 3 — What only a reader can find
|
|
51
|
+
|
|
52
|
+
| Direction | Question |
|
|
53
|
+
|---|---|
|
|
54
|
+
| Top-down | Does every `applied` `DEC-` actually appear in the files its `touches` names? |
|
|
55
|
+
| Bottom-up | Does anything in `.how/<pc>/` describe behaviour that `.what/<pc>/` never promised? |
|
|
56
|
+
| Decisions | Is there an `accepted` `DEC-` that was never applied, or an `applied` one with an empty `touches`? The second is V8; the first no validator can see |
|
|
57
|
+
| Chain | `BG → CAP → FR/NFR → UC → story → test` — where does it break? |
|
|
58
|
+
| Depth | Does any document carry more than its component's `mode` demands? Over-writing is drift too, and it is the direction nobody looks for |
|
|
59
|
+
| Vocabulary | Does any document use a domain noun that `.control/product-glossary.md` does not define, or a synonym for one it does? Detect against the rule in `wdi-blueprint`; MUST NOT keep a second rule here |
|
|
60
|
+
| Registry | Does `components.yaml` still describe what the corpus contains — a `<pc>` folder with no entry, an `LC` with no prose in the slot its `type` names, a container in the C4 set but not in `containers`, `owns:` claiming an entity another component also claims |
|
|
61
|
+
| Inventory | Do the three inventories still match the code? `inventory.py` answers it; carry its findings rather than re-deriving them |
|
|
62
|
+
| **Constitution** | Does an artifact break the rule its own guide states? |
|
|
63
|
+
| **Homeless output** | Does anything in `_bmad-output/` have no row in the ownership table in `corpus-guide.md`, or a row whose named owner is not installed? |
|
|
64
|
+
| **Evidence** | V24 answers the mechanical half — does every cited path still resolve. What is left for a reader: does the file still **contain** what is cited |
|
|
65
|
+
|
|
66
|
+
The chain check overlaps the validators on purpose. Validators answer what can be counted; this pass
|
|
67
|
+
answers what has to be read — a `UC` that exists and is wrong passes V2 and fails here.
|
|
68
|
+
|
|
69
|
+
### The Constitution check
|
|
70
|
+
|
|
71
|
+
The other checks compare documents with each other. This one compares a document with the rule that
|
|
72
|
+
governs it, and the four failures worth looking for are the ones no ID chain records:
|
|
73
|
+
|
|
74
|
+
| Looks like | Rule it breaks |
|
|
75
|
+
|---|---|
|
|
76
|
+
| Solution shape in `.what/` — a table, an endpoint, a framework | `corpus-guide.md`, and it is the most common one |
|
|
77
|
+
| A promise appearing first in `.how/` | The same rule, in the other direction |
|
|
78
|
+
| A file in the wrong slot | `.what/` numbers are reading order, `.how/` numbers are ABCE classification |
|
|
79
|
+
| A layer written by a skill that does not own it | The ownership table in `corpus-guide.md` |
|
|
80
|
+
| A rule stated in a `.constitution/method/` file | `status: Reference` — it explains, it MUST NOT bind |
|
|
81
|
+
| A `Reference` file contradicting a guide | The guide wins, and the contradiction is a defect to report |
|
|
82
|
+
|
|
83
|
+
You MUST NOT invent a rule to fail an artifact against. Every finding here MUST quote the guide it comes
|
|
84
|
+
from. A file at `status: Draft` MAY be read as guidance but MUST NOT be used to reject anything — that
|
|
85
|
+
holds for all three `codebase/*-guide.md` — and a file at `status: Reference` MUST NOT be cited to reject
|
|
86
|
+
anything at all.
|
|
87
|
+
|
|
88
|
+
### What the Evidence check is, and what it is not
|
|
89
|
+
|
|
90
|
+
It checks whether **citations still resolve**. It does **not** check whether the code implements the
|
|
91
|
+
corpus, and you MUST NOT widen it into that.
|
|
92
|
+
|
|
93
|
+
A general corpus-versus-code comparison would be red through the middle of every wave, and a check
|
|
94
|
+
that is always red is a check people learn to skip. What is already covered elsewhere MUST NOT be
|
|
95
|
+
re-reported here:
|
|
96
|
+
|
|
97
|
+
| Already answered by | Case |
|
|
98
|
+
|---|---|
|
|
99
|
+
| A red RTM row | Promised, not built yet |
|
|
100
|
+
| V2 · V3 | Documented, never scheduled |
|
|
101
|
+
| V4 | A story closed with no named test |
|
|
102
|
+
| `inventory.py` | The plan and the code disagreeing about a table, endpoint, or screen |
|
|
103
|
+
|
|
104
|
+
That leaves exactly one gap, and it is the one this check fills: **a descriptive claim about code
|
|
105
|
+
that already exists, which has quietly stopped being true.** A file renamed, a function removed, a
|
|
106
|
+
route unregistered — nothing in the ID chain moves, so no validator can see it.
|
|
107
|
+
|
|
108
|
+
Two properties keep the check healthy:
|
|
109
|
+
|
|
110
|
+
- It fires **only where a citation exists**. Prose with no cited source produces no finding, so there
|
|
111
|
+
is no flood.
|
|
112
|
+
- It is cheap: a path and symbol lookup, not a semantic judgement.
|
|
113
|
+
|
|
114
|
+
A claim the check proves absent MUST be labelled `[MISSING]` in the document rather than deleted —
|
|
115
|
+
see the evidence ladder in `sdd-guide.md`, which owns that rule.
|
|
116
|
+
|
|
117
|
+
## Output — an action matrix
|
|
118
|
+
|
|
119
|
+
Each finding gets four fields, and the last two are what make the report usable:
|
|
120
|
+
|
|
121
|
+
| Field | Content |
|
|
122
|
+
|---|---|
|
|
123
|
+
| What | The drift, stated concretely with both sides quoted |
|
|
124
|
+
| Where | File and section on each side |
|
|
125
|
+
| Which is right | Your reading, stated as a judgement, not hidden as a fact |
|
|
126
|
+
| Who fixes it | The skill that owns the layer needing the change — `wdi-problem` · `wdi-product` · `wdi-blueprint` · `wdi-component` · `wdi-ux` · `wdi-build` · `wdi-init` · `wdi-decision` · `wdi-question` · `wdi-log` · `wdi-systematic-debugging` · a human |
|
|
127
|
+
|
|
128
|
+
A finding you cannot assign to a fixer MUST be reported as an open question rather than left as an
|
|
129
|
+
observation.
|
|
130
|
+
|
|
131
|
+
Separate **drift** from **conflict** in the report, because they are answered differently: drift has
|
|
132
|
+
a right side and needs carrying across; a conflict has no clearly right side and needs deciding.
|
|
133
|
+
|
|
134
|
+
## Rules
|
|
135
|
+
|
|
136
|
+
- You MUST NOT edit. Not a typo, not a heading, not a link. The value of a read-only pass is that its
|
|
137
|
+
report can be trusted to describe the state before anything moved.
|
|
138
|
+
- You MUST NOT rank a finding as minor because it is small. Vocabulary drift is small and is the one
|
|
139
|
+
that compounds fastest.
|
|
140
|
+
- When two documents disagree and neither is clearly right, that is a decision, not a drift. Route it
|
|
141
|
+
to `wdi-decision` and say so.
|
|
142
|
+
- An output with no home MUST be reported as a gap in the method, and its home MUST NOT be guessed. The
|
|
143
|
+
gap has nowhere else to surface. Exploration output — research, brainstorming, forge, PRFAQ — is
|
|
144
|
+
homeless **by rule** and MUST NOT be reported.
|
|
145
|
+
- Run before every gate, and after any batch of edits that touched one layer without the other.
|
|
146
|
+
Running it only when something feels wrong defeats it — drift is silent by definition.
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wdi-report
|
|
3
|
+
description: Use when someone needs numbers about this project — progress for a client update, an estimate before the work is committed, or task rows ready to paste into a tracker. Three intents, progress and estimate and dispatch. Never invents a number.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# WDI Report
|
|
7
|
+
|
|
8
|
+
Three intents, and the first is deliberately fenced off from the other two **because their rules are opposite**.
|
|
9
|
+
|
|
10
|
+
| Intent | Answers | Rule |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| `progress` | What has moved, what is late, how much is proven | **Entirely derived.** MUST NOT write one number, date, or percentage that did not come from the registry or from git |
|
|
13
|
+
| `estimate` | How big this is, what the tasks are, how much load, what the timeline looks like | **Forward-facing.** MUST state which inputs exist and how precise that makes it, and MUST be labelled an estimate |
|
|
14
|
+
| `dispatch` | Task rows ready for an outside tracker | Reads the same table as `estimate`; recomputes nothing |
|
|
15
|
+
|
|
16
|
+
Confusing the first two is the failure this split exists to prevent: a forward-looking figure presented in the
|
|
17
|
+
voice of a derived one is the most expensive kind of wrong.
|
|
18
|
+
|
|
19
|
+
## What owns what
|
|
20
|
+
|
|
21
|
+
| Owner | Produces |
|
|
22
|
+
|---|---|
|
|
23
|
+
| `.constitution/scripts/validate.py` | `generated/rtm` · `dag` · `status` · `risks` · `components` · `decisions` · `blueprint` · `estimate` |
|
|
24
|
+
| `.constitution/scripts/timeline.py` | `generated/timeline` · `generated/report` · `.control/reports/<period>.md` |
|
|
25
|
+
| `.constitution/scripts/inventory.py` | The three inventories, derived from code |
|
|
26
|
+
| `wdi-reconcile` | Drift between corpus and registry — read-only, no file |
|
|
27
|
+
| **this skill** | The judgment on top: whether the tables are fresh enough to report on, and the human commentary written at publish time |
|
|
28
|
+
|
|
29
|
+
All three scripts are deterministic and already written. You MUST NOT hand-derive anything they produce, and you
|
|
30
|
+
MUST NOT write into `generated/` yourself. Your job starts where their output stops being self-explanatory.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
# Intent `progress`
|
|
35
|
+
|
|
36
|
+
## Step 1 — Refresh, or refuse
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
uv run .constitution/scripts/timeline.py --refresh --generate
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`--refresh` runs the validators first, so both halves of `generated/` are derived at the same commit. Read what
|
|
43
|
+
it prints before reading anything else:
|
|
44
|
+
|
|
45
|
+
| What it says | What you MUST do |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `rtm/status belum ada` (exit 3) | Stop. The tables cannot be built, so there is nothing honest to report |
|
|
48
|
+
| `git tidak menjawab` (exit 3) | Stop. Every actual date comes from git; without it there is no time dimension |
|
|
49
|
+
| `registry punya perubahan yang belum dicommit` | Say so in the report header. The numbers describe a working tree, not `main` |
|
|
50
|
+
| `story tanpa riwayat git` | Name those stories. They count toward progres janji but cannot appear under Proven |
|
|
51
|
+
| `n temuan validator` | Report the count and, if any are red, say which gate they block |
|
|
52
|
+
|
|
53
|
+
A report built on stale tables is worse than no report: it looks authoritative and is not.
|
|
54
|
+
|
|
55
|
+
## Step 2 — Read the derived time dimension
|
|
56
|
+
|
|
57
|
+
You MUST NOT derive dates yourself. `timeline.py` reads each story file's history and takes the first commit whose
|
|
58
|
+
frontmatter status left `draft` as the start, and the commit where it became `done` as the end. `FR` spans its
|
|
59
|
+
stories; `CAP` spans its `FR`, and closes only when every story under it is closed.
|
|
60
|
+
|
|
61
|
+
None of this is written back into any registry. A stored copy would be a second home for one fact, and the stored
|
|
62
|
+
copy is the one that goes wrong.
|
|
63
|
+
|
|
64
|
+
## Step 3 — Read `generated/timeline` and `generated/report`
|
|
65
|
+
|
|
66
|
+
`timeline` gives one row per `CAP`, plan beside actual, plus a gantt. `state` is `not-started`, `in-progress`,
|
|
67
|
+
`done`, or **`overdue`** — the last being V14.
|
|
68
|
+
|
|
69
|
+
You MUST list every overdue row **by name**, with what it is waiting on. The script prints them individually for
|
|
70
|
+
the same reason: aggregating them into a count is how a slipping plan stays comfortable.
|
|
71
|
+
|
|
72
|
+
`report` gives five composed sections covering the span since the last published report: **Proven** (RTM rows that
|
|
73
|
+
turned green, named) · **Moved** (`CAP` and `FR` that started or closed) · **Late** · **Defects** (grouped by
|
|
74
|
+
`root_cause`) · **Gates** (dated from the history of `index.yaml`).
|
|
75
|
+
|
|
76
|
+
Section 4 grouped by root cause is worth reading twice: it answers how many defects were a wrong requirement rather
|
|
77
|
+
than wrong code, and that ratio is a fact about the method, not about the team.
|
|
78
|
+
|
|
79
|
+
The left edge is the `asof` of the newest published report. When there is none, the script says the period is
|
|
80
|
+
unbounded on the left, and you MUST repeat that rather than picking a date.
|
|
81
|
+
|
|
82
|
+
## Step 4 — Publish
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
uv run .constitution/scripts/timeline.py --publish weekly
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
A published report is **frozen**. It states what was true on a date, exactly like minutes. The script refuses to
|
|
89
|
+
overwrite one (exit 4) rather than trusting anyone to remember.
|
|
90
|
+
|
|
91
|
+
- You MUST NOT edit a published report. If it was wrong, the next report says so.
|
|
92
|
+
- The `## Catatan` block is the one part a person writes, once, at publish time, before the commit.
|
|
93
|
+
- Commentary MUST cite rather than restate: a slip has a cause, and that cause already lives in a `DEC-`, an
|
|
94
|
+
`OQ-`, a risk, or a defect.
|
|
95
|
+
|
|
96
|
+
## Step 5 — Lead with the honest number
|
|
97
|
+
|
|
98
|
+
| Measure | Formula | Answers |
|
|
99
|
+
|---|---|---|
|
|
100
|
+
| **Progres janji** | green RTM rows ÷ total RTM rows | How much is **proven** |
|
|
101
|
+
| Progres kerja | stories `done` ÷ stories in wave | How much was worked on |
|
|
102
|
+
| Kesiapan gate | green validators ÷ applicable validators | Whether the next gate can open |
|
|
103
|
+
|
|
104
|
+
You MUST present **progres janji** first and label it as the one that counts. Progres kerja MUST NOT lead a
|
|
105
|
+
client-facing report: a story can be `done` while its RTM row is still red because the test has no name or the `UC`
|
|
106
|
+
does not exist — and that gap is exactly what the client is entitled to know.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
# Intent `estimate`
|
|
111
|
+
|
|
112
|
+
**It runs as early as G1, and sharpens every time an input arrives.** That is what makes it useful for sizing a
|
|
113
|
+
project before there is a line of code.
|
|
114
|
+
|
|
115
|
+
## Step 1 — State the input, and the precision it buys
|
|
116
|
+
|
|
117
|
+
You MUST say which of these exist and stop at the honest level. Claiming precision the inputs do not support is the
|
|
118
|
+
one thing this intent can get badly wrong.
|
|
119
|
+
|
|
120
|
+
| Input available | What can be estimated | Precision |
|
|
121
|
+
|---|---|---|
|
|
122
|
+
| **G1** — the brief | T-shirt size · rough capability count · the first risk list | very rough |
|
|
123
|
+
| **+ G2** — the PRD | **The candidate task list = the `FR` list** · `estimate_mandays` per `CAP` · `must/should/could/wont` · order from `depends_on` between `CAP` | rough |
|
|
124
|
+
| **+ tail of G2** — components born | Tasks grouped per component = per Epic · **`mode` per component, so document load is counted too** · `risk_accepted` marks exposure | medium |
|
|
125
|
+
| **+ G3** — the blueprint | Table, endpoint, and screen counts → real implementation load, not load guessed from an `FR` count | good |
|
|
126
|
+
| **+ G4** — component depth | Stories and test names → measured load | best |
|
|
127
|
+
|
|
128
|
+
## Step 2 — Inputs
|
|
129
|
+
|
|
130
|
+
`requirements.yaml` (`estimate_mandays`, `priority`, `depends_on`, `target_release`) · `components.yaml` (`mode`,
|
|
131
|
+
`risk_accepted`, `risk_note`) · the three `inventory-*.md` when they exist.
|
|
132
|
+
|
|
133
|
+
`estimate_mandays` on `CAP` is the **source**, and it is used for real here rather than being decoration. When it is
|
|
134
|
+
absent, say so — an estimate with no mandays input is a T-shirt size, and it MUST be reported as one.
|
|
135
|
+
|
|
136
|
+
## Step 3 — The output: one task table
|
|
137
|
+
|
|
138
|
+
Written to `.control/generated/estimate.md` by `validate.py --generate`. **Default one row per `FR`**, because that
|
|
139
|
+
is the ideal shape of a wave and because an `FR` has had a proof of done since birth.
|
|
140
|
+
|
|
141
|
+
| Column | Content |
|
|
142
|
+
|---|---|
|
|
143
|
+
| Task | The title, from the `FR` |
|
|
144
|
+
| `FR` | Its id |
|
|
145
|
+
| Epic | The Product Component |
|
|
146
|
+
| `mode` | That component's depth — this is what makes document load visible |
|
|
147
|
+
| Paparan | `risk_accepted` + `risk_note` |
|
|
148
|
+
| Beban | Mandays, derived from the parent `CAP`'s `estimate_mandays`, divided among its `FR` |
|
|
149
|
+
| Prioritas | From the `CAP` |
|
|
150
|
+
| Bergantung pada | From `depends_on` |
|
|
151
|
+
| Rilis | The `CAP`'s `target_release` |
|
|
152
|
+
|
|
153
|
+
## Step 4 — Say what it is, and what it is not
|
|
154
|
+
|
|
155
|
+
> A row in the estimate table is a **candidate** task. A wave in `waves.yaml` is a **real** one. The first missing
|
|
156
|
+
> is normal; the second is not.
|
|
157
|
+
|
|
158
|
+
The table is planning, not commitment. One row MAY become one wave, and three neighbouring rows MAY be merged into
|
|
159
|
+
one. **That merge is a human decision made when the wave opens**, and this intent MUST NOT pretend to already know
|
|
160
|
+
the answer.
|
|
161
|
+
|
|
162
|
+
- Every output MUST carry the word estimate, visibly, at the top.
|
|
163
|
+
- You MUST NOT present a mandays figure without naming what it was derived from.
|
|
164
|
+
- You MUST NOT include a date this intent computed itself. Plan dates come from `planned_end` on a `CAP`; where
|
|
165
|
+
there is none, the timeline is stated in sequence and dependency, not in dates.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
# Intent `dispatch`
|
|
170
|
+
|
|
171
|
+
Reads `.control/generated/estimate.md` and `waves.yaml`. **It recomputes nothing.**
|
|
172
|
+
|
|
173
|
+
It emits rows in a form that can be pasted into an outside tracker: Epic (the Product Component), Task (the wave, or
|
|
174
|
+
the candidate row where no wave exists yet), Sub-task (the story, where one exists), labels for `FR` and `CAP`, and
|
|
175
|
+
Fix Version from the release.
|
|
176
|
+
|
|
177
|
+
- Output goes **to the screen**. This intent MUST NOT write a file, and MUST NOT write to the tracker — entering it
|
|
178
|
+
is a human act.
|
|
179
|
+
- The corpus never reads back from the tracker. **The corpus is the source of truth; the tracker is a view.**
|
|
180
|
+
- A row whose Task is still a candidate MUST be marked as one. A candidate pasted as a real Task is how a tracker
|
|
181
|
+
fills with issues nobody committed to.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Rules
|
|
186
|
+
|
|
187
|
+
- You MUST NOT invent progress. When a table is missing or stale, name it and stop.
|
|
188
|
+
- You MUST NOT report `progress` in stories. The planning layer speaks in `CAP`, `FR`, and defects; stories are the
|
|
189
|
+
execution layer and are born too late to plan against.
|
|
190
|
+
- You MUST NOT hand-write anything under `generated/`. There is no exception.
|
|
191
|
+
- You MUST NOT re-run `--publish` to "fix" a report. The refusal is the rule working.
|
|
192
|
+
- When plan dates have moved since the last report, you MUST say so and point at the commit.
|
|
193
|
+
- When there is no previous report, say the period is unbounded on the left rather than picking a date.
|
|
194
|
+
- You MUST NOT mix the intents in one output. A derived number and a forward-looking one MUST NOT appear in the same
|
|
195
|
+
table without the labels that separate them.
|
|
196
|
+
|
|
197
|
+
## Output
|
|
198
|
+
|
|
199
|
+
**`progress`:** the published path, the freshness commit, progres janji, then the five sections — overdue rows named
|
|
200
|
+
individually, never counted away.
|
|
201
|
+
|
|
202
|
+
**`estimate`:** which inputs exist and the precision that buys, the task table, and what is a candidate rather than
|
|
203
|
+
a commitment.
|
|
204
|
+
|
|
205
|
+
**`dispatch`:** the paste-ready rows, on screen, with candidates marked.
|