@kiwidata/grimoire 0.1.3 → 0.1.5

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 (159) hide show
  1. package/AGENTS.md +56 -4
  2. package/README.md +107 -59
  3. package/dist/cli/index.js +7 -7
  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/core/check.d.ts.map +1 -1
  15. package/dist/core/check.js +165 -111
  16. package/dist/core/check.js.map +1 -1
  17. package/dist/core/ci.d.ts.map +1 -1
  18. package/dist/core/ci.js +50 -69
  19. package/dist/core/ci.js.map +1 -1
  20. package/dist/core/configure.d.ts +14 -0
  21. package/dist/core/configure.d.ts.map +1 -0
  22. package/dist/core/configure.js +434 -0
  23. package/dist/core/configure.js.map +1 -0
  24. package/dist/core/detect.d.ts.map +1 -1
  25. package/dist/core/detect.js +153 -26
  26. package/dist/core/detect.js.map +1 -1
  27. package/dist/core/diff.d.ts.map +1 -1
  28. package/dist/core/diff.js +62 -93
  29. package/dist/core/diff.js.map +1 -1
  30. package/dist/core/doc-style.d.ts +0 -4
  31. package/dist/core/doc-style.d.ts.map +1 -1
  32. package/dist/core/doc-style.js +103 -22
  33. package/dist/core/doc-style.js.map +1 -1
  34. package/dist/core/docs.js +202 -170
  35. package/dist/core/docs.js.map +1 -1
  36. package/dist/core/health.d.ts +6 -0
  37. package/dist/core/health.d.ts.map +1 -1
  38. package/dist/core/health.js +133 -96
  39. package/dist/core/health.js.map +1 -1
  40. package/dist/core/hooks.d.ts +0 -3
  41. package/dist/core/hooks.d.ts.map +1 -1
  42. package/dist/core/hooks.js +11 -16
  43. package/dist/core/hooks.js.map +1 -1
  44. package/dist/core/init.d.ts +2 -0
  45. package/dist/core/init.d.ts.map +1 -1
  46. package/dist/core/init.js +230 -406
  47. package/dist/core/init.js.map +1 -1
  48. package/dist/core/list.d.ts.map +1 -1
  49. package/dist/core/list.js +55 -65
  50. package/dist/core/list.js.map +1 -1
  51. package/dist/core/risk-register.d.ts +17 -0
  52. package/dist/core/risk-register.d.ts.map +1 -0
  53. package/dist/core/risk-register.js +73 -0
  54. package/dist/core/risk-register.js.map +1 -0
  55. package/dist/core/shared-setup.d.ts +0 -40
  56. package/dist/core/shared-setup.d.ts.map +1 -1
  57. package/dist/core/shared-setup.js +92 -56
  58. package/dist/core/shared-setup.js.map +1 -1
  59. package/dist/core/status.d.ts.map +1 -1
  60. package/dist/core/status.js +42 -52
  61. package/dist/core/status.js.map +1 -1
  62. package/dist/core/test-quality.d.ts +0 -8
  63. package/dist/core/test-quality.d.ts.map +1 -1
  64. package/dist/core/test-quality.js +24 -30
  65. package/dist/core/test-quality.js.map +1 -1
  66. package/dist/core/trace.d.ts.map +1 -1
  67. package/dist/core/trace.js +67 -75
  68. package/dist/core/trace.js.map +1 -1
  69. package/dist/core/update.d.ts.map +1 -1
  70. package/dist/core/update.js +61 -11
  71. package/dist/core/update.js.map +1 -1
  72. package/dist/core/validate.d.ts +1 -4
  73. package/dist/core/validate.d.ts.map +1 -1
  74. package/dist/core/validate.js +126 -148
  75. package/dist/core/validate.js.map +1 -1
  76. package/dist/index.d.ts +0 -3
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +0 -3
  79. package/dist/index.js.map +1 -1
  80. package/dist/utils/config.d.ts +15 -5
  81. package/dist/utils/config.d.ts.map +1 -1
  82. package/dist/utils/config.js +63 -42
  83. package/dist/utils/config.js.map +1 -1
  84. package/dist/utils/fs.d.ts +0 -12
  85. package/dist/utils/fs.d.ts.map +1 -1
  86. package/dist/utils/fs.js +0 -12
  87. package/dist/utils/fs.js.map +1 -1
  88. package/dist/utils/paths.d.ts +0 -6
  89. package/dist/utils/paths.d.ts.map +1 -1
  90. package/dist/utils/paths.js +0 -6
  91. package/dist/utils/paths.js.map +1 -1
  92. package/dist/utils/spawn.d.ts +0 -3
  93. package/dist/utils/spawn.d.ts.map +1 -1
  94. package/dist/utils/spawn.js +0 -3
  95. package/dist/utils/spawn.js.map +1 -1
  96. package/package.json +1 -1
  97. package/skills/grimoire-apply/SKILL.md +89 -25
  98. package/skills/grimoire-audit/SKILL.md +21 -1
  99. package/skills/grimoire-bug/SKILL.md +48 -9
  100. package/skills/grimoire-commit/SKILL.md +3 -2
  101. package/skills/grimoire-design/SKILL.md +259 -0
  102. package/skills/grimoire-design-consult/SKILL.md +200 -0
  103. package/skills/grimoire-discover/SKILL.md +139 -109
  104. package/skills/grimoire-draft/SKILL.md +131 -15
  105. package/skills/grimoire-plan/SKILL.md +119 -46
  106. package/skills/grimoire-pr/SKILL.md +7 -10
  107. package/skills/grimoire-pr-review/SKILL.md +46 -115
  108. package/skills/grimoire-precommit-review/SKILL.md +205 -0
  109. package/skills/grimoire-refactor/SKILL.md +6 -6
  110. package/skills/grimoire-review/SKILL.md +95 -156
  111. package/skills/grimoire-verify/SKILL.md +40 -7
  112. package/skills/grimoire-vuln-remediate/SKILL.md +107 -0
  113. package/skills/grimoire-vuln-triage/SKILL.md +109 -0
  114. package/skills/references/adversarial-personas.md +225 -0
  115. package/skills/references/brand-tokens-format.md +186 -0
  116. package/skills/references/code-quality.md +172 -0
  117. package/skills/references/container-scan-triage.md +102 -0
  118. package/skills/references/dependency-vuln-triage.md +236 -0
  119. package/skills/references/design-heuristics.md +138 -0
  120. package/skills/references/design-input-formats.md +190 -0
  121. package/skills/references/pattern-guard.md +180 -0
  122. package/skills/references/principles.md +82 -0
  123. package/skills/references/refactor-scan-categories.md +154 -2
  124. package/skills/references/review-personas.md +406 -0
  125. package/skills/references/security-compliance.md +22 -1
  126. package/skills/references/testing-contracts.md +1 -1
  127. package/skills/references/visual-fidelity.md +206 -0
  128. package/templates/accepted-risks.yml +47 -0
  129. package/templates/brand-tokens-example.json +13 -0
  130. package/templates/brand-voice-example.md +22 -0
  131. package/templates/constraints.md +25 -0
  132. package/templates/design-tool-setup-stub.md +59 -0
  133. package/dist/commands/archive.d.ts +0 -3
  134. package/dist/commands/archive.d.ts.map +0 -1
  135. package/dist/commands/archive.js +0 -22
  136. package/dist/commands/archive.js.map +0 -1
  137. package/dist/commands/log.d.ts +0 -3
  138. package/dist/commands/log.d.ts.map +0 -1
  139. package/dist/commands/log.js +0 -15
  140. package/dist/commands/log.js.map +0 -1
  141. package/dist/commands/map.d.ts +0 -3
  142. package/dist/commands/map.d.ts.map +0 -1
  143. package/dist/commands/map.js +0 -17
  144. package/dist/commands/map.js.map +0 -1
  145. package/dist/core/archive.d.ts +0 -9
  146. package/dist/core/archive.d.ts.map +0 -1
  147. package/dist/core/archive.js +0 -92
  148. package/dist/core/archive.js.map +0 -1
  149. package/dist/core/log.d.ts +0 -8
  150. package/dist/core/log.d.ts.map +0 -1
  151. package/dist/core/log.js +0 -150
  152. package/dist/core/log.js.map +0 -1
  153. package/dist/core/map.d.ts +0 -9
  154. package/dist/core/map.d.ts.map +0 -1
  155. package/dist/core/map.js +0 -302
  156. package/dist/core/map.js.map +0 -1
  157. package/templates/dupignore +0 -93
  158. package/templates/mapignore +0 -58
  159. package/templates/mapkeys +0 -65
