- Backend: Added OllamaProvider::chat_stream() with newline-delimited JSON parsing - Backend: Emit chat:token events for each token received from Ollama - Backend: Added futures dependency and stream feature for reqwest - Frontend: Added streamingContent state and chat:token event listener - Frontend: Real-time token display with auto-scroll - Frontend: Markdown and syntax highlighting support for streaming content - Fixed all TypeScript errors (tsc --noEmit) - Fixed all Biome warnings and errors - Fixed all Clippy warnings - Added comprehensive code quality documentation - Added tsc --noEmit to verification checklist Tested and verified: - Tokens stream in real-time - Auto-scroll works during streaming - Tool calls interrupt streaming correctly - Multi-turn conversations work - Smooth performance with no lag
163 lines
7.4 KiB
Markdown
163 lines
7.4 KiB
Markdown
# 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
|
|
* **Git:** The Assistant initiates a new local feature branch (e.g., `feature/story-name`) immediately.
|
|
|
|
### 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. Fix warnings if possible. Run tests and make sure they all pass before proceeding. Ask questions here if needed.
|
|
* **Action:** Ask the user to accept the story. **Wait for user acceptance.**
|
|
* **Action:** When the user accepts:
|
|
1. Mark the acceptance criteria as complete (change `[ ]` to `[x]`)
|
|
2. Move the story file to `stories/archive/` (e.g., `mv stories/XX_story_name.md stories/archive/`)
|
|
3. Commit both changes to the feature branch
|
|
4. Perform the squash merge: `git merge --squash feature/story-name`
|
|
5. Commit to master with a comprehensive commit message
|
|
6. 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.
|
|
|
|
|
|
---
|
|
|
|
## 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](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.**
|