Add formatError() helper that extracts both message and full stack from
unknown caught values, and use it at every status:"failed" catch site in
executor, agent-heartbeat, and triage. Stack traces now land in
store.logEntry outcome (persisted to task.log/activityLog) and in stderr
logger output, so failures like "Cannot read properties of undefined
(reading 'filter')" can be diagnosed without re-running.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Sort eligible todo tasks in Scheduler by priority first, then createdAt/id for stable FIFO ordering within each tier
- Sort eligible triage tasks using the same priority-aware ordering while preserving existing pause/status/recovery gating
- Add regression tests for scheduler and triage ordering, including blocked/paused/recovery-gated edge cases
- Update architecture docs to describe priority-first task dispatch behavior
- Update Fusion skill docs, prompts, and capability references to use public fn_* tool names consistently
- Align engine system prompts and tool schemas for messaging/task actions with fn_send_message, fn_read_messages, fn_task_* naming
- Refresh related tests across CLI, engine, dashboard, and core to match normalized tool naming and behavior
- Add a patch changeset for @runfusion/fusion describing the skill-tool namespace normalization
Atomic worktree creation: on `git worktree add` failure, remove the
partial directory so retries see a clean slate (executor.ts,
step-session-executor.ts). Add `reapOrphanWorktrees()` sweep on engine
startup to delete `.worktrees/*` dirs that have no `.git` file and are
not registered with git. Force readonly workflow steps to run pre-merge
so review personas reuse the coding worktree instead of allocating a
fresh post-merge one. Inject a Frontend UX Criteria checklist into
TRIAGE_SYSTEM_PROMPT when a task touches dashboard UI, so the first
coding pass can meet UX reviewer expectations.
Motivated by FN-2185 post-mortem: an incomplete `.worktrees/pale-raven`
dir blocked retries, and three Step 6 revision cycles over cosmetic UX
issues consumed ~13 hours.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Root cause: during a triage split the AI could set a child task's
`dependencies` to the parent id. The parent is hard-deleted after the split,
and the scheduler's dep check treats a missing id as unmet — permanently
blocking the dependent. This stranded FN-2164 behind the deleted FN-2163.
- core/store.deleteTask: refuse to delete when any live task still has the id
in its `dependencies` array. Throws TaskHasDependentsError listing dependents
so callers can rewrite or recover. Covers the triage-split path and any
future caller.
- engine/triage task_create: validate each proposed dependency before creating
a child — reject the parent id, reject unknown task ids, allow siblings
created earlier in the same split or pre-existing tasks.
- engine/triage split cleanup: wrap the parent deleteTask in try/catch that
keeps the parent alive (safer than stranding dependents) and logs the reason.
- engine/triage prompts: both the mandatory-split and proactive-split prompts
now explicitly state that subtask deps must never reference the parent.
- dashboard/routes /subtasks/create-tasks: reject parent-id deps, drop unknown
deps with an audit log entry, surface parentTaskCloseError + droppedDependencies
in the response instead of silently swallowing them.
- engine/executor: on execute entry, detect the drift state (in-progress task
with no worktree) and emit a loud log + task log entry; the existing
fresh-worktree path then recovers. Prevents silent "operating without a
worktree" behavior that we saw on FN-2152.
Tests:
core: 2907/2907 pass (+5 new, incl. deleteTask guard regression)
engine: 2554/2554 pass (+17 new, incl. task_create dep validation)
dashboard: 9064/9064 pass (+2 new for /subtasks/create-tasks).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Rename engine export and call sites to use createFnAgent consistently across runtime flows
- Update core lazy engine loader and dashboard agent-generation/planning/chat paths to reference createFnAgent
- Refresh affected unit and integration tests, including renaming pi-create-kb-agent.test.ts to pi-create-fn-agent.test.ts
- Update AGENTS.md documentation references to match the new createFnAgent name
- Add MailboxView as a full-page navigation view replacing the modal-based approach
- Migrate MessageStore from filesystem to SQLite backend for message persistence
- Implement conversation grouping for inbox display with unread badge state
- Remove modal plumbing (useModalManager, AppModals exports) and simplify App.tsx
- Add evictStaleProcessing() to TriageProcessor for self-healing hung triage sessions
- Add comprehensive MailboxView tests and Header mailbox tests
- Update README documentation with MailboxView features
- Add CSS styles for MailboxView component
- Fix MobileNavBar tests for mailbox tab visibility
- executor.test.ts: remove unused imports (Column, StuckTaskDetector),
replace Function type with EventListener, add MockTaskStore interface
- restart.integration.test.ts: replace require() with ESM import,
replace Function types with proper function signatures
- All tests pass
- Remove unused imports across 25 files in engine package
- Remove unused variable declarations in ipc-worker.ts, child-process-runtime.ts, and mission-autopilot.ts
- Clean up unnecessary imports in agent-instructions.ts, agent-tools.ts, cron-runner.ts, executor.ts, and other modules
- Minor cleanup in notifier.ts, peer-exchange-service.ts, pi.ts, plugin-runner.ts, and other files
- Improves code quality and reduces potential confusion from unused code
- 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
- 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>
The triage processor was only checking the global semaphore, not the
per-project maxConcurrent setting. Now it counts all active agents
(in-progress + specifying) and respects Math.min(perProjectAvailable,
semaphoreAvailable) before starting new triage tasks. This matches the
scheduler's concurrency enforcement and prevents triage from consuming
all available slots on startup.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The triage processor was kicking off all eligible tasks simultaneously,
queuing them all on the semaphore regardless of available slots. Now it
checks semaphore.availableCount first and only starts as many triage
tasks as there are free slots. Remaining tasks get picked up on the
next poll cycle (default 10-15s) as slots free up.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add ESLint configuration (eslint.config.mjs) for TypeScript/JavaScript linting
- Update executor prompts to include lint instruction before code submission
- Add lint check to triage prompt validation workflow
- Update agent prompts to emphasize lint compliance as quality requirement
- Add lint tool to agent toolset with file-level rule disabling capability
- Include lint in CI workflow with non-blocking status
- Update tests to verify lint-inclusive prompt behavior
- Add documentation for lint integration in contributing.md
- Add changeset for @gsxdsm/fusion minor release
- Update executor, triage, and merger prompt strings to identify the product as "fn"
- Align branch/worktree documentation examples with fusion/fn-* naming conventions
- Rename dashboard websocket attachment guard from __kbWebSocketsAttached to __fnWebSocketsAttached
- Refresh engine tests, dashboard utility comments, and TUI header text to remove stale kb wording
- Add task_document_write and task_document_read factories with schemas, revision-aware responses, and error handling in agent-tools
- Wire document tools into executor and triage sessions and update prompts to persist and reuse planning artifacts across runs
- Export document tool factories and parameter schemas from engine public entrypoints while keeping executor re-export compatibility
- Add comprehensive tests covering write/read success paths, empty/not-found cases, and store failure handling
- Fix pause-abort handler using updateTask({status: undefined}) which was a
no-op, leaving tasks stuck in 'specifying' forever after a pause interrupts
a session post-APPROVE. Changed to status: null to actually clear the field.
- Apply same fix to transient-error retry and general error catch paths.
- Wire StuckTaskDetector into TriageProcessor: trackTask/untrackTask/recordActivity
on session lifecycle, markStuckAborted to prevent stuck kills from being
reported as errors, and clear status to null on stuck-kill for next-poll retry.
- Update dashboard.ts to pass stuckTaskDetector to TriageProcessor and call
triageRef.current?.markStuckAborted in the shared onStuck callback.
- Add 3 tests covering pause-abort status clearing and stuck detector wiring.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add instructionsPath and instructionsText fields to Agent type and AgentStore
- Create agent-instructions resolver module in engine with priority-based resolution
- Wire custom instructions into executor, triage, reviewer, and merger agents
- Add PATCH /agents/:id/instructions API endpoint with file and text support
- Add instructions editor UI to dashboard agent detail config tab
- Add comprehensive tests for instructions resolver and AgentStore integration
- Add changeset for published package bump
- Add planningModelProvider/planningModelId fields to task model and API batch-update endpoint
- Wire triage engine to use per-task planning model override with settings hierarchy fallback
- Add planning model selector to TaskDetailModal Model tab
- Add comprehensive tests for triage engine planning model resolution and dashboard API/routes
- Add AgentPromptTemplate and AgentPromptsConfig types to ProjectSettings
- Create agent-prompts module with 7 built-in prompt templates and role resolver
- Wire engine agents (executor, reviewer, merger, triage) to use resolved prompts
- Add 25 test cases covering template resolution, role assignment, and validation
- Export new types from @fusion/core package
- Document agentPrompts configuration and built-in templates in AGENTS.md
- Add project-memory module in @fusion/core with read/write/resolve helpers and upsert-on-store hook
- Bootstrap project memory during task creation (store) with structured task context
- Inject resolved project memory into executor and triage agent system prompts
- Add comprehensive tests for project-memory module, store integration, and agent prompt changes
- Document project memory architecture and usage in README
- Update triage agent to proactively suggest splitting large tasks into subtasks during specification
- Tighten reviewer guidance to flag undersplit tasks that should be broken down further
- Add comprehensive tests for proactive subtask creation in triage (192 lines)
- Add reviewer tests for undersplit task detection (12 lines)
- Update README with documentation on proactive subtask splitting behavior
- Include user comments as context during AI triage spec generation and spec review
- Invalidate stale spec approvals when new user comments are added after approval
- Add lastApprovedAt tracking to task metadata for approval freshness detection
- Add comprehensive tests for comment-aware triage, review, and stale approval logic
- Add changeset for published package and update README with feature documentation
- Strengthen TRIAGE_SYSTEM_PROMPT with explicit subtask guidance rules and examples
- Strengthen buildSpecificationPrompt to reinforce proper subtask decomposition
- Add undersplit detection to spec reviewer to flag oversized or overly broad tasks
- Add test assertions for improved prompts covering undersplit detection and subtask guidance
- Add memoryEnabled boolean setting to core types and default settings
- Add Memory section toggle to SettingsModal dashboard UI
- Integrate memoryEnabled check in executor and triage engine prompts
- Add tests for settings UI, executor prompt behavior, and triage prompt behavior
- Update SettingsModal section count test for the new Memory section
- Log the selected model provider and ID during triage so the agent log records which model was used
- Add agent-log entry capturing triage model choice for observability
- Add comprehensive tests for triage model logging behavior
- Update AgentsView component and dashboard docs for consistency
- Remove obsolete AgentsView test
1. Scoping rules in agent prompts: executor, triage template, and reviewer
now explicitly forbid deleting/gutting modules, settings, interfaces,
exports, or test files outside the task's declared File Scope. Reviewer
will REVISE if out-of-scope removals are detected.
2. Pre-merge diffstat scope check: merger.ts validates the git diffstat
against the task's PROMPT.md File Scope before merging. Large deletions
outside scope are logged as warnings on the task (soft guardrail).
3. Changeset requirement for feature removal: triage template now requires
a .changeset/ entry when removing existing functionality. Executor and
reviewer enforce this requirement.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add state to tasks: persisted in DB, gates scheduler pickup to prevent immediate retry of transient failures
- Introduce shared recovery-policy module with bounded exponential backoff (1s → 60s, max 5 attempts)
- Wire recovery policy into executor, scheduler, and triage so all agents respect the same retry cadence
- Persist retry state (attempt count, next eligible time) in task metadata via store and DB schema
- Add DB migration for new retry columns and update schema tests
- Update README with recovery policy documentation
- Refactor dashboard Header component and styles, consolidate header tests
- Fix session-files route tests to align with updated route signatures