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.
Files changed (59) hide show
  1. package/.claude/THIRD_PARTY_NOTICES.md +69 -0
  2. package/.claude/agents/acceptance-tester.md +7 -2
  3. package/.claude/agents/code-reviewer.md +7 -2
  4. package/.claude/agents/ux-designer.md +43 -38
  5. package/.claude/hooks/validate-docs.ts +2 -1
  6. package/.claude/lib/config.ts +1 -0
  7. package/.claude/lib/discovery.ts +129 -31
  8. package/.claude/lib/engineering.ts +12 -6
  9. package/.claude/package.json +1 -0
  10. package/.claude/settings.json +1 -2
  11. package/.claude/skills/adopt/SKILL.md +5 -3
  12. package/.claude/skills/backlog/SKILL.md +2 -2
  13. package/.claude/skills/bootstrap/SKILL.md +9 -7
  14. package/.claude/skills/domain-model/SKILL.md +1 -1
  15. package/.claude/skills/feature/SKILL.md +37 -11
  16. package/.claude/skills/feature/scripts/intake.ts +1 -1
  17. package/.claude/skills/groom-backlog/SKILL.md +19 -16
  18. package/.claude/skills/implement/SKILL.md +169 -63
  19. package/.claude/skills/implement/scripts/check-scenarios.ts +1 -1
  20. package/.claude/skills/implement/scripts/story-context.ts +1 -1
  21. package/.claude/skills/implement/scripts/verify.ts +1 -1
  22. package/.claude/skills/prototype/LOGIC.md +101 -0
  23. package/.claude/skills/prototype/SKILL.md +85 -0
  24. package/.claude/skills/prototype/UI.md +130 -0
  25. package/.claude/skills/review-stories/SKILL.md +39 -19
  26. package/.claude/skills/shape/SKILL.md +2 -2
  27. package/.claude/skills/user-stories/SKILL.md +109 -51
  28. package/.claude/skills/user-stories/schema/story.schema.json +6 -3
  29. package/.claude/skills/user-stories/scripts/lint-story.ts +56 -0
  30. package/.claude/skills/user-stories/templates/story-template.md +5 -2
  31. package/.claude/skills/ux-design/SKILL.md +30 -5
  32. package/.opencode/agents/acceptance-tester.md +8 -3
  33. package/.opencode/agents/code-reviewer.md +8 -3
  34. package/.opencode/agents/ux-designer.md +44 -39
  35. package/.opencode/commands/bootstrap.md +1 -1
  36. package/.opencode/commands/feature.md +1 -1
  37. package/.opencode/commands/groom-backlog.md +1 -1
  38. package/.opencode/commands/implement.md +1 -1
  39. package/.opencode/commands/review-stories.md +1 -1
  40. package/AGENTS.md +17 -0
  41. package/CHANGELOG.md +38 -0
  42. package/README.md +64 -7
  43. package/guide/brownfield.md +2 -2
  44. package/guide/concepts.md +26 -5
  45. package/guide/greenfield.md +4 -3
  46. package/guide/release.md +1 -1
  47. package/package.json +1 -1
  48. package/src/cli.mjs +42 -4
  49. package/src/install.mjs +62 -6
  50. package/templates/docs/product/ux-guidelines.md +2 -0
  51. package/templates/docs/prototypes/README.md +9 -0
  52. package/templates/docs/stories/README.md +10 -3
  53. package/templates/docs/workflow.md +38 -13
  54. package/.claude/agents/lead-dev.md +0 -50
  55. package/.claude/agents/product-owner.md +0 -39
  56. package/.claude/agents/requirements-engineer.md +0 -44
  57. package/.opencode/agents/lead-dev.md +0 -67
  58. package/.opencode/agents/product-owner.md +0 -59
  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
- Delegate to `requirements-engineer` in two parts:
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 10 scenarios per story; no implementation plan inside a domain story; every story links its
91
- `events`; `status: draft`, then `review` when finished.
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 user approves
96
- every `ready`. Fix what the review finds through `requirements-engineer` – never by editing a story into shape
97
- yourself when the change is structural.
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 requirements-engineer reads both when deriving scenarios.
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 story review later only checks – product owner, lead dev, 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:
62
- - **PO**: 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?
63
- - **Lead dev**: Which existing code, data and stories change? Is there a migration? What is hard to test? Where does it cut into stories – each a vertical slice of at most ~10 scenarios?
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 the label `ui`.
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
- Delegate to `requirements-engineer`: derive stories for the feature's new or changed commands, policies and read models; name the event/command IDs, the label `feature:<slug>`, the label `ui` for every story with a frontend part, 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 story cut from step 2, and existing stories that need revising. Finished stories get `status: review`; have it report the IDs of all stories it created or revised.
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 still approves every change and every `ready`.
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 ?? "story"),
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 and a task for the `requirements-engineer`.
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 in parallel
43
+ ## 3. Challenge – two lenses, one pass
43
44
 
