@brunosps00/dev-workflow 1.3.0 → 1.5.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 (63) hide show
  1. package/.claude-plugin/marketplace.json +13 -0
  2. package/.claude-plugin/plugin.json +31 -0
  3. package/README.md +24 -4
  4. package/lib/build-plugin.js +79 -0
  5. package/lib/constants.js +19 -14
  6. package/lib/doctor.js +33 -0
  7. package/lib/hooks.js +179 -0
  8. package/lib/init.js +68 -0
  9. package/lib/skill-registry.js +13 -0
  10. package/lib/uninstall.js +22 -3
  11. package/lib/validate.js +62 -0
  12. package/lib/wrappers.js +1 -1
  13. package/package.json +6 -1
  14. package/scaffold/config/stack-mappings.json +40 -0
  15. package/scaffold/en/commands/dw-analyze-project.md +5 -1
  16. package/scaffold/en/commands/dw-context-budget.md +9 -0
  17. package/scaffold/en/commands/dw-harness-audit.md +3 -0
  18. package/scaffold/en/commands/dw-learn.md +41 -0
  19. package/scaffold/en/commands/dw-plan.md +3 -0
  20. package/scaffold/en/commands/dw-review.md +2 -0
  21. package/scaffold/en/commands/dw-run.md +2 -0
  22. package/scaffold/en/commands/dw-update.md +4 -1
  23. package/scaffold/pt-br/commands/dw-analyze-project.md +5 -1
  24. package/scaffold/pt-br/commands/dw-context-budget.md +9 -0
  25. package/scaffold/pt-br/commands/dw-harness-audit.md +3 -0
  26. package/scaffold/pt-br/commands/dw-learn.md +41 -0
  27. package/scaffold/pt-br/commands/dw-plan.md +3 -0
  28. package/scaffold/pt-br/commands/dw-review.md +2 -0
  29. package/scaffold/pt-br/commands/dw-run.md +2 -0
  30. package/scaffold/pt-br/commands/dw-update.md +4 -1
  31. package/scaffold/rules/README.md +22 -0
  32. package/scaffold/rules/common.md +29 -0
  33. package/scaffold/rules/csharp.md +18 -0
  34. package/scaffold/rules/python.md +18 -0
  35. package/scaffold/rules/react.md +18 -0
  36. package/scaffold/rules/rust.md +18 -0
  37. package/scaffold/rules/typescript.md +23 -0
  38. package/scaffold/rules-readme.md +8 -0
  39. package/scaffold/scripts/hooks/git-guardrails.mjs +79 -0
  40. package/scaffold/scripts/hooks/session-cost.mjs +126 -0
  41. package/scaffold/scripts/hooks/statusline.mjs +118 -0
  42. package/scaffold/scripts/lib/model-prices.json +12 -0
  43. package/scaffold/skill-registry.json +27 -0
  44. package/scaffold/skills/dw-cli-run/SKILL.md +3 -1
  45. package/scaffold/skills/dw-codebase-intel/SKILL.md +3 -1
  46. package/scaffold/skills/dw-debug-protocol/SKILL.md +4 -0
  47. package/scaffold/skills/dw-debug-protocol/references/agent-degradation.md +30 -0
  48. package/scaffold/skills/dw-execute-phase/SKILL.md +13 -0
  49. package/scaffold/skills/dw-git-discipline/SKILL.md +1 -0
  50. package/scaffold/skills/dw-llm-eval/SKILL.md +12 -0
  51. package/scaffold/skills/dw-memory/SKILL.md +12 -1
  52. package/scaffold/skills/dw-memory/references/instincts.md +45 -0
  53. package/scaffold/skills/dw-minimalism/SKILL.md +98 -0
  54. package/scaffold/skills/dw-review-rigor/SKILL.md +12 -0
  55. package/scaffold/skills/dw-review-rigor/references/false-positives.md +21 -0
  56. package/scaffold/skills/dw-review-rigor/references/self-eval-rubric.md +38 -0
  57. package/scaffold/skills/dw-silent-failure/SKILL.md +4 -2
  58. package/scaffold/skills/dw-simplification/SKILL.md +13 -0
  59. package/scaffold/skills/dw-simplification/references/dead-code-tools.md +23 -0
  60. package/scaffold/skills/dw-testing-discipline/SKILL.md +17 -0
  61. package/scaffold/skills/dw-ui-discipline/SKILL.md +1 -1
  62. package/scaffold/skills/dw-verify/SKILL.md +1 -1
  63. package/scaffold/skills/dw-verify/references/pre-check-and-status.md +28 -0