@@ -28,6 +28,34 @@ 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`) for symbols and reusable code, `.grimoire/docs/<area>.md` for conventions/boundaries, `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
+
51
+ **3. Plan to the principles.** Every task is gated by the four principles in `../references/principles.md` — **one right way, DRY, don't reinvent the wheel, keep it simple.** Concretely, before writing each task:
52
+ - **One right way:** name the single sanctioned approach. If the spec leaves two ways open, pick one (record why in the task) — never plan both.
53
+ - **DRY:** reuse before write (search the graph); don't plan a task that stores a fact already derivable from code/mcp or already homed elsewhere.
54
+ - **Don't reinvent:** prefer an existing tool/library/proven pattern over a bespoke mechanism. git for change process, standard libs for crypto/auth/parsing.
55
+ - **Keep it simple:** choose the least-code option inside the non-goals. Flag any task that adds an abstraction, a dependency, or a second mechanism — it needs an explicit reason.
56
+
57
+ These are gates, not aspirations — a task that adds a duplicate home or a reinvented wheel is rejected, not refined.
58
+
31
59
  ### 1. Select Change
32
60
  - List active changes in `.grimoire/changes/`
33
61
  - If multiple, ask user which one to plan
@@ -39,9 +67,10 @@ Derive implementation tasks from approved Gherkin features and MADR decisions. T
39
67
 
