Commit Graph

7258 Commits

Author SHA1 Message Date
Fusion (runfusion.ai)
637d5191d3 docs(FN-4820): complete Step 3 — file prioritized follow-up tasks
Fusion-Task-Id: FN-4820
Fusion-Task-Lineage: 8f15714c-4733-4733-8f47-a9b8738b9bcd
2026-05-16 18:51:15 -07:00
Fusion (runfusion.ai)
5b2b50e916 docs(FN-4820): complete Step 2 — author findings document
Fusion-Task-Id: FN-4820
Fusion-Task-Lineage: 8f15714c-4733-4733-8f47-a9b8738b9bcd
2026-05-16 18:51:14 -07:00
Fusion (runfusion.ai)
8405e1fce6 fix(FN-4786): align dashboard activity event typings
Fusion-Task-Id: FN-4786
Fusion-Task-Lineage: eb683ec8-8b9d-4e3d-852c-7076224afa6b
2026-05-16 18:40:05 -07:00
Fusion (runfusion.ai)
4863e3be8f feat(FN-4786): complete Step 6 — document planning loading fixes
Fusion-Task-Id: FN-4786
Fusion-Task-Lineage: eb683ec8-8b9d-4e3d-852c-7076224afa6b
2026-05-16 18:40:04 -07:00
Fusion (runfusion.ai)
825e5479f5 test(FN-4786): stabilize cli tmp-dir tests for workspace runs
Fusion-Task-Id: FN-4786
Fusion-Task-Lineage: eb683ec8-8b9d-4e3d-852c-7076224afa6b
2026-05-16 18:40:04 -07:00
Fusion (runfusion.ai)
ec169bf347 test(FN-4786): complete Step 4 — add first-turn loading regressions
Fusion-Task-Id: FN-4786
Fusion-Task-Lineage: eb683ec8-8b9d-4e3d-852c-7076224afa6b
2026-05-16 18:40:04 -07:00
Fusion (runfusion.ai)
560e35708a fix(FN-4786): complete Step 3 — replay first-turn thinking catch-up
Fusion-Task-Id: FN-4786
Fusion-Task-Lineage: eb683ec8-8b9d-4e3d-852c-7076224afa6b
2026-05-16 18:40:03 -07:00
Fusion (runfusion.ai)
84f914884a feat(FN-4786): complete Step 2 — globalize spin utility
Fusion-Task-Id: FN-4786
Fusion-Task-Lineage: eb683ec8-8b9d-4e3d-852c-7076224afa6b
2026-05-16 18:40:03 -07:00
gsxdsm
591e0b9e90 feat(FN-4819): merge fusion/fn-4819 2026-05-16 18:06:12 -07:00
Fusion
a1b1f9aa05 fix(FN-4811): defer self-healing reclaim when worktree has an active session
The reclaimSelfOwnedBranchConflicts sweep was force-pausing actively-running
tasks. Production failure shape on FN-4819:

  1. Self-healing sweep runs every cycle and inspects branch conflicts.
  2. For FN-4819, inspection classified the conflict as 'tip-already-merged'
     (the task's branch tip was already on main).
  3. Sweep called removeWorktree({ reason: SelfHealingBranchConflict }).
  4. The FN-4811 active-session gate correctly refused: the worktree was
     bound to FN-4819/executor (a live agent session was using it).
  5. The thrown ActiveSessionWorktreeRemovalError was caught by the outer
     reclaim catch block.
  6. The catch escalated to AutoRecoveryDispatcher with class
     'branch-conflict-unrecoverable'.
  7. decision.action === 'pause' marked the task failed + paused +
     pausedReason='branch-conflict-unrecoverable' + moved to in-review.

Net effect: the FN-4811 gate (which is correct \u2014 you can't yank a live
worktree) became a regression source because the self-healing sweep
interpreted the refusal as fatal. Tasks that were actively making progress
got paused with a misleading 'branch conflict unrecoverable' error.

Fix: at the top of the per-task reclaim loop in
reclaimSelfOwnedBranchConflicts, check
activeSessionRegistry.isPathActive(task.worktree) and continue for any
task whose worktree is currently bound to a live session. The reclaim
will retry on the next sweep (sweeps run every cycle) once the session
has finished using the worktree. No data is lost, no decision is forced.

Test added under
packages/engine/src/__tests__/reliability-interactions/reclaim-defers-on-active-session.test.ts
covering:
  - The skip path: when activeSessionRegistry has a registration for
    task.worktree, the sweep MUST NOT call inspectBranchConflict,
    removeWorktree, or isUsableTaskWorktree. The task MUST stay in
    in-progress, not be marked failed/paused, not be moved to in-review.
  - Control: with no registration, the sweep DOES proceed and reaches
    inspectBranchConflict (preserving existing behavior).

Full engine suite: 314 files, 5061 tests pass, 1 skipped. Lint clean.
Build clean.

Fusion-Task-Id: FN-4811
2026-05-16 17:59:03 -07:00
Fusion (runfusion.ai)
4691cbe199 fix(FN-4804): sync quick chat session and room selection
- Clear the active chat room when switching Quick Chat to a direct session
- Keep the hidden session dropdown value and initial-session state aligned with room selection changes
- Add dashboard regression coverage for switching from a room back to a direct chat and include a CLI patch changeset

Fusion-Task-Id: FN-4804
2026-05-16 17:47:48 -07:00
Fusion (runfusion.ai)
c3dd34f070 feat(FN-4816): add integration tests for node settings sync API routes
Adds integration tests for node settings sync API routes (`routes-nodes-sync.test.ts`), covering the settings push/pull and sync-status endpoints across the dashboard node management API.

Fusion-Task-Id: FN-4816

Fusion-Task-Lineage: 01f1bec6-f1c3-43bc-8854-5c4739f0e736
2026-05-16 17:44:25 -07:00
Fusion (runfusion.ai)
ae22b3e632 feat(FN-4813): complete Step 5 — add isolation transition runtime restart path
Fusion-Task-Id: FN-4813
Fusion-Task-Lineage: 846893a5-2afa-4817-8f64-8c444d2fd713
2026-05-16 17:34:14 -07:00
Fusion (runfusion.ai)
92b4899ee0 feat(FN-4813): complete Step 4 — wire handoff into scheduler and lease recovery
Fusion-Task-Id: FN-4813
Fusion-Task-Lineage: 846893a5-2afa-4817-8f64-8c444d2fd713
2026-05-16 17:34:12 -07:00
Fusion (runfusion.ai)
b2ca02f743 feat(FN-4813): complete docs, settings, and verification updates
Fusion-Task-Id: FN-4813
Fusion-Task-Lineage: 846893a5-2afa-4817-8f64-8c444d2fd713
2026-05-16 17:31:10 -07:00
Fusion (runfusion.ai)
7a5739faea feat(FN-4813): complete Step 6 — document mutex handoff and runtime scope
Fusion-Task-Id: FN-4813
Fusion-Task-Lineage: 846893a5-2afa-4817-8f64-8c444d2fd713
2026-05-16 17:31:10 -07:00
Fusion (runfusion.ai)
b81bfacf07 fix(FN-4813): avoid isolation transition double-write in project route
Fusion-Task-Id: FN-4813
Fusion-Task-Lineage: 846893a5-2afa-4817-8f64-8c444d2fd713
2026-05-16 17:31:09 -07:00
Fusion (runfusion.ai)
63adddadf9 feat(FN-4813): complete Step 5 — add isolation transition runtime restart path
Fusion-Task-Id: FN-4813
Fusion-Task-Lineage: 846893a5-2afa-4817-8f64-8c444d2fd713
2026-05-16 17:31:09 -07:00
Fusion (runfusion.ai)
2ca18e983a feat(FN-4813): complete Step 4 — wire handoff into scheduler and lease recovery
Fusion-Task-Id: FN-4813
Fusion-Task-Lineage: 846893a5-2afa-4817-8f64-8c444d2fd713
2026-05-16 17:31:09 -07:00
Fusion (runfusion.ai)
76ac6597cb fix(FN-4813): export handoff policy types from core barrel
Fusion-Task-Id: FN-4813
Fusion-Task-Lineage: 846893a5-2afa-4817-8f64-8c444d2fd713
2026-05-16 17:31:09 -07:00
Fusion (runfusion.ai)
2ff19bc9c9 feat(FN-4813): complete Step 3 — add owning-node handoff policy
Fusion-Task-Id: FN-4813
Fusion-Task-Lineage: 846893a5-2afa-4817-8f64-8c444d2fd713
2026-05-16 17:31:09 -07:00
Fusion (runfusion.ai)
735c8f413b feat(FN-4813): complete Step 2 — add distributed claim mutex tests
Fusion-Task-Id: FN-4813
Fusion-Task-Lineage: 846893a5-2afa-4817-8f64-8c444d2fd713
2026-05-16 17:31:09 -07:00
Fusion
86237c9a50 fix(FN-4811): unblock @fusion/engine typecheck so verification bootstrap can run
Symptom found while investigating 'tasks are still struggling': every
in-review task hitting pre-merge deterministic verification failed with

  [verification:bootstrap] bootstrap preamble failed (exit 2):
  [test-bootstrap] FAILED: workspace dist artifact rebuild did not complete.
  [test-bootstrap] command: pnpm --filter @fusion/engine build

Because pnpm --filter @fusion/engine build hit 17 TS errors from a prior
autonomous-agent refactor introducing a RemovalReason enum-like object
and two new audit event types. The bootstrap preamble is run by the
merger before every direct-merge verification, so a broken engine
typecheck blocked EVERY task from merging.

Fixes:

1. Duplicate RemovalReason re-export in worktree-pool.ts

   Both  and
    were present for the same identifier,
   producing TS2300 'Duplicate identifier'. RemovalReason is a const
   object with derived type (typeof-keyof pattern), so a single value
   export covers both kinds; the type-only re-export was redundant.

2. GitMutationType union missing the FN-4811 audit event types

   merger.ts and worktree-backend.ts were emitting
   'worktree:removal-refused-active-session' and
   'worktree:removal-forced-over-active-session' audit events, but the
   union in run-audit.ts didn't include them. Added both.

3. self-healing.test.ts vi.mock had wrong RemovalReason keys

   The mock only exposed 5 keys (SelfHealing*) but production code
   references HardCancel, Executor*, Merger*, PoolPrune, etc. Calls
   like removeWorktree({ reason: RemovalReason.MergerPostMerge }) were
   getting reason=undefined, producing confusing 'cannot remove
   worktree: [vitest] No RemovalReason export is defined on mock'
   error messages. Updated the mock to mirror the production const
   exactly.

4. worktree-backend.test.ts removeWorktree calls missing required reason

   The new contract makes reason: RemovalReason a required field on
   removeWorktree's input. Five existing test cases were missing it;
   added reason: RemovalReason.MergerCleanup to each.

5. integrity-warning-persisted-dedup.test.ts Settings cast

   The test's makeStore helper cast a partial settings object to
   Settings; TS rejected the narrowed type. Cast through unknown.

Verification:

  - pnpm --filter @fusion/engine build: clean
  - pnpm lint: clean
  - pnpm build (full workspace): clean
  - pnpm --filter @fusion/engine test: 5045 pass, 1 pre-existing
    aiMergeTask real-git timeout flake, 1 skipped

With this fix, the verification bootstrap can complete and the merger
can finalize tasks again.

Fusion-Task-Id: FN-4811
2026-05-16 17:23:15 -07:00
Fusion (runfusion.ai)
be9baad3bb fix(FN-4807): unblock engine build with typed liveness mocks
Fusion-Task-Id: FN-4807
Fusion-Task-Lineage: 3f03bd51-71c3-43c4-abe0-f636edeaf52b
2026-05-16 17:08:09 -07:00
Fusion (runfusion.ai)
52ab8a312f test(FN-4807): complete Step 4 — harden autostash suite timeout and cleanup
Fusion-Task-Id: FN-4807
Fusion-Task-Lineage: 3f03bd51-71c3-43c4-abe0-f636edeaf52b
2026-05-16 17:08:09 -07:00
Fusion (runfusion.ai)
a3ff539619 test(FN-4807): complete Step 3 — bound FN-3936 replay timeout
Fusion-Task-Id: FN-4807
Fusion-Task-Lineage: 3f03bd51-71c3-43c4-abe0-f636edeaf52b
2026-05-16 17:08:09 -07:00
Fusion (runfusion.ai)
8fd47b619f feat(FN-4811): complete Step 3 — update removeWorktree call sites
Fusion-Task-Id: FN-4811
Fusion-Task-Lineage: f3dac123-cb46-4d31-8a7e-dfc664bfdc5f
2026-05-16 16:55:04 -07:00
Fusion (runfusion.ai)
7a438f63ee fix(FN-4811): repair step-session registry wiring recursion
Fusion-Task-Id: FN-4811
Fusion-Task-Lineage: f3dac123-cb46-4d31-8a7e-dfc664bfdc5f
2026-05-16 16:55:03 -07:00
Fusion (runfusion.ai)
69d7b282cf feat(FN-4811): complete Step 1 — add active session registry wiring
Fusion-Task-Id: FN-4811
Fusion-Task-Lineage: f3dac123-cb46-4d31-8a7e-dfc664bfdc5f
2026-05-16 16:55:01 -07:00
Fusion
f4aa6d7b8b fix(FN-4811): persist done-task integrity warnings across engine restarts
The periodic self-healing sweep at
SelfHealingManager.reconcileDoneTaskIntegrity() emits a single
'Integrity warning: done-task finalize evidence is unproven (<reason>)' log
entry per task when the task is in 'done' but has no provable on-main
evidence. Dedup was via an in-memory finalizeUnprovenWarned Set per manager
instance, so every engine restart resurfaced the same warning on the next
sweep — significant noise on done tasks that legitimately lack evidence,
typically residue of FN-4811 contamination (FN-4771/FN-4778 in production).

Adds an optional MergeDetails.integrityWarning = { warnedAt, reason } field
and persists it on the first warning. Both warning sites in
reconcileDoneTaskIntegrity() (the unproven-and-still-mergeable branch and
the unproven-final branch) now consult the persisted record:

  - Same reason as persisted → skip re-emitting, just rehydrate the in-memory
    Set for in-process consistency.
  - Different reason → re-warn (so a *new* classification problem still
    surfaces) and update the persisted record.

Tests added under
packages/engine/src/__tests__/reliability-interactions/integrity-warning-persisted-dedup.test.ts
(real-git, 4 cases):

  - First sweep: emits warning + persists record.
  - Second sweep, same instance: in-memory Set dedupes (existing contract).
  - Fresh manager (simulated engine restart) + pre-persisted record:
    persisted dedup suppresses re-emission.
  - Fresh manager + persisted record with different reason: must re-warn
    and overwrite the persisted reason.

Full engine suite: 308 files, 5041 tests pass, 1 skipped. Lint clean.

Fusion-Task-Id: FN-4811
2026-05-16 16:51:43 -07:00
Fusion (runfusion.ai)
ba8e912aa8 test(FN-4809): complete Step 3 — cover merge attempt audit emission
Fusion-Task-Id: FN-4809
Fusion-Task-Lineage: bd632e33-b376-47de-ad99-da4610ae4690
2026-05-16 16:50:17 -07:00
Fusion (runfusion.ai)
42b8eebc8e feat(FN-4809): complete Step 3 — add changeset for merge attempt audit coverage
Fusion-Task-Id: FN-4809
Fusion-Task-Lineage: bd632e33-b376-47de-ad99-da4610ae4690
2026-05-16 16:50:16 -07:00
Fusion (runfusion.ai)
d898801ec3 test(FN-4809): complete Step 2 — cover merge attempt audit emission
Fusion-Task-Id: FN-4809
Fusion-Task-Lineage: bd632e33-b376-47de-ad99-da4610ae4690
2026-05-16 16:50:16 -07:00
Fusion (runfusion.ai)
df76612d78 feat(FN-4809): complete Step 1 — emit merge attempt audit events
Fusion-Task-Id: FN-4809
Fusion-Task-Lineage: bd632e33-b376-47de-ad99-da4610ae4690
2026-05-16 16:50:15 -07:00
Fusion (runfusion.ai)
4e5bcee14f feat(FN-4809): complete Step 2 — emit merge attempt audit events
Fusion-Task-Id: FN-4809
Fusion-Task-Lineage: bd632e33-b376-47de-ad99-da4610ae4690
2026-05-16 16:50:15 -07:00
Fusion
dcd6bf60f3 fix(FN-4811): recover from validation-failed remove + collapse broken FN-4806 nested branches
Two follow-ups stacked on the FN-4811 active-worktree liveness gate:

1. Stale conflict-path recovery (FN-4813 production failure)

   When 'git worktree remove --force' fails with 'fatal: validation failed,
   cannot remove working tree', the worktree directory is missing on disk
   and the git admin entry is stale. Without this recovery, every retry of
   tryCreateWorktree on a stale conflict path failed 3 times with
   'automatic cleanup failed', leaving tasks unable to create worktrees.

   cleanupConflictingWorktree now catches that specific error class, runs
   'git worktree prune' to drop the stale admin entry, best-effort deletes
   the branch, and returns success so the caller can proceed.

   Implementation note: the original attempt used existsSync(worktreePath)
   as a pre-check, but vitest's vi.clearAllMocks() can leave the existsSync
   mock returning undefined, causing the new branch to fire inside tests
   that didn't expect it and leading to worker OOM in
   executor-worktree.test.ts. The error-class-based catch is robust against
   mock state and matches the real production failure signal exactly.

2. Collapsed broken FN-4806 nested branches

   The previous FN-4806 refactor (commit 087b1a766) accidentally nested the
   genuine 'agent finished without calling fn_task_done after N retries'
   failure path INSIDE the silent-recovery branch, meaning ordinary
   failures were being silently requeued (no status=failed, no onError, no
   retry-budget burn) instead of being surfaced.

   Restored the clean two-branch structure:

     } else if (retryAbortedDueToReclaim) {
       // silent recovery (FN-4806)
     } else {
       // genuine no-fn_task_done exhaustion: mark failed, onError, burn budget
     }

   Also clears baseCommitSha on silent recovery (matches the parallel
   session-start-failure path's metadata clearing).

Tests:

  - Adds 'FN-4811 follow-up (FN-4813): recovers from validation failed'
    case to active-worktree-removal-liveness.test.ts (12 total cases).
  - executor-recovery.test.ts no-fn_task_done reclaim coverage now
    asserts baseCommitSha is cleared.
  - executor-recovery.test.ts 'does not mark task as failed when invalid
    transition error occurs on completion' regression fixed by restoring
    the failure-path branch.
  - executor-core.test.ts 'still enforces fn_task_done requirement in
    fast mode' restored.

Full engine suite: 307 files, 5037 tests pass, 1 skipped. Lint clean.

Fusion-Task-Id: FN-4811
2026-05-16 16:25:28 -07:00
gsxdsm
4180816e01 feat(FN-4805): merge fusion/fn-4805 2026-05-16 16:03:09 -07:00
gsxdsm
2f2fdd5e42 feat(FN-4803): merge fusion/fn-4803 2026-05-16 16:02:43 -07:00
Fusion (runfusion.ai)
7310642b68 test(FN-4806): add reclaim retry coverage and changeset
Fusion-Task-Id: FN-4806
Fusion-Task-Lineage: 4192226a-b24c-4681-b0fa-ce86f40fce64
2026-05-16 16:01:23 -07:00
Fusion (runfusion.ai)
087b1a7668 feat(FN-4806): complete Step 1 — split reclaim retry failure path
Fusion-Task-Id: FN-4806
Fusion-Task-Lineage: 4192226a-b24c-4681-b0fa-ce86f40fce64
2026-05-16 16:01:22 -07:00
Fusion
4c26aa6e91 fix(FN-4811): refuse to force-remove worktrees actively bound to live sessions
The executor's conflict-recovery paths (cleanupConflictingWorktree,
handleBranchConflict, and tryCreateWorktree's live-foreign/stale-resolved
branches) could force-remove a worktree even when it was currently bound
to an active executor session. This caused the FN-4781/FN-4804 cascade:

  - 'Execution blocked: assigned worktree path disappeared mid-task' as
    git deleted the live agent's filesystem out from under it
  - Two parallel runs for the same task alive simultaneously, with the
    second run started in a fresh worktree while the first was still
    holding the old session
  - Cross-task log attribution (an FN-4804 runContext writing to FN-4781)
  - Post-merge 'branch tip misbound but content found on main via trailer'
    rescues firing on every successful merge as the bookkeeping was
    corrupted mid-merge

