@curdx/flow 3.0.0 → 3.1.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 (219) hide show
  1. package/CHANGELOG.md +21 -87
  2. package/LICENSE +1 -1
  3. package/README.md +28 -129
  4. package/dist/index.mjs +995 -0
  5. package/package.json +33 -44
  6. package/.claude-plugin/marketplace.json +0 -48
  7. package/.claude-plugin/plugin.json +0 -52
  8. package/agent-preamble/preamble.md +0 -314
  9. package/agents/flow-adversary.md +0 -203
  10. package/agents/flow-architect.md +0 -198
  11. package/agents/flow-brownfield-analyst.md +0 -143
  12. package/agents/flow-debugger.md +0 -321
  13. package/agents/flow-edge-hunter.md +0 -289
  14. package/agents/flow-executor.md +0 -269
  15. package/agents/flow-orchestrator.md +0 -145
  16. package/agents/flow-planner.md +0 -247
  17. package/agents/flow-product-designer.md +0 -159
  18. package/agents/flow-qa-engineer.md +0 -282
  19. package/agents/flow-researcher.md +0 -166
  20. package/agents/flow-reviewer.md +0 -304
  21. package/agents/flow-security-auditor.md +0 -401
  22. package/agents/flow-triage-analyst.md +0 -272
  23. package/agents/flow-ui-researcher.md +0 -230
  24. package/agents/flow-ux-designer.md +0 -221
  25. package/agents/flow-verifier.md +0 -350
  26. package/bin/curdx-flow +0 -5
  27. package/bin/curdx-flow-state +0 -104
  28. package/bin/curdx-flow.js +0 -54
  29. package/cli/README.md +0 -104
  30. package/cli/doctor-workflow.js +0 -483
  31. package/cli/doctor.js +0 -73
  32. package/cli/help.js +0 -59
  33. package/cli/install-bundled-mcps.js +0 -37
  34. package/cli/install-companions.js +0 -19
  35. package/cli/install-context7-config.js +0 -80
  36. package/cli/install-curdx-plugin.js +0 -96
  37. package/cli/install-language.js +0 -35
  38. package/cli/install-next-steps.js +0 -29
  39. package/cli/install-options.js +0 -9
  40. package/cli/install-paths.js +0 -52
  41. package/cli/install-recommended-plugins.js +0 -104
  42. package/cli/install-required-plugins.js +0 -57
  43. package/cli/install-self-update.js +0 -62
  44. package/cli/install-workflow.js +0 -209
  45. package/cli/install.js +0 -101
  46. package/cli/lib/claude-commands.js +0 -41
  47. package/cli/lib/claude-ops.js +0 -47
  48. package/cli/lib/claude.js +0 -183
  49. package/cli/lib/config.js +0 -24
  50. package/cli/lib/doctor-claude-settings.js +0 -1186
  51. package/cli/lib/doctor-report.js +0 -978
  52. package/cli/lib/doctor-runtime-environment.js +0 -196
  53. package/cli/lib/frontmatter.js +0 -44
  54. package/cli/lib/json-schema.js +0 -57
  55. package/cli/lib/logging.js +0 -25
  56. package/cli/lib/process.js +0 -60
  57. package/cli/lib/prompts.js +0 -135
  58. package/cli/lib/runtime.js +0 -107
  59. package/cli/lib/semver.js +0 -109
  60. package/cli/lib/version.js +0 -12
  61. package/cli/protocols-body.md +0 -22
  62. package/cli/protocols.js +0 -162
  63. package/cli/registry.js +0 -123
  64. package/cli/router.js +0 -49
  65. package/cli/uninstall-actions.js +0 -360
  66. package/cli/uninstall-workflow.js +0 -146
  67. package/cli/uninstall.js +0 -42
  68. package/cli/upgrade-workflow.js +0 -80
  69. package/cli/upgrade.js +0 -91
  70. package/cli/utils.js +0 -40
  71. package/gates/adversarial-review-gate.md +0 -219
  72. package/gates/coverage-audit-gate.md +0 -182
  73. package/gates/devex-gate.md +0 -254
  74. package/gates/edge-case-gate.md +0 -194
  75. package/gates/karpathy-gate.md +0 -130
  76. package/gates/security-gate.md +0 -218
  77. package/gates/tdd-gate.md +0 -182
  78. package/gates/test-quality-gate.md +0 -59
  79. package/gates/verification-gate.md +0 -179
  80. package/hooks/hooks.json +0 -130
  81. package/hooks/scripts/common.sh +0 -237
  82. package/hooks/scripts/config-change-guard.sh +0 -94
  83. package/hooks/scripts/flow-context-watch.sh +0 -94
  84. package/hooks/scripts/inject-karpathy.sh +0 -53
  85. package/hooks/scripts/quick-mode-guard.sh +0 -69
  86. package/hooks/scripts/session-start.sh +0 -94
  87. package/hooks/scripts/session-title.sh +0 -87
  88. package/hooks/scripts/stop-watcher.sh +0 -231
  89. package/hooks/scripts/subagent-artifact-guard.sh +0 -92
  90. package/hooks/scripts/subagent-statusline.sh +0 -111
  91. package/hooks/scripts/task-lifecycle-guard.sh +0 -106
  92. package/hooks/scripts/teammate-idle-guard.sh +0 -83
  93. package/knowledge/artifact-output-discipline.md +0 -24
  94. package/knowledge/artifact-summary-contracts.md +0 -50
  95. package/knowledge/atomic-commits.md +0 -262
  96. package/knowledge/claude-code-runtime-contracts.md +0 -240
  97. package/knowledge/epic-decomposition.md +0 -307
  98. package/knowledge/execution-strategies.md +0 -303
  99. package/knowledge/karpathy-guidelines.md +0 -219
  100. package/knowledge/planning-reviews.md +0 -211
  101. package/knowledge/poc-first-workflow.md +0 -223
  102. package/knowledge/review-feedback-intake.md +0 -57
  103. package/knowledge/spec-driven-development.md +0 -180
  104. package/knowledge/systematic-debugging.md +0 -378
  105. package/knowledge/two-stage-review.md +0 -249
  106. package/knowledge/wave-execution.md +0 -403
  107. package/monitors/monitors.json +0 -8
  108. package/monitors/scripts/flow-state-monitor.sh +0 -102
  109. package/output-styles/curdx-evidence-first.md +0 -34
  110. package/output-styles/curdx-fast-mode.md +0 -42
  111. package/output-styles/curdx-spec-mode.md +0 -46
  112. package/schemas/agent-frontmatter.schema.json +0 -66
  113. package/schemas/config.schema.json +0 -134
  114. package/schemas/gate-frontmatter.schema.json +0 -30
  115. package/schemas/hooks.schema.json +0 -115
  116. package/schemas/output-style-frontmatter.schema.json +0 -22
  117. package/schemas/plugin-manifest.schema.json +0 -436
  118. package/schemas/plugin-settings.schema.json +0 -29
  119. package/schemas/skill-frontmatter.schema.json +0 -177
  120. package/schemas/spec-frontmatter.schema.json +0 -42
  121. package/schemas/spec-state.schema.json +0 -165
  122. package/settings.json +0 -8
  123. package/skills/brownfield-index/SKILL.md +0 -53
  124. package/skills/brownfield-index/references/applicability.md +0 -12
  125. package/skills/brownfield-index/references/handoff.md +0 -8
  126. package/skills/brownfield-index/references/index-contract.md +0 -10
  127. package/skills/browser-qa/SKILL.md +0 -39
  128. package/skills/browser-qa/references/handoff.md +0 -6
  129. package/skills/browser-qa/references/prerequisites.md +0 -10
  130. package/skills/browser-qa/references/qa-contract.md +0 -20
  131. package/skills/cancel/SKILL.md +0 -41
  132. package/skills/cancel/references/destructive-mode.md +0 -17
  133. package/skills/cancel/references/reporting.md +0 -18
  134. package/skills/cancel/references/state-recovery.md +0 -30
  135. package/skills/cancel/references/target-resolution.md +0 -7
  136. package/skills/debug/SKILL.md +0 -45
  137. package/skills/debug/references/context-gathering.md +0 -11
  138. package/skills/debug/references/failure-guard.md +0 -25
  139. package/skills/debug/references/intake.md +0 -12
  140. package/skills/debug/references/phase-workflow.md +0 -34
  141. package/skills/debug/references/reporting.md +0 -20
  142. package/skills/epic/SKILL.md +0 -39
  143. package/skills/epic/references/epic-artifacts.md +0 -20
  144. package/skills/epic/references/epic-intake.md +0 -9
  145. package/skills/epic/references/slice-handoff.md +0 -16
  146. package/skills/fast/SKILL.md +0 -62
  147. package/skills/fast/references/applicability.md +0 -25
  148. package/skills/fast/references/clarification.md +0 -20
  149. package/skills/fast/references/execution-contract.md +0 -56
  150. package/skills/help/SKILL.md +0 -55
  151. package/skills/help/references/dispatch.md +0 -20
  152. package/skills/help/references/overview.md +0 -39
  153. package/skills/help/references/troubleshoot.md +0 -47
  154. package/skills/help/references/workflow.md +0 -37
  155. package/skills/implement/SKILL.md +0 -104
  156. package/skills/implement/references/error-recovery.md +0 -36
  157. package/skills/implement/references/linear-execution.md +0 -43
  158. package/skills/implement/references/native-task-sync.md +0 -107
  159. package/skills/implement/references/preflight.md +0 -43
  160. package/skills/implement/references/progress-contract.md +0 -36
  161. package/skills/implement/references/state-init.md +0 -36
  162. package/skills/implement/references/stop-hook-execution.md +0 -50
  163. package/skills/implement/references/strategy-router.md +0 -38
  164. package/skills/implement/references/subagent-execution.md +0 -57
  165. package/skills/implement/references/wave-execution.md +0 -180
  166. package/skills/init/SKILL.md +0 -49
  167. package/skills/init/references/gitignore-and-health.md +0 -26
  168. package/skills/init/references/next-steps.md +0 -22
  169. package/skills/init/references/preflight.md +0 -15
  170. package/skills/init/references/scaffold-contract.md +0 -27
  171. package/skills/review/SKILL.md +0 -82
  172. package/skills/review/references/optional-passes.md +0 -48
  173. package/skills/review/references/preflight.md +0 -38
  174. package/skills/review/references/report-contract.md +0 -49
  175. package/skills/review/references/reporting.md +0 -20
  176. package/skills/review/references/stage-execution.md +0 -32
  177. package/skills/security-audit/SKILL.md +0 -47
  178. package/skills/security-audit/references/audit-contract.md +0 -21
  179. package/skills/security-audit/references/gate-handoff.md +0 -8
  180. package/skills/security-audit/references/scope-and-depth.md +0 -9
  181. package/skills/spec/SKILL.md +0 -100
  182. package/skills/spec/references/artifact-landing.md +0 -31
  183. package/skills/spec/references/phase-execution.md +0 -50
  184. package/skills/spec/references/planning-review.md +0 -31
  185. package/skills/spec/references/preflight-and-routing.md +0 -46
  186. package/skills/spec/references/reporting.md +0 -21
  187. package/skills/start/SKILL.md +0 -84
  188. package/skills/start/references/branch-routing.md +0 -51
  189. package/skills/start/references/mode-semantics.md +0 -12
  190. package/skills/start/references/preflight.md +0 -13
  191. package/skills/start/references/reporting.md +0 -20
  192. package/skills/start/references/state-seeding.md +0 -44
  193. package/skills/start/references/workflow-handoff.md +0 -26
  194. package/skills/status/SKILL.md +0 -41
  195. package/skills/status/references/gather-contract.md +0 -30
  196. package/skills/status/references/health-rules.md +0 -27
  197. package/skills/status/references/output-contract.md +0 -25
  198. package/skills/status/references/preflight.md +0 -10
  199. package/skills/status/references/recovery-hints.md +0 -18
  200. package/skills/ui-sketch/SKILL.md +0 -39
  201. package/skills/ui-sketch/references/brief-intake.md +0 -10
  202. package/skills/ui-sketch/references/iteration-handoff.md +0 -5
  203. package/skills/ui-sketch/references/variant-contract.md +0 -15
  204. package/skills/verify/SKILL.md +0 -56
  205. package/skills/verify/references/evidence-workflow.md +0 -39
  206. package/skills/verify/references/output-contract.md +0 -23
  207. package/skills/verify/references/preflight.md +0 -11
  208. package/skills/verify/references/report-handoff.md +0 -35
  209. package/skills/verify/references/strict-mode.md +0 -12
  210. package/templates/CONTEXT.md.tmpl +0 -53
  211. package/templates/PROJECT.md.tmpl +0 -59
  212. package/templates/ROADMAP.md.tmpl +0 -50
  213. package/templates/STATE.md.tmpl +0 -49
  214. package/templates/config.json.tmpl +0 -51
  215. package/templates/design.md.tmpl +0 -83
  216. package/templates/progress.md.tmpl +0 -77
  217. package/templates/requirements.md.tmpl +0 -76
  218. package/templates/research.md.tmpl +0 -83
  219. package/templates/tasks.md.tmpl +0 -107
