stories
Use only within active engineer/conduct DECIDE after architecture approval, when a committed `.docs/stories` acceptance artifact is required. Do not invoke for general user-story examples, requirements discussion, or direct implementation requests.
- License 许可
- Apache-2.0
- 最近更新
- 2026-11-11
- Stars
- ★ 7
- Forks
- 2
01 前言 Front Matter
- name
- stories
- phase
- decide
- requires
- [ "verify-claims" ]
- standalone
- true
- description
- Use only within active engineer/conduct DECIDE after architecture approval, when a committed `.docs/stories` acceptance artifact is required. Do not invoke for general user-story examples, requirements discussion, or direct implementation requests.
- enforcement
- gating
- implicit_invocation
- required
03 SKILL.md 正文
Purpose
Generates granular stories with happy and negative path scenarios, and is the always-present acceptance-criteria artifact for both tracks:
- Product track — extract stories from the approved PRD's enumerated functional requirements
(
FR-N); each FR is a unit. - Technical track — no PRD; write technical stories (Given/When/Then against the technical change) from the technical intent + the approved architecture.
Stories run after architecture-review (the design is known), so they describe behavior (WHAT) grounded in the agreed design — but they state observable behavior/acceptance, NOT the mechanism (architecture informs which scenarios exist; it is not copied as mechanism into story text — the how is the plan's job). Negative paths are mandatory — they feed TDD RED phases.
Read the Scope boundary: from .docs/track/<slug>.md as binding; preserve the confirmed narrow/comprehensive breadth outcome; do not permit a materially broader expansion beyond it unless the operator confirms before it enters the artifact.
Correctness gate: acceptance criteria become the definition of done. Apply the /verify-claims
protocol — if a scenario encodes an assumption about expected behavior that was never confirmed
(against the FR, the ADR, or the operator), flag it with its confidence and HARD-BLOCK for approval
(HALT if autonomous) rather than baking the guess into a Given/When/Then.
Architecture-induced negatives (do not miss these): because stories follow architecture, every failure mode a design decision introduces (an external call that times out, a queue that drops/dupes, a lock that contends) MUST appear as a negative-path story. These are exactly the cases that were missed when stories preceded the design.
If writing stories reveals a genuine structural gap the design lacks (a missing component/seam), do
not paper over it in story text — kick back to architecture (which re-opens in amendment mode).
Documentation boundary
Do not create stories, requirements, acceptance criteria, Done-When items, or notes for writing or
updating ordinary project documentation. When the request is documentation-only, route it to
/explore for direct documentation delivery. When documentation accompanies functional work, omit
the documentation portion entirely and write stories only for the functional behavior.
Practices
1. Load Input
- Product track: read the approved PRD from
.docs/specs/; work through its Functional Requirements (FR-N) — each FR is the unit you extract stories from. Technical track (no PRD): derive acceptance criteria from the technical intent + the approved architecture/ADRs. - Reference tech-context from session if loaded (e.g., Rails-specific negative paths)
- Review existing stories in
.docs/stories/for this feature area (avoid duplicates) - Check for DRAFT stories from
/bootstrap— if stories haveStatus: DRAFT, review and complete them rather than generating from scratch. Fill inTODOnegative paths, verify happy paths match actual behavior, and change**Status:** DRAFTto**Status:** Acceptedwhen done. - Recall relevant
.memory/entries
2. Generate Stories
Work through the PRD's functional requirements in order. For each FR-N, write one or
more granular stories — split a requirement into multiple stories when it spans distinct
behaviors, so each story stays small and independently verifiable. Tag every story with the
FR-N it came from (traceability: PRD → story → plan task). Every FR-N must be covered by
at least one story.
For removal-shaped stories, follow /code-removal: acceptance criteria describe surviving
observable behavior, never that code, files, or symbols no longer exist.
Every story heading MUST carry an id, in the form ## Story <id>: <title> (## Story 1: …,
## Story 2.1: …). The id is machine-parsed, not decorative: the engine splits a stories file into
per-story blocks by matching ## Story followed by whitespace and an id of [A-Za-z0-9.-].
A heading with no id — ## Story: Title — does not match, so the whole file collapses into a single
unnamed block and three gates silently degrade:
- the mandatory happy-path/negative-path check runs once over the whole file instead of per story, so a story missing a negative path passes whenever any other story in the file has one;
- per-story plan coverage falls back to a single file-derived id, so a plan covering one story satisfies coverage for all of them;
- every
story-<id>citation in a coherence mapping resolves to nothing and is rejected as a fabricated id — the first loud symptom, and it appears only at land, long after the real mistake.
Separators other than whitespace after the id are free (## Story 1: Title and ## Story 1 — Title
both parse). What is not optional is the id itself.
**Status:** Accepted
## Story 1: [Descriptive Title]
**Requirement:** FR-N
As a [role], I want [action] so that [outcome].
### Acceptance Criteria
#### Happy Path
- Given [specific precondition], when [specific action], then [specific expected result]
- Given [specific precondition], when [specific action], then [specific expected result]
#### Negative Paths
- Given [precondition], when [invalid input submitted], then [specific error handling]
- Given [precondition], when [unauthorized access attempted], then [specific rejection]
- Given [precondition], when [dependency times out], then [specific graceful degradation]
- Given [precondition], when [concurrent modification occurs], then [specific conflict resolution]
Do not prefix criteria with ids. The engine derives them positionally as
`S<story-heading-id>.<n>`, numbering happy paths then negative paths in one run — so the
first negative path of Story 1 is `S1.3`, never `S1.N1`. An authored id the engine does
not derive is unkeyable and halts `prd_audit`.
### Done When
- [ ] [Concrete, verifiable output — e.g., POST /contacts returns 201 with contact JSON including `id`, `name`, `email`]
- [ ] [Persistent side effect confirmed — e.g., contact row exists in database with correct attributes]
- [ ] [Contract/format verified — e.g., response envelope matches API contract]
"Done When" is the primary success gate. Acceptance criteria describe behavior; "Done When" defines the measurable outputs
build_review,prd_audit, or/code-reviewchecks to confirm the story is complete. Every story MUST have a "Done When" section. Checkboxes must be concrete and independently verifiable — not restatements of acceptance criteria.
3. Mandatory Negative Path Categories
Every story MUST consider these categories. Not all apply to every story — but each must be explicitly evaluated and included when relevant:
| Category | Applies When | Example |
|---|---|---|
| Invalid input | User-facing endpoints, form submissions | Malformed email, empty required fields, SQL injection attempts |
| Auth/permission failures | Protected resources | Unauthenticated access, wrong role, expired token |
| Timeouts & network errors | External API calls, DB queries | API unreachable, connection pool exhausted |
| Concurrent access | Shared mutable state | Two users editing same record, race conditions |
| Resource exhaustion | File uploads, batch processing | Disk full, memory limit, connection pool depleted |
| Partial failure & rollback | Multi-step operations | Step 3 of 5 fails — are steps 1-2 rolled back? |
| Dependency unavailability | DB, cache, queue, external APIs | Redis down, database unreachable, S3 outage |
| Data integrity | Writes, updates, deletes | Orphaned records, constraint violations, cascade effects |
| Cascade deletion effects | Entity has dependents (direct or transitive) | User deleted → what happens to their assigned cards, authored comments, owned teams? Test at every FK reference, not just direct parent |
| Model-level immutability | Record should be read-only after creation | Audit log entry, completed transaction — enforce at model layer (readonly!, validation), not just by omitting API endpoints |
| Exception class hierarchy | Code rescues/catches specific exception types | Verify rescue clauses match the actual exception tree — e.g., Stripe::AuthenticationError is NOT a subclass of Stripe::CardError. Test that the right exception type is caught, not a parent or sibling. |
| Dedup/idempotency key analysis | Any idempotency or deduplication criterion | Verify the dedup key correctly identifies duplicates without false positives (blocking legitimate operations) or false negatives (allowing true duplicates through). Test with edits that should NOT trigger dedup. |
| Invariant side-effect on alternate branches | A happy path delegates a critical side effect (record/ledger write, cleanup, metric, cache invalidation) to a helper, and an alternate branch (error path, no-remote/offline, degraded mode, early return) can bypass that helper | A no-remote authoring path returns before the helper that writes the authored-ledger entry → the ledger silently misses the key. Write a negative-path scenario asserting the side effect STILL occurs on each alternate branch — do not assume the happy-path test covers it. |
If tech-context is loaded, also include stack-specific categories. For Rails:
- N+1 queries on list endpoints
- Unsafe migrations on large tables
- Mass assignment via unexpected params
- Missing database indexes
- Background job failure and retry behavior
Complexity-Aware Depth: When the feature is classified as Small by /conduct's
complexity assessment, negative paths are required per STORY (at least 1 per story), not per
criterion. Focus on the highest-risk negative path for each story (typically validation/auth).
For Medium and Large features, the full per-criterion rule applies.
4. Quality Gates
GATE: No story is accepted without at least one negative path per acceptance criterion.
Each negative path MUST be:
- Concrete — "Given a user with expired JWT, when they request /api/orders, then they receive 401 with error body
{error: 'token_expired'}" - NOT vague — Reject: "handle errors gracefully" / "return appropriate error" / "fail safely"
- Testable — Each Given/When/Then maps directly to a test assertion
5. Save Stories
Save to .docs/stories/<feature-name>.md (one file per feature area).
If stories already exist for this feature area, append new stories to the existing file. When a DECIDE correction supersedes or modifies an assertion in an accepted story, replace the superseded story content in place during that DECIDE pass; never defer the correction to a later BUILD phase. The story carries no amendment record of any kind. Git history and the spec PR carry the correction's provenance. The corrected artifact becomes part of the spec-branch baseline before BUILD begins.
When a DECIDE pass amends a story file with pre-existing amendment blocks, resolve every amendment block in that file by folding its determined behavior into the current behavioral text during the same DECIDE pass. If a block's prose cannot determine current behavior, raise it through the correctness-and-assumption gate rather than deleting it.
Stamp the canonical approval marker. Every stories file MUST begin with a **Status:**
line. Once the operator approves the stories, the file carries **Status:** Accepted — this is
the single canonical approval token the downstream gates require. A file still pending review
carries **Status:** DRAFT. This is non-negotiable: the engineer land gate
(landSpec/runAuthoring) rejects stories lacking Status: Accepted, and the daemon backlog
skips a merged spec forever unless its stories declare Status: Accepted (no DRAFT). A
missing status line is treated as not approved — never leave it off.
6. Suggest Next Step
After stories are written, suggest invoking the conflict-check skill to verify no conflicts
with existing stories.
Verification
- [ ] Every story heading carries a machine-parseable id (
## Story <id>: <title>) — an id-less heading silently collapses the file into one block and degrades three gates - [ ] Every requirement in the design doc has at least one story
- [ ] Every story has both happy AND negative paths
- [ ] At least one negative path per acceptance criterion
- [ ] All negative paths are concrete Given/When/Then (not vague)
- [ ] Every story has a "Done When" section with concrete, verifiable output checkboxes
- [ ] Stack-specific negative paths included if tech-context loaded
- [ ] Stories saved to
.docs/stories/<feature-name>.md - [ ] No duplicate stories with existing content
- [ ] Stories file carries the canonical
**Status:** Acceptedmarker on approval (not DRAFT, not missing)
04 同仓库更多 Skills
build-review-dependency-hygiene
Judge whether a feature diff adds unnecessary, insufficiently pinned, or license-incompatible dependencies.
writing-system-tests
Use BEFORE implementing any feature that has stories in .docs/stories/ — generates failing acceptance specs from acceptance criteria as the RED phase of TDD. Generates HTTP/request-level acceptance tests for headless/API projects, end-to-end UI tests for projects with a frontend, using the project's own test framework and directory conventions.
verify-claims
Use only when an active workflow is about to rely on a nontrivial factual claim or assumption for a spec, plan, ADR, finding, or code decision. Do not invoke for casual questions, status reports, restatements, or trivially verifiable mechanics.
tdd
Use when implementing any feature or bugfix. Five-step cycle: RED → DOMAIN → GREEN → DOMAIN → COMMIT. Enforces test-first development with domain integrity review at every phase boundary.
stack-land
Use when an operator needs to land reviewed manual changes on the correct closed child of a stacked feature. Operator-invoked only: inspect ownership, propose the safe child with evidence, and require confirmation before opening the landing.
simplify
Use only at an active pipeline batch boundary after code has changed. Reviews current-batch duplication, complexity, over-engineering, and domain-modelling defects; do not invoke for ordinary refactors, code review, or requests that merely ask for simpler prose or code.