@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.
Files changed (127) hide show
  1. package/AGENTS.md +56 -4
  2. package/README.md +28 -1
  3. package/dist/cli/index.js +2 -0
  4. package/dist/cli/index.js.map +1 -1
  5. package/dist/commands/check.js +1 -1
  6. package/dist/commands/check.js.map +1 -1
  7. package/dist/commands/configure.d.ts +3 -0
  8. package/dist/commands/configure.d.ts.map +1 -0
  9. package/dist/commands/configure.js +19 -0
  10. package/dist/commands/configure.js.map +1 -0
  11. package/dist/commands/init.d.ts.map +1 -1
  12. package/dist/commands/init.js +2 -0
  13. package/dist/commands/init.js.map +1 -1
  14. package/dist/commands/map.d.ts.map +1 -1
  15. package/dist/commands/map.js +10 -11
  16. package/dist/commands/map.js.map +1 -1
  17. package/dist/core/archive.d.ts.map +1 -1
  18. package/dist/core/archive.js +32 -43
  19. package/dist/core/archive.js.map +1 -1
  20. package/dist/core/check.d.ts.map +1 -1
  21. package/dist/core/check.js +115 -104
  22. package/dist/core/check.js.map +1 -1
  23. package/dist/core/ci.d.ts.map +1 -1
  24. package/dist/core/ci.js +50 -69
  25. package/dist/core/ci.js.map +1 -1
  26. package/dist/core/configure.d.ts +14 -0
  27. package/dist/core/configure.d.ts.map +1 -0
  28. package/dist/core/configure.js +434 -0
  29. package/dist/core/configure.js.map +1 -0
  30. package/dist/core/detect.d.ts.map +1 -1
  31. package/dist/core/detect.js +153 -26
  32. package/dist/core/detect.js.map +1 -1
  33. package/dist/core/diff.d.ts.map +1 -1
  34. package/dist/core/diff.js +62 -93
  35. package/dist/core/diff.js.map +1 -1
  36. package/dist/core/doc-style.d.ts +0 -4
  37. package/dist/core/doc-style.d.ts.map +1 -1
  38. package/dist/core/doc-style.js +28 -23
  39. package/dist/core/doc-style.js.map +1 -1
  40. package/dist/core/docs.js +106 -100
  41. package/dist/core/docs.js.map +1 -1
  42. package/dist/core/health.js +55 -77
  43. package/dist/core/health.js.map +1 -1
  44. package/dist/core/hooks.d.ts +0 -3
  45. package/dist/core/hooks.d.ts.map +1 -1
  46. package/dist/core/hooks.js +0 -11
  47. package/dist/core/hooks.js.map +1 -1
  48. package/dist/core/init.d.ts +2 -0
  49. package/dist/core/init.d.ts.map +1 -1
  50. package/dist/core/init.js +230 -406
  51. package/dist/core/init.js.map +1 -1
  52. package/dist/core/list.d.ts.map +1 -1
  53. package/dist/core/list.js +55 -65
  54. package/dist/core/list.js.map +1 -1
  55. package/dist/core/log.d.ts.map +1 -1
  56. package/dist/core/log.js +23 -33
  57. package/dist/core/log.js.map +1 -1
  58. package/dist/core/map.d.ts +15 -2
  59. package/dist/core/map.d.ts.map +1 -1
  60. package/dist/core/map.js +257 -194
  61. package/dist/core/map.js.map +1 -1
  62. package/dist/core/shared-setup.d.ts +0 -40
  63. package/dist/core/shared-setup.d.ts.map +1 -1
  64. package/dist/core/shared-setup.js +87 -52
  65. package/dist/core/shared-setup.js.map +1 -1
  66. package/dist/core/status.d.ts.map +1 -1
  67. package/dist/core/status.js +42 -52
  68. package/dist/core/status.js.map +1 -1
  69. package/dist/core/test-quality.d.ts +0 -8
  70. package/dist/core/test-quality.d.ts.map +1 -1
  71. package/dist/core/test-quality.js +24 -30
  72. package/dist/core/test-quality.js.map +1 -1
  73. package/dist/core/trace.d.ts.map +1 -1
  74. package/dist/core/trace.js +31 -41
  75. package/dist/core/trace.js.map +1 -1
  76. package/dist/core/update.d.ts.map +1 -1
  77. package/dist/core/update.js +61 -11
  78. package/dist/core/update.js.map +1 -1
  79. package/dist/core/validate.d.ts +1 -4
  80. package/dist/core/validate.d.ts.map +1 -1
  81. package/dist/core/validate.js +126 -148
  82. package/dist/core/validate.js.map +1 -1
  83. package/dist/utils/config.d.ts +15 -5
  84. package/dist/utils/config.d.ts.map +1 -1
  85. package/dist/utils/config.js +63 -42
  86. package/dist/utils/config.js.map +1 -1
  87. package/dist/utils/fs.d.ts +0 -12
  88. package/dist/utils/fs.d.ts.map +1 -1
  89. package/dist/utils/fs.js +0 -12
  90. package/dist/utils/fs.js.map +1 -1
  91. package/dist/utils/paths.d.ts +0 -6
  92. package/dist/utils/paths.d.ts.map +1 -1
  93. package/dist/utils/paths.js +0 -6
  94. package/dist/utils/paths.js.map +1 -1
  95. package/dist/utils/spawn.d.ts +0 -3
  96. package/dist/utils/spawn.d.ts.map +1 -1
  97. package/dist/utils/spawn.js +0 -3
  98. package/dist/utils/spawn.js.map +1 -1
  99. package/package.json +1 -1
  100. package/skills/grimoire-apply/SKILL.md +84 -16
  101. package/skills/grimoire-audit/SKILL.md +21 -1
  102. package/skills/grimoire-bug/SKILL.md +48 -9
  103. package/skills/grimoire-commit/SKILL.md +2 -1
  104. package/skills/grimoire-design/SKILL.md +259 -0
  105. package/skills/grimoire-design-consult/SKILL.md +200 -0
  106. package/skills/grimoire-discover/SKILL.md +65 -2
  107. package/skills/grimoire-draft/SKILL.md +85 -2
  108. package/skills/grimoire-plan/SKILL.md +61 -18
  109. package/skills/grimoire-pr/SKILL.md +4 -6
  110. package/skills/grimoire-pr-review/SKILL.md +45 -114
  111. package/skills/grimoire-precommit-review/SKILL.md +205 -0
  112. package/skills/grimoire-refactor/SKILL.md +5 -5
  113. package/skills/grimoire-review/SKILL.md +74 -147
  114. package/skills/grimoire-verify/SKILL.md +33 -0
  115. package/skills/references/adversarial-personas.md +225 -0
  116. package/skills/references/brand-tokens-format.md +186 -0
  117. package/skills/references/code-quality.md +140 -0
  118. package/skills/references/design-heuristics.md +138 -0
  119. package/skills/references/design-input-formats.md +190 -0
  120. package/skills/references/pattern-guard.md +180 -0
  121. package/skills/references/refactor-scan-categories.md +152 -0
  122. package/skills/references/review-personas.md +405 -0
  123. package/skills/references/security-compliance.md +22 -1
  124. package/skills/references/visual-fidelity.md +206 -0
  125. package/templates/brand-tokens-example.json +13 -0
  126. package/templates/brand-voice-example.md +22 -0
  127. 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
