Files
storkit/.living_spec

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:

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
  • 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.

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.
  • 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).
  • Action: When the user accepts:
    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
  • Important: Do NOT mark acceptance criteria as complete before user acceptance. Only mark them complete when the user explicitly accepts the story.

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

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."

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?").
  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".

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 - 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 - 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.