kataster 0.3.0 → 0.4.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/.claude/THIRD_PARTY_NOTICES.md +69 -0
- package/.claude/agents/acceptance-tester.md +7 -2
- package/.claude/agents/code-reviewer.md +7 -2
- package/.claude/agents/ux-designer.md +43 -38
- package/.claude/hooks/validate-docs.ts +2 -1
- package/.claude/lib/config.ts +1 -0
- package/.claude/lib/discovery.ts +129 -31
- package/.claude/lib/engineering.ts +12 -6
- package/.claude/package.json +1 -0
- package/.claude/settings.json +1 -2
- package/.claude/skills/adopt/SKILL.md +5 -3
- package/.claude/skills/backlog/SKILL.md +2 -2
- package/.claude/skills/bootstrap/SKILL.md +9 -7
- package/.claude/skills/domain-model/SKILL.md +1 -1
- package/.claude/skills/feature/SKILL.md +37 -11
- package/.claude/skills/feature/scripts/intake.ts +1 -1
- package/.claude/skills/groom-backlog/SKILL.md +19 -16
- package/.claude/skills/implement/SKILL.md +169 -63
- package/.claude/skills/implement/scripts/check-scenarios.ts +1 -1
- package/.claude/skills/implement/scripts/story-context.ts +1 -1
- package/.claude/skills/implement/scripts/verify.ts +1 -1
- package/.claude/skills/prototype/LOGIC.md +101 -0
- package/.claude/skills/prototype/SKILL.md +85 -0
- package/.claude/skills/prototype/UI.md +130 -0
- package/.claude/skills/review-stories/SKILL.md +39 -19
- package/.claude/skills/shape/SKILL.md +2 -2
- package/.claude/skills/user-stories/SKILL.md +109 -51
- package/.claude/skills/user-stories/schema/story.schema.json +6 -3
- package/.claude/skills/user-stories/scripts/lint-story.ts +56 -0
- package/.claude/skills/user-stories/templates/story-template.md +5 -2
- package/.claude/skills/ux-design/SKILL.md +30 -5
- package/.opencode/agents/acceptance-tester.md +8 -3
- package/.opencode/agents/code-reviewer.md +8 -3
- package/.opencode/agents/ux-designer.md +44 -39
- package/.opencode/commands/bootstrap.md +1 -1
- package/.opencode/commands/feature.md +1 -1
- package/.opencode/commands/groom-backlog.md +1 -1
- package/.opencode/commands/implement.md +1 -1
- package/.opencode/commands/review-stories.md +1 -1
- package/AGENTS.md +17 -0
- package/CHANGELOG.md +38 -0
- package/README.md +64 -7
- package/guide/brownfield.md +2 -2
- package/guide/concepts.md +26 -5
- package/guide/greenfield.md +4 -3
- package/guide/release.md +1 -1
- package/package.json +1 -1
- package/src/cli.mjs +42 -4
- package/src/install.mjs +62 -6
- package/templates/docs/product/ux-guidelines.md +2 -0
- package/templates/docs/prototypes/README.md +9 -0
- package/templates/docs/stories/README.md +10 -3
- package/templates/docs/workflow.md +38 -13
- package/.claude/agents/lead-dev.md +0 -50
- package/.claude/agents/product-owner.md +0 -39
- package/.claude/agents/requirements-engineer.md +0 -44
- package/.opencode/agents/lead-dev.md +0 -67
- package/.opencode/agents/product-owner.md +0 -59
- package/.opencode/agents/requirements-engineer.md +0 -58
|
@@ -77,24 +77,26 @@ and reason. Do not let it become a mood board.
|
|
|
77
77
|
|
|
78
78
|
## Phase 5 – Foundation stories and the first slice
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
Write the stories yourself as the spec engineer (the `user-stories` skill is the method), in two parts:
|
|
81
81
|
|
|
82
82
|
1. **Foundation tech tasks** – what every later story relies on: repository skeleton, the single quality command
|
|
83
83
|
(`verify`), CI, the test harness and test data approach, auth/roles if the vision needs them, deployment.
|
|
84
84
|
Each is a tech task with a checklist and `depends_on`, not a domain story. Keep them minimal: foundation just
|
|
85
85
|
in time, not a platform project.
|
|
86
86
|
2. **The first vertical slice** – the smallest set of stories that delivers one real end-to-end path from the
|
|
87
|
-
vision (e.g. "report → triage → resolve"), each a story with Gherkin scenarios, `ui` where a person sees
|
|
87
|
+
vision (e.g. "report → triage → resolve"), each a story with Gherkin scenarios, `ui: true` where a person sees
|
|
88
88
|
something.
|
|
89
89
|
|
|
90
|
-
Rules: at most
|
|
91
|
-
`events`; `status: draft`, then `review` when
|
|
90
|
+
Rules: one story = one command + its events on one aggregate, at most 4 scenarios; no implementation plan inside a
|
|
91
|
+
domain story; every domain story links `aggregate`, `command` and its `events`; `status: draft`, then `review` when
|
|
92
|
+
finished. The spec linter must be green before `ready-for-human-review`.
|
|
93
|
+
|
|
92
94
|
|
|
93
95
|
## Phase 6 – Review
|
|
94
96
|
|
|
95
|
-
Read `.claude/skills/review-stories/SKILL.md` and follow it with the story IDs from Phase 5. The
|
|
96
|
-
every `ready`. Fix what
|
|
97
|
-
|
|
97
|
+
Read `.claude/skills/review-stories/SKILL.md` and follow it with the story IDs from Phase 5. The spec linter is the
|
|
98
|
+
gate; the user approves every `ready`. Fix what it finds in the story (or in the model, when an event or aggregate
|
|
99
|
+
is missing) – never work around a lint error.
|
|
98
100
|
|
|
99
101
|
## Phase 7 – Wrap-up
|
|
100
102
|
|
|
@@ -47,7 +47,7 @@ Same word, different meaning in two places → a hint at a bounded context bound
|
|
|
47
47
|
- An aggregate protects invariants that must be consistent **immediately**. Everything else is eventually consistent via events/policies.
|
|
48
48
|
- Keep them small. Reference other aggregates by ID only.
|
|
49
49
|
- Per aggregate in `events.yaml`: `context`, `invariants` (as testable statements). Assign commands and events via `aggregate`.
|
|
50
|
-
- **An invariant is stated once, on the aggregate** (user, 2026-10-01). A command's `rules` list only what it adds beyond them: defaults, actor permissions no invariant carries, required input, checks across aggregate or context boundaries, and consequences of the transition. Everything the stored state has to satisfy is an invariant, not a rule – the
|
|
50
|
+
- **An invariant is stated once, on the aggregate** (user, 2026-10-01). A command's `rules` list only what it adds beyond them: defaults, actor permissions no invariant carries, required input, checks across aggregate or context boundaries, and consequences of the transition. Everything the stored state has to satisfy is an invariant, not a rule – the spec engineer reads both when deriving scenarios.
|
|
51
51
|
- Sign of a wrong aggregate: a command needs data from several aggregates to check a rule.
|
|
52
52
|
|
|
53
53
|
## 4. Logical Data Model (`docs/architecture/data-model.md`)
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: feature
|
|
3
|
-
description: Entry point for a new feature or change once the initial discovery is done – accepts a free-text idea, an existing story (`ST-NNN`) or a ticket (`#123`, `PROJ-123`, URL), grills the idea, runs a focused event storming, updates domain model and ADRs, derives stories into the backlog (local, or the tracker mirror) and runs the story review; bug tickets go to a regression story instead.
|
|
3
|
+
description: Entry point for a new feature or change once the initial discovery is done – accepts a free-text idea, an existing story (`ST-NNN`) or a ticket (`#123`, `PROJ-123`, URL), grills the idea, runs a focused event storming, updates domain model and ADRs, derives stories into the backlog (local, or the tracker mirror) and runs the story review; bug tickets go to a regression story instead; `--prototype` adds a throwaway prototype before the stories.
|
|
4
4
|
disable-model-invocation: true
|
|
5
|
-
argument-hint: "<idea | ST-NNN | #issue | PROJ-123 | URL>"
|
|
5
|
+
argument-hint: "<idea | ST-NNN | #issue | PROJ-123 | URL> [--prototype[=ui|logic]]"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# New Feature
|
|
9
9
|
|
|
10
10
|
The argument is a feature idea, an existing story or a ticket. Empty → ask the user for it first.
|
|
11
11
|
Pick a short kebab-case slug for it (e.g. `order-photos`); stories get the label `feature:<slug>`.
|
|
12
|
+
`--prototype[=ui|logic]` is a flag, not part of the idea: strip it before resolving a reference. It asks for a
|
|
13
|
+
prototype before the stories are written; without a branch the `prototype` skill picks it from the question.
|
|
12
14
|
|
|
13
15
|
## 0. Intake – when the argument is a reference
|
|
14
16
|
|
|
@@ -28,7 +30,7 @@ Follow the route:
|
|
|
28
30
|
|---|---|
|
|
29
31
|
| `continue-story` | Read that story and treat it as the idea. Its open questions are the first grilling frontier. Do not create a parallel feature. |
|
|
30
32
|
| `review-story` | Stop; run `/review-stories <id>` (or revise the story if it is still being written). |
|
|
31
|
-
| `implement-story` | Stop; the next command is `/implement <id
|
|
33
|
+
| `implement-story` | Stop; the next command is `/implement <id>` – with `--prototype` if the user asked for one. |
|
|
32
34
|
| `new-story` | Finished behaviour is final; continue as a new feature and name the old story as the predecessor. |
|
|
33
35
|
| `bug` | Use the bug path below, not the feature pipeline. |
|
|
34
36
|
| `feature` | Continue with step 1. |
|
|
@@ -58,29 +60,53 @@ Do not run an event storming for a bug and do not create a feature slug unless t
|
|
|
58
60
|
Read `docs/product/vision.md`, `CONTEXT.md`, `docs/domain/events.yaml`, `docs/domain/context-map.md`, `docs/architecture/data-model.md`, `docs/adr/`, `docs/stories/BACKLOG.md`. Find out what already exists for this idea (events, stories, hotspots) before asking anything. With an intake result, use its source and matching story instead of searching from scratch. If a linked story exists, pull the tracker first (`/backlog-sync pull`) so the mirror is current.
|
|
59
61
|
|
|
60
62
|
## 2. Grill the idea
|
|
61
|
-
Call the `skill` tool four times, for `grilling`, `domain-model`, `architect` and `ux-design` (the first three are the set of `/grill-with-docs`, which can't be called from a skill). Grill the user until the frontier is empty and they confirm a shared understanding. The grilling carries the three perspectives the
|
|
62
|
-
- **
|
|
63
|
-
- **
|
|
63
|
+
Call the `skill` tool four times, for `grilling`, `domain-model`, `architect` and `ux-design` (the first three are the set of `/grill-with-docs`, which can't be called from a skill). Grill the user until the frontier is empty and they confirm a shared understanding. The grilling carries the three perspectives the spec linter cannot check – product, engineering, UX. With an intake result, the ticket's claims and the intake's `signals` seed the frontier; unresolved comments and contradictions are the first questions. Typical branches:
|
|
64
|
+
- **Product**: Which problem, for which user group, and what value? Measurable outcome? Does it fit the vision, or touch a non-goal? If it changes scope → update `docs/product/vision.md` with the user. Must vs. could – what ships first?
|
|
65
|
+
- **Engineering**: Which existing code, data and stories change? Is there a migration? What is hard to test? Where does it cut into stories – one command per story, at most 4 scenarios?
|
|
64
66
|
- Which existing processes, events and stories does it change? What's explicitly out of scope?
|
|
65
|
-
- **UX – does a person see anything?** Almost always yes – then the UX frontier of `ux-design` belongs in the rounds: entry point, the screen's one job, what is shown before acting, what happens afterwards, the rejected, empty, full and no-permission cases, and the UI wording. A feature whose screens nobody named gets them by accident. Stories with a frontend part get
|
|
67
|
+
- **UX – does a person see anything?** Almost always yes – then the UX frontier of `ux-design` belongs in the rounds: entry point, the screen's one job, what is shown before acting, what happens afterwards, the rejected, empty, full and no-permission cases, and the UI wording. A feature whose screens nobody named gets them by accident. Stories with a frontend part get `ui: true`.
|
|
68
|
+
- **Prototype – is paper enough?** When the UX frontier leaves a structural layout choice, a flow or a state model that cannot be settled in words, the UX lens proposes a prototype: one question, the branch (`ui` or `logic`), the variants or scenarios, and a timebox. The user decides. `--prototype` makes it explicit. Do not propose one for polish or for a question a guideline already answers. If it is agreed, run step 2b before the event storming.
|
|
66
69
|
- New or changed terms → `CONTEXT.md` inline.
|
|
67
70
|
- An architectural trade-off → ADR (`status: proposed`) only if the architect skill's three criteria hold.
|
|
68
71
|
|
|
69
72
|
Don't move on before the user confirms.
|
|
70
73
|
|
|
74
|
+
## 2b. Prototype (optional)
|
|
75
|
+
|
|
76
|
+
Only when the user asked (`--prototype`) or the grilling agreed on it. Load the `prototype` skill and follow
|
|
77
|
+
it. In short:
|
|
78
|
+
|
|
79
|
+
1. **Question and branch.** Name the one question and pick `ui` (what should it look like) or `logic` (does
|
|
80
|
+
the state model feel right). Write both at the top of the prototype and in its `README.md`.
|
|
81
|
+
2. **Delegate to `ux-designer`** with the question, the branch, the variants/scenarios, the timebox and the
|
|
82
|
+
target `docs/prototypes/<slug>/`. It writes a self-contained HTML prototype there – no application code,
|
|
83
|
+
no tests, no persistence, no shell.
|
|
84
|
+
3. **The user looks and decides.** Open the file, flip the variants or press the buttons. The verdict is the
|
|
85
|
+
user's, not the agent's.
|
|
86
|
+
4. **Capture.** The decision goes to `ux-designer` for `docs/product/ux-guidelines.md` (a G-number when it is
|
|
87
|
+
a recurring rule). Commit `docs/prototypes/<slug>/` on a throwaway branch `prototype/<slug>`, push it only
|
|
88
|
+
if the user wants to share it, then return to the branch you were on. The branch is never merged.
|
|
89
|
+
5. **Into the story.** In section 5 you write the verdict and the branch pointer into the story's `## Context`:
|
|
90
|
+
`Prototype: prototype/<slug> – <question> – <verdict>`, and the scenarios reflect the decision. The
|
|
91
|
+
`ux-designer` never writes the story itself.
|
|
92
|
+
|
|
93
|
+
If the question needs the real application (an existing page, real data), say so: that is an in-app prototype
|
|
94
|
+
and belongs to `/implement`, not to discovery. If the prototype does not answer the question within its
|
|
95
|
+
timebox, stop and record what is known.
|
|
96
|
+
|
|
71
97
|
## 3. Focused event storming
|
|
72
98
|
Read `.claude/skills/event-storming/SKILL.md` and follow it with the feature as focus: phases 1–6 (phase 0 is covered by step 2), 7–8 only if aggregates or contexts are affected. Capture the feature as its own flow (`FLOW-<FeatureName>`) and write `docs/domain/events.yaml` after every phase.
|
|
73
99
|
|
|
74
100
|
## 4. Domain model & architecture
|
|
75
101
|
- Contexts, aggregates or the data model affected → delegate to `domain-architect` with the file paths, the changed/new IDs from `events.yaml` and a clear task.
|
|
76
102
|
- An architectural trade-off came up that wasn't recorded during grilling → offer an ADR per the architect skill's three criteria (`status: proposed`, the user accepts).
|
|
77
|
-
- A UX decision changes or adds a guideline → delegate to `ux-designer`: write exactly these decisions into `docs/product/ux-guidelines.md`. The audit of existing screens belongs to `/groom-backlog`, not to the feature.
|
|
103
|
+
- A UX decision changes or adds a guideline → delegate to `ux-designer`: write exactly these decisions into `docs/product/ux-guidelines.md`. A prototype verdict is a decision like any other; the branch pointer and the verdict go into the story through step 5. The audit of existing screens belongs to `/groom-backlog`, not to the feature.
|
|
78
104
|
|
|
79
105
|
## 5. Stories
|
|
80
|
-
|
|
106
|
+
Write the stories yourself as the spec engineer (the `user-stories` skill is the method): derive one story per new or changed command, policy or read model; name `aggregate` and `command` (exactly one each), the event/command IDs, `ui: true` for every story with a frontend part, `type: chore`/`task` for non-domain work, the label `feature:<slug>`, the label `bug` for the bug path, the source reference (`Source: <ref> (<url>)`) for every story derived from a ticket, the UX decisions from step 2 (with the G-numbers of the guidelines they reference), the prototype verdict and branch pointer from step 2b, and existing stories that need revising. Do not merge two commands into one story; if the cut needs more than 4 scenarios, split it. Finished stories get `status: review` and are run through the spec linter.
|
|
81
107
|
|
|
82
108
|
## 6. Review
|
|
83
|
-
Read `.claude/skills/review-stories/SKILL.md` and follow it with the story IDs from step 5 as the arguments (only this feature's stories, not everything in `review`). The user
|
|
109
|
+
Read `.claude/skills/review-stories/SKILL.md` and follow it with the story IDs from step 5 as the arguments (only this feature's stories, not everything in `review`). The spec linter must be green before a story reaches `ready-for-human-review`; the user approves every change and every `ready`. There is no separate review subagent.
|
|
84
110
|
|
|
85
111
|
## 7. Wrap-up
|
|
86
|
-
Summarize: the source and the route taken (idea, ticket, existing story or bug), glossary changes, new/changed events, ADRs proposed, stories created and their review outcome (`ready` vs. still open), open hotspots/questions. Point to `docs/stories/BACKLOG.md`, where `ready` stories are queued for the engineering workflow. For a bug, say which documented rule was restored, or that the rule changed and became a feature.
|
|
112
|
+
Summarize: the source and the route taken (idea, ticket, existing story or bug), glossary changes, new/changed events, ADRs proposed, a prototype run and its verdict (if any), stories created and their review outcome (`ready` vs. still open), open hotspots/questions. Point to `docs/stories/BACKLOG.md`, where `ready` stories are queued for the engineering workflow. For a bug, say which documented rule was restored, or that the rule changed and became a feature.
|
|
@@ -94,7 +94,7 @@ function storyRef(story: d.Story): StoryRef {
|
|
|
94
94
|
path: d.rel(story.path),
|
|
95
95
|
title: String(story.meta.title ?? ""),
|
|
96
96
|
status: String(story.meta.status ?? ""),
|
|
97
|
-
type: String(story.meta.type ?? "
|
|
97
|
+
type: String(story.meta.type ?? "domain"),
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
100
|
|
|
@@ -15,7 +15,8 @@ every done story, every ADR and every answered open question since then may have
|
|
|
15
15
|
or differently important. Nothing here is a formality – a grooming run that changes nothing was a wasted run or a
|
|
16
16
|
healthy backlog, and you have to be able to say which.
|
|
17
17
|
|
|
18
|
-
Do **not** fix anything yourself. Grooming produces a decision for the user
|
|
18
|
+
Do **not** fix anything yourself. Grooming produces a decision for the user. The main session carries the product and
|
|
19
|
+
engineering lenses; it does not delegate them to simulated roles.
|
|
19
20
|
|
|
20
21
|
## 1. Mechanical health check
|
|
21
22
|
|
|
@@ -39,21 +40,23 @@ rows in `OPEN_QUESTIONS.md`, and the "revisit when …" lines parked in `docs/re
|
|
|
39
40
|
this list to the subagents – they cannot see it, and without it they re-read the same stories that were already
|
|
40
41
|
reviewed once.
|
|
41
42
|
|
|
42
|
-
## 3. Challenge
|
|
43
|
+
## 3. Challenge – two lenses, one pass
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
The main session holds both lenses at once. Write down which one produced each finding; do not average a conflict
|
|
46
|
+
between them away.
|
|
45
47
|
|
|
46
|
-
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
-
|
|
48
|
+
- **Value** – is the value still real and still in the vision? Is the story already covered by what was built? Does
|
|
49
|
+
the MVP slice still hold? Which `must` is not a `must` any more, and which `could` turned out to be one? Which
|
|
50
|
+
need from the vision still has no story?
|
|
51
|
+
- **Build** – do `depends_on`, `size` and `risk` still fit **now that the code exists**? Which story has become
|
|
50
52
|
smaller because the foundation is there, which bigger? Which dependency is technical fiction? Which story should
|
|
51
|
-
be split,
|
|
52
|
-
- `ux-designer` – only for stories with the label `ui` (or an obvious frontend part): does the story still match
|
|
53
|
-
`docs/product/ux-guidelines.md`, and which one builds a screen that a newer story has replaced?
|
|
53
|
+
be split (one command!), re-typed as `chore`/`task`, or dropped?
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
For stories with `ui: true` (or an obvious frontend part), ask the `ux-designer` only when a concrete question needs
|
|
56
|
+
it – component/pattern, an open UX decision, or a prototype. It advises; it does not gate.
|
|
57
|
+
|
|
58
|
+
Do not hand the backlog to subagents: the change list from step 2 is context they cannot see, and re-reading stories
|
|
59
|
+
that were already reviewed once is the cost this workflow removes.
|
|
57
60
|
|
|
58
61
|
## 4. Consolidate
|
|
59
62
|
|
|
@@ -61,22 +64,22 @@ Write `docs/reviews/YYYY-MM-DD-backlog-grooming.md`:
|
|
|
61
64
|
|
|
62
65
|
- the health-check findings with what they turned out to mean
|
|
63
66
|
- per challenged story: keep / revise / split / merge / drop, with the reason and who said it
|
|
64
|
-
- conflicts between the
|
|
67
|
+
- conflicts between the two lenses – name them, don't average them away
|
|
65
68
|
- proposed new stories, and stories proposed for `priority: wont`
|
|
66
69
|
- what explicitly stays as it is, so the next run does not re-litigate it
|
|
67
70
|
|
|
68
71
|
## 5. The user decides
|
|
69
72
|
|
|
70
73
|
Present it in rounds, at most 3 questions at a time, each with a recommended answer. Adopt nothing without consent.
|
|
71
|
-
A disagreement between
|
|
74
|
+
A disagreement between value and build is a question for the user, not something to resolve on their behalf.
|
|
72
75
|
|
|
73
76
|
## 6. Apply
|
|
74
77
|
|
|
75
|
-
- Content changes →
|
|
78
|
+
- Content changes → edit the story in the main session, referencing the grooming file; then re-run the spec linter.
|
|
76
79
|
- **Dropped stories are never deleted**: they get `priority: wont` and keep their file, so the decision stays
|
|
77
80
|
traceable. A story that is wrong rather than unwanted goes back to `status: review` and through `/review-stories`.
|
|
78
81
|
- A `done` story is never reopened – a change to finished behaviour is a new story.
|
|
79
|
-
- New stories from the grooming get `status: draft` and go through `/review-stories` like any other.
|
|
82
|
+
- New stories from the grooming get `status: draft` and go through `/review-stories` like any other (linter → human).
|
|
80
83
|
- With a tracker, push the applied changes (`/backlog-sync push`) before the wrap-up, so Jira/GitHub and the mirror
|
|
81
84
|
agree. A story that is not linked yet stays a local draft until the push creates it.
|
|
82
85
|
|
|
@@ -1,117 +1,223 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: implement
|
|
3
|
-
description: Engineering workflow – implements one story from docs/stories/
|
|
3
|
+
description: Engineering workflow – implements one story from docs/stories/ on its own branch, verifies, reviews scaled to the diff, refactors and hands the pull request to the user; `type: chore`/`task` (or `--fast`) takes the fast lane without Gherkin matching or formal reviews; `--prototype` settles an open UI question first.
|
|
4
4
|
disable-model-invocation: true
|
|
5
|
-
argument-hint: "[ST-NNN – empty = next ready story]"
|
|
5
|
+
argument-hint: "[ST-NNN – empty = next ready story] [--fast] [--prototype[=ui|logic]]"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Implement a Story
|
|
9
9
|
|
|
10
|
-
Story: the arguments from the invocation (empty → `node .claude/skills/implement/scripts/next-story.ts`; a story
|
|
10
|
+
Story: the arguments from the invocation (empty → `node .claude/skills/implement/scripts/next-story.ts`; a story
|
|
11
|
+
already `in-progress` is finished first). `--fast` and `--prototype[=ui|logic]` are flags, not the story ID: strip
|
|
12
|
+
them before resolving the story.
|
|
11
13
|
|
|
12
|
-
The main session writes the code; subagents only review
|
|
14
|
+
The main session writes the code; subagents only review, and only in the full domain lane. One checkpoint belongs to
|
|
15
|
+
the user: the **merge** (step 7). Everything before it runs without asking – a `ready` story is good enough to build
|
|
16
|
+
up to the pull request, and the acceptance tester accepts the story, not the user – unless the story turns out to be
|
|
17
|
+
wrong (see *When the story is wrong*), a seam is missing from the catalog (step 2), or the user asked for a prototype
|
|
18
|
+
(step 1b – the verdict is theirs).
|
|
13
19
|
|
|
14
|
-
|
|
20
|
+
## Two lanes
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
| Lane | Stories | What changes |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| **Domain** (default) | `type: domain` (legacy `story`) | TDD per Gherkin scenario, scenario ↔ test traceability, diff-scaled review, acceptance tester's verdict |
|
|
25
|
+
| **Fast** | `type: chore`, `type: task`, or `--fast` on such a story | branch → implement → lint/typecheck/unit tests → verify → PR; no Gherkin matching, no formal review pass, the user merges |
|
|
26
|
+
|
|
27
|
+
`--fast` on a `type: domain` story is ignored: the story has a command and scenarios, so it takes the domain lane.
|
|
28
|
+
If a "chore" turns out to touch a command, a migration or authorization, stop and say so – risk decides the lane,
|
|
29
|
+
not the label.
|
|
30
|
+
|
|
31
|
+
Engineering conventions: `docs/engineering/conventions.md` – read it if it exists; it describes the module layout,
|
|
32
|
+
how commands and read models are built, and the **seam catalog**.
|
|
33
|
+
|
|
34
|
+
Project profile: `.claude/project.json` – default branch, code roots, commands, preview provider, pull-request tool.
|
|
35
|
+
Read it instead of assuming `main`, `npm` or GitHub.
|
|
17
36
|
|
|
18
37
|
## 1. Prepare
|
|
19
|
-
1. Working tree clean, on the default branch (`repo.defaultBranch`), up to date (`git pull`). Otherwise stop and tell
|
|
38
|
+
1. Working tree clean, on the default branch (`repo.defaultBranch`), up to date (`git pull`). Otherwise stop and tell
|
|
39
|
+
the user.
|
|
20
40
|
2. With a tracker (`backlog.provider` ≠ `local`), pull first (`/backlog-sync pull`) and check that the story has its
|
|
21
41
|
`external` key – an unlinked story never reaches `ready`, so stop and report instead of implementing a stale mirror.
|
|
22
|
-
3. `node .claude/skills/implement/scripts/story-context.ts ST-NNN` – the context pack: story, exact test titles,
|
|
23
|
-
|
|
42
|
+
3. `node .claude/skills/implement/scripts/story-context.ts ST-NNN` – the context pack: story, exact test titles,
|
|
43
|
+
dependencies, events/commands/rules/invariants, glossary, data model, ADRs. Read it completely; it is your
|
|
44
|
+
source, not memory.
|
|
45
|
+
4. `git switch -c st-NNN-<slug>` (slug from the file name), then
|
|
46
|
+
`node .claude/skills/implement/scripts/story-status.ts ST-NNN in-progress` and commit `ST-NNN: start`.
|
|
47
|
+
5. **Pick the lane** and say it in one line: fast lane for `chore`/`task`, domain lane otherwise. The fast lane is
|
|
48
|
+
a shortcut for non-domain work, never a way to skip a risk review.
|
|
49
|
+
|
|
50
|
+
## 1b. Prototype (only when asked)
|
|
51
|
+
|
|
52
|
+
Only with `--prototype`, or when the user explicitly asks during the story. A `ui: true` story whose screen shape is
|
|
53
|
+
still open was not `ready`; this is the exception that settles it before the test plan. Load the `prototype` skill and
|
|
54
|
+
follow it.
|
|
55
|
+
|
|
56
|
+
1. **Standalone first.** Delegate to `ux-designer`: question, branch (`ui` or `logic`), variants/scenarios, timebox,
|
|
57
|
+
target `docs/prototypes/<slug>/`. It writes the self-contained HTML file. The user decides.
|
|
58
|
+
2. **In-app only when the question needs the real page** – an existing route, real data, the real header and
|
|
59
|
+
sidebar. You build the throwaway route or the `?variant=` gate yourself, following the project's routing
|
|
60
|
+
convention; the `ux-designer` defines the question and variants and reviews the result. The prototype stays out of
|
|
61
|
+
the production path and is captured on `prototype/<slug>`.
|
|
62
|
+
3. **Capture.** Commit `docs/prototypes/<slug>/` (or the in-app prototype) on `prototype/<slug>`, return to the story
|
|
63
|
+
branch, and write the verdict into the story's `## Context`: `Prototype: prototype/<slug> – <question> – <verdict>`.
|
|
64
|
+
A recurring rule goes to `ux-designer` for `docs/product/ux-guidelines.md`.
|
|
65
|
+
4. **Then decide.** If the prototype only settles layout and the scenarios still hold, continue with step 2. If it
|
|
66
|
+
changes behaviour or a scenario, the story goes back to `review` (see *When the story is wrong*), the main session
|
|
67
|
+
revises it, the spec linter runs and the user approves it again. The branch stays.
|
|
24
68
|
|
|
25
69
|
## 2. Test plan
|
|
26
|
-
|
|
70
|
+
|
|
71
|
+
**Domain lane.** Call the `skill` tool for `tdd` (and `codebase-design` when a new module or interface is involved).
|
|
27
72
|
Show one table and go on to step 3 without waiting:
|
|
28
73
|
|
|
29
74
|
| Scenario (exact test title) | Seam | Test type | Test file |
|
|
30
75
|
|---|---|---|---|
|
|
31
76
|
|
|
32
|
-
-
|
|
33
|
-
- Seams come from the seam catalog in the engineering conventions. A seam not in the catalog is a decision for the
|
|
77
|
+
- One row per Gherkin scenario – at most 4 by the 1-command rule.
|
|
78
|
+
- Seams come from the seam catalog in the engineering conventions. A seam not in the catalog is a decision for the
|
|
79
|
+
user – the one case where you stop here and ask.
|
|
34
80
|
- Name anything the story leaves open. Don't guess – see *When the story is wrong*.
|
|
35
81
|
|
|
36
82
|
Seams from the catalog are the "confirmed seams" the tdd skill requires; the user approved the catalog.
|
|
37
83
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
84
|
+
**Fast lane.** No scenario table. Name the files or packages you will touch and the unit/integration tests that
|
|
85
|
+
cover them; the story's checklist is the acceptance. If it already has scenarios, keep them as a sanity check but do
|
|
86
|
+
not create `ST-NNN:` test titles.
|
|
87
|
+
|
|
88
|
+
## 3. Red → green (domain) / implement (fast)
|
|
89
|
+
|
|
90
|
+
**Domain lane:**
|
|
91
|
+
- Per row: write the test (title exactly `ST-NNN: <scenario title>`), run it and see it fail for the right reason,
|
|
92
|
+
write the minimal code to pass, run it green. Commit: `ST-NNN: <scenario title>`.
|
|
93
|
+
- Domain IDs in the code: commands, events, read models and policies carry their ID from `events.yaml`
|
|
94
|
+
(`CMD-ReportProblem`, `EVT-ProblemReported`, …). New code uses the words of `CONTEXT.md`; a new term goes into
|
|
95
|
+
`CONTEXT.md` first (domain-model skill).
|
|
96
|
+
- Never weaken or delete an existing test to get green. If a test from an earlier story blocks you, its story and
|
|
97
|
+
this one contradict each other → *When the story is wrong*.
|
|
98
|
+
|
|
99
|
+
**Fast lane:**
|
|
100
|
+
- Implement the task, keep the change as small as the checklist says, and add or update unit tests where the change
|
|
101
|
+
can break behaviour. No test-title matching, no scenario traceability.
|
|
102
|
+
- Tick each checklist item in the story file as it becomes true (`- [x] …`).
|
|
103
|
+
- If the work turns into domain behaviour (a new/changed command, event or invariant), stop: the story is the wrong
|
|
104
|
+
type. Send it back to `review` as a `domain` story instead of deciding it in code.
|
|
105
|
+
|
|
106
|
+
**Both lanes** – hooks help on the way: formatting and lint after every write, the quick gate (type check + related
|
|
107
|
+
tests) before you finish a turn. In a monorepo, run the affected set for the packages you touched before the full
|
|
108
|
+
gate: `node .claude/skills/implement/scripts/affected.ts --changed <files>` (or `--base <defaultBranch>`), then
|
|
109
|
+
execute the printed command. It follows shared-library dependents; `verify.ts` still runs everything at the end.
|
|
46
110
|
|
|
47
111
|
## 4. Verify
|
|
48
|
-
`node .claude/skills/implement/scripts/verify.ts` (with `--e2e` when browser tests exist) must be green: lint incl.
|
|
112
|
+
`node .claude/skills/implement/scripts/verify.ts` (with `--e2e` when browser tests exist) must be green: lint incl.
|
|
113
|
+
module boundaries, type check, tests, events and stories valid, scenario ↔ test and domain ID traceability. Language
|
|
114
|
+
warnings: fix or justify.
|
|
49
115
|
|
|
50
|
-
The full `--e2e` run happens **once, before the push**. During red → green run only the spec you are working on;
|
|
116
|
+
The full `--e2e` run happens **once, before the push**. During red → green run only the spec you are working on;
|
|
117
|
+
after the refactor (step 6) run `verify.ts` without `--e2e` plus the specs the refactor touched – CI runs every
|
|
118
|
+
browser test on the pull request anyway (check `e2e`).
|
|
51
119
|
|
|
52
|
-
## 5. Review (
|
|
53
|
-
Push the branch (`git push -u origin st-NNN-<slug>`) so a preview deployment exists, when the project has one
|
|
54
|
-
(`review.preview` in `.claude/project.json`: `vercel`, `netlify`, … – use the provider's MCP or CLI, or the pull
|
|
55
|
-
request's preview comment). Otherwise there is no preview and the reviewers work from the code.
|
|
120
|
+
## 5. Review (domain lane only, scaled to the diff)
|
|
56
121
|
|
|
57
|
-
|
|
122
|
+
**Fast lane: skip this step.** No `code-reviewer`, no `acceptance-tester`, no review file. The gate is step 4 plus
|
|
123
|
+
the user's merge. If the diff touches authorization, input handling, a migration or security headers, say so and offer
|
|
124
|
+
the normal review anyway – the lane follows the risk, not the label.
|
|
58
125
|
|
|
59
|
-
**
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
126
|
+
**Domain lane.** Push the branch (`git push -u origin st-NNN-<slug>`) so a preview deployment exists, when the project
|
|
127
|
+
has one (`review.preview` in `.claude/project.json`: `vercel`, `netlify`, … – use the provider's MCP or CLI, or the
|
|
128
|
+
pull request's preview comment). Otherwise there is no preview and the reviewers work from the code.
|
|
129
|
+
|
|
130
|
+
Pick the lane from the **diff**, not from a size label:
|
|
131
|
+
|
|
132
|
+
**Light lane** – all of these hold: the diff is texts, layout, styles, links or docs; no command or route added or
|
|
133
|
+
changed; no input handling (no request handler, form action); no migration; no new dependency.
|
|
134
|
+
- Only `acceptance-tester` – task: story ID, base ref, the preview URL (if known), and: *also check the diff briefly
|
|
135
|
+
against the engineering conventions (texts from the catalogs, the shared page frames, domain language) and list
|
|
136
|
+
deviations as minors.* Writes `docs/reviews/ST-NNN-acceptance.md`.
|
|
63
137
|
- No `code-reviewer`, no extra code or security pass.
|
|
64
138
|
|
|
65
139
|
**Normal lane** – everything else. Start in **one** message:
|
|
66
140
|
- `code-reviewer` – task: story ID, base ref, the context pack command. Writes `docs/reviews/ST-NNN-code-review.md`.
|
|
67
141
|
- `acceptance-tester` – task: story ID, base ref, the preview URL (if known). Writes `docs/reviews/ST-NNN-acceptance.md`.
|
|
68
|
-
- Only
|
|
69
|
-
-
|
|
142
|
+
- Only when the **diff** touches the command layer or other shared platform code: ask the `code-reviewer` for a
|
|
143
|
+
second, bug-focused pass over the diff.
|
|
144
|
+
- Only when the **diff** touches input handling, login/roles/session, uploads or files, or security headers/CSP: ask
|
|
145
|
+
the `code-reviewer` for a security-focused pass.
|
|
70
146
|
|
|
71
|
-
|
|
147
|
+
Both reviewers report findings and never create stories. A finding is **fixed in this story** or becomes an open
|
|
148
|
+
question to the developer (step 6) – there is no follow-up ticket.
|
|
72
149
|
|
|
73
|
-
|
|
150
|
+
Say which lane you picked and why in one line.
|
|
74
151
|
|
|
75
152
|
## 6. Refactor
|
|
76
|
-
- Fix all blockers and majors **inside this story**, and the minors you agree with; say which minors you skip and why.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
153
|
+
- Fix all blockers and majors **inside this story**, and the minors you agree with; say which minors you skip and why.
|
|
154
|
+
Where a finding offers options, apply the recommended one without asking; ask only when no option is recommended.
|
|
155
|
+
- **No follow-up stories from reviews.** A finding that is too large for this story is either:
|
|
156
|
+
1. a **question to the developer** in the review file and in the wrap-up (with evidence and options), or
|
|
157
|
+
2. a line in `## Out of Scope` / a row in `OPEN_QUESTIONS.md` when it is a real decision for the user.
|
|
158
|
+
Only the main session and the user decide whether it becomes a new story; the reviewers never do.
|
|
159
|
+
- Refactor only with green tests; the tests must not change unless they were wrong (then say so). Run `affected.ts`
|
|
160
|
+
for the touched packages, then `node .claude/skills/implement/scripts/verify.ts` again (without `--e2e`) plus the
|
|
161
|
+
browser specs the refactor touched – see step 4.
|
|
162
|
+
|
|
163
|
+
## 7. Done, acceptance and merge → user checkpoint
|
|
164
|
+
|
|
165
|
+
**Fast lane:** tick the last checklist item, then
|
|
166
|
+
`node .claude/skills/implement/scripts/story-status.ts ST-NNN done` (it refuses while a checklist item is open).
|
|
167
|
+
Commit `ST-NNN: done`, push, open the pull request.
|
|
168
|
+
|
|
169
|
+
**Domain lane:** the **acceptance tester's verdict is the acceptance**: the story is `done` in the pull request, so
|
|
170
|
+
the user only merges.
|
|
171
|
+
1. After the refactor, check the verdict in `docs/reviews/ST-NNN-acceptance.md`. `accepted` or `accepted with
|
|
172
|
+
remarks` → continue. `not accepted` → fix the gaps in the story and run the `acceptance-tester` again, until it
|
|
173
|
+
accepts. Only when something goes badly wrong – the verdict stays `not accepted` after a second round, a scenario
|
|
174
|
+
can't be met as written, the preview shows a defect the tester couldn't see – ask the user, the way *When the story
|
|
175
|
+
is wrong* describes.
|
|
176
|
+
2. `node .claude/skills/implement/scripts/story-status.ts ST-NNN done` – refuses unless every scenario has its test
|
|
177
|
+
(domain) or every checklist item is ticked (chore/task/tech task/spike) and all dependencies are done. Commit
|
|
178
|
+
`ST-NNN: done`, push.
|
|
92
179
|
- GitHub: the status change closes the linked issue.
|
|
93
|
-
- Jira: `story-status.ts` prints the transition it could not make (MCP is agent-only). Run
|
|
94
|
-
`jira_transition_issue` on the printed key, then push the story body once
|
|
95
|
-
|
|
96
|
-
|
|
180
|
+
- Jira: `story-status.ts` prints the transition it could not make (MCP is agent-only). Run
|
|
181
|
+
`jira_get_transitions` + `jira_transition_issue` on the printed key, then push the story body once
|
|
182
|
+
(`/backlog-sync push`).
|
|
183
|
+
|
|
184
|
+
**Both lanes – the pull request:**
|
|
185
|
+
3. Title `ST-NNN: <story title>`, body = the scenarios as a checklist (domain) or the task checklist (fast lane),
|
|
186
|
+
links to the story and the review files (if any), the acceptance verdict (domain), the preview URL, remaining
|
|
187
|
+
minors/questions, and anything the user must approve (a conventions change). (No `gh` CLI, or it isn't
|
|
188
|
+
authenticated: push and give the user the compare URL `git push` prints.)
|
|
189
|
+
4. **The user merges** – on the preview if they want to look first. Afterwards: back to the default branch and
|
|
190
|
+
`git pull`.
|
|
97
191
|
|
|
98
192
|
## 8. Wrap-up
|
|
99
|
-
Summarize in a few lines: scenarios implemented, review findings fixed/skipped,
|
|
100
|
-
|
|
101
|
-
-
|
|
193
|
+
Summarize in a few lines: lane taken, scenarios implemented or task completed, review findings fixed/skipped, open
|
|
194
|
+
questions handed to the developer, glossary/ADR changes. Then:
|
|
195
|
+
- Suggest `/improve-codebase-architecture` after the foundation stories, when a bounded context is complete, or about
|
|
196
|
+
every 8–10 done stories.
|
|
197
|
+
- Name the next story (`node .claude/skills/implement/scripts/next-story.ts`) and tell the user to start it in a fresh
|
|
198
|
+
session (`/new`, then `/implement`): every turn re-reads the whole session, so a second story in the same one costs
|
|
199
|
+
several times the first.
|
|
102
200
|
|
|
103
201
|
## Spikes
|
|
104
202
|
A spike answers its **Question** within its **Timebox** – no test plan, no TDD for throwaway experiments.
|
|
105
|
-
-
|
|
106
|
-
|
|
203
|
+
- A UX or state-model spike is a prototype: load the `prototype` skill, keep the question and timebox in the story,
|
|
204
|
+
and capture the verdict the same way (step 1b).
|
|
205
|
+
- Before starting, tell the user the timebox and what will be kept (skeleton code that becomes the application gets
|
|
206
|
+
tests and passes verify).
|
|
207
|
+
- Tick each checklist item in the story file as it is answered; write results where the item says (an ADR's
|
|
208
|
+
consequences, `OPEN_QUESTIONS.md`). A new decision → ADR with `status: proposed` (architect skill); the user accepts.
|
|
107
209
|
- Timebox exhausted → stop, document what is known, and ask the user how to continue.
|
|
108
210
|
- Review: `code-reviewer` only for code that is kept; `acceptance-tester` checks the checklist evidence.
|
|
109
211
|
|
|
110
212
|
## When the story is wrong
|
|
111
|
-
Never guess. When a scenario contradicts another story, a rule or an ADR, can't be tested as written, or leaves a
|
|
213
|
+
Never guess. When a scenario contradicts another story, a rule or an ADR, can't be tested as written, or leaves a
|
|
214
|
+
decision open:
|
|
112
215
|
1. Stop implementing that part. Mark it `[OPEN]` in the story and add a row to `docs/stories/OPEN_QUESTIONS.md`.
|
|
113
|
-
2. `node .claude/skills/implement/scripts/story-status.ts ST-NNN review` and tell the user. The fix goes through
|
|
114
|
-
|
|
216
|
+
2. `node .claude/skills/implement/scripts/story-status.ts ST-NNN review` and tell the user. The fix goes through
|
|
217
|
+
discovery in the main session: revise the story, run the spec linter, and let the user approve it again
|
|
218
|
+
(`/review-stories`). Work already done on the branch stays.
|
|
219
|
+
3. New domain term → `CONTEXT.md` (domain-model skill). Architecture deviation → a `proposed` ADR (architect skill).
|
|
220
|
+
An accepted ADR is never edited; the hooks block it.
|
|
115
221
|
4. A `done` story is never reopened – a change to finished behaviour is a new story.
|
|
116
222
|
|
|
117
223
|
## Foundation stories
|
|
@@ -36,7 +36,7 @@ for (const [id, scenarios] of superseded) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
for (const [id, s] of stories) {
|
|
39
|
-
if (only ? id !== only : !["in-progress", "done"].includes(s.meta.status) || s.meta
|
|
39
|
+
if (only ? id !== only : !["in-progress", "done"].includes(s.meta.status) || !d.isDomain(s.meta)) continue;
|
|
40
40
|
const { covered, missing: untested } = e.scenarioCoverage(s, titles);
|
|
41
41
|
const missing = untested.filter((sc) => !superseded.get(id)?.has(sc));
|
|
42
42
|
for (const sc of missing) {
|
|
@@ -40,7 +40,7 @@ const out: string[] = [`# Context pack – ${id}: ${story.meta.title}`, ""];
|
|
|
40
40
|
|
|
41
41
|
// Story
|
|
42
42
|
out.push("## Story file", "", `\`${d.rel(story.path)}\``, "", "````markdown", storyText.trimEnd(), "````", "");
|
|
43
|
-
if (story.meta
|
|
43
|
+
if (d.isDomain(story.meta)) {
|
|
44
44
|
out.push("## Test titles (exact)", "", "Every scenario gets one test with exactly this title:", "");
|
|
45
45
|
for (const sc of e.scenarioTitles(story)) out.push(`- \`${e.testTitle(id, sc)}\``);
|
|
46
46
|
out.push("");
|
|
@@ -70,7 +70,7 @@ for (const s of appSteps.filter((s) => !commands[s] && !scripts[s])) {
|
|
|
70
70
|
const node = process.execPath;
|
|
71
71
|
const disc = join(here, "..", "..");
|
|
72
72
|
run("events.yaml", node, [join(disc, "event-storming", "scripts", "validate-events.ts")]);
|
|
73
|
-
run("stories", node, [join(disc, "user-stories", "scripts", "validate-stories.ts")]);
|
|
73
|
+
run("stories + spec linter", node, [join(disc, "user-stories", "scripts", "validate-stories.ts")]);
|
|
74
74
|
// The map is generated; staleness is a warning (adoption may not have run yet), not a failed gate.
|
|
75
75
|
run("repository map", node, [join(disc, "adopt", "scripts", "repo-map.ts"), "--check"], true);
|
|
76
76
|
run("path-scoped rules", node, [join(disc, "adopt", "scripts", "rule-doc.ts"), "--check"], true);
|