Adds a hard liveness gate centralized in findActiveWorktreeOwner(), which
checks both the in-memory activeWorktrees map and the DB for non-done,
non-paused, in-progress tasks bound to the worktree. The gate fires at
two points:

  1. cleanupConflictingWorktree returns false (refuses removal) when an
     active owner is found, logging an FN-4811 refusal entry.
  2. handleBranchConflict short-circuits to 'sticky' BEFORE invoking
     inspectBranchConflict, because some inspection branches force-remove
     unconditionally.

When cleanup is refused, the live-foreign and stale-resolved branches in
tryCreateWorktree now FALL THROUGH to the suffix-rename path (rather
than returning null) so the requesting task can still proceed without
disturbing the live owner.

Tests:

  - New reliability-interactions backstop at
    src/__tests__/reliability-interactions/active-worktree-removal-liveness.test.ts
    covers findActiveWorktreeOwner (5 cases: in-memory match, requesting
    task excluded, DB-level match, paused exclusion, terminal-column
    exclusion, self-exclusion), cleanupConflictingWorktree gate (3 cases:
    in-memory refuse, DB refuse, no-owner proceed), and handleBranchConflict
    gate (2 cases: short-circuit + inspection-skipped, no-owner proceeds).
  - Updates existing executor-worktree.test.ts assertion that was
    documenting the bug behavior (force-removing active worktree) to match
    the new contract (refuses + falls through to suffix-rename).