- - Write proposed `.feature` files in `.grimoire/changes/<change-id>/features/<capability>/`
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
- Review the specs through each persona's lens and flag gaps. **Only check personas relevant to the change** — don't manufacture issues.
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
- Evaluate through each relevant persona's lens — see `../references/elicitation-personas.md` for the full question set. In plan, you're checking completeness, not asking questions. Flag gaps as issues.
113
+ Persona lens (only those relevant to the change) — see `../references/elicitation-personas.md` for the full set:
80
114
 
81
- **Key checks per persona:**
82
- - **Outcome & Scope**: Does the manifest have a clear Why (outcome, not mechanism)? Does it have Non-goals? Do any scenarios contradict non-goals?
83
- - **PM**: Scenarios for success AND errors? User stories on every feature? Specific Given/When/Then (not vague)?
84
- - **Engineer**: Unvalidated assumptions on critical path? Prior art patterns documented (if building custom)? Scenarios specific enough for concrete file paths?
85
- - **Security**: Input/auth/sensitive-data scenarios have corresponding error/abuse scenarios? Quality Attribute targets not blank?
86
- - **Data**: External APIs or new models without `data.yml`? Data constraints specified (required, unique, nullable)?
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
- **If issues are found:**
122
+ **Response paths when a gap is found:**
90
123
 
