@kiwidata/grimoire 0.1.4 → 0.1.6

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 (112) hide show
  1. package/.claude-plugin/plugin.json +2 -2
  2. package/AGENTS.md +21 -25
  3. package/LICENSE +36 -0
  4. package/README.md +86 -61
  5. package/dist/cli/index.js +2 -43
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/cli/program.d.ts +4 -0
  8. package/dist/cli/program.d.ts.map +1 -0
  9. package/dist/cli/program.js +45 -0
  10. package/dist/cli/program.js.map +1 -0
  11. package/dist/commands/configure.d.ts.map +1 -1
  12. package/dist/commands/configure.js +2 -1
  13. package/dist/commands/configure.js.map +1 -1
  14. package/dist/core/check.d.ts.map +1 -1
  15. package/dist/core/check.js +47 -11
  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 +2 -2
  19. package/dist/core/ci.js.map +1 -1
  20. package/dist/core/doc-style.d.ts.map +1 -1
  21. package/dist/core/doc-style.js +76 -0
  22. package/dist/core/doc-style.js.map +1 -1
  23. package/dist/core/docs.d.ts.map +1 -1
  24. package/dist/core/docs.js +93 -74
  25. package/dist/core/docs.js.map +1 -1
  26. package/dist/core/health.d.ts +6 -0
  27. package/dist/core/health.d.ts.map +1 -1
  28. package/dist/core/health.js +78 -21
  29. package/dist/core/health.js.map +1 -1
  30. package/dist/core/hooks.d.ts.map +1 -1
  31. package/dist/core/hooks.js +17 -19
  32. package/dist/core/hooks.js.map +1 -1
  33. package/dist/core/list.d.ts.map +1 -1
  34. package/dist/core/list.js +4 -7
  35. package/dist/core/list.js.map +1 -1
  36. package/dist/core/pr.d.ts.map +1 -1
  37. package/dist/core/pr.js +0 -8
  38. package/dist/core/pr.js.map +1 -1
  39. package/dist/core/risk-register.d.ts +17 -0
  40. package/dist/core/risk-register.d.ts.map +1 -0
  41. package/dist/core/risk-register.js +73 -0
  42. package/dist/core/risk-register.js.map +1 -0
  43. package/dist/core/shared-setup.d.ts.map +1 -1
  44. package/dist/core/shared-setup.js +5 -4
  45. package/dist/core/shared-setup.js.map +1 -1
  46. package/dist/core/status.d.ts.map +1 -1
  47. package/dist/core/status.js +3 -3
  48. package/dist/core/status.js.map +1 -1
  49. package/dist/core/trace.d.ts.map +1 -1
  50. package/dist/core/trace.js +37 -35
  51. package/dist/core/trace.js.map +1 -1
  52. package/dist/core/update.d.ts.map +1 -1
  53. package/dist/core/update.js +1 -10
  54. package/dist/core/update.js.map +1 -1
  55. package/dist/index.d.ts +0 -3
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +0 -3
  58. package/dist/index.js.map +1 -1
  59. package/package.json +19 -2
  60. package/skills/grimoire-apply/SKILL.md +40 -37
  61. package/skills/grimoire-audit/SKILL.md +4 -1
  62. package/skills/grimoire-bug/SKILL.md +7 -3
  63. package/skills/grimoire-commit/SKILL.md +1 -1
  64. package/skills/grimoire-design/SKILL.md +3 -3
  65. package/skills/grimoire-discover/SKILL.md +77 -110
  66. package/skills/grimoire-draft/SKILL.md +55 -18
  67. package/skills/grimoire-plan/SKILL.md +58 -52
  68. package/skills/grimoire-pr/SKILL.md +7 -8
  69. package/skills/grimoire-pr-review/SKILL.md +2 -1
  70. package/skills/grimoire-refactor/SKILL.md +3 -3
  71. package/skills/grimoire-review/SKILL.md +13 -1
  72. package/skills/grimoire-verify/SKILL.md +19 -7
  73. package/skills/grimoire-vuln-remediate/SKILL.md +107 -0
  74. package/skills/grimoire-vuln-triage/SKILL.md +109 -0
  75. package/skills/references/artifact-map.md +44 -0
  76. package/skills/references/code-quality.md +41 -9
  77. package/skills/references/container-scan-triage.md +102 -0
  78. package/skills/references/dependency-vuln-triage.md +236 -0
  79. package/skills/references/principles.md +82 -0
  80. package/skills/references/refactor-scan-categories.md +2 -2
  81. package/skills/references/review-personas.md +13 -6
  82. package/skills/references/test-baseline.md +55 -0
  83. package/skills/references/testing-contracts.md +1 -1
  84. package/templates/accepted-risks.yml +47 -0
  85. package/templates/constraints.md +25 -0
  86. package/dist/commands/archive.d.ts +0 -3
  87. package/dist/commands/archive.d.ts.map +0 -1
  88. package/dist/commands/archive.js +0 -22
  89. package/dist/commands/archive.js.map +0 -1
  90. package/dist/commands/log.d.ts +0 -3
  91. package/dist/commands/log.d.ts.map +0 -1
  92. package/dist/commands/log.js +0 -15
  93. package/dist/commands/log.js.map +0 -1
  94. package/dist/commands/map.d.ts +0 -3
  95. package/dist/commands/map.d.ts.map +0 -1
  96. package/dist/commands/map.js +0 -16
  97. package/dist/commands/map.js.map +0 -1
  98. package/dist/core/archive.d.ts +0 -9
  99. package/dist/core/archive.d.ts.map +0 -1
  100. package/dist/core/archive.js +0 -81
  101. package/dist/core/archive.js.map +0 -1
  102. package/dist/core/log.d.ts +0 -8
  103. package/dist/core/log.d.ts.map +0 -1
  104. package/dist/core/log.js +0 -140
  105. package/dist/core/log.js.map +0 -1
  106. package/dist/core/map.d.ts +0 -22
  107. package/dist/core/map.d.ts.map +0 -1
  108. package/dist/core/map.js +0 -365
  109. package/dist/core/map.js.map +0 -1
  110. package/templates/dupignore +0 -93
  111. package/templates/mapignore +0 -58
  112. package/templates/mapkeys +0 -65
