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
@@ -0,0 +1,101 @@
1
+ # Logic Prototype
2
+
3
+ A single, self-contained HTML file (a **shareable demo**) that lets anyone drive a state model by clicking
4
+ buttons. Use this when the question is about **business logic, state transitions, or data shape**: the kind of
5
+ thing that looks reasonable on paper but only feels wrong once you push it through real cases.
6
+
7
+ Because it is one file with nothing to install, you can hand it to a non-developer (a designer, a PM, a domain
8
+ expert) and let them feel the model for themselves. So it speaks their language, not the code's.
9
+
10
+ ## When this is the right shape
11
+
12
+ - "I'm not sure if this state machine handles the edge case where X then Y."
13
+ - "Does this data model actually let me represent the case where ..."
14
+ - "I want to feel out what the API should look like before writing it."
15
+ - Anything where someone wants to **press buttons and watch state change**.
16
+
17
+ If the question is "what should this look like," this is the wrong branch. Use [UI.md](UI.md).
18
+
19
+ ## Process
20
+
21
+ ### 1. State the question
22
+
23
+ Before writing code, write down what state model and what question you are prototyping. One paragraph, at the
24
+ top of the demo (in a visible intro, not just a comment) and in the `README.md`. A logic prototype that answers
25
+ the wrong question is pure waste, so make the question explicit so it can be checked later.
26
+
27
+ ### 2. Isolate the logic in a portable module
28
+
29
+ Put the actual logic (the bit that is answering the question) in a single `<script>` block written as a small,
30
+ pure module that could be lifted out and dropped into the real codebase later. The page around it is throwaway;
31
+ this module isn't.
32
+
33
+ The right shape depends on the question:
34
+
35
+ - **A pure reducer**: `(state, action) => state`. Good when actions are discrete events and state is a single
36
+ value.
37
+ - **A state machine**: explicit states and transitions. Good when "which actions are even legal right now" is
38
+ part of the question.
39
+ - **A small set of pure functions** over a plain data type. Good when there is no implicit current state, just
40
+ transformations.
41
+ - **A class or module with a clear method surface** when the logic genuinely owns ongoing internal state.
42
+
43
+ Pick whichever shape best fits the question being asked, *not* whichever is easiest to wire to a page. Keep it
44
+ pure: no DOM, no `document`, no button handlers reaching inside it. The page calls into it; nothing flows the
45
+ other direction. This is what makes the prototype useful past its own lifetime: once the question is answered,
46
+ the validated reducer / machine / function set lifts into the real module on its own.
47
+
48
+ ### 3. Build the shareable HTML file
49
+
50
+ One file, plain HTML/CSS/JS: no framework, no bundler, no server, everything inline so it opens by double-click
51
+ and survives being emailed around. Anyone should be able to run it by opening it.
52
+
53
+ Write it for a non-developer. Every label is in **domain language** from `CONTEXT.md`, not code: buttons and
54
+ state read like the business, not like the reducer. Explain in plain words what is happening.
55
+
56
+ Lay it out with a clean hierarchy, top to bottom:
57
+
58
+ 1. **Title and one-line explanation** of what this demo lets you explore (the question from step 1).
59
+ 2. **Current state**: the full relevant state, rendered as a readable panel (labelled fields, not a raw JSON
60
+ dump), re-rendered after every click so the change is visible. Where it helps a non-developer follow, call
61
+ out what just changed.
62
+ 3. **Free-play buttons**: one button per action, always available, so anyone can poke at the model in any
63
+ order. Each click dispatches its action and re-renders the state.
64
+ 4. **Guided walkthroughs**: a set of **scenarios**, one per tab. Each tab holds a short plain-language
65
+ description of the scenario (the situation it sets up and what to watch for) and underneath it, the ordered
66
+ **buttons to press** for that scenario. Each step is a real button: clicking it performs that action and
67
+ moves to the next step. Starting a walkthrough resets to a known initial state so the scenario runs the same
68
+ way every time.
69
+
70
+ Choose scenarios that demonstrate the awkward cases, the ones hard to reason about on paper: the happy path, a
71
+ tricky edge case, an attempt at something that should be illegal.
72
+
73
+ Keep it beautiful but restrained: clean typography, generous spacing, one accent colour. No animations, no
74
+ gimmicks: nothing that competes with the state and the buttons.
75
+
76
+ ### 4. Hand it over
77
+
78
+ Send them the file, or open it for them. They will click through the walkthroughs and free-play whenever they
79
+ get to it; the interesting moments are when they say "wait, that shouldn't be possible" or "huh, I assumed X
80
+ would be different"; those are the bugs in the *idea*, which is the whole point. If they want new actions or a
81
+ new scenario, add them. Prototypes evolve.
82
+
83
+ ### 5. Capture the answer and the prototype
84
+
85
+ Once the prototype has answered its question, capture the answer, then capture the prototype the way the
86
+ [SKILL](SKILL.md) describes. The logic-specific mapping: the validated reducer / machine / function set lifts
87
+ into the real module (the decision, absorbed); the HTML shell rides along to the throwaway branch that keeps
88
+ the prototype as a primary source, and being one self-contained file, it stays trivially re-runnable there.
89
+
90
+ ## Anti-patterns
91
+
92
+ - **Don't add tests.** A prototype that needs tests is no longer a prototype.
93
+ - **Don't wire it to the real database.** Use in-memory state unless the question is specifically about
94
+ persistence.
95
+ - **Don't generalise.** No "what if we wanted to support X later." The prototype answers one question.
96
+ - **Don't blur the logic and the page together.** If the pure module references the DOM, `document`, or button
97
+ handlers, it is no longer liftable. Keep the page as a thin shell over a pure module.
98
+ - **Don't reach for a framework, bundler, or server.** One file the recipient double-clicks; a framework app or a
99
+ dev server defeats "shareable".
100
+ - **Don't ship the HTML shell into production.** The page is optimised for being clicked through by hand. The
101
+ logic module behind it is the bit worth keeping.
@@ -0,0 +1,85 @@
1
+ ---
2
+ name: prototype
3
+ description: Build a throwaway prototype to answer one design question – a self-contained HTML file for a logic/state question, or several radically different UI variants switchable in one file. Use when a UX or domain question cannot be settled on paper, and in /feature or /implement when the user asks for a prototype.
4
+ ---
5
+
6
+ # Prototype
7
+
8
+ A prototype is **throwaway code that answers a question**. The question decides the shape. It is not a first
9
+ draft of the feature: no tests, no persistence, no polish, no production path. The decision it settles is the
10
+ only thing that survives; the code is captured on a throwaway branch and never merged.
11
+
12
+ ## When this is the right tool
13
+
14
+ Use it when the question is one of these, and the user agrees:
15
+
16
+ - **"What should this look like?"** – a structural layout choice: three genuinely different information
17
+ hierarchies, not three colour variants.
18
+ - **"Does this logic / state model feel right?"** – a state machine, a set of rules or a data shape pushed
19
+ through cases that are hard to reason about on paper.
20
+ - **"How should this flow feel?"** – a sequence a person walks through, where the order and the feedback are
21
+ the question.
22
+
23
+ Do **not** prototype a question a guideline, the vision or the domain model already answers. Do not prototype
24
+ polish (colour, spacing, copy), and do not use it to avoid a grilling decision. The grilling comes first; the
25
+ prototype is evidence for one open branch of it.
26
+
27
+ ## Pick a branch
28
+
29
+ Identify which question is being answered – from the user's prompt, the story, the surrounding code, or by
30
+ asking if the user is around:
31
+
32
+ - **"Does this logic / state model feel right?"** → [LOGIC.md](LOGIC.md). One self-contained HTML file with
33
+ free-play buttons and tabbed guided walkthroughs that push the state model through the awkward cases. A
34
+ non-developer can drive it.
35
+ - **"What should this look like?"** → [UI.md](UI.md). Several radically different variants in one
36
+ self-contained HTML file, switchable via a `?variant=` URL search param and a floating bottom bar.
37
+
38
+ The two branches produce very different artifacts, so getting this wrong wastes the whole prototype. If the
39
+ question is genuinely ambiguous and the user isn't reachable, default to whichever branch better matches the
40
+ surrounding code (a backend module → logic; a page or component → UI) and state the assumption at the top of
41
+ the prototype.
42
+
43
+ ## Where it lives
44
+
45
+ In discovery, the prototype is **standalone**: `docs/prototypes/<slug>/index.html`, written by the
46
+ `ux-designer`, with a short `README.md` next to it (question, branch, variants/scenarios, timebox, verdict).
47
+ No application code, no framework, no build step, no shell. The user opens the file in a browser.
48
+
49
+ A question that genuinely needs the real application – an existing page, real data, the real header and
50
+ sidebar – is an **in-app prototype**. That is the exception: it is built by the main session during
51
+ `/implement` (see [UI.md](UI.md)), not by the `ux-designer`, and it follows the project's routing convention
52
+ with a clearly marked throwaway route. The same capture rules apply.
53
+
54
+ ## Rules that apply to both
55
+
56
+ 1. **Throwaway from day one, and clearly marked as such.** The path or the first line says `PROTOTYPE`. Name
57
+ it so a casual reader cannot mistake it for production.
58
+ 2. **Trivial to run.** Standalone: double-click the HTML file. In-app: one command from the project's task
59
+ runner. No thinking required to start it.
60
+ 3. **No persistence by default.** State lives in memory. Persistence is the thing the prototype is *checking*,
61
+ not something it depends on. If the question explicitly involves a database, use a scratch database or a
62
+ local file with a clear "PROTOTYPE, wipe me" name.
63
+ 4. **Skip the polish.** No tests, no error handling beyond what makes the prototype runnable, no abstractions.
64
+ The point is to learn something fast.
65
+ 5. **Surface the state.** After every action (logic) or on every variant switch (UI), render the full relevant
66
+ state so the user can see what changed.
67
+ 6. **One question, one timebox.** Write the question at the top, in the user's language, and agree a timebox
68
+ with the user (one working session is the default). If the timebox expires without an answer, stop and
69
+ record what is known – a second prototype needs a new question, not more polish.
70
+ 7. **Capture the answer, not the code.** Fold the validated decision into the real artifact – the story's
71
+ `## Context`, `docs/product/ux-guidelines.md` (a G-number when it is a recurring rule) or the domain model.
72
+ Then capture the prototype itself as a **primary source**: commit `docs/prototypes/<slug>/` on a throwaway
73
+ branch `prototype/<slug>`, push it only if the user wants to share it, and return to the branch you were
74
+ on. The branch is never merged. The story carries `Prototype: prototype/<slug> – <question> – <verdict>`.
75
+
76
+ ## How it plugs into the workflow
77
+
78
+ - **`/feature`** – the UX lens proposes a prototype when the frontier leaves a structural UI, flow or state
79
+ question. The user decides. `--prototype[=ui|logic]` makes it explicit. The verdict goes to the
80
+ `ux-designer` (guidelines) and into the story's `## Context` in the main session, before the stories are reviewed.
81
+ - **`/implement`** – only when the user asks (`--prototype`) or a spike's question is a UX/state question. A
82
+ `ui` story whose screen shape is still open was not `ready`; the prototype settles it, then the story goes
83
+ back to `review` if its behaviour changed. The engineering rule holds: never decide a story in the code.
84
+ - **The `ux-designer`** owns the skill and builds the standalone prototype. It never writes production code,
85
+ tests or stories. The main session captures the branch and passes the verdict on.
@@ -0,0 +1,130 @@
1
+ # UI Prototype
2
+
3
+ Generate **several radically different UI variations** in one self-contained HTML file, switchable from a
4
+ floating bottom bar. The user flips between variants in the browser, picks one (or steals bits from each), then
5
+ throws the rest away.
6
+
7
+ If the question is about logic/state rather than what something looks like, this is the wrong branch. Use
8
+ [LOGIC.md](LOGIC.md).
9
+
10
+ ## When this is the right shape
11
+
12
+ - "What should this page look like?"
13
+ - "I want to see a few options for this dashboard before committing."
14
+ - "Try a different layout for the settings screen."
15
+ - Any time the user would otherwise spend a day picking between three vague mockups in their head.
16
+
17
+ ## Two sub-shapes: standalone first
18
+
19
+ A UI prototype is easier to judge when it butts up against the rest of the app – real header, real sidebar,
20
+ real data, real density. A variant in a vacuum looks fine in isolation. But in discovery there is no app code
21
+ yet, and the `ux-designer` must not write it. So the default is standalone; the in-app shape is the exception.
22
+
23
+ ### Sub-shape A: standalone HTML (default in discovery)
24
+
25
+ One file, `docs/prototypes/<slug>/index.html`, with inline CSS and JS. No framework, no bundler, no server. It
26
+ opens by double-click and survives being emailed around.
27
+
28
+ - Use sample data that matches the domain (`CONTEXT.md`), not `foo`/`bar`.
29
+ - Give each variant a clear component name in the file: `VariantA`, `VariantB`, `VariantC`.
30
+ - Keep the page frame realistic: the header, the navigation and the density the real page will have. A blank
31
+ page hides design problems that a populated one exposes.
32
+ - If the feature will live inside an existing screen, render that screen's frame around the variants.
33
+
34
+ ### Sub-shape B: in-app throwaway route (only in `/implement`)
35
+
36
+ Only when the question genuinely needs the real application: an existing page, real data, the real header and
37
+ sidebar. The main session builds it, not the `ux-designer`. Follow the project's routing convention; do not
38
+ invent a new top-level structure. Name the route or the file so it is obviously a prototype. Same `?variant=`
39
+ pattern and the same switcher. Never wire it to real mutations; read-only is fine.
40
+
41
+ ## Process
42
+
43
+ ### 1. State the question and pick N
44
+
45
+ Default to **3 variants**. More than 5 stops being radically different and starts being noise, so cap there.
46
+
47
+ Write down the plan in one line, at the top of the file and in the `README.md`:
48
+
49
+ > "Three variants of the settings page, switchable via `?variant=`, on the existing `/settings` route."
50
+
51
+ ### 2. Generate radically different variants
52
+
53
+ Draft each variant. Hold each one to:
54
+
55
+ - The page's purpose and the data it has access to.
56
+ - The project's component library / styling system if the prototype is in-app; plain CSS if it is standalone.
57
+ - A clear component name in the file, e.g. `VariantA`, `VariantB`, `VariantC`.
58
+
59
+ Variants must be **structurally different**: different layout, different information hierarchy, different
60
+ primary affordance, not just different colours. Three slightly-tweaked card grids isn't a UI prototype, it's
61
+ wallpaper. If two drafts come out too similar, redo one with explicit "do not use a card grid" guidance.
62
+
63
+ ### 3. Wire them together
64
+
65
+ Create a single switcher in the file:
66
+
67
+ ```js
68
+ // pseudo-code, adapt to the file
69
+ const variant = new URLSearchParams(location.search).get("variant") ?? "A";
70
+ render(
71
+ variant === "A" ? VariantA(data) :
72
+ variant === "B" ? VariantB(data) :
73
+ VariantC(data)
74
+ );
75
+ renderSwitcher(["A", "B", "C"], variant);
76
+ ```
77
+
78
+ For sub-shape B (in-app), keep all the existing data fetching above the switcher; only the rendered subtree
79
+ changes per variant.
80
+
81
+ ### 4. Build the floating switcher
82
+
83
+ A small fixed-position bar at the bottom-centre of the screen with three pieces:
84
+
85
+ - **Left arrow**: cycles to the previous variant (wraps around).
86
+ - **Variant label**: shows the current variant key and, if the variant exports a name, that name too. e.g.
87
+ `B (Sidebar layout)`.
88
+ - **Right arrow**: cycles forward (wraps around).
89
+
90
+ Behaviour:
91
+
92
+ - Clicking an arrow updates the URL search param (`history.replaceState` in a standalone file, the framework's
93
+ router in-app) so the variant is shareable and reload-stable.
94
+ - Keyboard: `←` and `→` arrow keys also cycle. Don't intercept arrow keys when an `<input>`, `<textarea>`, or
95
+ `[contenteditable]` is focused.
96
+ - Visually distinct from the page (e.g. high-contrast pill, subtle shadow) so it is obviously not part of the
97
+ design being evaluated.
98
+ - In-app only: hidden in production builds, gated on `process.env.NODE_ENV !== "production"` or an equivalent
99
+ check, so a stray prototype merge cannot ship the bar to users. A standalone file never enters the build.
100
+
101
+ ### 5. Hand it over
102
+
103
+ Surface the file path or the URL (and the `?variant=` keys). The user will flip through whenever they get to
104
+ it. The interesting feedback is usually **"I want the header from B with the sidebar from C"**, which is the
105
+ actual design they want.
106
+
107
+ ### 6. Capture the answer and clean up
108
+
109
+ Once a variant has won, capture the answer (which variant and why), then capture the prototype the way the
110
+ [SKILL](SKILL.md) describes. Fold the winner into the real code and move the rest onto the throwaway branch,
111
+ not into main:
112
+
113
+ - **Standalone**: the decision goes into the story and, when it is a recurring rule, into
114
+ `docs/product/ux-guidelines.md`. The whole `docs/prototypes/<slug>/` folder goes to `prototype/<slug>`.
115
+ - **In-app**: fold the winner into the existing page; drop the losing variants and the switcher from the story
116
+ branch. The full set goes to `prototype/<slug>`.
117
+
118
+ The full set of variants is the primary source, so it lands on the throwaway branch, not the bin. Variant
119
+ components and the switcher left in the main branch rot fast and confuse the next reader.
120
+
121
+ ## Anti-patterns
122
+
123
+ - **Variants that differ only in colour or copy.** That's a tweak, not a prototype. Real variants disagree
124
+ about structure.
125
+ - **Sharing too much code between variants.** A shared header is fine; a shared layout defeats the point.
126
+ Each variant should be free to throw out the layout.
127
+ - **Wiring variants to real mutations.** Read-only prototypes are fine. If a variant needs to mutate, point it
128
+ at a stub: the question is "what should this look like", not "does the backend work".
129
+ - **Promoting the prototype directly to production.** The variant code was written under prototype
130
+ constraints (no tests, minimal error handling). Rewrite it properly when you fold it in.
@@ -1,31 +1,51 @@
1
1
  ---