44
- Start in **one** message, with the full file paths, the scope and the change list from step 2:
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
- - `product-owner` – is the value still real and still in the vision? Is the story already covered by what was
47
- built? Does the MVP slice still hold? Which `must` is not a `must` any more, and which `could` turned out to be
48
- one? Which need from the vision still has no story?
49
- - `lead-dev` – do `depends_on`, `size` and `risk` still fit **now that the code exists**? Which story has become
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, merged or dropped?
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
- Tell each one explicitly: **recommend, don't rewrite** – they change only the frontmatter fields they own
56
- (`priority` for the PO, `size`/`risk`/`depends_on` for the lead dev), everything else comes back as a proposal.
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 three – name them, don't average them away
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 PO and lead-dev is a question for the user, not something to resolve on their behalf.
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 → `requirements-engineer`, referencing the grooming file.
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/ test-first on its own branch, verifies, has it reviewed by code-reviewer and acceptance-tester, refactors, and sets it `done` on the acceptance tester's verdict and hands the pull request to the user to merge.
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 already `in-progress` is finished first).
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. One checkpoint belongs to the user: the **merge** (step 7). Everything before it runs without asking – a `ready` story is good enough to build up to the pull request, and the acceptance tester accepts the story, not the user – unless the story turns out to be wrong (see *When the story is wrong*) or a seam is missing from the catalog (step 2).
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
- Engineering conventions: `docs/engineering/conventions.md` – read it if it exists; it describes the module layout, how commands and read models are built, and the **seam catalog**.
20
+ ## Two lanes
15
21
 