@@ -52,7 +52,7 @@ Create `MEMORY.md` and `<N>_memory.md` on first use with the template below. Nev
52
52
  - Branch: <branch-name>
53
53
 
54
54
  ## Durable Decisions
55
- - <decision 1> — <one-line rationale>
55
+ - <decision 1> — <one-line rationale> — [confidence: 0.7; seen in tasks 1,3]
56
56
 
57
57
  ## Cross-Task Constraints
58
58
  - <constraint discovered during implementation that affects multiple tasks>
@@ -124,6 +124,16 @@ Before promoting an item from `<N>_memory.md` to `MEMORY.md`, ask:
124
124
 
125
125
  All three must be "yes" to promote. If any is "no", the item stays in task memory.
126
126
 
127
+ ### Confidence signal
128
+
129
+ Tag each durable decision with a confidence in `[0.3–0.9]` plus the tasks that confirmed it — `… — [confidence: 0.7; seen in tasks 1,3,5]`:
130
+
131
+ - Confirmed in **≥2 of the last 3 tasks** with no contradiction → **≥0.7** (trust it; safe to act on without re-deriving).
132
+ - Confirmed once, or inferred but not yet reused → **0.3–0.5** (tentative; gather more signal before relying).
133
+ - Contradicted by a later task or the repo → lower it or drop the decision (see Error Handling).
134
+
135
+ Confidence makes cross-task learning explicit and is the signal `/dw-learn` reads to promote high-confidence decisions into durable instincts, constitution principles, or rules.
136
+
127
137
  ### Belongs in shared memory
128
138
  - A discovered constraint affecting multiple tasks ("the Stripe API rate-limits to 100 req/s — batch operations must respect this")
129
139
  - A cross-cutting architectural decision made during implementation ("chose React Server Components for data fetching across the whole feature")
@@ -179,6 +189,7 @@ This budget is doctrine, not a hard gate. No command currently rejects work for
179
189
  - `/dw-run` — reads memory before coding; updates `<N>_memory.md` during; runs promotion test + updates `MEMORY.md` at the end.
180
190
  - `/dw-run` — runs promotion + compaction between tasks, so each task starts with clean shared state.
181
191
  - `/dw-autopilot` — threads memory through every phase (brainstorm → PRD → techspec → tasks → execution); on re-invocation reads `MEMORY.md` first to reconstitute cross-session context.
192
+ - `/dw-learn` — synthesizes confidence-tagged decisions here (plus bugfixes, deviations, git history) into atomic **instincts** in `.dw/memory/instincts/`; format, confidence rules, and promotion path in `references/instincts.md`.
182
193
 
183
194
  Callers should mention this skill in their "Skills Complementares" section.
184
195
 