91
- 1. Present findings grouped by persona, with a specific question for each gap
92
- 2. Ask the user to choose:
93
- - **Clarify now** answer the questions and update the draft before continuing to task generation
94
- - **Proceed anyway** acknowledge the gaps and plan around them (tasks will note where assumptions were made)
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
- This is not a gate level 1-2 changes (from manifest `complexity`) can proceed with minor gaps. Level 3-4 changes with multiple signals should strongly recommend clarification before planning.
129
+ If multiple gaps are found, batch them and present once. Wait for the user's response before generating tasks.
98
130
 
99
- **If no issues are found**, proceed directly to task generation.
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 (or create a draft PR)
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
- - A change exists in `.grimoire/changes/<change-id>/` with:
26
- - `manifest.md`
27
- - `tasks.md` with all (or most) tasks checked
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 same multi-persona lens as pre-commit review, but against the actual diff. Fetches the PR, loads linked grimoire artifacts via the Change trailer, and produces structured findings suitable for PR comments.
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.1"
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 same persona lens as `grimoire-review` (product, engineer, security, QA, data) to the real diff, cross-referenced with the PR's linked grimoire change (if any).
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. Complexity-Gated Depth
79
- Read `complexity` from the linked manifest frontmatter if available. Fall back to heuristics on the diff:
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
- | Signal | Depth |
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
- User can override: "full review", "just security", "just engineer", etc.
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
- ### 6. Product Manager Review
91
- *(Skip if PR is pure internal refactor with no user-facing change.)*
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
- Evaluate against the linked feature files (if any) or the PR body:
98
+ ### 7.5 Visual Fidelity (cheap tier)
94
99
 
95
- - **Scenario coverage**: If a feature file exists in the change, does the diff implement every scenario? Any scenario with no matching code change?
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
- Flag as **blocker** or **suggestion**.
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
- - **[blocker]** Scenario "Login with expired TOTP code" is in the feature file but no corresponding code path in `auth/verify.py`
182
- - **[suggestion]** PR body doesn't mention the rate-limit change — add it
117
+ - ...
183
118
 
184
119
  ## Senior Engineer
185
- - **[blocker]** `utils/hash_helpers.py` duplicates `security/crypto.py::hash_password` — reuse instead
186
- - **[suggestion]** New abstraction `AuthProviderFactory` has one caller; inline it
120
+ - ...
187
121
 
188
122
  ## Security Engineer
189
123
  ### STRIDE
190
- - Spoofing: N/A
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
- - **[blocker]** [A01:2021 / CWE-352] Missing CSRF check on `/api/profile` PATCH (`views/profile.py:42`)
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
- - **[blocker]** New TOTP verification path has no test (`auth/totp.py:15-48`)
201
- - **[suggestion]** Add negative test for malformed TOTP string
129
+ - ...
202
130
 
203
131
  ## Data Engineer
204
- - **[blocker]** Migration `0042_add_2fa.py` adds NOT NULL `totp_secret` on existing `users` table — will fail on deploy
205
- (or: "No schema changes — skipped.")
132
+ - ...
133
+
134
+ ## Code Style
135
+ - ...
206
136
 
207
137
  ## Summary
208
- - **5 blockers** — must be addressed before merge
209
- - **3 suggestions** — consider addressing
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
- ### 12. Post to PR (optional)
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
- ### 13. Link Back
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 are things that should stop the merge; suggestions are things the author should consider.
233
- - Respect the author. Findings describe the code, not the person. "This query is vulnerable to injection" not "you wrote an injection".
234
- - A PR without a `Change:` trailer in a grimoire repo is a soft finding, not a hard blocker — the team may have reasons.
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`.