@brunosps00/dev-workflow 2.0.0 → 2.2.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 (84) hide show
  1. package/.claude-plugin/marketplace.json +1 -0
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +176 -0
  4. package/README.md +10 -5
  5. package/lib/build-plugin.js +4 -1
  6. package/lib/constants.js +8 -2
  7. package/lib/init.js +26 -0
  8. package/lib/validate.js +21 -0
  9. package/package.json +1 -1
  10. package/scaffold/en/agent-instructions.md +2 -0
  11. package/scaffold/en/commands/dw-autopilot.md +2 -0
  12. package/scaffold/en/commands/dw-brainstorm.md +12 -8
  13. package/scaffold/en/commands/dw-bugfix.md +4 -2
  14. package/scaffold/en/commands/dw-claude-run.md +1 -1
  15. package/scaffold/en/commands/dw-codex-run.md +1 -1
  16. package/scaffold/en/commands/dw-copilot-run.md +1 -1
  17. package/scaffold/en/commands/dw-harness-audit.md +2 -0
  18. package/scaffold/en/commands/dw-help.md +6 -2
  19. package/scaffold/en/commands/dw-pause.md +1 -0
  20. package/scaffold/en/commands/dw-plan.md +2 -2
  21. package/scaffold/en/commands/dw-refactor.md +1 -0
  22. package/scaffold/en/commands/dw-report.md +169 -0
  23. package/scaffold/en/commands/dw-review.md +33 -2
  24. package/scaffold/en/commands/dw-run.md +3 -1
  25. package/scaffold/en/commands/dw-triage.md +220 -0
  26. package/scaffold/en/commands/dw-worktree.md +100 -0
  27. package/scaffold/en/templates/idea-onepager.md +28 -0
  28. package/scaffold/en/templates/task-template.md +1 -0
  29. package/scaffold/en/templates/tasks-template.md +9 -8
  30. package/scaffold/en/templates/triage-needs-info-template.md +23 -0
  31. package/scaffold/en/templates/triage-out-of-scope-template.md +36 -0
  32. package/scaffold/en/templates/triage-record-template.md +88 -0
  33. package/scaffold/pt-br/agent-instructions.md +2 -0
  34. package/scaffold/pt-br/commands/dw-autopilot.md +83 -81
  35. package/scaffold/pt-br/commands/dw-brainstorm.md +12 -9
  36. package/scaffold/pt-br/commands/dw-bugfix.md +4 -2
  37. package/scaffold/pt-br/commands/dw-claude-run.md +20 -20
  38. package/scaffold/pt-br/commands/dw-codex-run.md +20 -20
  39. package/scaffold/pt-br/commands/dw-context-budget.md +10 -10
  40. package/scaffold/pt-br/commands/dw-copilot-run.md +21 -21
  41. package/scaffold/pt-br/commands/dw-dockerize.md +102 -102
  42. package/scaffold/pt-br/commands/dw-find-skills.md +52 -52
  43. package/scaffold/pt-br/commands/dw-goal.md +41 -41
  44. package/scaffold/pt-br/commands/dw-harness-audit.md +13 -11
  45. package/scaffold/pt-br/commands/dw-help.md +6 -2
  46. package/scaffold/pt-br/commands/dw-intel.md +70 -70
  47. package/scaffold/pt-br/commands/dw-learn.md +24 -24
  48. package/scaffold/pt-br/commands/dw-new-project.md +88 -88
  49. package/scaffold/pt-br/commands/dw-open-design.md +53 -53
  50. package/scaffold/pt-br/commands/dw-opportunities.md +45 -45
  51. package/scaffold/pt-br/commands/dw-pause.md +40 -39
  52. package/scaffold/pt-br/commands/dw-plan.md +2 -2
  53. package/scaffold/pt-br/commands/dw-refactor.md +31 -30
  54. package/scaffold/pt-br/commands/dw-report.md +169 -0
  55. package/scaffold/pt-br/commands/dw-resume.md +22 -22
  56. package/scaffold/pt-br/commands/dw-review.md +33 -2
  57. package/scaffold/pt-br/commands/dw-run.md +3 -1
  58. package/scaffold/pt-br/commands/dw-skill-health.md +10 -10
  59. package/scaffold/pt-br/commands/dw-subtask-complete.md +4 -4
  60. package/scaffold/pt-br/commands/dw-subtask-start.md +4 -4
  61. package/scaffold/pt-br/commands/dw-triage.md +220 -0
  62. package/scaffold/pt-br/commands/dw-worktree.md +100 -0
  63. package/scaffold/pt-br/templates/bugfix-summary-template.md +20 -20
  64. package/scaffold/pt-br/templates/concerns-template.md +20 -20
  65. package/scaffold/pt-br/templates/idea-onepager.md +28 -0
  66. package/scaffold/pt-br/templates/project-onepager.md +32 -32
  67. package/scaffold/pt-br/templates/state-template.md +13 -13
  68. package/scaffold/pt-br/templates/task-template.md +1 -0
  69. package/scaffold/pt-br/templates/tasks-template.md +9 -8
  70. package/scaffold/pt-br/templates/triage-needs-info-template.md +23 -0
  71. package/scaffold/pt-br/templates/triage-out-of-scope-template.md +36 -0
  72. package/scaffold/pt-br/templates/triage-record-template.md +88 -0
  73. package/scaffold/scripts/hooks/git-guardrails.mjs +42 -24
  74. package/scaffold/scripts/lib/worktree-gc.mjs +460 -0
  75. package/scaffold/skill-registry.json +1 -1
  76. package/scaffold/skills/dw-cli-run/SKILL.md +10 -1
  77. package/scaffold/skills/dw-debug-protocol/SKILL.md +2 -0
  78. package/scaffold/skills/dw-debug-protocol/references/six-step-triage.md +60 -1
  79. package/scaffold/skills/dw-execute-phase/references/wave-coordination.md +14 -14
  80. package/scaffold/skills/dw-grilling/SKILL.md +17 -7
  81. package/scaffold/skills/dw-grilling/references/decision-tree.md +30 -7
  82. package/scaffold/skills/dw-simplification/references/deep-modules.md +50 -0
  83. package/scaffold/skills/dw-testing-discipline/SKILL.md +3 -1
  84. package/scaffold/skills/dw-testing-discipline/references/tdd-loop.md +83 -0
@@ -29,6 +29,7 @@ You are a session-handoff agent. Your job is to consolidate the current session'
29
29
  Read the conversation context and identify, **without inventing**:
30
30
 
31
31
  - **Open loops**: tasks/work started but not finished (e.g. "PRD `prd-foo` is at TechSpec stage, awaiting user approval"; "Task 3 of `prd-bar` failing on lint")
32
+ - **Leftover worktrees**: run `node .dw/scripts/lib/worktree-gc.mjs list`. Every `REMOVABLE` entry is an open loop to close **now** with `/dw-worktree clean --apply` — not something to record; `KEEP:*` entries go under Open Loops with their verdict and reason.
32
33
  - **Decisions made**: choices the user and agent agreed on during the session that affect future work