@@ -0,0 +1,45 @@
1
+ # Instincts — promoting durable memory into reusable behavior
2
+
3
+ An instinct is a small, atomic, confidence-weighted behavior learned from THIS project's work, promotable
4
+ into a constitution principle or rule. Instincts live in `.dw/memory/instincts/*.md` and are proposed and
5
+ curated by `/dw-learn` — never written without explicit approval. There is no always-on observer; instincts
6
+ are synthesized on demand from what the project already recorded (see `/dw-learn` sources).
7
+
8
+ ## File format (`.dw/memory/instincts/<slug>.md`)
9
+
10
+ ```markdown
11
+ ---
12
+ id: prefer-result-type-in-services
13
+ trigger: when writing a service method that can fail
14
+ confidence: 0.7 # 0.3 tentative … 0.9 near-certain (same scale as durable decisions)
15
+ domain: error-handling # code-style | testing | error-handling | git | workflow | security
16
+ scope: project # project | global
17
+ evidence:
18
+ - "MEMORY.md decision (seen in tasks 3,5)"
19
+ - "bugfix 004-null-order — same root cause"
20
+ ---
21
+
22
+ # Prefer Result type in services
23
+
24
+ ## Action
25
+ Return a typed Result/union from fallible service methods instead of throwing across layers.
26
+
27
+ ## Why
28
+ Two bugfixes traced to exceptions swallowed between layers; the confidence-tagged decision in MEMORY.md
29
+ already prefers this.
30
+ ```
31
+
32
+ ## Confidence (reuse the promotion signal)
33
+
34
+ Same scale and rule as durable decisions (see the **Confidence signal** section of this skill): ≥2
35
+ independent confirmations in recent work → ≥0.7. Lower it when a later task contradicts the instinct; drop
36
+ it when it stops being true.
37
+
38
+ ## Promotion path
39
+
40
+ - **≥0.7, project scope** → propose as a `.dw/constitution.md` principle (via the `/dw-analyze-project`
41
+ Step 8 flow) or a note on the relevant `.dw/rules-library/<stack>.md`.
42
+ - **Seen across multiple projects** → mark `scope: global` (a candidate for a shipped rule/skill).
43
+
44
+ High-confidence instincts (≥0.7) whose `trigger` matches the current work are loaded on demand by `/dw-run`
45
+ and `/dw-plan` — the same lazy pattern as `.dw/rules/concerns.md`. Never bulk-load the whole instinct set.
@@ -0,0 +1,98 @@
1
+ ---
2
+ name: dw-minimalism
3
+ description: Pre-generation YAGNI gate. Before writing new code, infra, or abstractions, climb the decision ladder (need it? reuse? stdlib? native? installed dep? one line?) at the active lite/full/ultra intensity. Triggers from /dw-run, /dw-plan, /dw-review and any "add X / build Y" intent.
4
+ allowed-tools:
5
+ - Read
6
+ - Grep
7
+ - Glob
8
+ - Bash
9
+ ---
10
+
11
+ # dw-minimalism — Write the Least Code That Solves the Problem
12
+
13
+ The cheapest code to maintain is the code you never wrote. This skill runs a
14
+ **pre-generation gate**: before producing a new function, file, dependency, or
15
+ abstraction, justify it against a decision ladder. It is the missing rung
16
+ between `dw-search-first` (which evaluates *external dependencies*) and
17
+ `dw-simplification` (which cleans up code *after* it exists).
18
+
19
+ ## When to Use
20
+
21
+ Read this skill when:
22
+
23
+ - `/dw-plan` is about to specify new modules/services — pressure-test scope before tasks are written.
24
+ - `/dw-run` is about to implement — climb the ladder before the first line of new code.
25
+ - `/dw-review` flags over-engineering (speculative generality, premature abstraction, unused options).
26
+ - The user (or a task) says "add X", "build Y", "create a helper/wrapper/abstraction for Z".
27
+
28
+ Do NOT use to:
29
+
30
+ - Block code that is genuinely required by an accepted PRD/TechSpec acceptance criterion.
31
+ - Strip safety, validation, accessibility, security, or error handling — minimalism is about *necessity*, never about cutting correctness. Removing a guard is not minimalism.
32
+ - Re-litigate existing code you are not touching (that is `dw-simplification`'s scope discipline).
33
+
34
+ ## The Decision Ladder
35
+
36
+ Evaluate **in order** and stop at the first rung that resolves the need. Record which rung justified the decision.
37
+
38
+ 1. **Does it need to exist? (YAGNI)** — Is there a current, concrete requirement, or is this for an imagined future? No requirement → don't build it. Defer to a task/ADR instead.
39
+ 2. **Already in the codebase?** — Search first (`grep`/`glob`/`.dw/intel/`). Reuse an existing function, type, or pattern over a new one.
40
+ 3. **Standard library / language built-in?** — Prefer the platform's own primitives over hand-rolled equivalents.
41
+ 4. **Native framework feature?** — The framework/runtime already in use may cover it (routing, validation, caching, etc.).
42
+ 5. **An already-installed dependency?** — Use a package the project already depends on before adding a new one. (New dependency → hand off to `dw-search-first` for the adopt/wrap/compose/build decision.)
43
+ 6. **Can it be one line / inlined?** — A small inline expression often beats a new helper, indirection layer, or config knob. Don't extract until there are real, repeated call sites.
44
+ 7. **Only then: the minimum viable implementation** — the smallest change that satisfies the requirement, no speculative parameters, hooks, or generality.
45
+
46
+ If you cannot name the rung that justifies the code, you are not ready to write it.
47
+
48
+ ## Intensity Modes
49
+
50
+ The active mode is read from `.dw/minimalism.json` (`{"mode":"full"}`); default `full` when absent.
51
+
52
+ | Mode | Behavior |
53
+ |------|----------|
54
+ | `off` | Skill is dormant; no minimalism gate applied. |
55
+ | `lite` | Apply rungs 1–2 only (YAGNI + reuse). Light touch; flags only obvious over-build. |
56
+ | `full` | **Default.** Apply the full ladder; flag speculative generality and premature abstraction. |
57
+ | `ultra` | Aggressive. Prefer inlining over any new helper/file; demand explicit justification for every new module, dependency, parameter, and config option. |
58
+
59
+ Stricter modes raise the bar for "this needs to exist"; none of them authorize cutting correctness, validation, or security.
60
+
61
+ ## Anti-patterns this gate catches
62
+
63
+ - A new utility/wrapper with a single caller (rung 6 — inline it).
64
+ - A config flag, strategy interface, or plugin point with exactly one implementation (rung 1 — YAGNI).
65
+ - A hand-rolled debounce/clone/group-by/date-format when stdlib or an installed dep already has it (rungs 3–5).
66
+ - A new dependency for a few lines of logic (rung 5 → `dw-search-first`).
67
+ - "Future-proofing" abstractions for requirements that do not exist yet (rung 1).
68
+
69
+ ## Red Flags (stop and climb the ladder)
70
+
71
+ "we'll probably need", "to be safe", "make it generic", "for flexibility",
72
+ "in case we want to", a base class / interface with one subclass, an options
73
+ object where every caller passes the same value.
74
+
75
+ ## Composition
76
+
77
+ - **New external dependency?** → hand off to `dw-search-first` (adopt / wrap / compose / build).
78
+ - **Code already exists and is too complex?** → that is `dw-simplification` (Chesterton's Fence, behavior-preserving).
79
+ - This skill sits *before* both: it decides whether the code should be written at all.
80
+
81
+ ## Structured Return
82
+
83
+ When invoked directly or by a harness, return or merge this block:
84
+
85
+ - **Status:** `PASS` when the proposed code is the minimum justified by a ladder rung, `FINDINGS` when over-build is detected and a leaner alternative exists, `BLOCKED` when the requirement is too unclear to judge necessity, `NOT_APPLICABLE` when no new code/dependency/abstraction is being introduced.
86
+ - **Scope:** the proposed code, the requirement it serves, and the active intensity mode.
87
+ - **Evidence:** the ladder rung that justified (or failed) the code, search hits for existing reuse, stdlib/native/installed-dep alternatives checked.
88
+ - **Artifacts:** the leaner alternative, a deferral task/ADR for speculative work, or the minimal implementation sketch.
89
+ - **Decisions:** build / reuse / inline / use-existing-dep / defer / skip — with the rejected heavier option.
90
+ - **Risks:** correctness or safety that must NOT be cut, hidden requirement that could justify more, future cost of the deferral.
91
+ - **Next Step:** write the minimal version, reuse the found code, or hand off to `dw-search-first`/`dw-simplification`.
92
+
93
+ ## Inspired by
94
+
95
+ Adapted from [`DietrichGebert/ponytail`](https://github.com/DietrichGebert/ponytail)
96
+ (MIT) — the "lazy senior developer" decision ladder and lite/full/ultra intensity
97
+ modes. Rebased on dev-workflow conventions and wired to compose with
98
+ `dw-search-first` and `dw-simplification`.
@@ -21,6 +21,17 @@ By `/dw-review --code-only`, `/dw-review --coverage-only`, `/dw-refactor`, and `
21
21
  - The scope the caller is reviewing (file paths, directories, or PR diff).
22
22
  - Optional: prior review reports in `.dw/spec/prd-*/reviews/` — so this round only surfaces NEW findings.
23
23
 
24
+ ## Pre-Report Gate
25
+
26
+ Before writing ANY finding, clear four checks — if any is "no"/"unsure", downgrade or drop it (an unactionable finding is noise):
27
+
28
+ 1. **Location** — exact file and line?
29
+ 2. **Failure mode** — a concrete input/state and the bad outcome it produces?
30
+ 3. **Context** — read the surrounding code (callers, imports, tests), not just the flagged line?
31
+ 4. **Severity** — defensible against Rule 2's definitions? (a missing JSDoc is never HIGH)
32
+
33
+ Report only findings you are **>80% confident** are real. A style preference no rule backs is not a finding. See `references/false-positives.md` for patterns LLM reviewers habitually mis-flag.
34
+
24
35
  ## The Five Rules
25
36
 
26
37
  ### 1. De-duplicate before writing
@@ -111,6 +122,7 @@ The caller emits:
111
122
  2. **Counts** — critical / high / medium / low.
112
123
  3. **Findings** — ordered by severity, each in the format above.
113
124
  4. **Well-implemented aspects** — short bulleted list, calibrates tone.
125
+ 5. **Self-score** — rate the report on the five axes in `references/self-eval-rubric.md`; any axis below top cites the gap, then fix (<30s) or flag.
114
126
 
115
127
  ## Critical Rules
116
128
 
@@ -0,0 +1,21 @@
1
+ # False Positives — patterns LLM reviewers habitually mis-flag
2
+
3
+ Loaded on demand by the Pre-Report Gate. Skip these unless you have evidence **specific to this codebase**
4
+ (a failing test, a real caller that doesn't guard, a project rule that forbids it). Flagging them anyway is
5
+ the most common way an AI review drowns real findings in noise.
6
+
7
+ | Tempting finding | Why it's usually wrong |
8
+ |---|---|
9
+ | "Add error handling here" | The error path is already handled by the caller or the framework — Express/Koa middleware, a React error boundary, a top-level `catch`, or a job runner that retries. Trace one level up before flagging. |
10
+ | "Missing input validation" | The function is internal and every caller already validated at the boundary. Validation belongs at the trust boundary, not on every hop. |
11
+ | "Magic number" | Well-known constants are self-documenting: HTTP codes (200/404/500), `1000`/`60`/`24`/`1024`, array index `0`/`-1`, `100` for percent. Only flag opaque domain numbers with no name. |
12
+ | "Function too long" | Length ≠ complexity. Exhaustive `switch`, config/lookup objects, test tables, and generated code are long *and* simple. Flag high branching/nesting, not line count. |
13
+ | "Missing JSDoc/docstring" | Internal helpers whose name and signature are self-describing don't need docs. Reserve for public API or non-obvious contracts. |
14
+ | "Possible null dereference" | A preceding line already narrowed the type or an `if` guard is in scope. Read the few lines above before asserting. |
15
+ | "Use `const` / style nit" | The linter/formatter already enforces this (Rule 4). It is a linter task, not a review finding. |
16
+ | "This could be a race condition" | Only real if there is actual shared mutable state across concurrent paths. A single-threaded request handler touching a local variable is not a race. |
17
+ | "Add a test for this" | Valid only if the behavior is untested AND load-bearing. Don't demand tests for trivial getters or framework glue. |
18
+ | "Extract this into a helper (DRY)" | Two similar lines are not duplication worth an abstraction. Premature extraction couples unrelated call sites — see `dw-minimalism`. |
19
+
20
+ **Rule of thumb:** if the "fix" would be rejected by a competent maintainer as busywork, it is a false
21
+ positive. When unsure whether a pattern is intentional, apply Rule 3 (verify intent) before writing it.
@@ -0,0 +1,38 @@
1
+ # Self-Evaluation Rubric — five axes, evidence required
2
+
3
+ A structured way for an agent to rate its own output **before** handing it over, without waiting for user
4
+ feedback. Used by `dw-review-rigor` (score the review itself) and cited by `dw-cli-run` (the 0–10 delivery
5
+ gate applies the same evidence discipline). Adapted from the ECC `agent-self-evaluation` skill.
6
+
7
+ ## The five axes (score each 1–5)
8
+
9
+ | Axis | Question | What a low score catches |
10
+ |---|---|---|
11
+ | **Accuracy** | Are the facts, claims, and code correct? | Hallucinated APIs, wrong file paths, syntax errors, unverified assertions |
12
+ | **Completeness** | Did it cover everything the request asked? | Missed edge cases, skipped subtasks, unhandled error paths |
13
+ | **Clarity** | Is it understandable and well-structured? | Confusing explanations, jargon, rambling, missing context |
14
+ | **Actionability** | Can the user act on it immediately? | Vague suggestions, missing steps, "you should X" without showing how |
15
+ | **Conciseness** | Is it the minimum needed to be complete? | Redundancy, over-explanation, filler, restating the question |
16
+
17
+ Scale: **5** = no reasonable improvement · **4** = minor nits · **3** = one notable weakness · **2** = a clear
18
+ gap that hurts usability · **1** = fundamentally misses the request.
19
+
20
+ ## The one hard rule: evidence for every score below 5
21
+
22
+ A score under 5 **must cite the specific gap** — quote the line, name the missing case, point at the
23
+ redundancy. "Completeness: 3 — doesn't handle the empty-array case in `parse()`" is a real score;
24
+ "Completeness: 3 — could be more thorough" is hand-waving and not allowed.
25
+
26
+ ## What to do with the scores
27
+
28
+ 1. Score each axis independently (don't average away a real weakness).
29
+ 2. If any axis is **≤ 3**: fix it now when the fix is under ~30 seconds; otherwise flag it explicitly in the
30
+ output so the user knows the gap exists.
31
+ 3. Keep the self-score short — a few lines, not a second report.
32
+
33
+ ## Anti-patterns
34
+
35
+ - **"Everything is a 5"** with no evidence — the most common failure; it means you didn't actually evaluate.
36
+ - **Over-penalizing scope** — grade only what was requested, not scope you invented.
37
+ - **Re-litigating decisions** — evaluate execution quality, not whether a settled decision was right.
38
+ - **Personal preference as a gap** — a nit the linter doesn't enforce and no rule backs is not a real deduction.
@@ -19,7 +19,8 @@ Use during `/dw-review`, `/dw-bugfix`, and `/dw-qa --fix` when failures may be h
19
19
  - Log-only handling where callers need the failure.
20
20
  - Generic rethrows that lose stack or input context.
21
21
  - Async work launched without awaiting, tracking, or explicit detachment.
22
- - Network/database/filesystem calls without timeout or rollback where the project requires it.
22
+ - Network/database/filesystem calls without a **timeout** — the call can hang indefinitely and block everything waiting on it.
23
+ - Transactional work (multi-step writes, DB mutations, chained external calls) without **rollback** on partial failure — leaves silently corrupted or half-written state.
23
24
 
24
25
  ## Reporting Standard
25
26
 
@@ -27,7 +28,8 @@ Only flag a finding when you can name:
27
28
 
28
29
  - the exact location,
29
30
  - the trigger,
30
- - the hidden bad outcome,
31
+ - the severity (critical / high / medium),
32
+ - the hidden bad outcome and its impact (what the user or system experiences when it fires),
31
33
  - the minimal fix.
32
34
 
33
35
  Inspired by ECC's `silent-failure-hunter`; adapted as both a skill and a dispatchable `dw-silent-failure-hunter` agent.
@@ -99,6 +99,18 @@ If a simplification touches >500 lines, **don't do it manually**. Use:
99
99
 
100
100
  Manual edits across hundreds of lines are how subtle bugs creep in.
101
101
 
102
+ ## Refactor risk levels
103
+
104
+ Before removing or restructuring, categorize by blast radius and act in that order — never all at once:
105
+
106
+ | Risk | Examples | Discipline |
107
+ |------|----------|-----------|
108
+ | **SAFE** | Unused exports, unused deps, unreachable branches | Batch-remove, run the gate after each batch, commit |
109
+ | **CAREFUL** | Consolidate duplicates, extract/inline, rename symbol | One or two per commit; re-read callers first |
110
+ | **RISKY** | Change a public API, alter a data structure, extract a layer | One per commit; regression tests first; pair review / ADR |
111
+
112
+ Start with SAFE and graduate only after the gate is green. For finding SAFE candidates on JS/TS (and other ecosystems), see `references/dead-code-tools.md`. This composes with Chesterton's Fence (Rule 1) — a tool calling code "unused" still needs the WHY check before deletion (reflection, dynamic imports, and framework entry points are invisible to static analysis).
113
+
102
114
  ## Verification protocol
103
115
 
104
116
  Before committing the simplification:
@@ -139,6 +151,7 @@ In the formal Level 3 review (post-Level 2 chain from `dw-review-implementation`
139
151
  - `references/complexity-metrics.md` — when each metric (cyclomatic, cognitive, depth, fanout) actually matters; how to measure cheaply.
140
152
  - `references/behavior-preserving.md` — characterization tests, refactor with test gate, rollback patterns, codemod tooling per language.
141
153
  - `references/deep-modules.md` — high-leverage modules behind small interfaces; deletion test, locality, leverage, seam, adapter diagnostic; anti-patterns (shallow wrapper, god-module). Invoked by `/dw-refactor` and `/dw-brainstorm` refactor-audit mode.
154
+ - `references/dead-code-tools.md` — per-ecosystem tools that surface SAFE-tier dead-code candidates (knip/depcheck/ts-prune for JS/TS; vulture/ruff for Python; deadcode/staticcheck for Go; cargo-udeps for Rust). Candidates still pass Chesterton's Fence before deletion.
142
155
 
143
156
  ## Inspired by
144
157
 
@@ -0,0 +1,23 @@
1
+ # Dead-code detection tools (find candidates; then apply Chesterton's Fence)
2
+
3
+ Detection tools surface **candidates** — they do not know about reflection, dynamic imports, framework
4
+ entry points, or external consumers of a public API. Every hit is a SAFE-tier candidate to verify, not an
5
+ automatic deletion. Run the gate (lint + tests + build) after each batch.
6
+
7
+ ## JavaScript / TypeScript
8
+ - `npx knip` — unused files, exports, and dependencies in one pass (the broadest single tool).
9
+ - `npx depcheck` — unused and missing npm dependencies.
10
+ - `npx ts-prune` — unused TypeScript exports.
11
+ - `npx eslint . --report-unused-disable-directives` — stale `eslint-disable` comments.
12
+
13
+ ## Other ecosystems
14
+ - **Python:** `vulture`, `ruff` (`F401` unused imports), `deptry` (unused dependencies).
15
+ - **Go:** `deadcode` (golang.org/x/tools/cmd/deadcode), `staticcheck` (`U1000`).
16
+ - **Rust:** `cargo +nightly udeps` (unused deps), the compiler's own `dead_code` warnings.
17
+ - **C# / .NET:** Roslyn analyzers (`IDE0051` unused private member, `IDE0059` unnecessary assignment).
18
+
19
+ ## Discipline
20
+ 1. Run the tool; treat every result as a **SAFE-tier candidate**, not a confirmed removal.
21
+ 2. For each candidate, apply Chesterton's Fence (Rule 1) — dynamic/reflective/plugin use won't appear in static analysis.
22
+ 3. Remove in batches by category (deps → exports → files); run the gate after each batch; commit per batch.
23
+ 4. Anything the tool flags that turns out to be load-bearing → add a comment explaining why, so the next pass doesn't re-flag it.
@@ -38,6 +38,23 @@ Each rule has nuance read `references/core-rules.md` for the long version with e
38
38
  - Verifying browser-side trust boundaries (auth, CSRF, headers) → `references/security-boundary.md`.
39
39
  - Picking which test workflow applies (UI / network / perf) → `references/three-workflow-patterns.md`.
40
40
 
41
+ ## Step 0 — detect the runner before writing any test
42
+
43
+ Do not assume `npm test`. The package manager and the test runner are different things — confirm both:
44
+
45
+ 1. Read `package.json` `scripts.test` (plus `test:watch` / `test:coverage`), or the language equivalent (`pyproject.toml`/`tox.ini`, `Cargo.toml`, `*.csproj`, `go.mod`).
46
+ 2. Identify the actual runner: jest / vitest / mocha / `node:test` / `bun:test` / pytest / `go test` / `cargo test` / `dotnet test`.
47
+ 3. Invoke it through the project's package manager, not a hardcoded `npm`:
48
+
49
+ | Manager | test | watch | coverage |
50
+ |---|---|---|---|
51
+ | npm | `npm test` | `npm test -- --watch` | `npm run test:coverage` |
52
+ | pnpm | `pnpm test` | `pnpm test --watch` | `pnpm test:coverage` |
53
+ | yarn | `yarn test` | `yarn test --watch` | `yarn coverage` |
54
+ | bun (native) | `bun test` | `bun test --watch` | `bun test --coverage` |
55
+
56
+ **Bun gotcha:** `bun test` runs Bun's native runner (`bun:test`); `bun run test` runs whatever `scripts.test` is (often jest/vitest). They are not interchangeable — use the one the project actually configures. When unsure, confirm with `<runner> --help`.
57
+
41
58
  ## Reference router
42
59
 
43
60
  | Doing what | Read |
@@ -34,7 +34,7 @@ Find the project's design source-of-truth in this order:
34
34
  4. Component library config — `components.json` for shadcn, theme exports.
35
35
  5. Storybook stories (implicit canonical components).
36
36
 
37
- If **at least one** exists: it wins. Defer to it. If a needed token is missing (e.g., a danger-secondary color), propose adding it to the authority FIRST, not inline.
37
+ **Stop at the first match** in this list — that source is the authority; defer to it and do not override it with a lower rung or a training-data default. If a needed token is missing (e.g., a danger-secondary color), propose adding it to the authority FIRST, not inline.
38
38
 
39
39
  If **none exists**: read `references/curated-defaults.md` and pick one of the 10 neutral palettes + one of the 10 font pairings shipped there. Mark the choice in the techspec/PR description: "Design source: no project authority found; using curated default `<name>`; recommend establishing `DESIGN.md`."
40
40
 
@@ -160,7 +160,7 @@ Verification failure is information, not a dead end. Protocol:
160
160
 
161
161
  Discover the project gate before claiming success. Prefer documented gates in `.dw/rules/`, then package scripts such as `verify`, `check`, `ci`, or `test`, then Makefile/just/pyproject equivalents. If no verification command exists, state that explicitly in the Verification Report and avoid completion language.
162
162
 
163
- Load `references/verification-discovery-and-attribution.md` when you need the full discovery checklist, command integration table, or attribution notes.
163
+ Load `references/verification-discovery-and-attribution.md` for the discovery checklist and attribution notes, or `references/pre-check-and-status.md` for the cheap diff-hygiene grep and the compact polling status line.
164
164
 
165
165
  ## Structured Return
166
166
 
@@ -0,0 +1,28 @@
1
+ # Cheap pre-check + compact status
2
+
3
+ Two lightweight companions to the full verification gate. Neither replaces the Verification Report — they
4
+ run *around* it.
5
+
6
+ ## Diff hygiene (cheap pre-commit grep)
7
+
8
+ Before running the full pipeline, one fast grep over the staged diff catches the most common "left it in"
9
+ mistakes:
10
+
11
+ ```bash
12
+ git diff --cached | grep -nE 'console\.(log|debug)|debugger|TODO: *remove|sk-[A-Za-z0-9]|api[_-]?key|password *='
13
+ ```
14
+
15
+ Hits are a smell to clear, not a gate by themselves. This is **not** the security gate — `/dw-secure-audit`
16
+ (gitleaks + Trivy + Semgrep) remains the authoritative secret/vuln check before commit/PR. Use this grep as a
17
+ 2-second sanity pass, then run the real pipeline.
18
+
19
+ ## Compact status (for real-time polling)
20
+
21
+ When a runner (e.g. `dw-cli-run`) polls progress *between* full reports, a one-line form is enough:
22
+
23
+ ```
24
+ Build: PASS | Lint: PASS | Tests: 42/42 | Verdict: READY
25
+ ```
26
+
27
+ The compact line never replaces the full report — the final completion claim still requires the Verification
28
+ Report Template with cited command output. Use the compact line for progress, the full template for the claim.