story-kit: accept 49_story_deterministic_bug_lifecycle_management

This commit is contained in:
Dave
2026-03-20 12:02:03 +00:00
parent 9581e5d51a
commit d3f462e518
27 changed files with 58 additions and 61 deletions

View File

@@ -10,7 +10,7 @@ The `prompt_permission` MCP tool returns plain text ("Permission granted for '..
## How to Reproduce
1. Start the story-kit server and open the web UI
1. Start the storkit server and open the web UI
2. Chat with the claude-code-pty model
3. Ask it to do something that requires a tool NOT in `.claude/settings.json` allow list (e.g. `wc -l /etc/hosts`, or WebFetch to a non-allowed domain)
4. The permission dialog appears — click Approve

View File

@@ -6,7 +6,7 @@ name: "Retry limit for mergemaster and pipeline restarts"
## User Story
As a developer using story-kit, I want pipeline auto-restarts to have a configurable retry limit so that failing agents don't loop infinitely consuming CPU and API credits.
As a developer using storkit, I want pipeline auto-restarts to have a configurable retry limit so that failing agents don't loop infinitely consuming CPU and API credits.
## Acceptance Criteria

View File

@@ -23,7 +23,7 @@ The watcher should periodically check `5_done/` and move items older than 4 hour
- All MCP tools and pipeline logic that reference `5_archived` need updating to use `5_done`
- Frontend pipeline display if it shows archived/done items
- `.story_kit/README.md`: update pipeline stage documentation
- Story 116's init scaffolding: `story-kit init` must create `5_done/` and `6_archived/` directories
- Story 116's init scaffolding: `storkit init` must create `5_done/` and `6_archived/` directories
- Any templates or scaffold code that creates the `.story_kit/work/` directory structure
## Acceptance Criteria
@@ -35,7 +35,7 @@ The watcher should periodically check `5_done/` and move items older than 4 hour
- [ ] Existing items in old `5_archived/` are migrated to `6_archived/`
- [ ] Frontend pipeline display updated if applicable
- [ ] `.story_kit/README.md` updated to reflect the new pipeline stages
- [ ] `story-kit init` scaffolding creates `5_done/` and `6_archived/` (coordinate with story 116)
- [ ] `storkit init` scaffolding creates `5_done/` and `6_archived/` (coordinate with story 116)
## Out of Scope

View File

@@ -17,21 +17,21 @@ const TEMPLATE_MARKER_CONTEXT: &str = "Agentic AI Code Assistant";
const TEMPLATE_MARKER_STACK: &str = "Agentic Code Assistant";
```
These markers are phrases that appear in the scaffold templates (`server/src/io/fs.rs` lines 233 and 269). The detection logic (`is_template_or_missing` at line 59) checks if the file *contains* the marker string. But these phrases are generic enough that real project content can contain them too — especially when the project being managed IS an agentic code assistant (i.e. story-kit managing itself).
These markers are phrases that appear in the scaffold templates (`server/src/io/fs.rs` lines 233 and 269). The detection logic (`is_template_or_missing` at line 59) checks if the file *contains* the marker string. But these phrases are generic enough that real project content can contain them too — especially when the project being managed IS an agentic code assistant (i.e. storkit managing itself).
## The Fix
Replace the content-based marker detection with a dedicated sentinel comment that only exists in untouched scaffold templates. The sentinel should be something that would never appear in real content, like an HTML comment:
```
<!-- story-kit:scaffold-template -->
<!-- storkit:scaffold-template -->
```
Changes needed:
1. **`server/src/io/onboarding.rs`**: Replace `TEMPLATE_MARKER_CONTEXT` and `TEMPLATE_MARKER_STACK` with a single `TEMPLATE_SENTINEL` constant set to `"<!-- story-kit:scaffold-template -->"`. Update `check_onboarding_status` to use it for both context and stack checks.
1. **`server/src/io/onboarding.rs`**: Replace `TEMPLATE_MARKER_CONTEXT` and `TEMPLATE_MARKER_STACK` with a single `TEMPLATE_SENTINEL` constant set to `"<!-- storkit:scaffold-template -->"`. Update `check_onboarding_status` to use it for both context and stack checks.
2. **`server/src/io/fs.rs`**: Add `<!-- story-kit:scaffold-template -->` as the first line of both `STORY_KIT_CONTEXT` and `STORY_KIT_STACK` template constants (lines 233 and 269).
2. **`server/src/io/fs.rs`**: Add `<!-- storkit:scaffold-template -->` as the first line of both `STORY_KIT_CONTEXT` and `STORY_KIT_STACK` template constants (lines 233 and 269).
3. **`server/src/io/onboarding.rs` tests**: Update the test `needs_onboarding_true_when_specs_contain_scaffold_markers` to use the sentinel instead of the old marker phrases. Also add a test confirming that content containing "Agentic AI Code Assistant" WITHOUT the sentinel does NOT trigger onboarding.
@@ -42,7 +42,7 @@ Changes needed:
## Acceptance Criteria
- [ ] Scaffold templates contain the sentinel `<!-- story-kit:scaffold-template -->` as first line
- [ ] Scaffold templates contain the sentinel `<!-- storkit:scaffold-template -->` as first line
- [ ] `needs_onboarding()` returns false for projects whose specs contain "Agentic AI Code Assistant" but NOT the sentinel
- [ ] `needs_onboarding()` returns true for untouched scaffold content (which contains the sentinel)
- [ ] Existing tests updated and passing

View File

@@ -21,7 +21,7 @@ As a project owner, I want agent role descriptions to explicitly require test-fi
## Test Results
<!-- story-kit-test-results: {"unit":[{"name":"Coder roles mention test-first and record_tests","status":"pass","details":"coder-1, coder-2, and coder-opus role fields and prompts updated to require test-first development and call record_tests MCP tool"},{"name":"QA roles verify record_tests was called","status":"pass","details":"qa and qa-2 role fields, prompts, and system_prompts updated to explicitly verify record_tests was called and flag missing results as FAIL"},{"name":"Mergemaster role checks ensure_acceptance before merging","status":"pass","details":"mergemaster role field, prompt workflow step 1, and system_prompt updated to call ensure_acceptance before triggering merge_agent_work"}],"integration":[]} -->
<!-- storkit-test-results: {"unit":[{"name":"Coder roles mention test-first and record_tests","status":"pass","details":"coder-1, coder-2, and coder-opus role fields and prompts updated to require test-first development and call record_tests MCP tool"},{"name":"QA roles verify record_tests was called","status":"pass","details":"qa and qa-2 role fields, prompts, and system_prompts updated to explicitly verify record_tests was called and flag missing results as FAIL"},{"name":"Mergemaster role checks ensure_acceptance before merging","status":"pass","details":"mergemaster role field, prompt workflow step 1, and system_prompt updated to call ensure_acceptance before triggering merge_agent_work"}],"integration":[]} -->
### Unit Tests (3 passed, 0 failed)

View File

@@ -22,7 +22,7 @@ As a project owner, I want test results written to the story markdown file when
## Test Results
<!-- story-kit-test-results: {"unit":[{"name":"test_write_persists","status":"pass","details":null}],"integration":[{"name":"test_roundtrip","status":"pass","details":null}]} -->
<!-- storkit-test-results: {"unit":[{"name":"test_write_persists","status":"pass","details":null}],"integration":[{"name":"test_roundtrip","status":"pass","details":null}]} -->
### Unit Tests (1 passed, 0 failed)
@@ -31,4 +31,3 @@ As a project owner, I want test results written to the story markdown file when
### Integration Tests (1 passed, 0 failed)
- ✅ test_roundtrip

View File

@@ -26,4 +26,4 @@ An MCP tool (e.g. add_criterion or edit_story) that can add/remove/update accept
- [ ] An MCP tool exists to add acceptance criteria to a story file
- [ ] An MCP tool exists to update the story description or user story text
- [ ] These tools auto-commit changes to the story file like other story-kit MCP tools do
- [ ] These tools auto-commit changes to the story file like other storkit MCP tools do

View File

@@ -13,7 +13,7 @@ As a Matrix room participant, I want the bot to only respond when I address it w
- [ ] Bot ignores messages that don't mention @timmy or the bot's Matrix user ID
- [ ] Bot responds normally when mentioned with @timmy at the start or anywhere in the message
- [ ] Bot still processes replies to its own messages (threaded replies)
- [ ] Existing command handling (story-kit MCP tools, etc.) still works when the bot is addressed
- [ ] Existing command handling (storkit MCP tools, etc.) still works when the bot is addressed
## Out of Scope

View File

@@ -14,7 +14,7 @@ The new merge-queue worktree approach (introduced ~24 hours ago) has a race cond
1. `run_squash_merge()` creates a `merge-queue/{story_id}` branch at master's current HEAD
2. It creates a temporary worktree, runs `git merge --squash`, commits, and runs quality gates — all in the merge-queue worktree
3. Meanwhile, the **filesystem watcher auto-commits pipeline file moves** to master (e.g. "story-kit: queue X for merge", "story-kit: done Y")
3. Meanwhile, the **filesystem watcher auto-commits pipeline file moves** to master (e.g. "storkit: queue X for merge", "storkit: done Y")
4. By the time step 7 tries `git merge --ff-only merge-queue/{story_id}` on master, master has diverged and the fast-forward fails
5. `run_squash_merge()` returns `success: false` (correctly) but `gates_passed: true` (misleading)
6. The `merge_agent_work` caller correctly reports failure — but the mergemaster is a Claude Code agent, not the Rust pipeline. The agent sees the failure, gives up on the squash merge, and instead manually moves the story file to done without the code
@@ -39,7 +39,7 @@ The stale `.story_kit/merge_workspace` directory from failed merges blocks subse
## Actual Result
Stories are moved to 5_done with pipeline commit messages like "story-kit: done ..." but the feature branch code is never squash-merged onto master. Feature branches retain unmerged commits.
Stories are moved to 5_done with pipeline commit messages like "storkit: done ..." but the feature branch code is never squash-merged onto master. Feature branches retain unmerged commits.
## Expected Result

View File

@@ -6,24 +6,24 @@ name: "Project scaffold does not write .mcp.json to project root"
## Description
When a new project is opened/scaffolded, `.mcp.json` is not written to the project root. The `write_mcp_json()` function (worktree.rs:6) is only called during worktree creation, not during `scaffold_story_kit()` (io/fs.rs:464) or `open_project()` (io/fs.rs:503). This means claude-pty spawned with `--permission-prompt-tool mcp__story-kit__prompt_permission` immediately fails because the MCP tool isn't available.
When a new project is opened/scaffolded, `.mcp.json` is not written to the project root. The `write_mcp_json()` function (worktree.rs:6) is only called during worktree creation, not during `scaffold_story_kit()` (io/fs.rs:464) or `open_project()` (io/fs.rs:503). This means claude-pty spawned with `--permission-prompt-tool mcp__storkit__prompt_permission` immediately fails because the MCP tool isn't available.
Additionally, there is no way for the user to trigger scaffolding from the CLI — `find_story_kit_root()` in main.rs falls through without scaffolding if `.story_kit/` doesn't exist yet, so the only path is via the UI file chooser.
## How to Reproduce
1. Create an empty directory or navigate to a project without `.story_kit/`
2. Run `story-kit`
2. Run `storkit`
3. Open the project via the UI file chooser
4. Try to chat using the claude-code provider
## Actual Result
Claude Code exits immediately with: `Error: MCP tool mcp__story-kit__prompt_permission (passed via --permission-prompt-tool) not found. Available MCP tools: none`
Claude Code exits immediately with: `Error: MCP tool mcp__storkit__prompt_permission (passed via --permission-prompt-tool) not found. Available MCP tools: none`
## Expected Result
`.mcp.json` is written to the project root during scaffolding/open, so claude-code can connect to the story-kit MCP server.
`.mcp.json` is written to the project root during scaffolding/open, so claude-code can connect to the storkit MCP server.
## Acceptance Criteria

View File

@@ -6,13 +6,13 @@ name: "Accept optional positional path argument on startup"
## User Story
As a user, I want to run `story-kit .` or `story-kit /path/to/project` to start the server with that directory as the project, so that I don't have to use the UI file chooser.
As a user, I want to run `storkit .` or `storkit /path/to/project` to start the server with that directory as the project, so that I don't have to use the UI file chooser.
## Acceptance Criteria
- [ ] Running `story-kit` with no args behaves as today (auto-detect from cwd)
- [ ] Running `story-kit .` opens the current directory as the project
- [ ] Running `story-kit /some/path` opens that path as the project
- [ ] Running `storkit` with no args behaves as today (auto-detect from cwd)
- [ ] Running `storkit .` opens the current directory as the project
- [ ] Running `storkit /some/path` opens that path as the project
- [ ] If the path has no .story_kit/, it is scaffolded automatically
- [ ] Invalid paths produce a clear error message

View File

@@ -6,7 +6,7 @@ name: "Skip selection screen when CLI path argument provided"
## User Story
As a user, I want the frontend to go straight to the project workspace when I start the server with an explicit path argument (e.g. `story-kit .`), so that I don't have to click through the selection screen for a project the server already opened.
As a user, I want the frontend to go straight to the project workspace when I start the server with an explicit path argument (e.g. `storkit .`), so that I don't have to click through the selection screen for a project the server already opened.
## Acceptance Criteria

View File

@@ -14,7 +14,7 @@ As a developer setting up a new project with Story Kit, I want the scaffold to g
- [ ] CLAUDE.md includes a directive to read .story_kit/README.md for the dev process
- [ ] Scaffold does not overwrite an existing CLAUDE.md (consistent with other scaffold files)
- [ ] Onboarding status does not check CLAUDE.md (it is not a required onboarding step)
- [ ] CLAUDE.md content matches the story-kit-app's own CLAUDE.md (command chaining rule + read .story_kit/README.md directive), prefixed with the scaffold sentinel
- [ ] CLAUDE.md content matches the storkit-app's own CLAUDE.md (command chaining rule + read .story_kit/README.md directive), prefixed with the scaffold sentinel
## Out of Scope

View File

@@ -15,7 +15,7 @@ As a user interacting with agents via the web UI, I want an "Always Allow" optio
- [ ] After Always Allow, Claude Code's built-in permission system handles future checks without calling the prompt tool
- [ ] Edit and Write rules use the tool name (e.g. Edit, Write)
- [ ] Bash rules use the command prefix pattern (e.g. Bash(git *))
- [ ] MCP tool rules use the tool name pattern (e.g. mcp__story-kit__create_story)
- [ ] MCP tool rules use the tool name pattern (e.g. mcp__storkit__create_story)
- [ ] Existing rules in settings.json are not duplicated
## Out of Scope

View File

@@ -1,6 +1,5 @@
---
name: "Show agent logs for a story in expanded work item"
merge_failure: "Merge workspace `.story_kit/merge_workspace` is still occupied by story 236's merge branch (merge-queue/236_story_show_test_results_for_a_story_in_expanded_work_item). The merge pipeline cannot create a new worktree while the existing one is present. To unblock: either wait for story 236's merge to complete, or manually clean up with `git worktree remove .story_kit/merge_workspace` and `git branch -D merge-queue/236_story_show_test_results_for_a_story_in_expanded_work_item`, then re-trigger the merge for story 235."
---
# Story 235: Show agent logs for a story in expanded work item
@@ -21,7 +20,7 @@ As a user, I want to see agent logs for a story inside its expanded view, so tha
## Test Results
<!-- story-kit-test-results: {"unit":[{"name":"shows placeholder when no agent is assigned to the story","status":"pass","details":null},{"name":"shows agent name and running status when agent is running","status":"pass","details":null},{"name":"shows log output when agent emits output events","status":"pass","details":null},{"name":"appends multiple output events to the log","status":"pass","details":null},{"name":"updates status to completed after done event","status":"pass","details":null},{"name":"shows failed status after error event","status":"pass","details":null},{"name":"shows completed agent status without subscribing to stream","status":"pass","details":null},{"name":"shows failed agent status for a failed agent without subscribing to stream","status":"pass","details":null},{"name":"shows agent logs section (not placeholder) when agent is assigned","status":"pass","details":null}],"integration":[]} -->
<!-- storkit-test-results: {"unit":[{"name":"shows placeholder when no agent is assigned to the story","status":"pass","details":null},{"name":"shows agent name and running status when agent is running","status":"pass","details":null},{"name":"shows log output when agent emits output events","status":"pass","details":null},{"name":"appends multiple output events to the log","status":"pass","details":null},{"name":"updates status to completed after done event","status":"pass","details":null},{"name":"shows failed status after error event","status":"pass","details":null},{"name":"shows completed agent status without subscribing to stream","status":"pass","details":null},{"name":"shows failed agent status for a failed agent without subscribing to stream","status":"pass","details":null},{"name":"shows agent logs section (not placeholder) when agent is assigned","status":"pass","details":null}],"integration":[]} -->
### Unit Tests (9 passed, 0 failed)

View File

@@ -1,6 +1,5 @@
---
name: "Show test results for a story in expanded work item"
merge_failure: "merge_agent_work tool returned empty output on 2 attempts. The tool was called successfully (confirmed via MERGE-DEBUG logs) but produced no result - no success/failure status, no gate output. Possible causes: (1) dirty working tree on master (unstaged changes to .claude/settings.json and .mcp.json), (2) internal tool error being swallowed silently. The feature branch has 2 commits ready to merge (ae62aab, 8d5b81e). Story is still in 4_merge/. Human investigation needed."
---
# Story 236: Show test results for a story in expanded work item
@@ -21,7 +20,7 @@ As a user, I want to see test results for a story inside its expanded view, so t
## Test Results
<!-- story-kit-test-results: {"unit":[{"name":"my_unit_test","status":"pass","details":null}],"integration":[{"name":"my_int_test","status":"fail","details":"assertion failed"}]} -->
<!-- storkit-test-results: {"unit":[{"name":"my_unit_test","status":"pass","details":null}],"integration":[{"name":"my_int_test","status":"fail","details":"assertion failed"}]} -->
### Unit Tests (1 passed, 0 failed)

View File

@@ -22,7 +22,7 @@ As a Matrix user messaging the bot, I want the bot to correctly recognize my cro
## Test Results
<!-- story-kit-test-results: {"unit":[{"name":"sender_with_cross_signing_identity_is_accepted","status":"pass","details":"Verifies get_user_identity Some(_) → accepted"},{"name":"sender_without_cross_signing_identity_is_rejected","status":"pass","details":"Verifies get_user_identity None → rejected"}],"integration":[]} -->
<!-- storkit-test-results: {"unit":[{"name":"sender_with_cross_signing_identity_is_accepted","status":"pass","details":"Verifies get_user_identity Some(_) → accepted"},{"name":"sender_without_cross_signing_identity_is_rejected","status":"pass","details":"Verifies get_user_identity None → rejected"}],"integration":[]} -->
### Unit Tests (2 passed, 0 failed)

View File

@@ -1,17 +1,17 @@
---
name: "Move story-kit ignores into .story_kit/.gitignore"
name: "Move storkit ignores into .story_kit/.gitignore"
---
# Story 259: Move story-kit ignores into .story_kit/.gitignore
# Story 259: Move storkit ignores into .story_kit/.gitignore
## User Story
As a developer using story-kit, I want story-kit-specific gitignore patterns to live inside .story_kit/.gitignore, so that the host project's root .gitignore stays clean and story-kit concerns are self-contained.
As a developer using storkit, I want storkit-specific gitignore patterns to live inside .story_kit/.gitignore, so that the host project's root .gitignore stays clean and storkit concerns are self-contained.
## Acceptance Criteria
- [ ] A .gitignore file exists at .story_kit/.gitignore containing all story-kit-specific ignore patterns
- [ ] The root .gitignore no longer contains story-kit-specific ignore patterns
- [ ] A .gitignore file exists at .story_kit/.gitignore containing all storkit-specific ignore patterns
- [ ] The root .gitignore no longer contains storkit-specific ignore patterns
- [ ] The deterministic project scaffold process creates .story_kit/.gitignore when initialising a new project
- [ ] Existing repos continue to work correctly after the change (no previously-ignored files become tracked)

View File

@@ -1,26 +1,26 @@
---
name: "Rename binary and all references from story-kit to storkit"
name: "Rename binary and all references from storkit to storkit"
agent: coder-opus
---
# Story 315: Rename binary and all references from story-kit to storkit
# Story 315: Rename binary and all references from storkit to storkit
## User Story
As a project owner, I want the binary, crate name, package name, and all code/config references renamed from story-kit/story_kit to storkit, so that the branding is consistent throughout the project.
As a project owner, I want the binary, crate name, package name, and all code/config references renamed from storkit/story_kit to storkit, so that the branding is consistent throughout the project.
## Acceptance Criteria
- [ ] Binary name changed from story-kit to storkit in Cargo.toml
- [ ] Crate/package name changed from story-kit/story_kit to storkit throughout Cargo.toml files
- [ ] Binary name changed from storkit to storkit in Cargo.toml
- [ ] Crate/package name changed from storkit/story_kit to storkit throughout Cargo.toml files
- [ ] All code references to story_kit (module names, paths, env vars like CARGO_MANIFEST_DIR) updated
- [ ] Config directory .story_kit renamed to .storkit
- [ ] All server code references to .story_kit paths updated
- [ ] Git commit messages prefix changed from 'story-kit:' to 'storkit:'
- [ ] Git commit messages prefix changed from 'storkit:' to 'storkit:'
- [ ] Frontend references updated (if any)
- [ ] script/* files updated to reference the new binary name
- [ ] Release script updated for new binary name
- [ ] MCP server name updated from story-kit to storkit
- [ ] MCP server name updated from storkit to storkit
- [ ] CLAUDE.md and README references updated
## Out of Scope

View File

@@ -15,7 +15,7 @@ As a developer running autonomous agents, I want all story file mutations to hap
- [ ] `start_agent` auto-commits the move from upcoming/ to current/ on master
- [ ] New MCP tool `check_criterion(story_id, criterion_index)` checks off an acceptance criterion and auto-commits to master
- [ ] New MCP tool `set_test_plan(story_id, status)` updates the test_plan front matter field and auto-commits to master
- [ ] All auto-commits use deterministic commit messages (e.g. "story-kit: accept story 42")
- [ ] All auto-commits use deterministic commit messages (e.g. "storkit: accept story 42")
- [ ] Agents never need to edit story markdown files directly — all mutations go through server tools
## Out of Scope

View File

@@ -15,7 +15,7 @@ As a developer running autonomous agents, I want all bug file mutations to happe
- [ ] New MCP tool `list_bugs()` returns all open bugs (files in `.story_kit/bugs/` excluding `archive/`)
- [ ] New MCP tool `close_bug(bug_id)` moves a bug from `.story_kit/bugs/` to `.story_kit/bugs/archive/` and auto-commits to master
- [ ] `start_agent` supports bug IDs (e.g. `bug-5-description`) — no move needed since bugs don't have upcoming/current
- [ ] All auto-commits use deterministic commit messages (e.g. "story-kit: create bug bug-6-fix-foo", "story-kit: close bug bug-5")
- [ ] All auto-commits use deterministic commit messages (e.g. "storkit: create bug bug-6-fix-foo", "storkit: close bug bug-5")
- [ ] Agents never need to edit bug markdown files directly — all mutations go through server tools
## Out of Scope

View File

@@ -22,7 +22,7 @@ The server is a file mover that commits. Every mutation handler does the same th
1. **`notify` crate** — does it reliably detect renames/moves across subdirectories on macOS and Linux? What events fire for `fs::rename`?
2. **Debouncing** — git operations touch multiple files. What's the right debounce window? Can we batch changes into a single commit?
3. **Deterministic commit messages** — can the watcher infer intent from the move? e.g., file appears in `2_current/` → "story-kit: start {story_id}", file appears in `5_archived/` → "story-kit: accept {story_id}"
3. **Deterministic commit messages** — can the watcher infer intent from the move? e.g., file appears in `2_current/` → "storkit: start {story_id}", file appears in `5_archived/` → "storkit: accept {story_id}"
4. **Race conditions** — what if the watcher fires while a git commit is in progress? Need a mutex or queue?
5. **What stays in mutation handlers** — do the MCP tools still need validation (e.g., "can't move to 2_current if not in 1_upcoming")? Or is the filesystem the only source of truth?
6. **Worktree interaction** — worktrees share `.git/`, so commits from the watcher in the main repo don't conflict with worktree work
@@ -50,7 +50,7 @@ The server is a file mover that commits. Every mutation handler does the same th
- **WebSocket integration** (`server/src/http/ws.rs`): Each WebSocket client subscribes to a `broadcast::Sender<WatcherEvent>`. When the watcher flushes a batch, it broadcasts a `WatcherEvent`; the WS handler converts it to `WorkItemChanged` and pushes it to the client. Frontend gets live updates with no polling.
- **`create_story` simplified** (`server/src/http/mcp.rs`): The MCP tool now writes the file and returns — `commit = false`. The watcher picks up the new file in `1_upcoming/` within 300 ms and auto-commits `"story-kit: create {story_id}"`.
- **`create_story` simplified** (`server/src/http/mcp.rs`): The MCP tool now writes the file and returns — `commit = false`. The watcher picks up the new file in `1_upcoming/` within 300 ms and auto-commits `"storkit: create {story_id}"`.
### Questions Answered
@@ -58,7 +58,7 @@ The server is a file mover that commits. Every mutation handler does the same th
2. **Debouncing**: 300 ms works well in practice. `fs::rename` is atomic and fires a single event. File writes (e.g. editing a story) may fire multiple events; 300 ms collapses them into one commit. Longer windows (500 ms+) could be used if git is slow.
3. **Deterministic commit messages**: Yes — directory name → action mapping is clean. Stage `1_upcoming``"story-kit: create {item_id}"`, `2_current``"story-kit: start {item_id}"`, `3_qa``"story-kit: queue {item_id} for QA"`, `4_merge``"story-kit: queue {item_id} for merge"`, `5_archived``"story-kit: accept {item_id}"`.
3. **Deterministic commit messages**: Yes — directory name → action mapping is clean. Stage `1_upcoming``"storkit: create {item_id}"`, `2_current``"storkit: start {item_id}"`, `3_qa``"storkit: queue {item_id} for QA"`, `4_merge``"storkit: queue {item_id} for merge"`, `5_archived``"storkit: accept {item_id}"`.
4. **Race conditions**: The watcher uses synchronous `git` subprocess calls inside the debounce flush. Since we're on a dedicated thread with no parallelism, there's no concurrent commit risk within the watcher. If a mutation handler commits first, `git commit` exits with "nothing to commit" and the watcher skips gracefully while still broadcasting the event.

View File

@@ -15,7 +15,7 @@ As a Story Kit user, I want every project initialised by Story Kit to have a scr
- [ ] The Rust server can invoke script/test as the canonical way to run all tests for any project
- [ ] Agents use script/test instead of guessing test commands — they only need to check output if exit code is non-zero, saving LLM tokens
- [ ] script/test exits 0 on success, non-zero on failure — agents treat it as a single pass/fail gate without parsing output on success
- [ ] For this project (story-kit-app), script/test runs cargo test, pnpm test, and pnpm test:e2e
- [ ] For this project (storkit-app), script/test runs cargo test, pnpm test, and pnpm test:e2e
## Out of Scope

View File

@@ -6,7 +6,7 @@ name: "Server-owned agent completion: remove report_completion dependency"
## User Story
As a developer using story-kit, I want the server to automatically run acceptance
As a developer using storkit, I want the server to automatically run acceptance
gates and advance the pipeline when an agent process exits, so that the pipeline
does not stall when an agent forgets or fails to call `report_completion`.

View File

@@ -10,7 +10,7 @@ GET /api/health returns 404 not found. The server should have a health check end
## How to Reproduce
1. Start the story-kit server
1. Start the storkit server
2. curl http://localhost:3001/api/health
3. Observe 404 not found response

View File

@@ -20,7 +20,7 @@ The correct mechanism for non-interactive permission handling is the `--permissi
## How to Reproduce
1. Start the story-kit server
1. Start the storkit server
2. Open the web UI and select claude-code-pty as the model
3. Send a message that triggers a tool requiring permission (e.g. "search the web for something")
4. Observe that no permission dialog appears — the tool either auto-approves or the denial appears as text in the tool drawer
@@ -54,7 +54,7 @@ A full-screen permission dialog appears showing the tool name and input, with Ap
- On receiving `WsRequest::PermissionResponse` from the client, send the decision back through the oneshot sender
### 5. Update Claude Code spawning (`server/src/llm/providers/claude_code.rs`)
- Add `--permission-prompt-tool mcp__story-kit__prompt_permission` to the CLI args
- Add `--permission-prompt-tool mcp__storkit__prompt_permission` to the CLI args
- Remove `PermissionReqMsg` struct and `permission_tx` parameter (no longer needed — permissions flow through MCP, not PTY)
- Clean up the triple-duplicate `permission_request` match arms (dead code from story 80 merge)

View File

@@ -13,11 +13,11 @@ Determine how to stop the filesystem watcher from auto-committing every pipeline
## Context
The watcher in `server/src/io/watcher.rs` currently auto-commits every file change in `.story_kit/work/`. A single story run generates 5+ commits just from pipeline moves:
- `story-kit: create 42_story_foo`
- `story-kit: start 42_story_foo`
- `story-kit: queue 42_story_foo for QA`
- `story-kit: queue 42_story_foo for merge`
- `story-kit: accept 42_story_foo`
- `storkit: create 42_story_foo`
- `storkit: start 42_story_foo`
- `storkit: queue 42_story_foo for QA`
- `storkit: queue 42_story_foo for merge`
- `storkit: accept 42_story_foo`
Since story runs complete relatively quickly, the intermediate state (current/qa/merge) is transient and doesn't need to be committed. Only creation and archival are meaningful checkpoints.
@@ -105,8 +105,8 @@ Prototype implemented: added `COMMIT_WORTHY_STAGES` constant and `should_commit_
- All 872 tests pass, clippy clean
A full story run will now produce only 2 pipeline commits instead of 5+:
- `story-kit: create 42_story_foo` (creation in `1_upcoming`)
- `story-kit: accept 42_story_foo` (archival in `6_archived`)
- `storkit: create 42_story_foo` (creation in `1_upcoming`)
- `storkit: accept 42_story_foo` (archival in `6_archived`)
The intermediate moves (`start`, `queue for QA`, `queue for merge`, `done`) are still broadcast to WebSocket clients for real-time frontend updates, but no longer clutter git history.