@@ -38,7 +38,7 @@ Derive implementation tasks from approved Gherkin features and MADR decisions. T
38
38
  - "See if there's an existing utility for Z"
39
39
  - "TODO: check if this conflicts with…"
40
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*.
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
42
 
43
43
  **2. Clarify or propose, never assume.** When the spec is ambiguous or silent on something you need to plan:
44
44
 
@@ -48,6 +48,14 @@ Resolve each one yourself before writing the task. Tools: codebase-memory-mcp (`
48
48
 
49
49
  The plan implements what's approved. It does not expand scope to hit a checklist.
50
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
+
51
59
  ### 1. Select Change
52
60
  - List active changes in `.grimoire/changes/`
53
61
  - If multiple, ask user which one to plan
@@ -55,13 +63,11 @@ The plan implements what's approved. It does not expand scope to hit a checklist
55
63
 
56
64
  ### 2. Read All Artifacts
57
65
 
58
- **Grimoire docs first, codebase second.** The `.grimoire/docs/` directory is a pre-computed map of the codebase — it tells you where code lives, what utilities exist, what patterns to follow, and what the data layer looks like. Read these *instead of* exploring the raw codebase. Only read specific source files when the docs don't have what you need.
66
+ Read the change's artifacts following `../references/artifact-map.md` — it defines what each file is, the grimoire-docs-first / graph-for-structure discipline, and the staleness gate. Plan-specific reading on top of that:
59
67
 
60
- **Always read:**
61
- - `manifest.md` for the change summary, **including complexity level, Assumptions, Pre-Mortem, and Prior Art sections**
62
- - All proposed `.feature` files
63
- - All proposed decision records, **including Cost of Ownership sections**
64
- - The current baseline (`features/`, `.grimoire/decisions/`) for context on what's changing
68
+ - `.grimoire/docs/constraints.md` — any constraints (security/NFR/observability) this change touches. These produce `unit-invariant` tasks, not scenarios.
69
+ - The current baseline (`features/`, `.grimoire/decisions/`) via `git diff main` exactly what this change adds vs. what already existed.
70
+ - Existing duplication in areas you're touching — `search_graph` for similar functions, or `grimoire health` (its `duplicates` metric) — so tasks consolidate rather than clone.
65
71
 
66
72
  **Validate the build-vs-buy decision:**
67
73
  - 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.
@@ -69,27 +75,6 @@ The plan implements what's approved. It does not expand scope to hit a checklist
69
75
  - If the decision was to **build custom**, verify the manifest documents (1) what existing tools were considered, (2) the specific requirements they don't meet, and (3) what design patterns are being borrowed from prior art.
70
76
  - If the decision was **hybrid** (adopt for part, build for part), ensure the boundary between adopted and custom code is clear in the tasks.
71
77
 
72
- **Read from grimoire docs (these replace codebase exploration):**
73
- - **`.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.
74
- - **`.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.
75
- - **`.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).
76
- - **`.grimoire/docs/.snapshot.json`** `duplicates` section if present — existing clones in areas you're touching, so tasks consolidate rather than add more.
77
-
78
- **Read proposed data changes:**
79
- - **`data.yml`** if present — proposed schema changes need migration and model tasks
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
-
86
- **Read specific source files only when:**
87
- - Area docs don't exist yet (tell the user to run `grimoire map` + `/grimoire:discover` first — planning without area docs produces worse tasks)
88
- - Area docs exist but you need to verify a specific implementation detail (e.g., exact function signature, exact import path)
89
- - You need to read existing step definitions to understand the test setup
90
-
91
- **Do NOT read the entire codebase** for "context." The plan skill's job is to produce tasks with specific file paths and specific assertions. Area docs + data schema give you this. Reading dozens of source files wastes context window and doesn't produce better plans.
92
-
93
78
  ### 3. Check Specification Completeness
