Commit Graph

1677 Commits

Author SHA1 Message Date
Fusion (runfusion.ai)
025683ca60 feat(FN-5438): add manual merge blocker bypass mode for queued tasks
Adds a manual merge blocker mode (FN-5438) that prevents automatic merging and provides a bypass mechanism to resume, wired through the merger, project engine, and task workflow API routes. Includes tests across core, engine route registration, and project engine layers, plus a changeset and documen

Fusion-Task-Id: FN-5438
2026-05-21 18:29:03 -07:00
Fusion (runfusion.ai)
f6f38676b4 feat(FN-5226): add scope auto-widen layer 2.5 to merger for attribution-bas
Merges the Layer 2.5 scope-auto-widen feature (FN-5226) into the merger: a new evaluator module that automatically widens a task's declared file scope based on git attribution prior to the existing scope partition gate, wired into `merger.ts` with full audit taxonomy, persisted task metadata, and re

Fusion-Task-Id: FN-5226
2026-05-21 16:30:31 -07:00
Fusion (runfusion.ai)
216c32bfe5 feat(FN-5347): reset manual retry counters across task retry surfaces
- Add a shared manual retry reset helper in core and export it for consumers
- Wire retry counter resets into CLI task retry, extension task retry, and dashboard task workflow routes
- Align retry reset behavior with task typing updates and remove superseded task-helper reset paths
- Add focused core/CLI/extension/dashboard tests plus docs and a changeset describing retry reset behavior
2026-05-21 15:45:48 -07:00
Fusion (runfusion.ai)
8df21a6b68 feat(FN-5353): fix merge-reuse handoff race by gating reacquire and strict
Fixes merge handoff stalls by enforcing strict queue targeting and self-enqueue in the merger (FN-5353 Step 4), forcing reacquire before reuse handoff gates (Step 5), and aligning integration-root contract tests (Steps 1 & 7). Consolidates two prior changesets into `fn-5353-merge-reuse-stall-fix.md`

Fusion-Task-Id: FN-5353
2026-05-21 15:30:13 -07:00
Fusion (runfusion.ai)
0c2416903f feat(FN-5363): enforce strict target lease to prevent merge queue pollution
Enforces strict target-lease behavior on merge queue rows, gates and scrubs polluted entries, enriches no-lease handoff diagnostics, and adds regression tests covering leased-target no-lease and polluted queue reuse paths, with audit registration and docs updates.

Fusion-Task-Id: FN-5363
2026-05-21 13:40:25 -07:00
gsxdsm
2d425b1e28 fix: scrub queued/blockedBy/overlapBlockedBy on in-review transition
A task that picked up status='queued' or overlapBlockedBy while waiting in
todo (file-scope overlap with a higher-priority peer) was carrying those
todo-dispatch markers into in-review, where the merge gate then permanently
refused with "task is marked 'queued'". Ghost-review → todo → scheduler
re-queue → stranded-completed-todo recovery → in-review formed a steady-
state loop that never let the task merge.

moveTaskInternal now treats queued/blockedBy/overlapBlockedBy as todo-only
dispatch state and clears them on every transition into in-review. failed
and awaiting-* statuses are left untouched (already covered by an existing
test, plus a new regression test for the queued case).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 11:08:14 -07:00
gsxdsm
7d25d98b2f fix(FN-5256): await disposal across task:moved-away and task:deleted
Close the last fire-and-forget gap from the previous fixes: the task:moved
(away from in-progress) and task:deleted listeners no longer call the
synchronous fire-and-forget `abortInFlightTaskWork`. Instead they track an
awaited disposal promise per task in `pendingTaskDisposals`. The task:moved
(to in-progress) dispatch path awaits any in-flight disposal for the same
task before calling `execute()`, so a fast bounce (in-progress → todo →
in-progress) no longer races the conflict-cleanup path against a still-live
shell.

