Commit Graph

614 Commits

Author SHA1 Message Date
gsxdsm
b2dce7d852 Recovery: Re-land (Close source-imported GitHub issues on ta 2026-05-28 19:49:31 -07:00
gsxdsm
2b66825fc1 test(core): force deterministic fs.watch failure with NUL-byte path
Prior attempt accepted either fs.watch failure path (sync throw vs async
error event) — but on Linux Node, fs.watch with `recursive: true` on a
missing directory silently succeeds (returns a no-op watcher, never
throws, never emits an error). Neither catch arm fires, so the warning
the test wants to assert never appears.

Switch to a NUL-byte-embedded path. Node validates the path argument up
front and throws ERR_INVALID_ARG_VALUE synchronously on every platform,
guaranteeing the `watch:fs-watch-setup` catch arm runs. Restore the
strict assertions on phase + message.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 10:46:21 -07:00
gsxdsm
2a3535893b feat(FN-5622): add goals REST API with store accessor and route handlers
Introduces a Goals REST API (`GET/POST/PUT /api/goals` and `GET/PUT /api/goals/:id`) backed by a new `@fusion/core` goal store and typed goal types, including comprehensive route and store test coverage. Documentation on architecture and storage is updated to reflect the new domain, and a changeset

Fusion-Task-Id: FN-5622

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5622
2026-05-28 10:32:16 -07:00
gsxdsm
8c0a75f50e test(core): accept either fs.watch failure path on Linux and macOS
`store-activity.test.ts > "logs fs.watch setup failures and keeps polling
active"` flakes on Linux CI: it sets `tasksDir` to a non-existent path
and expects `fs.watch` to throw synchronously (routed to
`watch:fs-watch-setup`). macOS Node does throw, but Linux Node returns a
watcher that emits an async `error` event instead (routed to
`watch:fs-watch-error`). The contract this test guards is "log the
failure and keep polling alive" — not which catch arm handled it.

Match either warning message + phase, and use `vi.waitFor` so the async
Linux path isn't raced by the spy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 10:03:29 -07:00
gsxdsm
d767e2ecbd feat(FN-5601): add OpenAI Responses API type support to custom providers
Added OpenAI Responses API as a new custom provider type, wiring `apiType: "responses"` through the core registry, engine routes, and dashboard UI with a dropdown selector; includes test coverage across the registry, routes, and component layers.

Fusion-Task-Id: FN-5601

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5601
2026-05-27 21:31:12 -07:00
gsxdsm
699556d5a0 Merge pull request #1106 from titosemi/fix/inbox-user-alias-normalization
fix(core): normalize bare "user" id to dashboard alias in inbox routing
2026-05-27 16:30:04 -07:00
Josemi Liebana
dd6c361083 fix(core): normalize bare "user" id to dashboard alias in inbox routing
Messages sent with to_id="user" (the natural alias agents use) were
silently dropped from getInbox() due to two gaps:

WRITE PATH (types.ts): normalizeMessageParticipant did not include "user"
in DASHBOARD_USER_ALIASES, so messages were stored with toId="user"
instead of toId="dashboard".

READ PATH (message-store.ts): getParticipantIdsForLookup did not include
"user" in the IN-clause for the dashboard mailbox lookup, so messages
already stored with toId="user" (from old sessions) were never returned.

Both paths now include "user" as a canonical alias for DASHBOARD_USER_ID.

Tests:
- normalizeMessageParticipant("user","user") -> {id:"dashboard",type:"user"}
- getInbox("dashboard","user") returns messages stored with toId="user"
  (legacy case: inserted directly into DB without normalization)
2026-05-27 18:47:52 +02:00
Josemi Liebana
d7e4cf7f94 fix(test): update useChat tests for order=desc and before-cursor pagination 2026-05-27 15:24:31 +02:00
Josemi Liebana
6e9ab0e989 feat(dashboard): load latest messages first with order=desc pagination
- Add order?: 'asc' | 'desc' to ChatMessagesFilter (core)
- Route handler passes order param from query string
- Initial load requests order=desc and reverses for display
- loadMoreMessages uses before cursor instead of offset
- hasMoreMessages starts false (prevents IntersectionObserver race)
- ChatView IntersectionObserver guards against messagesLoading
2026-05-27 11:57:21 +02:00
gsxdsm
390bd7f923 perf(dashboard): cache gh CLI checks and defer SQLite integrity scan
Cold-start dashboard responsiveness went from ~99s to ~6-11s. CPU profiling
identified two synchronous-spawn hotspots blocking the event loop:

- `GitHubTrackingReconciler` scanned up to 200 done tasks per startup,
  each call into `getIssue` invoking `isGhAvailable()` + `isGhAuthenticated()`
  via `execFileSync`. `gh auth status` makes a network roundtrip, so 400
  sync spawns ≈ 71s of pure event-loop blocking (69% of cold-start CPU).
  Memoized both checks with a 60s TTL; `resetGhAvailabilityCache()` is
  exported for login/logout flows that need immediate invalidation.

- `PRAGMA integrity_check(100)` walks every page of the SQLite file (~7s
  per database, multiple DBs × projects). The deferred check was scheduled
  3s after init — right in the responsiveness-critical window. Pushed to
  60s so the user is already interacting before it runs; check itself is
  unchanged.

Also yields the event loop between major InProcessRuntime init phases and
between self-healing recovery steps (34 per project), defers orphan-task
AI agent resumption by 30s (env-overridable, auto-zero under Vitest), and
ships an opt-in `FUSION_TRACE_EL_LAG=/path/to/file` event-loop lag tracer
that diagnosed all of the above.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 23:41:28 -07:00
gsxdsm
5eacd79b43 feat(FN-5584): merge fusion/fn-5584 2026-05-25 15:27:06 -07:00
gsxdsm
9b7e87667b feat(FN-5566): add soft-delete cleanup sweep for blocker residue
Added soft-delete reliability sweeps and guardrails to prevent blocker residue from persisting across delete operations, including column drift detection, deleted row sweep guards, and in-progress delete reconciliation, with comprehensive test coverage and documentation updates to the soft-delete ve

Fusion-Task-Id: FN-5566

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5566
2026-05-23 21:54:07 -07:00
gsxdsm
41727cd3bb feat(FN-5577): add github-tracking reconciler for deleted archived tasks
Added GitHub tracking reconciliation to sync hidden and deleted archived tasks on engine startup, spanning a new reconcile task listing method in the core store, a reconciler pass in the dashboard, and comprehensive test coverage for both the store listing and the deleted-archived reconciliation log

Fusion-Task-Id: FN-5577

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5577
2026-05-23 21:19:44 -07:00
gsxdsm
408e20bdc6 fix(merger): prevent tasks landing in Done with no commit on main
Two root-cause fixes for the "fake done" patterns surfaced while debugging
FN-5475's stuck preflight (it depended on FN-5233, which the board reported
as Done but whose squash had stranded on a sibling fusion/fn-* branch).