94
79
 
95
80
  Before generating tasks, evaluate whether the specifications are detailed enough to plan against. Underspecified requirements produce vague tasks, which produce wrong code.
@@ -133,11 +118,22 @@ Level 1-2 changes with minor gaps may proceed; level 3-4 with multiple gaps shou
133
118
  **If no real gaps**, proceed directly to task generation.
134
119
 
135
120
  ### 4. Generate Tasks
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.
121
+ 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.
122
+
123
+ **Tag every implementation task with a `verify:` level** — this tells `grimoire-apply` which test vehicle to use. Match the artifact:
124
+
125
+ | Task derives from | `verify:` | Test vehicle |
126
+ |-------------------|-----------|--------------|
127
+ | a `.feature` scenario (actor-observable behavior) | `scenario` | step definitions + Gherkin |
128
+ | a constraint in `constraints.md` (security/NFR/observability) | `unit-invariant` | unit/integration test asserting the invariant |
129
+ | an ADR consequence, refactor, or internal change with no spec | `characterization` | unit / characterization test |
130
+
131
+ **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).
137
132
 
138
133
  **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)
134
+ - `.feature` scenarios in this change → `verify: scenario`
135
+ - Constraints added/touched in `.grimoire/docs/constraints.md` `verify: unit-invariant`
136
+ - ADRs in this change (and their Confirmation sections) → `verify: unit-invariant` or `characterization`
141
137
  - `data.yml` entries in this change
142
138
  - The manifest's Assumptions, Pre-Mortem mitigations, and Prior Art borrowings
143
139
  - Verification tasks (run feature suite, run project suite, validate ADR confirmation)
@@ -259,8 +255,8 @@ Follow the rules in `../references/testing-contracts.md`. Key points: mock at HT
259
255
  - 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
260
256
 
261
257
  **Existing code to reuse:**
262
- - If `.grimoire/docs/` has area docs, check the Reusable Code tables for utilities that apply to this change
263
- - If the snapshot has duplicate data, check whether the area you're touching already has clones — tasks should consolidate rather than add more
258
+ - 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
259
+ - If `grimoire health`/mcp shows existing clones in the area you're touching, tasks should consolidate rather than add more
264
260
  - Add a "Reuse" section at the top of tasks.md listing specific functions/classes to import instead of rewriting
265
261
 
266
262
  **Verification (always last):**
@@ -282,12 +278,12 @@ The tasks file starts with a context block so any LLM can orient without re-read
282
278
 
283
279
  ## 1. <Capability/Area>
284
280
  <!-- context:
285
- - .grimoire/changes/<change-id>/features/<capability>/<name>.feature
281
+ - features/<name>.feature
286
282
  - .grimoire/docs/<area>.md
287
283
  - src/<area>/<file-to-edit>.ts
288
284
  - tests/<area>/<test-file>.ts
289
285
  -->
290
- - [ ] 1.1 Write step defs in `<exact path>` for scenario: "<scenario name>" in `<file>`
286
+ - [ ] 1.1 (verify: scenario) Write step defs in `<exact path>` for scenario: "<scenario name>" in `features/<file>`
291
287
  - Given: <what the step does, what it calls>
292
288
  - When: <what the step does, what it calls>
293
289
  - Then: <what to assert — specific expected values/states>
@@ -295,32 +291,40 @@ The tasks file starts with a context block so any LLM can orient without re-read
295
291
  - <specific function/class/view to create or modify>
296
292
  - <specific behavior to implement>
297
293
  - <edge cases to handle>
298
- - [ ] 1.3 Write step defs in `<exact path>` for scenario: "<next scenario>"
299
- ...
300
- - [ ] 1.4 Implement in `<exact path>`:
301
- ...
302
294
 
303
- ## 2. Shared Steps
295
+ ## 2. Constraints
296
+ <!-- context:
297
+ - .grimoire/docs/constraints.md
298
+ - src/<area>/<file-to-edit>.ts
299
+ - tests/<area>/<unit-test-file>.ts
300
+ -->
301
+ - [ ] 2.1 (verify: unit-invariant) Write unit test in `<exact path>` asserting constraint: "<assertion from constraints.md>"
302
+ - Arrange: <setup>
303
+ - Assert: <the invariant — exact expected behavior, no Gherkin>
304
+ - [ ] 2.2 Implement in `<exact path>`:
305
+ - <specific change that satisfies the invariant>
306
+
307
+ ## 3. Shared Steps
304
308
  <!-- context:
305
309
  - tests/step_defs/common.py
306
- - .grimoire/changes/<change-id>/features/<all relevant .feature files>
310
+ - features/<all relevant .feature files>
307
311
  -->
308
- - [ ] 2.1 Add to `<exact path>`:
312
+ - [ ] 3.1 Add to `<exact path>`:
309
313
  - Given "<step text>": <what it does>
310
314
  - Given "<step text>": <what it does>
311
315
 
312
- ## 3. Architecture
316
+ ## 4. Architecture
313
317
  <!-- context:
