@brunosps00/dev-workflow 1.4.0 → 1.6.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/plugin.json +1 -1
- package/README.md +6 -5
- package/lib/constants.js +6 -4
- package/lib/hooks.js +53 -11
- package/lib/init.js +49 -1
- package/package.json +4 -2
- package/scaffold/config/stack-mappings.json +40 -0
- package/scaffold/en/commands/dw-adr.md +49 -11
- package/scaffold/en/commands/dw-analyze-project.md +10 -1
- package/scaffold/en/commands/dw-brainstorm.md +103 -32
- package/scaffold/en/commands/dw-claude-run.md +8 -5
- package/scaffold/en/commands/dw-context-budget.md +9 -0
- package/scaffold/en/commands/dw-harness-audit.md +3 -0
- package/scaffold/en/commands/dw-learn.md +41 -0
- package/scaffold/en/commands/dw-plan.md +36 -5
- package/scaffold/en/commands/dw-review.md +1 -0
- package/scaffold/en/commands/dw-run.md +1 -0
- package/scaffold/en/templates/adr-template.md +8 -4
- package/scaffold/en/templates/idea-onepager.md +44 -2
- package/scaffold/pt-br/commands/dw-adr.md +49 -11
- package/scaffold/pt-br/commands/dw-analyze-project.md +10 -1
- package/scaffold/pt-br/commands/dw-brainstorm.md +105 -32
- package/scaffold/pt-br/commands/dw-claude-run.md +8 -5
- package/scaffold/pt-br/commands/dw-context-budget.md +9 -0
- package/scaffold/pt-br/commands/dw-harness-audit.md +3 -0
- package/scaffold/pt-br/commands/dw-learn.md +41 -0
- package/scaffold/pt-br/commands/dw-plan.md +36 -5
- package/scaffold/pt-br/commands/dw-review.md +1 -0
- package/scaffold/pt-br/commands/dw-run.md +1 -0
- package/scaffold/pt-br/templates/adr-template.md +8 -4
- package/scaffold/pt-br/templates/idea-onepager.md +44 -2
- package/scaffold/rules/README.md +22 -0
- package/scaffold/rules/common.md +29 -0
- package/scaffold/rules/csharp.md +18 -0
- package/scaffold/rules/python.md +18 -0
- package/scaffold/rules/react.md +18 -0
- package/scaffold/rules/rust.md +18 -0
- package/scaffold/rules/typescript.md +23 -0
- package/scaffold/rules-readme.md +8 -0
- package/scaffold/scripts/hooks/session-cost.mjs +126 -0
- package/scaffold/scripts/hooks/statusline.mjs +31 -0
- package/scaffold/scripts/lib/model-prices.json +12 -0
- package/scaffold/skill-registry.json +25 -1
- package/scaffold/skills/dw-cli-run/SKILL.md +13 -9
- package/scaffold/skills/dw-codebase-intel/SKILL.md +3 -1
- package/scaffold/skills/dw-debug-protocol/SKILL.md +4 -0
- package/scaffold/skills/dw-debug-protocol/references/agent-degradation.md +30 -0
- package/scaffold/skills/dw-domain-modeling/SKILL.md +84 -0
- package/scaffold/skills/dw-domain-modeling/references/adr-policy.md +48 -0
- package/scaffold/skills/dw-domain-modeling/references/glossary-format.md +66 -0
- package/scaffold/skills/dw-execute-phase/SKILL.md +13 -0
- package/scaffold/skills/dw-git-discipline/SKILL.md +1 -0
- package/scaffold/skills/dw-grilling/SKILL.md +98 -0
- package/scaffold/skills/dw-grilling/references/decision-tree.md +56 -0
- package/scaffold/skills/dw-grilling/references/interview-loop.md +52 -0
- package/scaffold/skills/dw-llm-eval/SKILL.md +12 -0
- package/scaffold/skills/dw-memory/SKILL.md +12 -1
- package/scaffold/skills/dw-memory/references/instincts.md +45 -0
- package/scaffold/skills/dw-review-rigor/SKILL.md +12 -0
- package/scaffold/skills/dw-review-rigor/references/false-positives.md +21 -0
- package/scaffold/skills/dw-review-rigor/references/self-eval-rubric.md +38 -0
- package/scaffold/skills/dw-silent-failure/SKILL.md +4 -2
- package/scaffold/skills/dw-simplification/SKILL.md +13 -0
- package/scaffold/skills/dw-simplification/references/dead-code-tools.md +23 -0
- package/scaffold/skills/dw-testing-discipline/SKILL.md +17 -0
- package/scaffold/skills/dw-ui-discipline/SKILL.md +1 -1
- package/scaffold/skills/dw-verify/SKILL.md +1 -1
- package/scaffold/skills/dw-verify/references/pre-check-and-status.md +28 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dw-domain-modeling
|
|
3
|
+
description: "Internal domain-vocabulary protocol for the native Grill flow. Loaded by /dw-brainstorm (grill mode) and referenced by /dw-analyze-project to keep canonical vocabulary: challenge fuzzy or overloaded terms, propose precise canonical names, stress-test with concrete edge-case scenarios, cross-check terms against the code, and persist resolved terms safely and lazily into .dw/domain (glossary for a single context, context-map plus per-context files for many). Rare ADR policy. Pipeline-internal, never exported, never implements code."
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Grep
|
|
7
|
+
- Glob
|
|
8
|
+
- Write
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# dw-domain-modeling — canonical vocabulary, kept in .dw/domain
|
|
12
|
+
|
|
13
|
+
The vocabulary layer of the native Grill flow. It keeps the language of the domain sharp: one canonical term per
|
|
14
|
+
concept, fuzzy language challenged, overloaded terms split, every term cross-checked against the code. Resolved
|
|
15
|
+
terms persist to `.dw/domain/**` — **never** to root `CONTEXT.md` and **never** into the auto-generated
|
|
16
|
+
`.dw/rules/` module files (those describe what the code IS; the glossary is human-curated vocabulary).
|
|
17
|
+
|
|
18
|
+
> **Internal protocol.** Loaded by `/dw-brainstorm --mode=grill`; read and linked (never regenerated) by
|
|
19
|
+
> `/dw-analyze-project`. Not standalone, not exported to the à-la-carte plugin.
|
|
20
|
+
|
|
21
|
+
## The disciplines
|
|
22
|
+
|
|
23
|
+
1. **Canonical vocabulary — one term per concept.** When several words compete for the same idea, pick the best
|
|
24
|
+
and record the rest as discouraged synonyms. The glossary's job is to end the debate, not catalogue it.
|
|
25
|
+
2. **Challenge fuzzy / overloaded terms.** When the user says "the user thing" or uses one word for two
|
|
26
|
+
concepts (`User` the account vs `User` the person), stop and propose precise names. Don't pretend to
|
|
27
|
+
understand — push back until the term is sharp.
|
|
28
|
+
3. **Stress-test with concrete scenarios.** Force precision with edge cases: *"A guest checks out without an
|
|
29
|
+
account — is that a Customer or a Visitor?"* Vague answers become the next grill question.
|
|
30
|
+
4. **Cross-check against the code.** Before recording a term, confirm it against the codebase. Surface
|
|
31
|
+
contradictions with the file and line: *"You call it `Subscription`, but `src/billing/plan.ts:12` models it
|
|
32
|
+
as `Plan`. Which is canonical?"* Don't argue from generalities.
|
|
33
|
+
5. **Persist safely, lazily, and only when authorized.** Create a `.dw/domain/**` file only **after** a term is
|
|
34
|
+
resolved AND the Grill flow has write authorization. No speculative files; no writing an unresolved term.
|
|
35
|
+
6. **Route single vs multi context.** One bounded context → one flat `.dw/domain/glossary.md`. Multiple contexts
|
|
36
|
+
(the same word means different things in billing vs shipping) → `.dw/domain/context-map.md` plus one
|
|
37
|
+
`.dw/domain/contexts/<slug>.md` per context. Full routing + format: `references/glossary-format.md`.
|
|
38
|
+
7. **ADR rarely, and only on approval.** Vocabulary decisions are not ADRs. Reach for an ADR only on the
|
|
39
|
+
three-criterion test, and only with separate explicit user approval — see `references/adr-policy.md`.
|
|
40
|
+
|
|
41
|
+
## Native artifacts
|
|
42
|
+
|
|
43
|
+
| Path | When |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `.dw/domain/glossary.md` | Single bounded context — the default. |
|
|
46
|
+
| `.dw/domain/context-map.md` | Two or more contexts — names the contexts and the terms that cross or clash. |
|
|
47
|
+
| `.dw/domain/contexts/<slug>.md` | Per-context glossary, one file per context. |
|
|
48
|
+
|
|
49
|
+
All created **lazily**: the directory and file appear only when the first term in that context is resolved and
|
|
50
|
+
authorization exists. `/dw-analyze-project` **reads and links** these when present and must **preserve** them —
|
|
51
|
+
never regenerate or overwrite `.dw/domain/**`.
|
|
52
|
+
|
|
53
|
+
## What a glossary entry is (and is not)
|
|
54
|
+
|
|
55
|
+
A definition is **one or two sentences** that say what the domain term **is**, plus a short list of discouraged
|
|
56
|
+
synonyms. It **excludes** implementation details (classes, files, tables), requirements ("must load in 200ms"),
|
|
57
|
+
scratch notes, and general programming concepts (timeouts, retries, DTOs) — even when the project uses them
|
|
58
|
+
heavily. The test: *is this concept unique to this domain, or general programming?* Only the former belongs.
|
|
59
|
+
Format and examples: `references/glossary-format.md`.
|
|
60
|
+
|
|
61
|
+
## Anti-patterns
|
|
62
|
+
|
|
63
|
+
- Writing vocabulary into `.dw/rules/<module>.md` or a root `CONTEXT.md` instead of `.dw/domain/**`.
|
|
64
|
+
- Creating a glossary file for a term that is not yet resolved, or before write authorization exists.
|
|
65
|
+
- Definitions that describe the code ("a `Repository` class in `src/`") instead of the concept.
|
|
66
|
+
- Listing every synonym as equal — pick one canonical term, discourage the rest.
|
|
67
|
+
- Splitting into multiple contexts prematurely — a single flat glossary is right until a word genuinely clashes
|
|
68
|
+
across contexts.
|
|
69
|
+
- Regenerating or overwriting `.dw/domain/**` from `/dw-analyze-project`.
|
|
70
|
+
|
|
71
|
+
## Structured Return
|
|
72
|
+
|
|
73
|
+
- **Status:** `PASS` · `FINDINGS` · `BLOCKED` · `NOT_APPLICABLE` — `PASS` when the terms in scope are resolved,
|
|
74
|
+
cross-checked against the code, and (when authorized) persisted to the correct `.dw/domain/**` path; `FINDINGS`
|
|
75
|
+
when terms remain fuzzy, a code contradiction is open, or authorization is missing so nothing was written;
|
|
76
|
+
`BLOCKED` when the caller supplied no vocabulary to resolve or the code cross-check cannot run;
|
|
77
|
+
`NOT_APPLICABLE` when there is no domain vocabulary at stake.
|
|
78
|
+
- **Scope:** the terms examined, single- vs multi-context routing, and the target `.dw/domain/**` path(s).
|
|
79
|
+
- **Evidence:** the code cross-checks (file:line) and scenarios used to sharpen each term.
|
|
80
|
+
- **Artifacts:** the glossary / context-map / per-context files written or proposed, with paths.
|
|
81
|
+
- **Decisions:** each canonical term chosen, the discouraged synonyms, and the routing decision.
|
|
82
|
+
- **Risks:** unresolved fuzziness, open code contradictions, or vocabulary written without authorization.
|
|
83
|
+
- **Next Step:** resolve the remaining terms, request write authorization, or hand the canonical vocabulary back
|
|
84
|
+
to the grill / one-pager.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# ADR policy — rare, three-criterion, approval-gated
|
|
2
|
+
|
|
3
|
+
Most decisions surfaced during a grill are **not** ADRs. Vocabulary choices, scope calls, and reversible
|
|
4
|
+
decisions belong in the glossary or the one-pager, not the ADR log. An ADR is for the rare decision that is
|
|
5
|
+
expensive to unwind and non-obvious to a future reader.
|
|
6
|
+
|
|
7
|
+
## The three-criterion test (all must hold)
|
|
8
|
+
|
|
9
|
+
| Criterion | Test |
|
|
10
|
+
|---|---|
|
|
11
|
+
| **Hard to reverse** | If we change this in 6 months, does it cost meaningfully more than a day — a migration, a re-architecture, a contract change? |
|
|
12
|
+
| **Surprising without context** | Would a competent new contributor reasonably reach a *different* decision, absent this record? |
|
|
13
|
+
| **Genuine trade-off** | Was there a real alternative we considered and chose against — a rejection worth remembering? |
|
|
14
|
+
|
|
15
|
+
If any criterion fails, **do not** write an ADR. Record the decision where it belongs (glossary, one-pager, PRD)
|
|
16
|
+
and move on. ADR-ing every casual decision turns the log into noise.
|
|
17
|
+
|
|
18
|
+
## Approval is always separate
|
|
19
|
+
|
|
20
|
+
Even when all three criteria hold, **creating an ADR needs a separate, explicit user approval.** A resolved grill
|
|
21
|
+
decision authorizes the glossary/alignment update — it does **not** authorize an ADR. Offer the ADR, state which
|
|
22
|
+
criteria it meets, and wait for the user to approve before anything is written.
|
|
23
|
+
|
|
24
|
+
## Routing — repo vs prd scope
|
|
25
|
+
|
|
26
|
+
ADRs are created via `/dw-adr`, which routes by `--scope`:
|
|
27
|
+
|
|
28
|
+
- **`--scope=repo`** → `.dw/adrs/adr-NNN.md`. Repo-wide decisions, and any decision made **before a PRD exists**
|
|
29
|
+
(a greenfield grill naturally produces repo-scoped ADRs).
|
|
30
|
+
- **`--scope=prd`** → `.dw/spec/<prd>/adrs/adr-NNN.md`. Decisions bound to a specific active PRD.
|
|
31
|
+
|
|
32
|
+
Default resolution when scope is unspecified (`--scope=` is always authoritative): the uniquely **active** PRD →
|
|
33
|
+
`prd`; no active PRD → `repo`; several active PRDs (ambiguous) → **ask**, don't guess. `NNN` is sequential within
|
|
34
|
+
the chosen scope's ADR directory.
|
|
35
|
+
|
|
36
|
+
**Active vs historical PRD** — deterministic and conservative, reading only evidence the repo already records
|
|
37
|
+
(never guessing): a PRD directory is a candidate only when it is **not terminal** (its `prd.md` status is not
|
|
38
|
+
shipped/merged/delivered/done/archived/superseded/cancelled). Choose the active one by precedence — an **explicit
|
|
39
|
+
target** (named PRD or `PRD_PATH`) → the **active session** (`.dw/STATE.md`) → the **current `feat/prd-<slug>`
|
|
40
|
+
branch**. If more than one non-terminal PRD survives with no disambiguating signal, **ask**. The authoritative
|
|
41
|
+
rule lives in the `/dw-adr` "Active PRD" section.
|
|
42
|
+
|
|
43
|
+
## What qualifies
|
|
44
|
+
|
|
45
|
+
Architectural shape, integration patterns between components, high-lock-in technology choices, bounded-context
|
|
46
|
+
boundaries, deliberate deviations from convention, non-visible constraints, and non-obvious rejected
|
|
47
|
+
alternatives. A vocabulary decision — "we call it `Tenant`, not `Org`" — does **not** qualify; it is a glossary
|
|
48
|
+
entry.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Glossary format and context routing
|
|
2
|
+
|
|
3
|
+
Where domain vocabulary lives, what an entry looks like, and how to decide between a single flat glossary and a
|
|
4
|
+
multi-context map.
|
|
5
|
+
|
|
6
|
+
## Paths (created lazily)
|
|
7
|
+
|
|
8
|
+
| Path | Purpose |
|
|
9
|
+
|---|---|
|
|
10
|
+
| `.dw/domain/glossary.md` | The single-context default. One flat glossary for the whole project. |
|
|
11
|
+
| `.dw/domain/context-map.md` | Multi-context index: names each bounded context and the terms that cross or clash between them. |
|
|
12
|
+
| `.dw/domain/contexts/<slug>.md` | One glossary per bounded context (`<slug>` = kebab-case context name). |
|
|
13
|
+
|
|
14
|
+
Never write vocabulary to root `CONTEXT.md` or to `.dw/rules/<module>.md`. The `.dw/rules/` files are
|
|
15
|
+
auto-generated analysis of what the code IS; the glossary is human-curated vocabulary and must survive
|
|
16
|
+
`/dw-analyze-project` runs untouched.
|
|
17
|
+
|
|
18
|
+
Create files only when a term is **resolved** and the Grill flow has **write authorization**. Do not scaffold
|
|
19
|
+
empty files or write an unresolved term.
|
|
20
|
+
|
|
21
|
+
## Entry format
|
|
22
|
+
|
|
23
|
+
Each term is a short entry:
|
|
24
|
+
|
|
25
|
+
```markdown
|
|
26
|
+
### Order
|
|
27
|
+
A customer's committed request to buy one or more items, in one of: pending, paid, shipped, delivered, refunded.
|
|
28
|
+
|
|
29
|
+
_Avoid:_ Purchase, Cart, Transaction
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Rules for an entry:
|
|
33
|
+
|
|
34
|
+
- **One or two sentences.** Define what the term **is**, not what a class does. If it needs a paragraph, the
|
|
35
|
+
concept is probably two concepts — split it.
|
|
36
|
+
- **`_Avoid:_` line** lists the discouraged synonyms. Pick one canonical term; every competing word goes here so
|
|
37
|
+
the debate does not reopen.
|
|
38
|
+
- **Exclude** implementation detail (files, classes, tables, endpoints), requirements/NFRs, scratch notes, and
|
|
39
|
+
general programming concepts (timeout, retry, DTO, cache) even if heavily used.
|
|
40
|
+
- **Inclusion test:** *is this concept unique to this domain, or is it general programming?* Only the former is a
|
|
41
|
+
glossary term. `Order`, `Tenant`, `Dunning` — yes. `Timeout`, `Repository`, `Idempotency key` — no.
|
|
42
|
+
|
|
43
|
+
Group entries under `##` subheadings when natural clusters emerge; a flat list of `###` terms is fine for a small
|
|
44
|
+
glossary.
|
|
45
|
+
|
|
46
|
+
## Single vs multi context — how to route
|
|
47
|
+
|
|
48
|
+
Start with **one flat `.dw/domain/glossary.md`**. It is the right default and stays right until a word genuinely
|
|
49
|
+
means different things in different parts of the system.
|
|
50
|
+
|
|
51
|
+
Split to multi-context only when a term **clashes across bounded contexts** — e.g. `Account` means a login in
|
|
52
|
+
Identity but a ledger in Billing. Then:
|
|
53
|
+
|
|
54
|
+
1. Create `.dw/domain/context-map.md`. List each context (Identity, Billing, Shipping…), a one-line description,
|
|
55
|
+
and the **shared or clashing terms** with the context each meaning belongs to.
|
|
56
|
+
2. Move each context's terms into `.dw/domain/contexts/<slug>.md` (e.g. `contexts/billing.md`).
|
|
57
|
+
3. In the context map, note translations: "Billing `Account` ≈ Identity `Organization`, not Identity `Account`."
|
|
58
|
+
|
|
59
|
+
Do not split pre-emptively. A single clean glossary beats three thin ones. When in doubt, stay single-context and
|
|
60
|
+
record the tension as a grill decision rather than forking files.
|
|
61
|
+
|
|
62
|
+
## Interaction with /dw-analyze-project
|
|
63
|
+
|
|
64
|
+
`/dw-analyze-project` must, when `.dw/domain/**` exists: read it, link it from `.dw/rules/index.md` (so
|
|
65
|
+
downstream commands find the canonical vocabulary), and **preserve it verbatim** — never regenerate, merge, or
|
|
66
|
+
overwrite. The analyzer owns `.dw/rules/**`; the Grill flow owns `.dw/domain/**`.
|
|
@@ -94,6 +94,19 @@ Closes RF-XX (partial — see tasks.md).
|
|
|
94
94
|
|
|
95
95
|
The commit message format is consistent across waves so `/dw-generate-pr` can build a clean PR body. See `references/atomic-commits.md`.
|
|
96
96
|
|
|
97
|
+
## De-Sloppify Pass (optional cleanup task)
|
|
98
|
+
|
|
99
|
+
LLM implementers are thorough but leave slop — tests of framework/language behavior, defensive checks the type system already enforces, leftover `console.log`, over-handled impossible states. Constraining the implementer with "don't over-engineer" degrades its output unpredictably; a **separate cleanup pass in a fresh context** works better. Two focused agents beat one constrained agent.
|
|
100
|
+
|
|
101
|
+
To request one, a task in `tasks.md` may carry `Cleanup After: <N>` in its frontmatter. The executor runs it as its own task (own commit) right after task N's wave lands, scoped to task N's diff:
|
|
102
|
+
|
|
103
|
+
- Remove tests that assert language/framework behavior rather than business logic.
|
|
104
|
+
- Remove type checks and guards the type system or a prior validation already guarantees.
|
|
105
|
+
- Remove `console.log`/debug prints and commented-out code.
|
|
106
|
+
- Keep every business-logic test and every real error path — when unsure, keep it.
|
|
107
|
+
|
|
108
|
+
The cleanup task commits as `refactor(<scope>): de-slop <task N title>` and must leave the gate green (lint + tests + build) — it never changes behavior. Opt-in: no `Cleanup After:` means no cleanup task runs.
|
|
109
|
+
|
|
97
110
|
## Checkpoint Protocol
|
|
98
111
|
|
|
99
112
|
If the executor exhausts its context budget mid-phase OR the user signals stop:
|
|
@@ -78,6 +78,7 @@ When wired into `/dw-generate-pr`, every PR must:
|
|
|
78
78
|
| Branch is 5 days old, tons of conflicts | Rebase from main daily; don't let drift compound |
|
|
79
79
|
| PR has 2,000 lines | Split. Identify natural seams: schema, backend, frontend, tests |
|
|
80
80
|
| Stuck mid-merge with conflicts | Resolve, don't `git checkout --theirs` blindly. The conflict is information |
|
|
81
|
+
| Rebase or merge to integrate? | Local-only branch → **rebase** onto `main` (linear history). Shared/pushed branch → **merge** (never rebase history others have pulled) |
|
|
81
82
|
|
|
82
83
|
## What this skill does NOT do
|
|
83
84
|
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dw-grilling
|
|
3
|
+
description: "Internal decision-tree interview protocol for the native Grill flow. Loaded by /dw-brainstorm (grill mode) and /dw-plan to stress-test a plan or PRD to shared understanding: build a dependency-ordered decision tree, ask exactly ONE unresolved decision per turn with a recommended answer plus rationale and a real alternative, discover facts from the repo/docs instead of asking, leave decisions to the user, and gate alignment on explicit confirmation. Pipeline-internal, never exported, never implements code."
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Grep
|
|
7
|
+
- Glob
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# dw-grilling — interview to shared understanding, one decision at a time
|
|
11
|
+
|
|
12
|
+
A relentless-but-disciplined interview that sharpens a plan/PRD until author and reviewer reach a
|
|
13
|
+
**shared understanding** — the alignment layer of the native Grill flow. It walks the design tree branch by
|
|
14
|
+
branch, resolving dependencies one at a time. It does not brainstorm options and it does not implement; it
|
|
15
|
+
converges decisions. Persistence (glossary, one-pager, PRD) is delegated — see `dw-domain-modeling` for
|
|
16
|
+
vocabulary and the calling command for the idea one-pager / PRD.
|
|
17
|
+
|
|
18
|
+
> **Internal protocol.** Loaded by `/dw-brainstorm --mode=grill` and by `/dw-plan` when it consumes an aligned
|
|
19
|
+
> handoff. Not a standalone skill, not exported to the à-la-carte plugin. If no calling command supplied the
|
|
20
|
+
> Grill context (target artifact + write authorization state), return `NOT_APPLICABLE`.
|
|
21
|
+
|
|
22
|
+
## Hard rules (non-negotiable)
|
|
23
|
+
|
|
24
|
+
1. **Exactly one unresolved decision per turn, then wait.** Never dump a list of questions — a batch is
|
|
25
|
+
bewildering and lets the reviewer skim instead of decide. Ask, wait, integrate the answer, ask the next.
|
|
26
|
+
2. **Every question carries a recommendation.** Structure: *evidence (when available) → the decision →
|
|
27
|
+
recommended answer → one-line rationale → a meaningful alternative and its trade-off.* A question with no
|
|
28
|
+
recommended answer is not ready to ask. See `references/interview-loop.md`.
|
|
29
|
+
3. **Facts are discovered, decisions are asked.** If the answer can be found in the codebase, rules, intel,
|
|
30
|
+
or docs, look it up and state it — do not ask the user a question the repo already answers. Only genuine
|
|
31
|
+
**decisions** (choices with no single correct answer) go to the user.
|
|
32
|
+
4. **Decisions belong to the user.** Recommend, argue, push back on vague language — but the user chooses.
|
|
33
|
+
Never answer your own decision question and move on.
|
|
34
|
+
5. **No implementation, ever.** Grill never edits source code. It produces alignment, not commits.
|
|
35
|
+
6. **Alignment is gated on explicit confirmation.** Do not declare shared understanding (or `status: aligned`)
|
|
36
|
+
until every dependency branch is resolved, glossary/code contradictions are closed, no blocking decision
|
|
37
|
+
remains, AND the user explicitly confirms. Otherwise persist a draft/paused state and stop.
|
|
38
|
+
|
|
39
|
+
## Before the first question — build the decision tree
|
|
40
|
+
|
|
41
|
+
Inspect project facts and open questions, then order them by dependency (never ask a downstream decision before
|
|
42
|
+
its blocker is resolved):
|
|
43
|
+
|
|
44
|
+
1. Read what already exists: `.dw/rules/`, `.dw/intel/` (via `/dw-intel` when present), `.dw/constitution.md`,
|
|
45
|
+
`.dw/domain/**` (glossary / context-map), current PRDs/TechSpecs, recent git activity.
|
|
46
|
+
2. Extract the open decisions the plan/PRD implies. Fold in vocabulary tension surfaced by `dw-domain-modeling`
|
|
47
|
+
(fuzzy or overloaded terms are decisions too).
|
|
48
|
+
3. Order them into a **dependency tree**: a node that constrains others comes first. Record it so a later turn
|
|
49
|
+
(or `/dw-plan`) can resume. Full method + the shared-understanding gate: `references/decision-tree.md`.
|
|
50
|
+
|
|
51
|
+
## The loop
|
|
52
|
+
|
|
53
|
+
For each unresolved node, in dependency order:
|
|
54
|
+
|
|
55
|
+
1. **Discover** every fact the node needs (repo/docs). State the facts and their source.
|
|
56
|
+
2. **Frame the decision** and give the recommended answer + rationale + one real alternative/trade-off.
|
|
57
|
+
3. **Ask** — one decision, then wait.
|
|
58
|
+
4. **Integrate** the answer. A resolved answer authorizes the matching glossary/alignment update (delegated to
|
|
59
|
+
`dw-domain-modeling`; the caller persists to the one-pager/PRD). ADR creation still needs a separate explicit
|
|
60
|
+
approval — never auto-create one.
|
|
61
|
+
5. **Re-walk** the tree: the answer may unlock or reshape downstream nodes.
|
|
62
|
+
|
|
63
|
+
When the tree is exhausted and contradictions are closed, present the shared-understanding summary and ask the
|
|
64
|
+
user to confirm. Only then is the session `aligned`.
|
|
65
|
+
|
|
66
|
+
## Allowed writes (only when the caller authorized them)
|
|
67
|
+
|
|
68
|
+
Grill is read-first. The only stateful writes the flow may make, and only after the corresponding decision is
|
|
69
|
+
resolved and write authorization exists, are: `.dw/domain/**` (via `dw-domain-modeling`), the active
|
|
70
|
+
`.dw/spec/ideas/<slug>.md`, an explicitly active PRD/TechSpec **after showing the proposed change**, and routed
|
|
71
|
+
ADR paths (after separate approval). Never source code. If authorization is absent, keep interviewing and report
|
|
72
|
+
what you *would* persist.
|
|
73
|
+
|
|
74
|
+
## Anti-patterns
|
|
75
|
+
|
|
76
|
+
- Asking two or more decisions in one turn — the batch defeats the protocol.
|
|
77
|
+
- Asking a question the codebase already answers — that is a fact, look it up.
|
|
78
|
+
- Recommending nothing ("what do you want to do about X?") — always bring a recommended answer.
|
|
79
|
+
- Declaring alignment without the user's explicit confirmation.
|
|
80
|
+
- Writing any artifact before its decision is resolved and authorization exists.
|
|
81
|
+
- Generating an option matrix here — that is `option-matrix`, a separate and mutually exclusive phase.
|
|
82
|
+
|
|
83
|
+
## Structured Return
|
|
84
|
+
|
|
85
|
+
- **Status:** `PASS` · `FINDINGS` · `BLOCKED` · `NOT_APPLICABLE` — `PASS` when the tree is fully resolved,
|
|
86
|
+
contradictions closed, and the user explicitly confirmed shared understanding (session `aligned`); `FINDINGS`
|
|
87
|
+
when decisions were resolved but blocking questions, unclosed contradictions, or a pending confirmation remain
|
|
88
|
+
(draft/paused); `BLOCKED` when the caller supplied no target artifact or write-authorization state, or the
|
|
89
|
+
interview cannot proceed; `NOT_APPLICABLE` when invoked without Grill context (no plan/PRD to sharpen).
|
|
90
|
+
- **Scope:** the artifact under grill (one-pager / PRD / TechSpec), the decision tree size, and how many nodes
|
|
91
|
+
are resolved vs open.
|
|
92
|
+
- **Evidence:** the facts discovered from repo/rules/intel/docs (with sources) that were used instead of asking.
|
|
93
|
+
- **Artifacts:** decision tree, resolved decisions with the recommended answer and the user's choice, and any
|
|
94
|
+
authorized `.dw/domain/**` / one-pager / PRD updates (with paths).
|
|
95
|
+
- **Decisions:** each resolved decision, the alternative rejected, and why.
|
|
96
|
+
- **Risks:** open decisions, unclosed glossary/code contradictions, and any decision made without full evidence.
|
|
97
|
+
- **Next Step:** either "user to confirm shared understanding" (with the remaining nodes) or "aligned — hand off
|
|
98
|
+
to /dw-plan" — never implement here.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Decision tree — build, order, gate, resume
|
|
2
|
+
|
|
3
|
+
Grill is not a flat questionnaire. It is a walk down a **dependency-ordered decision tree**, so an upstream
|
|
4
|
+
decision is never asked after the downstream decision it constrains.
|
|
5
|
+
|
|
6
|
+
## Build the tree (before the first question)
|
|
7
|
+
|
|
8
|
+
1. **Gather open decisions.** Read the plan/PRD and the project's durable facts (`.dw/rules/`, `.dw/intel/` via
|
|
9
|
+
`/dw-intel`, `.dw/constitution.md`, `.dw/domain/**`, current PRDs/TechSpecs, recent git activity). List every
|
|
10
|
+
decision the artifact leaves open. Fold in vocabulary tension from `dw-domain-modeling` — an overloaded or
|
|
11
|
+
fuzzy term is a decision node.
|
|
12
|
+
2. **Separate facts from decisions.** Discard anything the repo already answers (those are facts to state, not
|
|
13
|
+
ask). What remains is the decision set.
|
|
14
|
+
3. **Draw dependencies.** For each decision, mark which other decisions must be settled first. "Is refund a
|
|
15
|
+
state or a flag?" blocks "which events transition into it?". A node that constrains others is a **parent**.
|
|
16
|
+
4. **Topologically order.** Ask parents before children. Independent branches can be walked in any order, but
|
|
17
|
+
within a branch always resolve the blocker first.
|
|
18
|
+
|
|
19
|
+
Record the tree (nodes, dependencies, resolved/open) so the session — or a later `/dw-plan` handoff — can resume
|
|
20
|
+
exactly where it stopped.
|
|
21
|
+
|
|
22
|
+
## Walk the tree
|
|
23
|
+
|
|
24
|
+
Resolve nodes in dependency order using the per-turn contract (`interview-loop.md`). After each answer, **re-walk
|
|
25
|
+
the tree**: a resolved parent may add, remove, or reshape child nodes. New tension discovered mid-walk becomes a
|
|
26
|
+
new node, inserted in dependency order — not asked immediately if a blocker is still open.
|
|
27
|
+
|
|
28
|
+
## The shared-understanding gate
|
|
29
|
+
|
|
30
|
+
Declare alignment (and let the caller set the one-pager to `status: aligned`) only when **all** hold:
|
|
31
|
+
|
|
32
|
+
- Every dependency branch is resolved — no open decision node remains.
|
|
33
|
+
- Every glossary/code contradiction surfaced during the grill is closed (a canonical term chosen, or the code
|
|
34
|
+
discrepancy explained).
|
|
35
|
+
- No blocking open decision remains (a non-blocking "revisit later" may be recorded as a remaining decision).
|
|
36
|
+
- The user has **explicitly confirmed** shared understanding — not "sounds good", but an explicit yes to the
|
|
37
|
+
summary of resolved decisions and canonical vocabulary.
|
|
38
|
+
|
|
39
|
+
Present a shared-understanding summary before asking for confirmation: the resolved decisions, the canonical
|
|
40
|
+
terms, and the remaining (non-blocking) decisions with their owners.
|
|
41
|
+
|
|
42
|
+
## Paused / draft state
|
|
43
|
+
|
|
44
|
+
If the gate is not met — blocking decision open, contradiction unclosed, or the user not yet confirming — **do
|
|
45
|
+
not** declare alignment. Persist a draft/paused state:
|
|
46
|
+
|
|
47
|
+
- Keep the one-pager (or PRD) at its draft/paused status with the decision tree, resolved decisions, and the
|
|
48
|
+
remaining open nodes recorded (the caller performs the write, only if authorized).
|
|
49
|
+
- Return `FINDINGS` with the open nodes as the Next Step, so the next turn resumes the same tree.
|
|
50
|
+
|
|
51
|
+
## Handoff to /dw-plan
|
|
52
|
+
|
|
53
|
+
An `aligned` session is a handoff contract: the resolved product decisions, their evidence, and the canonical
|
|
54
|
+
vocabulary links. `/dw-plan` consumes this **without re-asking** the resolved decisions — it credits the aligned
|
|
55
|
+
evidence in its coverage matrices and asks only decisions the Grill did not cover (technical decisions may still
|
|
56
|
+
surface during TechSpec). Never re-litigate a decision the user already settled in the grill.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Interview loop — the per-turn contract
|
|
2
|
+
|
|
3
|
+
The unit of a grill is **one turn = one unresolved decision**. This file specifies the exact shape of a turn and
|
|
4
|
+
the fact-vs-decision discipline that keeps the interview honest.
|
|
5
|
+
|
|
6
|
+
## Question template
|
|
7
|
+
|
|
8
|
+
Every question is presented in this order. Skipping any part means the question is not ready to ask.
|
|
9
|
+
|
|
10
|
+
1. **Evidence (when available).** The facts you discovered from the repo/rules/intel/docs that bound this
|
|
11
|
+
decision, each with its source: `` src/orders/state.ts:42 defines OrderStatus = pending | paid | shipped ``.
|
|
12
|
+
If there is no evidence yet, discover it first — do not open with an unbounded question.
|
|
13
|
+
2. **The decision.** State the single choice on the table in one sentence.
|
|
14
|
+
3. **Recommended answer.** Your pick. Not "it depends" — commit to a default and let the user overrule it.
|
|
15
|
+
4. **Rationale.** One line on why the recommendation wins in *this* project's context.
|
|
16
|
+
5. **Alternative + trade-off.** At least one real alternative and what it costs — so the user is choosing, not
|
|
17
|
+
rubber-stamping. A recommendation with no stated alternative hides the trade-off.
|
|
18
|
+
|
|
19
|
+
Then **stop and wait.** Do not ask the next decision, do not preview the rest of the tree, do not answer your own
|
|
20
|
+
question. Integrate the reply, then move to the next node.
|
|
21
|
+
|
|
22
|
+
## Fact vs decision
|
|
23
|
+
|
|
24
|
+
The single most important discrimination in a grill:
|
|
25
|
+
|
|
26
|
+
- **Fact** — has one correct answer discoverable from the codebase, rules, intel, migrations, config, or
|
|
27
|
+
authoritative docs. *Look it up. Never ask.* Asking a fact wastes the user's turn and signals you did not read.
|
|
28
|
+
Example: "does the API already return `order_id` or `orderId`?" → grep, don't ask.
|
|
29
|
+
- **Decision** — has no single correct answer; it is a choice among viable options with a trade-off. *This is
|
|
30
|
+
what you ask*, one at a time, always with a recommendation. Example: "should a partially-refunded order be a
|
|
31
|
+
distinct state or a flag on `refunded`?"
|
|
32
|
+
|
|
33
|
+
When a "fact" turns out to be contested (the code says one thing, the user says another), that contradiction
|
|
34
|
+
itself becomes a decision — surface it: *"You said the API returns `OrderId`, but `src/api/orders.ts:42` returns
|
|
35
|
+
`{ order_id, status }`. Which is canonical?"*
|
|
36
|
+
|
|
37
|
+
## Recommendation discipline
|
|
38
|
+
|
|
39
|
+
- Recommend from evidence, not taste. Tie the pick to a rule, a code pattern, a constraint, or a prior decision.
|
|
40
|
+
- Make the recommendation falsifiable: state the one condition that would flip it.
|
|
41
|
+
- If you genuinely cannot recommend (truly balanced, user-values-dependent), say so explicitly and present the
|
|
42
|
+
two options with their trade-offs — but this should be rare. Defaulting to "no recommendation" is the failure
|
|
43
|
+
mode this protocol exists to prevent.
|
|
44
|
+
|
|
45
|
+
## Anti-patterns
|
|
46
|
+
|
|
47
|
+
- **Batching.** Five questions in one message. The reviewer skims and half go unanswered.
|
|
48
|
+
- **Interrogating facts.** Asking what the repo already states — reads as not having done the homework.
|
|
49
|
+
- **Empty questions.** "What should we do about caching?" with no recommendation and no alternative.
|
|
50
|
+
- **Leading past the answer.** Recommending, then implementing the recommendation before the user replies.
|
|
51
|
+
- **Vague acceptance.** Taking "sure, sounds good" to a bundle of decisions as alignment. One decision, one
|
|
52
|
+
explicit answer.
|
|
@@ -66,6 +66,17 @@ Structure:
|
|
|
66
66
|
|
|
67
67
|
See `references/reference-dataset.md` for case-design principles, sampling from production, and when to expand the set.
|
|
68
68
|
|
|
69
|
+
## Consistency (run-to-run stability)
|
|
70
|
+
|
|
71
|
+
The oracle ladder measures whether an output is *correct*; it does not measure whether the feature is *stable*. Because LLMs are non-deterministic, a case that passes once may fail the next run. Measure it:
|
|
72
|
+
|
|
73
|
+
- Re-run each case **N times** (default 3) against the same code + model + prompt.
|
|
74
|
+
- Record `pass_rate` (e.g. `2/3`) and `consistency` (fraction agreeing with the majority verdict) per case in `runs/<YYYY-MM-DD>.jsonl`.
|
|
75
|
+
- A case with pass_rate strictly between `1/N` and `(N-1)/N` is **flaky** — a signal, not a pass. A 2/3 pass hides a one-in-three production failure; investigate before shipping.
|
|
76
|
+
- Sample at the **temperature the feature uses in production** — consistency measured at temp 0 lies about a temp-0.7 feature.
|
|
77
|
+
|
|
78
|
+
Deterministic rungs (1–3) are usually stable; consistency matters most for rung 4 (LLM-as-judge) and agent trajectories. Record the run count `N` in the run log so later comparisons are apples-to-apples.
|
|
79
|
+
|
|
69
80
|
## RAG evaluation
|
|
70
81
|
|
|
71
82
|
Three orthogonal metrics — measure all three, not just one:
|
|
@@ -120,6 +131,7 @@ See `references/agent-eval.md` for examples and the decision tree.
|
|
|
120
131
|
- **Synthetic-only dataset.** No traceable production-failure source for any case. REJECTED — confirm at least 20% of cases come from real user inputs.
|
|
121
132
|
- **"Looks good to me" QA.** No reference dataset, no metric, no rubric — just sampling output and calling it good. REJECTED.
|
|
122
133
|
- **Coverage as metric.** Quoting "we tested 50 prompts" without saying what was measured. The number is meaningless without the metric.
|
|
134
|
+
- **Single-run eval on a non-deterministic feature.** Each case run once at production temperature; a lucky pass reported as a pass. REJECTED — report `pass_rate` over N runs (see Consistency).
|
|
123
135
|
|
|
124
136
|
## Integration with dev-workflow commands
|
|
125
137
|
|
|
@@ -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.
|
|
@@ -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.
|