`awaitAbortInFlightTaskWork` now claims each session surface (activeSessions,
activeStepExecutors, activeWorkflowStepSessions, activeSubagentSessions)
synchronously before awaiting any async abort. This lets concurrent disposal
calls for the same task dedupe naturally — the second call finds the maps
empty and no-ops, preserving the existing single-abort/single-dispose
contract that the soft-delete and user-cancel tests assert.

Adds a regression test in executor-user-cancel covering the re-dispatch
ordering: an immediate task:moved-to-in-progress that follows a still-running
task:moved-away must wait for abort to complete before execute() runs.

The legacy `abortInFlightTaskWork` is removed (no callers).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 10:14:38 -07:00
gsxdsm
cf0101be7c fix(FN-5256): keep live task worktrees through pause/resume races
Three independent reliability fixes that all surfaced as the same bug:
live tasks losing their worktrees mid-execution and emitting
`wrong_toplevel` errors.

Fix A — executor stale-self-owned classifier:
`reconcileSelfOwnedActiveSessionForRemoval` now takes a process-active
probe (`executingTaskLock.has`) and a minimum-idle window (default 5s)
in addition to the existing in-memory `activeWorktrees` binding probe.
Recently-registered or still-running entries are refused with
`process-active-refuses` / `too-recent-refuses`, with audit-grade
log lines. Both the pre-remove path
(`reconcileSelfOwnedBeforeRemove`), the post-throw retry in
`removeOwnWorktreeWithReconcile`, and the defensive reconcile in
`removeWorktree` route through the same hardened gates.

Fix B — pause synchronously reaps the agent session:
New `awaitAbortInFlightTaskWork` mirrors the existing fire-and-forget
abort but awaits each `session.abort()` /
`stepExecutor.terminateAllSessions()` /
`workflowSession.abort()`. `parkTaskAfterWorkflowStepPause` calls it
before `moveTask("todo")`, and the `task:updated` user-pause handler
routes through it, so a fast re-dispatch can no longer race a still-
live shell.

Fix C — self-healing realpath + active-task skip:
`reconcileTaskWorktreeMetadata` now realpath-normalizes both sides of
the registry comparison (handling macOS `/private/var/...`) and
refuses to clear `worktree`/`branch` on in-progress or in-review
tasks. The skip emits a new
`task:auto-recover-worktree-metadata-skipped-active` audit event;
executor-level recovery paths remain in charge of active tasks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 09:06:23 -07:00
Fusion (runfusion.ai)
a04ba3cf21 feat(FN-5413): add null description persist regression test
Added a regression test for null description persistence in the core task store and a CLI patch changeset to ship the fix.

Fusion-Task-Id: FN-5413
2026-05-21 08:20:42 -07:00
gsxdsm
04648a4a68 Merge commit '5f9f7776300afbc935d651949c50c60bca2cafd4' 2026-05-21 07:05:48 -07:00
Fusion (runfusion.ai)
5f9f777630 feat(FN-5374): raise room transcript defaults and align compaction settings
Raised room transcript defaults (`messagesBefore` and `daysBefore`) in the core settings schema and updated project-level setting defaults, with corresponding documentation refresh in the settings reference. Added full test coverage for room compaction defaults, pinned room default settings in Setti

Fusion-Task-Id: FN-5374
2026-05-21 07:05:48 -07:00
gsxdsm
97e6a0cc0e fix(FN-5256): skip cycle preflight when new task has no deps
The unconditional listTasks() in assertNoDependencyCycle was wasted work
for the common no-dependency write and broke the same-agent duplicate
intake fail-open path: tests that stub listTasks to throw had the cycle
check consume the rejection before _maybeAutoArchiveSameAgentDuplicate's
try/catch could swallow it, propagating the error out of createTask.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 06:40:15 -07:00
Fusion (runfusion.ai)
6fdfb1ad5c feat(FN-5425): add coordination notice system for multi-agent room task fil
Adds a `room-coordination.ts` helper module for multi-agent coordination messaging, wires coordination notices into the agent heartbeat path, and ships tests plus documentation for the feature. A changeset prepares the `@runfusion/fusion` package for release.