33
34
  - **Blockers encountered**: things that stopped forward motion (waiting on input, broken tooling, knowledge gap)
34
35
  - **Todos** mentioned in passing that don't yet have a PRD or task file
@@ -69,7 +69,7 @@ Before Stage 1, check for an idea one-pager at `.dw/spec/ideas/<slug>.md` and th
69
69
  - `schema_version: "1.1"`;
70
70
  - `status: aligned`;
71
71
  - `alignment.confirmed_by_user: true`;
72
- - every dependency branch is resolved (no open decision node);
72
+ - the **Decision Map** has every dependency branch resolved (no open decision node and `Frontier: none`);
73
73
  - glossary/code contradictions are closed;
74
74
  - no **blocking** entry remains under Remaining Decisions.
75
75
  If ANY check fails — or the file is malformed, internally inconsistent, `draft`, or `paused` — the one-pager is **input, not a trusted handoff**: read it for context, but treat all its decisions as **uncovered** and ask them normally. Never suppress a product question on the strength of `status: aligned` alone; `alignment.confirmed_by_user: true` and a resolved, non-blocking, contradiction-free tree are required too.</critical>
@@ -167,7 +167,7 @@ Runs when default mode (after TechSpec approval) OR `plan tasks`.
167
167
  4. **Test placement (`dw-testing-discipline`):** every test-adding subtask names its invariant per the placement doctrine. Owning layer specified.
168
168
  5. **Constitution alignment:** every task lists `Constitution: respects P-NNN` or `Constitution: deviates P-NNN — ADR planned: <slug>` or `Constitution: n/a — reason: <one-liner>`.
169
169
  6. **LLM-eval subtask (when applicable):** if the PRD has an AI feature, one task must include an Eval Plan subtask (reference dataset path, oracle rungs, judge calibration, target metrics).
170
- 7. **Dependency declaration:** each task explicitly lists which previous tasks it depends on. Validation rejects cycles.
170
+ 7. **Dependency declaration:** each task explicitly lists which previous tasks it depends on. Write the field as `Depends on: none` or `Depends on: 1.0, 2.0` in `tasks.md` and each `<N>_task.md`. Validation rejects cycles.
171
171
  8. **Output locations:**
172
172
  - Summary: `.dw/spec/prd-<feature-slug>/tasks.md`
173
173
  - Per-task files: `.dw/spec/prd-<feature-slug>/<N>_task.md`
@@ -29,6 +29,7 @@ You are the dev-workflow refactor audit entrypoint. This command restores an exp
29
29
  - Using Fowler smell taxonomy.
30
30
  - Loading `dw-review-rigor` and `dw-simplification` when available.
31
31
  - Applying Chesterton's Fence and deep-modules analysis before proposing a refactor.
32
+ - Loading the advanced deep-modules sections (`Dependency categories decide seam tests` and `Design It Twice for interface findings`) only when the surviving finding is a shallow interface, interface leak, or seam in the wrong place.
32
33
  - De-duplicating findings and severity-ordering P0-P3.
33
34
  - Saving the output to `<target>/refactor-plan.md`.
34
35
  5. If the target does not exist or is too broad, use the clarification questions to narrow it before scanning.
