@kiwidata/grimoire 0.1.6 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/cli/program.d.ts.map +1 -1
- package/dist/cli/program.js +2 -0
- package/dist/cli/program.js.map +1 -1
- package/dist/commands/comment-lint.d.ts +3 -0
- package/dist/commands/comment-lint.d.ts.map +1 -0
- package/dist/commands/comment-lint.js +14 -0
- package/dist/commands/comment-lint.js.map +1 -0
- package/dist/core/branch-check.d.ts.map +1 -1
- package/dist/core/branch-check.js +2 -16
- package/dist/core/branch-check.js.map +1 -1
- package/dist/core/comment-lint.d.ts +18 -0
- package/dist/core/comment-lint.d.ts.map +1 -0
- package/dist/core/comment-lint.js +215 -0
- package/dist/core/comment-lint.js.map +1 -0
- package/dist/core/doc-style.d.ts +1 -0
- package/dist/core/doc-style.d.ts.map +1 -1
- package/dist/core/doc-style.js +1 -1
- package/dist/core/doc-style.js.map +1 -1
- package/dist/core/docs.js +1 -1
- package/dist/core/docs.js.map +1 -1
- package/dist/core/health.js +1 -1
- package/dist/core/health.js.map +1 -1
- package/dist/core/hooks.js +39 -28
- package/dist/core/hooks.js.map +1 -1
- package/dist/core/init.js +1 -0
- package/dist/core/init.js.map +1 -1
- package/dist/core/list.js +2 -2
- package/dist/core/list.js.map +1 -1
- package/dist/core/status.js +2 -2
- package/dist/core/status.js.map +1 -1
- package/dist/core/update.d.ts.map +1 -1
- package/dist/core/update.js +22 -0
- package/dist/core/update.js.map +1 -1
- package/dist/core/validate.js +1 -1
- package/dist/core/validate.js.map +1 -1
- package/dist/utils/config.d.ts +2 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +4 -0
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/frontmatter.d.ts +6 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +13 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/paths.d.ts +1 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +5 -4
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/stdin.d.ts +3 -0
- package/dist/utils/stdin.d.ts.map +1 -0
- package/dist/utils/stdin.js +13 -0
- package/dist/utils/stdin.js.map +1 -0
- package/package.json +6 -2
- package/skills/grimoire-apply/SKILL.md +1 -1
- package/skills/grimoire-draft/SKILL.md +145 -215
- package/skills/references/artifact-map.md +2 -1
- package/templates/draft.md +108 -0
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: grimoire-draft
|
|
3
|
-
description:
|
|
3
|
+
description: Design a change collaboratively on one living draft.md, then project it into Gherkin features, constraints, and MADR decisions. Use when the user describes new functionality, requirements, or architecture choices.
|
|
4
4
|
compatibility: Designed for Claude Code (or similar products)
|
|
5
5
|
metadata:
|
|
6
6
|
author: kiwi-data
|
|
7
|
-
version: "0.
|
|
7
|
+
version: "0.2"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# grimoire-draft
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Design a change on **one living document** (`draft.md`), iterating with the user, then
|
|
13
|
+
**project** the agreed design into its durable homes (features, constraints, decisions).
|
|
14
|
+
|
|
15
|
+
The core idea: spread-out artifacts hinder the thinking. So you do all the designing in a
|
|
16
|
+
single coherent doc — diagram/sketch, a decision ledger, pseudo-code, an open-question
|
|
17
|
+
ledger — and only fragment it into separate homes **after agreement**. `draft.md` is
|
|
18
|
+
ephemeral: retained as reference through the pipeline, deleted when `grimoire-apply` clears
|
|
19
|
+
the change folder. Git history preserves it.
|
|
13
20
|
|
|
14
21
|
## Triggers
|
|
15
22
|
- User describes new functionality, behavior changes, or feature requests
|
|
@@ -17,244 +24,184 @@ Draft or update Gherkin features and MADR architecture decisions collaboratively
|
|
|
17
24
|
- User describes a technology choice, architecture decision, or trade-off
|
|
18
25
|
- Loose match: contains "feature", "requirement", "spec", "decision", "grimoire" with "create", "draft", "plan", "start", "new"
|
|
19
26
|
|
|
20
|
-
## Routing
|
|
27
|
+
## Routing (coarse — up front)
|
|
28
|
+
|
|
29
|
+
Decide only whether to design at all, and in which skill. The **fine** routing (which fact
|
|
30
|
+
becomes a feature vs. a constraint vs. a decision) happens later, at projection (step 7).
|
|
31
|
+
|
|
21
32
|
- Bug report ("something is broken") → `grimoire-bug` or `grimoire-bug-report`
|
|
22
33
|
- Pure refactoring (no behavior change) → no grimoire artifact needed. Suggest an ADR only if architecturally significant.
|
|
23
34
|
- Config, deps, formatting → not grimoire territory. Just do it.
|
|
24
|
-
-
|
|
35
|
+
- Otherwise → design it here. If genuinely unclear whether this is a grimoire change, ask one clarifying question rather than guessing.
|
|
25
36
|
|
|
26
37
|
## Workflow
|
|
27
38
|
|
|
28
|
-
### 1. Qualify the Request — Jurisdiction
|
|
39
|
+
### 1. Qualify the Request — Jurisdiction (coarse)
|
|
29
40
|
|
|
30
|
-
|
|
41
|
+
Confirm this is a change worth designing, and which skill owns it (table above). You do
|
|
42
|
+
**not** need to assign each fact to a home yet — during design everything lives in one
|
|
43
|
+
`draft.md`; per-fact routing is a projection concern (step 7, D13).
|
|
31
44
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
| **Constraint** — security control, NFR, performance budget, observability/logging guarantee, compliance rule | `.grimoire/docs/constraints.md` (assertion + rationale + how-verified) | NOT a `.feature` |
|
|
36
|
-
| **Architecture decision** — a trade-off or structural choice | MADR in `.grimoire/decisions/` | NOT a `.feature` |
|
|
37
|
-
| **Data model / external API contract** | data schema | NOT a `.feature` |
|
|
38
|
-
| **Both behavior + decision** | features AND a MADR | — |
|
|
39
|
-
| **Bug fix** | STOP → `grimoire-bug`. "The spec already describes correct behavior; just fix the code." | — |
|
|
40
|
-
| **Refactoring** (no behavior change) | STOP. No artifact. Suggest an ADR only if architecturally significant. | — |
|
|
41
|
-
| **Config / deps / formatting** | STOP. Not grimoire territory. | — |
|
|
45
|
+
The one up-front question that matters: **is this a behavior/feature/architecture change**
|
|
46
|
+
(→ design it here), or a bug / pure refactor / config tweak (→ route away, per the table)?
|
|
47
|
+
If unclear, ask one question. Do not default to "draft a feature".
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
### 2. Triviality Gate
|
|
44
50
|
|
|
45
|
-
|
|
51
|
+
Complexity is an **output** of design, not an input — you cannot score it honestly before
|
|
52
|
+
the design exists. Up front, make only one binary call:
|
|
46
53
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
- **Trivial** — config, typo, copy change, single-file fix, dependency bump. Skip the
|
|
55
|
+
`draft.md` loop: make the change directly, record a minimal `manifest.md` (Why + file
|
|
56
|
+
list), done.
|
|
57
|
+
- **Non-trivial** — anything else. Build a `draft.md` and design the change (steps 3–8).
|
|
51
58
|
|
|
52
|
-
|
|
59
|
+
The full **complexity level (1–4)** is scored at **projection** (step 7), once the design
|
|
60
|
+
is settled, and written to `manifest.md` — not before (a premature number biases the design
|
|
61
|
+
to fit it). During design, use the table below only as a rough guide for how deep to
|
|
62
|
+
research and elicit; depth grows with the change, it is not pre-allocated.
|
|
53
63
|
|
|
54
|
-
|
|
64
|
+
| Level | Label | Signals | Drives (recorded at projection) |
|
|
65
|
+
|-------|-------|---------|---------------------------------|
|
|
66
|
+
| 1 | Trivial | Config, typo, copy, single-file fix | handled by the gate above — no `draft.md` |
|
|
67
|
+
| 2 | Simple | Single capability, ≤3 files, no architecture/data changes | Plan: coarser tasks · Review: Senior Engineer only |
|
|
68
|
+
| 3 | Moderate | Multiple capabilities, architecture decisions, data/dep changes | Plan: fine-grained · Review: all relevant personas · manifest carries Assumptions + Pre-Mortem |
|
|
69
|
+
| 4 | Complex | Cross-cutting, multiple services, security-sensitive, new infra | Plan: fine-grained · Review: all personas mandatory (`grimoire-review` not optional) · Assumptions + Pre-Mortem |
|
|
55
70
|
|
|
56
|
-
|
|
71
|
+
If unsure between two levels at projection, pick the higher. The user can override ("treat this as complex").
|
|
57
72
|
|
|
58
|
-
|
|
73
|
+
### 3. Research Existing Solutions
|
|
59
74
|
|
|
60
|
-
|
|
61
|
-
|-------|-------|---------|----------|
|
|
62
|
-
| 1 | **Trivial** | Config, typo, copy change, single-file fix | Skip research (step 3). Minimal manifest (Why + Feature/Decision list only). No Pre-Mortem. |
|
|
63
|
-
| 2 | **Simple** | Single capability, ≤3 files, no architecture decisions, no data changes | Light research (step 3 — check built-ins and first-party only). Standard manifest. |
|
|
64
|
-
| 3 | **Moderate** | Multiple capabilities, architecture decisions, data model changes, new dependencies | Full research (step 3). Full manifest with Assumptions and Pre-Mortem. |
|
|
65
|
-
| 4 | **Complex** | Cross-cutting concerns, multiple services/systems, security-sensitive, new infrastructure | Full research (step 3). Full manifest. Mandatory `grimoire-review` after plan (not optional). |
|
|
75
|
+
Before designing, research what already exists. Do not ask the user to research — do it yourself.
|
|
66
76
|
|
|
67
|
-
|
|
68
|
-
-
|
|
69
|
-
-
|
|
77
|
+
- Trivial changes never reach this step (handled by the gate).
|
|
78
|
+
- Otherwise research **proportional to scope**: a single first-party capability needs only a
|
|
79
|
+
built-ins / first-party check; architecture decisions, new dependencies, or cross-cutting
|
|
80
|
+
concerns need full research across all categories.
|
|
70
81
|
|
|
71
|
-
|
|
82
|
+
Follow the methodology in `../references/build-vs-buy.md`. The findings feed the `draft.md`
|
|
83
|
+
**Why** (and, for an adopt/build/hybrid call, the manifest **Prior Art** at projection).
|
|
84
|
+
Present findings to the user and get agreement on direction before designing deeply.
|
|
72
85
|
|
|
73
|
-
###
|
|
74
|
-
Before designing, research what already exists. Do not ask the user to research — do it yourself.
|
|
86
|
+
### 4. Design Input Check
|
|
75
87
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
88
|
+
Check whether design artifacts already exist for this change, so the design is grounded in
|
|
89
|
+
real components and states rather than imagined ones. Consumed output anchors the `draft.md`
|
|
90
|
+
**At a glance** section.
|
|
79
91
|
|
|
80
|
-
|
|
92
|
+
- **Existing design output**: If `.grimoire/changes/<change-id>/designs/` is already populated (a prior `grimoire-design` run produced `problem.md`, `variants.md`, `variant-{n}.html`, or `figma-snapshot.json`), read those now. Treat them as authoritative for component shape, states, and visual tokens — do not re-query Figma. The visual + component/state material becomes the **At a glance** anchor and seeds the behavioral **Sketches**.
|
|
93
|
+
- **Figma MCP available, no design folder**: If `project.design_tool.mcp` is configured and `designs/` is absent, ask: "Figma file URL or node ID? (or skip)". On a URL or node reference, query the Figma MCP for frame data and cache the response at `.grimoire/changes/<change-id>/designs/figma-snapshot.json` per `../references/design-input-formats.md` §1 Cache. On "skip" or empty input, continue.
|
|
94
|
+
- **No MCP and no design folder**: skip this step silently.
|
|
81
95
|
|
|
82
|
-
###
|
|
96
|
+
### 5. Scaffold & Map Existing State
|
|
83
97
|
|
|
84
|
-
|
|
98
|
+
- Choose a `change-id`: kebab-case, verb-led (`add-`, `update-`, `remove-`).
|
|
99
|
+
- Ensure you're on a feature branch for this change (`grimoire-branch-guard` usually created it). The branch is where `draft.md` and, later, the projected artifacts are edited live.
|
|
100
|
+
- Create `.grimoire/changes/<change-id>/draft.md` from `templates/draft.md`, setting `kind: greenfield | refactor`.
|
|
85
101
|
|
|
86
|
-
|
|
87
|
-
- **Figma MCP available, no design folder**: If `project.design_tool.mcp` is configured and `designs/` is absent, ask: "Figma file URL or node ID? (or skip)". On a URL or node reference, query the Figma MCP for frame data and cache the response at `.grimoire/changes/<change-id>/designs/figma-snapshot.json` per `../references/design-input-formats.md` §1 Cache. On "skip" or empty input, continue to standard elicitation.
|
|
88
|
-
- **No MCP and no design folder**: skip this step silently. Fall back to the standard interview elicitation in step 4 below.
|
|
102
|
+
Then map what already exists so the design isn't blind:
|
|
89
103
|
|
|
90
|
-
|
|
104
|
+
- Read `features/` for the current behavioral baseline, `.grimoire/decisions/` for existing decisions, `.grimoire/docs/context.yml` for the deployment environment and sibling services. Check `.grimoire/changes/` for in-progress changes that overlap — flag conflicts. See `../references/artifact-map.md` for reading discipline.
|
|
105
|
+
- **For `kind: refactor` — build the Current state section (required).** Map how the touched system works **today**, with `file:line` breadcrumbs, into `draft.md` → *Current state*, followed by a severity-ranked Gaps/drift list. **Mandate the codebase graph**: if the repo isn't indexed, run `index_repository` first, then use `search_graph` / `trace_path` / `get_code_snippet` for qualified names, callers, and call chains. This map is the load-bearing grounding for a refactor — you cannot redesign what you haven't located.
|
|
106
|
+
- If `.grimoire/changes/<change-id>/consult.md` exists (from `grimoire-design-consult`), parse `## Inferred assumptions` and `## Inferred givens` and carry them into the `draft.md` design: assumptions → *Decided/Open* (each becomes an Open row, or a Decided row if the consult resolved it); givens → context for the *Decisions* ledger. The H2 headers `## Inferred assumptions` and `## Inferred givens` are load-bearing — they are the exact section names `grimoire-design-consult` writes; do not paraphrase, retitle, or fuzzy-match. **Open questions from `consult.md` are NOT copied** — they remain in `consult.md` as designer follow-up items.
|
|
91
107
|
|
|
92
|
-
###
|
|
108
|
+
### 6. Design the Change — the loop (the interview happens HERE)
|
|
93
109
|
|
|
94
|
-
|
|
110
|
+
This single loop replaces what used to be separate "elicit requirements", "draft", and
|
|
111
|
+
"collaborate" steps. **Interviewing IS iterating on `draft.md`.** There is no gather-then-
|
|
112
|
+
transcribe split — requirements surface, get questioned, and resolve inside the doc.
|
|
95
113
|
|
|
96
|
-
|
|
114
|
+
Iterate with the user, directly on `draft.md`:
|
|
97
115
|
|
|
98
|
-
|
|
99
|
-
|
|
116
|
+
```
|
|
117
|
+
loop:
|
|
118
|
+
propose → decisions into the Decisions ledger; shapes into Sketches; a diagram/sketch into At a glance
|
|
119
|
+
question → unknowns become rows under Open (use ../references/elicitation-personas.md as lenses)
|
|
120
|
+
user reacts → answers / edits the doc
|
|
121
|
+
resolve → strike the Open row IN PLACE: `RESOLVED: <answer> (Dn)` — never delete it
|
|
122
|
+
until Decided is stable AND Open is empty-or-deferred.
|
|
123
|
+
```
|
|
100
124
|
|
|
101
|
-
|
|
102
|
-
- **Adopting**: Focus on integration — how it fits, what config is needed. Skip deep business-rule elicitation.
|
|
103
|
-
- **Building custom**: Full elicitation — business rules, edge cases, data contracts, security, NFRs.
|
|
104
|
-
- **Hybrid**: Elicit deeply for custom parts. For adopted parts, focus on integration boundaries.
|
|
125
|
+
Discipline for the loop:
|
|
105
126
|
|
|
106
|
-
|
|
127
|
+
1. **Outcome & Non-goals first.** Pin these (into *Why*) before anything else — they set scope. Restate them back to the user.
|
|
128
|
+
2. **Batch questions, then wait.** Ask 3–5 at a time, grouped by concern, as Open rows. Stop. Wait. Do not propose decisions past an unanswered batch.
|
|
129
|
+
3. **Ask the question; don't pre-answer it.** "Should locked accounts get an email?" — not "I'll assume locked accounts get an email." The pre-answered form lets the user nod through assumptions they'd otherwise correct.
|
|
130
|
+
4. **One question per real ambiguity, not a checklist dump.** Ask the few that matter for *this* change.
|
|
131
|
+
5. **Disambiguate immediately.** If an answer is vague ("handle errors gracefully"), ask the specific follow-up and record the concrete answer. Never leave a vague answer in the ledger.
|
|
132
|
+
6. **Capture, don't extrapolate.** "Out of scope for now" → record as a non-goal and stop. Don't design a scenario "just in case".
|
|
133
|
+
7. **When the user delegates** ("just write something reasonable"), record it explicitly as an Open→RESOLVED row: "Defaulting to <choice> per user delegation — flag in review if wrong." The assumption stays visible.
|
|
134
|
+
8. **Sort facts by kind as they emerge.** An invariant (security control, NFR, performance budget, observability guarantee) is not a behavior — capture it in the *Constraints* section, not as a behavioral sketch. Apply the rough behaviour-vs-invariant test as you design (does an external actor observe it without reading code/logs?) so projection's admission test (step 7) gets clean input instead of slop to reroute. The fine fact-to-home routing still happens at projection; this just keeps the design honest while you think.
|
|
107
135
|
|
|
108
|
-
|
|
109
|
-
2. **Batch questions, then wait.** Ask 3-5 questions at a time, grouped by persona. Stop. Wait for the user's reply. Do not draft scenarios until the batch is answered.
|
|
110
|
-
3. **Ask the question; don't pre-answer it.** "Should locked accounts get an email?" — not "I'll assume locked accounts get an email, let me know if not." The pre-answered form lets the user nod through assumptions they'd otherwise correct.
|
|
111
|
-
4. **One question per ambiguity, not a checklist dump.** If the user said "users can reset password", do not ask 12 generic questions. Ask the 3 that matter for *this* feature.
|
|
112
|
-
5. **Disambiguate immediately.** If the user's answer is vague ("yeah, handle errors gracefully"), ask the specific follow-up ("for invalid tokens, do we redirect to login with a flash message, return a 400, or something else?"). Never leave a vague answer in the spec.
|
|
113
|
-
6. **Capture, don't extrapolate.** If the user explicitly says "out of scope for now", note it as a non-goal and stop. Don't draft a scenario "just in case".
|
|
114
|
-
7. **When the user pushes back on a question** ("just write something reasonable"), record their delegation explicitly: "Defaulting to <choice> per user delegation — flag in review if wrong." This makes the assumption visible later.
|
|
136
|
+
**Never silently fill an open question.** Either ask it (as an *Open* row), defer it to a non-goal, or record the inference explicitly in *Decided*. The *Decided/Open* ledger IS the requirements summary — before declaring the design done, walk it back to the user so they see every call and every guess.
|
|
115
137
|
|
|
116
|
-
|
|
138
|
+
**Nothing is written to `features/`, `.grimoire/docs/constraints.md`, or `.grimoire/decisions/` during this loop.** Everything lives in `draft.md`. The design is "done" when *Decided* is stable and *Open* is empty-or-deferred — and the user agrees.
|
|
117
139
|
|
|
118
|
-
|
|
119
|
-
- **Manifest Assumptions** (level 3-4) — each open question becomes an unvalidated assumption with the reading you chose.
|
|
120
|
-
- **Open questions in the Requirements Summary** — explicitly listed so the user sees what you guessed.
|
|
140
|
+
Do NOT proceed to projection without explicit user approval of the design.
|
|
121
141
|
|
|
122
|
-
|
|
142
|
+
### 7. Projection — generate the homes from draft.md
|
|
123
143
|
|
|
124
|
-
|
|
144
|
+
Once the user agrees the design is settled, project `draft.md` into its durable homes. This
|
|
145
|
+
is where the **fine routing** happens (each fact → its one home) and where the admission
|
|
146
|
+
test + principles gate run. Artifacts are written **live in their real locations** on the
|
|
147
|
+
branch — `git diff` is the staging area; there is no copy-into-the-change-folder.
|
|
125
148
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
- Read `features/` to understand the current behavioral baseline
|
|
129
|
-
- Read `.grimoire/decisions/` to understand existing architecture decisions
|
|
130
|
-
- Read `.grimoire/docs/context.yml` (if it exists) to understand the deployment environment, related services, and infrastructure — this tells you what's available (caches, queues, sibling services) and what constraints apply (deployment target, environments)
|
|
131
|
-
- Check `.grimoire/changes/` for any in-progress changes that might overlap
|
|
132
|
-
- If there's a conflict with an active change, flag it
|
|
133
|
-
- If `.grimoire/changes/<change-id>/consult.md` exists (from a prior `grimoire-design-consult` run), parse the `## Inferred assumptions` and `## Inferred givens` sections verbatim. Copy the contents of `## Inferred assumptions` into the manifest's Assumptions section, and copy `## Inferred givens` into a new Givens section at the same heading level (Givens applies to level 3-4 only — skip for level 1-2). The H2 headers `## Inferred assumptions` and `## Inferred givens` are load-bearing — they are the exact section names `grimoire-design-consult` writes; do not paraphrase, retitle, or fuzzy-match. Open questions from `consult.md` are NOT copied — they remain in `consult.md` as designer follow-up items.
|
|
149
|
+
First, **score the complexity level (1–4)** now that the design is settled, and write it to
|
|
150
|
+
`manifest.md` frontmatter as `complexity: <1-4>`.
|
|
134
151
|
|
|
135
|
-
|
|
136
|
-
- Choose a `change-id`: kebab-case, verb-led (`add-`, `update-`, `remove-`)
|
|
137
|
-
- Ensure you're on a feature branch for this change (`grimoire-branch-guard` usually created it). The branch is where all artifacts are edited live.
|
|
138
|
-
- Create `.grimoire/changes/<change-id>/` — this folder holds **only ephemeral process scaffolding**: `manifest.md` (and later `tasks.md`). It does NOT hold copies of features, decisions, or constraints — those are edited live in their real locations and tracked by `git diff`. The folder is deleted at finalize; the branch + PR + git log are the durable record.
|
|
152
|
+
Then project each kind of fact:
|
|
139
153
|
|
|
140
|
-
|
|
141
|
-
**For behavioral changes:**
|
|
154
|
+
**Behaviors → `features/*.feature`.** For each behavioral fact in the design:
|
|
142
155
|
|
|
143
|
-
|
|
156
|
+
*The feature-file admission test* — a scenario may be written **only if it passes all four gates**; if it fails any, it is a constraint or a decision, not a feature:
|
|
157
|
+
1. **External actor** — a user, operator, or external system does the thing. Internal actor → constraint/decision.
|
|
158
|
+
2. **Observable** — the actor sees the outcome without reading code or logs. "<200ms", "logs scrubbed of PII" → fails → constraint.
|
|
159
|
+
3. **Domain language** — domain nouns, zero implementation detail. Names a library/log-level/table (`loguru`, `INFO`, `bcrypt`, `users` table) → fails → leaking implementation.
|
|
160
|
+
4. **Survives reimplementation** — rewrite the internals from scratch; would the scenario still read the same? If it would change, it's pinned to implementation → not a feature.
|
|
144
161
|
|
|
145
|
-
|
|
162
|
+
Common slop this catches (all → `constraints.md`): "PII is scrubbed from logs", "all endpoints require auth", "responses are gzipped", "errors logged with a trace id".
|
|
146
163
|
|
|
147
|
-
|
|
164
|
+
*Extend vs. new — default is always extend; new files are the exception and require justification.* List existing feature files first (**required, not skippable** — do not write any scenario until this triage table is complete):
|
|
148
165
|
|
|
149
166
|
```
|
|
150
167
|
Existing feature files:
|
|
151
168
|
features/auth/login.feature — "User Login"
|
|
152
|
-
features/auth/registration.feature — "User Registration"
|
|
153
169
|
features/billing/invoices.feature — "Invoice Management"
|
|
154
|
-
...
|
|
155
170
|
```
|
|
156
171
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
**Step 2 — Match each proposed scenario to an existing file**
|
|
160
|
-
|
|
161
|
-
For each scenario you intend to draft, explicitly decide: extend or new? Show the decision:
|
|
172
|
+
For each scenario, decide extend-or-new and show it:
|
|
162
173
|
|
|
163
174
|
```
|
|
164
|
-
|
|
165
|
-
"
|
|
166
|
-
"User exports invoices as CSV" → extend features/billing/invoices.feature (same resource)
|
|
167
|
-
"User configures SSO provider" → NEW (no existing file owns SSO configuration)
|
|
175
|
+
"Admin resets a user's password" → extend features/auth/login.feature (same actor domain: auth)
|
|
176
|
+
"User configures SSO provider" → NEW (no existing file owns SSO configuration)
|
|
168
177
|
```
|
|
169
178
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
**Step 3 — Execute (edit live on the branch)**
|
|
173
|
-
|
|
174
|
-
Artifacts are edited **directly in their real locations** on the feature branch. The branch is the isolation; `git diff` is the staging area. There is no copy into `.grimoire/changes/` and no promote step (see `../references/principles.md` — don't reinvent git).
|
|
175
|
-
|
|
176
|
-
- **Extend:** add scenarios directly to the live `features/<same-relative-path>` file.
|
|
177
|
-
- **New file (requires justification):** state which existing files were considered and why none fit. Then create `features/<capability>/<name>.feature` directly.
|
|
178
|
-
|
|
179
|
-
Signals a scenario belongs in an existing file: same actor, same domain object, same entry point, same HTTP resource or screen.
|
|
180
|
-
Signals a genuinely new file: new actor type with no existing file, entirely new domain object, or existing file's Feature title would need "and" to cover both.
|
|
179
|
+
Signals to extend: same actor, same domain object, same entry point, same HTTP resource or screen. Signals genuinely new: new actor type with no existing file, entirely new domain object, or the existing Feature title would need "and" to cover both. If unsure, extend. A new file requires stating which files were considered and why none fit.
|
|
181
180
|
|
|
182
|
-
|
|
183
|
-
- Follow Gherkin best practices:
|
|
184
|
-
- Feature title + user story (As a / I want / So that)
|
|
185
|
-
- Background for shared preconditions
|
|
186
|
-
- One scenario per behavior
|
|
187
|
-
- Given/When/Then — describe WHAT, never HOW
|
|
188
|
-
- No implementation details in feature files
|
|
181
|
+
Then write Gherkin (Feature title + user story; Background for shared preconditions; one scenario per behavior; Given/When/Then describing WHAT, never HOW). Apply security tags per `../references/security-compliance.md` (only when there's a security surface; compliance tags only when `project.compliance` is set). When design input grounded the scenarios (step 4): use brand-token **names** not hex values when `.grimoire/brand/tokens.json` applies; prefer existing component names when `.grimoire/docs/components.md` exists, and flag any net-new component ("new component required — confirm before plan stage").
|
|
189
182
|
|
|
190
|
-
**When
|
|
191
|
-
- If a Figma snapshot or `grimoire-design` output is available, propose Gherkin scenarios per (component × state) grounded in those artifacts. Walk the component list and the enumerated states; emit one Scenario per pair.
|
|
192
|
-
- Present the proposed scenarios for user review before writing to `.feature` files — accept all / accept some / edit / reject any. Rejected scenarios are not written.
|
|
193
|
-
- If `grimoire-design` already produced user-accepted scenarios under `.grimoire/changes/<change-id>/designs/scenarios.feature`, do NOT re-propose them; write the accepted ones live into `features/` (applying the admission test) and only fill gaps (e.g., new components not yet covered).
|
|
183
|
+
**Constraints → `.grimoire/docs/constraints.md`.** Every invariant that failed the admission test (it's a security control / NFR / observability / compliance rule, not an actor-observable behavior) becomes one row: **assertion · rationale · how-verified · links**. The assertion is a flat statement ("Log output never contains PII or secrets"), not Given/When/Then. `how-verified` names the test that proves it (a `unit-invariant` the plan stage will create) — never a Gherkin scenario. If it stems from a decision, link the MADR; don't restate it. Create the file from `templates/constraints.md` if absent.
|
|
194
184
|
|
|
195
|
-
**
|
|
196
|
-
- When Figma variables map to tokens that also appear in `.grimoire/brand/tokens.json`, scenarios referencing visual properties must use token names, not hex values. Example: write `Then the submit button uses color.primary` not `Then the submit button is #0066ff`.
|
|
197
|
-
- Hardcoded hex values in scenarios drift silently when tokens change. Token names stay correct across re-skins.
|
|
185
|
+
**Decisions → `.grimoire/decisions/NNNN-*.md`.** Project each Decisions-ledger entry, applying the **novelty gate**: a MADR is for a decision with a real, project-specific trade-off between viable alternatives — not for industry-default tooling picks or ecosystem-forced conventions. Ask: *would a competent engineer on this stack make a different choice, and need our reasoning to understand ours?* If no, skip it. Obvious tooling/convention picks fold into the existing `Tooling and convention baseline` ADR (one line: choice → why), not a new sequential record. Genuine trade-offs get the next sequential number, status `proposed` (`grimoire-apply` flips to `accepted` at finalize), using `.grimoire/decisions/template.md`.
|
|
198
186
|
|
|
199
|
-
**
|
|
200
|
-
- When `.grimoire/docs/components.md` exists, prefer references to existing components by name in scenarios (e.g., `Then a Button with variant="primary" is rendered` over `Then a blue button appears`).
|
|
201
|
-
- Flag net-new components explicitly: emit "new component required — confirm before plan stage" alongside any scenario that introduces a component not listed in `components.md`. The plan stage will then decide whether to add it to the inventory or reuse an existing variant.
|
|
202
|
-
|
|
203
|
-
**Security tags on scenarios:**
|
|
204
|
-
Apply Gherkin tags per `../references/security-compliance.md` (section "Security Tags"). Tags drive stricter checks in plan, review, and verify stages. Apply compliance-specific tags only when `project.compliance` is configured. If no compliance frameworks and no security surface, don't add tags.
|
|
205
|
-
|
|
206
|
-
**For constraints (security / NFR / observability / compliance):**
|
|
207
|
-
|
|
208
|
-
Anything that failed the feature admission test because it's an invariant rather than an actor-observable behavior goes here — **not** into a `.feature`.
|
|
209
|
-
|
|
210
|
-
- Append to the live `.grimoire/docs/constraints.md` (create it from `templates/constraints.md` if absent).
|
|
211
|
-
- One row per constraint: **assertion · rationale · how-verified · links**. The assertion is a flat statement of what must always hold ("Log output never contains PII or secrets"), not a Given/When/Then.
|
|
212
|
-
- `how-verified` names the test that proves it (a `unit-invariant` test the plan stage will create) — never a Gherkin scenario.
|
|
213
|
-
- If the constraint stems from a decision, link the MADR; don't restate the decision (DRY).
|
|
214
|
-
|
|
215
|
-
**For architecture decisions:**
|
|
216
|
-
|
|
217
|
-
- **Novelty gate — record only novel decisions.** A MADR is for a decision with a real, project-specific trade-off between viable alternatives. It is NOT for industry-default tooling picks (the standard test runner, CLI parser, git wrapper, linter) or for conventions the ecosystem forces (ESM `.js` import suffix, where the framework expects files). If the honest "Considered Options" would be "the obvious default vs. things nobody would pick here", do not write an ADR. Before writing one, ask: *would a competent engineer on this stack make a different choice, and would they need our reasoning to understand ours?* If no, skip it.
|
|
218
|
-
- **Obvious tooling/conventions go in the baseline record, not their own ADR.** When you do need to write down a default pick (e.g. a new dev dependency), add a row to the existing `Tooling and convention baseline` ADR (one line: choice → why) rather than minting a new sequential record. Reserve sequential ADRs for genuine trade-offs.
|
|
219
|
-
- Write the MADR record directly into the live `.grimoire/decisions/` with the next sequential number (`NNNN-title.md`)
|
|
220
|
-
- Use the template from `.grimoire/decisions/template.md` or the AGENTS.md format
|
|
221
|
-
- Include considered options, decision drivers, and consequences
|
|
222
|
-
- Draft status `proposed`; `grimoire-apply` flips it to `accepted` at finalize
|
|
223
|
-
|
|
224
|
-
**For changes that touch data:**
|
|
225
|
-
- Check `.grimoire/docs/data/schema.yml` for the current data schema (if it exists)
|
|
226
|
-
- If the change adds, modifies, or removes data models, fields, indexes, or external API integrations, write a `data.yml` in `.grimoire/changes/<change-id>/` showing the proposed schema changes
|
|
227
|
-
- Use the same YAML format as `schema.yml` but only include what's changing — new models, added/removed fields, new external API integrations
|
|
228
|
-
- Mark changes clearly with `action:` on each entry:
|
|
187
|
+
**Data changes → `.grimoire/changes/<change-id>/data.yml`.** If the change adds/modifies/removes data models, fields, indexes, or external API integrations, write `data.yml` (same YAML shape as `schema.yml`, only what's changing, `action:` on each entry):
|
|
229
188
|
|
|
230
189
|
```yaml
|
|
231
190
|
# Proposed data changes for: add-user-profiles
|
|
232
|
-
|
|
233
191
|
users:
|
|
234
192
|
action: modify
|
|
235
193
|
source: src/models/user.py
|
|
236
194
|
fields:
|
|
237
|
-
avatar_url:
|
|
238
|
-
|
|
239
|
-
type: varchar
|
|
240
|
-
nullable: true
|
|
241
|
-
legacy_name: # removing a field
|
|
242
|
-
action: remove
|
|
243
|
-
|
|
195
|
+
avatar_url: { action: add, type: varchar, nullable: true }
|
|
196
|
+
legacy_name: { action: remove }
|
|
244
197
|
profiles:
|
|
245
|
-
action: add
|
|
198
|
+
action: add
|
|
246
199
|
type: collection
|
|
247
200
|
fields:
|
|
248
201
|
user_id: { type: objectId, ref: users }
|
|
249
202
|
bio: { type: string, max_length: 500 }
|
|
250
|
-
social_links:
|
|
251
|
-
type: array
|
|
252
|
-
items:
|
|
253
|
-
platform: { type: string }
|
|
254
|
-
url: { type: string }
|
|
255
|
-
|
|
256
203
|
github_api:
|
|
257
|
-
action: add
|
|
204
|
+
action: add
|
|
258
205
|
type: external_api
|
|
259
206
|
provider: GitHub
|
|
260
207
|
schema_ref: https://docs.github.com/en/rest
|
|
@@ -263,60 +210,43 @@ github_api:
|
|
|
263
210
|
get_user:
|
|
264
211
|
method: GET
|
|
265
212
|
path: /users/{username}
|
|
266
|
-
request:
|
|
267
|
-
headers:
|
|
268
|
-
|
|
269
|
-
response: # document what you expect back
|
|
213
|
+
request:
|
|
214
|
+
headers: { Authorization: "Bearer {token}" }
|
|
215
|
+
response:
|
|
270
216
|
login: { type: string, required: true }
|
|
271
217
|
avatar_url: { type: string, required: true }
|
|
272
218
|
name: { type: string, nullable: true }
|
|
273
|
-
error_response:
|
|
219
|
+
error_response:
|
|
274
220
|
message: { type: string }
|
|
275
221
|
status: { type: integer }
|
|
276
222
|
```
|
|
277
223
|
|
|
278
|
-
**Contract documentation is mandatory for external APIs.** Every endpoint
|
|
279
|
-
|
|
280
|
-
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
-
|
|
289
|
-
-
|
|
290
|
-
- **
|
|
291
|
-
- **Level 3-4**: Include an **Assumptions** section: list what must be true for this change to succeed. For each assumption, note whether there is evidence or it is unvalidated. Unvalidated assumptions on the critical path should be flagged to the user.
|
|
292
|
-
- **Level 3-4**: Include a **Pre-Mortem** section: imagine this change has failed or caused a production incident 6 months from now — what went wrong? List 2-5 plausible failure modes with mitigations or "accepted" if the risk is acknowledged.
|
|
293
|
-
- The manifest must include a **Prior Art** section summarizing the research from step 3: what was found, what was evaluated, and why the chosen direction (adopt, build, or hybrid) was selected. If the decision was to build, include what's being borrowed from existing implementations. This section is consumed by the plan and review stages — without it, reviewers can't validate the build-vs-buy decision.
|
|
294
|
-
|
|
295
|
-
### 8. Collaborate
|
|
296
|
-
- Present the draft to the user
|
|
297
|
-
- Iterate based on feedback
|
|
298
|
-
- Do NOT proceed to plan stage without user approval
|
|
299
|
-
|
|
300
|
-
### 9. Validate
|
|
301
|
-
- Verify `.feature` files have valid Gherkin syntax
|
|
302
|
-
- Verify MADR records have valid YAML frontmatter (status, date)
|
|
303
|
-
- Verify manifest is complete and accurate
|
|
304
|
-
- Every Feature has a user story
|
|
305
|
-
- Every Scenario has at least Given + When + Then
|
|
306
|
-
- No implementation details leaked into features
|
|
307
|
-
- **Re-run the admission test on every scenario you wrote** (step 1): external actor, observable, domain language, survives reimplementation. Any scenario that now fails is slop — move it to `constraints.md` or a MADR before proceeding.
|
|
308
|
-
- **Principles gate** (`../references/principles.md`): no fact written to two homes (DRY), no second way to do an existing thing (one right way), no reinvented wheel (don't reinvent), no artifact created past the stated scope (KISS).
|
|
224
|
+
**Contract documentation is mandatory for external APIs.** Every endpoint must document `request` (what you send), `response` (fields you read, `required: true` for those your code depends on), and `error_response` (the error shape you handle). Downstream skills generate contract tests from this. If you don't know the exact shape, reference `schema_ref` and document the subset your client uses — that subset is the contract. No data impact → skip `data.yml` entirely.
|
|
225
|
+
|
|
226
|
+
**Manifest (`manifest.md`).** Generate it from `draft.md` as the durable plan-input glue: `complexity` (just scored), Why + Non-goals, the artifact list (added/modified/removed features, decisions, constraints), and a **Prior Art** section summarizing step 3's research (what was found/evaluated, why adopt/build/hybrid; if building, what's borrowed). **Level 3–4** also carry **Assumptions** (what must be true; mark evidence vs. unvalidated; flag unvalidated ones on the critical path) and a **Pre-Mortem** (2–5 plausible failure modes 6 months out, with mitigations or "accepted"). These come straight from the `draft.md` Decided/Open and Cut sections.
|
|
227
|
+
|
|
228
|
+
**Do NOT delete `draft.md`.** Retain it read-only as the agreed reference through plan → … → apply. `grimoire-apply` removes it with the change folder at finalize.
|
|
229
|
+
|
|
230
|
+
### 8. Validate (at projection)
|
|
231
|
+
|
|
232
|
+
- `.feature` files have valid Gherkin; every Feature has a user story; every Scenario has at least Given + When + Then.
|
|
233
|
+
- MADR records have valid YAML frontmatter (status, date).
|
|
234
|
+
- Manifest is complete and accurate; `complexity` is set.
|
|
235
|
+
- **Re-run the admission test on every scenario you wrote**: external actor, observable, domain language, survives reimplementation. Any scenario that now fails is slop — move it to `constraints.md` or a MADR.
|
|
236
|
+
- **Principles gate** (`../references/principles.md`): no fact written to two homes (DRY), no second way to do an existing thing (one right way), no reinvented wheel, no artifact created past the stated scope (KISS). Note: `draft.md` co-existing with the homes is **not** a DRY violation — it is the (soon-deleted) source the homes were projected from, not a parallel authority.
|
|
309
237
|
|
|
310
238
|
## Important
|
|
311
239
|
- ONE change at a time. Don't combine unrelated changes.
|
|
312
|
-
-
|
|
313
|
-
- **
|
|
314
|
-
-
|
|
315
|
-
-
|
|
316
|
-
-
|
|
317
|
-
- **Figma access token is read from `FIGMA_ACCESS_TOKEN`
|
|
240
|
+
- **`draft.md` is the only surface you design on.** Features, constraints, MADRs, and the manifest are **generated from it** at projection — never authored by hand in parallel during design.
|
|
241
|
+
- **Features describe actor-observable behavior, not implementation, and not invariants.** No external actor, not observable, or names a library/log-level/table → it's a constraint (→ `constraints.md`) or a decision (→ MADR). This is the #1 source of feature-file slop.
|
|
242
|
+
- **One fact, one home** (`../references/principles.md`). A capability lives in one `.feature`; a control in one constraint row; a decision in one MADR. Never the same fact in two homes (at rest).
|
|
243
|
+
- Decisions live in **one inline ledger** in `draft.md` while designing; they project to separate MADRs only at step 7. This is how coupled decisions stay legible during the thinking.
|
|
244
|
+
- Artifacts (post-projection) are edited **live on the branch** — never copied into `.grimoire/changes/`. `git diff` is the staging area.
|
|
245
|
+
- **Figma access token is read from `FIGMA_ACCESS_TOKEN` by the MCP server.** Never log it, never write it to config or any artifact (`manifest.md`, `consult.md`, `figma-snapshot.json`, `draft.md`). The MCP handles auth transparently.
|
|
318
246
|
|
|
319
247
|
## Done
|
|
320
|
-
When the user approves the
|
|
248
|
+
When the user approves the design and it has been projected, the workflow is complete.
|
|
249
|
+
`draft.md` remains as reference until `grimoire-apply` clears it. Present the change
|
|
250
|
+
directory path and suggest next steps:
|
|
321
251
|
- `grimoire-plan` to generate implementation tasks
|
|
322
|
-
- Or further iteration if the user wants changes
|
|
252
|
+
- Or further iteration on `draft.md` if the user wants changes
|
|
@@ -8,7 +8,8 @@ Loaded by skills that read a change's specs before acting (`grimoire-plan`, `gri
|
|
|
8
8
|
|
|
9
9
|
Per-change (under `.grimoire/changes/<change-id>/`):
|
|
10
10
|
|
|
11
|
-
- **`
|
|
11
|
+
- **`draft.md`** — the living design doc the change was designed on (diagram/sketch, decision ledger, pseudo-code, Decided/Open ledger). The single source the other artifacts were **projected** from at the end of `grimoire-draft`. Ephemeral: retained read-only as the agreed-design reference through the pipeline, deleted when `grimoire-apply` clears the change folder. Read it for the *intent and rationale* behind the projected artifacts; the features/constraints/decisions remain the authoritative homes.
|
|
12
|
+
- **`manifest.md`** — change summary, complexity level, and the Why. Level 3-4 also carry Assumptions, Pre-Mortem, and **Prior Art** (the build-vs-buy rationale). Generated from `draft.md` at projection.
|
|
12
13
|
- **`features/*.feature`** — behavioral specifications. Edited live in `features/` on the branch.
|
|
13
14
|
- **decision records** — architectural choices for this change, edited live in `.grimoire/decisions/`, including Cost of Ownership sections.
|
|
14
15
|
- **`tasks.md`** — the implementation plan (present once planned).
|