@pavp/storywright 1.5.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,172 +1,96 @@
1
1
  ---
2
2
  name: story-generate
3
- description: Transform an ambiguous prompt, half-baked story, screenshot, or Figma link into a Jira-ready user story with acceptance criteria, DoD, edge cases, and risks. Ask only critical clarifying questions.
3
+ description: Transform an ambiguous prompt, half-baked story, screenshot, or Figma link into a Cohn+Gherkin user story. Inherits all hard rules from storywright-base.
4
4
  trigger: "/story-generate | generate a user story | write a user story | turn this into a story | crear historia de usuario"
5
- intent: Top-level orchestrator skill that drives the full story generation flow by composing component skills.
6
- version: 1.0.0
5
+ intent: Top-level orchestrator that drafts a fresh story from any input. Behavior 100% identical to siblings except for source (raw / ambiguous input) and split-behavior (recommend /story-split when pre-split count ≥2).
6
+ version: 2.3.0
7
7
  inputs:
8
8
  - text
9
9
  - image
10
10
  - figma-link
11
11
  outputs:
12
- - story.jira-wiki.md
13
12
  - story.standard.md
14
- - clarifications.md
13
+ - story.jira-wiki.md
14
+ - .storywright-context.json
15
15
  composes:
16
+ - _components/storywright-base
16
17
  - _components/clarification-questions
17
18
  - _components/acceptance-criteria
18
19
  - _components/invest-checklist
19
- - _components/definition-of-done
20
- - _components/business-rules
21
- - _components/edge-cases
22
- - _components/analytics-events
23
- - _components/risks-and-dependencies
24
20
  - _components/jira-wiki-formatter
25
21
  ---
26
22
 
27
23
  ## Purpose
28
24
 
29
- Take whatever the PM has — a one-liner, a half-baked story, a screenshot, a Figma link — and produce a story that an engineer can pick up and ship without follow-up questions. Always output two artifacts (Jira wiki + CommonMark).
30
-
31
- ## When to use
32
-
33
- - The user has a goal but not a story (e.g., "Permitir login con Google").
34
- - The user pastes a vague story and wants it production-ready.
35
- - The user drops an image/Figma link and asks for stories.
36
-
37
- ## Inputs & how to interpret each
25
+ Take whatever the PM has — a one-liner, a half-baked story, a screenshot, a Figma link — and produce a Cohn+Gherkin story an engineer can pick up and ship without follow-up questions.
38
26
 
39
- ### Text prompts
40
- Anything from a single phrase to a paragraph. If the prompt names only a feature, infer the implicit user goal.
27
+ **All hard rules, canonical output shape, language detection, mechanical pre-split test, context persistence, terminal-only Q, and INVEST handling live in `[[storywright-base]]`. Read that first. Anything in this file is a SOURCE-SPECIFIC or SPLIT-BEHAVIOR delta only.**
41
28
 
42
- ### Local images (PNG/JPG)
43
- Use vision. Extract:
44
- - UI elements (buttons, fields, navigation)
45
- - Visible states (loading, error, success)
46
- - Inferred flow (what does each element trigger?)
47
- - Confidence per inference (high / medium / low). Anything below high → add `> ⚠️ Assumed:` blockquote in the output and surface in clarifications.
29
+ ## Source-specific differential
48
30
 
49
- ### Figma links
50
- If MCP Figma is available (see `[[story-from-figma]]`), use it to enumerate frames, components, navigation. If not, fall back to asking the user to drop screenshots.
31
+ - **Source:** raw / ambiguous text, optionally fused with screenshot and/or Figma URL.
32
+ - **What changes vs base:** at intake the prompt may name only a feature; infer the implicit user goal via rule 3 (persona sharpening) + rule G (passive-goal check) of the base. Mixed inputs follow the base conflict-detection rule plus the source-priority table below.
51
33
 
52
- ### Mixed inputs (text + image + Figma)
53
-
54
- The skill is designed to **fuse multiple sources** in a single invocation. Common pairings:
55
-
56
- - **Text + screenshot** — text states the goal, image shows the proposed UI. Use text for `User Story / Goal / Scope`, image for `Components / States / Edge cases / UX flow`.
57
- - **Text + Figma link** — text gives intent, Figma gives implementation surface. Use text for `User Story / Business goal`, Figma for `Technical considerations / Edge cases / Components / Multi-screen flows`.
58
- - **Text + image + Figma** — full triangulation. Highest fidelity; also highest chance of conflict.
59
-
60
- **Source priority (when sources disagree):**
34
+ ### Mixed-input source priority (text + image + Figma)
61
35
 
62
36
  | Section | Primary | Secondary | Tertiary |
63
37
  |---|---|---|---|