2
2
  name: review-stories
3
- description: Has stories checked in one lead-dev pass (value, build, UX), applies the small fixes and guides the user to approval (status ready).
3
+ description: Runs the deterministic spec linter on finished stories, fixes mechanical gaps, moves green stories to ready-for-human-review and guides the user to approval (status ready). No subagent review pass.
4
4
  disable-model-invocation: true
5
5
  argument-hint: "[ST-IDs, empty = all with status review]"
6
6
  ---
7
7
 
8
8
  # Story Review
9
9
 
10
- The perspectives of product owner, lead dev and UX were settled with the user in the grilling. This review checks
11
- that the stories carry them – one pass, not a second discovery (user, 2026-10-26).
10
+ There is no simulated role play. The domain, architecture and testability decisions were made in the grilling and
11
+ the event storming; the **spec linter** now checks mechanically that the story carries them. The user approves; the
12
+ agent does not approve on their behalf.
12
13
 
13
14
  1. **Selection**: Stories from the invocation arguments, or all with `status: review` in `docs/stories/`. With a
14
15
  tracker (`backlog.provider` ≠ `local`), pull first (`/backlog-sync pull`) so the review sees the tracker's state.
15
16
  None found → report and stop.
16
- 2. **Delegate once** to `lead-dev` with the full file paths of the stories, the review file path
17
- `docs/reviews/YYYY-MM-DD-story-review.md` and the task *story review: all three lenses*. It sets `size`, `risk`,
18
- `depends_on` and `priority` and writes the findings into the review file.
19
- 3. **Let the user decide** only what the findings leave open: conflicts with a decision from the grilling, a
20
- proposed split, a proposed new story (max. 3 questions at a time, each with a recommended answer). Adopt nothing
21
- that changes a grilling decision without consent.
22
- 4. **Apply**:
23
- - Small content changes (a scenario, a wording, a Context line, a G-reference) → edit the story yourself.
24
- - A split or a restructured story → delegate to `requirements-engineer` (referencing the review file).
25
- - With a tracker, push the selected stories that are still unlinked (`/backlog-sync push ST-001 …`) **before**
26
- setting `ready` – the push creates the issue and writes `external`; without it the validator refuses `ready`.
27
- - Approved stories: `node .claude/skills/implement/scripts/story-status.ts ST-NNN ready` (only if `size` is set
28
- and no `[OPEN]` remains – the script checks this). GitHub follows the status change directly; for Jira, run the
29
- transition the script prints.
30
- - Push the changed and approved stories again so body, labels and status agree in the tracker.
31
- 5. Wrap-up: run `node .claude/skills/user-stories/scripts/validate-stories.ts`, show the status overview and point to `docs/stories/BACKLOG.md` (regenerated automatically), where `ready` stories are queued for the engineering workflow.
17
+ 2. **Lint first** – this is the gate, not a suggestion:
18
+
19
+ ```bash
20
+ node .claude/skills/user-stories/scripts/lint-story.ts ST-NNN
21
+ ```
22
+
23
+ Errors are the agent's to fix in the story: a missing `aggregate`/`command`, a command that belongs to another
24
+ aggregate, events that are not exactly what the command produces, a missing `Given/When/Then`, more than 4
25
+ scenarios, duplicate titles, a broken reference. Do not weaken a check to get green – if the model is missing the
26
+ event or aggregate, fix `docs/domain/events.yaml` (event-storming/domain-model skill) first.
27
+ 3. **Warnings that matter**: a `ui: true` story with no empty/rejection case, a legacy `type: story`, a scenario that
28
+ reads like a UX guideline restated. Fix what is clearly right; leave the rest as a note in the review summary.
29
+ This is not a second discovery – adopt nothing that changes a decision from the grilling without asking.
30
+ 4. **Tracker link**: with a tracker, push unlinked stories (`/backlog-sync push ST-001 …`) **before** setting
31
+ `ready` – the push creates the issue and writes `external`; without it the validator refuses `ready`.
32
+ 5. **Linter green → `ready-for-human-review`**:
33
+
34
+ ```bash
35
+ node .claude/skills/implement/scripts/story-status.ts ST-NNN ready-for-human-review
36
+ ```
37
+
38
+ The script validates the file and refuses on any lint error.
39
+ 6. **The user approves** – present one short table (ID, title, type, command/aggregate, scenario count, warnings) and
40
+ ask for approval. On approval:
41
+
42
+ ```bash
43
+ node .claude/skills/implement/scripts/story-status.ts ST-NNN ready
44
+ ```
45
+
46
+ With a tracker, push again so body, labels and status agree. If the user declines, the story goes back to
47
+ `review` or `draft` with their reason.
48
+ 7. **UX on demand only**: a story with `ui: true` may get a component/Figma proposal from the `ux-designer`, but
49
+ only when the user asks. It is advice, never a gate – do not wait for it.
50
+ 8. Wrap-up: run `node .claude/skills/user-stories/scripts/lint-story.ts`, show the status overview and point to
51
+ `docs/stories/BACKLOG.md` (regenerated automatically), where `ready` stories are queued for engineering.
@@ -64,7 +64,7 @@ Three starting points:
64
64
  does not. Confidence is `medium` at best; say what is inferred. If the sibling is central, recommend
65
65
  `/adopt <sibling>` as the first slice before committing to a cost range.
66
66
 
67
- ## 2. Frame – product owner lens
67
+ ## 2. Frame – product lens
68
68
 
69
69
  Call the `grilling` skill. The frontier:
70
70
 
@@ -103,7 +103,7 @@ Produce a recommendation **with at least one alternative and its consequence**,
103
103
 
104
104
  The user decides.
105
105
 
106
- ## 4. Impact – lead-dev lens
106
+ ## 4. Impact – engineering lens
107
107
 
108
108
  Split the answer into **change** and **build new**. Leave nothing implicit.
109
109