story-kit: start spike 61 - Filesystem Watcher Architecture

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dave
2026-02-20 17:55:28 +00:00
parent 99613d095e
commit a57ac257a2

View File

@@ -0,0 +1,44 @@
---
name: Filesystem Watcher Architecture
test_plan: pending
---
# Spike 61: Filesystem Watcher Architecture
## Question
Can we replace all the individual mutation handlers (`move_story_to_current`, `move_story_to_archived`, `close_bug_to_archive`, `move_story_to_merge`, etc.) with a single filesystem watcher on `work/` that auto-commits any change and notifies the frontend?
## Motivation
The server is a file mover that commits. Every mutation handler does the same thing: `fs::rename` + `git_stage_and_commit` with a deterministic message. There are hundreds of lines of near-identical code. A watcher would:
- **Replace N mutation functions with 1 watcher** — any file appearing/disappearing in `work/*/` gets auto-committed
- **MCP tools become one-liners** — just `fs::rename(from, to)`, the watcher handles commit + notify
- **IDE drag-and-drop works** — drag a story from `1_upcoming/` to `2_current/` in Zed, watcher commits and frontend updates
- **Manual edits work** — edit a story file, watcher commits it
- **Frontend notifications for free** — watcher broadcasts over WebSocket, no per-handler notification code
## What to Explore
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}"
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
7. **Startup** — does the watcher detect drift on startup (files moved while server was down)?
## Success Criteria
- [ ] Prototype watcher using `notify` crate that detects file changes in `work/`
- [ ] Watcher debounces and auto-commits with deterministic messages
- [ ] Watcher broadcasts a WebSocket notification after commit
- [ ] At least one MCP tool (e.g. `create_story`) simplified to just write the file, letting the watcher commit
- [ ] Dragging a file in the IDE triggers commit + frontend update
- [ ] Document: what broke, what was hard, what's the migration path
## Out of Scope
- Full migration of all handlers (that's a follow-up story if the spike succeeds)
- Frontend panel implementation (story 55 handles that)