story-kit: merge 164_bug_dev_process_readme_documents_wrong_pipeline_stages
This commit is contained in:
@@ -56,7 +56,8 @@ project_root/
|
||||
│ ├── 2_current/ # Work in progress
|
||||
│ ├── 3_qa/ # QA review
|
||||
│ ├── 4_merge/ # Ready to merge to master
|
||||
│ └── 5_archived/ # Completed work
|
||||
│ ├── 5_done/ # Merged and completed (auto-swept to 6_archived after 4 hours)
|
||||
│ └── 6_archived/ # Long-term archive
|
||||
├── worktrees/ # Agent worktrees (managed by the server)
|
||||
├── specs/ # Minimal guardrails (context + stack)
|
||||
│ ├── 00_CONTEXT.md # High-level goals, domain definition, and glossary
|
||||
@@ -77,7 +78,9 @@ All work items (stories, bugs, spikes) live in the same `work/` pipeline. Items
|
||||
|
||||
Items move through stages by moving the file between directories:
|
||||
|
||||
`1_upcoming` → `2_current` → `3_qa` → `4_merge` → `5_archived`
|
||||
`1_upcoming` → `2_current` → `3_qa` → `4_merge` → `5_done` → `6_archived`
|
||||
|
||||
Items in `5_done` are auto-swept to `6_archived` after 4 hours by the server.
|
||||
|
||||
### Filesystem Watcher
|
||||
|
||||
@@ -119,10 +122,10 @@ When the user asks for a feature, follow this 4-step loop strictly:
|
||||
### Step 3: Verification (Close)
|
||||
* **Action:** For each Acceptance Criterion in the story, write a failing test (red), mark the criterion as tested, make the test pass (green), and refactor if needed. Keep only one failing test at a time.
|
||||
* **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 `work/5_archived/`.
|
||||
* **Move to Archived:** After acceptance, move the story from `work/2_current/` (or `work/4_merge/`) to `work/5_archived/`.
|
||||
* **Action:** Do not accept stories yourself. Ask the user if they accept the story. If they agree, move the story file to `work/5_done/`.
|
||||
* **Move to Done:** After acceptance, move the story from `work/2_current/` (or `work/4_merge/`) to `work/5_done/`.
|
||||
* **Action:** When the user accepts:
|
||||
1. Move the story file to `work/5_archived/`
|
||||
1. Move the story file to `work/5_done/`
|
||||
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
|
||||
@@ -137,7 +140,7 @@ When the user asks for a feature, follow this 4-step loop strictly:
|
||||
* The only files that should exist after story completion:
|
||||
* Updated code in `src/`
|
||||
* Updated guardrails in `specs/` (if needed)
|
||||
* Archived work item in `work/5_archived/`
|
||||
* Archived work item in `work/5_done/` (server auto-sweeps to `work/6_archived/` after 4 hours)
|
||||
|
||||
---
|
||||
|
||||
@@ -163,7 +166,7 @@ Not everything needs to be a full story. Simple bugs can skip the story process:
|
||||
3. **Write a Failing Test:** Before fixing the bug, write a test that reproduces it (red). This proves the bug exists and prevents regression.
|
||||
4. **Fix the Bug:** Make minimal code changes to make the test pass (green).
|
||||
5. **User Testing:** Let the user verify the fix in the worktree before merging. Do not proceed until they confirm.
|
||||
6. **Archive & Merge:** Move the bug file to `work/5_archived/`, squash merge to master, delete the worktree and branch.
|
||||
6. **Archive & Merge:** Move the bug file to `work/5_done/`, squash merge to master, delete the worktree and branch.
|
||||
7. **No Guardrail Update Needed:** Unless the bug reveals a missing constraint
|
||||
|
||||
### Bug vs Story vs Spike
|
||||
@@ -192,7 +195,7 @@ Not everything needs a story or bug fix. Spikes are time-boxed investigations to
|
||||
* **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 the spike file to `work/5_archived/`.
|
||||
4. **Archive:** Move the spike file to `work/5_done/`.
|
||||
|
||||
### Spike Output
|
||||
* Decision and evidence, not production code
|
||||
@@ -218,7 +221,7 @@ If a user hands you this document and says "Apply this process to my project":
|
||||
1. **Check for MCP Tools:** Look for `.mcp.json` in the project root. If it exists, you have programmatic access to workflow tools and agent spawning capabilities.
|
||||
2. **Analyze the Request:** Ask for the high-level goal ("What are we building?") and the tech preferences ("Rust or Python?").
|
||||
3. **Git Check:** Check if the directory is a git repository (`git status`). If not, run `git init`.
|
||||
4. **Scaffold:** Run commands to create the `work/` and `specs/` folders with the 5-stage pipeline (`work/1_upcoming/` through `work/5_archived/`).
|
||||
4. **Scaffold:** Run commands to create the `work/` and `specs/` folders with the 6-stage pipeline (`work/1_upcoming/` through `work/6_archived/`).
|
||||
5. **Draft Context:** Write `specs/00_CONTEXT.md` based on the user's answer.
|
||||
6. **Draft Stack:** Write `specs/tech/STACK.md` based on best practices for that language.
|
||||
7. **Wait:** Ask the user for "Story #1".
|
||||
|
||||
@@ -67,12 +67,10 @@ struct WorktreeListEntry {
|
||||
/// response so the agents panel is not cluttered with old completed items on
|
||||
/// frontend startup.
|
||||
pub fn story_is_archived(project_root: &path::Path, story_id: &str) -> bool {
|
||||
project_root
|
||||
.join(".story_kit")
|
||||
.join("work")
|
||||
.join("5_archived")
|
||||
.join(format!("{story_id}.md"))
|
||||
.exists()
|
||||
let work = project_root.join(".story_kit").join("work");
|
||||
let filename = format!("{story_id}.md");
|
||||
work.join("5_done").join(&filename).exists()
|
||||
|| work.join("6_archived").join(&filename).exists()
|
||||
}
|
||||
|
||||
pub struct AgentsApi {
|
||||
@@ -298,29 +296,39 @@ mod tests {
|
||||
use crate::agents::AgentStatus;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn make_archived_dir(tmp: &TempDir) -> path::PathBuf {
|
||||
fn make_work_dirs(tmp: &TempDir) -> path::PathBuf {
|
||||
let root = tmp.path().to_path_buf();
|
||||
let archived = root
|
||||
.join(".story_kit")
|
||||
.join("work")
|
||||
.join("5_archived");
|
||||
std::fs::create_dir_all(&archived).unwrap();
|
||||
for stage in &["5_done", "6_archived"] {
|
||||
std::fs::create_dir_all(root.join(".story_kit").join("work").join(stage)).unwrap();
|
||||
}
|
||||
root
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn story_is_archived_false_when_file_absent() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let root = make_archived_dir(&tmp);
|
||||
let root = make_work_dirs(&tmp);
|
||||
assert!(!story_is_archived(&root, "79_story_foo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn story_is_archived_true_when_file_present() {
|
||||
fn story_is_archived_true_when_file_in_5_done() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let root = make_archived_dir(&tmp);
|
||||
let root = make_work_dirs(&tmp);
|
||||
std::fs::write(
|
||||
root.join(".story_kit/work/5_archived/79_story_foo.md"),
|
||||
root.join(".story_kit/work/5_done/79_story_foo.md"),
|
||||
"---\nname: test\n---\n",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(story_is_archived(&root, "79_story_foo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn story_is_archived_true_when_file_in_6_archived() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let root = make_work_dirs(&tmp);
|
||||
std::fs::write(
|
||||
root.join(".story_kit/work/6_archived/79_story_foo.md"),
|
||||
"---\nname: test\n---\n",
|
||||
)
|
||||
.unwrap();
|
||||
@@ -330,11 +338,11 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn list_agents_excludes_archived_stories() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let root = make_archived_dir(&tmp);
|
||||
let root = make_work_dirs(&tmp);
|
||||
|
||||
// Place an archived story file
|
||||
// Place an archived story file in 6_archived
|
||||
std::fs::write(
|
||||
root.join(".story_kit/work/5_archived/79_story_archived.md"),
|
||||
root.join(".story_kit/work/6_archived/79_story_archived.md"),
|
||||
"---\nname: archived story\n---\n",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
Reference in New Issue
Block a user