Full engine suite: 307 files, 5035 tests pass.

Fusion-Task-Id: FN-4811
2026-05-16 15:36:07 -07:00
Fusion
3f8a5e6839 fix(FN-4806): silently recover when worktree/branch reclaimed mid-retry
The executor's no-fn_task_done retry loop has two reclaim signals
(retryAbortedDueToReclaim=true): (1) pre-retry liveness recheck where the
task DB shows worktree/branch was cleared, and (2) session-start failure
because the worktree path no longer exists. Both are engine self-heal
situations triggered by FN-4546 stale-active-branch reclaim, FN-4742
self-healing removals, or related housekeeping paths — the agent never
got a fair retry attempt.

Previously these surfaced as task status=failed with error
'Worktree/branch reclaimed during no-fn_task_done retry — requeueing',
fired onError, and burned the taskDoneRetryCount budget. Three legitimate
problems followed: tasks accumulated spurious failures in the UI, the
exhausted-budget branch escalated reclaimed tasks to in-review instead of
retrying, and the noise masked the underlying worktree-removal regression
(FN-4811).

Now the reclaim branch silently:
- clears stale worktree/branch metadata so the next pickup creates a fresh worktree
- requeues to todo with preserveProgress
- logs an informational 'engine self-heal, no failure' line
- does NOT set status=failed, does NOT bump taskDoneRetryCount, does NOT call onError