64
- | User Story / Goal | Text | Figma (frame titles, callouts) | Image |
65
- | Business Rules / Scope | Text | Figma | Image |
38
+ | User Story / Goal | Text | Figma frame titles | Image |
39
+ | Scope | Text | Figma | Image |
66
40
  | UI Components / States | Figma | Image | Text |
67
- | Edge Cases | Figma + Image (states shown) | Text | — |
68
- | Technical Considerations | Figma (component naming, design system refs) | Text | Image |
69
- | Acceptance Criteria | Triangulate all three | — | — |
41
+ | AC observable outcomes | Triangulate | | — |
42
+
43
+ Conflicts BLOCKING `AskUserQuestion` per base rule 1.
44
+
45
+ ## Split behavior differential
70
46
 
71
- **Conflict handling:**
47
+ If the base **deterministic pre-split test** returns count ≥2:
48
+ - **STOP drafting.**
49
+ - Output a terminal message listing candidate children + per-pair dep notes (base rule 10) + V audit (base rule 11).
50
+ - Recommend `/story-split` to the user.
51
+ - Do NOT auto-split, do NOT produce a 15-section story.
72
52
 
73
- 1. **Detect the conflict explicitly.** Example: text says "Google only" but Figma shows Google + Facebook buttons.
74
- 2. **Do NOT silently pick a winner.** Surface the conflict in `clarifications.md` as a BLOCKING question: *"Text says X but design shows Y which is canonical?"*
75
- 3. **If the user is in-session, ask immediately** before drafting. If running batch, mark the story `DRAFT` and write both options in scope/out-of-scope with `> ⚠️ Conflict:` annotation.
76
- 4. **Scope coverage check:** if Figma shows N flows but text describes 1, ask whether to (a) generate 1 story bounded to text, (b) generate N stories from Figma, or (c) generate 1 story + flag remaining flows as roadmap.
53
+ If count ≤1:
54
+ - Proceed with the base step-by-step Application skeleton (read context language persona passive-goal gap-check siblings fill canonical block INVEST → render).
77
55
 
78
56
  ## Application (step-by-step)
79
57
 
80
- 1. **Detect input types present** text, image, figma-link, or any combination. Branch accordingly:
81
- - **Single source** → process as before.
82
- - **Mixed sources** → run the "Mixed inputs" protocol above, including source-priority lookup and explicit conflict detection BEFORE drafting.
83
- 2. **Intake gap check** — invoke `[[clarification-questions]]`. If it returns BLOCKING questions, **ask first** before drafting.
84
- 3. **Detect language** of input (es | en | other). Output in the input language.
85
- 4. **Draft skeleton** of the structured story (all 15 sections from the template).
86
- 5. **Fill the CORE first** (always required, in order):
87
- 1. **Title** — concise, ≤8 words.
88
- 2. **Summary** — single value-focused sentence ("Enable Google login for trial users to reduce signup friction"), NOT a feature label ("Add Google button"). Elevator pitch.
89
- 3. **User Story** (As a / I want to / so that).
90
- - **Persona check:** if role is "user" or "customer", push for sharper ("trial user", "Workspace admin"). Generic personas hide motivation.
91
- - **"So that" check:** outcome must be distinct from action. "So I can save my work" = restating; "So I don't lose progress if tab crashes" = real motivation.
92
- 4. **Acceptance Criteria** via `[[acceptance-criteria]]` — at minimum the happy path + one failure mode.
93
- 5. **Definition of Done** via `[[definition-of-done]]`.
94
-
95
- 6. **Fill OPTIONAL sections only if they have real content.** Drop any that would be empty or boilerplate:
96
- - Contexto / Business goal — include when there's a stated trigger or KPI
97
- - Scope / Out of scope — include when boundaries are non-obvious
98
- - `[[business-rules]]` — include when invariants exist beyond the ACs
99
- - Technical considerations — include when surface/SDK/flag matters
100
- - `[[edge-cases]]` — include when ≥3 high-impact edges exist
101
- - `[[analytics-events]]` — include when story has measurable funnel
102
- - `[[risks-and-dependencies]]` — include when there are real blockers or unknowns
103
-
104
- The bias is **less is more**. A clean 4-section story beats a 15-section one full of `N/A`.
105
- 6. **Run INVEST self-check** via `[[invest-checklist]]`:
106
- - `READY` → continue.
107
- - `NOT A STORY` (V failed) → STOP. Tell the user this is a tech task, not a user story. Suggest reframing or combining with user-facing work.
108
- - `NEEDS REFINEMENT` (T or N failed) → revise the failing sections in place.
109
- - `RUN A SPIKE` (E failed on unknowns) → recommend a 1–2 day investigation; do not split or generate yet.
110
- - `SPLIT RECOMMENDED` (I, E, or S failed) → STOP. Hand off to `[[story-split]]`. **Never auto-split.**
111
- 7. **Render outputs** via `[[jira-wiki-formatter]]`:
112
- - `story.jira-wiki.md` — Jira wiki markup
113
- - `story.standard.md` — CommonMark
114
- 8. **If clarifications remain unresolved** (user skipped them, or low-confidence visual inferences exist):
115
- - Emit `clarifications.md` with the outstanding questions
116
- - Mark the story output with a `DRAFT` banner at the top
117
- - Tell the user explicitly what would unblock promoting from DRAFT to READY
118
- 9. **Present both artifacts** as fenced code blocks. Ask the user whether to save to disk (offer paths under `./stories/<slug>/`).
58
+ Follow the **base Application** skeleton exactly. The only override is step 7's split branch (above): on count ≥2, route to `/story-split` recommendation instead of host-side recursion.
119
59
 