Fusion-Task-Id: FN-5425
2026-05-21 00:17:33 -07:00
gsxdsm
5c15031416 fix(health): re-run integrity check on Refresh health, not just re-read cache
The dashboard's corruption banner refresh action was a no-op for clearing
stale corruption flags after the user repaired the DB. Database.
scheduleBackgroundIntegrityCheck runs the integrity check exactly once at
engine boot and then early-returns forever after, so corruptionDetected
was sticky for the life of the process. POST /api/health/refresh just
read the cached flag back.

Add Database.refreshIntegrityCheck() and TaskStore.refreshDatabaseHealth()
which synchronously re-run the integrity check and update the cached
state, and have the route use them. After REINDEX / fn db --vacuum / any
in-place repair, users can now clear the banner without restarting the
engine.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:02:53 -07:00
gsxdsm
85f0de9881 Merge commit 'b12ff26f36daaf31e807f4920c61c2a7b3727a64' 2026-05-20 22:34:32 -07:00
Fusion (runfusion.ai)
b12ff26f36 feat(FN-5424): add opencode-go provider to settings with model refresh on k
Exposes the `opencode-go` provider via `startup-model-sync`, wires it into the daemon and serve commands, and adds a refresh-status indicator in the SettingsModal that triggers model reloading whenever the provider key is saved. Includes a changeset, settings documentation, and corresponding tests a

Fusion-Task-Id: FN-5424
2026-05-20 22:34:32 -07:00
gsxdsm
d90da81079 fix(core): default null task.description to empty string on persist
The tasks table description column is NOT NULL, so a task arriving with
description == null/undefined would fail the insert with a constraint
error. Default to "" in getTaskPersistValues, matching the ?? null / ?? 0
treatment of other optional fields.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 22:25:15 -07:00
gsxdsm
57dbff4ba4 fix(FN-5407): stop checkpoint-truncating live DB during backup
Backups opened a second node:sqlite connection against the live fusion.db
and ran PRAGMA wal_checkpoint(TRUNCATE) before copying. A node:sqlite
SIGSEGV mid-checkpoint (the recurring pager_write crash noted in db.ts)
could leave the main DB file extended-but-zeroed, which is exactly the
failure mode that wiped a 1GB fusion.db tonight.

Replace the in-process checkpoint with a plain cp of the main DB plus any
sibling -wal/-shm files. SQLite replays the WAL on first open, so
uncheckpointed pages survive without us ever opening a second connection
against the live database.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 22:09:30 -07:00
gsxdsm
b936ab9bb5 feat(FN-5414): merge fusion/fn-5414 2026-05-20 20:15:43 -07:00
Fusion (runfusion.ai)
2baaad743a feat(FN-5407): add paired central backup support to backup command and stor
FN-5407 adds paired central backup support to the Fusion task management system, with both the core backup engine and CLI commands updated to handle central database backup pairs. Documentation was updated to reflect the new capability, and two stabilization fixes were included to handle central bac

Fusion-Task-Id: FN-5407
2026-05-20 20:05:08 -07:00
Fusion (runfusion.ai)
1a5aff9c44 feat(FN-5337): remove speculative orphan requeue from self-healing sweep
Removes the speculative orphan requeue mutation path from self-healing, replacing it with an observation-only sweep that no longer attempts to re-enqueue orphaned tasks — a conservative regression that eliminates noisy false-positive recovery attempts. The change includes rewritten unit coverage, a

Fusion-Task-Id: FN-5337
2026-05-20 18:49:38 -07:00
Fusion (runfusion.ai)
dbccdb1275 feat(FN-5375): enforce manifest-gated cloudflared checksum installation
Added manifest-gated checksum verification for cloudflared remote access tunnels: a pinned manifest validator (Step 1) and enforcement logic (Step 2) wired into the settings memory routes, with aligned tests and documentation covering fail-closed install behavior and pending-manifest guidance.