314
- - .grimoire/changes/<change-id>/decisions/<nnnn-title>.md
318
+ - .grimoire/decisions/<nnnn-title>.md
315
319
  - src/<files affected by decision>
316
320
  -->
317
- - [ ] 3.1 In `<exact path>`: <specific change from ADR>
318
- - [ ] 3.2 Add test in `<exact path>`: <ADR confirmation check — what to assert>
321
+ - [ ] 4.1 (verify: characterization) In `<exact path>`: <specific change from ADR>
322
+ - [ ] 4.2 Add test in `<exact path>`: <ADR confirmation check — what to assert>
319
323
 
320
- ## 4. Verification
321
- - [ ] 4.1 Run `<exact test command>` — all new scenarios green
322
- - [ ] 4.2 Run `<exact test command>` — no regressions
323
- - [ ] 4.3 Run `<exact test command>` — full project suite
324
+ ## 5. Verification
325
+ - [ ] 5.1 Run `<exact test command>` — all new scenarios green
326
+ - [ ] 5.2 Run `<exact test command>` — no regressions
327
+ - [ ] 5.3 Run `<exact test command>` — full project suite
324
328
  ```
325
329
 
326
330
  **Context blocks are mandatory.** Every task section (except Verification) must have a `<!-- context: ... -->` listing the files needed. This serves two purposes:
@@ -330,11 +334,13 @@ The tasks file starts with a context block so any LLM can orient without re-read
330
334
  ### 6. Quality Check
331
335
  Before presenting to the user, verify the plan:
332
336
  - [ ] Every task references a specific file path (no "implement the feature")
333
- - [ ] Every step definition task describes what to assert (no "write a test")
337
+ - [ ] 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.
338
+ - [ ] Every test task describes what to assert (no "write a test")
334
339
  - [ ] Every implementation task describes what to create/modify (no "add the code")
335
340
  - [ ] The verification section has the exact commands to run
336
- - [ ] Tasks are ordered: shared steps → step defs → production code → verification
341
+ - [ ] Tasks are ordered: shared steps → test → production code → verification
337
342
  - [ ] No task requires the LLM to make architectural decisions — those should already be in the ADR
343
+ - [ ] **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.
338
344
 
339
345
  If any task is too vague, make it more specific before presenting. Read more codebase if needed.
340
346
 
@@ -17,14 +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 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).
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
- - 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)
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
28
28
 
29
29
  ## Workflow
30
30
 
@@ -117,9 +117,8 @@ Check that the branch is pushed to the remote before creating. If not, offer to
117
117
 
118
118
  ### 6. Link Back
119
119
  After PR creation:
120
- - Update manifest's status to `complete` if not already
121
- - Add the PR URL to the manifest as a comment or field
122
- - 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.
123
122
 
124
123
  ## Important
125
124
  - The PR description must trace back to grimoire artifacts — this is what makes the audit trail work.
@@ -129,4 +128,4 @@ After PR creation:
129
128
  - If tasks are incomplete, warn the user but don't block PR creation — they may want a draft PR.
130
129
 
131
130
  ## Done
132
- 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.
@@ -64,13 +64,14 @@ git log <base>..<head> --format="%B" | grep -E "^Change:"
64
64
 
65
65
  If present:
66
66
  - Change ID = trailer value
67
- - 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.
68
68
  - Read `manifest.md`, all `.feature` files in the change, decision records, `tasks.md`, `data.yml`
69
69
  - Also grep for `Scenarios:` and `Decisions:` trailers to scope review to the named items
70
70
 
71
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.
72
72
 
73
73
  ### 4. Gather Project Context
74
+ See `../references/artifact-map.md` for what each artifact is and the grimoire-docs-first / staleness discipline.
74
75
  - `.grimoire/config.yaml` — language, tools, `commit_style`, `comment_style`, `project.compliance`, `dep_audit`
75
76
  - `.grimoire/docs/context.yml` — deployment environment, related services
76
77
  - `.grimoire/docs/data/schema.yml` — current data baseline
@@ -26,7 +26,7 @@ Systematically find, prioritize, and plan tech debt reduction. Combines automate
26
26
  ## Prerequisites
27
27
  - A grimoire-initialized project (`.grimoire/` exists)
28
28
  - Git history available (hotspot analysis needs `git log`)
29
- - Ideally: `grimoire map` + `/grimoire:discover` already run (area docs help contextualize findings)
29
+ - Ideally: codebase-memory-mcp indexed (live structure/duplication intelligence) + `/grimoire:discover` run (area intent docs help contextualize findings)
30
30
 
31
31
  ## Debt Item Format
32
32
 
@@ -113,7 +113,7 @@ Run applicable scans from the categories in `../references/refactor-scan-categor
113
113
  - **Circular dependencies** — tight coupling between modules
114
114
  - **Dependency staleness** — uses `config.tools.dep_audit` or package manager outdated commands
115
115
  - **Broken promises** — aged TODO/FIXME/HACK comments via `grep` + `git blame`