120
60
  ## Examples
121
61
 
122
62
  ### Good — text prompt
123
63
  Input: *"Permitir login con Google"*
64
+ - Language auto-detect → ES.
65
+ - Persona sharpening → ask: trial user? admin? signed-out visitor?
66
+ - Pre-split count = 1 (one auth flow). Continue.
67
+ - Draft canonical block; INVEST → READY. Render.
124
68
 
125
- Flow:
126
- 1. Run gap check → 3 BLOCKING questions: scope of accounts, account linking, surface (web/mobile/both).
127
- 2. Ask the 3 questions, wait for answers.
128
- 3. Draft + fill all 15 sections.
129
- 4. INVEST → `READY`.
130
- 5. Render both outputs.
131
- 6. Done.
132
-
133
- ### Good — image input
134
- Input: screenshot of a dashboard with a filter sidebar.
135
-
136
- Flow:
137
- 1. Vision: extract filter categories, infer apply/reset actions.
138
- 2. Confidence on "filters persist across navigation" → MEDIUM → mark as `⚠️ Assumed` and surface in clarifications.
139
- 3. Run gap check → 1 BLOCKING (does this replace or augment current filters?).
140
- 4. Ask, draft, fill, INVEST, render.
141
-
142
- ### Bad
143
-
69
+ ### Good — broad input routed to split
144
70
  Input: *"Build the new dashboard"*
71
+ - Pre-split count ≥2 → STOP. Terminal message: candidate children + dep notes + V audit + "Run `/story-split`".
72
+ - No drafted story written.
145
73
 
146
- Don't draft. The scope is too broad. Run gap check → propose splitting into smaller stories at the **clarification step**, before the story is drafted. (Effectively delegates to `[[story-split]]` upfront.)
74
+ ### Good passive goal fires
75
+ Input: *"As a user, I want to view list of customers, so that I find details."*
76
+ - Rule G fires. Ask: "What does the user do with the customer they find?"
77
+ - User: "Call them." → so-that strengthened.
147
78
 
148
- ## Common Pitfalls
79
+ ### Bad
80
+ Writing any sidecar question file (violates base rule 1).
149
81
 
150
- - Drafting before asking the critical questions. Always run intake first.
151
- - Ignoring confidence in image inferences. If you guessed, say so.
152
- - Auto-splitting. Never. Propose, wait, then split.
153
- - Mixing English and Spanish in the output. Pick the input language.
154
- - Skipping the `clarifications.md` file when assumptions remain.
82
+ ### Bad
83
+ Drafting a 15-section story when pre-split count ≥2 (violates split behavior differential).
155
84
 
156
85
  ## References
157
86
 
158
- - [[story-refine]] (use when input is an existing story to improve)
159
- - [[story-split]] (use when INVEST fails on Independent/Estimable/Small)
160
- - [[story-from-figma]] (use when input is a Figma link)
161
- - [[clarification-questions]]
162
-
163
- ## Output templates
164
-
165
- See `templates/story.jira-wiki.md` and `templates/story.standard.md` in this skill's folder for the canonical section ordering and formatting.
87
+ - [[storywright-base]] the rulebook
88
+ - [[story-refine]] (when input is an existing story)
89
+ - [[story-split]] (when count ≥2)
90
+ - [[story-from-figma]] (when input is Figma URL)
166
91
 
167
92
  <claude-specific>
