2025-12-24 16:29:33 +00:00
# The Story-Driven Spec Workflow (SDSW)
**Target Audience:** Large Language Models (LLMs) acting as Senior Engineers.
**Goal:** To maintain long-term project coherence, prevent context window exhaustion, and ensure high-quality, testable code generation in large software projects.
---
## 1. The Philosophy
We treat the codebase as the implementation of a * * "Living Specification."**
Instead of ephemeral chat prompts ("Fix this", "Add that"), we work through persistent artifacts.
* **Stories ** define the * Change * .
* **Specs ** define the * Truth * .
* **Code ** defines the * Reality * .
**The Golden Rule:** You are not allowed to write code until the Spec reflects the new reality requested by the Story.
---
## 2. Directory Structure
When initializing a new project under this workflow, create the following structure immediately:
```text
project_root/
.living_spec
|-- README.md # This document
├── stories/ # The "Inbox" of feature requests.
├── specs/ # The "Brain" of the project.
│ ├── README.md # Explains this workflow to future sessions.
│ ├── 00_CONTEXT.md # High-level goals, domain definition, and glossary.
│ ├── tech/ # Implementation details (Stack, Architecture, Constraints).
│ │ └── STACK.md # The "Constitution" (Languages, Libs, Patterns).
│ └── functional/ # Domain logic (Platform-agnostic behavior).
│ ├── 01_CORE.md
│ └── ...
└── src/ # The Code.
```
---
## 3. The Cycle (The "Loop")
When the user asks for a feature, follow this 4-step loop strictly:
### Step 1: The Story (Ingest)
* **User Input: ** "I want the robot to dance."
* **Action: ** Create a file `stories/XX_robot_dance.md` .
* **Content: **
* **User Story: ** "As a user, I want..."
* **Acceptance Criteria: ** Bullet points of observable success.
* **Out of scope: ** Things that are out of scope so that the LLM doesn't go crazy
2026-02-06 16:28:40 +00:00
* **Git: ** Make a local feature branch for the story, named from the story (e.g., `feature/story-33-camera-format-auto-selection` ). You must create and switch to the feature branch before making any edits.
2025-12-24 16:29:33 +00:00
### Step 2: The Spec (Digest)
* **Action: ** Update the files in `specs/` .
* **Logic: **
* Does `specs/functional/LOCOMOTION.md` exist? If no, create it.
* Add the "Dance" state to the state machine definition in the spec.
* Check `specs/tech/STACK.md` : Do we have an approved animation library? If no, propose adding one to the Stack or reject the feature.
* **Output: ** Show the user the diff of the Spec. **Wait for approval. **
### Step 3: The Implementation (Code)
* **Action: ** Write the code to match the * Spec * (not just the Story).
* **Constraint: ** adhere strictly to `specs/tech/STACK.md` (e.g., if it says "No `unwrap()` ", you must not use `unwrap()` ).
### Step 4: Verification (Close)
* **Action: ** Write a test case that maps directly to the Acceptance Criteria in the Story.
2026-02-06 16:28:40 +00:00
* **Action: ** Run compilation and make sure it succeeds without errors. Consult `specs/tech/STACK.md` and run all required linters listed there (treat warnings as errors). Run tests and make sure they all pass before proceeding. Ask questions here if needed.
* **Action: ** Do not accept stories yourself. Ask the user if they accept the story. If they agree, move the story file to `stories/archive/` . Tell the user they should commit (this gives them the chance to exclude files via .gitignore if necessary).
2025-12-25 15:39:22 +00:00
* **Action: ** When the user accepts:
2026-02-06 16:28:40 +00:00
1. Move the story file to `stories/archive/` (e.g., `mv stories/XX_story_name.md stories/archive/` )
2. Commit both changes to the feature branch
3. Perform the squash merge: `git merge --squash feature/story-name`
4. Commit to master with a comprehensive commit message
5. Delete the feature branch: `git branch -D feature/story-name`
2025-12-25 15:39:22 +00:00
* **Important: ** Do NOT mark acceptance criteria as complete before user acceptance. Only mark them complete when the user explicitly accepts the story.
2025-12-24 16:29:33 +00:00
2026-02-06 16:28:40 +00:00
**CRITICAL - NO SUMMARY DOCUMENTS:**
* **NEVER ** create a separate summary document (e.g., `STORY_XX_SUMMARY.md` , `IMPLEMENTATION_NOTES.md` , etc.)
* **NEVER ** write terminal output to a markdown file for "documentation purposes"
* The `specs/` folder IS the documentation. Keep it updated after each story.
* If you find yourself typing `cat << 'EOF' > SUMMARY.md` or similar, **STOP IMMEDIATELY ** .
* The only files that should exist after story completion:
* Updated code in `src/`
* Updated specs in `specs/`
* Archived story in `stories/archive/`
---
## 3.5. Bug Workflow (Simplified Path)
Not everything needs to be a full story. Simple bugs can skip the story process:
### When to Use Bug Workflow
* Defects in existing functionality (not new features)
* State inconsistencies or data corruption
* UI glitches that don't require spec changes
* Performance issues with known fixes
### Bug Process
1. **Document Bug: ** Create `bugs/bug-N-short-description.md` with:
* **Symptom: ** What the user observes
* **Root Cause: ** Technical explanation (if known)
* **Reproduction Steps: ** How to trigger the bug
* **Proposed Fix: ** Brief technical approach
* **Workaround: ** Temporary solution if available
2. **Fix Immediately: ** Make minimal code changes to fix the bug
3. **Archive: ** Move fixed bugs to `bugs/archive/` when complete
4. **No Spec Update Needed: ** Unless the bug reveals a spec deficiency
### Bug vs Story
* **Bug: ** Existing functionality is broken → Fix it
* **Story: ** New functionality is needed → Spec it, then build it
* **Spike: ** Uncertainty/feasibility discovery → Run spike workflow
---
## 3.6. Spike Workflow (Research Path)
Not everything needs a story or bug fix. Spikes are time-boxed investigations to reduce uncertainty.
### When to Use a Spike
* Unclear root cause or feasibility
* Need to compare libraries/encoders/formats
* Need to validate performance constraints
### Spike Process
1. **Document Spike: ** Create `spikes/spike-N-short-description.md` with:
* **Question: ** What you need to answer
* **Hypothesis: ** What you expect to be true
* **Timebox: ** Strict limit for the research
* **Investigation Plan: ** Steps/tools to use
* **Findings: ** Evidence and observations
* **Recommendation: ** Next step (Story, Bug, or No Action)
2. **Execute Research: ** Stay within the timebox. No production code changes.
3. **Escalate if Needed: ** If implementation is required, open a Story or Bug and follow that workflow.
4. **Archive: ** Move completed spikes to `spikes/archive/` .
### Spike Output
* Decision and evidence, not production code
* Specs updated only if the spike changes system truth
2025-12-24 16:29:33 +00:00
---
## 4. Context Reset Protocol
When the LLM context window fills up (or the chat gets slow/confused):
1. **Stop Coding. **
2. **Instruction: ** Tell the user to open a new chat.
3. **Handoff: ** The only context the new LLM needs is in the `specs/` folder.
* * Prompt for New Session: * "I am working on Project X. Read `specs/00_CONTEXT.md` and `specs/tech/STACK.md` . Then look at `stories/` to see what is pending."
2026-02-06 16:28:40 +00:00
2025-12-24 16:29:33 +00:00
---
## 5. Setup Instructions (For the LLM)
If a user hands you this document and says "Apply this process to my project":
1. **Analyze the Request: ** Ask for the high-level goal ("What are we building?") and the tech preferences ("Rust or Python?").
2025-12-24 17:17:35 +00:00
2. **Git Check: ** Check if the directory is a git repository (`git status` ). If not, run `git init` .
3. **Scaffold: ** Run commands to create the `specs/` and `stories/` folders.
4. **Draft Context: ** Write `specs/00_CONTEXT.md` based on the user's answer.
5. **Draft Stack: ** Write `specs/tech/STACK.md` based on best practices for that language.
6. **Wait: ** Ask the user for "Story #1 ".
2025-12-27 16:50:18 +00:00
---
## 6. Code Quality Tools
**MANDATORY:** Before completing Step 4 (Verification) of any story, you MUST run all applicable linters and fix ALL errors and warnings. Zero tolerance for warnings or errors.
### TypeScript/JavaScript: Biome
* **Tool: ** [Biome ](https://biomejs.dev/ ) - Fast formatter and linter
* **Check Command: ** `npx @biomejs/biome check src/`
* **Fix Command: ** `npx @biomejs/biome check --write src/`
* **Unsafe Fixes: ** `npx @biomejs/biome check --write --unsafe src/`
* **Configuration: ** `biome.json` in project root
* **When to Run: **
* After every code change to TypeScript/React files
* Before committing any frontend changes
* During Step 4 (Verification) - must show 0 errors, 0 warnings
**Biome Rules to Follow:**
* No `any` types (use proper TypeScript types or `unknown` )
* No array index as `key` in React (use stable IDs)
* No assignments in expressions (extract to separate statements)
* All buttons must have explicit `type` prop (`button` , `submit` , or `reset` )
* Mouse events must be accompanied by keyboard events for accessibility
* Use template literals instead of string concatenation
* Import types with `import type { }` syntax
* Organize imports automatically
### Rust: Clippy
* **Tool: ** [Clippy ](https://github.com/rust-lang/rust-clippy ) - Rust linter
* **Check Command: ** `cargo clippy --all-targets --all-features`
* **Fix Command: ** `cargo clippy --fix --allow-dirty --allow-staged`
* **When to Run: **
* After every code change to Rust files
* Before committing any backend changes
* During Step 4 (Verification) - must show 0 errors, 0 warnings
**Clippy Rules to Follow:**
* No unused variables (prefix with `_` if intentionally unused)
* No dead code (remove or mark with `#[allow(dead_code)]` if used conditionally)
* Use `?` operator instead of explicit error handling where possible
* Prefer `if let` over `match` for single-pattern matches
* Use meaningful variable names
* Follow Rust idioms and best practices
### Build Verification Checklist
Before asking for user acceptance in Step 4:
- [ ] Run `cargo clippy` (Rust) - 0 errors, 0 warnings
- [ ] Run `cargo check` (Rust) - successful compilation
- [ ] Run `cargo test` (Rust) - all tests pass
- [ ] Run `npx @biomejs/biome check src/` (TypeScript) - 0 errors, 0 warnings
- [ ] Run `npm run build` (TypeScript) - successful build
- [ ] Manually test the feature works as expected
- [ ] All acceptance criteria verified
**Failure to meet these criteria means the story is NOT ready for acceptance.**