1. resolveTaskMergeTarget rejects fusion/fn-* sibling branches as a merge
   destination — when a task's baseBranch was inherited from a sibling/dependent
   dispatch, the merger detached onto and squashed against that branch instead
   of advancing main. New audit event surfaces the steering miss so the
   underlying baseBranch-propagation bug stays observable.

2. self-healing findLandedTaskCommit verifies ownership against each grep
   candidate's body before attribution. The previous code blindly accepted the
   first hit of `git log --grep=FN-XXXX` (which matches the entire commit
   message); FN-5441 and FN-5446 were both marked done against an unrelated
   FN-5483 commit whose body merely mentioned them in prose. commitOwnedByTask
   is also tightened: trailers must be line-anchored and the subject fallback
   must match conventional-commit form, not a bare substring.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 17:16:45 -07:00
Fusion (runfusion.ai)
2d2e5b809f feat(FN-5233): add tombstone recreate guard and allow-resurrection delete f
Implements the FN-5233 tombstone system for soft-delete resurrection: a configurable `tombstoneWindowSeconds` deduplicates recreation of recently deleted tasks, with an `allowResurrection` flag that permits explicit resurrect-on-recreate, tombstone recreate guards in the store layer, and cleanup of

Fusion-Task-Id: FN-5233
2026-05-23 17:07:14 -07:00
gsxdsm
a201f56f09 feat(core): add mergeAdvanceAutoSync project setting
Schema for what the merger should do in other worktrees still checked out
on the integration branch when it advances the branch ref. Modes:
  off          — legacy (user pulls manually)
  ff-only      — fast-forward only when other worktree is clean
  stash-and-ff — Smart Pull pipeline (default)

