@kiwidata/grimoire 0.1.1

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 (215) hide show
  1. package/.claude-plugin/plugin.json +8 -0
  2. package/AGENTS.md +217 -0
  3. package/README.md +748 -0
  4. package/bin/grimoire.js +2 -0
  5. package/dist/cli/index.d.ts +2 -0
  6. package/dist/cli/index.d.ts.map +1 -0
  7. package/dist/cli/index.js +42 -0
  8. package/dist/cli/index.js.map +1 -0
  9. package/dist/commands/archive.d.ts +3 -0
  10. package/dist/commands/archive.d.ts.map +1 -0
  11. package/dist/commands/archive.js +22 -0
  12. package/dist/commands/archive.js.map +1 -0
  13. package/dist/commands/branch-check.d.ts +3 -0
  14. package/dist/commands/branch-check.d.ts.map +1 -0
  15. package/dist/commands/branch-check.js +16 -0
  16. package/dist/commands/branch-check.js.map +1 -0
  17. package/dist/commands/check.d.ts +3 -0
  18. package/dist/commands/check.d.ts.map +1 -0
  19. package/dist/commands/check.js +22 -0
  20. package/dist/commands/check.js.map +1 -0
  21. package/dist/commands/ci.d.ts +3 -0
  22. package/dist/commands/ci.d.ts.map +1 -0
  23. package/dist/commands/ci.js +18 -0
  24. package/dist/commands/ci.js.map +1 -0
  25. package/dist/commands/diff.d.ts +3 -0
  26. package/dist/commands/diff.d.ts.map +1 -0
  27. package/dist/commands/diff.js +10 -0
  28. package/dist/commands/diff.js.map +1 -0
  29. package/dist/commands/docs.d.ts +3 -0
  30. package/dist/commands/docs.d.ts.map +1 -0
  31. package/dist/commands/docs.js +11 -0
  32. package/dist/commands/docs.js.map +1 -0
  33. package/dist/commands/health.d.ts +3 -0
  34. package/dist/commands/health.d.ts.map +1 -0
  35. package/dist/commands/health.js +13 -0
  36. package/dist/commands/health.js.map +1 -0
  37. package/dist/commands/init.d.ts +3 -0
  38. package/dist/commands/init.d.ts.map +1 -0
  39. package/dist/commands/init.js +21 -0
  40. package/dist/commands/init.js.map +1 -0
  41. package/dist/commands/list.d.ts +3 -0
  42. package/dist/commands/list.d.ts.map +1 -0
  43. package/dist/commands/list.js +22 -0
  44. package/dist/commands/list.js.map +1 -0
  45. package/dist/commands/log.d.ts +3 -0
  46. package/dist/commands/log.d.ts.map +1 -0
  47. package/dist/commands/log.js +15 -0
  48. package/dist/commands/log.js.map +1 -0
  49. package/dist/commands/map.d.ts +3 -0
  50. package/dist/commands/map.d.ts.map +1 -0
  51. package/dist/commands/map.js +17 -0
  52. package/dist/commands/map.js.map +1 -0
  53. package/dist/commands/pr.d.ts +3 -0
  54. package/dist/commands/pr.d.ts.map +1 -0
  55. package/dist/commands/pr.js +17 -0
  56. package/dist/commands/pr.js.map +1 -0
  57. package/dist/commands/status.d.ts +3 -0
  58. package/dist/commands/status.d.ts.map +1 -0
  59. package/dist/commands/status.js +12 -0
  60. package/dist/commands/status.js.map +1 -0
  61. package/dist/commands/test-quality.d.ts +3 -0
  62. package/dist/commands/test-quality.d.ts.map +1 -0
  63. package/dist/commands/test-quality.js +37 -0
  64. package/dist/commands/test-quality.js.map +1 -0
  65. package/dist/commands/trace.d.ts +3 -0
  66. package/dist/commands/trace.d.ts.map +1 -0
  67. package/dist/commands/trace.js +12 -0
  68. package/dist/commands/trace.js.map +1 -0
  69. package/dist/commands/update.d.ts +3 -0
  70. package/dist/commands/update.d.ts.map +1 -0
  71. package/dist/commands/update.js +22 -0
  72. package/dist/commands/update.js.map +1 -0
  73. package/dist/commands/validate.d.ts +3 -0
  74. package/dist/commands/validate.d.ts.map +1 -0
  75. package/dist/commands/validate.js +17 -0
  76. package/dist/commands/validate.js.map +1 -0
  77. package/dist/core/archive.d.ts +9 -0
  78. package/dist/core/archive.d.ts.map +1 -0
  79. package/dist/core/archive.js +92 -0
  80. package/dist/core/archive.js.map +1 -0
  81. package/dist/core/branch-check.d.ts +27 -0
  82. package/dist/core/branch-check.d.ts.map +1 -0
  83. package/dist/core/branch-check.js +205 -0
  84. package/dist/core/branch-check.js.map +1 -0
  85. package/dist/core/check.d.ts +24 -0
  86. package/dist/core/check.d.ts.map +1 -0
  87. package/dist/core/check.js +372 -0
  88. package/dist/core/check.js.map +1 -0
  89. package/dist/core/ci.d.ts +24 -0
  90. package/dist/core/ci.d.ts.map +1 -0
  91. package/dist/core/ci.js +162 -0
  92. package/dist/core/ci.js.map +1 -0
  93. package/dist/core/detect.d.ts +10 -0
  94. package/dist/core/detect.d.ts.map +1 -0
  95. package/dist/core/detect.js +368 -0
  96. package/dist/core/detect.js.map +1 -0
  97. package/dist/core/diff.d.ts +29 -0
  98. package/dist/core/diff.d.ts.map +1 -0
  99. package/dist/core/diff.js +197 -0
  100. package/dist/core/diff.js.map +1 -0
  101. package/dist/core/doc-style.d.ts +16 -0
  102. package/dist/core/doc-style.d.ts.map +1 -0
  103. package/dist/core/doc-style.js +192 -0
  104. package/dist/core/doc-style.js.map +1 -0
  105. package/dist/core/docs.d.ts +6 -0
  106. package/dist/core/docs.d.ts.map +1 -0
  107. package/dist/core/docs.js +478 -0
  108. package/dist/core/docs.js.map +1 -0
  109. package/dist/core/health.d.ts +7 -0
  110. package/dist/core/health.d.ts.map +1 -0
  111. package/dist/core/health.js +489 -0
  112. package/dist/core/health.js.map +1 -0
  113. package/dist/core/hooks.d.ts +5 -0
  114. package/dist/core/hooks.d.ts.map +1 -0
  115. package/dist/core/hooks.js +168 -0
  116. package/dist/core/hooks.js.map +1 -0
  117. package/dist/core/init.d.ts +9 -0
  118. package/dist/core/init.d.ts.map +1 -0
  119. package/dist/core/init.js +563 -0
  120. package/dist/core/init.js.map +1 -0
  121. package/dist/core/list.d.ts +4 -0
  122. package/dist/core/list.d.ts.map +1 -0
  123. package/dist/core/list.js +170 -0
  124. package/dist/core/list.js.map +1 -0
  125. package/dist/core/log.d.ts +8 -0
  126. package/dist/core/log.d.ts.map +1 -0
  127. package/dist/core/log.js +150 -0
  128. package/dist/core/log.js.map +1 -0
  129. package/dist/core/map.d.ts +9 -0
  130. package/dist/core/map.d.ts.map +1 -0
  131. package/dist/core/map.js +302 -0
  132. package/dist/core/map.js.map +1 -0
  133. package/dist/core/pr.d.ts +9 -0
  134. package/dist/core/pr.d.ts.map +1 -0
  135. package/dist/core/pr.js +273 -0
  136. package/dist/core/pr.js.map +1 -0
  137. package/dist/core/shared-setup.d.ts +52 -0
  138. package/dist/core/shared-setup.d.ts.map +1 -0
  139. package/dist/core/shared-setup.js +221 -0
  140. package/dist/core/shared-setup.js.map +1 -0
  141. package/dist/core/status.d.ts +6 -0
  142. package/dist/core/status.d.ts.map +1 -0
  143. package/dist/core/status.js +114 -0
  144. package/dist/core/status.js.map +1 -0
  145. package/dist/core/test-quality.d.ts +33 -0
  146. package/dist/core/test-quality.d.ts.map +1 -0
  147. package/dist/core/test-quality.js +378 -0
  148. package/dist/core/test-quality.js.map +1 -0
  149. package/dist/core/trace.d.ts +6 -0
  150. package/dist/core/trace.d.ts.map +1 -0
  151. package/dist/core/trace.js +211 -0
  152. package/dist/core/trace.js.map +1 -0
  153. package/dist/core/update.d.ts +10 -0
  154. package/dist/core/update.d.ts.map +1 -0
  155. package/dist/core/update.js +149 -0
  156. package/dist/core/update.js.map +1 -0
  157. package/dist/core/validate.d.ts +20 -0
  158. package/dist/core/validate.d.ts.map +1 -0
  159. package/dist/core/validate.js +275 -0
  160. package/dist/core/validate.js.map +1 -0
  161. package/dist/index.d.ts +19 -0
  162. package/dist/index.d.ts.map +1 -0
  163. package/dist/index.js +20 -0
  164. package/dist/index.js.map +1 -0
  165. package/dist/utils/config.d.ts +61 -0
  166. package/dist/utils/config.d.ts.map +1 -0
  167. package/dist/utils/config.js +172 -0
  168. package/dist/utils/config.js.map +1 -0
  169. package/dist/utils/fs.d.ts +17 -0
  170. package/dist/utils/fs.d.ts.map +1 -0
  171. package/dist/utils/fs.js +38 -0
  172. package/dist/utils/fs.js.map +1 -0
  173. package/dist/utils/paths.d.ts +10 -0
  174. package/dist/utils/paths.d.ts.map +1 -0
  175. package/dist/utils/paths.js +35 -0
  176. package/dist/utils/paths.js.map +1 -0
  177. package/dist/utils/spawn.d.ts +5 -0
  178. package/dist/utils/spawn.d.ts.map +1 -0
  179. package/dist/utils/spawn.js +34 -0
  180. package/dist/utils/spawn.js.map +1 -0
  181. package/package.json +68 -0
  182. package/skills/grimoire-apply/SKILL.md +274 -0
  183. package/skills/grimoire-audit/SKILL.md +129 -0
  184. package/skills/grimoire-branch-guard/SKILL.md +111 -0
  185. package/skills/grimoire-bug/SKILL.md +160 -0
  186. package/skills/grimoire-bug-explore/SKILL.md +242 -0
  187. package/skills/grimoire-bug-report/SKILL.md +237 -0
  188. package/skills/grimoire-bug-session/SKILL.md +222 -0
  189. package/skills/grimoire-bug-triage/SKILL.md +274 -0
  190. package/skills/grimoire-commit/SKILL.md +150 -0
  191. package/skills/grimoire-discover/SKILL.md +297 -0
  192. package/skills/grimoire-draft/SKILL.md +202 -0
  193. package/skills/grimoire-plan/SKILL.md +329 -0
  194. package/skills/grimoire-pr/SKILL.md +134 -0
  195. package/skills/grimoire-pr-review/SKILL.md +240 -0
  196. package/skills/grimoire-refactor/SKILL.md +251 -0
  197. package/skills/grimoire-remove/SKILL.md +112 -0
  198. package/skills/grimoire-review/SKILL.md +247 -0
  199. package/skills/grimoire-verify/SKILL.md +223 -0
  200. package/skills/references/bug-classification.md +154 -0
  201. package/skills/references/build-vs-buy.md +77 -0
  202. package/skills/references/elicitation-personas.md +118 -0
  203. package/skills/references/refactor-register-format.md +88 -0
  204. package/skills/references/refactor-scan-categories.md +102 -0
  205. package/skills/references/schema-format.md +68 -0
  206. package/skills/references/security-compliance.md +110 -0
  207. package/skills/references/testing-contracts.md +93 -0
  208. package/templates/context.yml +110 -0
  209. package/templates/debt-exceptions.yml +61 -0
  210. package/templates/decision.md +50 -0
  211. package/templates/dupignore +93 -0
  212. package/templates/example.feature +24 -0
  213. package/templates/manifest.md +29 -0
  214. package/templates/mapignore +58 -0
  215. package/templates/mapkeys +65 -0
