wdi-method 0.4.6 → 0.5.2

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 (87) hide show
  1. package/README.md +271 -252
  2. package/bin/wdi-method.js +1221 -1030
  3. package/kit/.constitution/method/README.md +73 -169
  4. package/kit/.constitution/{constitution.md → method/constitution.md} +10 -56
  5. package/kit/.constitution/{document → method/document}/architecture-guide.md +209 -209
  6. package/kit/.constitution/{document → method/document}/corpus-guide.md +4 -4
  7. package/kit/.constitution/{document → method/document}/delivery-flow-guide.md +338 -338
  8. package/kit/.constitution/{document → method/document}/sdd-guide.md +1 -1
  9. package/kit/.constitution/{document → method/document}/templates/cross-cutting.md +2 -2
  10. package/kit/.constitution/{document → method/document}/templates/design-system.md +67 -67
  11. package/kit/.constitution/{document → method/document}/templates/inventory.md +69 -69
  12. package/kit/.constitution/{document → method/document}/templates/sdd.md +1 -1
  13. package/kit/.constitution/{document → method/document}/templates/structure-codebase.md +129 -129
  14. package/kit/.constitution/{document → method/document}/templates/structure-document.md +90 -90
  15. package/kit/.constitution/{language-guide.md → method/language-guide.md} +2 -2
  16. package/kit/.constitution/{method-glossary.md → method/method-glossary.md} +169 -169
  17. package/kit/.constitution/{repo-guide.md → method/repo-guide.md} +120 -97
  18. package/kit/.constitution/method/scripts/__pycache__/validate.cpython-314.pyc +0 -0
  19. package/kit/.constitution/{scripts → method/scripts}/timeline.py +2 -2
  20. package/kit/.constitution/{scripts → method/scripts}/validate.py +1648 -1581
  21. package/kit/.constitution/{structure-guide.md → method/structure-guide.md} +3 -3
  22. package/kit/.constitution/method/why/README.md +169 -0
  23. package/kit/.constitution/method/{artifact-map.md → why/artifact-map.md} +5 -5
  24. package/kit/.constitution/method/{portability.md → why/portability.md} +6 -6
  25. package/kit/.constitution/method/{rationale.md → why/rationale.md} +5 -5
  26. package/kit/.constitution/project/README.md +68 -68
  27. package/kit/.constitution/project/constitution.md +64 -0
  28. package/kit/assets/bmad-custom/bmad-advanced-elicitation.toml +15 -15
  29. package/kit/assets/bmad-custom/bmad-architecture.toml +33 -33
  30. package/kit/assets/bmad-custom/bmad-code-review.toml +13 -13
  31. package/kit/assets/bmad-custom/bmad-correct-course.toml +28 -28
  32. package/kit/assets/bmad-custom/bmad-prd.toml +42 -42
  33. package/kit/assets/bmad-custom/bmad-product-brief.toml +34 -34
  34. package/kit/assets/bmad-custom/bmad-retrospective.toml +9 -9
  35. package/kit/assets/bmad-custom/bmad-spec.toml +16 -16
  36. package/kit/assets/bmad-custom/bmad-ux.toml +19 -19
  37. package/kit/skills/wdi-blueprint/SKILL.md +203 -203
  38. package/kit/skills/wdi-build/SKILL.md +244 -244
  39. package/kit/skills/wdi-component/SKILL.md +1 -1
  40. package/kit/skills/wdi-help/SKILL.md +98 -98
  41. package/kit/skills/wdi-init/SKILL.md +1 -1
  42. package/kit/skills/wdi-problem/SKILL.md +90 -90
  43. package/kit/skills/wdi-product/SKILL.md +127 -127
  44. package/kit/skills/wdi-reconcile/SKILL.md +2 -2
  45. package/kit/skills/wdi-report/SKILL.md +205 -205
  46. package/kit/skills/wdi-systematic-debugging/SKILL.md +193 -193
  47. package/kit/skills/wdi-ux/SKILL.md +145 -145
  48. package/kit-overlay/AGENTS.md +215 -212
  49. package/kit-overlay/README.md +24 -17
  50. package/kit-overlay/constitution.md +10 -56
  51. package/kit-overlay/portability.md +6 -6
  52. package/kit-overlay/repo-guide.md +120 -97
  53. package/package.json +4 -2
  54. package/scaffold/.control/questions/blocking.md +1 -1
  55. package/kit/.constitution/README.md +0 -66
  56. /package/kit/.constitution/{document → method/document}/bmad-guide.md +0 -0
  57. /package/kit/.constitution/{document → method/document}/bmad-skill-register.md +0 -0
  58. /package/kit/.constitution/{document → method/document}/brief-guide.md +0 -0
  59. /package/kit/.constitution/{document → method/document}/decision-guide.md +0 -0
  60. /package/kit/.constitution/{document → method/document}/prd-guide.md +0 -0
  61. /package/kit/.constitution/{document → method/document}/srs-guide.md +0 -0
  62. /package/kit/.constitution/{document → method/document}/templates/addendum.md +0 -0
  63. /package/kit/.constitution/{document → method/document}/templates/architecture-spine.md +0 -0
  64. /package/kit/.constitution/{document → method/document}/templates/brief.md +0 -0
  65. /package/kit/.constitution/{document → method/document}/templates/c4.md +0 -0
  66. /package/kit/.constitution/{document → method/document}/templates/contract.md +0 -0
  67. /package/kit/.constitution/{document → method/document}/templates/decision.md +0 -0
  68. /package/kit/.constitution/{document → method/document}/templates/flow.md +0 -0
  69. /package/kit/.constitution/{document → method/document}/templates/integration.md +0 -0
  70. /package/kit/.constitution/{document → method/document}/templates/lc.md +0 -0
  71. /package/kit/.constitution/{document → method/document}/templates/lifecycle.md +0 -0
  72. /package/kit/.constitution/{document → method/document}/templates/meeting.md +0 -0
  73. /package/kit/.constitution/{document → method/document}/templates/model.md +0 -0
  74. /package/kit/.constitution/{document → method/document}/templates/oq.md +0 -0
  75. /package/kit/.constitution/{document → method/document}/templates/prd.md +0 -0
  76. /package/kit/.constitution/{document → method/document}/templates/questions.md +0 -0
  77. /package/kit/.constitution/{document → method/document}/templates/rtr.md +0 -0
  78. /package/kit/.constitution/{document → method/document}/templates/rules.md +0 -0
  79. /package/kit/.constitution/{document → method/document}/templates/scn.md +0 -0
  80. /package/kit/.constitution/{document → method/document}/templates/srs.md +0 -0
  81. /package/kit/.constitution/{document → method/document}/templates/uc.md +0 -0
  82. /package/kit/.constitution/{document → method/document}/templates/ux.md +0 -0
  83. /package/kit/.constitution/{document → method/document}/ux-guide.md +0 -0
  84. /package/kit/.constitution/{scripts → method/scripts}/inventory.py +0 -0
  85. /package/kit/.constitution/{codebase/brownfield-guide.md → project/codebase-brownfield-guide.md} +0 -0
  86. /package/kit/.constitution/{codebase/conventions-guide.md → project/codebase-conventions-guide.md} +0 -0
  87. /package/kit/.constitution/{codebase/stack-guide.md → project/codebase-stack-guide.md} +0 -0