168
- - Use extended thinking for INVEST check and for vision confidence scoring.
169
- - Cache the 15-section taxonomy and component invocation order across calls.
170
- - When input includes images, attach them to the same message as the prompt to use Claude's native vision (do not describe-then-reason in two steps).
171
- - Use prompt caching on the component skill bodies (they're long and reused).
93
+ - Read `[[storywright-base]]` before applying. Do not duplicate its rules in your reasoning.
94
+ - For mixed inputs, attach images in the same message for native vision.
95
+ - Use extended thinking for INVEST and pre-split counting.
172
96
  </claude-specific>
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: story-refine
3
- description: Audit an existing user story and fix it in place. Cohn+Gherkin canonical output. Asks clarifications ONLY in terminal. Recommends split when story has multiple outcomes.
3
+ description: Audit an existing user story and fix it in place. Cohn+Gherkin canonical. Inherits all hard rules from storywright-base.
4
4
  trigger: "/story-refine | refine this story | improve this story | refinar historia | this story is incomplete"
5
- intent: Refinement skill for stories that already exist but are incomplete or weakly specified. Default philosophy = Mike Cohn (story is a conversation starter, not a spec). Splits aggressively. Never produces mini-PRDs.
6
- version: 2.2.0
5
+ intent: Refinement skill for stories that already exist but are incomplete or weakly specified. Behavior 100% identical to siblings except for source (existing story text) and split-behavior (recommend /story-split when pre-split count ≥2).
6
+ version: 2.3.0
7
7
  inputs:
8
8
  - text
9
9
  - image
@@ -13,6 +13,7 @@ outputs:
13
13
  - story.jira-wiki.md
14
14
  - .storywright-context.json
15
15
  composes:
16
+ - _components/storywright-base
16
17
  - _components/clarification-questions
17
18
  - _components/acceptance-criteria
18
19
  - _components/invest-checklist
@@ -21,292 +22,81 @@ composes:
21
22
 
22
23
  ## Purpose
23
24
 
24
- Bring an existing user story up to standard *without* turning it into a feature spec. Output is conversation-ready, Cohn-format, Gherkin AC. If the story is too big, recommend split — do not refine an oversized story into a longer one.
25
+ Bring an existing user story up to standard *without* turning it into a feature spec.
25
26
 
26
- ## Hard rules (no exceptions)
27
+ **All hard rules, canonical output shape, language detection, mechanical pre-split test, context persistence, terminal-only Q, mechanical NxN dep matrix, per-child V audit, and INVEST handling live in `[[storywright-base]]`. Read that first. Anything in this file is a SOURCE-SPECIFIC or SPLIT-BEHAVIOR delta only.**
27
28
 
28
- 1. **Terminal-only clarifications.** Never write any sidecar question file. All gap questions go through `AskUserQuestion` (batch in groups of ≤4). If a gap is non-blocking, mark `⚠️ Assumed` inline in the story body — do not ask.
29
+ ## Source-specific differential
29
30
 
30
- 2. **Cohn + Gherkin canonical.** One Use Case block. One AC scenario per story (one Given chain, one `When`, one `Then`). If the story naturally needs >1 `When`/`Then` **STOP refining, recommend `/story-split`**.
31
+ - **Source:** an existing user story (text). May be vague, missing sections, or have hand-wavy ACs.
32
+ - **What changes vs base:**
33
+ - **Preserve original wording** where it was already good. Refine is NOT regenerate — if the PM already wrote a sharp persona / goal / so-that, do not rephrase it.
34
+ - **Don't renumber ACs** the team may already reference externally. Append new content, don't shuffle.
35
+ - **Detect which sections are present / missing / weak** before applying the base canonical block. Fill only what's weak; leave good sections alone.
36
+ - If companion image / Figma is attached, base conflict-detection applies. Story text is canonical for `User Story / Scope / Business value`; image/Figma is canonical for `component names / observable states` referenced in AC.
31
37
 
32
- 3. **No mini-PRDs.** The following sections are PROHIBITED in story output (they belong to DoD, design handoff, or sibling tickets):
33
- - Non-Functional Requirements blocks (a11y/i18n/perf/tokens) — these live in the team's global Definition of Done
34
- - Edge Cases enumerations — sibling stories or DoD
35
- - Dependencies as prose — use Jira ticket links instead
36
- - Visual specs derived from raster mockups (pixel measurements, hex inferences) inline with each claim
37
- - Refinement logs >3 lines (>5 if verdict is SPLIT RECOMMENDED)
38
+ ## Split behavior differential
38
39
 
39
- 4. **Output language matches the user's chat language**, not the story's. Auto-detect first (see rule 4a); only ask via `AskUserQuestion` if detection is ambiguous.
40
+ If the base **deterministic pre-split test** returns count ≥2:
41
+ - **STOP refining.**
42
+ - Output a terminal message listing candidate children + per-pair dep notes (base rule 10) + V audit (base rule 11).
43
+ - Recommend `/story-split` to the user.
44
+ - Do NOT produce an oversized refined story.
40
45
 
41
- 5. **Visual inference confidence — single banner only.** Do NOT tag every visual claim. Instead, add ONE banner at the top of the Design Reference block declaring the source type. All claims under that block inherit the banner's confidence level.
42
- - Raster source (PNG/JPG) banner: `**Source: raster mockup all visual specs are pixel-derived, not token-confirmed.**`
43
- - Figma source → banner: `**Source: Figma → values can be tokenized at implementation.**`
44
- - Design-token source → banner: `**Source: design tokens → values are authoritative.**`
45
- - Never assert hex values, pixel sizes, or exact spacing from raster without the raster banner.
46
-
47
- 6. **Sibling task IDs.** If story body references "next task", "future task", "another story", "siblings" — check `<output-folder>/.storywright-context.json` first (rule 9). If unresolved, ask via `AskUserQuestion`. If user has none yet, leave a `TODO: link sibling` placeholder, do not invent (unless rule F applies — see below).
48
-
49
- 7. **Mockup chrome detection — closed list.** Chrome = exactly these elements:
50
- - left nav rail / sidebar
51
- - top bar (user menu, global breadcrumbs, global search)
52
- - footer
53
- - persistent toast/snackbar slot
54
- - persistent modal scrim
55
- - app-level tabs
56
-
57
- If companion image shows any of the above and the story body does not mention them, ask via `AskUserQuestion` whether each one is in-scope, sibling-scope, or out-of-scope. Anything not on this list (cards, section headers, in-flow buttons) is NOT chrome — do not surface as a chrome question.
58
-
59
- 8. **Anti-PRD is part of INVEST `Small`, not a separate step.** See `[[invest-checklist]]` step 7 — line count ceiling lives inside the `Small` criterion so there is one source of truth.
60
-
61
- 9. **Cross-skill context persistence.** When the skill resolves any clarification via `AskUserQuestion`, write the **answers** to `<output-folder>/.storywright-context.json`. This is NOT a question file — it is a resolved-answers file. Read only from the exact output folder of the current invocation; never search siblings or parents. Schema:
62
- ```json
63
- {
64
- "version": 1,
65
- "decided_at": "<ISO date>",
66
- "decided_by_skill": "story-refine",
67
- "language": "EN | ES | ...",
68
- "chrome_scope": "in-scope | in-scope-placeholder | sibling | out-of-scope",
69
- "siblings": "TODO | <list of IDs> | not-applicable",
70
- "design_source": "raster | figma | tokens",
71
- "naming_pattern": "<see rule F>",
72
- "extra": {}
73
- }
74
- ```
75
- Future skills (`story-split`, `story-from-figma`, etc.) MUST read this file before re-asking the same questions.
76
-
77
- 10. **Children independence — mechanical detection (A).** When the skill recommends or executes split, build an NxN dependency matrix MECHANICALLY, not by intuition:
78
- - For each child Cj, parse its `Given:` and `and Given:` lines.
79
- - If any `Given` text contains a surface noun owned by child Ci (e.g., Cj's Given mentions "the grid" and Ci's title/scope owns "grid") → mark `DEP(Cj → Ci)`.
80
- - The dependency map IS the union of those text matches. Do not add deps "you sense" without a Given citation.
81
- - Affected child's INVEST `Independent` becomes `PARTIAL · depends on <Ci>`; parent EPIC lists explicit build order derived from the matrix (topological).
82
- - Independence-by-intuition is forbidden. If a dep is real but no Given mentions it, rewrite the child's Given to make it explicit, then re-run the match.
83
-
84
- 11. **Per-child V audit (C).** After split, for each candidate child run a one-line V test: "If only this child ships and no sibling exists, does a real user complete a real task?". If the answer is "no, useless until <other child> ships" → mark V as `WEAK · merge-upstream-candidate` and recommend merging that child into its parent surface instead of keeping it standalone. Do not let stylistic/UI-fragment children survive the split.
85
-
86
- 12. **Passive-goal downstream prompt (G).** If the story's `I want to` verb is passive/observational (`view, see, read, browse, look at, inspect, monitor`) and the `so that` does not name a follow-up user action — ask once via `AskUserQuestion`: "What does the user do with this data?". Use the answer to strengthen the `so that` clause. This forces explicit value. Skip the prompt if `so that` already names a downstream action (e.g., "so that I can call the customer").
87
-
88
- ### 4a. Language auto-detect — expanded signals (E)
89
-
90
- Run cheap detection before asking. Look at multiple signals, not just Gherkin keywords:
91
-
92
- | Signal | Where to look | Weight |
93
- |---|---|---|
94
- | Gherkin keywords in M ("Given/When/Then") | AC block | high |
95
- | Persona phrasing in M ("As a user" vs "Como un usuario") | Use Case | high |
96
- | Column / field names in M ("Phone - primary", "Teléfono - principal") | AC bullets | medium |
97
- | Domain verbs in M ("clicking" vs "hacer clic", "submitting" vs "enviar") | AC bullets | medium |
98
- | Title language | header | low |
99
-
100
- **Decision:**
101
- - All high+medium signals agree on language M → adopt M silently. No question. Mark inline `⚠️ Assumed: output language = <M> (auto-detected from <signals>)`.
102
- - Signals split (some EN, some ES) → ask once via `AskUserQuestion`.
103
- - User-chat language = L, story-body signals = M, but high signals tie → prefer M (story body is contract).
104
-
105
- Persist via rule 9.
106
-
107
- ### Rule F. Naming pattern — ask once, persist
108
-
109
- When the skill needs to invent a tentative ticket slug (e.g., for sibling references with no IDs yet) AND `.storywright-context.json` has no `naming_pattern` field, ask once via `AskUserQuestion`:
110
-
111
- ```
112
- Which naming pattern do you use for tickets?
113
- - kebab-case feature-action → "customer-search-bar-wire"
114
- - verb-noun → "wire-search-bar"
115
- - domain-action → "search.customer.wire-input"
116
- - Jira prefix + numeric → "CSB-001" (assume next available)
117
- ```
118
-
119
- Persist the answer in `.storywright-context.json` under `naming_pattern`. Use it for all sibling slugs in the current run AND future skills reading the same context file.
120
-
121
- ## When to use
122
-
123
- - User pastes an existing story (text) and asks to make it Jira-ready.
124
- - A story has ACs but no testable outcomes.
125
- - INVEST gate fails on `Testable` or `Negotiable` — fixable in place (not splittable).
126
-
127
- For oversized stories that fail `Independent / Estimable / Small`, OR have multiple `When`/`Then` pairs, OR have >1 distinct outcome (per the deterministic counter below) → hand off to `[[story-split]]` instead.
128
-
129
- ## Inputs & interpretation
130
-
131
- - **text** — existing story. Detect which sections are present, which are missing, which are weak.
132
- - **image (optional)** — companion screenshot/mockup. Use to validate UI claims only. NEVER as source for pixel-precise visual specs inline with each AC claim (see rule 5).
133
- - **figma-link (optional)** — companion design. Use to enrich AC observable outcomes (states, named components).
134
-
135
- ### Mixed inputs source-priority
136
-
137
- - Story text canonical for `User Story / Scope / Business value`.
138
- - Image/Figma canonical for `component names / observable states` referenced inside AC.
139
- - Conflicts → BLOCKING `AskUserQuestion`. Never silently rewrite the story to match the design.
140
-
141
- ## Canonical output shape (this is the WHOLE story)
142
-
143
- ```markdown
144
- ### [Title]
145
-
146
- #### Use Case
147
- - **As a** [persona]
148
- - **I want to** [action]
149
- - **so that** [outcome with downstream action — see rule G]
150
-
151
- #### Preconditions (optional, only if user provided)
152
- - ...
153
-
154
- #### Out of Scope (optional, only if user provided)
155
- - ...
156
-
157
- #### Acceptance Criteria
158
- - **Scenario:** [single-outcome scenario name]
159
- - **Given:** [context — surface nouns here drive dep matrix per rule A]
160
- - **and Given:** [context]
161
- - **When:** [single trigger]
162
- - **Then:** [single observable outcome]
163
-
164
- #### Design Reference (optional)
165
- **Source: <raster | figma | tokens> → <inherited-confidence banner from rule 5>**
166
- - [link or path]
167
- - visual notes: [...]
168
-
169
- #### INVEST
170
- - I/N/V/E/S/T — one line each, evidence-based.
171
- - **Verdict:** READY | SPLIT RECOMMENDED | NEEDS REFINEMENT | NOT A STORY
172
-
173
- #### Refinement log (≤3 lines; ≤5 if verdict=SPLIT)
174
- - ...
175
- ```
176
-
177
- Nothing else. No NFR block. No Edge Cases enumeration. No Dependencies prose. No Assumptions block (assumptions get `⚠️ Assumed` inline or are resolved via `AskUserQuestion`).
46
+ If count ≤1:
47
+ - Proceed with the base step-by-step Application skeleton, applying the source-specific preservation rules above.
178
48
 
179
49
  ## Application (step-by-step)
180
50
 
181
- 0. **Detect companion sources** (image, figma-link). Run conflict detection against story text. Run chrome-detection using the closed list in rule 7. Surface conflicts as BLOCKING `AskUserQuestion` calls.
182
-
183
- 1. **Parse story** into the canonical sections above. Note: present / missing / weak.
184
-
185
- 2. **Read prior context.** If `<output-folder>/.storywright-context.json` exists (exact folder only — no sibling fallback), load it. Apply resolved answers; skip the corresponding questions.
186
-
187
- 3. **Language resolution (rule 4 + 4a).** Auto-detect using the expanded signal table. Ask only if signals split. Persist via rule 9.
188
-
189
- 4. **Passive-goal check (rule G).** If `I want to` verb is observational AND `so that` lacks downstream action → ask once. Persist resolution into the strengthened `so that` clause.
190
-
191
- 5. **Gap-check.** For each weak/missing section:
192
- - **Blocking** (changes scope, AC outcome, or persona) → `AskUserQuestion` immediately (batched ≤4).
193
- - **Non-blocking** (additive detail) → fill inline marked `⚠️ Assumed: <text>`. Do not ask.
194
-
195
- 6. **Sibling reference check (rule 6).** If found and unlinked → ask via `AskUserQuestion` once. If user opts for tentative slugs, apply rule F (naming pattern). Persist via rule 9.
196
-
197
- 7. **Deterministic pre-split test.** Apply this counter mechanically — do not eyeball:
198
-
199
- **Count = sum of all hits below:**
200
- | Signal | Hit value |
201
- |---|---|
202
- | AC bullet starting with an action verb at the user level ("clicking", "submitting", "entering", "navigating") | +1 each |
203
- | Distinct `When [event]` phrasing already implied in the story | +1 each |
204
- | Distinct named UI surface mentioned at the AC level — see (D) below for what counts | +1 each |
205
-
206
- **(D) Surface vs styling rule (deterministic).** A "named UI surface" counts as +1 ONLY if it has its own user goal — meaning there is a verb in the story body where the user *does something with that surface* (clicks it, navigates with it, reads it, configures it). If a noun is mentioned only in a styling context (color, background, padding, alignment) or as a sub-component of a parent surface (column inside a grid, label inside a button) → it is NOT a surface. It is styling. Count = 0.
207
-
208
- Examples:
209
- - "header row visually distinct (purple background)" — styling of grid → 0
210
- - "pagination control with page numbers and arrows" — surface with user goal (navigating) → +1
211
- - "5 columns: Code, Customer name, Phone, Email, Address" — columns are sub-components of grid → 0 (grid still counts once)
212
- - "results counter next to search button" — surface with user goal (reading count) → +1
213
-
214
- **Do NOT count:**
215
- - sub-bullets describing the same flow (column names inside one grid = the grid itself, not separate outcomes)
216
- - styling of an existing surface (header purple = part of grid, not a new outcome)
217
- - preconditions or "rendered" statements (passive layout assertions are not Whens)
218
-
219
- **Decision:**
220
- - Count ≤1 → continue to step 8.
221
- - Count ≥2 → **STOP. Recommend `/story-split` via terminal message.** Output: list of candidate children + per-pair dependency note (rule 10) + V audit per child (rule 11).
222
-
223
- 8. **Fill the weak sections** using `[[acceptance-criteria]]` (single Gherkin block) and `[[invest-checklist]]`. Preserve original wording where it was already good.
224
-
225
- 9. **Run INVEST** via `[[invest-checklist]]` (which embeds the anti-PRD line-count check inside `Small` — rule 8).
226
- - `READY` → render.
227
- - `SPLIT RECOMMENDED` → STOP, recommend split (and run rule 10 children-independence matrix + rule 11 V audit per child).
228
- - `NEEDS REFINEMENT` → iterate failing dimension, max 1 cycle, then STOP.
229
- - `NOT A STORY` → tell user it's a tech task and stop.
230
-
231
- 10. **Render** both outputs via `[[jira-wiki-formatter]]`. Files: `story.standard.md` + `story.jira-wiki.md`. Plus `.storywright-context.json`. No other files.
232
-
233
- 11. **Refinement log** ≤3 bullets (≤5 if SPLIT) appended at story end.
51
+ Follow the **base Application** skeleton exactly. Refine-specific behavior:
52
+ - Step 5 (gap-check): only fill **weak/missing** sections; leave sharp sections alone.
53
+ - Step 7 (pre-split test): on count ≥2 STOP refining, route to `/story-split` recommendation.
54
+ - Step 11 (log): label as "Refinement log".
234
55
 
235
56
  ## Examples
236
57
 
237
58
  ### Good — READY
238
59
  Input: story with title + Use Case + 2 vague ACs.
239
- Output: canonical block, ≤30 lines, AC tightened to single Given/When/Then, INVEST verdict READY, ≤3-line refinement log, `.storywright-context.json` written.
240
-
241
- ### Good SPLIT (Spanish)
242
- Input: historia con 7 bullets de AC (grilla + contador + paginación + link).
243
- Output: NO refined story. Mensaje terminal:
244
- ```
245
- SPLIT RECOMMENDED. Conteo determinístico = 4 (grilla, contador, paginación, link).
246
- Children candidatos:
247
- 1. Page shell + chrome (si in-scope)
248
- 2. Grid 5 columnas + header style
249
- 3. Contador de resultados
250
- 4. Control de paginación
251
- 5. Link affordance en customer name
252
- Matriz independencia (parse mecánico de Given):
253
- - C4.Given menciona "the grid" → DEP(C4 → C2) → PARTIAL
254
- - C5.Given menciona "the grid" → DEP(C5 → C2) → PARTIAL
255
- - Orden build: C1 → C2 → {C3, C4, C5}
256
- V audit per child:
257
- - C1: PASS (chrome funcional = workspace context)
258
- - C2: PASS (read records)
259
- - C3: WEAK · merge-upstream-candidate — counter sin grid no entrega valor
260
- - C4: PASS (navigate pages)
261
- - C5: PASS (link affordance)
262
- Corré /story-split para expandir; considera mergear C3 en C2.
263
- ```
60
+ - Pre-split count = 1.
61
+ - Tighten ACs to single Given/When/Then. Leave Use Case alone (was good).
62
+ - INVEST READY. ≤3-line Refinement log. Render.
264
63
 
265
- ### Good — passive-goal prompt fires
266
- Input: "As a user, I want to view list of customers, so that I quickly find details."
267
- Skill detects passive verb `view` + thin `so that`.
268
- Asks: "What does the user do with the customer they find?"
269
- User: "Call them to schedule a service."
270
- Refined `so that`: "so that I can quickly find a customer and call them to schedule a service."
64
+ ### Good — SPLIT
65
+ Input: story with 7 AC bullets (grid + counter + pagination + link).
66
+ - Pre-split count = 4 (grid, counter, pagination, link).
67
+ - STOP. Terminal message: candidate children + dep notes + V audit + "Run `/story-split`".
68
+ - No refined story written.
271
69
 
272
- ### Bad
273
- Adding NFR / a11y / i18n / Dependencies sections "to be thorough". Violates rule 3.
274
-
275
- ### Bad
276
- Writing any sidecar question file instead of asking via `AskUserQuestion`. Violates rule 1.
70
+ ### Good — passive goal fires
71
+ Refining: *"As a user, I want to view list of customers, so that I find details."*
72
+ - Rule G of base fires. Ask: "What does the user do with the customer they find?"
73
+ - User: "Call them." → strengthen so-that.
277
74
 
278
75
  ### Bad
279
- Tagging every visual claim with `[mockup-pixel-derived]` instead of using the single banner. Violates rule 5.
76
+ Treating refine like generate restating the user goal when the PM already wrote it.
280
77
 
281
78
  ### Bad
282
- Claiming 5 children all `Independent` after split without running the mechanical matrix from rule 10.
79
+ Renumbering AC bullets the team may already reference.
283
80
 
284
81
  ### Bad
285
- Counting "header row purple" as +1 in the pre-split test. It is styling of the grid (rule D), not a separate surface. Should be 0.
82
+ Producing a 400-line refined story (violates base rule 3 + INVEST Small ceiling).
286
83
 
287
- ## Common Pitfalls
84
+ ## Common Pitfalls (refine-specific)
288
85
 
289
- - Treating refine like generate. If the PM already wrote the user goal, don't restate it.
290
- - Renumbering ACs — append new content, don't shuffle.
291
- - Skipping the deterministic pre-split test (step 7). Refining oversized stories produces oversized refined stories.
292
- - Eyeballing outcome counts or dep matrix instead of running the mechanical rules (D, A).
293
- - Re-asking questions already answered in `.storywright-context.json`.
294
- - Letting weak-V children survive the split (rule 11).
295
- - Skipping the downstream-action prompt for passive goals (rule G).
86
+ - Rewriting good content. If a section is sharp, leave it.
87
+ - Renumbering ACs. Append, don't shuffle.
88
+ - Skipping the base pre-split test (step 7) refining an oversized story produces an oversized refined story.
89
+ - All other pitfalls listed in `[[storywright-base]]` apply equally.
296
90
 
297
91
  ## References
298
92
 
299
- - [[story-generate]]
300
- - [[story-split]]
301
- - [[invest-checklist]]
302
- - [[acceptance-criteria]]
93
+ - [[storywright-base]] — the rulebook
94
+ - [[story-generate]] (when input is ambiguous, not an existing story)
95
+ - [[story-split]] (when count ≥2)
96
+ - [[story-from-figma]] (when input is Figma URL)
303
97
 
304
98
  <claude-specific>
305
- - Diff the original sections against the refined ones in your reasoning; only emit changes that materially improve the story.
306
- - Never call Write for any question/clarification sidecar file. Use `AskUserQuestion`.
307
- - Treat step 7 (deterministic pre-split test) as a hard gate; do not skip even when the user explicitly asks to refine.
308
- - Read `.storywright-context.json` ONLY from the exact target output folder. Do not search siblings or parents.
309
- - After split, build the dependency matrix from Given-text parsing (rule 10), not intuition.
310
- - After split, run V audit per child (rule 11) and flag merge-upstream-candidates loudly.
311
- - For passive `I want to` verbs, fire rule G prompt before INVEST.
99
+ - Read `[[storywright-base]]` before applying. Do not duplicate its rules in your reasoning.
100
+ - Diff the original sections against the refined ones; only emit changes that materially improve the story.
101
+ - Use extended thinking when running the base pre-split counter.
312
102
  </claude-specific>