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 core loader, dashboard server chat/planning routes, and frontend agent IDs/storage keys from kb-agent to fn-agent naming
- Update dashboard hooks and components (agent list, chat view, quick chat) to use the new fn agent key prefixes consistently
- Refresh engine, dashboard, core, and CLI tests/mocks to remove remaining kb-agent route and temp prefix references
- Update storage/gap-analysis docs to reflect fn agent key names and add a @gsxdsm/fusion patch changeset for the rename
- 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 project settings for pushAfterMerge and pushRemote with defaults and typed merge result fields for push status/errors
- Implement post-merge remote sync in the merger with pull --rebase, auto/AI conflict resolution, and one non-fast-forward retry before push
- Expose push-after-merge controls in Settings modal with conditional Push Remote input and coverage for desktop/mobile save flows
- Document the new settings in the settings reference and stabilize CLI cross-build help test timeout
- Add mock-only rationale comments and tighten assignment watcher typing in heartbeat tests
- Replace SQLite-backed MessageStore setup in heartbeat message-flow coverage with an in-memory fake store
- Swap assignment watcher AgentStore setup to an EventEmitter-based mock with explicit heartbeat and budget stubs
- Refactor run-audit integration tests to use an in-memory TaskStore fake for recording and filtering audit events
- Update executor, reviewer, core prompt templates, and path-boundary messaging to reference the .fusion/memory/ directory instead of a single MEMORY.md file
- Broaden worktree boundary checks in pi path validation to allow .fusion/memory/ directory access from task worktrees
- Align memory backend metadata and dashboard backend labels to display file backend storage as .fusion/memory/
- Refresh core/engine tests to assert the new directory-based memory wording and boundary behavior
- Add heartbeatIntervalMultiplier to shared settings schema/types with settings parity coverage
- Apply heartbeat multiplier in engine scheduling logic while preserving explicit per-agent interval behavior
- Add Settings modal and Agents view controls for heartbeat multiplier and per-agent interval overrides, including new styling
- Expand dashboard and engine test coverage for multiplier/heartbeat controls and document the new setting
- Add "source" export entries for @fusion/core, @fusion/dashboard, and @fusion/engine package exports
- Configure tsup/esbuild to include the "source" condition when resolving workspace dependencies
- Pass --conditions=source to bun compile so compiled CLI binaries resolve source-conditioned exports consistently
- Replace direct console.warn calls in agent-instructions with createLogger("agent-instructions") warnings
- Keep existing truncation and path-validation safeguards while standardizing diagnostic output format
- Add focused diagnostics tests that verify single warning emission for truncation and invalid instructionsPath scenarios
- Add coverage for missing instructions files and project memory read failures to ensure graceful fallback behavior
- Replace previously silent catch blocks in auto-merge and settings-listener flows with runtimeLog.warn messages
- Add warning logs for startup and periodic auto-merge sweeps plus poll interval fallback when settings reads fail
- Add regression tests that force each swallowed-error path and assert structured warnings are emitted
- Cover global/engine unpause resumeOrphaned failures and stuck-detector checkNow failures in project-engine tests
- Promote HEARTBEAT_NO_TASK_SYSTEM_PROMPT as the primary no-task heartbeat constant while keeping a backward-compatible alias.
- Refine no-task heartbeat guidance for lightweight ambient coordination and explicit tool usage.
- Select the no-task prompt for heartbeat runs without task context before appending instruction/rating overlays.
- Update heartbeat regression tests to assert the renamed no-task prompt constant and prompt/tool expectations.
- Return the created task ID directly from runTaskPlan and propagate it through fn_task_plan
- Remove hardcoded FN-### log parsing so CLI extension supports structured IDs like PROJ-042
- Add heartbeat fallback parsing from task_create text output when details.taskId is absent
- Expand engine and CLI tests to cover structured task IDs and updated task-plan return behavior
- Add structured warning logs in silent catch paths for IPC worker shutdown, plugin unregistration cleanup, child runtime metrics polling, and merger build rollback reset
- Improve merger rollback warning context to make build-verification reset and retry failures easier to diagnose
- Add regression tests covering each new warning path to ensure errors are surfaced without changing existing control flow
- Add StepSessionExecutor test coverage for cherry-pick abort logging when conflict cleanup fails
- Update HEARTBEAT_NO_TASK_SYSTEM_PROMPT copy to emphasize inbox, memory, delegation, and heartbeat_done usage
- Expand heartbeat monitor tests to assert no-task prompt/tool alignment and preserve task-scoped prompt behavior
- Harden first-run and App view tests by using a safe cwd fallback and more robust async UI waits
- Add best-effort dashboard performance reporting hooks in App and useProjects via a new reportDashboardPerf API helper
Introduce a shared test-utils module and global vitest setup that
guarantee tests never write to the real .fusion directory or leak temp
directories under /tmp.
Infrastructure:
- packages/core/src/__test-utils__/workspace.ts — tempWorkspace(),
useIsolatedCwd(), trackForCleanup(), assertOutsideRealFusion() with
auto-cleanup in afterEach.
- packages/core/src/__test-utils__/vitest-setup.ts — per-worker guard:
chdirs each worker into an isolated tmp dir, wraps process.chdir to
refuse the real .fusion, scopes tmp dirs under fusion-test-workers/
(skips cwd change in thread-pool workers where chdir isn't supported).
- packages/core/src/__test-utils__/vitest-teardown.ts — globalSetup
hook that wipes the shared parent even when workers are SIGKILLed.
- scripts/check-test-isolation.mjs + `test:isolated` / `test:check-
isolation` scripts for CI.
- @fusion/test-utils alias + setupFiles + globalSetup wired into core,
cli, engine, dashboard, tui vitest configs; matching tsconfig paths.
Test refactors (no behavior change):
- cli provider-settings, auth-paths, provider-auth — switch leaking
mkdtempSync calls to tempWorkspace().
- core migration, first-run, store-backward-compat — replace manual
process.chdir save/restore with useIsolatedCwd().
- tui fusion-context — replace 9 hardcoded tmp paths (collision-prone
under parallelism) with tempWorkspace().
- dashboard useTheme, FileBrowser, TaskCard — resolve source-file reads
against a PACKAGE_ROOT computed from import.meta.url instead of cwd,
so tests don't depend on the process working directory.
Verified: full suite (~15,500 tests across 8 packages + plugins) passes
and the orphan-detector reports zero leaked temp directories after a
complete run.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Remove legacy .fusion/memory.md fallback references and normalize prompts/docs to .fusion/memory/MEMORY.md
- Stop legacy mirror writes and fallback reads in core memory backend and project memory flows
- Update engine worktree boundary checks and tests for canonical memory file handling
- Align dashboard memory/settings surfaces and route tests with canonical memory behavior
- Add model-favorites persistence test coverage for mission interview and new agent dialogs
- Add structured warning logs for plugin-runner fallback paths instead of silent catches
- Add warning telemetry in agent-tools for agent-memory directory, QMD search, and index refresh failures
- Log cron-runner session disposal failures and update agent-logger persistence warnings to use logger output
- Expand engine tests to cover warning behavior across plugin-runner, agent-tools, cron-runner, and agent-logger
- Update core and engine prompt text to reference .fusion/memory/ with MEMORY.md and daily-note guidance
- Allow worktree tool boundary access to .fusion/memory/ files while preserving legacy .fusion/memory.md compatibility
- Revise memory compaction/insight extraction messaging and related type/docs comments to use canonical memory paths
- Refresh dashboard and test expectations across core/engine/dashboard/docs for the new memory path wording
- Add HEARTBEAT_NO_TASK_SYSTEM_PROMPT for no-task heartbeat sessions with only non-task-scoped tooling guidance
- Switch heartbeat session setup to choose the no-task base prompt when executing without task context
- Keep agent instruction and memory enrichment on top of the selected base prompt for both task and no-task runs
- Extend heartbeat tests to verify no-task prompts exclude task-scoped tool references and are passed into createKbAgent
- Log final-path git reset --merge cleanup failures in aiMergeTask with task-scoped warning details
- Preserve the original "all 3 attempts exhausted" merge error even when cleanup reset fails
- Add merger retry tests covering successful final cleanup and failed final cleanup logging behavior
- Add a patch changeset for @gsxdsm/fusion documenting the improved merger diagnostics
- Convert seed-sample-nodes into a test-only helper and remove direct execution against the real central database
- Replace private-looking host examples with RFC 5737 test-net addresses in node connection docs and ConnectNodeModal expectations
- Add Vitest aliases for @fusion/core and @fusion/engine to stabilize cross-package test imports
- Load AgentReflectionService via local engine source path in in-process runtime to avoid alias resolution failures
- Add defensive cleanup for in-memory task tracking when tasks move state or agents pause
- Improve stuck-detection and self-healing flow to reduce leaked state and missed recovery paths
- Add logging around previously swallowed errors and tighten executor cleanup behavior
- Expand restart and self-healing reliability tests to cover regression scenarios
- Recompute slice status when adding a feature so stale "complete" slices cascade back to milestone and mission statuses
- Require checkMissionCompletion to verify every feature is done before marking a mission complete
- Add mission-wide status-chain recomputation when stale complete slices or milestones are detected during reconciliation
- Expand core and engine tests to cover addFeature downgrades, stale complete states, and feature-level completion checks