refactor(plugin)!: ship as a Claude Code plugin, one dir link per harness

Skills move to skills/<name>/SKILL.md and the repo gains both manifests, so
it is now a marketplace hosting exactly one plugin whose root is the repo
root (source: "."). Claude Code installs it from git; no symlinks involved.

Why: install.sh wired the library into every consuming repo as an ABSOLUTE
symlink to $CHECKOUT_DIR. The checkout moved three times, most recently when
local-dev@1966d5a dropped the embedded .skills/ copy, and nothing migrated
the links — 243 dangling links across 12 repos, hidden from git by the
**/.claude/skills/ ignore rule. Worse, ~/dev spans two path roots
(/Users/mathias on the iCloud-shared Macs, /home/mathias on koala), so an
absolute link stored there is broken on one side by construction. Re-running
the installer cannot fix that; only removing the mechanism can.

install.sh keeps the harnesses with no plugin system and drops from 42 links
per harness to one directory link, via the convergent ~/.agents/skills
convention that Pi and OpenCode both read:

  ~/.agents/skills          -> $CHECKOUT_DIR/skills
  ~/.config/crush/skills    -> ~/.agents/skills
  ~/.config/opencode/skills -> ~/.agents/skills

wire_claude_repo is deleted outright rather than gated behind a flag — on a
mixed-root fleet it cannot be made correct. Antigravity and Vibe targets go
too; both unused. CHECKOUT_DIR keeps its host-local default deliberately:
pointing it into ~/dev would put a git working tree inside iCloud with two
concurrent writers.

Taskfile drops five near-identical wiring loops (they had already drifted)
and delegates to install.sh. `task check` gains frontmatter validation, a
stray-root-entry gate, and manifest/tag version parity — the loose
secret-hygiene.md sat unloadable for months because nothing checked layout.

Verified: claude plugin validate . passes clean; a probe skill loaded as
skills:zzprobe through --plugin-dir; task check green at 42 skills.

Refs: #23
Bump-Type: minor

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BeAp5LTscnz2W7Ubt4eJ6m
This commit is contained in:
2026-08-23 14:29:51 +02:00
co-authored by Claude Opus 5
parent 21be3ea245
commit 56a947b2a0
88 changed files with 182 additions and 253 deletions
+246
View File
@@ -0,0 +1,246 @@
---
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