@@ -0,0 +1,169 @@
1
+ <system_instructions>
2
+ You are the progress-report loop. While long work is running in this session, you emit a detailed, timestamped report at a fixed cadence (default every 10 minutes) saying **what is already done, what is being done right now, and what is still left** — without the user having to ask "any news?". Each report goes to the chat AND is appended to a daily log under `.dw/reports/`. The loop disarms itself when the work is finished.
3
+
4
+ ## When to Use
5
+ - Use when the user says "report every N minutes", "keep me posted while this runs", "give me status reports", "I want to know where we are every 10 minutes".
6
+ - Auto-armed by `/dw-run` (all-tasks and `--resume` modes), by `/dw-autopilot` (execution invocation), and by the `dw-cli-run` adapters (`/dw-codex-run`, `/dw-claude-run`, `/dw-copilot-run`) when they dispatch long work. Auto-arm is idempotent and can be disabled with `DW_REPORT_AUTO=off`.
7
+ - Do NOT use as a substitute for `/dw-pause` (mental-state handoff) or `/dw-goal status` (goal contract state). This is a heartbeat about work in flight, not durable project state.
8
+ - Do NOT use to poll a background task the harness already notifies you about — the loop reports *around* those notifications; it never replaces them.
9
+
10
+ ## Pipeline Position
11
+ **Predecessor:** any long-running command (`/dw-run`, `/dw-autopilot`, `/dw-goal`, `/dw-codex-run`, builds, deploys) | **Successor:** none — the loop ends with a final report; `/dw-pause` may consume the day's log.
12
+
13
+ ## Modes
14
+
15
+ | Invocation | Behavior |
16
+ |------------|----------|
17
+ | `/dw-report` | Arm the loop at the default cadence (**10 minutes**). If already armed, print the current state and do nothing else. |
18
+ | `/dw-report --every <N>m` | Arm (or re-arm) the loop at `N` minutes (`5m`, `10m`, `15m`, `30m`; `--every 600s` also accepted). Minimum `1m`. |
19
+ | `/dw-report now` | Emit one report immediately, without touching the cadence. Works armed or not. |
20
+ | `/dw-report status` | Show whether the loop is armed, the cadence, when it was armed, the last report time, how many reports were emitted, and the log path. |
21
+ | `/dw-report stop` | Disarm. Emits a final report first if there is unreported progress. |
22
+
23
+ ## Inputs
24
+
25
+ | Variable | Description | Example |
26
+ |----------|-------------|---------|
27
+ | `{{EVERY}}` | Cadence. Optional; defaults to `10m`. | `--every 5m` |
28
+ | `DW_REPORT_AUTO` | Env var. `off` disables auto-arm from other commands (manual `/dw-report` still works). | `DW_REPORT_AUTO=off` |
29
+ | `DW_REPORT_BELL` | Env var. Optional shell command executed right before each report is written (local sound, desktop notification, etc.). Silent when unset. | `DW_REPORT_BELL="paplay /usr/share/sounds/freedesktop/stereo/message.oga"` |
30
+
31
+ `report.bell` in `.dw/config.json` is the file-based equivalent of `DW_REPORT_BELL` (env var wins). Because the bell is machine-specific, prefer the env var over committing it.
32
+
33
+ ## State and Artifacts
34
+
35
+ ```
36
+ .dw/reports/
37
+ ├── .gitignore # ????-??-??.md and .active.json are machine-local (created by init/update)
38
+ ├── .active.json # loop state — exists only while armed
39
+ └── YYYY-MM-DD.md # append-only daily log; one entry per emitted report
40
+ ```
41
+
42
+ `.active.json` schema:
43
+
44
+ ```json
45
+ {
46
+ "schema_version": "1.0",
47
+ "armed_at": "2026-08-24 15:10:02",
48
+ "every_seconds": 600,
49
+ "vehicle": "wakeup | background-bash",
50
+ "armed_by": "user | dw-run | dw-autopilot | dw-cli-run",
51
+ "seq": 3,
52
+ "last_report_at": "2026-08-24 15:40:12",
53
+ "last_state": "working | blocked | finished"
54
+ }
55
+ ```
56
+
57
+ Timestamps are **real** — always taken from `date '+%Y-%m-%d %H:%M:%S'`, never estimated.
58
+
59
+ ## Vehicle — how the loop stays alive
60
+
61
+ <critical>The main thread never sleeps in the foreground. Pick ONE vehicle, record it in `.active.json`, and never claim "loop armed" unless that vehicle is actually scheduled.</critical>
62
+
63
+ 1. **Native wakeup (PREFERRED — Claude Code).** Use the harness's scheduled-wakeup facility (the same mechanism as `/loop` in self-paced mode): after every tick, schedule the next wake-up in `every_seconds`. Pass `noop: true` on a silent tick and `noop: false` on a tick that reported. The `reason` is `dw-report tick every <N>m`. The loop dies with the session — no orphan.
64
+ 2. **Background shell timer (FALLBACK — Codex, Copilot, OpenCode, or any harness without wakeups).** Run, in the background, `sleep <every_seconds>; date '+%Y-%m-%d %H:%M:%S'`. When its completion notification arrives, run the tick, then start the next timer. One timer at a time; never chain sleeps in the foreground.
65
+ 3. **Never a system cron.** A cron does not know when the work ended and keeps firing (and ringing the bell) for days. If the harness only offers cron-style scheduling, use it but treat `/dw-report stop` and the auto-disarm rule as mandatory cleanup.
66
+
67
+ If the work changes vehicle mid-way (e.g. the session is resumed elsewhere), `/dw-report status` must say so honestly: `armed in state file, but no wake-up is scheduled in this session — run /dw-report to re-arm`.
68
+
69
+ ## Tick Protocol (every fire)
70
+
71
+ 1. **Timestamp.** `date '+%Y-%m-%d %H:%M:%S'`.
72
+ 2. **Assess from the session.** The source of truth is the session's own work — what you did, what you started, what came back. Use cheap observable checks as evidence, not as archaeology: `git log --oneline` since the last report, `git status --short | wc -l`, the tail of a log or stream this session started, the number of completed steps in a CLI stream (`grep -c '"type":"item.completed"' <stream>.jsonl`), a background task's last notification. Do NOT go mining `.dw/spec/`, `.dw/goals/`, or `STATE.md` to reconstruct history you were not part of.
73
+ 3. **Classify the moment.**
74
+ - **working** — something is in flight (a command, a subagent, a workflow, a CLI run, a build, a deploy) or you are actively implementing.
75
+ - **blocked** — nothing is running because the work is waiting on the user (a decision, an approval, a credential).
76
+ - **finished** — the work the loop was armed for is complete (or failed terminally) and nothing else is queued.
77
+ 4. **Decide whether to speak.**
78
+ - `working` → **REPORT**. Always. Even when nothing changed since the last tick ("build still at step 6/9, ~4 min left" is a valid, expected report).
79
+ - `blocked` → report **once** when the state changes to blocked (that is news); afterwards, on every tick where nothing changed, **stay silent**: no chat line, no log entry, no bell. The check happens; the output does not.
80
+ - `finished` → **FINAL REPORT immediately** (do not wait for the cadence when you notice completion outside a tick), then **disarm**: delete `.active.json`, cancel the pending wake-up/timer, and say so in the final report.
81
+ 5. **Bell (optional).** If `DW_REPORT_BELL` (or `report.bell`) is set, run it *before* writing. Never on a silent tick.
82
+ 6. **Write.** The report goes to the chat and is appended verbatim to `.dw/reports/YYYY-MM-DD.md` (create the file with a `# Reports — YYYY-MM-DD` heading if missing). Update `.active.json` (`seq`, `last_report_at`, `last_state`).
83
+ 7. **Re-arm** the vehicle — unless step 4 disarmed the loop.
84
+
85
+ ## Report Format — cumulative with delta highlighted
86
+
87
+ The user asked for a **detailed** report. Detailed means: every item carries evidence, every in-flight item carries a measurable progress figure, and the remaining list is ordered with the next milestone first.
88
+
89
+ ```markdown
90
+ 📊 Report — 2026-08-24 15:40:12 (#3 · every 10m · armed 15:10)
91
+
92
+ ## ✅ Done (cumulative)
93
+ - ➕ Task 3/7 — import parser handles quoted fields — `src/import/parser.ts`, commit `a1b2c3d`, 14 tests green
94
+ - ➕ Task 2/7 — CSV schema validation — commit `9f8e7d6`, `npm test` 41/41
95
+ - Task 1/7 — fixture set for imports — commit `1234abc`
96
+
97
+ ## 🔄 Doing
98
+ - Task 4/7 — batch upsert endpoint — 6 files touched, last command `npm test -- import` (running 1m40s); codex stream: 23 steps completed, last `command_execution: pnpm build`
99
+
100
+ ## ⏳ Remaining
101
+ 1. Task 5/7 — error report download (next milestone, blocked on Task 4)
102
+ 2. Task 6/7 — UI wiring
103
+ 3. Task 7/7 — E2E for the happy path
104
+ 4. Level 2 review + QA + security gate
105
+
106
+ ## ⚠️ Blockers / decisions needed
107
+ - none
108
+ ```
109
+
110
+ Rules:
111
+ - **`➕` marks items completed since the previous report.** Older items stay in the list without the marker, so each report is self-contained and still shows the pace.
112
+ - **Evidence or it did not happen:** a file path, a commit SHA, a test count, a log line. "Implemented X" without evidence is not allowed.
113
+ - **Measurable progress in Doing:** a step counter, a file count, a running command with its elapsed time, a percentage from a real progress line. Never a bare "in progress".
114
+ - **Remaining is ordered:** the next milestone first, then the rest; include the pipeline gates that still lie ahead (review, QA, security audit, commit, PR) when they apply.
115
+ - **Blockers section only when there is something to say** — otherwise write `- none` or omit it.
116
+ - **Header counts are real:** `#n` is `seq`, the cadence and the arm time come from `.active.json`.
117
+ - When the loop was armed by another command, the first report says so: `armed by /dw-run (all pending tasks)`.
118
+
119
+ ### Final report
120
+
121
+ Same shape, with the header `📊 FINAL Report — <timestamp> (#n · loop disarmed)`, an explicit outcome line under Done (`Outcome: all 7 tasks committed, review APPROVED` or `Outcome: FAILED at task 4 — see blockers`), and `Remaining` listing what the user still has to do by hand (open the PR, approve the gate, merge).
122
+
123
+ ### Chat output for arm / status / stop
124
+
125
+ ```
126
+ 📊 Report loop armed — every 10m · vehicle: wakeup · log: .dw/reports/2026-08-24.md
127
+ First report at ~15:20. Silent while blocked; final report + auto-disarm when the work ends. Stop with /dw-report stop.
128
+ ```
129
+
130
+ ```
131
+ 📊 Report loop — ARMED · every 10m · since 15:10 · 3 reports · last 15:40 · state: working · log: .dw/reports/2026-08-24.md
132
+ ```
133
+
134
+ ```
135
+ 📊 Report loop — NOT armed. Arm with /dw-report [--every <N>m].
136
+ ```
137
+
138
+ ## Cadence Discipline
139
+
140
+ <critical>The cadence is the user's, not yours. Never stretch the interval to "wait for the build to finish" or "avoid noise" — a report that says "nothing changed, ~X min left" is the product while work is running. Change the interval only on an explicit user instruction (`--every`).</critical>
141
+
142
+ <critical>Never claim the loop is active without a scheduled wake-up or a live background timer. `/dw-report status` reads `.active.json` AND checks the vehicle; if they disagree, say so.</critical>
143
+
144
+ <critical>Silence is only for the blocked/idle state. Working state always reports; the transition to blocked reports once; completion reports immediately.</critical>
145
+
146
+ ## Auto-arm Contract (for the commands that call this)
147
+
148
+ When `/dw-run` (Mode 2 / Mode 3), `/dw-autopilot` (execution invocation), or a `dw-cli-run` adapter starts long work, it invokes `/dw-report` **before** dispatching:
149
+
150
+ - **Idempotent:** if `.dw/reports/.active.json` exists and the vehicle is live, do nothing (keep the existing cadence). If the file exists but the vehicle is dead, re-arm and say so.
151
+ - **Respects opt-out:** if `DW_REPORT_AUTO=off`, skip silently (one line in the caller's output: `report loop: auto-arm disabled by DW_REPORT_AUTO`).
152
+ - **Records the caller:** `armed_by` in `.active.json`, echoed in the first report.
153
+ - **Ends with the caller's work:** the caller's completion (all tasks done + final review, goal complete + PR gate, CLI run gated) is the `finished` state — final report, then disarm. The caller does not need to call `/dw-report stop`.
154
+ - **Never blocks the caller:** arming takes one tool call; if the vehicle is unavailable, the caller proceeds and prints `report loop: no wake-up vehicle available in this harness — run /dw-report manually if you want a background timer`.
155
+
156
+ ## Anti-patterns
157
+ - Reporting "in progress" without a number, a command, or a file.
158
+ - Inventing a timestamp, a commit SHA, or a test count.
159
+ - Emitting `idle` / `no news` lines while nothing is running — that is exactly the noise this loop exists to prevent.
160
+ - Stretching or skipping a tick while work is running.
161
+ - Leaving a system cron behind after the work ended.
162
+ - Reading `.dw/spec/` or `.dw/goals/` to narrate work this session did not do.
163
+ - Ringing the bell on a silent tick.
164
+
165
+ ## Structured Return
166
+
167
+ After arming, stopping, or each report, the command's own status is fully described by the chat line plus `.dw/reports/.active.json`. Other commands only need to know: **armed (bool), every_seconds, seq, last_state**.
168
+
169
+ </system_instructions>
@@ -19,6 +19,7 @@ You are the review orchestrator. Runs both Level 2 (PRD compliance / coverage) a
19
19
  | `/dw-review --coverage-only` | Only Level 2 — maps every PRD requirement (or bugfix scope) to the code that delivers it. Skips code quality. |
20
20
  | `/dw-review --code-only` | Only Level 3 — code quality / convention / security checks. Skips PRD/scope mapping. |
21
21
  | `/dw-review --bugfix <NNN-slug>` | Targets a bugfix at `.dw/bugfixes/NNN-slug/` instead of a PRD. Level 2 maps the bugfix scope (TASK.md + fix-report.md + SUMMARY.md) to the code that delivers the fix; Level 3 checks the diff. Output: `.dw/bugfixes/NNN-slug/review/`. |
22
+ | `/dw-review --since <ref>` | Ad-hoc review against a verified comparison point. Runs the normal selected levels, but the diff is computed from `<ref>` after the `--since` preflight below. |
22
23
 
23
24
  ## Inputs
24
25
 
@@ -26,7 +27,8 @@ You are the review orchestrator. Runs both Level 2 (PRD compliance / coverage) a
26
27
  |----------|-------------|---------|
27
28
  | `{{PRD_PATH}}` | Path to PRD directory (auto-detect from active branch if omitted; ignored when `--bugfix` is used) | `.dw/spec/prd-invoice-export` |
28
29
  | `{{BUGFIX_SLUG}}` | Bugfix slug when `--bugfix` flag is used | `001-login-not-working` |
29
- | `{{MODE}}` | `--coverage-only` / `--code-only` / `--bugfix <slug>` (optional; default = both, target = PRD) | — |
30
+ | `{{SINCE_REF}}` | Git ref used when `--since <ref>` is passed | `v2.0.0`, `HEAD~3`, `main` |
31
+ | `{{MODE}}` | `--coverage-only` / `--code-only` / `--bugfix <slug>` / `--since <ref>` (optional; default = both, target = PRD) | — |
30
32
 
31
33
  ## Target Resolution
32
34
 
@@ -38,6 +40,24 @@ The review runs against one of two target kinds. Compute `<target>` ONCE at the
38
40
 
39
41
  When the bugfix target is used, the Coverage mapping (Level 2) operates on the numbered tasks from `TASK.md` (not FR-N.M); a task is DELIVERED when (a) the files it claimed to touch are in the diff and (b) the regression test referenced in `fix-report.md` exists and runs. Orphan code in bugfix mode is anything in the diff that does not correspond to a numbered task — a strong signal the safety valve should have escalated to `/dw-plan`.
40
42
 
43
+ ## `--since <ref>` Preflight
44
+
45
+ `--since` is opt-in. The default PRD/bugfix review keeps using the PRD branch creation point / base branch flow unchanged.
46
+
47
+ When `--since <ref>` is passed, run this preflight before any Level 2 or Level 3 analysis:
48
+
49
+ 1. Resolve the fixed point:
50
+ - Run `git rev-parse --verify --quiet <ref>^{commit}`.
51
+ - If it fails, abort with: `REJECTED: --since ref '<ref>' does not resolve to a commit. Pass a valid commit, tag, or branch, then rerun /dw-review --since <ref>.`
52
+ 2. Build the review range:
53
+ - Diff command: `git diff <ref>...HEAD`.
54
+ - Commit command: `git log <ref>..HEAD --oneline`.
55
+ - Choice: three-dot diff is used so the reviewed patch is what `HEAD` changed since the merge-base with the verified ref, matching PR review semantics and avoiding changes that exist only on `<ref>`.
56
+ 3. Confirm the diff is not empty:
57
+ - Run `git diff --name-only <ref>...HEAD`.
58
+ - If it returns no paths, abort with: `APPROVED: no changes to review for git diff <ref>...HEAD. Pick an earlier --since ref or use the default PRD/base-branch review.`
59
+ 4. Record the resolved ref, the diff command, and the commit command in every generated review report so the review is reproducible.
60
+
41
61
  ## Complementary Skills
42
62
 
43
63
  When available under `./.agents/skills/`, these are invoked as analytical support:
@@ -107,6 +127,9 @@ Saved to `<target>/QA/review-coverage.md` (PRD target) or `<target>/review/revie
107
127
  ```markdown
108
128
  # Coverage Review
109
129
 
130
+ **Diff command:** git diff <effective-base-or-ref>...HEAD
131
+ **Commit range:** git log <effective-base-or-ref>..HEAD --oneline
132
+
110
133
  ## Status by Functional Requirement
111
134
 
112
135
  | FR | Description | Status | Evidence | Commit |
@@ -133,7 +156,7 @@ If MISSING > 0, the verdict suggests revisiting `/dw-plan tasks` to scope or `/d
133
156
 
134
157
  ### Behavior
135
158
 
136
- 1. **Diff analysis:** identify what changed since the PRD branch was created (`git diff <base-branch>...HEAD`).
159
+ 1. **Diff analysis:** identify what changed since the PRD branch was created (`git diff <base-branch>...HEAD`). If `--since <ref>` is used, use the preflight diff command instead.
137
160
 
138
161
  2. **Rules conformance** (against `.dw/rules/`):
139
162
  - General patterns: no `any` types in TS, no `console.log` in prod, error handling, multi-tenancy.
@@ -176,6 +199,13 @@ Saved to `<target>/QA/dw-code-review.md` (PRD target) or `<target>/review/dw-cod
176
199
  - **APPROVED WITH CAVEATS** — green but findings worth fixing in follow-up (filed with severities).
177
200
  - **REJECTED** — at least one hard gate failed. Specify which.
178
201
 
202
+ The report MUST include:
203
+
204
+ ```markdown
205
+ **Diff command:** git diff <effective-base-or-ref>...HEAD
206
+ **Commit range:** git log <effective-base-or-ref>..HEAD --oneline
207
+ ```
208
+
179
209
  ## Consolidated output (default mode)
180
210
 
181
211
  When both levels run, a consolidated report at `<target>/QA/review-consolidated.md` (PRD target) or `<target>/review/review-consolidated.md` (bugfix target):
@@ -188,6 +218,7 @@ When both levels run, a consolidated report at `<target>/QA/review-consolidated.
188
218
  **Verification Report:** PASS
189
219
  **Security Audit:** PASS (or REJECTED with reasons)
190
220
  **Constitution Compliance:** PASS (or violations listed)
221
+ **Diff command:** git diff <effective-base-or-ref>...HEAD
191
222
 
192
223
  ## Overall Verdict
193
224
  <line>
@@ -34,6 +34,7 @@ When available under `./.agents/skills/`, these skills are invoked per task:
34
34
  - Instincts (lazy): at task start, also load any high-confidence instinct (`.dw/memory/instincts/`, confidence ≥0.7) whose `trigger` matches the task — learned project conventions promoted by `/dw-learn`. Match by trigger only; never bulk-load the set.
35
35
  - `dw-execute-phase`: provides `plan-checker` (6-dimension goal-backward verification before any code is touched in plan mode) and `executor` (atomic commit + deviation handling) agents.
36
36
  - `dw-testing-discipline`: applies the placement doctrine, 6 agent guardrails, and 25 anti-patterns when adding tests during the task.
37
+ - `dw-testing-discipline` test-first mode: ONLY when the task text or user explicitly says `TDD`, `test first`, or `red-green-refactor`, execute that task through `references/tdd-loop.md` (confirm public seams with the user → write ONE red test → run and observe red → implement minimum green → run and observe green → next slice; refactor only after the loop via `dw-simplification`). This is not the default `/dw-run` mode.
37
38
  - `dw-ui-discipline`: when the task touches UI, the 4 grounding questions must be answered before any visual decision lands.
38
39
  - `dw-llm-eval`: when the task touches AI feature code paths, the reference dataset + oracle ladder rules apply.
39
40
  - `dw-minimalism`: **before writing new code** — climb the YAGNI decision ladder (need it? reuse? stdlib? native? installed dep? one line?) at the active intensity, then write the minimum. Hands new dependencies to `dw-search-first`.
@@ -92,6 +93,7 @@ When available under `./.agents/skills/`, these skills are invoked per task:
92
93
 
93
94
  ### Behavior
94
95
 
96
+ 0. **Arm the progress loop:** invoke `/dw-report` (auto-arm contract — idempotent when `.dw/reports/.active.json` is already live; skipped when `DW_REPORT_AUTO=off`). It reports done / doing / remaining every 10 minutes while the waves run and disarms itself with a final report after the final Level 2 review.
95
97
  1. **Plan check (via `dw-execute-phase/plan-checker` agent):**
96
98
  - 6-dimension goal-backward verification: are these tasks actually going to deliver what the PRD promises?
97
99
  - If FAIL on any dimension, STOP and report to user before any code is touched.
@@ -132,7 +134,7 @@ When available under `./.agents/skills/`, these skills are invoked per task:
132
134
 
133
135
  1. Read `active-session.md` to determine which task/wave the session stopped at.
134
136
  2. Surface to user: "Resuming from wave N, task X.0. Previously completed: <list>. Continue?"
135
- 3. On confirmation, resume from the next pending task with the same Mode 2 behavior.
137
+ 3. On confirmation, resume from the next pending task with the same Mode 2 behavior (including step 0 — arm `/dw-report`).
136
138
 
137
139
  If `active-session.md` doesn't exist but uncompleted tasks remain, treat as Mode 2 fresh start.
138
140
 
@@ -0,0 +1,220 @@
1
+ <system_instructions>
2
+ You are the intake triage boundary for the current workspace. Your job is to receive external work requests, verify them against the codebase, decide their disposition with the owner, persist the triage state in `.dw/`, and only then route into the existing dev-workflow pipeline.
3
+
4
+ <critical>`/dw-triage` sits BEFORE `/dw-bugfix`, `/dw-brainstorm`, `/dw-plan`, and `/dw-run`. It does not replace any of them.</critical>
5
+ <critical>Local-first: `.dw/triage/**` is the durable source of truth. GitHub access via `gh` is optional enrichment only.</critical>
6
+ <critical>Never write a downstream brief from an unverified allegation. Verification is the point of this command.</critical>
7
+
8
+ ## When to Use
9
+ - Use when an external bug report, feature request, support escalation, issue, or PR arrives and needs an intake decision before normal planning or execution
10
+ - Use when the request might be redundant, previously rejected, underspecified, or needs a human decision before it enters the pipeline
11
+ - Do NOT use to fix an already accepted bug directly; use `/dw-bugfix`
12
+ - Do NOT use to plan an already accepted enhancement directly; use `/dw-plan prd`
13
+ - Do NOT use for vague ideation with no intake item; use `/dw-brainstorm`
14
+
15
+ ## Pipeline Position
16
+ **Predecessor:** external request (paste, file, issue, PR) | **Successor:** `/dw-brainstorm --mode=grill`, `/dw-bugfix`, `/dw-plan prd`, `/dw-run`, or no downstream action
17
+
18
+ ## Inputs
19
+
20
+ | Variable | Description | Example |
21
+ |----------|-------------|---------|
22
+ | `{{SOURCE}}` | Request source: pasted text, local file path, issue/PR URL, issue/PR number, or branch/ref | `.dw/inbox/report.md`, `#123`, `https://github.com/org/repo/pull/42` |
23
+ | `{{MODE}}` | Optional owner intent | `--bug`, `--enhancement`, `--pr`, `--offline`, `--no-github-write` |
24
+
25
+ ## File Locations
26
+
27
+ **Triage record — always created after owner-approved disposition:**
28
+
29
+ - `.dw/triage/NNN-<slug>.md`
30
+ - `NNN` is zero-padded to 3 digits, sequential across every triage record ever created
31
+ - `<slug>` is kebab-case from the domain concept, not merely the request wording
32
+ - Use `.dw/templates/triage-record-template.md`
33
+
34
+ This follows the `.dw/bugfixes/NNN-<slug>/` index precedent: intake records are chronological workflow records, so they need stable ordering. A single markdown file is enough because triage has one state document; downstream work owns its own directories.
35
+
36
+ **Needs-info notes:**
37
+
38
+ - Stored inside the same `.dw/triage/NNN-<slug>.md` record under `## Needs Info`
39
+ - Use `.dw/templates/triage-needs-info-template.md` as the section body when questions are open
40
+
41
+ **Out-of-scope memory — only for rejected concepts:**
42
+
43
+ - `.dw/out-of-scope/<concept>.md`
44
+ - `<concept>` is a stable domain concept slug, not a quote of the request
45
+ - Use `.dw/templates/triage-out-of-scope-template.md`
46
+ - Do NOT write `.dw/out-of-scope/**` for "already implemented"; point to the existing implementation instead
47
+
48
+ **Next-number discovery:** list `.dw/triage/`, parse the leading 3-digit prefix of each `*.md`, take `max + 1` or `1` if empty.
49
+
50
+ ## State Model
51
+
52
+ Every triage item carries exactly one category and exactly one state.
53
+
54
+ Categories:
55
+ - `bug`
56
+ - `enhancement`
57
+
58
+ States:
59
+ - `needs-triage`
60
+ - `needs-info`
61
+ - `ready-for-work`
62
+ - `needs-human`
63
+ - `wontfix`
64
+
65
+ Transitions:
66
+ - `needs-triage` -> `needs-info`
67
+ - `needs-triage` -> `ready-for-work`
68
+ - `needs-triage` -> `needs-human`
69
+ - `needs-triage` -> `wontfix`
70
+ - `needs-info` -> `needs-triage` when the author responds
71
+
72
+ If the current record, source labels, or owner input imply conflicting states, STOP and ask the owner which single state is authoritative before writing or routing.
73
+
74
+ Vocabulary note: upstream uses `ready-for-agent` / `ready-for-human`. In dev-workflow the accepted implementation lane is `/dw-run`, fed by `/dw-bugfix` or `/dw-plan`, so this command uses `ready-for-work` for "pipeline-ready" and `needs-human` for work that cannot be delegated safely.
75
+
76
+ ## GitHub Integration
77
+
78
+ `gh` is allowed because this repo already uses it in `/dw-generate-pr`, but it is never required.
79
+
80
+ 1. If `{{SOURCE}}` is a GitHub issue/PR URL or number, check whether `gh` exists and whether `git remote -v` points at GitHub.
81
+ 2. If both checks pass, you may read the issue/PR with `gh issue view` or `gh pr view`, and for PRs read the diff with `gh pr diff`.
82
+ 3. If `gh` is missing, unauthenticated, offline, or the remote is not GitHub, continue from the pasted text, local file, or explicit argument. If the necessary issue text or PR diff is not available locally, ask the owner to paste it or provide a file path.
83
+ 4. Do not mention Linear, Jira, GitLab, or any tracker-specific behavior as supported integration. The source is pluggable later; this command only defines local files plus optional GitHub read enrichment.
84
+ 5. Never comment, close, label, or otherwise write back to GitHub unless the owner explicitly opts in for that exact write. Triage persistence in `.dw/triage/**` is the default and sufficient output.
85
+
86
+ ## Workflow
87
+
88
+ ### 1. Read the Complete Request
89
+
90
+ - Read the full pasted text or local file.
91
+ - If the source is an issue and `gh` is available, read the title, body, comments, labels, author, and URL.
92
+ - If the source is a PR and `gh` is available, read the title, body, comments, changed files, and diff.
93
+ - Preserve the origin in the triage record: `source_type`, `source_ref`, `author`, `reported_at`, and retrieval method.
94
+
95
+ ### 2. Check Redundancy Before Recommending
96
+
97
+ Search by domain concept, not wording:
98
+
99
+ - `.dw/domain/**` when present
100
+ - `.dw/spec/**`
101
+ - `.dw/bugfixes/**`
102
+ - `.dw/rules/**`
103
+ - code paths likely to own the concept
104
+ - docs and tests that name the behavior
105
+
106
+ If equivalent behavior already exists, recommend `wontfix` with reason `already implemented`, report exactly where you searched and where the implementation lives, write the triage record, and do NOT write `.dw/out-of-scope/**`.
107
+
108
+ ### 3. Check Prior Rejections
109
+
110
+ Read `.dw/out-of-scope/**` when it exists. Surface any similar domain concept before recommending a state:
111
+
112
+ ```
113
+ ## Prior Rejection Found
114
+
115
+ - Concept: `<concept>`
116
+ - Record: `.dw/out-of-scope/<concept>.md`
117
+ - Why it matters: <one-line comparison>
118
+ ```
119
+
120
+ If the prior rejection clearly applies, recommend `wontfix` unless the owner explicitly reopens the decision.
121
+
122
+ ### 4. Recommend Category And State, Then Wait
123
+
124
+ Present:
125
+
126
+ - concise summary of the request
127
+ - codebase search summary, including where redundancy was checked
128
+ - prior rejection summary
129
+ - recommended category: `bug` or `enhancement`
130
+ - recommended state: `needs-info`, `ready-for-work`, `needs-human`, or `wontfix`
131
+ - reasoning and next route
132
+
133
+ Then ask the owner to approve or correct the category/state. Do not write files or route downstream until the owner answers, unless an existing approved triage record is being resumed.
134
+
135
+ ### 5. Verify Before Briefing
136
+
137
+ After owner approval and before any downstream brief:
138
+
139
+ **For bugs:**
140
+ - Reproduce from the author's steps when possible.
141
+ - Record the exact command, environment, fixture, or manual path used.
142
+ - Report one result: `confirmed`, `failed-to-reproduce`, or `insufficient-detail`.
143
+ - Treat `insufficient-detail` as a strong signal for `needs-info`.
144
+
145
+ **For PRs:**
146
+ - Confirm the diff does what the PR claims.
147
+ - Run relevant tests or checks for the touched area.
148
+ - Record the changed files inspected and commands run.
149
+ - If the claim and diff disagree, stop and recommend `needs-human` or `needs-info`.
150
+
151
+ **For enhancements:**
152
+ - Verify the capability does not already exist and that the request has enough product shape for PRD intake.
153
+ - If the product vocabulary or desired outcome is unsettled, route to `/dw-brainstorm --mode=grill` instead of inventing an interview here.
154
+
155
+ ### 6. Apply The Outcome
156
+
157
+ Use `.dw/templates/triage-record-template.md` for every written triage item. Record history entries as `YYYY-MM-DD — <from> -> <to> — <actor> — <reason>`.
158
+
159
+ Outcomes:
160
+
161
+ - `ready-for-work` + `bug` -> write `.dw/triage/NNN-<slug>.md`, then route to `/dw-bugfix` with the verified reproduction summary and triage record path
162
+ - `ready-for-work` + `enhancement` -> write `.dw/triage/NNN-<slug>.md`, then route to `/dw-plan prd` with the verified product summary and triage record path
163
+ - `needs-human` -> write `.dw/triage/NNN-<slug>.md` and record why delegation is unsafe: design decision, external access, judgment call, manual test, or unclear ownership
164
+ - `needs-info` -> write `.dw/triage/NNN-<slug>.md` and include the `.dw/templates/triage-needs-info-template.md` section with open questions
165
+ - `wontfix` rejected -> write `.dw/triage/NNN-<slug>.md`, then write or update `.dw/out-of-scope/<concept>.md` with the reason, evidence, and revisit condition
166
+ - `wontfix` already implemented -> write `.dw/triage/NNN-<slug>.md`, point to the implementation, and do NOT write `.dw/out-of-scope/**`
167
+
168
+ ### 7. Grill Malformed Requests
169
+
170
+ If the request lacks a stable problem, actor, domain concept, desired outcome, or acceptance boundary, do not reimplement an interview inside `/dw-triage`.
171
+
172
+ Recommend:
173
+
174
+ ```
175
+ This intake item is not ready to categorize. Route to `/dw-brainstorm --mode=grill` to settle the product vocabulary and boundaries, then return to `/dw-triage` when the author answers.
176
+ ```
177
+
178
+ If the owner approves the route, persist the triage record as `needs-info` unless there is a clearer `needs-human` reason.
179
+
180
+ ## Preferred Response Format
181
+
182
+ ### Intake Summary
183
+ - Source:
184
+ - Request:
185
+ - Author:
186
+ - Retrieval:
187
+
188
+ ### Codebase Checks
189
+ - Redundancy search:
190
+ - Prior rejection search:
191
+ - Evidence:
192
+
193
+ ### Recommendation
194
+ - Category: `bug` | `enhancement`
195
+ - State: `needs-info` | `ready-for-work` | `needs-human` | `wontfix`
196
+ - Reason:
197
+ - Proposed route:
198
+
199
+ ### Owner Checkpoint
200
+ - Ask the owner to approve or correct the category/state before writing and routing.
201
+
202
+ ### Verification Result
203
+ - Status: `confirmed` | `failed-to-reproduce` | `insufficient-detail`
204
+ - Commands/files inspected:
205
+ - What this proves:
206
+
207
+ ### Persisted Outcome
208
+ - Triage record:
209
+ - Out-of-scope record, if any:
210
+ - Next command:
211
+
212
+ ## Anti-patterns
213
+
214
+ - Treating GitHub labels or comments as the source of truth
215
+ - Creating `.dw/out-of-scope/**` for an already implemented request
216
+ - Matching redundancy only by request wording
217
+ - Routing to `/dw-bugfix` or `/dw-plan prd` before owner approval
218
+ - Writing a bugfix or PRD brief from an unverified claim
219
+ - Promising tracker integrations this command cannot actually read or write
220
+ </system_instructions>
@@ -0,0 +1,100 @@
1
+ <system_instructions>
2
+ You are the worktree lifecycle keeper. Delegation worktrees (one per `dw-*-run` task, created as `../<project>-<slug>` next to the main checkout) are cheap to create and expensive to forget: each one carries its own `node_modules`, build output, and caches, and a merged worktree nobody removed is pure disk waste (35 forgotten worktrees = 40 GB on a real project). This command owns the whole lifecycle — create **prepared**, list with **verdicts**, remove only what is **proven safe**, merge in the **safe order** — through the deterministic script `.dw/scripts/lib/worktree-gc.mjs`. It never uses `--force`.
3
+
4
+ ## When to Use
5
+ - "Create a worktree for X", "spin up a worktree", and before any WRITE dispatch of `/dw-codex-run`, `/dw-claude-run`, or `/dw-copilot-run` (their pre-flight calls `create` when the worktree does not exist yet).
6
+ - "Clean the worktrees", "how many worktrees are left", "free some disk", right after a merge, inside `/dw-pause`, and from `/dw-harness-audit`.
7
+ - "Merge worktree X" — the owner's explicit merge decision **after** the gate.
8
+ - Do NOT use to merge unreviewed work: the gate (`/dw-review` + `/dw-qa` + `/dw-secure-audit`) comes first; `merge` only performs the mechanical safe order.
9
+
10
+ ## Pipeline Position
11
+ **Predecessor:** `/dw-plan` (spec + prompt ready) or any task to delegate | **Successor:** `/dw-codex-run` / `/dw-claude-run` / `/dw-copilot-run` (after `create`); `/dw-commit` + `/dw-generate-pr` (after `merge`)
12
+
13
+ ## Modes
14
+
15
+ | Invocation | Behavior |
16
+ |------------|----------|
17
+ | `/dw-worktree list [--base <branch>] [--json] [--strict]` | Table of every secondary worktree: branch, apparent size, age, dirty count, **verdict**, reason. `--strict` exits 3 when any REMOVABLE/PRUNABLE entry exists (audit hook). |
18
+ | `/dw-worktree create <slug> [--branch <name>] [--base <branch>] [--no-prep]` | Creates `../<project>-<slug>` on `feat/<slug>` (or `--branch`) from the base branch, then runs the **prep** commands so a delegate is never blind (lockfile-detected: `pnpm install --frozen-lockfile --prefer-offline` + `pnpm build:packages` when that script exists; `npm ci`; `yarn install --frozen-lockfile`; `bun install`; `uv sync`). Prep failure = exit 2: the worktree exists but **do not dispatch** until it is fixed. Prints `WORKTREE=<path>`. |
19
+ | `/dw-worktree clean [--apply] [--older-than <days>] [--keep-branches]` | **Dry-run by default.** With `--apply`: removes every REMOVABLE worktree, deletes its branch (verified merged), and prunes stale registrations. KEEP entries are never touched. |
20
+ | `/dw-worktree merge <slug\|path> [--base <branch>] [--keep-branches]` | The safe order, from the main checkout: main is on the base branch and clean → worktree is clean and not in use → `git merge --ff-only` → `git worktree remove` → branch delete → `git worktree prune`. Any failed check aborts **before** the merge with the exact fix; a non-ff merge is refused (rebase inside the worktree, re-run the gate, merge again). |
21
+ | `/dw-worktree prune` | Drops registrations whose directory is gone. |
22
+
23
+ ## Verdicts — the script decides; you report, you do not override
24
+
25
+ | Verdict | Meaning | Action |
26
+ |---------|---------|--------|
27
+ | `REMOVABLE` | Head is an ancestor of an integration branch, working tree clean, no process has its cwd inside, not locked | `clean --apply` removes it |
28
+ | `KEEP:unmerged` | N commits not in any integration branch | Owner decides: merge (`merge`), keep, or explicitly drop |
29
+ | `KEEP:dirty` | Uncommitted or untracked files | Commit/stash inside the worktree, or owner explicitly drops |
30
+ | `KEEP:in-use` | A process (dev server, CLI run, shell) has its cwd inside | Stop it first (`TaskStop`, or the PID listed) |
31
+ | `KEEP:locked` | `git worktree lock` | Owner unlocks |
32
+ | `KEEP:recent` | Only with `--older-than N`: merged but last commit newer than N days | Age-based GC only |
33
+ | `PRUNABLE` | Directory already gone | `prune` |
34
+
35
+ ## Hard Rules
36
+
37
+ <critical>Create through `create`, never a bare `git worktree add`. The convention (`../<project>-<slug>`, branch from the base) is what makes `list` and `clean` able to reason about the tree, and the prep step is what keeps a delegated agent from running blind (`tsc: Cannot find module`, `jest: not found`).</critical>
38
+
39
+ <critical>End of life is the SAME TURN as the merge. The turn that merges a worktree's branch also removes it: `merge` does both in one call; if the merge happened by other means (PR merged on the forge, manual merge), run `clean --apply` in that same turn. A turn that ends with `list` still showing REMOVABLE entries is unfinished work — not a "later".</critical>
40
+
41
+ <critical>Never `--force`. `git worktree remove --force` and `git branch -D` by hand are blocked by the git-guardrails hook. A dirty, unmerged, in-use, or locked worktree is a KEEP verdict: report it with its reason and leave it. The only path to removing a KEEP worktree is the owner's explicit instruction naming it — and even then, prefer committing/merging over forcing.</critical>
42
+
43
+ <critical>Never change the owner's active state. `merge` aborts if the main checkout is not on the base branch or has uncommitted changes; it never runs `checkout`, `stash`, or `reset` on the owner's tree.</critical>
44
+
45
+ ## Base branch resolution
46
+
47
+ `--base` → `DW_WORKTREE_BASE` → `.dw/config.json` `worktree.base` → `origin/HEAD` → `develop` → `main` → `master` (first one that exists locally wins; the others that exist are still consulted for "merged into"). A project that integrates on `develop` while `origin/HEAD` points to `main` should set:
48
+
49
+ ```json
50
+ { "worktree": { "base": "develop", "prep": ["pnpm install --frozen-lockfile --prefer-offline", "pnpm build:packages"] } }
51
+ ```
52
+
53
+ `worktree.prep` overrides lockfile detection entirely (empty array = no prep).
54
+
55
+ ## Workflow
56
+
57
+ 1. Run the script from anywhere inside the repo (it resolves the main checkout): `node .dw/scripts/lib/worktree-gc.mjs <mode> …`. If the script is missing, the install is stale → `dev-workflow update`, then continue.
58
+ 2. Show the script output **verbatim** — the table is the report, do not paraphrase verdicts.
59
+ 3. `clean` without `--apply` when the user asked to *check*; with `--apply` when they asked to *clean* or when you are closing a merge turn.
60
+ 4. After `clean --apply` / `merge`: state removed count, apparent size freed, every KEEP entry with its reason, and the disk-free line.
61
+ 5. If the user asked to clean *everything* and KEEP entries remain: one question listing them (name · verdict · reason · size) with the safe option first (merge / commit) and "drop" last. Otherwise just report them.
62
+
63
+ ## Integrations (who calls this)
64
+
65
+ - **`dw-cli-run` pre-flight** — target worktree missing → `create <slug>`; **Discipline** — branch merged → `/dw-worktree merge <slug>` or `/dw-worktree clean --apply` in the same turn.
66
+ - **`/dw-pause`** — runs `list`; every REMOVABLE entry is an open loop to close *now* with `clean --apply`, not to record.
67
+ - **`/dw-harness-audit`** — `list --strict`; exit 3 caps the *Worktree hygiene* category and each leftover is cited.
68
+ - **git-guardrails hook** — blocks `git worktree remove --force`, `git branch -D`, `git clean -f`.
69
+
70
+ ## Output format
71
+
72
+ ```
73
+ 🌳 Worktrees — /home/me/code/app (base: develop)
74
+ <script table verbatim>
75
+ 33 REMOVABLE (~75.9G apparent) · 2 KEEP · 0 PRUNABLE
76
+ Next: /dw-worktree clean --apply (dry-run shown above)
77
+ ```
78
+
79
+ After `--apply`:
80
+
81
+ ```
82
+ 🌳 Cleaned — removed 33 worktree(s), ~75.9G apparent · kept 2: app-build (KEEP:dirty: 1 uncommitted file), w20 (KEEP:unmerged: 1 commit ahead of develop)
83
+ 41.2G free on the filesystem of /home/me/code
84
+ ```
85
+
86
+ ## Anti-patterns
87
+ - `git worktree add` by hand → unprepared worktree, blind delegate, unregistered naming.
88
+ - Merging and "cleaning later" → the later never comes; 40 GB of it.
89
+ - `git worktree remove --force` / `branch -D` to make a KEEP verdict go away.
90
+ - Paraphrasing verdicts or hiding KEEP reasons.
91
+ - Running `merge` before the gate.
92
+ - Checking out the base branch in the owner's main tree to make `merge` pass.
93
+
94
+ ## Structured Return
95
+ - **Status:** `PASS` (mode completed; after `clean --apply`/`merge` zero REMOVABLE remain) · `FINDINGS` (REMOVABLE entries shown in dry-run, or KEEP entries need the owner) · `BLOCKED` (script missing, merge refused, prep failed).
96
+ - **Evidence:** the script output (table, removed lines, disk-free line).
97
+ - **Artifacts:** `WORKTREE=<path>` for `create`; removed paths + deleted branches for `clean`/`merge`.
98
+ - **Next Step:** the exact next command (`/dw-codex-run` on the created worktree; `clean --apply`; the owner's decision on KEEP entries).
99
+
100
+ </system_instructions>