Threads through DEFAULT_PROJECT_SETTINGS, PROJECT_SETTINGS_KEYS (auto via
Object.keys), the docs settings table, and parity + persistence tests.
Merger consumption lands in the follow-up engine change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 14:19:50 -07:00
gsxdsm
8f5c1f97ad feat(FN-5255): flip directMergeCommitStrategy default from squash to direct
Changes the default merge strategy from squash to direct by flipping `directMergeCommitStrategy` in the settings schema and types, with the core implementation in `merger-ref-update-advance.ts`. Also aligns a heartbeat executor test assertion with the FN-5060 deduplication shape.

Fusion-Task-Id: FN-5255

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5255
2026-05-23 11:08:08 -07:00
gsxdsm
687237bd91 feat(FN-5411): add project identity recovery and identity-aware startup rea
Implements project identity tracking and recovery across the Fusion system (FN-5411), enabling persistent identity for projects across storage migrations, daemon reattaches, and CLI session management. Adds a project identity metadata API and central reattach ensure mechanism, wires identity stampin

Fusion-Task-Id: FN-5411

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5411
2026-05-23 04:18:55 -07:00
gsxdsm
4d1cad027c feat(FN-5444): add merge handoff test coverage for task worktree
Adds test coverage for merge queue and heartbeat handoff interactions (FN-5444), including source metadata expectations in heartbeat executor tests, merge handoff coverage gaps, and reuse scenarios in the merger worktree integration tests.

Fusion-Task-Id: FN-5444

Fusion-Task-Lineage: 45e1b43f-8ae3-46ba-a5ee-25e8c661e753

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5444
2026-05-23 03:50:05 -07:00
gsxdsm
51fc826199 fix(engine,core): dedup heartbeat-spawned follow-ups by parent task
Same-agent intake guard now also matches siblings sharing a
sourceParentTaskId, so repeated heartbeats from one parent task
can't bypass dedup just because triage rewrites the title.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 03:05:46 -07:00
gsxdsm
2bee6b0824 fix(tests): drop SIGTERM handlers + skip flaky reconciliation test
The SIGTERM/SIGINT/SIGHUP handlers added to db.test.ts and the engine
tmp-dir tests re-raised signals after cleanup, which killed vitest itself
(exit 143) under the full engine reliability suite. Keep `afterAll` +
`beforeExit`/`exit` + lock-child kill — those cover the macOS file-handle
leak that was the actual driver of the merge-verification cascade.

Also skip project-engine-manager `retries failed project starts on
subsequent reconciliation ticks` — flake under full-suite load (30s
timeout) that passes in ~46ms standalone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 00:22:19 -07:00
gsxdsm
d3ad0641c4 feat(FN-5486): merge fusion/fn-5486 2026-05-22 23:42:44 -07:00
gsxdsm
380f8b8e5e fix(core-tests): plug kb-db-test-* leaks on SIGTERM fork recycle
Vitest's forks pool SIGTERMs a fork when a test times out, which skips
`beforeExit`/`exit` handlers and leaves `kb-db-test-*` dirs behind.
`holdWriteLock` child processes also kept WAL/SHM handles open, blocking
recursive removal on macOS. Both paths now run cleanup: SIGTERM/SIGINT/
SIGHUP handlers sweep tracked dirs and re-raise the signal, and active
lock-helper children are tracked and SIGKILLed during cleanup so the
parent dir can be removed.

These leaks tripped scripts/check-test-isolation.mjs during deterministic
merge verification, failing auto-merge with "Completion handoff limbo
recovery exhausted" (e.g. FN-5521, FN-5486).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 23:27:44 -07:00
gsxdsm
2a3a07a612 feat(FN-5403): merge fusion/fn-5403 2026-05-22 23:12:49 -07:00
gsxdsm
3a6a4ece6a feat(FN-5432): merge fusion/fn-5432 2026-05-22 16:09:43 -07:00
Fusion (runfusion.ai)
c3890a9b43 feat(FN-5496): reconcile soft-deleted tasks with active blockers
Added soft-delete blocker recovery logic to the scheduler and self-healing systems, enabling reconciliation of stale blocker reasons when tasks are archived or restored. The changes include corresponding tests for the completion guard behavior, scheduler recovery paths, and self-healing integration,