Fusion-Task-Id: FN-5375
2026-05-20 18:43:17 -07:00
Fusion (runfusion.ai)
8e67404680 fix(FN-5345): address code-review findings on engine fixes
Follow-up to 1983dac6e addressing nine findings from a code review of the
FN-5345/FN-5377 engine fixes. Includes a real bug fix (commit-message bypass
of the amend detection), two reliability invariant restorations (FN-4811 +
FN-4954 in the new D3 reuse-fallback path), a resource-leak cleanup, plus
test/audit/taxonomy polish.

HIGH

- D3 reuse-fallback now respects FN-4811 active-session safety: matches whose
  path is currently owned by a different task in activeSessionRegistry are
  skipped, never silently rebound. Skipped owners are recorded in audit
  metadata for forensics.
- D3 reuse-fallback now respects FN-4954 pool-lease bookkeeping: when
  recycleWorktrees=true AND a worktree pool is attached, the direct-reuse
  shortcut is bypassed and the existing acquireTaskWorktree path is used so
  WorktreePool.acquire/.release stays consistent. Without this guard the
  new path could trip PoolDoubleLeaseError.
- prepare-commit-msg amend detection tokenizes the parent command line and
  stops at the first message-supplying flag (-m/-F/--message/--file/=variants)
  so a commit message containing the substring '--amend' cannot bypass the
  guard. New regression test in prepare-commit-msg-empty-guard.real-git.test.ts.

MEDIUM

