Some checks failed
release / tag (push) Has been cancelled
Phase 1 of mathias/skills extraction (infra#62 Track D — homelab next-step plan addendum). Imports ~/dev/.skills/ verbatim (19 skill dirs + SKILLS_INDEX.md) and adds the installation surface: - Taskfile.yml — install / update / list / release / check targets - install.sh — bootstrap installer for hosts without Task. Idempotent symlink wirer; default checkout at ~/.local/share/skills/ on every host; SKILLS_REF env var pins a tag (default: main). - .gitea/workflows/release.yml — auto-tag every push to main by Bump-Type footer (major/minor/patch, default patch). Skipped when commit contains [skip-release]. - README — usage, versioning, contribution flow, secret-hygiene rule. Phase 1 wires Claude Code only (~/.claude/skills/<name> global + <repo>/.claude/skills/<name> per-repo). Phase 2 adds Crush, opencode, antigravity, and gitea-resident agents (cobalt-dingo, agentsquad) once their skill conventions are researched. Public repo, markdown-only — no secrets, no client names. Verified via pre-push grep before initial push. [skip-release]
247 lines
7.6 KiB
Markdown
247 lines
7.6 KiB
Markdown
---
|
||
name: user-stories
|
||
description: Decompose problems into thin, deliverable user stories using Elephant Carpaccio and INVEST criteria. Use after problem analysis, before planning and implementation.
|
||
---
|
||
|
||
# User Stories
|
||
|
||
## Core Philosophy
|
||
|
||
A user story is a placeholder for a conversation, not a specification. It captures who needs something, what they need, and why — in the smallest unit that still delivers end-to-end value.
|
||
|
||
The goal is **thin slices** — the Elephant Carpaccio technique. An elephant is too big to eat at once; slice it as thin as possible (carpaccio) so each slice is still valuable, testable, and deliverable.
|
||
|
||
## When to Use
|
||
|
||
- You have a problem analysis and need to break it into implementable units
|
||
- A feature is too large to estimate or implement
|
||
- You need to communicate scope and prioritize with a stakeholder
|
||
- You need to discover the minimum viable version of a feature
|
||
|
||
**Input required:** A problem analysis (load `problem-analysis` skill first) or clear requirements.
|
||
|
||
## INVEST Criteria
|
||
|
||
Every user story must be:
|
||
|
||
| Criterion | Meaning |
|
||
|-----------|---------|
|
||
| **Independent** | Can be developed without requiring another story to be complete first |
|
||
| **Negotiable** | Details can be discussed and refined |
|
||
| **Valuable** | Delivers clear value to an end user (not just infrastructure) |
|
||
| **Estimable** | Clear enough scope to understand complexity |
|
||
| **Small** | Can be completed in a single sprint (1–2 weeks) |
|
||
| **Testable** | Has clear, specific acceptance criteria |
|
||
|
||
## Story Format
|
||
|
||
```
|
||
**Story Title:** [Descriptive name]
|
||
|
||
**As a** [user type / persona]
|
||
**I want** [the capability or feature]
|
||
**So that** [the business value or outcome]
|
||
|
||
**Acceptance Criteria:**
|
||
- Given [starting context]
|
||
When [action taken]
|
||
Then [observable outcome]
|
||
- Given [another context]
|
||
When [action]
|
||
Then [outcome]
|
||
|
||
**Definition of Done:**
|
||
- [User-facing quality requirement]
|
||
- [Business completion criterion]
|
||
- [Performance/security requirement if applicable]
|
||
```
|
||
|
||
## Elephant Carpaccio: Slicing Technique
|
||
|
||
The most common mistake is making stories too large. Use these slicing patterns to cut large stories thin.
|
||
|
||
### Slicing Pattern 1: By Data Variation
|
||
|
||
If a feature works differently for different data, make each variation its own story.
|
||
|
||
```
|
||
Large story: "Users can search invoices"
|
||
|
||
Thin slices:
|
||
1. "Users can search invoices by exact invoice number"
|
||
2. "Users can search invoices by customer name (partial match)"
|
||
3. "Users can search invoices by date range"
|
||
4. "Users can combine multiple search criteria"
|
||
```
|
||
|
||
### Slicing Pattern 2: By User Scenario
|
||
|
||
Different user journeys are separate stories.
|
||
|
||
```
|
||
Large story: "Users can manage their account"
|
||
|
||
Thin slices:
|
||
1. "New users can register with email and password"
|
||
2. "Registered users can log in"
|
||
3. "Logged-in users can update their display name"
|
||
4. "Users can reset their password via email"
|
||
```
|
||
|
||
### Slicing Pattern 3: By Error Condition
|
||
|
||
Happy path first, then error handling as a separate story.
|
||
|
||
```
|
||
Story 1: "Users can upload a PDF invoice (happy path)"
|
||
Story 2: "Users see a clear error when uploading non-PDF files"
|
||
Story 3: "Users see a clear error when uploading files > 10MB"
|
||
```
|
||
|
||
### Slicing Pattern 4: By Performance
|
||
|
||
Basic version first, then performance improvement as a separate story.
|
||
|
||
```
|
||
Story 1: "Users can export invoice reports (any performance)"
|
||
Story 2: "Invoice export completes in under 5 seconds for reports up to 1000 items"
|
||
```
|
||
|
||
### Slicing Pattern 5: By Rules/Workflow
|
||
|
||
Each business rule is a candidate for its own story.
|
||
|
||
```
|
||
Large story: "The system applies discounts to orders"
|
||
|
||
Thin slices:
|
||
1. "Premium customers receive a 10% discount automatically"
|
||
2. "Orders over 1000 SEK receive free shipping"
|
||
3. "Discount codes can be applied at checkout"
|
||
```
|
||
|
||
## Prioritization Framework
|
||
|
||
Order stories by:
|
||
|
||
1. **Risk reduction first** — stories that test unknown territory early
|
||
2. **User value** — which story delivers the most value if we stopped here?
|
||
3. **Learning** — stories that reveal information needed for later stories
|
||
4. **Dependencies** — stories that others depend on come first
|
||
|
||
```
|
||
Risk reduction: "Integrate with Bankgirot API (spike)"
|
||
→ We don't know if this is feasible; find out first
|
||
|
||
User value: "Users can view their invoice list"
|
||
→ Most basic valuable state; everything else builds on this
|
||
|
||
Foundation: "Authentication: users can log in"
|
||
→ Many other stories depend on this
|
||
```
|
||
|
||
## Story Decomposition Example
|
||
|
||
**Problem:** A financial automation tool needs to process invoices for payment.
|
||
|
||
**Too large:** "Process invoices for payment"
|
||
|
||
**Decomposed with Elephant Carpaccio:**
|
||
|
||
1. **Parse PDF invoice, extract total amount**
|
||
- Given a valid Swedish PDF invoice
|
||
- When I upload it to the system
|
||
- Then the system displays the extracted amount and recipient
|
||
- AC: Displays IBAN, amount, and due date for 10 sample invoices
|
||
|
||
2. **Queue a payment for approval**
|
||
- Given a parsed invoice
|
||
- When I click "Approve for payment"
|
||
- Then the payment is queued with status "pending"
|
||
- AC: Payment appears in pending list, can be viewed
|
||
|
||
3. **Execute a queued payment via Bankgirot**
|
||
- Given a payment in "pending" status
|
||
- When the batch window runs
|
||
- Then an ISO 20022 payment instruction is submitted
|
||
- AC: Submission confirmed, status changes to "submitted"
|
||
|
||
4. **View payment status after submission**
|
||
- As a user I can see whether a submitted payment succeeded or failed
|
||
- AC: Status reflects Bankgirot confirmation/rejection
|
||
|
||
5. **Handle rejected payments**
|
||
- Given a submitted payment that is rejected by Bankgirot
|
||
- When the rejection is received
|
||
- Then the user sees a clear error message with the rejection reason
|
||
- AC: Rejection reason from Bankgirot is displayed, payment status is "rejected"
|
||
|
||
Each slice is independently valuable and testable.
|
||
|
||
## Output Document
|
||
|
||
The output of this skill is a `user-stories.md` file:
|
||
|
||
```markdown
|
||
# User Stories: [Feature Name]
|
||
|
||
## Personas
|
||
- **[Persona 1]**: [Who they are and what they care about]
|
||
- **[Persona 2]**: ...
|
||
|
||
## Stories (Prioritized)
|
||
|
||
### Phase 1: Foundation
|
||
|
||
#### Story 1: [Title]
|
||
As a [persona]...
|
||
|
||
#### Story 2: [Title]
|
||
...
|
||
|
||
### Phase 2: Core Features
|
||
|
||
#### Story 3: [Title]
|
||
...
|
||
|
||
## Decomposition Rationale
|
||
[Why stories were sliced this way; what dependencies exist]
|
||
|
||
## Stories Deferred to v2
|
||
- [Story A]: [Reason]
|
||
```
|
||
|
||
## Common Mistakes
|
||
|
||
| Mistake | Fix |
|
||
|---------|-----|
|
||
| Technical tasks disguised as stories ("Set up database") | Reframe as user value ("Users can create an account") |
|
||
| "And" in the title | Split into two stories |
|
||
| No acceptance criteria | Every story must have testable criteria |
|
||
| Stories depending on each other at the same priority level | Reorder so foundational stories come first |
|
||
| Implementation details in acceptance criteria ("use PostgreSQL") | Keep criteria in user/business terms |
|
||
|
||
## Mathias Context
|
||
|
||
As a digital PM:
|
||
- Stories should capture **business value**, not technical tasks
|
||
- Stories are the bridge between problem analysis and technical implementation
|
||
- When the business says "build feature X", decompose it into stories that can be delivered incrementally
|
||
- A story with 10 acceptance criteria is not one story — it's many. Split it.
|
||
- The goal is to find the thinnest slice that's still worth shipping
|
||
|
||
## Transition to Next Steps
|
||
|
||
After stories are written:
|
||
|
||
1. Load `spec-driven-dev` skill to write a technical specification
|
||
2. Load `planning` skill to convert stories into an implementation plan
|
||
3. Load `atdd` skill to implement stories with acceptance test-driven development
|
||
|
||
## Cross-References
|
||
|
||
- Requires: `problem-analysis` skill output
|
||
- Leads to: `planning` and `atdd` skills
|
||
- INVEST criteria origin: Bill Wake
|
||
- Elephant Carpaccio: Alistair Cockburn
|