40
68
  **Always read:**
41
69
  - `manifest.md` for the change summary, **including complexity level, Assumptions, Pre-Mortem, and Prior Art sections**
42
- - All proposed `.feature` files
43
- - All proposed decision records, **including Cost of Ownership sections**
44
- - The current baseline (`features/`, `.grimoire/decisions/`) for context on what's changing
70
+ - All `.feature` files for this change (edited live in `features/` on the branch)
71
+ - All decision records for this change (edited live in `.grimoire/decisions/`), **including Cost of Ownership sections**
72
+ - `.grimoire/docs/constraints.md` any constraints (security/NFR/observability) this change adds or touches. These produce `unit-invariant` tasks, not scenarios.
73
+ - The current baseline (`features/`, `.grimoire/decisions/`) via `git diff main` to see exactly what this change adds vs. what already existed
45
74
 
46
75
  **Validate the build-vs-buy decision:**
47
76
  - Check that `manifest.md` has a **Prior Art** section documenting what existing solutions were researched. If it's missing or empty, **stop and tell the user** — planning without a build-vs-buy analysis produces plans that ignore cheaper alternatives.
@@ -50,16 +79,21 @@ Derive implementation tasks from approved Gherkin features and MADR decisions. T
50
79
  - If the decision was **hybrid** (adopt for part, build for part), ensure the boundary between adopted and custom code is clear in the tasks.
51
80
 
52
81
  **Read from grimoire docs (these replace codebase exploration):**
53
- - **`.grimoire/docs/<area>.md`** for each area the change touches — these contain: key files with responsibilities, reusable utilities (exact function names, file paths, line numbers), naming conventions, structural patterns, and "Where New Code Goes" guidance. This is the information that lets you write tasks with exact file paths without reading every source file.
82
+ - **`.grimoire/docs/<area>.md`** for each area the change touches — these contain Purpose, Boundaries, Conventions (naming/structure), and "Where New Code Goes" guidance. For key files, exact symbols, reusable utilities (function names, file paths, line numbers), and call graphs, **query the graph** `search_graph` / `get_code_snippet` / `get_architecture`. Area docs give you intent and placement; the graph gives you the live structure to write exact file paths and reuse existing code.
54
83
  - **`.grimoire/docs/data/schema.yml`** — the full data model: every table/collection, field types, relationships, indexes, and external API contracts with `source:` pointers to ORM code. Read this instead of reading individual model files.