16
- Project profile: `.claude/project.json` – default branch, code roots, commands, preview provider, pull-request tool. Read it instead of assuming `main`, `npm` or GitHub.
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 the user.
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, dependencies, events/commands/rules/invariants, glossary, data model, ADRs. Read it completely; it is your source, not memory.
23
- 4. `git switch -c st-NNN-<slug>` (slug from the file name), then `node .claude/skills/implement/scripts/story-status.ts ST-NNN in-progress` and commit `ST-NNN: start`.
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
- Call the `skill` tool for `tdd` (and `codebase-design` when a new module or interface is involved).
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
- - **Story**: one row per Gherkin scenario. **Tech task**: one row per checklist item that can be tested; the rest gets its evidence named (setting, document). **Spike**: no table – see *Spikes*.
33
- - Seams come from the seam catalog in the engineering conventions. A seam not in the catalog is a decision for the user – the one case where you stop here and ask.
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
- ## 3. Red → green, one scenario at a time
39
- - Per row: write the test (title exactly `ST-NNN: <scenario title>`), run it and see it fail for the right reason, write the minimal code to pass, run it green. Commit: `ST-NNN: <scenario title>`.
40
- - Domain IDs in the code: commands, events, read models and policies carry their ID from `events.yaml` (`CMD-ReportProblem`, `EVT-ProblemReported`, …). New code uses the words of `CONTEXT.md`; a new term goes into `CONTEXT.md` first (domain-model skill).
41
- - Never weaken or delete an existing test to get green. If a test from an earlier story blocks you, its story and this one contradict each other → *When the story is wrong*.
42
- - Hooks help on the way: formatting and lint after every write, the quick gate (type check + related tests) before you finish a turn.
43
- - In a monorepo, run the affected set for the packages you touched before the full gate:
44
- `node .claude/skills/implement/scripts/affected.ts --changed <files>` (or `--base <defaultBranch>`), then
45
- execute the printed command. It follows shared-library dependents; `verify.ts` still runs everything at the end.
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. module boundaries, type check, tests, events and stories valid, scenario ↔ test and domain ID traceability. Language warnings: fix or justify.
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; after the refactor (step 6) run `verify.ts` without `--e2e` plus the specs the refactor touched – CI runs every browser test on the pull request anyway (check `e2e`).
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 (in parallel, scaled to the story)
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
- Pick the lane first – review effort follows the risk of the diff, not a fixed list:
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
- **Light lane** – when **all** of these hold: size **S**, `events: []`, no command, no migration, no input handling
60
- (no request handler, form action or route added or changed), no new dependency. Typical: static pages, texts, a
61
- link, layout.
62
- - Only `acceptance-tester` – task: story ID, base ref, the preview URL (if known), and: *also check the diff briefly against the engineering conventions (texts from the catalogs, the shared page frames, domain language) and list deviations as minors.* Writes `docs/reviews/ST-NNN-acceptance.md`.
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 for size **L/XL** or a story that changes the command layer or other shared platform code: ask the `code-reviewer` for a second, bug-focused pass over the diff.
69
- - Only when the **diff** touches input handling, login/roles/session, uploads or files, or security headers/CSP: ask the `code-reviewer` for a security-focused pass.
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
- Say which lane you picked and why in one line.
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
- Tell the reviewers the follow-up hurdle below, so they grade findings with it in mind.
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. Where a finding offers options, apply the recommended one without asking; ask only when no option is recommended or a follow-up story is at stake.
77
- - **Follow-up hurdle** – a finding becomes a new story only if all of these hold:
78
- 1. it is a security or data-loss risk, or it blocks a *named* upcoming story;
79
- 2. it cannot be fixed in this story within about an hour;
80
- 3. no existing story can take it (check the stories that will first touch that code – prefer adding a checklist item there, via `requirements-engineer`, over a new story).
81
- Otherwise it stays a line in the review file ("skipped minor" or "revisit when …") – no story. Say for each follow-up why it passes the hurdle.
82
- - Follow-ups that pass: delegate to `requirements-engineer` as new tech-task stories (`status: draft`, label `follow-up`), referencing the review file. They go through `/review-stories` like any story.
83
- - **Foundation just in time**: technical groundwork goes into the first story that needs it, not into a separate tech task ahead of the domain stories – a `must` tech task with met dependencies jumps ahead of every domain story in the backlog order.
84
- - Refactor only with green tests; the tests must not change unless they were wrong (then say so). Run
85
- `affected.ts` for the touched packages, then `node .claude/skills/implement/scripts/verify.ts` again (without
86
- `--e2e`) plus the browser specs the refactor touched – see step 4.
87
-
88
- ## 7. Acceptance and merge → user checkpoint
89
- The **acceptance tester's verdict is the acceptance**: the story is `done` in the pull request, so the user only merges.
90
- 1. After the refactor, check the verdict in `docs/reviews/ST-NNN-acceptance.md`. `accepted` or `accepted with remarks` → continue. `not accepted` → fix the gaps in the story and run the `acceptance-tester` again, until it accepts. Only when something goes badly wrong – the verdict stays `not accepted` after a second round, a scenario can't be met as written, the preview shows a defect the tester couldn't see – ask the user, the way *When the story is wrong* describes.
91
- 2. `node .claude/skills/implement/scripts/story-status.ts ST-NNN done` – refuses unless every scenario has its test (story) or every checklist item is ticked (spike/tech task) and all dependencies are done. Commit `ST-NNN: done`, push.
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 `jira_get_transitions` +
94
- `jira_transition_issue` on the printed key, then push the story body once (`/backlog-sync push`).
95
- 3. Open a pull request: title `ST-NNN: <story title>`, body = the scenarios as a checklist, links to the story and both review files, the acceptance verdict, the preview URL, remaining minors, and anything the user must approve (a conventions change). (No `gh` CLI, or it isn't authenticated: push and give the user the compare URL `git push` prints.)
96
- 4. **The user merges** – on the preview if they want to look first. Afterwards: back to the default branch and `git pull`.
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, follow-ups created, glossary/ADR changes. Then:
100
- - Suggest `/improve-codebase-architecture` after the foundation stories, when a bounded context is complete, or about every 8–10 done stories.
101
- - Name the next story (`node .claude/skills/implement/scripts/next-story.ts`) and tell the user to start it in a fresh session (`/new`, then `/implement`): every turn re-reads the whole session, so a second story in the same one costs several times the first.
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
- - Before starting, tell the user the timebox and what will be kept (skeleton code that becomes the application gets tests and passes verify).
106
- - Tick each checklist item in the story file as it is answered; write results where the item says (an ADR's consequences, `OPEN_QUESTIONS.md`). A new decision → ADR with `status: proposed` (architect skill); the user accepts.
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 decision open:
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 discovery: `requirements-engineer` revises the story, `/review-stories` approves it again. Work already done on the branch stays.
114
- 3. New domain term → `CONTEXT.md` (domain-model skill). Architecture deviation → a `proposed` ADR (architect skill). An accepted ADR is never edited; the hooks block it.
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.type !== "story") continue;
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.type === "story") {
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);