Manual squash-merge of feature/story-478_… into master after the in-pipeline
mergemaster runs failed silently. The 478 agent did substantial real work
across multiple respawn cycles before being interrupted; commits on the
feature branch were intact and verified high-quality but never merged via
the normal pipeline path due to compounding bugs:
- The first mergemaster attempt ran ($0.82 in tokens) and exited "Done"
cleanly but didn't push anything to master — likely the worktree was
briefly on master rather than the feature branch when the merge_agent_work
MCP tool ran, so it found nothing to merge.
- Subsequent timer fires defaulted to spawning coders instead of resuming
mergemaster, burning more tokens for no progress.
- Bug 510 (split-brain shadows yanking done stories back to current) and
bug 501 (timers don't cancel on stop/completion) compounded the cost.
What this commit lands:
- server/src/crdt_sync.rs (new, ~518 lines): GET /crdt-sync WebSocket
handler that subscribes to locally-applied SignedOps and streams them as
binary frames. Per-peer bounded queue (256 ops) drops slow peers.
- server/src/crdt_state.rs: new public functions subscribe_ops(),
all_ops_json(), apply_remote_op() backing the sync handler. Adds the
CRDT_OP_TX broadcast channel (capacity 1024).
- server/src/main.rs: wires up the sync subsystem at startup.
- server/src/http/mod.rs: registers the new endpoint.
- server/src/config.rs: adds optional rendezvous field for outbound peers.
- server/src/worktree.rs: minor changes from the original branch.
- server/Cargo.toml: cfg lint suppression for CrdtNode derive.
- crates/bft-json-crdt/src/debug.rs: fix unused-variable warnings.
Resolved a trivial test-mod merge conflict in crdt_state.rs (both 478 and
503 added new tests at the end of the test module — kept both sets).
Note: this is the squash of the original 478 work that the user explicitly
authorized landing. The earlier rogue commit ac9f3ecf — which added a
DIFFERENT, broken implementation of the same feature directly to master
under the user's identity without consent — was reverted earlier in this
session. The forensic tags rogue-commit-2026-04-09-ac9f3ecf and
pre-502-reset-2026-04-09 still exist for incident audit.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rename all references from storkit to huskies across the codebase:
- .storkit/ directory → .huskies/
- Binary name, Cargo package name, Docker image references
- Server code, frontend code, config files, scripts
- Fix script/test to build frontend before cargo clippy/test
so merge worktrees have frontend/dist available for RustEmbed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add three HTTP endpoints for OAuth login without terminal access:
- GET /oauth/authorize — generates PKCE params, redirects to
claude.com/cai/oauth/authorize with code=true and full scopes
- GET /callback — exchanges auth code for tokens via JSON POST to
platform.claude.com/v1/oauth/token, writes ~/.claude/.credentials.json
- GET /oauth/status — returns current credential state as JSON
Uses SHA-256 (sha2 crate) for PKCE code challenge. The authorize URL
targets claude.com/cai/ (not platform.claude.com) which is required
for Max/Pro subscriptions to grant user:inference scope.
Users visit http://localhost:3001/oauth/authorize in their browser
to authenticate. Matrix/WhatsApp can send this link when auth fails.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Commit e4227cf (a story creation auto-commit) erroneously deleted 175
files from master's tree, likely due to a race condition between
concurrent git operations. This commit re-adds all files from the
working directory.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Renames the config directory and updates 514 references across 42 Rust
source files, plus CLAUDE.md, .gitignore, Makefile, script/release,
and .mcp.json files. All 1205 tests pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add notify-based filesystem watcher for .story_kit/work/ that
auto-commits changes with deterministic messages and broadcasts
events over WebSocket. Push full pipeline state (Upcoming, Current,
QA, To Merge) to frontend on connect and after every watcher event.
Strip dead UI: remove ReviewPanel, GatePanel, TodoPanel,
UpcomingPanel and all associated REST polling. Replace with 4
generic StagePanel components driven by WebSocket. Simplify
AgentPanel to roster-only.
Delete all 11 workflow HTTP endpoints and 16 request/response types
from the server. Clean dead code from workflow module. MCP tools
call Rust functions directly and need none of the HTTP layer.
Net: ~4,100 lines deleted, ~400 added.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace single [agent] config with multi-agent [[agent]] roster system.
Each agent has name, role, model, allowed_tools, max_turns, max_budget_usd,
and system_prompt fields that map to Claude CLI flags at spawn time.
- AgentConfig expanded with structured fields, validated at startup (panics
on duplicate names, empty names, non-positive budgets/turns)
- Backwards-compatible: legacy [agent] format auto-wraps with deprecation warning
- AgentPool uses composite "story_id:agent_name" keys for concurrent agents
- agent_name added to AgentEvent variants, AgentInfo, start/stop/subscribe APIs
- GET /agents/config returns roster, POST /agents/config/reload hot-reloads
- POST /agents/start accepts optional agent_name, /agents/stop requires it
- SSE route updated to /agents/:story_id/:agent_name/stream
- Frontend: roster badges, agent selector dropdown, composite-key state
- Project root initialized to cwd at startup so config endpoints work immediately
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add git worktree isolation for concurrent story agents. Each agent now
runs in its own worktree with setup/teardown commands driven by
.story_kit/project.toml config. Agents stream output via SSE and support
start/stop lifecycle with Pending/Running/Completed/Failed statuses.
Backend: config.rs (TOML parsing), worktree.rs (git worktree lifecycle),
refactored agents.rs (broadcast streaming), agents_sse.rs (SSE endpoint).
Frontend: AgentPanel.tsx with Run/Stop buttons and streaming output log.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reverts port changes made during the spike back to default (3001/5173).
Adds two new stories for multi-worktree support: dynamic port management
(story 32) and worktree diff inspection with editor integration (story 33).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Proves that spawning `claude -p` in a pseudo-terminal from Rust gets Max
subscription billing (apiKeySource: "none", rateLimitType: "five_hour")
instead of per-token API charges. Concurrent agents run in parallel PTY
sessions with session resumption via --resume for multi-turn conversations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add workflow engine with acceptance gates, test recording, and review
queue. Frontend displays gate status (blocked/ready), test summaries,
failing badges, and warnings. Proceed action is disabled when gates
are not met. Includes 13 unit tests (Vitest) and 9 E2E tests
(Playwright) covering all five acceptance criteria.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>