55
84
  - **`.grimoire/docs/context.yml`** — the project's deployment environment, related services, infrastructure dependencies, CI/CD pipelines, and observability setup. Read this to understand deployment constraints (e.g., Lambda means no long-running processes, Kubernetes means you may need health check endpoints), cross-service boundaries (e.g., auth is handled by a sibling service, not this project), and infrastructure available at runtime (e.g., Redis is available for caching, RabbitMQ for async tasks).
56
- - **`.grimoire/docs/.snapshot.json`** `duplicates` section if present existing clones in areas you're touching, so tasks consolidate rather than add more.
85
+ - Existing duplication in areas you're touching — query codebase-memory-mcp (`search_graph` for similar functions) or run `grimoire health` (its config-driven `duplicates` metric) so tasks consolidate rather than add more clones.
57
86
 
58
87
  **Read proposed data changes:**
59
88
  - **`data.yml`** if present — proposed schema changes need migration and model tasks
60
89
 
90
+ **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.
91
+
92
+ - **Level 1-2:** Warn ("Area doc for `<area>` is behind recent commits — its boundaries/conventions may be wrong; rely on the graph for structure") and proceed. Note inferred paths with `<!-- inferred: area doc may be stale -->`.
93
+ - **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.
94
+
61
95
  **Read specific source files only when:**
62
- - Area docs don't exist yet (tell the user to run `grimoire map` + `/grimoire:discover` first — planning without area docs produces worse tasks)
96
+ - Area docs don't exist yet (tell the user to run `/grimoire:discover` first — planning without area docs produces worse tasks)
63
97
  - Area docs exist but you need to verify a specific implementation detail (e.g., exact function signature, exact import path)
64
98
  - You need to read existing step definitions to understand the test setup
65
99
 
@@ -69,41 +103,70 @@ Derive implementation tasks from approved Gherkin features and MADR decisions. T
69
103
 
70
104
  Before generating tasks, evaluate whether the specifications are detailed enough to plan against. Underspecified requirements produce vague tasks, which produce wrong code.
71
105
 
72
- Review the specs through each persona's lens and flag gaps. **Only check personas relevant to the change** — don't manufacture issues.
106
+ **Flag real gaps only do not manufacture issues to hit a checklist.** A "gap" exists when:
107
+ - The spec contradicts itself (a scenario violates a non-goal; two scenarios disagree).
108
+ - A scenario you need to plan against has missing detail you cannot infer from project conventions (e.g., "redirect to dashboard" — which dashboard URL?).
109
+ - The manifest is missing a section the complexity level requires (Assumptions / Pre-Mortem / Prior Art on level 3-4).
110
+ - A scenario references an external API or data model with no contract in `data.yml` / `schema.yml`.
111
+
112
+ **Not a gap** (do not flag):
113
+ - 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.
114
+ - 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).
115
+ - A non-functional concern (perf, observability) is unspecified at level 1-2.
73
116
 
74
117
  #### Outcome & Scope check
75
118
  - 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
119
  - 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
120
  - Do any scenarios appear to implement something listed as a non-goal? Flag as **blocker** — the draft contradicts itself.
78
121
 
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.
122
+ Persona lens (only those relevant to the change) — see `../references/elicitation-personas.md` for the full set:
123
+
124
+ - **Outcome & Scope**: Why states outcome (not mechanism)? Non-goals exist? No scenario contradicts a non-goal?
125
+ - **PM**: User stories present? Given/When/Then specific?
126
+ - **Engineer**: Critical-path assumptions validated or flagged? Prior art documented (if building custom)?
127
+ - **Security**: Scenarios with auth/input/sensitive-data tags have corresponding constraints? Quality Attribute targets not blank?
128
+ - **Data**: External APIs or new models have `data.yml`? Constraints (required/unique/nullable) specified?
129
+ - **QA**: Where the spec explicitly references an error path, is the expected behavior specified?
80
130
 
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?
131
+ **Response paths when a gap is found:**
88
132
 
