wdi-method 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +203 -0
  3. package/bin/wdi-method.js +906 -0
  4. package/kit/.constitution/README.md +66 -0
  5. package/kit/.constitution/codebase/brownfield-guide.md +18 -0
  6. package/kit/.constitution/codebase/conventions-guide.md +18 -0
  7. package/kit/.constitution/codebase/stack-guide.md +18 -0
  8. package/kit/.constitution/constitution.md +135 -0
  9. package/kit/.constitution/document/architecture-guide.md +209 -0
  10. package/kit/.constitution/document/bmad-guide.md +151 -0
  11. package/kit/.constitution/document/bmad-skill-register.md +71 -0
  12. package/kit/.constitution/document/brief-guide.md +94 -0
  13. package/kit/.constitution/document/corpus-guide.md +341 -0
  14. package/kit/.constitution/document/decision-guide.md +134 -0
  15. package/kit/.constitution/document/delivery-flow-guide.md +338 -0
  16. package/kit/.constitution/document/prd-guide.md +202 -0
  17. package/kit/.constitution/document/sdd-guide.md +206 -0
  18. package/kit/.constitution/document/srs-guide.md +147 -0
  19. package/kit/.constitution/document/templates/addendum.md +71 -0
  20. package/kit/.constitution/document/templates/architecture-spine.md +100 -0
  21. package/kit/.constitution/document/templates/brief.md +110 -0
  22. package/kit/.constitution/document/templates/c4.md +77 -0
  23. package/kit/.constitution/document/templates/contract.md +52 -0
  24. package/kit/.constitution/document/templates/cross-cutting.md +80 -0
  25. package/kit/.constitution/document/templates/decision.md +64 -0
  26. package/kit/.constitution/document/templates/design-system.md +67 -0
  27. package/kit/.constitution/document/templates/flow.md +51 -0
  28. package/kit/.constitution/document/templates/integration.md +69 -0
  29. package/kit/.constitution/document/templates/inventory.md +69 -0
  30. package/kit/.constitution/document/templates/lc.md +47 -0
  31. package/kit/.constitution/document/templates/lifecycle.md +52 -0
  32. package/kit/.constitution/document/templates/meeting.md +47 -0
  33. package/kit/.constitution/document/templates/model.md +55 -0
  34. package/kit/.constitution/document/templates/oq.md +45 -0
  35. package/kit/.constitution/document/templates/prd.md +226 -0
  36. package/kit/.constitution/document/templates/questions.md +75 -0
  37. package/kit/.constitution/document/templates/rtr.md +61 -0
  38. package/kit/.constitution/document/templates/rules.md +47 -0
  39. package/kit/.constitution/document/templates/scn.md +40 -0
  40. package/kit/.constitution/document/templates/sdd.md +146 -0
  41. package/kit/.constitution/document/templates/srs.md +149 -0
  42. package/kit/.constitution/document/templates/structure-codebase.md +129 -0
  43. package/kit/.constitution/document/templates/structure-document.md +90 -0
  44. package/kit/.constitution/document/templates/uc.md +69 -0
  45. package/kit/.constitution/document/templates/ux.md +77 -0
  46. package/kit/.constitution/document/ux-guide.md +99 -0
  47. package/kit/.constitution/language-guide.md +69 -0
  48. package/kit/.constitution/method/README.md +169 -0
  49. package/kit/.constitution/method/artifact-map.md +155 -0
  50. package/kit/.constitution/method/portability.md +91 -0
  51. package/kit/.constitution/method/rationale.md +246 -0
  52. package/kit/.constitution/method-glossary.md +169 -0
  53. package/kit/.constitution/project/README.md +68 -0
  54. package/kit/.constitution/repo-guide.md +97 -0
  55. package/kit/.constitution/scripts/inventory.py +527 -0
  56. package/kit/.constitution/scripts/timeline.py +665 -0
  57. package/kit/.constitution/scripts/validate.py +1579 -0
  58. package/kit/.constitution/structure-guide.md +202 -0
  59. package/kit/assets/bmad-custom/bmad-advanced-elicitation.toml +15 -0
  60. package/kit/assets/bmad-custom/bmad-architecture.toml +31 -0
  61. package/kit/assets/bmad-custom/bmad-build-auto.toml +10 -0
  62. package/kit/assets/bmad-custom/bmad-build.toml +52 -0
  63. package/kit/assets/bmad-custom/bmad-code-review.toml +12 -0
  64. package/kit/assets/bmad-custom/bmad-correct-course.toml +27 -0
  65. package/kit/assets/bmad-custom/bmad-deep-recon.toml +11 -0
  66. package/kit/assets/bmad-custom/bmad-prd.toml +42 -0
  67. package/kit/assets/bmad-custom/bmad-product-brief.toml +34 -0
  68. package/kit/assets/bmad-custom/bmad-retrospective.toml +9 -0
  69. package/kit/assets/bmad-custom/bmad-spec.toml +15 -0
  70. package/kit/assets/bmad-custom/bmad-ux.toml +19 -0
  71. package/kit/assets/bmad-custom/config.toml +6 -0
  72. package/kit/skills/wdi-blueprint/SKILL.md +203 -0
  73. package/kit/skills/wdi-build/SKILL.md +244 -0
  74. package/kit/skills/wdi-component/SKILL.md +172 -0
  75. package/kit/skills/wdi-decision/.gitkeep +0 -0
  76. package/kit/skills/wdi-decision/SKILL.md +183 -0
  77. package/kit/skills/wdi-help/.gitkeep +0 -0
  78. package/kit/skills/wdi-help/SKILL.md +98 -0
  79. package/kit/skills/wdi-init/SKILL.md +149 -0
  80. package/kit/skills/wdi-log/SKILL.md +107 -0
  81. package/kit/skills/wdi-problem/SKILL.md +90 -0
  82. package/kit/skills/wdi-product/SKILL.md +127 -0
  83. package/kit/skills/wdi-question/.gitkeep +0 -0
  84. package/kit/skills/wdi-question/SKILL.md +88 -0
  85. package/kit/skills/wdi-reconcile/.gitkeep +0 -0
  86. package/kit/skills/wdi-reconcile/SKILL.md +146 -0
  87. package/kit/skills/wdi-report/SKILL.md +205 -0
  88. package/kit/skills/wdi-review/SKILL.md +118 -0
  89. package/kit/skills/wdi-systematic-debugging/SKILL.md +193 -0
  90. package/kit/skills/wdi-systematic-debugging/references/condition-based-waiting.md +115 -0
  91. package/kit/skills/wdi-systematic-debugging/references/defense-in-depth.md +122 -0
  92. package/kit/skills/wdi-systematic-debugging/references/find-polluter.sh +72 -0
  93. package/kit/skills/wdi-systematic-debugging/references/root-cause-tracing.md +169 -0
  94. package/kit/skills/wdi-ux/SKILL.md +145 -0
  95. package/kit-overlay/AGENTS.md +196 -0
  96. package/kit-overlay/README.md +66 -0
  97. package/kit-overlay/constitution.md +135 -0
  98. package/kit-overlay/portability.md +91 -0
  99. package/kit-overlay/repo-guide.md +97 -0
  100. package/lib/agents-block.mjs +52 -0
  101. package/lib/identity.mjs +65 -0
  102. package/package.json +37 -0
  103. package/scaffold/.control/decisions/.gitkeep +0 -0
  104. package/scaffold/.control/generated/.gitkeep +2 -0
  105. package/scaffold/.control/meetings/.gitkeep +0 -0
  106. package/scaffold/.control/memlog/.gitkeep +0 -0
  107. package/scaffold/.control/product-glossary.md +21 -0
  108. package/scaffold/.control/project-non-technical-log.md +23 -0
  109. package/scaffold/.control/questions/answered.md +11 -0
  110. package/scaffold/.control/questions/assumptions.md +15 -0
  111. package/scaffold/.control/questions/blocking.md +21 -0
  112. package/scaffold/.control/questions/external.md +11 -0
  113. package/scaffold/.control/registry/components.yaml +21 -0
  114. package/scaffold/.control/registry/decisions.yaml +6 -0
  115. package/scaffold/.control/registry/defects.yaml +3 -0
  116. package/scaffold/.control/registry/index.yaml +46 -0
  117. package/scaffold/.control/registry/requirements.yaml +15 -0
  118. package/scaffold/.control/registry/risks.yaml +5 -0
  119. package/scaffold/.control/registry/usecases.yaml +6 -0
  120. package/scaffold/.control/registry/waves.yaml +5 -0
  121. package/scaffold/.control/structure-codebase.md +19 -0
  122. package/scaffold/.control/structure-document.md +25 -0
@@ -0,0 +1,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.