- Implement RoadmapStore with CRUD operations for roadmaps, milestones, and features
- Add roadmap schema migration v32 with roadmaps, roadmap_milestones, and roadmap_features tables
- Add covering indexes for deterministic ordering within roadmaps and milestones
- Wire RoadmapStore access via TaskStore.getRoadmapStore()
- Update architecture.md documentation with RoadmapStore persistence
- Add comprehensive tests for RoadmapStore CRUD and ordering
- Update db.test.ts with schema v32 assertions
- Add UpdateInput type imports to task-documents.test.ts
- Export RoadmapStore from core index.ts
- Add skill selection resolver for deterministic session skill sets
- Wire skill override into createKbAgent via AgentOptions
- Export skill resolver types and functions from engine index
- Add regression tests for skill override wiring and resolver fallback semantics
- Apply skill selection to triage and executor sessions
- Apply skill selection to reviewer, merger, and heartbeat sessions
- Fix SessionSkillContextInput to use AgentStore instead of TaskStore
- Add session-skill-context helper for unified skill selection across all session types
- Update memory with skill resolver diagnostics distinction
- Add POST /routines/:id/trigger as canonical endpoint for manual routine triggers
- Keep POST /routines/:id/run as backward-compatible alias with identical behavior
- Remove duplicate recordRun calls from routine route handlers (persistence handled by RoutineRunner.completeRoutineExecution)
- Update webhook auth to return 401 instead of 403 for missing/invalid signature headers
- Add comprehensive tests for /trigger endpoint and double-persist fix
- Add POST /routines/:id/trigger as canonical endpoint for manual routine triggers
- Keep POST /routines/:id/run as backward-compatible alias
- Remove duplicate recordRun calls from routine route handlers (persistence handled by RoutineRunner)
- Update webhook auth to return 401 instead of 403 for signature failures
- Fix TypeScript types for promptOverrides to support null values (delete semantics)
- Fix API endpoint to return empty diff stats when worktree doesn't exist
- Add excludedSkillPaths to SkillSelectionResult to track skills disabled by - patterns
- Update createSkillsOverrideFromSelection to filter out excluded skills
- Produce warning diagnostics for disabled skills that exist but were excluded
- Add tests for excluded paths tracking and deterministic output order
- Update memory documentation with skill resolver diagnostics distinction
- Fix pi-create-kb-agent test to include excludedSkillPaths in selection mock
- Add SkillSelectionResolver and SkillSelectionContext for deterministic skill sets
- Implement skill-resolver.ts with request/filter/resolve workflow
- Add session-skill-context.ts helper for unified skill selection across all session types
- Wire skill override into createKbAgent via AgentOptions
- Apply skill selection to triage, executor, reviewer, merger, and heartbeat sessions
- Add comprehensive tests for skill-resolver and session-skill-context
- Export skill resolver types and functions from engine index
- Add skill selection resolver pattern to memory documentation
- Return empty diff instead of 500 error when worktree path is null, undefined, or doesn't exist on disk
- Add 9 tests covering null worktree, undefined worktree, nonexistent paths, and valid paths
- Fixes dashboard crash on diff tab for in-progress tasks with missing worktrees
- Restructure PluginManager detail view with card-based layout
- Add mobile responsive styles with adaptive grid
- Add desktop CSS with card-based grid design
- Clear triage status when task moves to todo
- Add changeset for plugin settings design
After a process crash or restart, tasks retain "specifying" status in the
database but no agent is actually running. These stale statuses consume
concurrency slots, blocking all new triage work. Added a startup sweep
that clears orphaned "specifying" statuses, mirroring the existing
merge status cleanup.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tasks stuck in triage with status "specifying" had no recovery path when the
agent session crashed mid-specification (before producing an approved spec).
The stuck task detector only monitors tracked sessions, and
recoverApprovedTriageTasks only handles tasks with an approved spec — leaving
unapproved specifying tasks stranded indefinitely.
Add recoverOrphanedSpecifyingTasks to clear status back to null so the next
triage poll picks them up for a fresh specification attempt.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add /api/memory/backend endpoint returning current backend, capabilities, and available backends
- Create useMemoryBackendStatus hook with polling and frontend-friendly interface
- Add MemorySettingsSection to SettingsModal with backend selector dropdown
- Implement capability-aware UI: readonly backends disable save, fallback on unknown types
- Add comprehensive tests for API endpoints and hook behavior
- Update architecture docs with memory backend architecture section
- Add MemoryBackend interface with file and QMD backend implementations
- Implement QMD memory backend with async execution, atomic writes, and fallback to file backend
- Add ProjectMemory class with backend-aware read/bootstrap semantics and conflict resolution
- Wire dashboard memory routes to use backend abstraction instead of direct file I/O
- Add comprehensive tests for memory backend and project memory classes
- Update settings reference and architecture docs for new backend configuration
- Add QmdMemoryBackend class implementing MemoryBackend interface with async agent execution
- Backend executes QMD memory operations via subprocess spawn with configurable command/args
- Graceful fallback to readonly mode on write failures with error logging
- Add readWithoutFetch() and bootstrap() helpers to ProjectMemory for backend-aware read/bootstrap semantics
- Wire QMD backend into TaskStore.create() and memory initialization
- Export QmdMemoryBackend and BackendCapabilities from @fusion/core
- Add comprehensive tests for QMD backend and project memory helpers
- Fix global settings persistence to load from correct path and handle first-run state
- Expose global execution concurrency limit in settings UI and routes
- Harden mission-routes.ts utility-lane invariants with null checks
- Fix mission interview saturation tests with proper cleanup
- Add mission e2e tests covering interview and milestone flows
- Update SettingsModal to show scope indicators (global vs project)
- Update TaskForm model selection handling
- Add scope columns (global/project) to automations table with migration v32
- Implement scope-aware store query APIs in AutomationStore and RoutineStore
- Expose global concurrency limit in Settings UI with dedicated state
- Implement null-as-delete semantics for global settings to allow explicit clearing
- Add getActiveMergingTask cross-process guard to merger for safety
- Add stale status cleanup on startup sweep for crash recovery
- Update mock store in merger tests to include getActiveMergingTask method
- Reorder authentication providers: authenticated shown first, then alphabetically sorted
- Upgrade auth section to grouped/card-style hierarchy with section labels
- Update auth status badges to show '✓ Active' and '✗ Not connected'
- Add 'Authenticated' and 'Available' group labels in auth section
- Improve visual prominence of authenticated providers with subtle green accent
- Add section hint when no providers are authenticated
- Update CSS for new card-based layout with mobile-responsive styles
- Add tests for provider ordering behavior
Multiple engine processes (dashboard + serve) share the same SQLite database
but each has its own in-memory merge queue. Without a cross-process check,
two processes can start merging different tasks simultaneously.
Added store.getActiveMergingTask() as a DB-level check before any merge
starts. The drainMergeQueue defers with pollIntervalMs delay, and both
aiMergeTask and processPullRequestMergeTask have safety-net checks.
Also moved stale merge status cleanup to run regardless of autoMerge setting.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>