@brunosps00/dev-workflow 1.2.1 → 1.4.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.
- package/.claude-plugin/marketplace.json +13 -0
- package/.claude-plugin/plugin.json +31 -0
- package/README.md +25 -3
- package/lib/build-plugin.js +79 -0
- package/lib/constants.js +17 -8
- package/lib/doctor.js +33 -0
- package/lib/hooks.js +137 -0
- package/lib/init.js +20 -0
- package/lib/skill-registry.js +13 -0
- package/lib/uninstall.js +22 -3
- package/lib/validate.js +62 -0
- package/lib/wrappers.js +1 -1
- package/package.json +6 -1
- package/scaffold/en/commands/dw-claude-run.md +44 -0
- package/scaffold/en/commands/dw-codex-run.md +47 -0
- package/scaffold/en/commands/dw-copilot-run.md +47 -0
- package/scaffold/en/commands/dw-plan.md +1 -0
- package/scaffold/en/commands/dw-review.md +1 -0
- package/scaffold/en/commands/dw-run.md +1 -0
- package/scaffold/en/commands/dw-update.md +4 -1
- package/scaffold/pt-br/commands/dw-claude-run.md +45 -0
- package/scaffold/pt-br/commands/dw-codex-run.md +47 -0
- package/scaffold/pt-br/commands/dw-copilot-run.md +49 -0
- package/scaffold/pt-br/commands/dw-plan.md +1 -0
- package/scaffold/pt-br/commands/dw-review.md +1 -0
- package/scaffold/pt-br/commands/dw-run.md +1 -0
- package/scaffold/pt-br/commands/dw-update.md +4 -1
- package/scaffold/scripts/hooks/git-guardrails.mjs +79 -0
- package/scaffold/scripts/hooks/statusline.mjs +87 -0
- package/scaffold/skill-registry.json +38 -0
- package/scaffold/skills/dw-cli-run/SKILL.md +217 -0
- package/scaffold/skills/dw-minimalism/SKILL.md +98 -0
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
"expected_output": "A selected API testing recipe and evidence path for the active stack.",
|
|
11
11
|
"load_policy": "lazy-references",
|
|
12
12
|
"context_limit": 12000,
|
|
13
|
+
"invocation": "explicit",
|
|
14
|
+
"exportable": true,
|
|
13
15
|
"bundled": true
|
|
14
16
|
},
|
|
15
17
|
{
|
|
@@ -21,6 +23,19 @@
|
|
|
21
23
|
"expected_output": "A selected service recipe and composition guidance.",
|
|
22
24
|
"load_policy": "lazy-references",
|
|
23
25
|
"context_limit": 12000,
|
|
26
|
+
"invocation": "explicit",
|
|
27
|
+
"exportable": true,
|
|
28
|
+
"bundled": true
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "dw-cli-run",
|
|
32
|
+
"kind": "protocol",
|
|
33
|
+
"tier": "core",
|
|
34
|
+
"owner": "dw-codex-run,dw-claude-run,dw-copilot-run",
|
|
35
|
+
"trigger": "Fire an AI CLI (Codex/Claude/Copilot) in a dedicated git worktree to implement a prepared prompt; resumable per-task session; STOP for the gate",
|
|
36
|
+
"expected_output": "Audit-logged run with a 0-10 dual evaluation, a resumable session-id sidecar, and a STOP-for-gate Structured Return.",
|
|
37
|
+
"load_policy": "lazy-references",
|
|
38
|
+
"context_limit": 18000,
|
|
24
39
|
"bundled": true
|
|
25
40
|
},
|
|
26
41
|
{
|
|
@@ -111,6 +126,19 @@
|
|
|
111
126
|
"context_limit": 12000,
|
|
112
127
|
"bundled": true
|
|
113
128
|
},
|
|
129
|
+
{
|
|
130
|
+
"name": "dw-minimalism",
|
|
131
|
+
"kind": "protocol",
|
|
132
|
+
"tier": "core",
|
|
133
|
+
"owner": "dw-run,dw-plan,dw-review",
|
|
134
|
+
"trigger": "Before writing new code, infrastructure, or abstractions: YAGNI decision ladder and lite/full/ultra intensity",
|
|
135
|
+
"expected_output": "A minimalism verdict (build/reuse/inline/skip) with the ladder rung that justified it.",
|
|
136
|
+
"load_policy": "always-small",
|
|
137
|
+
"context_limit": 8000,
|
|
138
|
+
"invocation": "model",
|
|
139
|
+
"exportable": true,
|
|
140
|
+
"bundled": true
|
|
141
|
+
},
|
|
114
142
|
{
|
|
115
143
|
"name": "dw-review-rigor",
|
|
116
144
|
"kind": "protocol",
|
|
@@ -131,6 +159,7 @@
|
|
|
131
159
|
"expected_output": "Adopt/wrap/compose/build decision with checked search channels.",
|
|
132
160
|
"load_policy": "always-small",
|
|
133
161
|
"context_limit": 6000,
|
|
162
|
+
"exportable": true,
|
|
134
163
|
"bundled": true
|
|
135
164
|
},
|
|
136
165
|
{
|
|
@@ -153,6 +182,7 @@
|
|
|
153
182
|
"expected_output": "Simplification target, risk, behavior-preserving checks, and recommendation.",
|
|
154
183
|
"load_policy": "lazy-references",
|
|
155
184
|
"context_limit": 12000,
|
|
185
|
+
"exportable": true,
|
|
156
186
|
"bundled": true
|
|
157
187
|
},
|
|
158
188
|
{
|
|
@@ -197,6 +227,7 @@
|
|
|
197
227
|
"expected_output": "Fresh verification report with cited command evidence.",
|
|
198
228
|
"load_policy": "always-small",
|
|
199
229
|
"context_limit": 12000,
|
|
230
|
+
"exportable": true,
|
|
200
231
|
"bundled": true
|
|
201
232
|
},
|
|
202
233
|
{
|
|
@@ -208,6 +239,8 @@
|
|
|
208
239
|
"expected_output": "Rewritten prose with AI-writing tells removed and voice preserved.",
|
|
209
240
|
"load_policy": "lazy-references",
|
|
210
241
|
"context_limit": 6000,
|
|
242
|
+
"invocation": "explicit",
|
|
243
|
+
"exportable": true,
|
|
211
244
|
"bundled": true
|
|
212
245
|
},
|
|
213
246
|
{
|
|
@@ -219,6 +252,8 @@
|
|
|
219
252
|
"expected_output": "Selected Remotion rule references and implementation guidance.",
|
|
220
253
|
"load_policy": "lazy-references",
|
|
221
254
|
"context_limit": 8000,
|
|
255
|
+
"invocation": "explicit",
|
|
256
|
+
"exportable": true,
|
|
222
257
|
"bundled": true
|
|
223
258
|
},
|
|
224
259
|
{
|
|
@@ -230,6 +265,7 @@
|
|
|
230
265
|
"expected_output": "High-confidence security findings or explicit pass.",
|
|
231
266
|
"load_policy": "lazy-references",
|
|
232
267
|
"context_limit": 14000,
|
|
268
|
+
"exportable": true,
|
|
233
269
|
"bundled": true
|
|
234
270
|
},
|
|
235
271
|
{
|
|
@@ -241,6 +277,8 @@
|
|
|
241
277
|
"expected_output": "Selected performance rule references and metric-driven recommendations.",
|
|
242
278
|
"load_policy": "lazy-references",
|
|
243
279
|
"context_limit": 12000,
|
|
280
|
+
"invocation": "explicit",
|
|
281
|
+
"exportable": true,
|
|
244
282
|
"bundled": true
|
|
245
283
|
}
|
|
246
284
|
]
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dw-cli-run
|
|
3
|
+
description: "Shared runner protocol for the dw-*-run commands (dw-codex-run / dw-claude-run / dw-copilot-run). Fires an autonomous AI CLI (Codex / Claude / Copilot) INSIDE a dedicated git worktree to implement a prepared prompt/spec, with streaming captured to a durable audit log, a resumable per-task session, a 0–10 dual evaluation, graded escalation, and a STOP for the human gate. Loaded by those commands — substitute the CLI-specific adapter table they supply. NEVER runs in the main checkout; NEVER auto-merges (the owner decides after the gate)."
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
- AskUserQuestion
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# dw-cli-run — fire an AI CLI in the right worktree, audit it, keep the session, stop for the gate
|
|
11
|
+
|
|
12
|
+
CLI-**agnostic** core protocol for the delegation step of `dw-codex-run` / `dw-claude-run` / `dw-copilot-run`: a
|
|
13
|
+
**git worktree** holds a **prompt/spec** already prepared → this protocol fires the autonomous CLI there
|
|
14
|
+
(streaming, non-blocking) → **captures the whole run to a durable audit log** → **keeps a resumable per-task
|
|
15
|
+
session** → **evaluates the delivery 0–10** → escalates on failure → **STOPS for the gate** (merge is the owner's
|
|
16
|
+
call). It exists because running these CLIs by hand is repetitive and risky: wrong worktree, hangs without a TTY,
|
|
17
|
+
lost audit trail, and forgetting to measure quality before merge.
|
|
18
|
+
|
|
19
|
+
> **Dual-use:** these CLIs perform **autonomous edits with auto-approve**. Confirm the **right worktree** and the
|
|
20
|
+
> **scope** before firing. The isolated worktree is the mitigation that justifies the auto-approve flag.
|
|
21
|
+
|
|
22
|
+
## The adapter table (supplied by the invoking command)
|
|
23
|
+
The command that loaded you (`dw-codex-run` / `dw-claude-run` / `dw-copilot-run`) provides a **CLI adapter table**
|
|
24
|
+
with these slots. Substitute them into the steps below — everything else is identical across CLIs:
|
|
25
|
+
|
|
26
|
+
| Slot | Meaning |
|
|
27
|
+
|---|---|
|
|
28
|
+
| `DISPATCH` | first-run command (background, streaming → audit log, `</dev/null`) |
|
|
29
|
+
| `STREAM` | flag(s) that make it emit parseable streaming events (JSON/JSONL) |
|
|
30
|
+
| `AUTO` | auto-approve / non-interactive flag (justified by the isolated worktree) |
|
|
31
|
+
| `RESUME <id>` | re-run command that **continues the SAME session/context** by id |
|
|
32
|
+
| `RESUME_LAST` | "resume the last session of this cwd" fallback |
|
|
33
|
+
| `SESSION_ID` | how to obtain/fix the session-id (from the stream, a sidecar, or a flag) |
|
|
34
|
+
| `DONE_SIGNAL` | the stream event that means the turn finished |
|
|
35
|
+
| `USAGE` | where token usage appears in the stream |
|
|
36
|
+
|
|
37
|
+
If the command did not supply an adapter table, return `BLOCKED` — this skill is not invoked standalone.
|
|
38
|
+
|
|
39
|
+
## RULE (hard) — never the main thread / main checkout
|
|
40
|
+
Run **only** inside a **dedicated git worktree** (off main). **NEVER** fire the CLI in the repo's **main checkout**
|
|
41
|
+
(the root tree on the primary branch, e.g. `~/code/<project>` on `main`) — the CLI edits autonomously and that
|
|
42
|
+
would corrupt the owner's active tree. If the target is the main checkout, **ABORT** (`BLOCKED`) and instruct:
|
|
43
|
+
create/use a worktree first (`git worktree add ../<project>-<slug> -b <branch> main`). Mandatory check before
|
|
44
|
+
running: `git worktree list` → the target is a secondary worktree (not the one flagged as main) **AND** the CLI's
|
|
45
|
+
`cwd` is that worktree.
|
|
46
|
+
|
|
47
|
+
## Pre-flight (fail early > run in the wrong place)
|
|
48
|
+
1. `<cli> --version` answers (CLI + credentials present). Missing → `BLOCKED`.
|
|
49
|
+
2. `git worktree list` — confirm the target worktree and that it is **not** the main checkout.
|
|
50
|
+
3. A **prompt/spec** exists (what the CLI receives). Common conventions: `.dw/spec/<slug>/codex-prompt.md`
|
|
51
|
+
(dev-workflow), `PROMPT.md`, `TASK.md`, or a path the owner names. **Read it** — it is the scope/fence/gate.
|
|
52
|
+
|
|
53
|
+
## Where to run — pick the VEHICLE (the main thread NEVER runs inline)
|
|
54
|
+
The main thread **orchestrates**; execution goes to one of these:
|
|
55
|
+
- **Workflow (PREFERRED)** — when there is a pipeline (CLI implements → evaluate 0–10 → **gate fan-out**). One
|
|
56
|
+
workflow agent runs the CLI (network OK). Shows in `/workflows` + parallelizes. Structure as separate
|
|
57
|
+
**phases/agents**: `[agent that runs the CLI]` → `[gate agents]`.
|
|
58
|
+
- **Single Agent (subagent)** — one-off dispatch of ONE run, no gate fan-out. Lighter; background; returns the
|
|
59
|
+
report. Does not show in `/workflows`.
|
|
60
|
+
- **Background Bash** — fallback only (no workflow/agent harness). Needs network → run un-sandboxed so the CLI can
|
|
61
|
+
reach its API.
|
|
62
|
+
|
|
63
|
+
> **Nesting:** the agent running the CLI **must not spawn further subagents** (nesting limit; Workflow nests only
|
|
64
|
+
> 1 level). The gate is **another phase/agent** of the workflow — never a sub-spawn from inside the runner agent.
|
|
65
|
+
|
|
66
|
+
## Protocol
|
|
67
|
+
1. **Resolve target.** Worktree + prompt path (from the user or inferred). Derive a `<slug>` (the spec slug or
|
|
68
|
+
worktree tag) — it keys the durable audit log and the session sidecar.
|
|
69
|
+
2. **Model + effort — the parent SIZES the complexity and proposes.** Read the prompt and size it; **propose**
|
|
70
|
+
model+effort with a one-line rationale (CLI-specific names live in the adapter table); the owner confirms or
|
|
71
|
+
overrides; if told "you pick", decide by heuristic. Signals: number of tasks; fence breadth; sensitive surface
|
|
72
|
+
(auth/security/tenant/migration/financial); "foundation/redesign/architectural" vs "mechanical fix/typo/docs";
|
|
73
|
+
E2E/secure-audit in the gate. Start **one notch below the ceiling** and escalate on failure (see Escalation).
|
|
74
|
+
3. **Set up the durable audit dir (OUTSIDE the worktree).** `<AUDIT>=<main-repo-or-home>/.dw/cli-run/` — it MUST
|
|
75
|
+
survive `git worktree remove` (the worktree's `QA/` is wiped on merge). Files: `<AUDIT>/<slug>.log` (stream),
|
|
76
|
+
`<AUDIT>/<slug>.session` (session-id sidecar), optionally `<AUDIT>/<slug>.last.md` (final message).
|
|
77
|
+
4. **Dispatch (first run) in BACKGROUND with streaming → durable audit log.** Use the adapter's `DISPATCH`:
|
|
78
|
+
```bash
|
|
79
|
+
cd <WORKTREE> && <DISPATCH ... STREAM AUTO ... "$(cat <PROMPT_PATH>)"> </dev/null \
|
|
80
|
+
> <AUDIT>/<slug>.log 2>&1 # durable streaming audit trail
|
|
81
|
+
```
|
|
82
|
+
- `</dev/null` ALWAYS (no TTY → hang). `STREAM` = parseable events; **don't** swallow everything with
|
|
83
|
+
`2>/dev/null`.
|
|
84
|
+
- **The stream log IS the audit trail (always capture).** It records, live and progressively, EVERYTHING the
|
|
85
|
+
CLI does: each shell `command`, item started/completed, the CLI's `agent_message` (reasoning + answers),
|
|
86
|
+
tool-calls, and the final `DONE_SIGNAL` (with `USAGE`/tokens). A "last message" capture (`-o` and friends)
|
|
87
|
+
holds only the **final** message; the stream holds the **whole path**.
|
|
88
|
+
- **Durability (critical for "audit later"):** write the stream log to a dir **outside** the worktree (step 3).
|
|
89
|
+
If it lived in the worktree's `QA/`, post-merge cleanup would delete it and the audit would vanish. Audit
|
|
90
|
+
later: shell commands `grep -oE '"command":"[^"]*"' <log>`; CLI reasoning/answers `grep '"agent_message"'
|
|
91
|
+
<log>`; tokens via the adapter's `USAGE` field; a readable transcript = `agent_message` + `command` in file
|
|
92
|
+
order.
|
|
93
|
+
5. **SESSION PER TASK (the heart) — capture on first run, resume by id.**
|
|
94
|
+
- **First run:** obtain the **session-id** per the adapter's `SESSION_ID` (from the stream, a sidecar, or a
|
|
95
|
+
fixed flag) and write it to the durable sidecar `<AUDIT>/<slug>.session` (one line: the id). This sidecar
|
|
96
|
+
lives outside the worktree → it survives `git worktree remove`.
|
|
97
|
+
- **Resume the SAME context:** read `<AUDIT>/<slug>.session` and re-run the adapter's `RESUME <id>` with the
|
|
98
|
+
follow-up prompt → the CLI continues the **same session/context** (its reasoning, the files it already
|
|
99
|
+
touched, the gate state). This is how "come back to the C6 run with full context" works: re-run with the id.
|
|
100
|
+
- **Fallback:** if the sidecar is missing, the adapter's `RESUME_LAST` resumes the last session of this cwd
|
|
101
|
+
(worktree = the session's cwd), so context is recoverable as long as you run from the same worktree.
|
|
102
|
+
- Always record the session-id + sidecar path in the Structured Return (Artifacts) so a later turn can resume.
|
|
103
|
+
6. **Detect "DONE" — by the stream, NEVER by `pgrep` of the worktree path.** The done signal is the adapter's
|
|
104
|
+
`DONE_SIGNAL` in the stream log **+** the worktree showing a commit/report (`git -C <worktree> log`, last
|
|
105
|
+
message filled). A `pgrep -f "<worktree-path>"` (or `-f "<...>/last-message"`) **self-matches your own grep
|
|
106
|
+
command** (the path is in the grep's argv) → false "running" that can hold a **READY** delivery for hours (and
|
|
107
|
+
a `until ! pgrep ...` waiter with that pattern **never terminates**, since it sees itself alive). In background
|
|
108
|
+
(`run_in_background`/Workflow), the **completion notification** is the signal. If you truly need pgrep,
|
|
109
|
+
restrict to `pgrep -af "<cli> "` and filter `/proc/<pid>/cmdline` — never pgrep the raw path.
|
|
110
|
+
7. **Gate needs network?** Auto-approve modes that keep a sandbox **block network** for the CLI's shell commands →
|
|
111
|
+
`install`/build/test/E2E fail with `EAI_AGAIN`. If the prompt tells the CLI to run the gate, the adapter's
|
|
112
|
+
`AUTO` flag must be the **network-allowed** variant (full access) so the CLI runs the gate and self-validates.
|
|
113
|
+
Justified because the **hard RULE** guarantees an isolated worktree. Without network in the gate, the CLI only
|
|
114
|
+
implements and reports `blockers` (the gate then sits with the parent).
|
|
115
|
+
8. **Read-only / analysis mode:** when only reviewing (no edits), use the adapter's read-only variant and drop the
|
|
116
|
+
auto-edit flag.
|
|
117
|
+
|
|
118
|
+
## Mandatory evaluation — 0–10 score (ALWAYS)
|
|
119
|
+
When the run finishes, the parent **evaluates the delivery and gives a 0–10 score** (10 = full conformance +
|
|
120
|
+
complete delivery). Do not skip it — it is the signal that decides gate vs escalation. Score against the prompt:
|
|
121
|
+
- **Scope/fence conformance** (did the ask; stayed inside the allowlist).
|
|
122
|
+
- **Technical gate** (lint/test/build/E2E per the prompt — green?).
|
|
123
|
+
- **Completeness** (every task/item delivered).
|
|
124
|
+
- **Hygiene** (committed, no junk, nothing outside the fence, no forbidden deps).
|
|
125
|
+
- **Quality / no regression.**
|
|
126
|
+
**Acceptance bar: score ≥9** (owner's decision). Bands: **≥9** = acceptable (ready for the human gate); **6–8** =
|
|
127
|
+
`FINDINGS` → **escalate** to reach ≥9; **<6** = failure → **escalate**. `BLOCKED` if the ladder is exhausted
|
|
128
|
+
without reaching 9. Always show the score + a short per-criterion rationale.
|
|
129
|
+
|
|
130
|
+
## Dual evaluation: the CLI auto-gates (MAX effort) → Claude re-gates (compares scores)
|
|
131
|
+
The CLI **can't grade its own exam alone** — hence two layers. The CLI auto-gates cheaply (close to the work) and
|
|
132
|
+
**Claude audits independently** and **compares the scores** (catches an inflated self-score).
|
|
133
|
+
1. **CLI auto-gate (loop, MAX effort).** The prompt MUST instruct: after implementing, **run the SAME gate** and
|
|
134
|
+
give a **self-score 0–10**; **fix and re-run while the self-score <9 or the gate isn't green**, at max effort.
|
|
135
|
+
Stop at self-score ≥9 + green gate (or report `blockers`). The final report carries the self-score + per
|
|
136
|
+
criterion.
|
|
137
|
+
2. **Claude re-gate (independent).** When the CLI declares pass, the parent **re-runs the SAME gate** (fan-out,
|
|
138
|
+
prefer Workflow → `/workflows`) and gives its **own 0–10** — without trusting the self-score.
|
|
139
|
+
3. **Compare + decide.** Claude ≥9 and small gap → **PASS** (ready for the owner's merge decision). Claude <9 OR a
|
|
140
|
+
large gap (CLI overestimated) → re-execute: hand the gaps back via **session resume** (step 5, max effort) and
|
|
141
|
+
repeat 1→2→3 until it converges. **The score that counts for acceptance is Claude's**; the self-score is signal
|
|
142
|
+
+ an inflation detector. Always record both scores + the gap in the Structured Return.
|
|
143
|
+
|
|
144
|
+
## Graded escalation on failure
|
|
145
|
+
If the score is low / the gate failed / the CLI didn't finish, **re-run the SAME task one notch up** — gradual, no
|
|
146
|
+
giving up on the first stumble, no jumping to the top.
|
|
147
|
+
- **Ladder (one at a time):** first **effort** low→medium→high→xhigh (adapter names them); exhausted, bump the
|
|
148
|
+
**model** one tier and reset effort to high. Re-run and **re-score**.
|
|
149
|
+
- **Continue vs restart:** coherent partial edits → **resume the session** (step 5, keeps context). Broken/dirty
|
|
150
|
+
worktree → **reset first** (`git -C <worktree> reset --hard && git clean -fd`) and run fresh at the higher notch
|
|
151
|
+
— don't stack error on error.
|
|
152
|
+
- **Stop:** at **score ≥9** (ready for the gate) OR when **exhausted** (strongest model + max effort still below)
|
|
153
|
+
→ `BLOCKED` with evidence. Announce each notch; with autonomy, escalate to the ceiling yourself.
|
|
154
|
+
|
|
155
|
+
## Detailed output → direct the next step
|
|
156
|
+
The delivery must be **detailed enough for the parent to decide the next step** — not an opaque "done". When it
|
|
157
|
+
finishes: **read the final message in full** + scan the stream; complement with `git -C <worktree> status` and
|
|
158
|
+
`git diff --stat` to see what truly changed (don't trust only what the CLI said). Then **produce a HANDOFF**: what
|
|
159
|
+
the **gate** should focus on, what to **adjust/redo**, whether to **escalate**, what's **outside the fence /
|
|
160
|
+
uncommitted**, and the **blockers** — record it in the Structured Return (Evidence/Artifacts/Next Step). If the
|
|
161
|
+
report is shallow, treat as `FINDINGS` and ask for detail (resume) or reconstruct it from the diff first.
|
|
162
|
+
|
|
163
|
+
## Telemetry (tokens + time) — always report
|
|
164
|
+
The stream ends with the adapter's `USAGE` block (token counts). Extract it from the log.
|
|
165
|
+
- **Effective billable ≈ `(input − cached_input) + output`** — input is often ~95%+ cache; reporting only the raw
|
|
166
|
+
number misleads. Show both (raw + effective).
|
|
167
|
+
- **Wall-clock:** the done event usually carries no duration → measure it yourself: wrap the dispatch with
|
|
168
|
+
`/usr/bin/time` or `date +%s` before/after. Report in minutes.
|
|
169
|
+
- **Command count:** `grep -c '"command"' <log>` (effort proxy).
|
|
170
|
+
- Record all of it under Structured Return → Telemetry. Useful for cost, escalation, and comparing fan-out phases.
|
|
171
|
+
|
|
172
|
+
## Discipline (when finishing)
|
|
173
|
+
- **STOP — not merged.** The CLI implemented in the worktree; **run the gate** (tests/lint/build + review; if the
|
|
174
|
+
project uses dev-workflow: `/dw-review` + `/dw-qa` + `/dw-secure-audit`) **before** any merge.
|
|
175
|
+
- **Merge = the owner's explicit decision.** Never automatic here.
|
|
176
|
+
- Flag **uncommitted** work or edits **outside the fence**.
|
|
177
|
+
- **Stop/abort a running CLI:** use **`TaskStop <task_id>`** (if `run_in_background`/Workflow) OR
|
|
178
|
+
**`git worktree remove --force <worktree>`** (pulls the rug — the CLI has nowhere to write and dies). Fallback:
|
|
179
|
+
`kill -9` **only** the PIDs from `pgrep -af "<cli> "` whose `/proc/<pid>/cmdline` matches the worktree tag.
|
|
180
|
+
**NEVER walk UP the process tree (ppid → ppid…) to kill "the supervisor":** the background CLI is a **child of
|
|
181
|
+
the Claude session itself** (`<cli> ← claude ← bash ← init`) → killing the ancestors **takes down the session**.
|
|
182
|
+
Apparent "respawns" are just the node workers of ONE run.
|
|
183
|
+
|
|
184
|
+
## Anti-patterns
|
|
185
|
+
- Running in the main checkout / without confirming the worktree — corrupts the active tree. *(pre-flight 2)*
|
|
186
|
+
- Merging/pushing inside the skill — merge lives outside, after the gate.
|
|
187
|
+
- Skipping the 0–10 score — loses the quality/escalation signal.
|
|
188
|
+
- Suppressing all output (or not capturing the stream to a log) — loses the audit of what the CLI did.
|
|
189
|
+
- **Detecting "done" by `pgrep` of the worktree path** — self-matches your own command → false "running" that
|
|
190
|
+
holds ready deliveries. Use `DONE_SIGNAL` + worktree. *(step 6)*
|
|
191
|
+
- **Killing the CLI by walking up the PID tree** — takes down the Claude session. Use `TaskStop`/`worktree
|
|
192
|
+
remove`. *(Discipline)*
|
|
193
|
+
- Losing the session-id — without the sidecar you can't resume the SAME context; capture it on the first run.
|
|
194
|
+
|
|
195
|
+
## Structured Return
|
|
196
|
+
- **Status:** `PASS` · `FINDINGS` · `BLOCKED` · `NOT_APPLICABLE` — `PASS` = ran, score ≥9, stopped clean in the
|
|
197
|
+
right worktree, ready for the gate; `FINDINGS` = ran, score 6–8 or caveats (uncommitted/out-of-fence/partial);
|
|
198
|
+
`BLOCKED` = missing CLI/credential/worktree/prompt/adapter table, or escalation exhausted without reaching 9;
|
|
199
|
+
`NOT_APPLICABLE` = no worktree+prompt → still planning.
|
|
200
|
+
- **Score:** **Claude's score** (0–10 — counts for acceptance, bar ≥9) + the **CLI self-score** + the **gap**;
|
|
201
|
+
per-criterion rationale (conformance/gate/completeness/hygiene/quality). Large gap = inflated self-score.
|
|
202
|
+
- **Scope:** worktree + branch + prompt used; CLI + model + effort + sandbox/auto mode; escalation notches taken.
|
|
203
|
+
- **Evidence:** path of the durable audit log + final-message file; stream JSONL excerpt; `git status`/diff of the
|
|
204
|
+
worktree post-run.
|
|
205
|
+
- **Artifacts:** files created/changed (diff summary); **the session-id + sidecar path** (`<AUDIT>/<slug>.session`)
|
|
206
|
+
so a later turn can resume; the durable audit log path.
|
|
207
|
+
- **Decisions:** model/effort and why; implementation vs read-only; continue (resume) vs reset on retry.
|
|
208
|
+
- **Risks:** out of fence, uncommitted, gate not run, dual-use (autonomous edits).
|
|
209
|
+
- **Telemetry:** tokens from the done event (input/cached/output/reasoning + **effective billable**) + **wall-clock**
|
|
210
|
+
+ command count.
|
|
211
|
+
- **Next Step:** "run the gate in the worktree; merge is the owner's decision" — and the exact resume command
|
|
212
|
+
(`RESUME <id>`) to continue this session.
|
|
213
|
+
|
|
214
|
+
## Notes
|
|
215
|
+
The CLI-specific flag names, model list, resume form, and session-id capture live in the **adapter table** of the
|
|
216
|
+
invoking command (`dw-codex-run` / `dw-claude-run` / `dw-copilot-run`). This skill holds the CLI-agnostic protocol
|
|
217
|
+
only; substitute the adapter slots and everything above applies unchanged.
|
|
@@ -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`.
|