Fusion-Task-Id: FN-5496
2026-05-22 10:58:44 -07:00
gsxdsm
16b18bf338 chore(dashboard): publish MobileNavBar render decision to vpdebug
Surface the live mode / modalOpen / keyboardOpen / footerVisible / view
values that MobileNavBar uses for its early-return so the ?vpdebug overlay
can show which one is hiding the bar on Android. Also dumps the
.project-content className so we can correlate with `--with-mobile-nav`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 09:37:23 -07:00
Fusion (runfusion.ai)
4b484fd818 feat(FN-5485): clear userPaused state on manual retry reset with regression
Adds retry-reset logic that clears the user-paused flag on tasks, ensuring they can resume automatically after a retry is triggered, with regression tests covering the behavior across the CLI extension and core manual-reset module.

Fusion-Task-Id: FN-5485
2026-05-22 08:23:45 -07:00
gsxdsm
3a0d179ba2 Fn-5196 2026-05-22 04:09:22 -07:00
Fusion (runfusion.ai)
9a09498397 feat(FN-5196): return 410 Gone for hard-archived task deletions
Implement the hard-archived delete contract: add a typed `ArchivedTaskDeleteError`, map hard-archived task deletes to HTTP 410 Gone at both the store and routes layers, and document the invariant in the soft-delete verification matrix.

Fusion-Task-Id: FN-5196
2026-05-22 02:04:42 -07:00
Fusion (runfusion.ai)
9c2b61eec6 feat(FN-5204): add test mode activation across settings, engine, and dashboard
- Add core settings schema/types support for testMode with model-resolution override handling
- Enforce engine session lane overrides in test mode with targeted helper coverage
- Add dashboard settings toggle plus persistent test-mode banner and related component tests
- Update settings documentation and parity/roundtrip tests for the new test mode behavior
2026-05-22 00:15:14 -07:00
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)
b8147dd3b1 feat(FN-5405): remove broad-scope triage heuristics and UI advisory chips/b
Removes the broad-scope detection feature end-to-end: the TaskCard chip and TaskDetailModal advisory banner are gone from the dashboard, the triage heuristic that flagged tasks as broad-scope has been deleted from the engine along with its associated run-audit events, and documentation references ha

Fusion-Task-Id: FN-5405
2026-05-21 15:07:15 -07:00
gsxdsm
109f969f06 Merge commit '0c2416903f4f7d29fc5933d440a46a9c55f80235' 2026-05-21 13:40:25 -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
9bc5b5f4e9 feat(FN-5443): merge fusion/fn-5443 2026-05-21 13:36:39 -07:00
Fusion (runfusion.ai)
b3f995c857 feat(FN-5348): remove cwd-main integration mode fallback
Removes the `cwd-main` integration fallback mode (FN-5348), eliminating the legacy shortcut path where the merger would operate directly on the project root instead of a dedicated worktree. Steps normalize the `reuse-task-worktree` integration mode as the sole path, wire stricter mode invariants in

Fusion-Task-Id: FN-5348
2026-05-21 12:49:50 -07:00
Fusion (runfusion.ai)
79850b233f feat(FN-5349): add integration branch resolver with auto-recovery fallback
FN-5349 adds a dedicated integration branch resolution module (`packages/engine/src/integration-branch.ts`) replacing ad-hoc dynamic fallbacks, routes merger branch conflict resolution through it, wires auto-recovery handlers (branch-worktree, contamination) to use integration branch fallback, and w

Fusion-Task-Id: FN-5349
2026-05-21 12:04:58 -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
933cea434a feat(FN-5256): merge fusion/fn-5256 2026-05-21 11:06:26 -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
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
Fusion (runfusion.ai)
e12adeb3fa feat(FN-5256): complete Step 2 — enforce cycle checks on writes 2026-05-21 04:15:21 -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
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)
c60045df22 feat(FN-5223): anchor staleness and stall detectors to engine activation ti
The merge introduces an engine-activation timestamp as the staleness floor for task age calculations, replacing arbitrary wall-clock thresholds with a runtime-relative anchor. Step 1 adds settings defaults, Steps 2–4 wire the floor helper through project engine, in-process runtime, and task store hy

Fusion-Task-Id: FN-5223
2026-05-20 14:29:07 -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