The genuine 'agent finished without calling fn_task_done after N retries'
exhaustion path (retryAbortedDueToReclaim=false) is unchanged.

Tests updated in
packages/engine/src/__tests__/reliability-interactions/executor-no-task-done-vs-worktree-reclaim.test.ts
to assert the new silent-recovery contract on all three reclaim paths.

Fusion-Task-Id: FN-4806
2026-05-16 15:16:05 -07:00
Fusion (runfusion.ai)
22dbc4951e test(FN-4788): update schema-version assertions to 83
Fusion-Task-Id: FN-4788
Fusion-Task-Lineage: 8de6c7f4-cf0f-4b1f-b664-4e8533b88919
2026-05-16 15:05:15 -07:00
Fusion (runfusion.ai)
9b7550a3f1 test(FN-4788): complete Step 4 — add secrets schema coverage
Fusion-Task-Id: FN-4788
Fusion-Task-Lineage: 8de6c7f4-cf0f-4b1f-b664-4e8533b88919
2026-05-16 15:05:15 -07:00
Fusion (runfusion.ai)
7f294614b5 feat(FN-4788): complete Step 2 — add central secrets_global schema migration
Fusion-Task-Id: FN-4788
Fusion-Task-Lineage: 8de6c7f4-cf0f-4b1f-b664-4e8533b88919
2026-05-16 15:05:15 -07:00
Fusion (runfusion.ai)
268eec50a9 feat(FN-4788): complete Step 1 — add project secrets schema migration
Fusion-Task-Id: FN-4788
Fusion-Task-Lineage: 8de6c7f4-cf0f-4b1f-b664-4e8533b88919
2026-05-16 15:05:15 -07:00
Fusion (runfusion.ai)
5bb15b1713 test(FN-4803): stabilize cli bundled plugin integration timeout
Fusion-Task-Id: FN-4803
Fusion-Task-Lineage: cbfa10fd-33a6-469c-9cb4-3a647bc47b84
2026-05-16 14:56:56 -07:00
Fusion (runfusion.ai)
246609a415 feat(FN-4803): complete Steps 4-5 — docs update and changeset
Fusion-Task-Id: FN-4803
Fusion-Task-Lineage: cbfa10fd-33a6-469c-9cb4-3a647bc47b84
2026-05-16 14:56:56 -07:00
Fusion (runfusion.ai)
5204177c2b test(FN-4803): complete Step 3 — cover github dedup toggle behavior
Fusion-Task-Id: FN-4803
Fusion-Task-Lineage: cbfa10fd-33a6-469c-9cb4-3a647bc47b84
2026-05-16 14:56:56 -07:00
Fusion (runfusion.ai)
371b1be7f7 feat(FN-4803): complete Step 1 — add dedup toggle in settings modal
Fusion-Task-Id: FN-4803
Fusion-Task-Lineage: cbfa10fd-33a6-469c-9cb4-3a647bc47b84
2026-05-16 14:56:56 -07:00