116
- - **Duplication** — textual clones via `.snapshot.json` or `config.tools.duplicates`; plus semantic duplicate detection via `search_graph(semantic_query=[...])` to find re-implementations under different names (requires `codebase-memory-mcp`)
116
+ - **Duplication** — textual clones via `config.tools.duplicates` or `grimoire health` (config-driven duplicates metric); plus semantic duplicate detection via `search_graph(semantic_query=[...])` to find re-implementations under different names (requires `codebase-memory-mcp`)
117
117
  - **Dead code** — uses `config.tools.dead_code` or `codebase-memory-mcp` graph queries
118
118
  - **Test debt** — high complexity + low coverage
119
119
  - **Pattern divergence** — code that contradicts established codebase patterns; uses `codebase-memory-mcp` peer group analysis + hallucinated reference detection (skip if graph not indexed)
@@ -209,7 +209,7 @@ For each item the user approves to fix:
209
209
  4. Hand off to `/grimoire:plan` for task generation, then `/grimoire:apply` for implementation
210
210
 
211
211
  **Refactoring-specific guidance for the plan/apply stages:**
212
- - **All existing tests must keep passing.** A refactoring that breaks tests is not a refactoring.
212
+ - **Capture a baseline first, then keep it.** Apply records which tests were already failing at change start (`baseline.md`, see `../references/test-baseline.md`). For a refactor this is the whole safety net: "passing" means *no new failures vs the baseline*, not "zero failures." A test red before you started is pre-existing and accepted; a test you turn red is the refactor breaking behavior — and that means it's not a refactoring. Diff against the baseline after each incremental move.
213
213
  - **Prefer incremental moves over big-bang rewrites.** Move one function at a time, run tests after each move.
214
214
  - **Add tests before refactoring if test debt is part of the item.** You need a safety net before restructuring.
215
215
  - **Update imports incrementally.** When moving code to a new module, re-export from the old location first, then update consumers, then remove the re-export.
@@ -42,7 +42,7 @@ This step is optional. The user can skip it by saying "skip review" or "go strai
42
42
  - If only one, confirm it
43
43
 
44
44
  ### 2. Gather Context
45
- Read all artifacts for the change:
45
+ Read all artifacts for the change — see `../references/artifact-map.md` for what each is and the grimoire-docs-first / staleness discipline:
46
46
  - `manifest.md` — change summary, scope, **and Prior Art section** (build-vs-buy rationale)
47
47
  - All `.feature` files — behavioral specifications
48
48
  - All decision records — architectural choices
@@ -95,6 +95,12 @@ Persona scope for design review:
95
95
  - 4.6 Code Style Reviewer — **skip** (no code yet; runs only on diff reviews)
96
96
  - 4.7 Adversarial User — engage per matrix; criteria in `../references/adversarial-personas.md`
97
97
  - 4.8 Contrarian — runs last when any persona produced a blocker; calibrates other personas' findings post-hoc
98
+ - 4.9 Principles Auditor — **runs on every review (complexity ≥ 2), always.** Audits the design against the four principles in `../references/principles.md` and raises a finding for each violation lacking a stated reason:
99
+ - **One right way** — does any artifact introduce a second way to do something the codebase already does? Does a spec leave two approaches open ("X or Y")? → blocker until one is chosen.
100
+ - **DRY** — is any fact given a second home (a capability in feature + MADR + constraint; a constant/rule duplicated)? Does any task store something derivable from code/mcp? → blocker.
101
+ - **Don't reinvent the wheel** — does any task build a mechanism that an existing tool/library/proven pattern already provides (custom crypto/auth, a bespoke change-tracking/diff/staging process where git suffices)? → blocker.
102
+ - **Keep it simple** — any abstraction, indirection, new dependency, or new file justified only by a hypothetical, or scope reaching past a non-goal? → suggestion (blocker if it adds a maintained surface).
103
+ - Also enforce the **artifact-jurisdiction** rule: any `.feature` scenario that is really a constraint (security/NFR/observability), an internal technical detail, or a non-functional concern is a blocker — it belongs in `constraints.md` or a MADR, not Gherkin.
98
104
 
99
105
  ### 5.5 Visual Fidelity (cheap tier)
100
106
 
@@ -144,6 +150,12 @@ Compile into the standard report layout (§5 of the personas reference):
144
150
  - **[suggestion]** [axe-color-contrast] `designs/preview.html` — Element has insufficient color contrast 3.8. Impact: serious.
145
151
  (or: "axe-core: no violations." / "axe-core not installed — install `@axe-core/cli` for accessibility checks.")
146
152
 
153
+ ## Principles Auditor
154
+ - **[blocker]** [DRY] PII-scrubbing behavior is specified in both `features/pii-log-scrubbing.feature` and ADR-0008 — one authoritative home. Move to `constraints.md`, link the MADR.
155
+ - **[blocker]** [jurisdiction] `features/logging-observability.feature` describes internal log structure (no external actor) — belongs in `constraints.md`, not a `.feature`.
156
+ - **[suggestion]** [KISS] Task 3.2 adds a `BaseExtractor` for a single caller — inline until a second extractor exists.
157
+ (or: "No principle violations found.")
158
+
147
159
  ## Contrarian <!-- omit when zero findings from all personas -->