89
- **If issues are found:**
133
+ 1. **Ambiguous** (the spec is contradictory or admits two readings) → ask the user one specific question. Do not pick a reading.
134
+ 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.
135
+ 3. **Missing detail derivable from conventions** → infer, plan, and annotate the task with `<!-- inferred: ... -->` so the user can override.
136
+ 4. **Missing manifest section the complexity level requires** → ask the user; flag as a gate for level 3-4.
90
137
 
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
138
+ If multiple gaps are found, batch them and present once. Wait for the user's response before generating tasks.
96
139
 
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.
140
+ Level 1-2 changes with minor gaps may proceed; level 3-4 with multiple gaps should not.
98
141
 
99
- **If no issues are found**, proceed directly to task generation.
142
+ **If no real gaps**, proceed directly to task generation.
100
143
 
101
144
  ### 4. Generate Tasks
102
- 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.
145
+ Create `.grimoire/changes/<change-id>/tasks.md`. **Every task produces both production code AND a test — but the test level matches the artifact the task derives from.** Tasks are structured as pairs: the failing test first, then the production code.
146
+
147
+ **Tag every implementation task with a `verify:` level** — this tells `grimoire-apply` which test vehicle to use. Match the artifact:
148
+
149
+ | Task derives from | `verify:` | Test vehicle |
150
+ |-------------------|-----------|--------------|
151
+ | a `.feature` scenario (actor-observable behavior) | `scenario` | step definitions + Gherkin |
152
+ | a constraint in `constraints.md` (security/NFR/observability) | `unit-invariant` | unit/integration test asserting the invariant |
153
+ | an ADR consequence, refactor, or internal change with no spec | `characterization` | unit / characterization test |
154
+
155
+ **Do not plan a `.feature` scenario task for a constraint or an internal change.** Constraints get `unit-invariant` unit tests; internal changes get `characterization` tests. Forcing Gherkin onto a non-behavioral concern is the antipattern that fills feature files with slop (one right way: behavior → scenario, everything else → unit test).
156
+
157
+ **THE PLAN'S SCOPE IS WHAT WAS APPROVED.** Tasks may only derive from:
158
+ - `.feature` scenarios in this change → `verify: scenario`
159
+ - Constraints added/touched in `.grimoire/docs/constraints.md` → `verify: unit-invariant`
160
+ - ADRs in this change (and their Confirmation sections) → `verify: unit-invariant` or `characterization`
161
+ - `data.yml` entries in this change
162
+ - The manifest's Assumptions, Pre-Mortem mitigations, and Prior Art borrowings
163
+ - Verification tasks (run feature suite, run project suite, validate ADR confirmation)
164
+
165
+ 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.
103
166
 
104
167
  **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
168
 
106
- **THE PLAN MUST BE SPECIFIC ENOUGH TO EXECUTE WITHOUT FURTHER PLANNING.**
169
+ **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
170
 
108
171
  **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
172
 