@@ -1,193 +1,193 @@
1
- ---
2
- name: wdi-systematic-debugging
3
- description: Use when encountering any bug, test failure, build failure, or unexpected behavior, before proposing any fix. Covers root-cause investigation, hypothesis testing, and the escalation rule when repeated fixes fail.
4
- ---
5
-
6
- # Systematic Debugging
7
-
8
- BMad has no debugging workflow — `bmad-build` assumes you already know what to build. This skill
9
- covers the gap: something is broken and the cause is unknown.
10
-
11
- ## The Iron Law
12
-
13
- **NO FIX WITHOUT ROOT CAUSE INVESTIGATION FIRST.**
14
-
15
- You MUST complete Phase 1 before proposing any fix. A fix that treats a symptom is a failure even
16
- when the symptom disappears.
17
-
18
- ## When to use
19
-
20
- Use for any technical issue: test failure, production bug, unexpected behavior, performance problem,
21
- build failure, integration failure.
22
-
23
- **Its home is G5, but its trigger is not positional.** Most invocations happen while coding, and
24
- that is why `AGENTS.md`, `bmad-build`, and the ship-story orchestration carry this rule in their
25
- worker context. What actually fires it is a pair of conditions — *something is broken* **and** *the
26
- cause is unknown* — so it MAY be invoked in any stage, by anyone, to investigate: a red
27
- `validate.py` while writing an SRS at G3, a `wdi-reconcile` report that makes no sense, a
28
- generator producing an empty timeline. None of those wait for G5, and none of them are a
29
- misuse of this skill.
30
-
31
- The second condition matters as much as the first. A test failing because of a missing import is not
32
- a trigger — you already know the cause. A test failing for a reason you cannot name is.
33
-
34
- Nor does the finding always land in code: three of the four `root_cause` categories send it back to
35
- `.what/` or `.how/` — see [Where the finding lands](#where-the-finding-lands).
36
-
37
- Use it *especially* when the pressure argues against it — an emergency, an "obvious one-line fix", a
38
- previous fix that did not hold. Systematic debugging is faster than guess-and-check, and the
39
- pressure cases are exactly where guessing costs the most.
40
-
41
- A simple-looking bug has a root cause too. You MUST NOT skip phases because the issue looks small.
42
-
43
- ## Phase 1 — Root cause investigation
44
-
45
- 1. **Read the error completely.** Full stack trace, line numbers, file paths, error codes. The
46
- answer is often already in it.
47
- 2. **Reproduce it.** Exact steps, every time. If it is not reproducible, gather more data — you
48
- MUST NOT proceed on a guess.
49
- 3. **Check what changed.** `git diff`, recent commits, new dependencies, config, environment.
50
- 4. **Instrument the boundaries.** When more than one component is involved (browser → API →
51
- service → database; CI → build → deploy), add logging at *each* boundary before proposing
52
- anything: what enters, what exits, what config propagated. Run once to find *which* boundary
53
- fails, then investigate only that one.
54
- 5. **Trace the bad value backward** to where it originates — see
55
- [references/root-cause-tracing.md](references/root-cause-tracing.md). Fix at the source, never
56
- where the symptom surfaced.
57
-
58
- ## Phase 2 — Pattern analysis
59
-
60
- 1. Find working code in this repo that does the same kind of thing.
61
- 2. Read the reference implementation **completely**. Skimming produces partial understanding, and
62
- partial understanding produces the next bug.
63
- 3. List every difference between working and broken, however small. You MUST NOT dismiss a
64
- difference as irrelevant before testing it.
65
- 4. Name the dependencies the broken path assumes: config, environment, state, ordering.
66
-
67
- ## Phase 3 — Hypothesis
68
-
69
- 1. State one hypothesis in writing: "X is the root cause because Y."
70
- 2. Test it with the **smallest possible change**. One variable at a time.
71
- 3. Worked → Phase 4. Did not work → form a *new* hypothesis. You MUST NOT stack a second fix on
72
- top of a failed one.
73
- 4. If you do not understand something, say so plainly and investigate further. Pretending to know
74
- is what produces fix #4.
75
-
76
- ## Phase 4 — Implementation
77
-
78
- 1. **Write the failing test first.** Simplest reproduction that fails for the right reason. Run it
79
- and confirm it fails before writing any fix. A fix without a test that failed first does not
80
- stick and cannot be proven.
81
- 2. **One fix, addressing the root cause.** No bundled refactoring, no "while I'm here" improvements.
82
- 3. **Verify with evidence.** The test passes, no other test broke, and you have the command output
83
- to show it. Claiming success without the output is prohibited.
84
- 4. **If the fix fails, count your attempts.**
85
- - Fewer than 3 → return to Phase 1 with what you now know.
86
- - **3 or more → STOP. Do not attempt fix #4.**
87
-
88
- ## Phase 5 — Record the finding
89
-
90
- An investigation that ends in chat has to be repeated. Before you close out — whether the fix landed
91
- or the three-fix rule stopped you — record what you found in `.control/registry/defects.yaml`. This
92
- is the only registry write this skill owns, and it exists so one question can be answered with a
93
- number rather than a memory: **how many of our defects turned out to be a wrong requirement rather
94
- than wrong code.**
95
-
96
- ### Find the row, or open one
97
-
98
- A defect found by a tester is usually already there, carrying only `id`, `title`, `found_in`, and
99
- `reported`. Anyone MAY open such a row without running any skill, and an empty `root_cause` is a
100
- legitimate state meaning *not yet diagnosed* — you are the step that fills it, not the step that
101
- guards it. When no row exists, open one yourself, taking the next number in the `BUG-` sequence
102
- (`HOT-` when it arrived through the hotfix path).
103
-
104
- You MUST NOT require a row to exist before investigating. A defect nobody recorded is still a
105
- defect; refusing to work until the paperwork is right is how the file becomes a formality.
106
-
107
- ### Write three fields, and only these three
108
-
109
- | Field | Where it comes from |
110
- |---|---|
111
- | `root_cause` | Your Phase 1–3 conclusion, in the four categories of the table above |
112
- | `violates` | The `FR-` or `UC-` the defect breaks. MUST be filled for `requirement` and `architecture`: a defect that violates something without naming what cannot be traced back to the corpus, and V20 fails it |
113
- | `fix` | `fastpath` for a pure code defect, the wave id otherwise. The table above already decides this — `requirement` and `architecture` MUST NOT be `fastpath` |
114
-
115
- You MUST NOT write a closure date. It is derived from the history of `defects.yaml` itself by
116
- `.constitution/scripts/timeline.py`, and a hand-written date would be a second home for one fact —
117
- the stored copy being the one that goes wrong.
118
-
119
- You MUST NOT edit `title`, `found_in`, or `reported`. Whoever opened the row owns those; correcting
120
- them silently erases what was actually reported.
121
-
122
- ### `status: fixed` follows the route, not the merge
123
-
124
- The moment the patch merges is not the moment the defect closes. What closes it depends on the row's
125
- own `root_cause`:
126
-
127
- | `root_cause` | Closes when |
128
- |---|---|
129
- | `code` | The failing test from Phase 4 passes and the fix is merged |
130
- | `requirement` | The `FR-` or `UC-` in `violates` has actually changed — the code alone MUST NOT close it |
131
- | `architecture` | The `DEC-` is `accepted` and named on the row. V20 fails a `fixed` row without one |
132
- | `environment` | The handling is in place and the monitoring exists |
133
-
134
- Setting `fixed` before its row's condition is met is the failure this whole registry exists to
135
- prevent: it turns "we patched the code" into "the requirement was right all along".
136
-
137
- ### When the three-fix rule stopped you
138
-
139
- You MUST still record. The rule triggering *is* the finding — `root_cause: architecture`, `violates`
140
- naming what the architecture broke, and the row left `open` until the `DEC-` exists. An escalation that
141
- leaves no trace looks identical to a bug that was never investigated.
142
-
143
- ## The three-fix rule
144
-
145
- Three failed fixes is not three failed hypotheses — it is a signal that the architecture is wrong.
146
-
147
- Symptoms: each fix uncovers new coupling or shared state somewhere else; each fix needs "a bit of
148
- refactoring" to land; each fix creates a new symptom elsewhere.
149
-
150
- When this happens you MUST stop and raise it with the owner rather than continue. In this project's
151
- terms, the outcome is a `DEC-` — a correction of course is one too — not another patch.
152
-
153
- ## Where the finding lands
154
-
155
- | What the root cause turns out to be | Where it goes |
156
- |---|---|
157
- | Genuine code defect, no artifact was wrong | Fast Path — fix, test, done |
158
- | A requirement was missing or wrong | Back to the Impact Matrix in `.constitution/document/delivery-flow-guide.md`; the FR/UC changes before the code does |
159
- | An architecture decision was wrong | `wdi-decision`, which wraps `bmad-correct-course`; MUST NOT be absorbed as a code patch |
160
- | Environmental, timing-dependent, or external | Document the investigation, implement handling (retry, timeout, clear error), add monitoring |
161
-
162
- These four categories are exactly the values of `root_cause` in `.control/registry/defects.yaml`.
163
- Phase 5 is where your verdict lands in that file.
164
-
165
- The last row is real but rare. Most "no root cause" conclusions are incomplete investigations —
166
- treat that verdict with suspicion in yourself.
167
-
168
- ## Red flags — stop and return to Phase 1
169
-
170
- If you catch yourself thinking any of these, the process has already broken down:
171
-
172
- | Thought | Reality |
173
- |---|---|
174
- | "Quick fix now, investigate later" | The first fix sets the pattern. There is no later. |
175
- | "Just change X and see if it works" | That is guessing with extra steps. |
176
- | "It's probably X, let me fix that" | Seeing a symptom is not understanding a cause. |
177
- | "I'll skip the test and verify manually" | Untested fixes regress silently. |
178
- | "Several changes at once saves time" | You will not know which one worked, or what else broke. |
179
- | "The reference is long, I'll adapt the pattern" | Partial reading guarantees the next bug. |
180
- | "One more fix attempt" (after 2+) | Three failures means the architecture is the problem. |
181
- | "Emergency — no time for process" | Thrashing is slower. Always. |
182
-
183
- Signals from the owner that mean the same thing: *"stop guessing"*, *"is that actually
184
- happening?"*, *"will that show us anything?"*, *"we're stuck?"*
185
-
186
- ## Supporting techniques
187
-
188
- | File | Use when |
189
- |---|---|
190
- | [references/root-cause-tracing.md](references/root-cause-tracing.md) | The error surfaces deep in a call stack and you must trace backward to the origin |
191
- | [references/defense-in-depth.md](references/defense-in-depth.md) | Root cause is found and you are deciding where validation belongs |
192
- | [references/condition-based-waiting.md](references/condition-based-waiting.md) | Flaky timing, arbitrary sleeps, race conditions |
193
- | [references/find-polluter.sh](references/find-polluter.sh) | A test passes alone but fails in the suite — bisects to find the polluting test |
1
+ ---
2
+ name: wdi-systematic-debugging
3
+ description: Use when encountering any bug, test failure, build failure, or unexpected behavior, before proposing any fix. Covers root-cause investigation, hypothesis testing, and the escalation rule when repeated fixes fail.
4
+ ---
5
+
6
+ # Systematic Debugging
7
+
8
+ BMad has no debugging workflow — `bmad-build` assumes you already know what to build. This skill
9
+ covers the gap: something is broken and the cause is unknown.
10
+
11
+ ## The Iron Law
12
+
13
+ **NO FIX WITHOUT ROOT CAUSE INVESTIGATION FIRST.**
14
+
15
+ You MUST complete Phase 1 before proposing any fix. A fix that treats a symptom is a failure even
16
+ when the symptom disappears.
17
+
18
+ ## When to use
19
+
20
+ Use for any technical issue: test failure, production bug, unexpected behavior, performance problem,
21
+ build failure, integration failure.
22
+
23
+ **Its home is G5, but its trigger is not positional.** Most invocations happen while coding, and
24
+ that is why `AGENTS.md`, `bmad-build`, and the ship-story orchestration carry this rule in their
25
+ worker context. What actually fires it is a pair of conditions — *something is broken* **and** *the
26
+ cause is unknown* — so it MAY be invoked in any stage, by anyone, to investigate: a red
27
+ `validate.py` while writing an SRS at G3, a `wdi-reconcile` report that makes no sense, a
28
+ generator producing an empty timeline. None of those wait for G5, and none of them are a
29
+ misuse of this skill.
30
+
31
+ The second condition matters as much as the first. A test failing because of a missing import is not
32
+ a trigger — you already know the cause. A test failing for a reason you cannot name is.
33
+
34
+ Nor does the finding always land in code: three of the four `root_cause` categories send it back to
35
+ `.what/` or `.how/` — see [Where the finding lands](#where-the-finding-lands).
36
+
37
+ Use it *especially* when the pressure argues against it — an emergency, an "obvious one-line fix", a
38
+ previous fix that did not hold. Systematic debugging is faster than guess-and-check, and the
39
+ pressure cases are exactly where guessing costs the most.
40
+
41
+ A simple-looking bug has a root cause too. You MUST NOT skip phases because the issue looks small.
42
+
43
+ ## Phase 1 — Root cause investigation
44
+
45
+ 1. **Read the error completely.** Full stack trace, line numbers, file paths, error codes. The
46
+ answer is often already in it.
47
+ 2. **Reproduce it.** Exact steps, every time. If it is not reproducible, gather more data — you
48
+ MUST NOT proceed on a guess.
49
+ 3. **Check what changed.** `git diff`, recent commits, new dependencies, config, environment.
50
+ 4. **Instrument the boundaries.** When more than one component is involved (browser → API →
51
+ service → database; CI → build → deploy), add logging at *each* boundary before proposing
52
+ anything: what enters, what exits, what config propagated. Run once to find *which* boundary
53
+ fails, then investigate only that one.
54
+ 5. **Trace the bad value backward** to where it originates — see
55
+ [references/root-cause-tracing.md](references/root-cause-tracing.md). Fix at the source, never
56
+ where the symptom surfaced.
57
+
58
+ ## Phase 2 — Pattern analysis
59
+
60
+ 1. Find working code in this repo that does the same kind of thing.
61
+ 2. Read the reference implementation **completely**. Skimming produces partial understanding, and
62
+ partial understanding produces the next bug.
63
+ 3. List every difference between working and broken, however small. You MUST NOT dismiss a
64
+ difference as irrelevant before testing it.
65
+ 4. Name the dependencies the broken path assumes: config, environment, state, ordering.
66
+
67
+ ## Phase 3 — Hypothesis
68
+
69
+ 1. State one hypothesis in writing: "X is the root cause because Y."
70
+ 2. Test it with the **smallest possible change**. One variable at a time.
71
+ 3. Worked → Phase 4. Did not work → form a *new* hypothesis. You MUST NOT stack a second fix on
72
+ top of a failed one.
73
+ 4. If you do not understand something, say so plainly and investigate further. Pretending to know
74
+ is what produces fix #4.
75
+
76
+ ## Phase 4 — Implementation
77
+
78
+ 1. **Write the failing test first.** Simplest reproduction that fails for the right reason. Run it
79
+ and confirm it fails before writing any fix. A fix without a test that failed first does not
80
+ stick and cannot be proven.
81
+ 2. **One fix, addressing the root cause.** No bundled refactoring, no "while I'm here" improvements.
82
+ 3. **Verify with evidence.** The test passes, no other test broke, and you have the command output
83
+ to show it. Claiming success without the output is prohibited.
84
+ 4. **If the fix fails, count your attempts.**
85
+ - Fewer than 3 → return to Phase 1 with what you now know.
86
+ - **3 or more → STOP. Do not attempt fix #4.**
87
+
88
+ ## Phase 5 — Record the finding
89
+
90
+ An investigation that ends in chat has to be repeated. Before you close out — whether the fix landed
91
+ or the three-fix rule stopped you — record what you found in `.control/registry/defects.yaml`. This
92
+ is the only registry write this skill owns, and it exists so one question can be answered with a
93
+ number rather than a memory: **how many of our defects turned out to be a wrong requirement rather
94
+ than wrong code.**
95
+
96
+ ### Find the row, or open one
97
+
98
+ A defect found by a tester is usually already there, carrying only `id`, `title`, `found_in`, and
99
+ `reported`. Anyone MAY open such a row without running any skill, and an empty `root_cause` is a
100
+ legitimate state meaning *not yet diagnosed* — you are the step that fills it, not the step that
101
+ guards it. When no row exists, open one yourself, taking the next number in the `BUG-` sequence
102
+ (`HOT-` when it arrived through the hotfix path).
103
+
104
+ You MUST NOT require a row to exist before investigating. A defect nobody recorded is still a
105
+ defect; refusing to work until the paperwork is right is how the file becomes a formality.
106
+
107
+ ### Write three fields, and only these three
108
+
109
+ | Field | Where it comes from |
110
+ |---|---|
111
+ | `root_cause` | Your Phase 1–3 conclusion, in the four categories of the table above |
112
+ | `violates` | The `FR-` or `UC-` the defect breaks. MUST be filled for `requirement` and `architecture`: a defect that violates something without naming what cannot be traced back to the corpus, and V20 fails it |
113
+ | `fix` | `fastpath` for a pure code defect, the wave id otherwise. The table above already decides this — `requirement` and `architecture` MUST NOT be `fastpath` |
114
+
115
+ You MUST NOT write a closure date. It is derived from the history of `defects.yaml` itself by
116
+ `.constitution/method/scripts/timeline.py`, and a hand-written date would be a second home for one fact —
117
+ the stored copy being the one that goes wrong.
118
+
119
+ You MUST NOT edit `title`, `found_in`, or `reported`. Whoever opened the row owns those; correcting
120
+ them silently erases what was actually reported.
121
+
122
+ ### `status: fixed` follows the route, not the merge
123
+
124
+ The moment the patch merges is not the moment the defect closes. What closes it depends on the row's
125
+ own `root_cause`:
126
+
127
+ | `root_cause` | Closes when |
128
+ |---|---|
129
+ | `code` | The failing test from Phase 4 passes and the fix is merged |
130
+ | `requirement` | The `FR-` or `UC-` in `violates` has actually changed — the code alone MUST NOT close it |
131
+ | `architecture` | The `DEC-` is `accepted` and named on the row. V20 fails a `fixed` row without one |
132
+ | `environment` | The handling is in place and the monitoring exists |
133
+
134
+ Setting `fixed` before its row's condition is met is the failure this whole registry exists to
135
+ prevent: it turns "we patched the code" into "the requirement was right all along".
136
+
137
+ ### When the three-fix rule stopped you
138
+
139
+ You MUST still record. The rule triggering *is* the finding — `root_cause: architecture`, `violates`
140
+ naming what the architecture broke, and the row left `open` until the `DEC-` exists. An escalation that
141
+ leaves no trace looks identical to a bug that was never investigated.
142
+
143
+ ## The three-fix rule
144
+
145
+ Three failed fixes is not three failed hypotheses — it is a signal that the architecture is wrong.
146
+
147
+ Symptoms: each fix uncovers new coupling or shared state somewhere else; each fix needs "a bit of
148
+ refactoring" to land; each fix creates a new symptom elsewhere.
149
+
150
+ When this happens you MUST stop and raise it with the owner rather than continue. In this project's
151
+ terms, the outcome is a `DEC-` — a correction of course is one too — not another patch.
152
+
153
+ ## Where the finding lands
154
+
155
+ | What the root cause turns out to be | Where it goes |
156
+ |---|---|
157
+ | Genuine code defect, no artifact was wrong | Fast Path — fix, test, done |
158
+ | A requirement was missing or wrong | Back to the Impact Matrix in `.constitution/method/document/delivery-flow-guide.md`; the FR/UC changes before the code does |
159
+ | An architecture decision was wrong | `wdi-decision`, which wraps `bmad-correct-course`; MUST NOT be absorbed as a code patch |
160
+ | Environmental, timing-dependent, or external | Document the investigation, implement handling (retry, timeout, clear error), add monitoring |
161
+
162
+ These four categories are exactly the values of `root_cause` in `.control/registry/defects.yaml`.
163
+ Phase 5 is where your verdict lands in that file.
164
+
165
+ The last row is real but rare. Most "no root cause" conclusions are incomplete investigations —
166
+ treat that verdict with suspicion in yourself.
167
+
168
+ ## Red flags — stop and return to Phase 1
169
+
170
+ If you catch yourself thinking any of these, the process has already broken down:
171
+
172
+ | Thought | Reality |
173
+ |---|---|
174
+ | "Quick fix now, investigate later" | The first fix sets the pattern. There is no later. |
175
+ | "Just change X and see if it works" | That is guessing with extra steps. |
176
+ | "It's probably X, let me fix that" | Seeing a symptom is not understanding a cause. |
177
+ | "I'll skip the test and verify manually" | Untested fixes regress silently. |
178
+ | "Several changes at once saves time" | You will not know which one worked, or what else broke. |
179
+ | "The reference is long, I'll adapt the pattern" | Partial reading guarantees the next bug. |
180
+ | "One more fix attempt" (after 2+) | Three failures means the architecture is the problem. |
181
+ | "Emergency — no time for process" | Thrashing is slower. Always. |
182
+
183
+ Signals from the owner that mean the same thing: *"stop guessing"*, *"is that actually
184
+ happening?"*, *"will that show us anything?"*, *"we're stuck?"*
185
+
186
+ ## Supporting techniques
187
+
188
+ | File | Use when |
189
+ |---|---|
190
+ | [references/root-cause-tracing.md](references/root-cause-tracing.md) | The error surfaces deep in a call stack and you must trace backward to the origin |
191
+ | [references/defense-in-depth.md](references/defense-in-depth.md) | Root cause is found and you are deciding where validation belongs |
192
+ | [references/condition-based-waiting.md](references/condition-based-waiting.md) | Flaky timing, arbitrary sleeps, race conditions |
193
+ | [references/find-polluter.sh](references/find-polluter.sh) | A test passes alone but fails in the suite — bisects to find the polluting test |