@@ -0,0 +1,77 @@
1
+ # Build vs Buy Research
2
+
3
+ Research methodology for evaluating existing solutions before designing custom code. Used by draft (conduct research), plan (validate decision), review (check prior art).
4
+
5
+ ## When to Research
6
+
7
+ - **Level 1 (Trivial)**: Skip entirely
8
+ - **Level 2 (Simple)**: Check built-ins and first-party ecosystem only
9
+ - **Level 3-4 (Moderate/Complex)**: Full research across all categories
10
+
11
+ ## Research Categories
12
+
13
+ Search for existing solutions across these categories (skip categories that clearly don't apply):
14
+
15
+ - **Language/framework built-ins**: Does the framework already have this? (e.g., Django has auth, React has context, Express has middleware). Check official docs.
16
+ - **First-party ecosystem**: Official plugins, extensions, or companion packages from the framework maintainers.
17
+ - **Popular libraries**: Search the relevant package registry (npm, PyPI, crates.io, etc.) for well-maintained packages. Use web search to find comparison articles, "best of" lists, and Stack Overflow recommendations.
18
+ - **Open-source projects**: GitHub repos that solve the same problem as a standalone tool or reference implementation.
19
+ - **SaaS/managed services**: Hosted solutions that handle the problem as a service (e.g., Auth0 for auth, Stripe for payments, Algolia for search).
20
+
21
+ For each candidate found, gather:
22
+ - **Name and link** to docs/repo
23
+ - **Maintenance signals**: last release date, commit frequency, open issues, download count
24
+ - **Fit**: does it match the project's language, framework, and deployment constraints?
25
+ - **Scope match**: does it solve 100% of the need, 80%, or just a part?
26
+ - **Trade-offs**: what design decisions does it impose? What would the project give up by adopting it?
27
+
28
+ ## Decision Framework
29
+
30
+ | Signal | Points toward **adopt** | Points toward **build** |
31
+ |--------|------------------------|------------------------|
32
+ | Scope match | Solves ≥80% of the need | Solves <50% or forces unwanted constraints |
33
+ | Maintenance | Active, >1 maintainer, regular releases | Abandoned, single maintainer, or unmaintained fork |
34
+ | Integration cost | Drop-in or <1 day to integrate | Requires significant adapter code or workarounds |
35
+ | Customization | Configurable or extensible where needed | Core behavior can't be changed without forking |
36
+ | Dependencies | Few, well-known transitive deps | Heavy dependency tree or conflicts with project deps |
37
+ | Security | Audited, follows best practices, no known CVEs | Unaudited, handles sensitive data unsafely |
38
+ | Licensing | Compatible with project license | Incompatible or ambiguous license |
39
+ | Project constraints | Fits deployment target, bundle size, performance needs | Doesn't fit runtime environment or adds unacceptable overhead |
40
+
41
+ When the decision is close, **prefer adopting** — maintaining custom code is almost always more expensive than people expect.
42
+
43
+ ## If Building: Learn from What Exists
44
+
45
+ When the decision is to build custom code, **study existing implementations before designing**:
46
+
47
+ - **Document the prior art**: For each relevant existing tool, note its architecture, data flows, API design, and key abstractions. What patterns does it use? What did its maintainers learn over time (check changelogs, migration guides, design docs)?
48
+ - **Identify what's different**: Be precise about why the project's needs diverge. "We need something different" is not enough — state the specific requirements that existing tools don't meet.
49
+ - **Borrow deliberately**: List specific design patterns, data flow approaches, API shapes, or architectural decisions from existing tools that should inform the custom implementation. This prevents reinventing what others have already refined.
50
+ - **Scope the custom work**: Define the minimum viable version. If an existing tool does 10 things and you only need 3, build those 3. Don't replicate the full feature set.
51
+
52
+ ## Present Findings Format
53
+
54
+ Present a structured summary **before drafting any artifacts**:
55
+
56
+ ```markdown
57
+ ## Prior Art Research
58
+
59
+ ### Existing Solutions Found
60
+ 1. **[name]** — [one-line description]. [fit assessment]. [key trade-off].
61
+ 2. **[name]** — ...
62
+
63
+ ### Recommendation
64
+ - **Adopt [name]** because [reasons] → draft becomes an ADR documenting the adoption
65
+ - OR **Build custom** because [specific gaps: requirement X isn't met by any option, constraint Y rules out adoption]. Borrowing [patterns/flows] from [existing tool].
66
+ - OR **Hybrid**: adopt [name] for [scope] and build custom [scope] because [reasons]
67
+
68
+ ### If Building: What Makes This Different
69
+ - [Requirement that no existing tool meets]
70
+ - [Constraint that rules out adoption]
71
+ - [Design decision that must differ from prior art, and why]
72
+
73
+ ### If Building: Borrowed from Prior Art
74
+ - [Pattern/flow/API shape] from [tool] — because [reason it's proven]
75
+ ```
76
+
77
+ Wait for user agreement on the direction before proceeding.
@@ -0,0 +1,118 @@
1
+ # Elicitation Personas
2
+
3
+ Persona-driven questions to surface requirements. Used by draft (gather requirements), plan (check completeness), review (evaluate design).
4
+
5
+ ## How to Use
6
+
7
+ - **In draft**: Ask these questions to gather requirements before drafting.
8
+ - **In plan**: Use as a completeness checklist — flag gaps in the specs, don't ask the user.
9
+ - **In review**: Use as evaluation criteria — check if the design addresses each concern.
10
+
11
+ ## Depth by Complexity Level
12
+
13
+ | Level | Depth |
14
+ |-------|-------|
15
+ | 1 (Trivial) | Skip entirely |
16
+ | 2 (Simple) | Outcome + non-goals, then 1-3 targeted questions from the most relevant persona |
17
+ | 3 (Moderate) | Outcome + non-goals, then applicable personas in a single focused batch |
18
+ | 4 (Complex) | Outcome + non-goals, then all applicable personas in batches of 3-5, wait between batches |
19
+
20
+ Don't ask every question — only ask questions whose answers aren't already clear.
21
+
22
+ ## Outcome & Scope — Always Ask First
23
+
24
+ Before diving into persona questions, establish the outcome and boundaries. These two questions prevent the most common spec failures — building the wrong thing and building too much:
25
+
26
+ - **Outcome**: What problem are you solving, and how will you know it's solved? What does the user or system look like *after* this change that's different from today?
27
+ - **Non-goals**: What is explicitly out of scope? What should this change NOT do, NOT handle, or NOT affect? Are there adjacent features, edge cases, or future plans that we should deliberately leave alone?
28
+
29
+ Record the answers. Non-goals become constraints in the manifest and guard rails during drafting — if a scenario starts creeping into a non-goal, stop and flag it.
30
+
31
+ ## Product Manager — Functional Completeness
32
+
33
+ Ask when: the change has user-facing behavior.
34
+
35
+ - Who are the actors? Is there more than one user role involved? Do they see/do different things?
36
+ - What triggers this — user action, scheduled job, external event, or another system?
37
+ - What does success look like from the user's perspective? What do they see/receive?
38
+ - What are the business rules? Validation constraints, conditional logic, calculations, limits?
39
+ - What happens when the user makes a mistake? Invalid input, wrong state, missing data?
40
+ - Are there state transitions? What states can this entity be in, and what moves it between them?
41
+ - Is there a UI component? What does each state look like — loading, empty, error, success, partial?
42
+ - *(If UI)* Do you have designs or mockups? Check `.grimoire/config.yaml` under `project.design_tool` for where designs live. Ask the user to point to the specific screen/flow — reference it in the requirements summary so downstream skills can consult it.
43
+ - Does this interact with existing features? Could it conflict with or depend on other workflows?
44
+ - Does this need to support multiple languages or locales? If so, which ones?
45
+ - What accessibility standard applies? (WCAG 2.1 AA is the most common default. If the project has no standard, ask.)
46
+
47
+ ## Senior Engineer — Architecture & Integration
48
+
49
+ Ask when: the change introduces new components, services, dependencies, or data flows.
50
+
51
+ - What's the deployment context? Does this run in the same service or cross service boundaries?
52
+ - What existing components does this touch? Are there shared modules, APIs, or databases involved?
53
+ - Are there concurrency concerns? Multiple users or processes acting on the same data?
54
+ - What's the data flow? Where does data enter, how is it transformed, where does it end up?
55
+ - Are there ordering or idempotency requirements? What happens if this runs twice?
56
+ - Does this need to be backwards-compatible with existing clients, APIs, or data formats?
57
+ - Is there a rollout concern? Can this be deployed incrementally, or is it all-or-nothing? Feature flag needed?
58
+ - What are the performance expectations? Response time target, expected throughput, data volume at scale?
59
+ - How will you observe this in production? What metrics, logs, or alerts should exist? What does "healthy" look like on a dashboard?
60
+ - What's the availability target? What happens during partial outages — degrade gracefully or fail fast?
61
+ - *(If adopting)* What customization or configuration does the library need for this project's constraints?
62
+ - *(If adopting)* Where does the library's responsibility end and custom code begin?
63
+
64
+ ## Security Engineer — Security & Compliance
65
+
66
+ Ask when: the change involves authentication, authorization, user input, sensitive data, or external-facing endpoints.
67
+
68
+ - Who should have access to this? Are there roles, permissions, or ownership rules?
69
+ - Does this handle sensitive data (PII, credentials, financial, health)? Where is it stored and transmitted?
70
+ - Is there user-provided input? What's the attack surface — injection, XSS, CSRF, file upload?
71
+ - Are there compliance requirements (GDPR, HIPAA, PCI-DSS, SOC2)? Data residency or retention rules?
72
+ - Does this cross a trust boundary? Is data coming from an external system or untrusted source?
73
+
74
+ ## QA Engineer — Testability & Edge Cases
75
+
76
+ Ask when: the change has complex behavior, multiple paths, or integration points.
77
+
78
+ - What are the boundary values? Min/max lengths, zero vs. one, empty collections, null states?
79
+ - What are the timing edge cases? Concurrent edits, race conditions, timeout during processing?
80
+ - What external dependencies could fail? How should the system behave when they do — retry, fallback, error?
81
+ - Is there existing behavior that could regress? What should still work exactly as before?
82
+
83
+ ## Data Engineer — Data & Schema
84
+
85
+ Ask when: the change creates, modifies, or removes data models, or integrates with external APIs.
86
+
87
+ - What data entities are involved? What are the relationships between them?
88
+ - What are the field constraints? Required, unique, nullable, max length, valid ranges, enums?
89
+ - How does this data grow? Is there a retention policy, archival strategy, or cleanup needed?
90
+ - Is there existing data that needs migrating? Can the migration run live or does it need downtime?
91
+ - Are there external API contracts? What fields does the client read, and what happens if the schema changes?
92
+
93
+ ## Requirements Summary Template
94
+
95
+ After elicitation, summarize what you learned in a short **Requirements Summary**. This becomes the foundation for scenarios and decisions. Format:
96
+
97
+ ```markdown
98
+ ## Requirements Summary
99
+
100
+ **Outcome**: [what problem this solves, how we'll know it's solved]
101
+ **Non-goals**: [what's explicitly out of scope — won't do, won't handle, won't affect]
102
+ **Actors**: [who]
103
+ **Trigger**: [what starts this]
104
+ **Happy path**: [what success looks like]
105
+ **Business rules**: [validation, constraints, logic]
106
+ **Error cases**: [what can go wrong]
107
+ **Data**: [what's created/modified, key constraints]
108
+ **Security**: [access control, sensitive data, compliance]
109
+ **Performance**: [response time, throughput, data volume targets — if applicable]
110
+ **Observability**: [key metrics, alerts, what "healthy" looks like — if applicable]
111
+ **Availability**: [uptime target, degradation strategy — if applicable]
112
+ **Accessibility**: [WCAG level, requirements — if applicable]
113
+ **i18n**: [supported locales — if applicable]
114
+ **Design reference**: [link to mockup/design, or "none" — if UI change]
115
+ **Open questions**: [anything the user couldn't answer yet — flag as unvalidated assumptions]
116
+ ```
117
+
118
+ Wait for user confirmation of the summary before proceeding to draft.
@@ -0,0 +1,88 @@
1
+ # Debt Register Format
2
+
3
+ Reference for `grimoire-refactor` step 4. The register is `.grimoire/docs/debt-register.yml`.
4
+
5
+ ## Required Fields
6
+
7
+ - `id` — `debt-NNN`, monotonically increasing
8
+ - `category` — one of: `hotspot`, `structural_bloat`, `data_structure`, `circular_dependency`, `dependency_staleness`, `broken_promise`, `duplication`, `dead_code`, `test_debt`
9
+ - `severity` — `high`, `medium`, `low`
10
+ - `location` — file path (with optional `:line`), or `path <> path` for relationships
11
+ - `title` — short human-readable summary
12
+ - `detail` — evidence: what was measured, what threshold was exceeded, consequences
13
+ - `fingerprint` — `sha256(category + normalized_location)` for dedup across scans
14
+ - `status` — `open` | `triaged` | `in-progress` | `resolved` | `accepted`
15
+
16
+ ## Optional Fields
17
+
18
+ - `metrics` — numeric measurements (churn count, complexity score, line count, etc.)
19
+ - `suggestion` — recommended refactoring approach
20
+ - `effort` — `small` (<1 hour), `medium` (1-4 hours), `large` (>4 hours)
21
+ - `consequences` — what happens if NOT addressed (forces articulation of impact)
22
+ - `causes` — `evolution`, `deadline`, `knowledge`, `dependency`
23
+ - `quadrant` — Fowler's: `deliberate-prudent`, `deliberate-reckless`, `inadvertent-prudent`, `inadvertent-reckless`
24
+ - `change_id` — grimoire change created to address this item
25
+ - `first_detected` / `last_detected` — date tracking
26
+
27
+ ## Example
28
+
29
+ ```yaml
30
+ # Grimoire Debt Register
31
+ # Generated by /grimoire:refactor
32
+ # Last scanned: 2026-04-06
33
+
34
+ summary:
35
+ total: 12
36
+ high: 3
37
+ medium: 5
38
+ low: 4
39
+ open: 9
40
+ accepted: 2
41
+ in_progress: 1
42
+ resolved: 0
43
+
44
+ items:
45
+ - id: debt-001
46
+ fingerprint: a1b2c3d4
47
+ category: hotspot
48
+ severity: high
49
+ location: src/api/views.py
50
+ title: "High-churn, high-complexity API view module"
51
+ detail: "38 commits in 6 months, cyclomatic complexity 24. Handles 12 endpoints with mixed concerns."
52
+ consequences: "Every API change requires understanding 847 lines. Bug rate 3x project average."
53
+ causes: evolution
54
+ metrics: { churn: 38, complexity: 24, lines: 847 }
55
+ suggestion: "Split by resource: UserViews, OrderViews, ProductViews. Extract validation."
56
+ effort: medium
57
+ status: open
58
+ first_detected: 2026-04-06
59
+ last_detected: 2026-04-06
60
+
61
+ - id: debt-002
62
+ fingerprint: c9d0e1f2
63
+ category: data_structure
64
+ severity: medium
65
+ location: src/types/config.ts
66
+ title: "AppConfig interface with 28 optional fields"
67
+ detail: "28 fields, 22 optional. Used in 3 different contexts."
68
+ consequences: "Every consumer must null-check fields always present in its context."
69
+ causes: evolution
70
+ metrics: { fields: 28, optional_ratio: 0.79 }
71
+ suggestion: "Split into ServerConfig, ClientConfig, CLIConfig with shared BaseConfig."
72
+ effort: medium
73
+ status: accepted
74
+ quadrant: deliberate-prudent
75
+ exception_reason: "Splitting would break plugin API. Revisit in Q4."
76
+ first_detected: 2026-04-06
77
+ last_detected: 2026-04-06
78
+ ```
79
+
80
+ ## Register Rules
81
+
82
+ - Status lifecycle: `open` -> `triaged` -> `in-progress` -> `resolved` (or `accepted` via exception)
83
+ - `first_detected` set once, never updated. `last_detected` updated each scan.
84
+ - Items matched by exception: `status: accepted` with `quadrant` and `exception_reason`
85
+ - Expired exceptions: revert to `status: open` with note in detail
86
+ - `consequences` forces articulation of real impact, not just code aesthetics
87
+ - On refresh: match by fingerprint, preserve status/first_detected, update last_detected/metrics, mark undetected items as `resolved`
88
+ - Sort: severity (high first), then hotspot score within severity
@@ -0,0 +1,102 @@
1
+ # Refactor Scan Categories
2
+
3
+ Reference for `grimoire-refactor` step 2. Each category produces findings with a category, location, severity, and suggested action.
4
+
5
+ ## 2a. Hotspots (churn x complexity)
6
+
7
+ Files that change frequently AND are hard to change. Highest-ROI refactoring targets.
8
+
9
+ **How to scan:**
10
+ 1. Change frequency: `git log --format=format: --name-only --since="6 months ago" | sort | uniq -c | sort -rn | head -50`
11
+ 2. Complexity: run `config.tools.complexity` (configured during init — e.g., radon, eslint complexity plugin, or line count + nesting depth as proxy)
12
+ 3. Multiply: `churn_rank x complexity_rank = hotspot_score`
13
+ 4. Top 10-20 files by hotspot score are targets
14
+
15
+ **Severity:** high = top 5 (churn >20 AND complexity above threshold), medium = 6-15, low = 16+
16
+
17
+ ## 2b. Structural Bloat
18
+
19
+ | Signal | Threshold | Meaning |
20
+ |---|---|---|
21
+ | Oversized files | >300 lines (Python), >500 (TS/JS), >400 (Go) | File does too much — split |
22
+ | Long functions | >50 lines or >4 nesting levels | Extract or flatten |
23
+ | God classes | >10 public methods or >500 lines | Split by responsibility |
24
+ | Too many exports | >15 from one module | Grab bag, not a module |
25
+ | Deep nesting | >4 levels of indentation in logic | Guard clauses, extract, pipeline |
26
+ | Wrapper-only layers | Function body is a single delegation call | Inline or remove |
27
+ | Large switch/if-else | >5 branches | Lookup table, strategy, polymorphism |
28
+
29
+ **Severity:** high = 2x+ threshold, medium = 1-2x, low = marginally over
30
+
31
+ ## 2c. Data Structure Complexity
32
+
33
+ | Signal | Meaning |
34
+ |---|---|
35
+ | Models >15 fields | Represents multiple concepts — split |
36
+ | >3 nesting levels | Flatten or normalize |
37
+ | Type unions >4 variants | Separate types or polymorphism |
38
+ | >70% field overlap between types | Consolidate or extract shared base |
39
+ | Config with conditional logic | Business logic hiding as config |
40
+ | >50% optional fields | God DTO serving multiple use cases |
41
+ | Enums >10 values | Proper type hierarchy |
42
+
43
+ **How to scan:** Read `schema.yml` if exists, scan ORM models / interfaces / dataclasses, count fields and nesting.
44
+
45
+ **Severity:** high = >25 fields or >4 nesting, medium = 15-25 or 3-4 nesting, low = structural smell but manageable
46
+
47
+ ## 2d. Circular Dependencies
48
+
49
+ **How to scan:**
50
+ - JS/TS: `dependency-cruiser` or `madge` if available, else trace imports from area docs
51
+ - Python: trace imports, look for `TYPE_CHECKING` blocks (circular import workaround signal)
52
+ - Go: circular imports are compile errors — look for oversized packages to split
53
+
54
+ **Severity:** high = >3 modules or crosses architecture boundaries, medium = 2-module cycles, low = within single area
55
+
56
+ ## 2e. Dependency Staleness
57
+
58
+ **How to scan:** Run `config.tools.dep_audit` if configured, or:
59
+ - Node: `npm outdated --json`
60
+ - Python: `pip list --outdated --format=json`
61
+ - Count major versions behind, check last publish date
62
+
63
+ **Severity:** high = >2 major versions behind or unmaintained (2+ years no release), medium = 1-2 major behind, low = minor/patch behind
64
+
65
+ ## 2f. Broken Promises
66
+
67
+ TODO/FIXME/HACK/XXX comments that have aged.
68
+
69
+ **How to scan:**
70
+ 1. Find comments: `grep -rn 'TODO\|FIXME\|HACK\|XXX' --include="*.py" --include="*.ts" --include="*.js" --include="*.go" ...`
71
+ 2. Age from `git blame` — when was this line last touched?
72
+ 3. Older = higher priority
73
+
74
+ **Severity:** high = >1 year old, medium = 3 months to 1 year, low = <3 months
75
+
76
+ ## 2g. Duplication
77
+
78
+ **How to scan:**
79
+ - Read `.grimoire/docs/.snapshot.json` `duplicates` section if present
80
+ - Or run `config.tools.duplicates` if configured (e.g., jscpd)
81
+ - Group by area — within-area dupes are easy to consolidate
82
+
83
+ **Severity:** high = >30 lines or >3 copies, medium = 10-30 lines or 2 copies, low = <10 lines
84
+
85
+ ## 2h. Dead Code
86
+
87
+ **How to scan:**
88
+ - Run `config.tools.dead_code` if configured (e.g., knip, vulture)
89
+ - Cross-reference area docs' reusable code tables (in table but never imported = dead)
90
+ - If `codebase-memory-mcp` available: `query_graph` for functions with zero callers
91
+
92
+ **Severity:** high = entire unused modules/classes, medium = unused exported functions, low = unused imports/variables
93
+
94
+ ## 2i. Test Debt
95
+
96
+ **How to scan:**
97
+ - Get coverage report if available — files <50% coverage
98
+ - Cross-reference with complexity — high complexity + low coverage = dangerous
99
+ - Check for trivial assertions (`assert True`, `expect(true).toBe(true)`)
100
+ - Check for over-mocked tests (testing mocks, not behavior)
101
+
102
+ **Severity:** high = complex code (top quartile) with <30% coverage, medium = moderate complexity with <50%, low = simple code with low coverage
@@ -0,0 +1,68 @@
1
+ # Data Schema Format
2
+
3
+ Reference for `grimoire-discover` step 5. The schema is `.grimoire/docs/data/schema.yml`.
4
+
5
+ ## Format
6
+
7
+ ```yaml
8
+ # Grimoire Data Schema
9
+ # Auto-generated by /grimoire:discover
10
+ # Last updated: YYYY-MM-DD
11
+ # Source: <what was scanned>
12
+
13
+ users:
14
+ type: table # table | collection | document | external_api
15
+ source: src/models/user.py:12 # where defined in code
16
+ note: "Core user identity" # optional context
17
+ fields:
18
+ id: { type: integer, pk: true }
19
+ email: { type: varchar, unique: true, not_null: true }
20
+ role:
21
+ type: enum
22
+ values: [admin, member, guest]
23
+ default: member
24
+ preferences: # nested (Mongo, JSON column, etc.)
25
+ type: object
26
+ fields:
27
+ theme: { type: string, default: "light" }
28
+ indexes:
29
+ - fields: [email]
30
+ unique: true
31
+ relationships:
32
+ - type: has_many
33
+ target: posts
34
+ foreign_key: author_id
35
+
36
+ # --- External APIs ---
37
+ stripe_payments:
38
+ type: external_api
39
+ provider: Stripe
40
+ schema_ref: https://stripe.com/docs/api/charges # full spec location
41
+ client: src/integrations/stripe.py # where we call it
42
+ auth: api_key
43
+ endpoints:
44
+ create_charge:
45
+ method: POST
46
+ path: /v1/charges
47
+ fields:
48
+ amount: { type: integer, note: "in cents" }
49
+ currency: { type: string }
50
+ response:
51
+ id: { type: string }
52
+ status: { type: string, enum: [succeeded, failed] }
53
+ error_response:
54
+ message: { type: string }
55
+ ```
56
+
57
+ ## Rules
58
+
59
+ - Document what exists in the code, not what the database contains
60
+ - `source:` points to ORM model or migration file — schema.yml is a summary, code is truth
61
+ - `type:` — `table` for SQL, `collection` for Mongo/document, `document` for nested sub-documents, `external_api` for consumed APIs
62
+ - Nested `fields` for embedded objects/arrays (document DBs, JSON columns)
63
+ - `note:` only when field name isn't self-explanatory
64
+ - `relationships` when ORM defines them explicitly
65
+ - For external APIs: `schema_ref` is most important — point to the full spec
66
+ - For external APIs: `client` points to where the codebase calls the API
67
+ - Don't duplicate entire OpenAPI specs — summarize endpoints you actually use, point to full spec via `schema_ref`
68
+ - If project has no data layer, skip this step entirely
@@ -0,0 +1,110 @@
1
+ # Security & Compliance Reference
2
+
3
+ Loaded by skills when feature files have security tags or `project.compliance` is configured in `.grimoire/config.yaml`.
4
+
5
+ ## Security Tags
6
+
7
+ Apply these Gherkin tags to scenarios with security implications. Downstream skills (plan, review, verify) use them to enforce stricter checks.
8
+
9
+ | Tag | When to apply |
10
+ |---|---|
11
+ | `@security` | Authentication, authorization, access control, cryptographic operations |
12
+ | `@auth` | Login, logout, session management, token handling, role-based access |
13
+ | `@pii` | Create, read, update, or delete personally identifiable information |
14
+ | `@input-validation` | User input that could be malicious (forms, APIs, file uploads) |
15
+ | `@secrets` | API keys, credentials, tokens, or secret management |
16
+
17
+ ### Compliance-specific tags (only when `project.compliance` is configured)
18
+
19
+ | Tag | When to apply |
20
+ |---|---|
21
+ | `@pci-dss` | Payment card data, cardholder data environment, payment processing |
22
+ | `@hipaa` | Protected health information, patient data, healthcare records |
23
+ | `@gdpr` | EU personal data, consent management, data subject rights |
24
+ | `@soc2` | Audit logging, access controls, availability requirements |
25
+
26
+ Multiple tags can apply to one scenario.
27
+
28
+ ## What Each Tag Requires
29
+
30
+ ### In planning (grimoire-plan)
31
+ - `@security` / `@auth` — specify which auth library/framework; include a negative scenario task (assert 401/403)
32
+ - `@pii` — tasks for encryption at rest, access logging, data minimization; if GDPR in compliance, add consent + erasure tasks
33
+ - `@input-validation` — explicit validation/sanitization at boundary; negative test tasks for malicious input (SQLi, XSS, path traversal)
34
+ - `@secrets` — specify env vars or secret store, never hardcoded; add a task to verify no secrets in source
35
+ - `@pci-dss` — no card data in logs, TLS, tokenization, audit trail for cardholder data access
36
+ - `@hipaa` — access controls with audit logging, encryption at rest/transit, minimum necessary access
37
+ - `@gdpr` — lawful basis, consent mechanism if needed, data subject rights (access, rectify, erase, port), retention limits
38
+ - `@soc2` — audit logging for all access, change management documentation, availability monitoring
39
+
40
+ ### In verification (grimoire-verify)
41
+ - `@security` / `@auth` — confirm auth checks exist in implementation, negative test covers unauthorized access (401/403)
42
+ - `@pii` — data encrypted at rest, access logged, no PII in log output
43
+ - `@input-validation` — validation at boundary, negative tests for malicious input exist
44
+ - `@secrets` — values from env/secret store, no hardcoded credentials in source
45
+ - `@pci-dss` — no card data in logs, TLS for transmission, audit trail present
46
+ - `@hipaa` — access controls + audit logging, encryption at rest/transit
47
+ - `@gdpr` — consent mechanism if applicable, erasure support, data retention limits
48
+ - `@soc2` — audit logging, access controls, availability monitoring
49
+
50
+ A security-tagged scenario with no corresponding security verification in the tests is a **CRITICAL** issue.
51
+
52
+ ## STRIDE Threat Analysis
53
+
54
+ For each new endpoint, data flow, or trust boundary a change introduces:
55
+
56
+ | Threat | Question |
57
+ |---|---|
58
+ | **S**poofing | Can an attacker impersonate a user or service? Auth checks at every entry point? |
59
+ | **T**ampering | Can input or data in transit be modified? Integrity validated (checksums, signatures, CSRF)? |
60
+ | **R**epudiation | Are security-relevant actions logged? Could an attacker act without a trace? |
61
+ | **I**nfo Disclosure | Could errors, logs, or responses leak sensitive data (stack traces, PII, tokens)? |
62
+ | **D**enial of Service | Unbounded operations (large uploads, expensive queries, no rate limits)? |
63
+ | **E**levation of Privilege | Can a user escalate to admin? Role/permission checks at the right layer? |
64
+
65
+ Skip categories that don't apply. Don't manufacture threats.
66
+
67
+ ## OWASP Top 10 Surface Scan
68
+
69
+ For changed files, do a lightweight scan:
70
+
71
+ | OWASP Category | What to check in the diff |
72
+ |---|---|
73
+ | A01: Broken Access Control | New endpoints missing auth decorators/middleware; direct object references without ownership checks |
74
+ | A02: Cryptographic Failures | Weak hashing, missing encryption for sensitive data, hardcoded keys |
75
+ | A03: Injection | String concatenation in SQL/commands/templates, `eval()`, `innerHTML` with user data |
76
+ | A04: Insecure Design | Missing rate limiting on auth endpoints, no account lockout |
77
+ | A05: Security Misconfiguration | Debug mode enabled, default credentials, overly permissive CORS |
78
+ | A06: Vulnerable Components | New dependencies without version pins, known-vulnerable packages |
79
+ | A07: Auth Failures | Weak password requirements, session tokens in URLs |
80
+ | A08: Data Integrity Failures | Insecure deserialization (`pickle`, `yaml.load`), missing integrity checks |
81
+ | A09: Logging Failures | Security events not logged, PII/secrets in log output |
82
+ | A10: SSRF | User-controlled URLs in server-side HTTP requests without allowlist |
83
+
84
+ Tag each finding with OWASP category and CWE ID.
85
+
86
+ ## CWE Quick Reference
87
+
88
+ | Finding | OWASP / CWE |
89
+ |---|---|
90
+ | Missing auth checks | A01:2021 / CWE-862 |
91
+ | SQL injection | A03:2021 / CWE-89 |
92
+ | Command injection | A03:2021 / CWE-78 |
93
+ | XSS | A03:2021 / CWE-79 |
94
+ | Custom/weak crypto | A02:2021 / CWE-327, CWE-328 |
95
+ | Hardcoded secrets | A07:2021 / CWE-798 |
96
+ | SSRF | A10:2021 / CWE-918 |
97
+ | Insecure deserialization | A08:2021 / CWE-502 |
98
+
99
+ ## Compliance Framework Verification
100
+
101
+ Only applies when `project.compliance` is configured.
102
+
103
+ - **`owasp`** — OWASP Top 10 risks addressed (see surface scan above)
104
+ - **`pci-dss`** — No card numbers in logs, TLS for transmission, tokenization, audit trail, access controls on cardholder data
105
+ - **`hipaa`** — Access controls + audit logging, encryption at rest/transit, minimum necessary access, BAA implications for third-party services
106
+ - **`gdpr`** — Lawful basis identified, consent mechanism if needed, data subject rights (access, rectify, erase, port), retention limits, privacy by design
107
+ - **`soc2`** — Audit logging for access and changes, availability monitoring, logical access controls, change management documentation
108
+ - **`iso27001`** — Risk assessment documented, information classification applied, access control policy followed, incident response considered
109
+
110
+ Missing compliance coverage on a tagged scenario is a **blocker**.
@@ -0,0 +1,93 @@
1
+ # Testing & Contract Reference
2
+
3
+ Loaded by skills that involve writing tests, mocking external services, or verifying contract compliance.
4
+
5
+ ## Mocking Strategy
6
+
7
+ **Mock at the HTTP boundary, not at the client level.**
8
+
9
+ - **DO mock**: the HTTP transport layer using the project's HTTP mocking library (check `config.tools` or existing test imports for: `responses`, `httpx_mock`, `nock`, `msw`, `wiremock`). Fixture responses must match the contract in `schema.yml`.
10
+ - **DON'T mock**: your own client wrapper. If you mock `stripe_client.create_charge()`, you're testing that your code calls a function — not that it handles the real response shape. The client wrapper is the code under test.
11
+ - **DON'T mock**: internal services within the same repo. Use the real code. Mocking between internal modules hides integration bugs that only surface in production.
12
+
13
+ ## Fixture Management
14
+
15
+ - Fixtures live alongside tests (e.g., `tests/fixtures/stripe_create_charge.json`)
16
+ - One fixture per endpoint, named after the endpoint, not the test
17
+ - Each fixture is a concrete instance of the `schema.yml` contract
18
+ - When the contract changes, the fixture must change — stale fixtures are false-positive tests
19
+ - Include at least one error response fixture per external API (matching `error_response` in `schema.yml`)
20
+
21
+ ## Contract Test Requirements
22
+
23
+ Every external API integration needs contract tests that assert:
24
+ 1. Every `required: true` response field is read and typed correctly in the client
25
+ 2. Request payloads match the documented shape (required fields present, types correct)
26
+ 3. Error response handling matches the documented `error_response` shape
27
+ 4. Use recorded/fixture responses (not live calls) so tests run locally without network
28
+
29
+ For contract regression tests: if the client starts reading a new field or stops sending a required field, the test must fail.
30
+
31
+ ## Mocking Anti-Patterns
32
+
33
+ - Mocking your own client wrapper and asserting it was called — tests wiring, not behavior
34
+ - `unittest.mock.patch` on the function under test — replacing the thing you're testing
35
+ - Fixture responses that don't match any documented contract — fictional, prove nothing
36
+ - Mocking so aggressively that removing production code still passes the test
37
+ - Test creates a mock and asserts against the mock's return value (circular)
38
+
39
+ ## Verify Before Using
40
+
41
+ Before importing a module, calling a function, or adding a dependency — confirm it exists.
42
+
43
+ **Imports and functions:**
44
+ - Check area docs' Reusable Code table first (exact paths and line numbers)
45
+ - If importing from a file you haven't read, read it first
46
+ - If an import fails, don't guess — read the actual module for the real export name
47
+
48
+ **Dependencies and packages:**
49
+ - Only add packages already in `package.json` / `requirements.txt` / `pyproject.toml` / equivalent
50
+ - If a task requires a new package, verify it exists (should be specified in the plan)
51
+ - Never guess at a package name
52
+
53
+ **APIs and endpoints:**
54
+ - Check `schema.yml` for external API contracts (real endpoints, methods, field names)
55
+ - For internal APIs, read the area doc or route file — don't assume paths
56
+
57
+ ## Step Definition Conventions
58
+
59
+ Step definitions are organized by **domain concept**, NOT by feature file. One step file per feature file is an anti-pattern — steps should be reusable across features.
60
+
61
+ **Before writing step definitions, check the project's existing test setup.** Read test config files, existing step definitions, and `package.json` / `requirements.txt` / `pyproject.toml` to determine which framework is in use and follow its conventions.
62
+
63
+ **Key rules:**
64
+ - NEVER create one step definition file per feature file
65
+ - Given steps are most likely to be shared — put them in a common location
66
+ - When/Then steps are more domain-specific — group by domain
67
+ - If a step is used by 2+ features, move it to the shared/common file
68
+ - Step definition bodies should be thin — delegate to helper functions, page objects, or API clients
69
+ - **Match the project's existing patterns.** Don't introduce a new framework.
70
+
71
+ Common patterns by ecosystem (use as reference, not gospel — follow the project's actual conventions):
72
+
73
+ **Python (Behave):** `features/steps/` with `auth_steps.py`, `common_steps.py`, `environment.py`
74
+
75
+ **Python (pytest-bdd):** `tests/conftest.py` for shared fixtures + `tests/step_defs/test_auth.py` per domain
76
+
77
+ **JavaScript/TypeScript (Cucumber.js):** `features/step_definitions/` with `auth.steps.ts`, `common.steps.ts`, `features/support/world.ts`
78
+
79
+ **React / Frontend (Playwright/Cypress + Cucumber):** `e2e/steps/` with domain step files + `e2e/pages/` for page objects
80
+
81
+ ## Step Definition Quality
82
+
83
+ Every Then step must have a specific assertion with an exact expected value:
84
+ - **Strong:** `assert result == "expected_value"`, `expect(status).toBe(302)`
85
+ - **Weak:** `assert result is not None`, `expect(result).toBeDefined()`
86
+ - **Trivial:** `assert True`, `pass`, empty body — always CRITICAL
87
+
88
+ Anti-patterns:
89
+ - `def step_impl(): pass` — empty body, always passes
90
+ - Asserting against the return value of the function you just wrote (circular)
91
+ - `assert True` or `assert response is not None` — trivially true
92
+ - Catching exceptions in the step def so it never fails
93
+ - No `assert`/`expect` in a Then step — CRITICAL