- Early empty-own-diff fast-path extracted into tryEarlyEmptyOwnDiffFinalize()
  helper. Removes the exception-as-control-flow sentinel ('skip-early-fast-path:
  not-reuse-mode') in favor of a plain if (eligible) { try { ... } catch {} }
  block.
- Fast-path best-effort cleans up the stranded fusion/<id> worktree and branch
  before completeTask(), so empty-own-diff residuals do not accumulate in
  .worktrees/ or the branch namespace. FN-4811 guard ensures we never remove
  a foreign-owned worktree.
- Two new audit subtypes in run-audit.ts replace the prior overloading of
  merge:reuse-fallback-new-worktree:
    - merge:reuse-fallback-pruned-stale-registration
    - merge:reuse-fallback-reused-existing-registration
  merge:reuse-fallback-new-worktree is now reserved for actual new-worktree
  creation. Local emitReuseHandoffAuditEvent type union updated to match.
- New direct classifier test in merger-finalize-unproven.real-git.test.ts
  ('classifies proven-no-op for empty-own-diff branches') covers the new
  branch in classifyOwnedLandedEvidence that self-healing and post-handoff
  paths also depend on.

LOW

- Alpine/busybox ps fallback: prepare-commit-msg hook reads /proc/$PPID/cmdline
  if 'ps -o args=' returns empty (busybox ps often lacks '-o args=' support).
- New backstop test variant 'FN-5345: empty-own-diff fast-path fires even
  when branch is registered to two worktrees' reproduces the actual FN-5345
  production wedge geometry where fusion/<id> was double-registered to two
  worktrees.

Tests
  - Full @fusion/engine suite: 448 files / 5881 tests / 9 skipped, all green
  - pnpm lint green, pnpm build green
2026-05-20 17:54:26 -07:00
Fusion (runfusion.ai)
1983dac6e4 fix(FN-5345): refuse empty commits + early empty-own-diff finalize
Three engine-level fixes for the in-review wedge class identified via FN-5345
(verification-only task with empty handoff commit + drifted worktree mapping
escalating to 'merge-deadlock-detected: verified content not on main' after
FN-4999 completion-handoff-limbo recovery exhausts).

D1 — prepare-commit-msg empty-commit guard
  Fusion task worktrees install a prepare-commit-msg hook that refuses
  'git commit --allow-empty' and other zero-staged-diff commits. Amend
  (detected via $2==commit source arg or '--amend' in 'ps -o args= -p $PPID')
  and merge/squash/cherry-pick/revert/rebase ceremonies are allowed.

D5 — early empty-own-diff fast-path in aiMergeTask
  In reuse-task-worktree integration mode, BEFORE any reuse-handoff acquisition,
  detect branches with own_commit_count >= 1 but zero net diff vs merge-base
  (git diff --quiet <mergeBase>..<branch>) and finalize as no-op with
  mergeDetails.noOpMerge=true + task:auto-recover-finalize-already-on-main
  audit (reason: empty-own-diff-early-fast-path). cwd-main integration mode
  is unchanged. classifyOwnedLandedEvidence also detects empty-own-diff so
  self-healing and post-handoff finalize paths benefit too.

D3 — reuse-fallback consults existing branch registration
  Before creating a fresh worktree in merger's reacquireReuseIntegrationWorktree,
  consult 'git worktree list --porcelain' for existing registrations of
  fusion/<id>. Reuse extant usable registrations directly. Prune stale
  registrations first. Eliminates FN-5083-class double-registration where
  'git worktree add -f' on an already-registered branch produced two worktrees
  both claiming the branch and wedged the next handoff gate.

Tests
  - New real-git backstop: prepare-commit-msg-empty-guard.real-git.test.ts
  - New reliability interaction backstop in merge-reuse-task-worktree.test.ts
    ('FN-5345: empty-own-diff branch auto-finalizes via early fast-path')
  - commit-msg-trailer.real-git.test.ts updated to use real commits (it was
    relying on --allow-empty, which the new guard now refuses)
  - Full @fusion/engine suite: 448 files / 5879 tests / 9 skipped, all green
  - pnpm lint green, pnpm build green
2026-05-20 17:31:48 -07:00
Fusion (runfusion.ai)
fd202e9356 feat(FN-5329): remove orphan rescue and branch-recovery primitives from eng
Removes the branch-recovery CLI surface, orphan-rescue engine primitives, and their associated tests (over 1,500 lines deleted), while restoring a minimal prune-only orphan branch sweep with proper git audit mutation types. Documentation across `cli-reference.md`, `task-management.md`, and `AGENTS.m

Fusion-Task-Id: FN-5329
2026-05-20 16:43:27 -07:00
Fusion (runfusion.ai)
b06cf64cd4 feat(FN-5321): add evidence gap detector for external integration manifests
Implements external integration validation (FN-5321) with a manifest validator scaffold, worktrunk manifest wiring, and an evidence gap detector that runs during spec validation and triage; the reviewer also gates on external integration readiness. Includes tests for manifest, evidence gap, and tria

Fusion-Task-Id: FN-5321
2026-05-20 15:54:44 -07:00
Fusion (runfusion.ai)
8f2d5e7e61 feat(FN-5220): guard explicit duplicate markers in triage and self-healing
Adds an explicit duplicate-marker guard (FN-5220) spanning core helper, dashboard API endpoint, triage short-circuit, and self-healing sweep to detect and handle duplicate task creation attempts; includes comprehensive test coverage across unit, API, and integration layers plus documentation.

Fusion-Task-Id: FN-5220
2026-05-20 14:28:45 -07:00
gsxdsm
5548dc57de fix(dashboard): autostash dirty working tree across git pull and surface reapply conflicts
The dashboard's git pull endpoint failed outright when the working tree had
local edits or untracked files. It now stashes (including untracked) under a
fusion-dashboard-pull-autostash label, performs the pull, and reapplies the
stash. If reapplying conflicts, the stash is preserved and GitPullResult
surfaces autostashed/stashReapplied/stashConflict plus a message pointing at
the stash label so the user can resolve from the Stashes view.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 14:28:36 -07:00
gsxdsm
c824810181 fix(FN-5279): apply reuse-mode squash to local main and guard executor-lease race
In reuse-task-worktree mode the merger detaches HEAD in the task worktree so
the squash commit lands on detached HEAD; nothing previously advanced the
project root's local integration branch, so changes never appeared on main.
Step 5c now applies the squash to projectRootDir via git merge --ff-only,
falling back to a regular merge with AI conflict resolution if main has
diverged. pushAfterMerge (when enabled) now runs from projectRootDir where
the branch was just advanced, so parsePushRemoteTarget can resolve a branch
instead of failing on the worktree's detached HEAD.

Also tightens acquireReuseHandoff: the executor-lease check above the
queue-lease acquisition was non-atomic, letting a local executor grab the
task between checks. Re-check after acquisition and release the queue
lease with a precise diagnostic instead of proceeding into a generic
failure later.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 14:28:19 -07:00
gsxdsm
d6196a8665 fix(FN-5363): implement targetTaskId in store SQL so lease targets correct task
The previous commit wired targetTaskId through the engine caller but the
store's acquireMergeQueueLease SQL still grabbed the queue head unconditionally,
leaving the no-lease loop intact. This lands the store-side change: when
targetTaskId is provided it attempts a direct-match UPDATE first; only falls
back to queue-head ordering if that row isn't available (backward-compatible).

Adds regression test covering the polluted-queue-head scenario (FN-5363).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 12:05:41 -07:00
gsxdsm
7df11bc2cf fix(FN-5353): reacquire fresh worktree when reuse handoff fails instead of falling back to main
Before: when reuse-task-worktree was configured but task worktree was missing/unusable,
merger fell back to cwd-main, losing the task worktree isolation benefit.

After: merger creates a fresh worktree for the task branch inline (using the standard
git worktree add pattern with identity guard installation) and retries the reuse handoff.
Only falls back to cwd-main if fresh acquisition also fails.

Three new audit events track the recovery path:
- merge:reuse-worktree-fresh-acquire — fresh acquisition started
- merge:reuse-worktree-fresh-acquired — fresh worktree created and bound to task
- merge:reuse-fallback-cwd-main — only when fresh acquisition itself fails (last resort)

Behavior:
- Missing/unusable task worktree → fresh worktree created, merge continues from it
- Fresh acquisition fails → cwd-main fallback (last resort, fully audited)
- Genuine liveness conflict (usable worktree but lease refused) → re-thrown, not masked

Regression test covers the missing-worktree case: verifies fresh acquisition + handoff
succeeds without any cwd-main fallback event.
2026-05-20 10:58:29 -07:00
Fusion (runfusion.ai)
22d59b5f9a feat(FN-5279): add merge integration worktree feature with settings UI and
Implements the `mergeIntegrationWorktree` setting (FN-5279) that allows tasks to reuse their own worktree as the integration root instead of spawning a separate one. Steps 1–2 added the settings schema, types, and SettingsModal surface with documentation; Step 3 wired an integration-root resolver th

Fusion-Task-Id: FN-5279
2026-05-20 09:42:40 -07:00
Fusion (runfusion.ai)
9011c2107e feat(FN-5320): canonicalize worktrunk binary name and manifest
Implements canonical worktrunk binary naming and manifest handling (FN-5320), adding a worktrunk installer that canonicalizes the executable name and manifest data, with documentation updates for architecture and settings, plus test alignments across routes, audit, and worktree acquisition fixtures.

Fusion-Task-Id: FN-5320
2026-05-20 07:44:57 -07:00
Fusion (runfusion.ai)
232a9fea86 feat(FN-5322): fix main chat composer flex sizing and expand behavior
Fixes the main chat composer flex sizing so the input area properly expands (FN-5322), with regression guards in the autosize test suite and a new browser layout smoke script covering the composer expand behavior.

Fusion-Task-Id: FN-5322
2026-05-20 07:20:01 -07:00
Fusion (runfusion.ai)
9efcf9375a feat(FN-5271): add precommit identity guard for worktree hooks
Adds pre-commit identity guard handling for branch case normalization (FN-5271), updating the worktree hooks implementation and adding a real-git integration test alongside a changeset for `@runfusion/fusion`.

Fusion-Task-Id: FN-5271
2026-05-20 06:42:05 -07:00
Fusion (runfusion.ai)
35b2971f54 feat(FN-5216): sanitize duplicate paths in file scope when parsing task sto
The merge adds a file scope sanitizer to the task store that deduplicates and normalizes path entries, with test coverage in `store-parsing.test.ts`; a small documentation fix accompanies the change in AGENTS.md.

Fusion-Task-Id: FN-5216
2026-05-20 06:14:47 -07:00
Fusion (runfusion.ai)
1b49cbc94d feat(FN-5284): surface db corruption via health checks, self-healing, and d
- fix(FN-5284): add db corruption audit mutation type
- feat(FN-5284): complete Step 7 — document corruption surfacing
- feat(FN-5284): complete Step 6 — add db corruption banner
- feat(FN-5284): complete Step 5 — extend health payload
- feat(FN-5284): complete Step 3 — surface db corruption in self-healing
- feat(FN-5284): complete Step 2 — add db corruption notification event
- feat(FN-5284): complete Step 1 — expose integrity check errors

Fusion-Task-Id: FN-5284
2026-05-20 04:13:43 -07:00
Fusion (runfusion.ai)
93b11c6c0c feat(FN-5241): add atomic in-review handoff seam with executor/self-healing
The merge introduces an atomic review handoff seam in the core store (`packages/core/src/store.ts`) and migrates executor and self-healing transitions to use it, replacing the previous multi-step mutable-state handoff with a single transactional operation. Extensive reliability backstops and regress

Fusion-Task-Id: FN-5241
2026-05-20 01:01:08 -07:00
Fusion (runfusion.ai)
b7ddfc9d20 feat(FN-5171): add near-duplicate task guard to CLI create command
Adds a near-duplicate guard to the CLI task creation command (FN-5171), preventing creation of tasks with titles that are visually or semantically identical to existing ones, with 262 new test cases covering the detection logic and the standard changeset entry.

Fusion-Task-Id: FN-5171
2026-05-20 00:41:33 -07:00
Fusion (runfusion.ai)
f4039266e2 fix(FN-5170): use in-process tar extraction for company imports
- Replace host tar invocation in parseCompanyArchive with in-process archive extraction
- Add core regression coverage for parsing archive contents without shell tar behavior
- Add unmocked dashboard route tests covering CLI company archive imports end to end
- Add a changeset for the published @runfusion/fusion package update

Fusion-Task-Id: FN-5170
2026-05-19 23:55:58 -07:00
gsxdsm
e908cbcb42 fix(FN-5291): downgrade file-scope invariant failures 2026-05-19 23:00:11 -07:00
gsxdsm
98033bc869 feat(engine): guard one engine per project per machine
Adds a per-machine singleton lock that engages in
ProjectEngineManager.createAndStart() before any engine subsystems
spin up. Two fn dashboard processes can no longer run engines for the
same project on the same host — previously they would share .fusion/
state and corrupt worktrees / task rows for in-process projects.

The guard combines two independent checks:
  - A proper-lockfile file at <project>/.fusion/engine.lock with
    stale-lock recovery (auto-released on process death).
  - A loopback listener on a hashed per-project address — UDS on
    POSIX, named pipe on Windows. Stale UDS files are probed and
    unlinked before a retry bind.

Failures raise EngineAlreadyRunningError. Both guards are released
from stopAll() and pauseProject(); a release on engine.start()
failure lets retries re-acquire cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 22:50:39 -07:00
gsxdsm
959f7cd4eb chore(release): v0.32.0
Version bump via changesets.
2026-05-19 22:09:26 -07:00
gsxdsm
a164e84b46 fix(core): harden fusion.db pragmas against mid-write crashes
Switch synchronous from NORMAL to FULL and restore the default
wal_autocheckpoint of 1000 (was 100). The aggressive checkpoint
cadence + NORMAL fsync left a wide window for torn pages whenever
a writer crashed mid-checkpoint, which is exactly what happened
when node:sqlite SIGSEGV'd inside pager_write and corrupted the
production db.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 22:05:36 -07:00
gsxdsm
c4745caec0 fix(dashboard): grow main chat composer height as message grows
Reorders ChatView's input handler to resize the textarea before the
controlled setMessageInput call (matching QuickChat) so the height
assignment lands in the same frame as the keystroke and isn't lost to
React 18 batching. Also adds a 40px floor to clampChatInputHeight so a
0-scrollHeight measurement can't collapse the composer to zero.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 21:17:44 -07:00
Fusion (runfusion.ai)
6b24b56b81 feat(FN-5242): add merge queue storage and lease API to task store
- docs(FN-5242): complete Step 7 — document merge queue storage
- docs(FN-5242): complete Step 5 — add changeset and exports
- fix(FN-5242): order merge queue audit assertions chronologically
- test(FN-5242): complete Step 4 — cover merge queue leasing
- feat(FN-5242): complete Step 2 — add merge queue lease API
- feat(FN-5242): complete Step 1 — add mergeQueue schema v89

Fusion-Task-Id: FN-5242
2026-05-19 21:14:49 -07:00
Fusion (runfusion.ai)
17eb85ed81 feat(FN-5266): add metadata-driven pre-commit identity guard
Implements metadata-driven pre-commit identity guard hooks in the worktree layer, replacing static hook bodies with configurable metadata; adds regression tests covering shared-hook worktrees and the metadata-driven lock behavior.

Fusion-Task-Id: FN-5266
2026-05-19 21:08:21 -07:00
Fusion (runfusion.ai)
b078a8135e feat(FN-5232): add deterministic verification-followup deduplication to pre
Implements deterministic followup deduplication for the project engine, routing eval and PR followups through a new `verification-followup-dedup` helper that excludes the parent task to prevent self-referential loops, with tests covering eval-followups, merge-error-recovery, PR comments, and the new

Fusion-Task-Id: FN-5232
2026-05-19 19:28:05 -07:00
gsxdsm
2d42476dac fix(dashboard): fire github tracking on duplicate and refine routes
The duplicate and refine task routes returned without invoking
createTrackingIssueForTask, depending on TaskStore's internal
task-created hook to do it. That works in production with a real
TaskStore but leaves no path through mocked test stores — which is why
routes-tasks-ops's duplicate/refine tests expecting createIssue calls
were failing.

Call createTrackingIssueForTask explicitly after duplicateTask and
refineTask, in a best-effort try/catch so a tracking failure can't
block the response. Mirrors the existing PATCH /tasks/:id flow.

Also wire registerGithubTrackingHook with a test logger in
routes-planning-tracking.test.ts and have the mock store fire the hook
after createTask so the planning create-task flow's expectations land.

Fix the two PATCH tests in routes-tasks-ops that mocked getTask to
already return a linked issue — using mockResolvedValueOnce for the
pre-creation state and mockResolvedValue for the post-creation state
so createTrackingIssueForTask sees the unlinked task first.

Fixes 9 failing tests across routes-tasks-ops.test.ts (6) and
routes-planning-tracking.test.ts (3).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 18:52:36 -07:00
Fusion (runfusion.ai)
7dafde4c43 feat(FN-5188): complete Step 6 — document bootstrap guard
Fusion-Task-Id: FN-5188
Fusion-Task-Lineage: 6d238ff1-2d69-44e7-8694-ec19e412f8ef
2026-05-19 17:27:21 -07:00