148
160
  - **[blocker upheld]** ...
149
161
  - **[blocker → suggestion]** ...
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: grimoire-verify
3
- description: Verify that implementation matches feature specs and decision records. Use after apply is complete, before archiving the change.
3
+ description: Verify that implementation matches feature specs and decision records. Use after apply is complete, before committing and opening a PR.
4
4
  compatibility: Designed for Claude Code (or similar products)
5
5
  metadata:
6
6
  author: kiwi-data
@@ -9,11 +9,11 @@ metadata:
9
9
 
10
10
  # grimoire-verify
11
11
 
12
- Verify that implementation matches the feature specs and decision records. Run after apply, before archive.
12
+ Verify that implementation matches the feature specs and decision records. Run after apply, before commit and PR.
13
13
 
14
14
  ## Triggers
15
15
  - User wants to verify a grimoire change is correctly implemented
16
- - User asks to check, verify, or review a change before archiving
16
+ - User asks to check, verify, or review a change before committing
17
17
  - Loose match: "verify", "check", "review" with a change reference
18
18
 
19
19
  ## Routing
@@ -41,6 +41,7 @@ Two modes:
41
41
  ### 2. Load Artifacts
42
42
  For change verification:
43
43
  - Read `manifest.md`, proposed `.feature` files, decision records, `tasks.md`
44
+ - Read `baseline.md` if present (the test state captured at change start) — it's how you tell a regression from a failure that was already red
44
45
 
45
46
  For baseline verification:
46
47
  - Read all `features/**/*.feature` and `.grimoire/decisions/*.md`
@@ -76,6 +77,17 @@ Flag issues:
76
77
  - Decision's Confirmation criteria not verifiable → WARNING
77
78
  - Decision consequences not addressed → WARNING
78
79
 
80
+ ### 3.C2 Regression vs Baseline
81
+
82
+ Run the configured suites (`config.tools.unit_test`, `config.tools.bdd_test`) and classify each failure against `baseline.md`:
83
+
84
+ - Failing now **and** in the baseline → **pre-existing**, already accepted by the user at change start. Not a regression. Do not blame the change.
85
+ - Failing now, **not** in the baseline → **regression** introduced by this change → CRITICAL. Must be fixed before the change finalizes.
86
+ - Passing now, failing in the baseline → incidentally fixed; note it, don't require it.
87
+ - **No `baseline.md` / baseline skipped** → you cannot classify. List all failures and say plainly they're untriaged. Do NOT assert "existing tests pass" or call anything "pre-existing" without a baseline to back it.
88
+
89
+ The rule: a failure is "pre-existing" only if it's in `baseline.md`. Otherwise it's the change's. Full protocol: `../references/test-baseline.md`.
90
+
79
91
  ### 3.D Test Quality Intelligence
80
92
 
81
93
  Go beyond "does a step definition exist?" to "would this test catch a real bug?"
@@ -236,8 +248,8 @@ Produce a structured report:
236
248
 
237
249
  ### 8. Recommend Next Steps
238
250
  Based on the report:
239
- - **All clear** → recommend archiving the change
240
- - **Critical issues** → must fix before archiving
251
+ - **All clear** → recommend committing and opening a PR (git diff is the staging area, the PR is the changelog)
252
+ - **Critical issues** → must fix before committing
241
253
  - **Warnings only** → user decides whether to fix or accept
242
254
  - **Dead features found** → suggest a removal change or updating the features
243
255
 
@@ -251,6 +263,6 @@ Based on the report:
251
263
 
252
264
  ## Done
253
265
  When the verification report is presented, the workflow is complete. Suggest next steps based on findings:
254
- - **All clear** → `grimoire archive <change-id>` or `grimoire-pr`
255
- - **Critical issues** → must fix before archiving
266
+ - **All clear** → `grimoire-commit` then `grimoire-pr`
267
+ - **Critical issues** → must fix before committing
256
268
  - **Warnings only** → user decides whether to fix or accept
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: grimoire-vuln-remediate
3
+ description: File the dev work from a vulnerability triage — turn affected findings into tickets in the configured bug tracker, record risk-accepted items with expiry, and stub grimoire changes for non-trivial fixes. Consumes a grimoire-vuln-triage record. Use after triage, when you're ready to action the findings that actually matter.
4
+ compatibility: Designed for Claude Code (or similar products)
5
+ metadata:
6
+ author: kiwi-data
7
+ version: "0.1"
8
+ ---
9
+
10
+ # grimoire-vuln-remediate
11
+
12
+ `grimoire-vuln-triage` decides *what matters*. This skill **files the work** for the findings that survived: it turns `affected` advisories into tickets in the team's configured bug reporting system, records `accept` items in a risk-acceptance register with an expiry, and stubs a grimoire change for fixes too big to be a one-line bump. It never invents urgency — it acts on the triage's verdicts.
13
+
14
+ The split is deliberate: triage classifies (read-only, repeatable), remediate commits to action (writes tickets, branches, registers). Run triage first.
15
+
16
+ ## Triggers
17
+ - After triage: "file these", "create the tickets", "remediate the CVEs", "action the vuln triage"
18
+ - "open tickets for the affected vulnerabilities", "track the risk-accepted ones"
19
+ - User points at a triage record and asks to take it forward
20
+ - Loose match: "vuln remediate", "file vulnerabilities", "security tickets", "remediation plan"
21
+
22
+ ## Routing
23
+ - No triage record yet → `grimoire-vuln-triage` first. Do not file tickets off a raw scanner dump — file only what triage marked `affected`.
24
+ - A fix that's a real code change (new abstraction, behavior change, schema) → stub a change and hand to `grimoire-draft` / `grimoire-plan` / `grimoire-apply`.
25
+ - A confirmed-exploitable code defect a developer will fix immediately → `grimoire-bug` (reproduction-first).
26
+ - Infra follow-ups (base-image bump, secrets-in-image, IaC misconfig from the triage's "Infra follow-ups") → infra board / `grimoire-draft`, not app remediation.
27
+
28
+ ## Prerequisites
29
+ - A triage record at `.grimoire/security/vulns/<run-date>/triage.md` (from `grimoire-vuln-triage`). If the user points at a different path, use it.
30
+ - `.grimoire/config.yaml` — read `bug_trackers` (MCP) for where to file. If `none`, fall back to a local remediation doc.
31
+
32
+ ## Workflow
33
+
34
+ ### 1. Read the triage record
35
+
36
+ Load the triage. Pull the actionable buckets — **ignore `fixed` and `not_affected`** (triage already dismissed them; they are the audit trail, not work):
37
+ - **hotfix-now** — expedited, confidential handling.
38
+ - **next-release** — normal release-cycle work.
39
+ - **accept** — no fix available / low risk → goes to the risk-acceptance register, not a fix ticket.
40
+ - **under_investigation** — file a time-boxed investigation task, not a fix. **Does not enter the risk register** — it isn't a decision yet. When the investigation resolves, re-run remediate so it routes to close / ticket / register.
41
+ - **Infra follow-ups** — route separately (Step 5).
42
+
43
+ Cross-check the record's totals against what you're about to file so nothing is dropped or invented.
44
+
45
+ ### 2. Decide the fix type per affected item
46
+
47
+ For each `affected` advisory, classify the remediation so it routes correctly:
48
+ - **Trivial bump** — a patch/minor version with a fix exists (`upgrade X 1.2.3 → 1.2.4`), no API break. Can be a direct PR or a simple ticket.
49
+ - **Non-trivial fix** — major-version bump, code changes, base-image rebuild, or a transitive dep that needs a constraint/override. Needs design → stub a grimoire change (Step 4).
50
+ - **No fix available** — `will_not_fix` / no fixed version. Not a fix ticket → risk-acceptance register with an expiry (Step 3). Never file an "upgrade X" ticket when no fixed version exists.
51
+
52
+ ### 3. File the work into the configured bug reporting system
53
+
54
+ Read `bug_trackers` in `.grimoire/config.yaml`.
55
+
56
+ **If a tracker MCP is configured (Jira / Linear / GitHub):**
57
+ - **Idempotency first** — search the tracker for the CVE/GHSA id before creating anything. If a ticket exists, update it (link the triage, refresh urgency); don't duplicate. Mirror both directions like `grimoire-bug-triage`.
58
+ - **One ticket per advisory** (or per package-upgrade when several CVEs share one bump — group by the fix, not the CVE). Include: id(s), component + version, fixed version / action, urgency, reachability + exposure summary, and a link back to `.grimoire/security/vulns/<run-date>/triage.md`. Set priority from urgency (hotfix-now → highest).
59
+ - **hotfix-now is confidential** — mirror `grimoire-bug-triage` §7. Do **not** post exploit details, reachability specifics, or a step-by-step in a public tracker. If the tracker is public, the ticket states impact + "fix in progress, details held privately"; the detail stays in the local triage record. Notify the security owner out of band. Recommend an expedited branch (non-descriptive name) + out-of-band release.
60
+ - **under_investigation** → a time-boxed task ("confirm reachability of <CVE> in <path> by <date>"), assigned, with the open question from triage.
61
+
62
+ **If `bug_trackers: none`:**
63
+ - Write `.grimoire/security/vulns/<run-date>/remediation.md` — a checklist: one entry per actionable item with `[ ]` checkbox, id(s), action (exact upgrade or change-stub link or accept-ref), urgency, suggested owner, and the triage link. This is the deliverable the team works from until a tracker exists. Tell the user where it is.
64
+
65
+ ### 4. Stub a grimoire change for non-trivial fixes
66
+
67
+ For each non-trivial fix, create `.grimoire/changes/<change-id>/manifest.md` so the normal build workflow takes over:
68
+ - Frontmatter `status: proposed`, plus `source: vuln-triage`, the CVE id(s), and the triage path.
69
+ - **Why**: the vulnerability + why a one-line bump isn't enough (major break, code path affected, transitive constraint).
70
+ - **Scope**: the upgrade/change needed and the blast radius from triage (which code paths touch the vulnerable surface).
71
+ - Point the user at `grimoire-draft` / `grimoire-plan` to continue. Reference the change-id from the ticket so the trail is intact.
72
+
73
+ ### 5. Record risk-accepted items (with expiry)
74
+
75
+ **Register invariant: only a settled `accept` verdict enters the register.** The register means "we triaged this, decided, and consciously accepted the residual risk." Two states must stay out of it:
76
+ - **`under_investigation`** — not decided yet. It gets an investigation task (Step 3), nothing in the register. The register's `vex_justification` must be a real VEX code, not "pending"; a finding you can't yet justify hasn't been accepted. When the investigation resolves, *then* it routes — to `not_affected` (close), `affected` (ticket/change), or `accept` (register).
77
+ - **`not_affected`** — already dismissed by triage, deterministically, every scan. It needs no register entry; adding one would bloat the register with the unreachable os-package noise the reachability verdict already suppresses.
78
+
79
+ For every settled `accept` item, append to `.grimoire/security/accepted-risks.yml` (create from the template if absent). Each entry: `cve`, `component`, `vex_justification` (a real code), `reason` (why it's acceptable — reachability/exposure/no-fix), `owner`, `accepted` date, and an **`expires`** date (when to re-triage — sooner for higher residual risk, default ~90 days). An accepted risk is not closed — it's scheduled for re-evaluation.
80
+
81
+ **This register is read back by `grimoire-vuln-triage` during reconciliation** — an unexpired entry auto-suppresses that CVE as a known-accepted, so the same finding doesn't re-flood the queue next scan. An **expired** entry is re-surfaced for re-triage. Don't accept the same CVE twice; update the existing entry.
82
+
83
+ A no-fix os-package finding that is genuinely **`affected` and accepted** (reachable, no patched base yet) belongs here — with `component_type: os-package` and the trace summary from `container-scan-triage.md`. One that is **`not_affected`** (unreachable, like a headless API's GPU/terminal libs) does **not**.
84
+
85
+ ### 6. Optionally execute trivial bumps (skippable)
86
+
87
+ Offer — don't assume — to apply trivial bumps directly: edit the manifest pin, run the lockfile update (`uv lock` / `npm install` / etc.), and run the configured `dep_audit` to confirm the advisory clears. Keep it on a branch. This step is **opt-in**; if the user just wants tickets, file and stop. If you do apply, the supply-chain rules in `security-compliance.md` still hold (committed lockfile + integrity hashes).
88
+
89
+ ### 7. Report and update the record
90
+
91
+ Update the triage record (or a sibling `remediation.md`) with what was filed: ticket refs, change-ids, register entries. Report the headline:
92
+ - N tickets filed (M hotfix-now expedited), K risk-accepted (next review dates), J change stubs, I investigations.
93
+ - Any hotfix-now: restate it's flagged for the security owner and expedited.
94
+ - Where the artifacts are (tracker links / local docs / register).
95
+
96
+ ## Important
97
+ - **Act only on triage verdicts.** This skill files what triage marked `affected` / `accept` / `under_investigation`. It does not re-triage, re-rank, or escalate on its own. If a verdict looks wrong, send it back to `grimoire-vuln-triage`, don't override it here.
98
+ - **No fixed version → no upgrade ticket.** A `will_not_fix` / no-fix finding goes to the risk register with an expiry, or to infra for a base bump. Filing "upgrade X" when X has no fix wastes a developer's time.
99
+ - **Group by the fix, not the CVE.** One upgrade often clears several advisories — one ticket, listing all the CVEs it resolves.
100
+ - **hotfix-now is confidential.** No exploit detail in public trackers; impact-only, details local, security owner notified out of band, expedited branch.
101
+ - **Idempotent.** Search before filing; update existing tickets and register entries instead of duplicating. Sync local ↔ tracker both ways.
102
+ - **`accept` carries an expiry and feeds back into triage.** The register is the loop that stops accepted noise from re-flooding every scan — and re-surfaces it when the expiry passes.
103
+ - **The register holds only settled `accept` verdicts.** `under_investigation` gets an investigation task, never a register entry (it isn't decided); `not_affected` is already suppressed by triage's reachability verdict each run. Keep the invariant clean: register = decided + accepted, with a real VEX justification.
104
+ - **Steps are skippable.** Filing, change-stubbing, and direct bumps are independent — do what the user asked for and stop.
105
+
106
+ ## Done
107
+ When every actionable triage finding has a home — a ticket (or remediation.md entry), a change stub, or a risk-register entry with an expiry — and the triage record reflects what was filed, remediation is complete. Hotfix-now items are flagged and confidential; accepted items are scheduled for re-triage.