@@ -1,57 +0,0 @@
1
- # Review Feedback Intake — Verify Before Changing
2
-
3
- CurDX-Flow treats review feedback as technical input, not orders to blindly implement. The goal is to fix real issues while avoiding scope creep, regressions, and performative agreement.
4
-
5
- ## Intake Pattern
6
-
7
- For each review item:
8
-
9
- 1. **Read** the full finding, including severity, evidence, and suggested fix.
10
- 2. **Restate** the technical requirement in one sentence.
11
- 3. **Verify** against the codebase/spec:
12
- - Is the finding true at the referenced path/line?
13
- - Does it violate an FR, AC, AD, gate, test, or user decision?
14
- - Does the suggested fix break existing behavior or platform constraints?
15
- 4. **Classify**:
16
- - `BLOCKER`: correctness, security, missing requirement, failing verify, broken CI.
17
- - `IMPORTANT`: maintainability or test gap that should be fixed before ship.
18
- - `SUGGESTION`: non-blocking improvement or preference.
19
- - `PUSHBACK`: technically wrong, violates YAGNI, conflicts with D-NN, or lacks evidence.
20
- 5. **Act one item at a time**:
21
- - Fix blockers first.
22
- - Run the smallest relevant verification after each fix.
23
- - Record pushback with evidence instead of silently ignoring it.
24
-
25
- ## Required Artifact
26
-
27
- When review produces any nontrivial feedback, append a section to `.flow/specs/<active>/.progress.md`:
28
-
29
- ```markdown
30
- ## Review Feedback Intake YYYY-MM-DD
31
-
32
- | Item | Source | Classification | Decision | Evidence | Follow-up |
33
- |---|---|---|---|---|---|
34
- | R-01 | review-report.md#... | BLOCKER | fix | `npm test` fails AC-2.1 | Task 4.4 |
35
- | R-02 | review-report.md#... | PUSHBACK | defer | D-07 says no CSV export | none |
36
- ```
37
-
38
- ## Pushback Rules
39
-
40
- Push back when the feedback:
41
-
42
- - Adds unused features or speculative architecture.
43
- - Conflicts with explicit user decisions (`D-NN`).
44
- - Breaks compatibility that the current code intentionally preserves.
45
- - Is unsupported by evidence and cannot be reproduced.
46
- - Optimizes style while leaving spec compliance unresolved.
47
-
48
- Pushback must be technical: cite code, tests, specs, or decisions. Do not use emotional language.
49
-
50
- ## Fix Loop
51
-
52
- 1. Intake review items.
53
- 2. Convert accepted blockers/important issues into tasks or direct fixes.
54
- 3. Run targeted verification per item.
55
- 4. Re-run `/curdx-flow:verify` when behavior changed.
56
- 5. Re-run `/curdx-flow:review` until blockers are gone.
57
-
@@ -1,180 +0,0 @@
1
- # Spec-Driven Development — CurdX-Flow Methodology
2
-
3
- > Spec-driven development (SDD): decompose the path from "idea" to "code" into 4 verifiable phases, each with clear deliverables.
4
- >
5
- > Agents reference this file via `@${CLAUDE_PLUGIN_ROOT}/knowledge/spec-driven-development.md`.
6
-
7
- ---
8
-
9
- ## Core Idea
10
-
11
- **Do not write code until research, requirements, and design are clear.**
12
-
13
- ```
14
- ┌─────────┐ ┌─────────────┐ ┌────────┐ ┌───────┐ ┌─────────┐
15
- │ Research │ → │ Requirements │ → │ Design │ → │ Tasks │ → │ Execute │
16
- └─────────┘ └─────────────┘ └────────┘ └───────┘ └─────────┘
17
- "can it be done" "what to do" "how to do" "split how" "actually do"
18
- ```
19
-
20
- Each phase:
21
- - Has an independent Markdown deliverable (research.md / requirements.md / design.md / tasks.md)
22
- - Output is user-reviewed before progressing to the next
23
- - Later phases strictly reference prior conclusions — no re-litigation
24
-
25
- ---
26
-
27
- ## Why This Way?
28
-
29
- ### Problems from not doing this (writing code directly)
30
-
31
- ```
32
- User: "Add user authentication"
33
- AI: writes 800 lines of JWT code
34
- User: "Actually I wanted session cookies"
35
- AI: rewrites 800 lines of session code
36
- User: "I forgot to mention SSO is required"
37
- AI: rewrites again…
38
- ```
39
-
40
- What's wasted isn't code — it's context tokens and decision fatigue from churn.
41
-
42
- ### Benefits of doing it this way
43
-
44
- - **Catch misunderstandings early** — ask during research, not at implementation time
45
- - **Decisions are traceable** — every choice is written in design.md; later refer to `AD-01` rather than re-debating
46
- - **Interruptible and resumable** — spec files persist; tomorrow's continuation requires only a read
47
- - **Team collaboration** — others can pick up the work by reading the spec
48
-
49
- ---
50
-
51
- ## The 4 Phases Explained
52
-
53
- ### Phase 1: Research
54
-
55
- **Question**: Can this be done? What should it use?
56
-
57
- **Key behaviors** (flow-researcher agent):
58
- 1. Read `.flow/PROJECT.md` and `.flow/CONTEXT.md` to understand project background
59
- 2. Call `mcp__claude_mem__search` to retrieve relevant historical experience
60
- 3. Use sequential-thinking proportional to the unknowns (1 thought for a trivial prototype, many for a novel domain)
61
- 4. Scan the codebase for reusable modules
62
- 5. Use `mcp__context7__*` to look up latest docs for relevant libraries
63
- 6. When necessary, WebSearch for the latest technical trends
64
-
65
- **Deliverable**: `research.md` — includes:
66
- - Problem understanding + explicit assumptions
67
- - 2-3 candidate technical approaches
68
- - Existing code analysis
69
- - Feasibility judgment + recommended direction
70
-
71
- **Next-step decision**: the recommended direction enters requirements; if entirely infeasible, stop here.
72
-
73
- ---
74
-
75
- ### Phase 2: Requirements
76
-
77
- **Question**: What will the user see / experience?
78
-
79
- **Key behaviors** (flow-product-designer agent):
80
- 1. Read `research.md` to understand technical direction
81
- 2. Translate technical capabilities into user stories (US-NN)
82
- 3. Write 2-5 acceptance criteria per story (AC-X.Y)
83
- 4. List FR (functional requirements) + NFR (non-functional requirements)
84
- 5. Define an **explicit out-of-scope** list (prevents later scope creep)
85
- 6. Raise open questions for the user to answer
86
-
87
- **Deliverable**: `requirements.md`
88
-
89
- **User review focus**:
90
- - Are the user stories correct? (maybe research misunderstood)
91
- - Are edge cases handled reasonably?
92
- - Is the out-of-scope list accepted?
93
-
94
- ---
95
-
96
- ### Phase 3: Design
97
-
98
- **Question**: How is the code organized? What decisions are made?
99
-
100
- **Key behaviors** (flow-architect agent):
101
- 1. Read `research.md` + `requirements.md`
102
- 2. **Use sequential-thinking proportional to the tradeoff surface** — the phases below are orientation, not a quota:
103
- - Constraints (from NFR / tech stack)
104
- - Option comparison (only when alternatives genuinely compete)
105
- - Selection + accepted tradeoff
106
- - Self-rebuttal
107
- A well-known stack pick may finish in 1 thought; a distributed-system design may run many. Do not pad.
108
- 3. Assign an `AD-NN` ID to each architectural decision
109
- 4. Draw a data flow diagram (mermaid)
110
- 5. Define component interfaces + error paths
111
- 6. Make the test strategy explicit
112
-
113
- **Deliverable**: `design.md`
114
-
115
- **Freeze**: once tasks begin, the design is frozen. If changes are needed, return to the design phase to update (and bump AD numbers).
116
-
117
- ---
118
-
119
- ### Phase 4: Tasks (decomposition)
120
-
121
- **Question**: How many steps to do it? How is each step verified?
122
-
123
- **Key behaviors** (flow-planner agent):
124
- 1. Read `requirements.md` + `design.md`
125
- 2. Decompose by POC-First 5 Phases (see `poc-first-workflow.md`)
126
- 3. Each task has 5 fields: `Do` / `Files` / `Done-when` / `Verify` / `Commit`
127
- 4. **Multi-source coverage audit**: for each FR / AC / AD / decision, confirm there is a covering task (no omissions)
128
- 5. Mark `[P]` (parallel-safe) and `[VERIFY]` (checkpoint)
129
- 6. Simple decomposition doesn't need sequential-thinking; run a coverage audit at the end (every FR/AC/AD has a task)
130
-
131
- **Deliverable**: `tasks.md`
132
-
133
- **Verification standard**: each `Verify` field must be an **automated command**, not "manual test".
134
-
135
- ---
136
-
137
- ## Spec-File Invariants
138
-
139
- Regardless of the path taken, the 4 files must satisfy:
140
-
141
- 1. **Clear dependency chain**: requirements reference research conclusions; design references requirements' FR; tasks reference design's AD.
142
- 2. **IDs unique and stable**: US-01 refers to the same story across every file.
143
- 3. **Auditable and traceable**: every implementation task can be traced to some FR or AC.
144
- 4. **No backward edits**: once frozen, changes bump the version number (1.0 → 1.1), with prior versions kept.
145
-
146
- ---
147
-
148
- ## Spec vs Epic Difference
149
-
150
- - **Spec**: a single independently-deliverable feature. Typically 1-2 weeks of effort.
151
- - **Epic**: a collection of specs. The `epic` skill (auto-invoked, or say "break this big feature down") breaks down a large goal into multiple specs.
152
-
153
- `.flow/specs/<name>/` is a single-spec directory.
154
- `.flow/_epics/<name>/` is an Epic directory (contains the dependency graph and sub-spec list).
155
-
156
- ---
157
-
158
- ## When Not to Use the Full Flow
159
-
160
- SDD is not dogma. The following scenarios may skip phases:
161
-
162
- - **One-off scripts** (`/curdx-flow:fast` mode) — skip all specs
163
- - **UI prototype exploration** (the `ui-sketch` skill) — only research + design sketches
164
- - **Emergency hotfix** (`/curdx-flow:fast "spike: validate <hypothesis>"` mode) — validating the assumption is enough
165
-
166
- But **production code changes** should follow the full flow. Rationale:
167
- - Code may be only 20 lines, but impact may reach all users
168
- - The spec file itself is a record of "why" — valuable for future maintenance
169
-
170
- ---
171
-
172
- ## Division of Labor with claude-mem
173
-
174
- - **claude-mem** automatically captures all tool calls and conversation → implicit memory
175
- - **Spec files** are **explicit decision records** → consciously written
176
-
177
- The two complement each other:
178
- - Agents `mcp__claude_mem__search` the history before starting research
179
- - What gets written into research.md is filtered, retention-worthy conclusions
180
- - Subsequent sessions: claude-mem auto-injects recent context; spec files provide the structured overview
@@ -1,378 +0,0 @@
1
- # Systematic Debugging — 4-Stage Methodology
2
-
3
- > Agents reference this via `@${CLAUDE_PLUGIN_ROOT}/knowledge/systematic-debugging.md`.
4
-
5
- ---
6
-
7
- ## Why Systematic
8
-
9
- **Unsystematic debugging**:
10
- - "Try this" → doesn't work
11
- - "Try that" → doesn't work
12
- - "Change this line" → looks good?
13
- - (half an hour later) the bug is back
14
-
15
- **Problems**:
16
- - Without a root cause → fix isn't sturdy
17
- - No failing test → no regression protection
18
- - Consumes a lot of time
19
- - Introduces new bugs while fixing bugs
20
-
21
- **Systematic debugging**: explicit 4 stages, each with deliverables, preventing skipping.
22
-
23
- ---
24
-
25
- ## 4-Stage Overview
26
-
27
- ```
28
- Phase 1: Root Cause Investigation
29
- ↓ a clear root cause statement
30
- Phase 2: Pattern Analysis
31
- ↓ compare working vs broken
32
- Phase 3: Hypothesis & Test
33
- ↓ single hypothesis, minimal test, verify
34
- Phase 4: Implement Fix
35
- ↓ failing test → fix root cause → verify
36
- ```
37
-
38
- Skipping any stage = incomplete.
39
-
40
- ---
41
-
42
- ## Phase 1: Root Cause Investigation
43
-
44
- ### Step 1.1: Read the error carefully
45
-
46
- Don't skim and start changing things. **Read every word**:
47
-
48
- ```
49
- TypeError: Cannot read property 'email' of undefined
50
- at validateUser (src/auth/login.ts:42:18)
51
- at processLogin (src/auth/login.ts:15:3)
52
- at async Router.post (src/routes/auth.ts:22:5)
53
- ```
54
-
55
- What I can learn:
56
- - **Type**: TypeError (not a logic error)
57
- - **Cause**: reading .email on undefined
58
- - **Location**: login.ts:42
59
- - **Call chain**: processLogin → validateUser
60
- - **Entry**: POST /auth/... route handler
61
-
62
- Don't skip these.
63
-
64
- ### Step 1.2: Reliable reproduction
65
-
66
- Establish **minimal** reproduction steps:
67
-
68
- ```
69
- Preconditions:
70
- 1. Run dev server
71
- 2. Clear cookies
72
- 3. Visit /login
73
-
74
- Steps:
75
- 1. Leave email empty
76
- 2. Fill password with anything
77
- 3. Click Submit
78
-
79
- Expected: 400 + "email required"
80
- Actual: 500 + stack trace with the TypeError above
81
- ```
82
-
83
- If **unstable** (sometimes happens, sometimes not):
84
- - Record under what conditions it occurs
85
- - Under what conditions it doesn't
86
- - This hints at: race condition / initialization order / environment difference
87
-
88
- ### Step 1.3: Check recent changes
89
-
90
- ```bash
91
- git log --oneline -20 src/auth/login.ts
92
- git log --oneline --all --since="7 days ago"
93
- git diff HEAD~5 src/auth/login.ts
94
- ```
95
-
96
- Most bugs are introduced by recent changes. Look at the suspicious recent commits first.
97
-
98
- ### Step 1.4: Trace data flow
99
-
100
- Backwards from the error point:
101
-
102
- ```
103
- error at login.ts:42: user.email is undefined
104
- → where does user come from?
105
- → validateUser(user) parameter
106
- → req.body.user in processLogin
107
- → route parameter req.body
108
- → JSON.parse(request.body)
109
- → payload from client
110
-
111
- Reasoning:
112
- If payload = `{email: ""}`,
113
- req.body = {email: ""},
114
- and code reads req.body.user.email → undefined.email → crash
115
- ```
116
-
117
- Root cause found: the code expected `req.body.user.email`, but the API contract sends `req.body.email`.
118
-
119
- ### Step 1.5: Root cause statement
120
-
121
- The completion sign for Phase 1: **being able to write the root cause in one sentence**.
122
-
123
- Format:
124
- > "Root cause: <specific cause>; trigger: <specific condition>; scope: <scope>"
125
-
126
- Example:
127
- > "Root cause: validateUser reads req.body.user.email, but the API sends req.body.email; trigger: all login requests; scope: the entire login flow fails 100%."
128
-
129
- **Forbidden**:
130
- - "Might be..." (hypothesis, not root cause)
131
- - "Maybe..." (same)
132
- - "I think..." (subjective)
133
-
134
- If still at the "might be" level → continue investigating, don't enter Phase 2.
135
-
136
- ---
137
-
138
- ## Phase 2: Pattern Analysis
139
-
140
- ### Step 2.1: Find working examples
141
-
142
- 90% of the code in the system doesn't have this bug. What does that 90% look like?
143
-
144
- ```bash
145
- # Find similar scenarios
146
- grep -rn "req.body" src/routes/
147
- ```
148
-
149
- Results:
150
- ```
151
- src/routes/auth.ts:15: const { email } = req.body ← works
152
- src/routes/auth.ts:22: req.body.user.email ← broken
153
- src/routes/user.ts:10: const { name } = req.body ← works
154
- src/routes/order.ts:8: const { amount } = req.body ← works
155
- ```
156
-
157
- ### Step 2.2: Locate the difference
158
-
159
- ```
160
- Working pattern: const { email } = req.body (destructure top-level fields)
161
- Broken pattern: req.body.user.email (access nested field)
162
- ```
163
-
164
- Difference is clear → confirms the root cause.
165
-
166
- ### Step 2.3: Isolated case or systemic?
167
-
168
- ```bash
169
- grep -rn "req\.body\.user\." src/
170
- ```
171
-
172
- If the `req.body.user` pattern is used in multiple places:
173
- - A wrong mental model exists in the system
174
- - Fix all of them, not just one
175
-
176
- If only this one:
177
- - Isolated case, fix only here
178
-
179
- ---
180
-
181
- ## Phase 3: Hypothesis & Test
182
-
183
- ### Step 3.1: Single hypothesis
184
-
185
- **Do not** test multiple hypotheses simultaneously. If something works, you won't know which one did it.
186
-
187
- **Single hypothesis**:
188
- > "Hypothesis: changing login.ts:42 from req.body.user.email to req.body.email will fix this bug."
189
-
190
- ### Step 3.2: Minimal test
191
-
192
- ```bash
193
- # Reproduce with current code first
194
- curl -X POST localhost:3000/auth/login \
195
- -d '{"email":"","password":""}'
196
- # → 500 + TypeError ✓ (reproduces)
197
-
198
- # Make the minimum change (in memory / editor, don't commit)
199
- # Edit login.ts:42
200
-
201
- # Test again
202
- curl ... # expect 400 + "email required"
203
-
204
- # If success → hypothesis confirmed
205
- # If failure → hypothesis wrong; go back to Phase 1
206
- ```
207
-
208
- ### Step 3.3: Hypothesis confirmed → Phase 4
209
-
210
- Once confirmed, proceed to the fix.
211
-
212
- Hypothesis refuted → **do not** keep guessing; go back to Phase 1 and re-investigate the data flow.
213
-
214
- ---
215
-
216
- ## Phase 4: Implement Fix
217
-
218
- ### Step 4.1: Write a failing test (**before code**)
219
-
220
- ```typescript
221
- // login.test.ts
222
- test("rejects empty email with 400 (regression for #N)", async () => {
223
- const res = await request(app)
224
- .post("/auth/login")
225
- .send({ email: "", password: "any" })
226
-
227
- expect(res.status).toBe(400)
228
- expect(res.body.error).toMatch(/email required/i)
229
- })
230
- ```
231
-
232
- Run:
233
- ```bash
234
- npm test -- login.test.ts
235
- # ✗ FAIL (expected, since it currently crashes with 500)
236
- ```
237
-
238
- Commit: `test(auth): red - reject empty email in login`
239
-
240
- ### Step 4.2: Fix the root cause (not the symptom)
241
-
242
- Phase 1 root cause: the code mis-reads `req.body.user.email`.
243
-
244
- **Correct fix**: change to `req.body.email`
245
- ```typescript
246
- // login.ts
247
- - const email = req.body.user.email // wrong
248
- + const email = req.body.email // correct
249
- ```
250
-
251
- **Symptom fix** (wrong): add a null check
252
- ```typescript
253
- // ✗ symptom fix (doesn't answer "why is user.email undefined")
254
- if (!req.body.user?.email) return res.status(400)
255
- ```
256
-
257
- ### Step 4.3: Verify
258
-
259
- ```bash
260
- npm test -- login.test.ts
261
- # ✓ PASS
262
-
263
- # Full test run to ensure no regressions
264
- npm test
265
- # ✓ all pass
266
- ```
267
-
268
- ### Step 4.4: Commit the fix
269
-
270
- ```
271
- fix(auth): green - read email from req.body directly
272
-
273
- Root cause: validateUser expected req.body.user.email but API
274
- contract sends req.body.email directly. This caused TypeError
275
- on all login requests (100% failure).
276
-
277
- Phase 1-4 analysis:
278
- - Phase 1: traced data flow, found contract mismatch
279
- - Phase 2: 3 other routes use correct `req.body.{field}` pattern
280
- - Phase 3: hypothesis confirmed by minimal test
281
- - Phase 4: test + fix + full regression passed
282
-
283
- Fixes: #N
284
- ```
285
-
286
- ---
287
-
288
- ## 3-Failure Protection (Anti-Loop)
289
-
290
- ```python
291
- failed_attempts = 0
292
-
293
- while bug_not_fixed:
294
- run_4_phases()
295
- if failed:
296
- failed_attempts += 1
297
-
298
- if failed_attempts >= 3:
299
- STOP_AND_REPORT:
300
- """
301
- I tried 3 different approaches, all failed:
302
- 1. <method 1>: <why it failed>
303
- 2. <method 2>: <why it failed>
304
- 3. <method 3>: <why it failed>
305
-
306
- This suggests the underlying problem may be:
307
- - Wrong architecture (e.g., auth layer shouldn't own token mgmt)
308
- - Dependency issue (e.g., bcrypt version incompatibility)
309
- - Data issue (e.g., schema mismatches code)
310
- - Tests don't reflect real scenarios
311
-
312
- Recommendation: user intervention to decide direction.
313
- """
314
- ```
315
-
316
- **Key**: do not blindly attempt a 4th time. 3 failures mean your hypothesis framework is wrong — step back and see the big picture.
317
-
318
- ---
319
-
320
- ## Forbidden Anti-Patterns
321
-
322
- ### 1. Pray programming
323
-
324
- ```python
325
- for retry in range(10):
326
- try:
327
- do_thing()
328
- break
329
- except:
330
- pass
331
- ```
332
- This is not fixing the bug, it's **masking** it.
333
-
334
- ### 2. "Maybe it's..." attribution
335
-
336
- ```
337
- "Maybe it's a network issue" → didn't verify
338
- "Maybe permissions" → didn't ls -la
339
- "Maybe timezone" → didn't check timestamps
340
- ```
341
- **Verify** before attributing.
342
-
343
- ### 3. Fix without a failing test
344
-
345
- "I fixed it" → no test written → 6 months later a regression → debug again
346
-
347
- Every fix comes with:
348
- 1. A failing test that reproduces the bug
349
- 2. The fix
350
- 3. Test passes
351
-
352
- ### 4. Bypassing the root cause
353
-
354
- ```typescript
355
- // Bug: user.email is null causing crash
356
- // ✗ wrong fix: if (!user?.email) return defaultEmail
357
- // ✓ correct fix: trace data flow, find where email becomes null
358
- ```
359
-
360
- ### 5. Half-fix
361
-
362
- - ✗ Fixed one place, but similar code exists in 5 more
363
- - ✓ Phase 2 analysis identifies all cases, fixes all at once
364
-
365
- ---
366
-
367
- ## Summary
368
-
369
- ```
370
- The value of systematic debugging:
371
- Phase 1 ensures → don't fix on a hypothesis
372
- Phase 2 ensures → recognize patterns, avoid isolated cases
373
- Phase 3 ensures → know the fix works before applying
374
- Phase 4 ensures → fix is durable + regression-proof
375
-
376
- Unsystematic → fixes fast but fragile → bitten again by the same bug
377
- Systematic → fixes slow but thorough → solved once, never looked back
378
- ```