@kiwidata/grimoire 0.1.3 → 0.1.4
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/AGENTS.md +56 -4
- package/README.md +28 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/check.js +1 -1
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/configure.d.ts +3 -0
- package/dist/commands/configure.d.ts.map +1 -0
- package/dist/commands/configure.js +19 -0
- package/dist/commands/configure.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +2 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/map.d.ts.map +1 -1
- package/dist/commands/map.js +10 -11
- package/dist/commands/map.js.map +1 -1
- package/dist/core/archive.d.ts.map +1 -1
- package/dist/core/archive.js +32 -43
- package/dist/core/archive.js.map +1 -1
- package/dist/core/check.d.ts.map +1 -1
- package/dist/core/check.js +115 -104
- package/dist/core/check.js.map +1 -1
- package/dist/core/ci.d.ts.map +1 -1
- package/dist/core/ci.js +50 -69
- package/dist/core/ci.js.map +1 -1
- package/dist/core/configure.d.ts +14 -0
- package/dist/core/configure.d.ts.map +1 -0
- package/dist/core/configure.js +434 -0
- package/dist/core/configure.js.map +1 -0
- package/dist/core/detect.d.ts.map +1 -1
- package/dist/core/detect.js +153 -26
- package/dist/core/detect.js.map +1 -1
- package/dist/core/diff.d.ts.map +1 -1
- package/dist/core/diff.js +62 -93
- package/dist/core/diff.js.map +1 -1
- package/dist/core/doc-style.d.ts +0 -4
- package/dist/core/doc-style.d.ts.map +1 -1
- package/dist/core/doc-style.js +28 -23
- package/dist/core/doc-style.js.map +1 -1
- package/dist/core/docs.js +106 -100
- package/dist/core/docs.js.map +1 -1
- package/dist/core/health.js +55 -77
- package/dist/core/health.js.map +1 -1
- package/dist/core/hooks.d.ts +0 -3
- package/dist/core/hooks.d.ts.map +1 -1
- package/dist/core/hooks.js +0 -11
- package/dist/core/hooks.js.map +1 -1
- package/dist/core/init.d.ts +2 -0
- package/dist/core/init.d.ts.map +1 -1
- package/dist/core/init.js +230 -406
- package/dist/core/init.js.map +1 -1
- package/dist/core/list.d.ts.map +1 -1
- package/dist/core/list.js +55 -65
- package/dist/core/list.js.map +1 -1
- package/dist/core/log.d.ts.map +1 -1
- package/dist/core/log.js +23 -33
- package/dist/core/log.js.map +1 -1
- package/dist/core/map.d.ts +15 -2
- package/dist/core/map.d.ts.map +1 -1
- package/dist/core/map.js +257 -194
- package/dist/core/map.js.map +1 -1
- package/dist/core/shared-setup.d.ts +0 -40
- package/dist/core/shared-setup.d.ts.map +1 -1
- package/dist/core/shared-setup.js +87 -52
- package/dist/core/shared-setup.js.map +1 -1
- package/dist/core/status.d.ts.map +1 -1
- package/dist/core/status.js +42 -52
- package/dist/core/status.js.map +1 -1
- package/dist/core/test-quality.d.ts +0 -8
- package/dist/core/test-quality.d.ts.map +1 -1
- package/dist/core/test-quality.js +24 -30
- package/dist/core/test-quality.js.map +1 -1
- package/dist/core/trace.d.ts.map +1 -1
- package/dist/core/trace.js +31 -41
- package/dist/core/trace.js.map +1 -1
- package/dist/core/update.d.ts.map +1 -1
- package/dist/core/update.js +61 -11
- package/dist/core/update.js.map +1 -1
- package/dist/core/validate.d.ts +1 -4
- package/dist/core/validate.d.ts.map +1 -1
- package/dist/core/validate.js +126 -148
- package/dist/core/validate.js.map +1 -1
- package/dist/utils/config.d.ts +15 -5
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +63 -42
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/fs.d.ts +0 -12
- package/dist/utils/fs.d.ts.map +1 -1
- package/dist/utils/fs.js +0 -12
- package/dist/utils/fs.js.map +1 -1
- package/dist/utils/paths.d.ts +0 -6
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +0 -6
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/spawn.d.ts +0 -3
- package/dist/utils/spawn.d.ts.map +1 -1
- package/dist/utils/spawn.js +0 -3
- package/dist/utils/spawn.js.map +1 -1
- package/package.json +1 -1
- package/skills/grimoire-apply/SKILL.md +84 -16
- package/skills/grimoire-audit/SKILL.md +21 -1
- package/skills/grimoire-bug/SKILL.md +48 -9
- package/skills/grimoire-commit/SKILL.md +2 -1
- package/skills/grimoire-design/SKILL.md +259 -0
- package/skills/grimoire-design-consult/SKILL.md +200 -0
- package/skills/grimoire-discover/SKILL.md +65 -2
- package/skills/grimoire-draft/SKILL.md +85 -2
- package/skills/grimoire-plan/SKILL.md +61 -18
- package/skills/grimoire-pr/SKILL.md +4 -6
- package/skills/grimoire-pr-review/SKILL.md +45 -114
- package/skills/grimoire-precommit-review/SKILL.md +205 -0
- package/skills/grimoire-refactor/SKILL.md +5 -5
- package/skills/grimoire-review/SKILL.md +74 -147
- package/skills/grimoire-verify/SKILL.md +33 -0
- package/skills/references/adversarial-personas.md +225 -0
- package/skills/references/brand-tokens-format.md +186 -0
- package/skills/references/code-quality.md +140 -0
- package/skills/references/design-heuristics.md +138 -0
- package/skills/references/design-input-formats.md +190 -0
- package/skills/references/pattern-guard.md +180 -0
- package/skills/references/refactor-scan-categories.md +152 -0
- package/skills/references/review-personas.md +405 -0
- package/skills/references/security-compliance.md +22 -1
- package/skills/references/visual-fidelity.md +206 -0
- package/templates/brand-tokens-example.json +13 -0
- package/templates/brand-voice-example.md +22 -0
- package/templates/design-tool-setup-stub.md +59 -0
|
@@ -35,7 +35,7 @@ Before doing anything, determine what kind of change this is:
|
|
|
35
35
|
- **Refactoring** → STOP. No behavior change = no grimoire artifact. Suggest an ADR only if it's a significant architectural shift.
|
|
36
36
|
- **Config/deps/formatting** → STOP. Not grimoire territory.
|
|
37
37
|
|
|
38
|
-
If unclear, ask the user one clarifying question to route correctly.
|
|
38
|
+
If unclear, ask the user one clarifying question to route correctly. **Do not guess the routing and proceed.** A wrong routing wastes both your context and the user's time — one question costs less.
|
|
39
39
|
|
|
40
40
|
### 2. Score Complexity
|
|
41
41
|
|
|
@@ -63,7 +63,20 @@ Before designing, research what already exists. Do not ask the user to research
|
|
|
63
63
|
|
|
64
64
|
Follow the methodology in `../references/build-vs-buy.md`. Present findings to the user and wait for agreement before proceeding.
|
|
65
65
|
|
|
66
|
+
### 4.0 Design Input Check
|
|
67
|
+
|
|
68
|
+
Before interviewing, check whether design artifacts already exist for this change. If so, the interview is grounded in real components and states rather than imagined ones.
|
|
69
|
+
|
|
70
|
+
- **Existing design output**: If `.grimoire/changes/<change-id>/designs/` is already populated (a prior `grimoire-design` run produced `problem.md`, `variants.md`, `variant-{n}.html`, or `figma-snapshot.json`), read those artifacts now. Treat them as authoritative for component shape, states, and visual tokens — do not re-query Figma.
|
|
71
|
+
- **Figma MCP available, no design folder**: If `project.design_tool.mcp` is configured and `designs/` is absent, ask: "Figma file URL or node ID? (or skip)". On a URL or node reference, query the Figma MCP for frame data and cache the response at `.grimoire/changes/<change-id>/designs/figma-snapshot.json` per `../references/design-input-formats.md` §1 Cache. On "skip" or empty input, continue to standard elicitation.
|
|
72
|
+
- **No MCP and no design folder**: skip this step silently. Fall back to the standard interview elicitation in step 4 below.
|
|
73
|
+
|
|
74
|
+
When design input is consumed (either path), carry the extracted component list, states, and any token references into the elicitation in step 4 — these become concrete anchors for the questions you ask the user, replacing generic prompts.
|
|
75
|
+
|
|
66
76
|
### 4. Elicit Requirements
|
|
77
|
+
|
|
78
|
+
**Interview, don't assume.** The most common drafting failure is filling in gaps with plausible-sounding guesses. Every unstated detail is either (a) something the user has an opinion on and you must ask, or (b) something project conventions answer unambiguously. Never a third option where you invent.
|
|
79
|
+
|
|
67
80
|
Now that you know whether you're building, adopting, or going hybrid, surface the requirements the user hasn't specified.
|
|
68
81
|
|
|
69
82
|
- **Level 1**: Skip this step.
|
|
@@ -74,6 +87,24 @@ The build-vs-buy outcome shapes which questions matter:
|
|
|
74
87
|
- **Building custom**: Full elicitation — business rules, edge cases, data contracts, security, NFRs.
|
|
75
88
|
- **Hybrid**: Elicit deeply for custom parts. For adopted parts, focus on integration boundaries.
|
|
76
89
|
|
|
90
|
+
#### Interview protocol
|
|
91
|
+
|
|
92
|
+
1. **Outcome & Non-goals first.** Always ask these two before any persona questions — they set scope. Restate the answers back to the user before continuing.
|
|
93
|
+
2. **Batch questions, then wait.** Ask 3-5 questions at a time, grouped by persona. Stop. Wait for the user's reply. Do not draft scenarios until the batch is answered.
|
|
94
|
+
3. **Ask the question; don't pre-answer it.** "Should locked accounts get an email?" — not "I'll assume locked accounts get an email, let me know if not." The pre-answered form lets the user nod through assumptions they'd otherwise correct.
|
|
95
|
+
4. **One question per ambiguity, not a checklist dump.** If the user said "users can reset password", do not ask 12 generic questions. Ask the 3 that matter for *this* feature.
|
|
96
|
+
5. **Disambiguate immediately.** If the user's answer is vague ("yeah, handle errors gracefully"), ask the specific follow-up ("for invalid tokens, do we redirect to login with a flash message, return a 400, or something else?"). Never leave a vague answer in the spec.
|
|
97
|
+
6. **Capture, don't extrapolate.** If the user explicitly says "out of scope for now", note it as a non-goal and stop. Don't draft a scenario "just in case".
|
|
98
|
+
7. **When the user pushes back on a question** ("just write something reasonable"), record their delegation explicitly: "Defaulting to <choice> per user delegation — flag in review if wrong." This makes the assumption visible later.
|
|
99
|
+
|
|
100
|
+
#### Open-question discipline
|
|
101
|
+
|
|
102
|
+
After the interview, list every open question that wasn't answered. These become:
|
|
103
|
+
- **Manifest Assumptions** (level 3-4) — each open question becomes an unvalidated assumption with the reading you chose.
|
|
104
|
+
- **Open questions in the Requirements Summary** — explicitly listed so the user sees what you guessed.
|
|
105
|
+
|
|
106
|
+
Never silently fill in an open question. Either ask, defer to a non-goal, or record the inference.
|
|
107
|
+
|
|
77
108
|
Present a Requirements Summary (template in the reference) and wait for user confirmation before proceeding.
|
|
78
109
|
|
|
79
110
|
### 5. Check Existing State
|
|
@@ -82,6 +113,7 @@ Present a Requirements Summary (template in the reference) and wait for user con
|
|
|
82
113
|
- Read `.grimoire/docs/context.yml` (if it exists) to understand the deployment environment, related services, and infrastructure — this tells you what's available (caches, queues, sibling services) and what constraints apply (deployment target, environments)
|
|
83
114
|
- Check `.grimoire/changes/` for any in-progress changes that might overlap
|
|
84
115
|
- If there's a conflict with an active change, flag it
|
|
116
|
+
- If `.grimoire/changes/<change-id>/consult.md` exists (from a prior `grimoire-design-consult` run), parse the `## Inferred assumptions` and `## Inferred givens` sections verbatim. Copy the contents of `## Inferred assumptions` into the manifest's Assumptions section, and copy `## Inferred givens` into a new Givens section at the same heading level (Givens applies to level 3-4 only — skip for level 1-2). The H2 headers `## Inferred assumptions` and `## Inferred givens` are load-bearing — they are the exact section names `grimoire-design-consult` writes; do not paraphrase, retitle, or fuzzy-match. Open questions from `consult.md` are NOT copied — they remain in `consult.md` as designer follow-up items.
|
|
85
117
|
|
|
86
118
|
### 6. Scaffold the Change
|
|
87
119
|
- Choose a `change-id`: kebab-case, verb-led (`add-`, `update-`, `remove-`)
|
|
@@ -89,7 +121,44 @@ Present a Requirements Summary (template in the reference) and wait for user con
|
|
|
89
121
|
|
|
90
122
|
### 7. Draft Artifacts
|
|
91
123
|
**For behavioral changes:**
|
|
92
|
-
|
|
124
|
+
|
|
125
|
+
Before writing any `.feature` file, triage existing files. **The default is always extend. New files are the exception and require explicit justification.**
|
|
126
|
+
|
|
127
|
+
**Step 1 — List existing feature files (required, not skippable)**
|
|
128
|
+
|
|
129
|
+
Read `features/` recursively. Print a table before doing anything else:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
Existing feature files:
|
|
133
|
+
features/auth/login.feature — "User Login"
|
|
134
|
+
features/auth/registration.feature — "User Registration"
|
|
135
|
+
features/billing/invoices.feature — "Invoice Management"
|
|
136
|
+
...
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
If `features/` is empty or doesn't exist, skip to step 3.
|
|
140
|
+
|
|
141
|
+
**Step 2 — Match each proposed scenario to an existing file**
|
|
142
|
+
|
|
143
|
+
For each scenario you intend to draft, explicitly decide: extend or new? Show the decision:
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
Scenario triage:
|
|
147
|
+
"Admin resets a user's password" → extend features/auth/login.feature (same actor domain: auth)
|
|
148
|
+
"User exports invoices as CSV" → extend features/billing/invoices.feature (same resource)
|
|
149
|
+
"User configures SSO provider" → NEW (no existing file owns SSO configuration)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Do not proceed to writing until this table is complete. If unsure about a match, default to extend.
|
|
153
|
+
|
|
154
|
+
**Step 3 — Execute**
|
|
155
|
+
|
|
156
|
+
- **Extend:** copy the matching baseline file to `.grimoire/changes/<change-id>/features/<same-relative-path>/` and add scenarios there.
|
|
157
|
+
- **New file (requires justification):** state which existing files were considered and why none fit. Then create `.grimoire/changes/<change-id>/features/<capability>/<name>.feature`.
|
|
158
|
+
|
|
159
|
+
Signals a scenario belongs in an existing file: same actor, same domain object, same entry point, same HTTP resource or screen.
|
|
160
|
+
Signals a genuinely new file: new actor type with no existing file, entirely new domain object, or existing file's Feature title would need "and" to cover both.
|
|
161
|
+
|
|
93
162
|
- If modifying an existing feature, copy the current baseline first, then modify
|
|
94
163
|
- Follow Gherkin best practices:
|
|
95
164
|
- Feature title + user story (As a / I want / So that)
|
|
@@ -98,6 +167,19 @@ Present a Requirements Summary (template in the reference) and wait for user con
|
|
|
98
167
|
- Given/When/Then — describe WHAT, never HOW
|
|
99
168
|
- No implementation details in feature files
|
|
100
169
|
|
|
170
|
+
**When design data was provided (step 4.0):**
|
|
171
|
+
- If a Figma snapshot or `grimoire-design` output is available, propose Gherkin scenarios per (component × state) grounded in those artifacts. Walk the component list and the enumerated states; emit one Scenario per pair.
|
|
172
|
+
- Present the proposed scenarios for user review before writing to `.feature` files — accept all / accept some / edit / reject any. Rejected scenarios are not written.
|
|
173
|
+
- If `grimoire-design` already produced user-accepted scenarios under `.grimoire/changes/<change-id>/features/`, do NOT re-propose them; treat them as the baseline and only fill gaps (e.g., new components not yet covered).
|
|
174
|
+
|
|
175
|
+
**Brand-tokens grounding:**
|
|
176
|
+
- When Figma variables map to tokens that also appear in `.grimoire/brand/tokens.json`, scenarios referencing visual properties must use token names, not hex values. Example: write `Then the submit button uses color.primary` not `Then the submit button is #0066ff`.
|
|
177
|
+
- Hardcoded hex values in scenarios drift silently when tokens change. Token names stay correct across re-skins.
|
|
178
|
+
|
|
179
|
+
**Component-library awareness:**
|
|
180
|
+
- When `.grimoire/docs/components.md` exists, prefer references to existing components by name in scenarios (e.g., `Then a Button with variant="primary" is rendered` over `Then a blue button appears`).
|
|
181
|
+
- Flag net-new components explicitly: emit "new component required — confirm before plan stage" alongside any scenario that introduces a component not listed in `components.md`. The plan stage will then decide whether to add it to the inventory or reuse an existing variant.
|
|
182
|
+
|
|
101
183
|
**Security tags on scenarios:**
|
|
102
184
|
Apply Gherkin tags per `../references/security-compliance.md` (section "Security Tags"). Tags drive stricter checks in plan, review, and verify stages. Apply compliance-specific tags only when `project.compliance` is configured. If no compliance frameworks and no security surface, don't add tags.
|
|
103
185
|
|
|
@@ -195,6 +277,7 @@ This is the contract. Downstream skills (plan, review, verify) use it to generat
|
|
|
195
277
|
- Features describe behavior, not implementation. If you catch yourself writing step-level implementation details, you've gone too far.
|
|
196
278
|
- The manifest is lightweight glue — don't over-document. Just enough to capture why.
|
|
197
279
|
- Always check if a capability/feature already exists before creating a new one.
|
|
280
|
+
- **Figma access token is read from `FIGMA_ACCESS_TOKEN` env var by the MCP server.** Never log the token, never write it to config, never include it in `manifest.md`, `consult.md`, `figma-snapshot.json`, or any other artifact. The MCP server handles authentication transparently — grimoire-draft never needs to see the token value.
|
|
198
281
|
|
|
199
282
|
## Done
|
|
200
283
|
When the user approves the draft, the workflow is complete. Present the change directory path and suggest next steps:
|
|
@@ -28,6 +28,26 @@ Derive implementation tasks from approved Gherkin features and MADR decisions. T
|
|
|
28
28
|
|
|
29
29
|
## Workflow
|
|
30
30
|
|
|
31
|
+
### Operating Rules (apply to every step)
|
|
32
|
+
|
|
33
|
+
**1. Verify, don't delegate.** Any claim that can be answered by reading the codebase is *your* job — do it now, do not punt it to the implementer or the user. Forbidden task shapes:
|
|
34
|
+
|
|
35
|
+
- "Check whether `foo()` is already used somewhere"
|
|
36
|
+
- "Verify if module X exists"
|
|
37
|
+
- "Confirm the import path for Y"
|
|
38
|
+
- "See if there's an existing utility for Z"
|
|
39
|
+
- "TODO: check if this conflicts with…"
|
|
40
|
+
|
|
41
|
+
Resolve each one yourself before writing the task. Tools: codebase-memory-mcp (`search_graph`, `trace_path`, `get_code_snippet`), `.grimoire/docs/<area>.md` reusable-code tables, `Grep`, neighbor files. The task should state the *answer* ("Reuse `parse_invoice` in `src/billing/parsing.py:42`" or "No existing utility — write new"), never the *question*.
|
|
42
|
+
|
|
43
|
+
**2. Clarify or propose, never assume.** When the spec is ambiguous or silent on something you need to plan:
|
|
44
|
+
|
|
45
|
+
- **Ambiguous** (spec contradicts itself, two readings are plausible) → ask the user one specific question. Do not pick a reading and proceed.
|
|
46
|
+
- **Silent on a scenario you think is needed** (e.g., "what if the login attempt rate-limits?") → propose adding it. Route back to `grimoire-draft` for the spec update, or ask the user to confirm before you add a corresponding task. **Do not silently invent scenarios, edge cases, or tasks not derivable from approved features / ADRs / `data.yml` / manifest sections.**
|
|
47
|
+
- **Confident** (spec is clear or the unstated detail follows obviously from project conventions) → plan, but note the inference in a `<!-- inferred: ... -->` comment so the user can override.
|
|
48
|
+
|
|
49
|
+
The plan implements what's approved. It does not expand scope to hit a checklist.
|
|
50
|
+
|
|
31
51
|
### 1. Select Change
|
|
32
52
|
- List active changes in `.grimoire/changes/`
|
|
33
53
|
- If multiple, ask user which one to plan
|
|
@@ -58,6 +78,11 @@ Derive implementation tasks from approved Gherkin features and MADR decisions. T
|
|
|
58
78
|
**Read proposed data changes:**
|
|
59
79
|
- **`data.yml`** if present — proposed schema changes need migration and model tasks
|
|
60
80
|
|
|
81
|
+
**Staleness gate:** For each area doc loaded, check its `last_updated` date against `git log -1 --format=%ci <directory>`. If any doc is older than the most recent commit to its directory, it's stale — the file paths, utility names, and patterns it describes may no longer be accurate.
|
|
82
|
+
|
|
83
|
+
- **Level 1-2:** Warn ("Area doc for `<area>` is behind recent commits — reusable utilities and file paths may be wrong") and proceed. Note inferred paths with `<!-- inferred: area doc may be stale -->`.
|
|
84
|
+
- **Level 3-4:** Treat as a blocker. Do not generate tasks until the user refreshes stale docs via `grimoire-discover` targeted refresh. Planning with stale docs at this complexity produces wrong file paths and misses recent utilities — the cost of re-planning outweighs the cost of refreshing first.
|
|
85
|
+
|
|
61
86
|
**Read specific source files only when:**
|
|
62
87
|
- Area docs don't exist yet (tell the user to run `grimoire map` + `/grimoire:discover` first — planning without area docs produces worse tasks)
|
|
63
88
|
- Area docs exist but you need to verify a specific implementation detail (e.g., exact function signature, exact import path)
|
|
@@ -69,41 +94,59 @@ Derive implementation tasks from approved Gherkin features and MADR decisions. T
|
|
|
69
94
|
|
|
70
95
|
Before generating tasks, evaluate whether the specifications are detailed enough to plan against. Underspecified requirements produce vague tasks, which produce wrong code.
|
|
71
96
|
|
|
72
|
-
|
|
97
|
+
**Flag real gaps only — do not manufacture issues to hit a checklist.** A "gap" exists when:
|
|
98
|
+
- The spec contradicts itself (a scenario violates a non-goal; two scenarios disagree).
|
|
99
|
+
- A scenario you need to plan against has missing detail you cannot infer from project conventions (e.g., "redirect to dashboard" — which dashboard URL?).
|
|
100
|
+
- The manifest is missing a section the complexity level requires (Assumptions / Pre-Mortem / Prior Art on level 3-4).
|
|
101
|
+
- A scenario references an external API or data model with no contract in `data.yml` / `schema.yml`.
|
|
102
|
+
|
|
103
|
+
**Not a gap** (do not flag):
|
|
104
|
+
- The spec doesn't include a scenario you personally would have added. The approved feature set is the scope. If you think a scenario is missing, see "Clarify or propose, never assume" in Operating Rules — propose it back to draft, do not silently add planning for it.
|
|
105
|
+
- A negative path is unspecified but project conventions make it obvious (e.g., invalid input returns 400 — that's the framework default, not a spec gap).
|
|
106
|
+
- A non-functional concern (perf, observability) is unspecified at level 1-2.
|
|
73
107
|
|
|
74
108
|
#### Outcome & Scope check
|
|
75
109
|
- Does the manifest have a clear **Why** that describes the outcome, not just the mechanism? ("Users can reset passwords" not "Add password reset endpoint.")
|
|
76
110
|
- Does the manifest have a **Non-goals** section? If missing or empty on a level 3-4 change, flag it — without non-goals, scope creep is invisible during implementation.
|
|
77
111
|
- Do any scenarios appear to implement something listed as a non-goal? Flag as **blocker** — the draft contradicts itself.
|
|
78
112
|
|
|
79
|
-
|
|
113
|
+
Persona lens (only those relevant to the change) — see `../references/elicitation-personas.md` for the full set:
|
|
80
114
|
|
|
81
|
-
**
|
|
82
|
-
- **
|
|
83
|
-
- **
|
|
84
|
-
- **
|
|
85
|
-
- **
|
|
86
|
-
- **
|
|
87
|
-
- **QA**: Negative scenario for every happy path? Boundary values specified?
|
|
115
|
+
- **Outcome & Scope**: Why states outcome (not mechanism)? Non-goals exist? No scenario contradicts a non-goal?
|
|
116
|
+
- **PM**: User stories present? Given/When/Then specific?
|
|
117
|
+
- **Engineer**: Critical-path assumptions validated or flagged? Prior art documented (if building custom)?
|
|
118
|
+
- **Security**: Scenarios with auth/input/sensitive-data tags have corresponding constraints? Quality Attribute targets not blank?
|
|
119
|
+
- **Data**: External APIs or new models have `data.yml`? Constraints (required/unique/nullable) specified?
|
|
120
|
+
- **QA**: Where the spec explicitly references an error path, is the expected behavior specified?
|
|
88
121
|
|
|
89
|
-
**
|
|
122
|
+
**Response paths when a gap is found:**
|
|
90
123
|
|
|
91
|
-
1.
|
|
92
|
-
2.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
- **Return to draft** — go back to `grimoire-draft` to fill in the gaps
|
|
124
|
+
1. **Ambiguous** (the spec is contradictory or admits two readings) → ask the user one specific question. Do not pick a reading.
|
|
125
|
+
2. **Missing scenario the planner believes is required** → propose adding it via `grimoire-draft`. State the rationale ("this feature handles money — failure-path behavior should be in the spec"). Do not silently add a planning task for it.
|
|
126
|
+
3. **Missing detail derivable from conventions** → infer, plan, and annotate the task with `<!-- inferred: ... -->` so the user can override.
|
|
127
|
+
4. **Missing manifest section the complexity level requires** → ask the user; flag as a gate for level 3-4.
|
|
96
128
|
|
|
97
|
-
|
|
129
|
+
If multiple gaps are found, batch them and present once. Wait for the user's response before generating tasks.
|
|
98
130
|
|
|
99
|
-
|
|
131
|
+
Level 1-2 changes with minor gaps may proceed; level 3-4 with multiple gaps should not.
|
|
132
|
+
|
|
133
|
+
**If no real gaps**, proceed directly to task generation.
|
|
100
134
|
|
|
101
135
|
### 4. Generate Tasks
|
|
102
136
|
Create `.grimoire/changes/<change-id>/tasks.md`. **Every scenario must produce both production code AND tests.** Tasks are structured as pairs: step definitions first, then production code.
|
|
103
137
|
|
|
138
|
+
**THE PLAN'S SCOPE IS WHAT WAS APPROVED.** Tasks may only derive from:
|
|
139
|
+
- Approved `.feature` scenarios in this change
|
|
140
|
+
- Approved ADRs in this change (and their Confirmation sections)
|
|
141
|
+
- `data.yml` entries in this change
|
|
142
|
+
- The manifest's Assumptions, Pre-Mortem mitigations, and Prior Art borrowings
|
|
143
|
+
- Verification tasks (run feature suite, run project suite, validate ADR confirmation)
|
|
144
|
+
|
|
145
|
+
Do not add tasks for scenarios you wish existed, edge cases you imagine, observability you'd like, or refactors you'd prefer. If you think one is needed, see Operating Rules §2 — propose, don't insert.
|
|
146
|
+
|
|
104
147
|
**THE PLAN MUST RESPECT NON-GOALS.** Read the manifest's Non-goals section. If a task would touch, implement, or extend something listed as a non-goal, do not include it. If you think a non-goal should be reconsidered, flag it to the user — don't silently include it.
|
|
105
148
|
|
|
106
|
-
**THE PLAN MUST BE SPECIFIC ENOUGH TO EXECUTE WITHOUT FURTHER PLANNING.**
|
|
149
|
+
**THE PLAN MUST BE SPECIFIC ENOUGH TO EXECUTE WITHOUT FURTHER PLANNING.** Specific means *answered*, not *delegated*: file paths resolved (not "find the right file"), reusable utilities named with exact symbol + path (not "check if one exists"), import paths verified (not "confirm the import"). See Operating Rules §1.
|
|
107
150
|
|
|
108
151
|
**THE PLAN MUST PREFER SIMPLICITY.** For each task, choose the approach with the least code, fewest new files, and smallest surface area. If a task can be solved by adding a few lines to an existing file, don't create a new module. If a standard library function does the job, don't pull in a dependency. If three lines of inline code are clearer than a helper, keep them inline. Flag any task that introduces a new abstraction, utility, or pattern — it needs a reason.
|
|
109
152
|
|
|
@@ -17,16 +17,14 @@ Generate a pull request description from grimoire change artifacts and optionall
|
|
|
17
17
|
- Loose match: "PR", "pull request", "ready to merge", "create PR"
|
|
18
18
|
|
|
19
19
|
## Routing
|
|
20
|
-
- Tasks incomplete → `grimoire-apply` first
|
|
20
|
+
- Tasks incomplete or finalize not done → `grimoire-apply` first. Do not create a PR before the change is finalized — PR must reflect the archived state (decisions promoted, manifest archived, change directory removed).
|
|
21
21
|
- Haven't committed yet → `grimoire-commit` first
|
|
22
22
|
- Want a pre-merge design review → this skill includes optional post-implementation review
|
|
23
23
|
|
|
24
24
|
## Prerequisites
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- Feature files and/or decision records
|
|
29
|
-
- The change should be on a feature branch (created during apply)
|
|
25
|
+
- Change has been finalized: `.grimoire/changes/<change-id>/` is removed, manifest is in `.grimoire/archive/`
|
|
26
|
+
- All decisions promoted to `.grimoire/decisions/`
|
|
27
|
+
- The change is on a feature branch (created during apply)
|
|
30
28
|
|
|
31
29
|
## Workflow
|
|
32
30
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: grimoire-pr-review
|
|
3
|
-
description: Review a teammate's pull request using the
|
|
3
|
+
description: Review a teammate's pull request using the shared multi-persona engine, against the actual PR diff. Fetches the PR, loads linked grimoire artifacts via the Change trailer, and produces structured findings suitable for PR comments.
|
|
4
4
|
compatibility: Designed for Claude Code (or similar products)
|
|
5
5
|
metadata:
|
|
6
6
|
author: kiwi-data
|
|
7
|
-
version: "0.
|
|
7
|
+
version: "0.2"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# grimoire-pr-review
|
|
11
11
|
|
|
12
|
-
Review a pull request authored by someone else. Applies the
|
|
12
|
+
Review a pull request authored by someone else. Applies the shared persona engine in `../references/review-personas.md` to the real diff, cross-referenced with the PR's linked grimoire change (if any).
|
|
13
13
|
|
|
14
14
|
## Triggers
|
|
15
15
|
- User asks to review a teammate's PR / MR
|
|
@@ -18,6 +18,7 @@ Review a pull request authored by someone else. Applies the same persona lens as
|
|
|
18
18
|
|
|
19
19
|
## Routing
|
|
20
20
|
- Reviewing your own pre-merge change you just built → `grimoire-pr` (has optional post-impl review)
|
|
21
|
+
- Reviewing your own staged but uncommitted diff → `grimoire-precommit-review`
|
|
21
22
|
- Reviewing a design before any code exists → `grimoire-review`
|
|
22
23
|
- Verifying scenarios pass after merge → `grimoire-verify`
|
|
23
24
|
- Writing a bug report against merged behavior → `grimoire-bug-report`
|
|
@@ -70,104 +71,36 @@ If present:
|
|
|
70
71
|
If no `Change:` trailer exists, that's itself a finding for a grimoire-managed repo: flag as **suggestion** ("commits missing audit trailer — `grimoire trace` won't find this PR") unless the project clearly doesn't use grimoire.
|
|
71
72
|
|
|
72
73
|
### 4. Gather Project Context
|
|
73
|
-
- `.grimoire/config.yaml` — language, tools, `commit_style`, `project.compliance`, `dep_audit`
|
|
74
|
+
- `.grimoire/config.yaml` — language, tools, `commit_style`, `comment_style`, `project.compliance`, `dep_audit`
|
|
74
75
|
- `.grimoire/docs/context.yml` — deployment environment, related services
|
|
75
76
|
- `.grimoire/docs/data/schema.yml` — current data baseline
|
|
76
77
|
- Relevant `.grimoire/docs/<area>.md` for the directories touched by the diff
|
|
77
78
|
|
|
78
|
-
### 5.
|
|
79
|
-
|
|
79
|
+
### 5. Build Project Briefing
|
|
80
|
+
Follow `../references/review-personas.md` §1 (Project Briefing) to construct the briefing block. Inject as preface to every persona run below.
|
|
80
81
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
| Docs only, ≤50 lines | Senior engineer skim only |
|
|
84
|
-
| Linked manifest complexity 1-2, diff <200 lines, no security tags | Senior engineer + security quick scan |
|
|
85
|
-
| Linked manifest complexity 3, OR diff touches auth/data/API | All relevant personas (skip data if no schema change, skip QA if no user-facing change) |
|
|
86
|
-
| Linked manifest complexity 4, OR diff >500 lines, OR touches multiple domains | All personas mandatory |
|
|
82
|
+
### 6. Pick Personas — Diff Review Gating
|
|
83
|
+
Use the **Diff review** table in `../references/review-personas.md` §3 (Complexity Gating). Read `complexity` from the linked manifest if present; otherwise infer from diff size and touched areas. User can override ("full review", "just security", "just code style", etc.).
|
|
87
84
|
|
|
88
|
-
|
|
85
|
+
### 7. Run Personas
|
|
86
|
+
For each selected persona, follow its evaluation criteria in `../references/review-personas.md` §4 against the **PR diff** (with linked artifacts as cross-reference where relevant). Apply the materiality gate (§2) — every finding cites a briefing axis or feature-inventory gap, or is dropped.
|
|
89
87
|
|
|
90
|
-
|
|
91
|
-
|
|
88
|
+
Persona scope for PR review:
|
|
89
|
+
- 4.1 Product Manager — skip if pure internal refactor
|
|
90
|
+
- 4.2 Senior Engineer — always
|
|
91
|
+
- 4.3 Security Engineer — always; full STRIDE + code-level scan + compliance
|
|
92
|
+
- 4.4 QA Engineer — skip if pure internal
|
|
93
|
+
- 4.5 Data Engineer — skip if no migrations / models / schema / external API client touched
|
|
94
|
+
- 4.6 Code Style Reviewer — always
|
|
95
|
+
- 4.7 Adversarial User — engage per matrix in `../references/adversarial-personas.md` when the diff touches a user-facing surface
|
|
96
|
+
- 4.8 Contrarian — runs last when any persona produced a blocker; calibrates other personas' findings post-hoc
|
|
92
97
|
|
|
93
|
-
|
|
98
|
+
### 7.5 Visual Fidelity (cheap tier)
|
|
94
99
|
|
|
95
|
-
-
|
|
96
|
-
- **Non-goals**: Does the diff touch anything the manifest's Non-goals section excludes?
|
|
97
|
-
- **Acceptance**: From the diff alone, could a PM validate this meets the feature's acceptance criteria?
|
|
98
|
-
- **Clarity**: Does the PR body (or linked manifest) make the user-visible outcome clear?
|
|
100
|
+
Follow `../references/visual-fidelity.md` for the code-phase invocation (PR diff scope, auto-invoked when `.grimoire/brand/tokens.json` exists). Skip silently when tokens.json is absent and the diff has no styling-surface changes. Fold the engine's output under the "Visual Fidelity" section of the report.
|
|
99
101
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
### 7. Senior Engineer Review
|
|
103
|
-
Review the actual code:
|
|
104
|
-
|
|
105
|
-
- **Simplicity**: Is this the simplest implementation? Any unnecessary abstraction, indirection, or config that could be inlined?
|
|
106
|
-
- **Conventions**: Does the new code match the file layout, naming, and patterns already in the touched areas? Check `.grimoire/docs/<area>.md` if present.
|
|
107
|
-
- **Reuse**: Are there existing utilities/functions that were re-implemented? `grep` for similar names or check the area doc's reusable-code list.
|
|
108
|
-
- **Dead code**: Functions added but not called, imports unused, commented-out code, stubs with no implementation.
|
|
109
|
-
- **Scope creep**: Files changed outside the scope implied by the change-id or manifest. Formatting-only changes to unrelated files = noise.
|
|
110
|
-
- **Error handling**: Are errors handled at boundaries? Internal code shouldn't be littered with defensive checks; external inputs must be validated.
|
|
111
|
-
- **Tests**: Do new behaviors have tests? Do the tests make real assertions (not just `assert true` / mock everything)? Check `../references/testing-contracts.md` if the framework matches.
|
|
112
|
-
- **Contract compatibility**: If `data.yml` / `schema.yml` exists, does the diff change request/response shape for a documented API? If yes, where's the contract test update?
|
|
113
|
-
- **Dependencies**: Any new packages in `package.json` / `requirements.txt` / `Cargo.toml` etc. not mentioned in tasks? Any version bumps that aren't noted?
|
|
114
|
-
- **Task alignment**: If `tasks.md` exists for the change, does the diff complete the tasks as written? Any task that was "done" but has no corresponding code?
|
|
115
|
-
|
|
116
|
-
Flag as **blocker** or **suggestion**.
|
|
117
|
-
|
|
118
|
-
### 8. Security Engineer Review
|
|
119
|
-
Apply `../references/security-compliance.md`.
|
|
120
|
-
|
|
121
|
-
#### 8a. STRIDE on the diff
|
|
122
|
-
For every new entry point, data flow, or trust boundary introduced by the diff:
|
|
123
|
-
|
|
124
|
-
| Threat | Question |
|
|
125
|
-
|---|---|
|
|
126
|
-
| **S**poofing | Auth check at every new route/handler? |
|
|
127
|
-
| **T**ampering | Input/message integrity validated? CSRF on state-changing requests? |
|
|
128
|
-
| **R**epudiation | Security-relevant actions logged? |
|
|
129
|
-
| **I**nfo disclosure | Error responses, logs, stack traces leaking PII/tokens/secrets? |
|
|
130
|
-
| **D**oS | Unbounded loops, unlimited file uploads, expensive queries on user input, no rate limit? |
|
|
131
|
-
| **E**oP | Role/permission checks at the right layer? Any bypass via missing middleware? |
|
|
132
|
-
|
|
133
|
-
Skip categories that don't apply.
|
|
134
|
-
|
|
135
|
-
#### 8b. Code-level scan
|
|
136
|
-
- **Secrets**: Grep the diff for hardcoded keys, tokens, passwords, cloud credentials, JWT secrets. Flag any hit as **blocker**.
|
|
137
|
-
- **Injection**: Raw SQL with string concatenation, shell-exec with user input, `eval`/`exec`, unsafe deserialization. Tag with OWASP + CWE.
|
|
138
|
-
- **Input validation**: New endpoints without schema validation, file uploads without size/type limits, path params used directly in filesystem calls (path traversal).
|
|
139
|
-
- **Auth**: New routes/handlers missing auth decorators / middleware. Compare against neighbors in the same file.
|
|
140
|
-
- **Dependencies**: New packages in lockfile — check the name is real (typosquat risk), check project's `dep_audit` tool output if committed. Flag packages with zero downloads or suspicious maintainers.
|
|
141
|
-
- **PII**: New logging statements that could emit PII; new storage of personal data without encryption.
|
|
142
|
-
- **Cross-service auth**: If `context.yml` lists related services, are service-to-service calls authenticated?
|
|
143
|
-
|
|
144
|
-
#### 8c. Compliance
|
|
145
|
-
If `project.compliance` configured, verify per `../references/security-compliance.md` section "Compliance Framework Verification". Any security-tagged scenario in the linked change with no corresponding verification in the diff = **blocker**.
|
|
146
|
-
|
|
147
|
-
#### 8d. Tag findings
|
|
148
|
-
Every security finding gets OWASP 2021 + CWE tags. See the CWE quick-reference in `../references/security-compliance.md`.
|
|
149
|
-
|
|
150
|
-
### 9. QA Engineer Review (optional)
|
|
151
|
-
Skip if PR is purely internal.
|
|
152
|
-
|
|
153
|
-
- **Test presence**: Every new user-facing behavior has a test? Every scenario from the linked feature file has step definitions?
|
|
154
|
-
- **Test quality**: Are tests asserting outputs, or just that code "ran"? Over-mocked tests are a red flag.
|
|
155
|
-
- **Negative paths**: For each happy path in the diff, is there a failure-path test?
|
|
156
|
-
- **Observability**: New feature — how will it be debugged in prod? Structured logs / metrics / error surfaces?
|
|
157
|
-
- **Regression risk**: Which existing tests cover the touched code? Were any tests removed or weakened in the diff?
|
|
158
|
-
- **Accessibility**: New UI — keyboard nav, aria labels, contrast?
|
|
159
|
-
|
|
160
|
-
### 10. Data Engineer Review (optional)
|
|
161
|
-
Skip unless diff touches migrations, models, schema files, or external API clients.
|
|
162
|
-
|
|
163
|
-
- **Migrations**: Safe to run on a live DB? Adding a NOT NULL without default on a large table = **blocker**. Renames without a two-step migration = **blocker**.
|
|
164
|
-
- **Indexes**: New foreign keys with no index? New query patterns against unindexed columns?
|
|
165
|
-
- **Naming**: New fields follow existing schema conventions?
|
|
166
|
-
- **Breaking contract**: Compare `data.yml` vs `schema.yml` — removed/renamed/retyped response fields or new required request fields = **blocker** unless a migration path is documented.
|
|
167
|
-
- **Transactions**: Multi-step writes wrapped in a transaction?
|
|
168
|
-
|
|
169
|
-
### 11. Present Findings
|
|
170
|
-
Compile into a single report structured for PR comments:
|
|
102
|
+
### 8. Present Findings
|
|
103
|
+
Compile into the standard report layout (§5 of the personas reference):
|
|
171
104
|
|
|
172
105
|
```markdown
|
|
173
106
|
# PR Review: <PR title> (#<number>)
|
|
@@ -177,41 +110,38 @@ Compile into a single report structured for PR comments:
|
|
|
177
110
|
**Complexity:** <1-4 or "inferred: moderate">
|
|
178
111
|
**Files changed:** <N> **Lines:** +<add> / -<del>
|
|
179
112
|
|
|
113
|
+
## Project Briefing
|
|
114
|
+
<briefing block>
|
|
115
|
+
|
|
180
116
|
## Product Manager
|
|
181
|
-
-
|
|
182
|
-
- **[suggestion]** PR body doesn't mention the rate-limit change — add it
|
|
117
|
+
- ...
|
|
183
118
|
|
|
184
119
|
## Senior Engineer
|
|
185
|
-
-
|
|
186
|
-
- **[suggestion]** New abstraction `AuthProviderFactory` has one caller; inline it
|
|
120
|
+
- ...
|
|
187
121
|
|
|
188
122
|
## Security Engineer
|
|
189
123
|
### STRIDE
|
|
190
|
-
-
|
|
191
|
-
- Tampering: new `/api/profile` PATCH has no CSRF token check
|
|
192
|
-
- Info disclosure: `logger.info(f"login attempt for {email}")` emits PII
|
|
193
|
-
|
|
124
|
+
- ...
|
|
194
125
|
### Findings
|
|
195
|
-
-
|
|
196
|
-
- **[blocker]** [A09:2021 / CWE-532] Email logged in plaintext (`auth/login.py:88`)
|
|
197
|
-
- **[suggestion]** [A07:2021 / CWE-307] No rate limiting on login handler
|
|
126
|
+
- ...
|
|
198
127
|
|
|
199
128
|
## QA Engineer
|
|
200
|
-
-
|
|
201
|
-
- **[suggestion]** Add negative test for malformed TOTP string
|
|
129
|
+
- ...
|
|
202
130
|
|
|
203
131
|
## Data Engineer
|
|
204
|
-
-
|
|
205
|
-
|
|
132
|
+
- ...
|
|
133
|
+
|
|
134
|
+
## Code Style
|
|
135
|
+
- ...
|
|
206
136
|
|
|
207
137
|
## Summary
|
|
208
|
-
- **
|
|
209
|
-
- **
|
|
138
|
+
- **N blockers** — must be addressed before merge
|
|
139
|
+
- **M suggestions** — consider addressing
|
|
210
140
|
|
|
211
|
-
Recommendation: Request changes.
|
|
141
|
+
Recommendation: Request changes / Approve.
|
|
212
142
|
```
|
|
213
143
|
|
|
214
|
-
###
|
|
144
|
+
### 9. Post to PR (optional)
|
|
215
145
|
Offer three modes:
|
|
216
146
|
|
|
217
147
|
- **Print only** (default) — just show the report
|
|
@@ -224,17 +154,18 @@ Offer three modes:
|
|
|
224
154
|
|
|
225
155
|
Ask the user which mode before posting. Never post without confirmation — PR comments are visible to the whole team.
|
|
226
156
|
|
|
227
|
-
###
|
|
157
|
+
### 10. Link Back
|
|
228
158
|
If a linked grimoire change was found and the review surfaced blockers that need spec changes (not just code changes), suggest the author run `grimoire-draft` or `grimoire-plan` on that change to update the artifacts before pushing fixes.
|
|
229
159
|
|
|
230
160
|
## Important
|
|
231
161
|
- This is a code review against a real diff — reference specific files and line numbers for every finding.
|
|
232
|
-
- Be direct. Don't pad with praise. Blockers
|
|
233
|
-
- Respect the author. Findings describe the code, not the person.
|
|
234
|
-
- A PR without a `Change:` trailer in a grimoire repo is a soft finding, not a hard blocker
|
|
162
|
+
- Be direct. Don't pad with praise. Blockers stop the merge; suggestions are advisory.
|
|
163
|
+
- Respect the author. Findings describe the code, not the person.
|
|
164
|
+
- A PR without a `Change:` trailer in a grimoire repo is a soft finding, not a hard blocker.
|
|
235
165
|
- Don't re-derive tasks or specs. If the linked change's artifacts are wrong, that's a separate `grimoire-draft` / `grimoire-plan` cycle.
|
|
236
166
|
- If the diff is too large or too sprawling to review meaningfully, say so — offer to focus on a subset rather than producing a shallow full-pass review.
|
|
237
167
|
- Never post to the PR without explicit user confirmation.
|
|
168
|
+
- All persona evaluation criteria, the materiality gate, the briefing structure, and the complexity-depth table live in `../references/review-personas.md`. Don't duplicate them here — read that file when running a persona.
|
|
238
169
|
|
|
239
170
|
## Done
|
|
240
171
|
When the report is presented (and optionally posted), the workflow is complete. If blockers exist, suggest the author address them; if not, suggest approving via `gh pr review <id> --approve`.
|