@@ -216,8 +279,8 @@ Follow the rules in `../references/testing-contracts.md`. Key points: mock at HT
216
279
  - If a library was rejected for a specific reason (e.g., doesn't support X), add a comment to the relevant task noting this so future developers don't re-evaluate the same option
217
280
 
218
281
  **Existing code to reuse:**
219
- - If `.grimoire/docs/` has area docs, check the Reusable Code tables for utilities that apply to this change
220
- - If the snapshot has duplicate data, check whether the area you're touching already has clones — tasks should consolidate rather than add more
282
+ - Query the graph (`search_graph` by concept/name) for existing utilities that apply to this change; area docs give conventions, the graph gives the reusable symbols
283
+ - If `grimoire health`/mcp shows existing clones in the area you're touching, tasks should consolidate rather than add more
221
284
  - Add a "Reuse" section at the top of tasks.md listing specific functions/classes to import instead of rewriting
222
285
 
223
286
  **Verification (always last):**
@@ -239,12 +302,12 @@ The tasks file starts with a context block so any LLM can orient without re-read
239
302
 
240
303
  ## 1. <Capability/Area>
241
304
  <!-- context:
242
- - .grimoire/changes/<change-id>/features/<capability>/<name>.feature
305
+ - features/<name>.feature
243
306
  - .grimoire/docs/<area>.md
244
307
  - src/<area>/<file-to-edit>.ts
245
308
  - tests/<area>/<test-file>.ts
246
309
  -->
247
- - [ ] 1.1 Write step defs in `<exact path>` for scenario: "<scenario name>" in `<file>`
310
+ - [ ] 1.1 (verify: scenario) Write step defs in `<exact path>` for scenario: "<scenario name>" in `features/<file>`
248
311
  - Given: <what the step does, what it calls>
249
312
  - When: <what the step does, what it calls>
250
313
  - Then: <what to assert — specific expected values/states>
@@ -252,32 +315,40 @@ The tasks file starts with a context block so any LLM can orient without re-read
252
315
  - <specific function/class/view to create or modify>
253
316
  - <specific behavior to implement>
254
317
  - <edge cases to handle>
255
- - [ ] 1.3 Write step defs in `<exact path>` for scenario: "<next scenario>"
256
- ...
257
- - [ ] 1.4 Implement in `<exact path>`:
258
- ...
259
318
 
260
- ## 2. Shared Steps
319
+ ## 2. Constraints
320
+ <!-- context:
321
+ - .grimoire/docs/constraints.md
322
+ - src/<area>/<file-to-edit>.ts
323
+ - tests/<area>/<unit-test-file>.ts
324
+ -->
325
+ - [ ] 2.1 (verify: unit-invariant) Write unit test in `<exact path>` asserting constraint: "<assertion from constraints.md>"
326
+ - Arrange: <setup>
327
+ - Assert: <the invariant — exact expected behavior, no Gherkin>
328
+ - [ ] 2.2 Implement in `<exact path>`:
329
+ - <specific change that satisfies the invariant>
330
+
331
+ ## 3. Shared Steps
261
332
  <!-- context:
262
333
  - tests/step_defs/common.py
263
- - .grimoire/changes/<change-id>/features/<all relevant .feature files>
334
+ - features/<all relevant .feature files>
264
335
  -->
265
- - [ ] 2.1 Add to `<exact path>`:
336
+ - [ ] 3.1 Add to `<exact path>`:
266
337
  - Given "<step text>": <what it does>
267
338
  - Given "<step text>": <what it does>
268
339
 
269
- ## 3. Architecture
340
+ ## 4. Architecture
270
341
  <!-- context:
271
- - .grimoire/changes/<change-id>/decisions/<nnnn-title>.md
342
+ - .grimoire/decisions/<nnnn-title>.md
272
343
  - src/<files affected by decision>
273
344
  -->
274
- - [ ] 3.1 In `<exact path>`: <specific change from ADR>
275
- - [ ] 3.2 Add test in `<exact path>`: <ADR confirmation check — what to assert>
345
+ - [ ] 4.1 (verify: characterization) In `<exact path>`: <specific change from ADR>
346
+ - [ ] 4.2 Add test in `<exact path>`: <ADR confirmation check — what to assert>
276
347
 
277
- ## 4. Verification
278
- - [ ] 4.1 Run `<exact test command>` — all new scenarios green
279
- - [ ] 4.2 Run `<exact test command>` — no regressions
280
- - [ ] 4.3 Run `<exact test command>` — full project suite
348
+ ## 5. Verification
349
+ - [ ] 5.1 Run `<exact test command>` — all new scenarios green
350
+ - [ ] 5.2 Run `<exact test command>` — no regressions
351
+ - [ ] 5.3 Run `<exact test command>` — full project suite
281
352
  ```
282
353
 
283
354
  **Context blocks are mandatory.** Every task section (except Verification) must have a `<!-- context: ... -->` listing the files needed. This serves two purposes:
@@ -287,11 +358,13 @@ The tasks file starts with a context block so any LLM can orient without re-read
287
358
  ### 6. Quality Check
288
359
  Before presenting to the user, verify the plan:
289
360
  - [ ] Every task references a specific file path (no "implement the feature")
290
- - [ ] Every step definition task describes what to assert (no "write a test")
361
+ - [ ] Every implementation task carries a `verify:` tag matching its source artifact — `scenario` only for `.feature` behavior; `unit-invariant` for constraints; `characterization` for internal/refactor. No `.feature` scenario task for a constraint or internal change.
362
+ - [ ] Every test task describes what to assert (no "write a test")
291
363
  - [ ] Every implementation task describes what to create/modify (no "add the code")
292
364
  - [ ] The verification section has the exact commands to run
293
- - [ ] Tasks are ordered: shared steps → step defs → production code → verification
365
+ - [ ] Tasks are ordered: shared steps → test → production code → verification
294
366
  - [ ] No task requires the LLM to make architectural decisions — those should already be in the ADR
367
+ - [ ] **Principles gate** (`../references/principles.md`): no task introduces a duplicate home for an existing fact (DRY), a second way to do an existing thing (one right way), a reinvented wheel where a tool/library/proven pattern exists (don't reinvent), or an abstraction/dependency justified only by a hypothetical (KISS). Any that does has a stated reason.
295
368
 
296
369
  If any task is too vague, make it more specific before presenting. Read more codebase if needed.
297
370
 
@@ -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 — the PR reflects the finished branch state (decisions accepted, change folder 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/tasks were ephemeral scaffolding)
26
+ - Decision records are live in `.grimoire/decisions/` with status `accepted`
27
+ - The change is on a feature branch (created during draft/apply); its diff vs. `main` is the change
30
28
 
31
29
  ## Workflow
32
30
 
@@ -119,9 +117,8 @@ Check that the branch is pushed to the remote before creating. If not, offer to
119
117
 
120
118
  ### 6. Link Back
121
119
  After PR creation:
122
- - Update manifest's status to `complete` if not already
123
- - Add the PR URL to the manifest as a comment or field
124
- - Suggest running `grimoire archive <change-id>` to complete the lifecycle
120
+ - The `Change: <change-id>` trailer on the commits links them to the change; the PR body + git log are the durable record (the change folder was already removed at finalize).
121
+ - Suggest merging the PR to complete the change. There is no archive step — git history is the history.
125
122
 
126
123
  ## Important
127
124
  - The PR description must trace back to grimoire artifacts — this is what makes the audit trail work.
@@ -131,4 +128,4 @@ After PR creation:
131
128
  - If tasks are incomplete, warn the user but don't block PR creation — they may want a draft PR.
132
129
 
133
130
  ## Done
134
- When the PR is created (or description is presented for manual creation), the workflow is complete. Suggest `grimoire archive <change-id>` to complete the lifecycle.
131
+ When the PR is created (or description is presented for manual creation), the workflow is complete. Suggest merging the PR to complete the change — git history + the `Change:` trailer are the record; there is no separate archive step.
@@ -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`
@@ -63,111 +64,43 @@ git log <base>..<head> --format="%B" | grep -E "^Change:"
63
64
 
64
65
  If present:
65
66
  - Change ID = trailer value
66
- - Load artifacts: first check `.grimoire/changes/<change-id>/` (in-progress), then `.grimoire/archive/*<change-id>*/` (archived). Try the PR's head branch checked out locally if needed.
67
+ - Load artifacts: check `.grimoire/changes/<change-id>/` for an active change. If the change is already finalized/merged the change folder is gone — read the artifacts from the PR's head branch (`git diff main` shows the live `features/`, `.grimoire/decisions/`, `.grimoire/docs/constraints.md`) and use the `Change:` trailer to correlate commits.
67
68
  - Read `manifest.md`, all `.feature` files in the change, decision records, `tasks.md`, `data.yml`
68
69
  - Also grep for `Scenarios:` and `Decisions:` trailers to scope review to the named items
69
70
 
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`.