Commit Graph

9366 Commits

Author SHA1 Message Date
gsxdsm
feb9ffd383 feat(dashboard): add optional-steps authoring panel to the node editor
New WorkflowOptionalStepsPanel (sibling to Fields/Settings) lets authors
add/remove optional steps and set each one's defaultOn, with unknown ids
shown as muted removable rows. Wire optionalSteps state through both load
paths (incl. the fragment path, which also dropped settings), every
flowToIr/serializeGraph call site, and the save handler deps — fixing a
stale-closure that dropped defaultOn edits on save. Extract the shared
phaseBadge helper. Mobile gets an Optional steps tab too.
2026-06-21 00:18:15 -07:00
gsxdsm
4c7bfcf175 feat(dashboard): preserve optionalSteps through flowToIr round-trip
Thread an optionalSteps param through flowToIr (counts as a v2 signal,
re-attached like fields/settings, omitted entirely when empty for byte
identity) and add an optionalStepsOf reader mirroring fieldsOf/settingsOf.
Without this, saving a workflow through the node editor silently dropped
its optional-step declaration.
2026-06-21 00:05:13 -07:00
gsxdsm
d4e91d4597 feat(core): add workflow-step seam + browser-verification optional step to stepwise workflow
The stepwise-coding IR had no workflow-step seam node, so a per-task
enabledWorkflowSteps entry (e.g. browser verification) would never execute.
Add the seam node on the success path (steps -> workflow-step -> review,
once post-foreach) and declare browser-verification as an optional step,
matching the coding workflow. Covers the dead-toggle gap with resolver and
engine execution-divergence tests.
2026-06-21 00:02:31 -07:00
gsxdsm
2c1cff820b Merge pull request #1695 from Runfusion/fix/full-suite-engine-core-hang
fix(ci): raise shard watchdog floor to 15min to stop Full Suite false-kills
2026-06-20 22:01:03 -07:00
gsxdsm
9af9bf4fd9 docs(plans): add Full Suite engine/core watchdog-budget fix plan 2026-06-20 21:54:10 -07:00
gsxdsm
fdccca9d27 fix(review): apply autofix feedback
- Reformat shard-floor justification as an FNXC:TestInfrastructure comment
  (project-standards: AGENTS.md FNXC_LOG convention).
- Clarify that the shard and dashboard-lane 15min floors are not coupled and
  may diverge (maintainability: avoid implying an unenforced contract).
- Add a regression-guard test pinning shard.floor=15min and asserting a 525s
  derived budget clamps up to the floor, so an accidental revert to the old
  5min floor fails loudly (correctness + testing + project-standards).
2026-06-20 21:53:31 -07:00
gsxdsm
74e056ed99 fix(ci): raise shard watchdog floor to 15min to stop false-kills
The Full Suite (non-blocking) workflow has been red for 30+ runs on main.
Diagnosis: the @fusion/engine [1/2], [2/2] and @fusion/core [2/2] shard
slices were SIGKILLed at their watchdog budgets (405s/405s/338s), not because
they hang but because those budgets are too tight for current wall-clock.

Local baselines (this machine, all pass, exit 0):
  - engine [2/2]: 145s wall / 309 files
  - core   [2/2]: 283s wall / 172 files  (old budget was only 338s!)

deriveBudgetMs tightens the budget to expected*3.5 whenever the committed
scripts/test-timings.json is <30d old. The snapshot (2026-06-03) undercounts
the import- and real-git-subprocess overhead of these heavy slices, so the
'fresh' snapshot produced a too-tight, false-kill budget on slower CI runners
-- the exact failure mode the floor/ceiling band exists to prevent.

Fix (plan KTD-2): raise the shard band floor 5min -> 15min so the heaviest
slices can't be tightened into a false-kill, while a true hang is still bounded
far under the job's 60min ceiling. Mirrors the dashboard-lane heavy-lane floor.
Follow-up: refresh scripts/test-timings.json from a default-branch CI run.
2026-06-20 21:48:14 -07:00
gsxdsm
37c4cfa56e FN-6808: handle AI CLI probe spawn failures
Resolve synchronous AI CLI probe launch failures as unavailable auth states.

- Catch synchronous spawn failures in Claude and Droid probe helpers so fire-and-forget validation paths do not reject.
- Return unavailable/unauthenticated sentinels for Droid model discovery and CLI presence/auth checks.
- Add regression coverage for Claude and Droid presence/auth probes plus a patch changeset.

Files changed:
 .../fn-6808-cli-probe-unhandled-rejection.md       |  5 ++++
 .../src/__tests__/process-manager.test.ts          | 25 ++++++++++++++++++++
 .../src/__tests__/process-manager.test.ts          | 25 ++++++++++++++++++++
 packages/pi-claude-cli/src/process-manager.ts      | 12 +++++++++-
 .../src/process-manager.ts                         | 27 +++++++++++++++++++---
 5 files changed, 90 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-6808

Fusion-Task-Lineage: 79702ef2-e116-4313-a557-da17a6888c30
2026-06-20 21:32:43 -07:00
gsxdsm
185ff70d86 FN-6819: keep sidebar settings above footer
Keep the experimental left sidebar Settings control clear of the fixed executor footer while preserving readable project selector fallbacks.

- Share the executor footer visibility state with the left sidebar and project content.
- Reserve executor-footer height on the sidebar when the status footer is visible so Settings stays clickable in expanded and collapsed modes.
- Add project-selector translation fallbacks for incomplete locale fixtures.
- Cover footer-clearance behavior in left sidebar tests and add a patch changeset.

Files changed:
 .changeset/fn-6819-sidebar-footer-clearance.md     |  5 +++
 packages/dashboard/app/App.tsx                     |  8 +++--
 .../dashboard/app/components/LeftSidebarNav.css    |  9 ++++++
 .../dashboard/app/components/LeftSidebarNav.tsx    |  4 ++-
 .../dashboard/app/components/ProjectSelector.css   |  2 +-
 .../dashboard/app/components/ProjectSelector.tsx   | 11 +++++--
 .../components/__tests__/LeftSidebarNav.test.tsx   | 36 ++++++++++++++++++++++
 7 files changed, 67 insertions(+), 8 deletions(-)

Fusion-Task-Id: FN-6819

Fusion-Task-Lineage: 950da852-8dcf-4379-a91b-0188b12d1a6c
2026-06-20 21:23:17 -07:00
gsxdsm
3c6db08270 FN-6805: color workflow counts by column
Align workflow switcher status count badges with their board column colors.

- Map Todo, In Progress, and Done workflow count badge text to the matching board column CSS tokens.
- Cover the badge color contract with a CSS fixture regression test.
- Document the color-token behavior for board and list workflow dropdown counts.

Files changed:
 docs/dashboard-guide.md                            |  2 +-
 .../dashboard/app/components/WorkflowSwitcher.css  | 10 +++++++---
 .../components/__tests__/WorkflowSwitcher.test.tsx | 22 ++++++++++++++++++++++
 3 files changed, 30 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-6805

Fusion-Task-Lineage: aab7140c-ad37-4bd8-b73d-199534285b37
2026-06-20 21:16:16 -07:00
gsxdsm
c766bc9c95 FN-6811: keep terminal symbols out of xterm metrics
Keep terminal symbol fonts scoped away from xterm's measured text stacks across modal and session surfaces.

- add a scoped symbols @font-face to the session terminal CSS chunk
- defensively strip the symbols font from resolved xterm font-family presets
- expand modal, session, and CSS regression tests for symbols-free measurement and scoped glyph fallback
- document recurrence #6 and the remaining real-device iOS Safari verification gap

Files changed:
 .../xterm-symbols-nerd-font-unicode-range.md       | 13 ++++--
 .../dashboard/app/__tests__/terminal-input.test.ts | 51 ++++++++++++++++++----
 .../dashboard/app/components/SessionTerminal.css   | 11 +++++
 .../dashboard/app/components/TerminalModal.css     |  3 ++
 .../components/__tests__/SessionTerminal.test.tsx  |  3 ++
 .../components/__tests__/TerminalModal.test.tsx    | 47 ++++++++++++++++++--
 .../dashboard/app/utils/terminalPreferences.ts     | 17 ++++++--
 7 files changed, 127 insertions(+), 18 deletions(-)

Fusion-Task-Id: FN-6811

Fusion-Task-Lineage: 15a6fc1f-34c6-44d4-b9ea-8b5b3baae267
2026-06-20 21:02:51 -07:00
gsxdsm
5d9162e138 FN-6806: show workflow counts only when expanded
Keep workflow dropdown triggers compact until the menu opens.

- Hide Todo, In Progress, and Done count badges from the collapsed workflow switcher trigger.
- Preserve active-workflow and option counts while the dropdown is expanded for comparison.
- Update Board, List, switcher tests, and dashboard docs for the expanded-only count behavior.

Files changed:
 docs/dashboard-guide.md                            |  2 +-
 .../dashboard/app/components/WorkflowSwitcher.tsx  |  8 +++--
 .../app/components/__tests__/Board.test.tsx        |  3 +-
 .../app/components/__tests__/ListView.test.tsx     |  5 ++-
 .../components/__tests__/WorkflowSwitcher.test.tsx | 36 +++++++++++++++++-----
 5 files changed, 41 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-6806

Fusion-Task-Lineage: a3c2db33-fe08-4207-9aae-548b292d98bd
2026-06-20 20:36:18 -07:00
gsxdsm
7fa3cf17f6 Merge pull request #1694 from Runfusion/fix/benign-todo-pause-abort-log-noise
Fix benign pause-abort failure notification + task-chat ephemeral agent detection
2026-06-20 20:33:06 -07:00
gsxdsm
2e6cfa22ff Address PR review feedback (#1694)
- TaskChatTab: add FNXC:TaskDetailChat prefix/date to the ephemeral
  active-session comment, matching the file's comment convention.
- useModalManager: clear stale planning/subtask resume-session id (and
  initial plan) when opening a fresh planning/subtask flow, so the modal
  no longer reopens into a prior session.
- boardWorkflowsCache: validate cached workflow item shape (id/name/
  columns) and taskWorkflowIds value types so a malformed cache entry
  can't pass and later crash Board on render.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 20:25:44 -07:00
gsxdsm
7b85fead54 Address code-review findings on pause-abort + task-chat fixes
- Reliability (P3): emit an `Auto-recovered:`-prefixed log on the
  benign-todo stale-failure clear path so NotificationService
  proactively cancels the pending failure timer (recoveredStatus path)
  instead of relying only on the fire-time re-check, which is
  race-contingent when failureNotificationDelayMs is near 0. Scoped to
  the actual-clear path so the common no-failure re-queue isn't
  mislabeled as a recovery.
- Project-standards (P3): add the required yyyy-MM-dd-hh:mm stamp to the
  new FNXC comments (AGENTS.md FNXC_LOG convention).
- Maintainability (P3): extract the scheduler "queued" waiting marker to
  a named SCHEDULER_WAITING_STATUS constant.
- Testing: pin the guard's skip on a clean todo row, assert the
  Auto-recovered log fires on the stale-failure path, and add a
  paused+unassigned in-progress idle case (paused early-return wins over
  the ephemeral active-session path).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 20:07:07 -07:00
gsxdsm
b990872827 Extend ephemeral active-session detection to in-review tasks
Mirror the in-progress fix for in-review: a reviewer/merger runs
ephemerally with no assignedAgentId/checkedOutBy, so an in-review task
in an active review/merge status (reviewing, merging, merging-fix,
fixing) now reads as a live session without an assignment. A null-status
in-review row is awaiting human review, not actively worked, so it stays
assignment-gated and idle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 19:57:14 -07:00
gsxdsm
a2342cadae Fix task chat always showing "no agent is working" in ephemeral mode
isActiveAgentSession required a persistent assignedAgentId/checkedOutBy,
but the scheduler only sets those when ephemeralAgentsEnabled === false
(scheduler.ts:1857). The default is ephemeralAgentsEnabled: true
(settings-schema.ts:351), so an actively-executing in-progress task
never has either field and always read as idle, showing the
"No agent is working on this task right now" hint while an agent was
running. sessionLive only covers live CLI sessions, not ephemeral runs.

Treat assignment as sufficient-but-not-necessary: a non-blocked,
non-"queued" in-progress task is a live agent session on its own.
"queued" (the waiting marker) stays assignment-gated and in-review is
unchanged, so existing FN-6314 idle/active behavior is preserved.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 19:48:09 -07:00
gsxdsm
2d327604ff Clear stale failed status on benign todo pause-abort
A pause/resume abort parked status:"failed" on an earlier non-todo
observation stays dispatchable (scheduler filters on column+paused, not
status, scheduler.ts:1288) and re-enters the FN-6782 benign-todo branch.
That branch logged "benign" but left status:"failed"/error on the row,
so the board kept showing it failed and the deferred failure
notification fired (notification-service fire-time check sees
status==="failed") — contradicting the benign log. recoverPausedAbortFailures
that would clear it is suppressed during global/engine pause
(self-healing.ts:8125), so the failure survived the pause window.

Reconcile the row with the benign reclassification: clear status/error
when the live row carries them, so the board agrees it's benign and the
pending notification is suppressed at dispatch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 19:47:56 -07:00
gsxdsm
c8c76a2d1b FN-6801: float sidebar collapse toggle
Replace the sidebar brand-row collapse control with a floating border toggle.\n\n- Remove the empty sidebar brand shell and keep the collapse control reachable in both expanded and rail modes.\n- Style the collapse button as a floating affordance on the sidebar edge.\n- Cover the missing brand shell, accessible toggle labels, pressed state, and persisted collapsed state in sidebar tests.\n- Update dashboard documentation to describe the border-mounted toggle.\n\nFiles changed:\n docs/dashboard-guide.md                            |  2 +-\n .../dashboard/app/components/LeftSidebarNav.css    | 30 +++++++++++-----------\n .../dashboard/app/components/LeftSidebarNav.tsx    | 28 ++++++++++----------\n .../components/__tests__/LeftSidebarNav.test.tsx   | 27 +++++++++++++++++++\n 4 files changed, 56 insertions(+), 31 deletions(-)

Fusion-Task-Id: FN-6801

Fusion-Task-Lineage: e1384565-c0cc-4564-b556-f5b74a501c41
2026-06-20 19:08:50 -07:00
gsxdsm
36b8950dbe FN-6804: carry workflow selection into planning creates
Planning and subtask creation now preserve the workflow lane chosen from dashboard task entry points.

- Thread optional workflow IDs through quick entry, modal state, planning mode, and subtask breakdown flows.
- Apply supplied or parent-derived workflow IDs when creating planning and breakdown tasks, including validation errors for invalid workflow selections.
- Cover workflow-aware task creation and quick-entry modal handoff with regression tests and document the dashboard behavior.

Files changed:
 .changeset/planning-subtask-workflow-selection.md  |   5 +
 docs/dashboard-guide.md                            |   2 +
 packages/dashboard/app/App.tsx                     |   8 +-
 packages/dashboard/app/api/legacy.ts               |   6 +
 packages/dashboard/app/components/AppModals.tsx    |   2 +
 packages/dashboard/app/components/Board.tsx        |   4 +-
 packages/dashboard/app/components/Column.tsx       |   5 +-
 .../dashboard/app/components/InlineCreateCard.tsx  |  20 ++-
 packages/dashboard/app/components/Lane.tsx         |   4 +-
 packages/dashboard/app/components/ListView.tsx     |   4 +-
 .../dashboard/app/components/PlanningModeModal.tsx |  18 +-
 .../dashboard/app/components/QuickEntryBox.tsx     |  24 ++-
 .../app/components/SubtaskBreakdownModal.tsx       |  20 ++-
 packages/dashboard/app/components/TaskForm.tsx     |   4 +-
 .../components/__tests__/QuickEntryBox.test.tsx    |  34 ++++
 packages/dashboard/app/hooks/useModalManager.ts    |  26 ++-
 .../planning-subtask-create-workflow-route.test.ts | 192 +++++++++++++++++++++
 .../src/routes/register-planning-subtask-routes.ts |  72 ++++++--
 18 files changed, 398 insertions(+), 52 deletions(-)

Fusion-Task-Id: FN-6804
Fusion-Task-Lineage: ca03e666-2dd4-4983-8c84-c5540f5adb0b
2026-06-20 18:04:02 -07:00
gsxdsm
da5fea6e11 FN-6756: add Shadcn color theme variants
Add the Shadcn color family to dashboard theme selection and persisted theme validation.

- Register blue, green, red, purple, pink, orange, yellow, mono, and black Shadcn theme IDs across core and dashboard selectors.
- Add swatches and CSS token blocks for light and dark variants, including bootstrap loading coverage.
- Document the expanded theme count and include a minor changeset for the published CLI package.

Files changed:
 .changeset/shadcn-color-variants.md                |    5 +
 docs/dashboard-guide.md                            |    2 +-
 packages/core/src/types.ts                         |   10 +
 .../dashboard/app/components/ThemeSelector.css     |  126 +++
 packages/dashboard/app/components/themeOptions.ts  |    9 +
 .../dashboard/app/hooks/__tests__/useTheme.test.ts |   41 +
 packages/dashboard/app/index.html                  |    2 +-
 packages/dashboard/app/public/theme-data.css       | 1177 ++++++++++++++++++++
 8 files changed, 1370 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-6756

Fusion-Task-Lineage: 143e717a-9718-419f-a6c5-34305e53c65d
2026-06-20 17:17:32 -07:00
gsxdsm
26bd85d4c5 FN-6800: center mobile nav icons in fixed slots
Normalize mobile bottom navigation icon slots so unread indicators no longer skew perceived spacing.

- Wrap every mobile nav icon in a consistent token-sized slot.
- Keep chat unread dots inside the icon slot instead of protruding past it.
- Extend MobileNavBar tests to assert icon-slot structure and spacing CSS.
- Add a patch changeset for the published Fusion package.

Files changed:
 .changeset/fn-6800-mobile-nav-spacing.md           |  5 ++++
 packages/dashboard/app/components/MobileNavBar.css | 22 ++++++++++++-----
 packages/dashboard/app/components/MobileNavBar.tsx | 28 ++++++++++++++++------
 .../app/components/__tests__/MobileNavBar.test.tsx | 24 ++++++++++++++++++-
 4 files changed, 65 insertions(+), 14 deletions(-)

Fusion-Task-Id: FN-6800

Fusion-Task-Lineage: 66ac21cf-6761-4b2c-b2ae-723998ae2632
2026-06-20 16:33:07 -07:00
gsxdsm
c808177979 FN-6776: prevent workflow board legacy flash
Prevent workflow-enabled board surfaces from flashing the legacy layout during first paint.

- Hydrate Board and ListView workflow metadata from a per-project session cache before async revalidation.
- Gate legacy board/list rendering behind settings and workflow-lane metadata readiness, with neutral skeleton states for cold or empty workflow loads.
- Add regression coverage for no-legacy-flash behavior and cache validation, plus docs and changeset notes.

Files changed:
 .changeset/fn-6776-board-flash.md                  |   5 +
 docs/dashboard-guide.md                            |   1 +
 packages/dashboard/app/App.tsx                     |   4 +
 packages/dashboard/app/components/Board.css        |  69 +++++
 packages/dashboard/app/components/Board.tsx        |  53 +++-
 packages/dashboard/app/components/ListView.css     |  53 ++++
 packages/dashboard/app/components/ListView.tsx     |  52 +++-
 .../__tests__/board-no-legacy-flash.test.tsx       | 326 +++++++++++++++++++++
 .../utils/__tests__/boardWorkflowsCache.test.ts    |  71 +++++
 .../dashboard/app/utils/boardWorkflowsCache.ts     |  49 ++++
 10 files changed, 676 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-6776

Fusion-Task-Lineage: caa8e53f-9b6d-49a6-94ca-b694550b43ef
2026-06-20 15:42:16 -07:00
gsxdsm
08d1f09107 FN-6796: preserve benign in-review pause aborts
Preserve completed in-review tasks when benign pause/resume aborts surface after executor handoff.

- Detect non-user hard-cancel pause aborts on clean completed in-review rows and clear the transient abort marker without moving the task.
- Let self-healing recover persisted safe in-review pause-abort parks in place while keeping hard-cancel, pause, autoMerge:false, terminal merge, and live-execution guards intact.
- Cover executor and self-healing recovery paths with regression tests, document the audit metadata, and add a patch changeset.

Files changed:
 .../fn-6796-pause-resume-in-review-recovery.md     |  5 ++
 AGENTS.md                                          |  1 +
 docs/architecture.md                               |  2 +
 .../engine/src/__tests__/executor-recovery.test.ts | 97 +++++++++++++++++++++-
 .../active-worktree-removal-liveness.test.ts       |  2 +-
 .../self-healing-paused-abort-recovery.test.ts     | 90 +++++++++++++++++++-
 packages/engine/src/executor.ts                    | 35 ++++++++
 packages/engine/src/self-healing.ts                | 38 +++++++--
 8 files changed, 257 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-6796

Fusion-Task-Lineage: d2fe6c6d-c118-4f2f-b19e-58e6f1b29384
2026-06-20 15:11:22 -07:00
gsxdsm
661016c469 Merge pull request #1693 from Runfusion/fix/offload-integrity-check
Offload background integrity_check off the main event loop
2026-06-20 15:03:38 -07:00
gsxdsm
580e72b6a7 Harden background integrity-check offload (PR #1693 review)
Addresses review feedback (Greptile P1/P2, CodeRabbit) on the async
background integrity check. All three issues shared one root cause:
state read/cleared from a pre-await snapshot across the async boundary.

- Closed-instance race (P1): runBackgroundIntegrityCheck guards `this.closed`
  before every in-process integrityCheck() call (both before the offload and
  after the await). A connection closing mid-offload no longer throws out of
  the scheduler.
- Stuck-pending on throw + late-subscriber race (P1/P2): the scheduler now
  clears integrityCheckPending UNCONDITIONALLY in a finally, iterating the
  CURRENT shared.subscribers set rather than a pre-await snapshot. A thrown
  check, or a Database that subscribed during the seconds-long await window,
  can no longer be left pinned at integrityCheckPending=true forever.
- No spawn timeout (P2): integrityCheckSqliteFileAsync now passes
  AbortSignal.timeout(5m); a disk-stalled/hung sqlite3 child always settles
  the promise (→ verified:false fallback) instead of leaking and stranding
  the shared entry. AbortSignal.timeout's timer is unref'd, so it never keeps
  the process alive at shutdown.
- FNXC markers added to the two new symbols (per AGENTS.md convention).

Rejected: the suggestion to remove the `// FNXC:Database` marker — FNXC is a
mandatory project convention (AGENTS.md), and a prior review flagged the
absence of these markers as a defect.

Tests: regression test that pending clears for all participants when the
check throws; test that runBackgroundIntegrityCheck returns ok without
throwing on a closed instance; strengthened the healthy-DB assertion.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 14:34:37 -07:00
gsxdsm
d07a5d6ce5 Offload background integrity_check off the main event loop
The boot-time integrity check (scheduleBackgroundIntegrityCheck, ~60s
after init) ran PRAGMA integrity_check on the live connection, walking
every page and freezing the event loop for several seconds — the largest
single read-contention stall in normal operation.

Offload it to the sqlite3 CLI in a child process (async spawn), matching
the existing out-of-process pattern used by quickCheckSqliteFile and
.recover. The CLI connection is opened -readonly so it can never
checkpoint or write the live WAL; this works because the live process
holds the DB open (so the -shm exists). When the CLI is unavailable or
can't open read-only, fall back to the in-process check (verified=false),
preserving today's behavior on those environments.

- New integrityCheckSqliteFileAsync(dbPath, limit) module helper.
- New private runBackgroundIntegrityCheck() seam (offload + fallback) so
  the scheduler has one testable, deterministic policy point.
- Background scheduler callback is now async (IIFE + finally) with errors
  swallowed so a background timer can't crash the process.

VACUUM is intentionally NOT offloaded: the call graph shows it is invoked
only by the `fn db vacuum` CLI command and tests, never from the periodic
maintenance loop, so it is not a background event-loop stall — and an
out-of-process VACUUM on a live WAL DB would add corruption surface for no
hot-path benefit.

Tests updated to the async/offloaded seam (deterministic regardless of
whether the sqlite3 CLI exists in the environment), plus coverage for the
new helper.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 14:12:59 -07:00
gsxdsm
849eefa35e Merge pull request #1692 from Runfusion/fix/sqlite-read-contention
Reduce SQLite read contention: bound WAL growth + release vacuum lock
2026-06-20 13:53:35 -07:00
gsxdsm
61c29cc6b4 Reduce SQLite read contention: bound WAL growth + release vacuum lock
Investigation of reported DB read contention found two cross-process
contention sources in the SQLite layer (single synchronous node:sqlite
connection per process, WAL mode):

- Unbounded WAL on central-db and archive-db. Neither set
  journal_size_limit, so their WAL never truncated back down after a
  checkpoint and every reader paid an ever-growing WAL-index scan. Add
  journal_size_limit=4MB (matching db.ts) plus explicit
  synchronous=FULL/wal_autocheckpoint=1000 for intent. central-db is the
  most cross-process-shared DB; archive-db had the same latent gap.

- vacuum() held the EXCLUSIVE lock past its own runtime. Resetting
  locking_mode to NORMAL does not drop the WAL exclusive lock until the
  connection next touches the DB, so other processes stayed locked out of
  reads (SQLITE_BUSY) until some unrelated query ran. A plain read does
  NOT release it in WAL mode (verified); a PASSIVE checkpoint does. Run
  one in the finally, guard the locking_mode reset so it can't mask the
  original error or skip the release, and log swallowed failures.

Tests: assert the new PRAGMAs on central-db and archive-db, and that a
second connection can read immediately after vacuum() returns.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 13:24:38 -07:00
gsxdsm
7e7eb6299d Harden orphan-worktree/stale-task-dir cleanup (code-review follow-up)
Addresses findings from a multi-agent review of the two prior fixes.

P0 (executor.ts): the stale-conflict recovery force-removed worktreePath with
no bounds check; that path can come from a git admin entry resolving outside
.worktrees/. Now refuses unless the path is inside the worktrees dir, not a
symlink (realpathSync), not a registered worktree, and not actively owned, and
re-verifies liveness in the catch instead of trusting the error string. Also
excludes spawn failures (spawn git ENOENT) from the stale-path classification.

worktree-pool.ts: resolveGitdirPointer -> dotGitPointerIsDangling. Reaps only
when a .git link's gitdir target is confirmed missing; a real .git dir,
unparseable pointer, or any read/stat failure is treated as NOT dangling
(conservative) so a transient read error on a live worktree can't trigger rm.
Drops the string|"directory"|null sentinel union.

core store.ts: bypass the reconcile recency window when the live task table is
empty (corruption/restore: surviving task.json keep old mtimes) and when
fusion.db was auto-recovered on startup, so .recover row loss isn't stranded.
Adds an ignoreRecencyWindow option.

Tests: executor recovery + out-of-bounds refusal, unparseable .git skip,
recency boundary, empty-DB/forced bypass. engine 135 + core 12 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 12:46:34 -07:00
gsxdsm
26ebb9206f Stop reconcile from resurrecting long-deleted task dirs
On restart, reconcileOrphanedTaskDirs re-imported ancient .fusion/tasks/<id>/
directories that had no DB row, surfacing old low-numbered tasks (FN-001, ...)
onto the live board — looking like "all task IDs reset / starting over".

The sweep is meant to recover dirs that appear after store init (heartbeat
races) or rows lost to recent DB corruption. Modern deletes leave a soft-delete
tombstone (caught by taskIdExistsAnywhere), but legacy hard-deletes left none,
so a months-old task.json with no DB row was silently re-imported.

Gate recovery on a 7-day recency window (task.json mtime). Older orphans are
skipped (reason: stale-orphan-dir-beyond-recency-window) and left for explicit
recovery or directory cleanup; heartbeat-race and recent-corruption recovery
still work. Adds a regression test for the stale-dir skip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 12:00:51 -07:00
gsxdsm
b2f564c2be FN-6791: add i18n regression guardrails
Add focused i18n regression coverage for dashboard localization guardrails.

- Assert dashboard hardcoded-string lint ignores stay limited to non-shipping patterns.
- Verify real locale catalogs retain key parity across supported locales and namespaces.
- Cover fallback behavior for empty secondary translations, missing keys, unsupported locale tags, and Chinese locale normalization.
- Document that @fusion/i18n tests now protect lint-ignore scope and catalog parity drift.

Files changed:
 docs/i18n-contributing.md                          |  2 +
 .../i18n/src/__tests__/i18n-gate-coverage.test.ts  | 65 +++++++++++++++++++
 .../i18n/src/__tests__/locale-fallback.test.ts     | 72 ++++++++++++++++++++++
 3 files changed, 139 insertions(+)

Fusion-Task-Id: FN-6791

Fusion-Task-Lineage: 7f52113e-237a-415d-a109-51295fdc0372
2026-06-20 11:02:55 -07:00
gsxdsm
bdf95f8d65 FN-6770: localize dashboard workflow and task UI strings
Localize dashboard workflow, task, setup, and pull request UI copy through the shared i18n resources.

- Replace hardcoded dashboard strings in workflow, task detail/chat/comment, setup wizard, PR, and related modal components with translation lookups.
- Add app/common namespace keys across English and secondary locale catalogs, plus regenerated i18n resource types.
- Add the published package changeset and clear the now-localized component files from the i18n lint deferral list.

Files changed:
 .changeset/fn-6770-localize-workflow-task-pr.md    |   5 +
 i18next.config.ts                                  |  17 +-
 packages/dashboard/app/components/Board.tsx        |  10 +-
 .../dashboard/app/components/PrCreateModal.tsx     |  38 +--
 packages/dashboard/app/components/PrPanel.tsx      |   2 +-
 .../dashboard/app/components/PullRequestView.tsx   |  51 ++--
 .../dashboard/app/components/SettingsModal.tsx     |  92 +++----
 .../dashboard/app/components/SetupWizardModal.tsx  |   8 +-
 packages/dashboard/app/components/TaskChatTab.tsx  | 107 ++++----
 packages/dashboard/app/components/TaskComments.tsx |   2 +-
 .../dashboard/app/components/TaskDetailModal.tsx   |  54 ++--
 .../app/components/WorkflowNodeEditor.tsx          | 109 +++++----
 .../app/components/WorkflowResultsTab.tsx          | 190 +++++++-------
 .../dashboard/app/components/WorkflowSelector.tsx  |  20 +-
 packages/i18n/locales/en/app.json                  | 268 ++++++++++++++++++--
 packages/i18n/locales/en/common.json               |  28 +--
 packages/i18n/locales/es/app.json                  | 268 ++++++++++++++++++--
 packages/i18n/locales/es/common.json               |  28 +--
 packages/i18n/locales/fr/app.json                  | 268 ++++++++++++++++++--
 packages/i18n/locales/fr/common.json               |  28 +--
 packages/i18n/locales/ko/app.json                  | 268 ++++++++++++++++++--
 packages/i18n/locales/ko/common.json               |  28 +--
 packages/i18n/locales/zh-CN/app.json               | 268 ++++++++++++++++++--
 packages/i18n/locales/zh-CN/common.json            |  28 +--
 packages/i18n/locales/zh-TW/app.json               | 268 ++++++++++++++++++--
 packages/i18n/locales/zh-TW/common.json            |  28 +--
 packages/i18n/src/resources.d.ts                   | 272 ++++++++++++++++++---
 27 files changed, 2144 insertions(+), 609 deletions(-)

Fusion-Task-Id: FN-6770

Fusion-Task-Lineage: 393b6b8a-1902-4e46-a53e-b4a0793022ca
2026-06-20 10:35:40 -07:00
gsxdsm
c0d78f19c5 FN-6795: update quarantine ledger after rescue triage
Refresh the test quarantine records after loaded-lane rescue verification.

- document the FN-6795 CLI and core quarantine triage outcomes
- rescue passing core and CLI test files by removing their ledger/config excludes
- retain CLI package-lane-only timeout quarantines and add the newly observed bin test flake

Files changed:
 docs/testing.md                  |  4 ++++
 packages/cli/vitest.config.ts    | 10 +++++++---
 packages/core/vitest.config.ts   |  4 +++-
 scripts/lib/test-quarantine.json | 25 +++++--------------------
 4 files changed, 19 insertions(+), 24 deletions(-)

Fusion-Task-Id: FN-6795
Fusion-Task-Lineage: b4460fc7-848f-4d54-89b4-cfd4d4533d57
2026-06-20 10:28:25 -07:00
gsxdsm
61ff17a057 FN-6797: harden in-review dependency rebound audits
Harden in-review dependency drift reconciliation with explicit guarded no-action audit evidence.

- Emit no-action run-audit events when pause, auto-merge, live execution, checkout, or rebound mutation guards prevent an in-review dependency rebound.
- Preserve scheduler dependency satisfaction semantics so in-review dependencies remain non-blocking under merge-request shadow mode without accepted markers.
- Extend regression coverage and run-audit documentation for guarded in-review rebounds.

Files changed:
 .changeset/fn-6797-in-review-dependency-drift.md   |   5 +
 AGENTS.md                                          |   2 +-
 docs/architecture.md                               |   4 +-
 .../in-review-unmet-dependency-reconcile.test.ts   |  18 ++-
 packages/engine/src/__tests__/self-healing.test.ts |  79 +++++++++++--
 packages/engine/src/self-healing.ts                | 129 ++++++++++++++++-----
 6 files changed, 190 insertions(+), 47 deletions(-)

Fusion-Task-Id: FN-6797

Fusion-Task-Lineage: f94c7875-619a-47be-88f5-320a4dda3b34
2026-06-20 10:21:26 -07:00
gsxdsm
438cd75eaf Fix leaked orphan worktree dirs failing execute node
Directories under .worktrees/ that survive with a dangling .git pointer
(present on disk, but their .git/worktrees/<name> admin entry is gone) are
invisible to `git worktree list`/`prune` yet collide with freshly generated
worktree names. The executor's conflict cleanup then fails with
"is not a working tree", failing the workflow graph at node 'execute' after
3 attempts.

- executor.ts: extend FN-4813 stale-conflict recovery to also treat
  "is not a working tree" and ENOENT (not just "validation failed, cannot
  remove working tree") as "no live worktree here" — prune the admin entry,
  force-remove the leftover dir, and proceed with fresh creation.
- worktree-pool.ts: reapOrphanWorktrees skipped any dir on mere .git-file
  presence, contradicting its own documented invariant. Resolve the .git
  pointer and only skip when the gitdir target exists; reap dangling
  pointers like any other orphan so they stop accumulating across runs.
- Tests for both the dangling (reaped) and valid (skipped) .git cases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 09:58:23 -07:00
gsxdsm
eca96fbd0b FN-6771: localize settings section copy
Localize dashboard settings section text and restore i18n lint coverage for those files.

- Replace hardcoded settings section labels, help text, placeholders, and status copy with i18n lookups.
- Add settings translation keys across supported app and common locale catalogs and refresh generated resource types.
- Remove the settings sections from the i18n lint deferral list and document that coverage requirement.
- Add a patch changeset for the published Fusion package.

Files changed:
 .changeset/fn-6771-localize-settings-sections.md   |   5 +
 docs/i18n-contributing.md                          |   3 +-
 i18next.config.ts                                  |  26 +-
 .../settings/sections/AgentPermissionsSection.tsx  |  55 +-
 .../settings/sections/AppearanceSection.tsx        |  91 +-
 .../settings/sections/AuthenticationSection.tsx    | 457 +++-------
 .../settings/sections/BackupsSection.tsx           | 229 ++---
 .../settings/sections/CommandsSection.tsx          |  49 +-
 .../settings/sections/ExperimentalSection.tsx      | 109 +--
 .../settings/sections/GeneralSection.tsx           | 487 ++++-------
 .../settings/sections/GlobalGeneralSection.tsx     | 183 +---
 .../settings/sections/GlobalModelsSection.tsx      | 525 ++++-------
 .../components/settings/sections/MemorySection.tsx | 458 +++-------
 .../components/settings/sections/MergeSection.tsx  | 863 ++++++------------
 .../settings/sections/NodeRoutingSection.tsx       | 108 +--
 .../settings/sections/NodeSyncSection.tsx          | 105 +--
 .../settings/sections/NotificationsSection.tsx     | 484 ++++------
 .../settings/sections/PluginsSection.tsx           | 105 +--
 .../settings/sections/ProjectModelsSection.tsx     | 971 ++++++++-------------
 .../components/settings/sections/RemoteSection.tsx | 560 +++++-------
 .../settings/sections/ResearchGlobalSection.tsx    | 314 ++-----
 .../settings/sections/ResearchProjectSection.tsx   | 226 ++---
 .../settings/sections/RuntimesSections.tsx         |  40 +-
 .../settings/sections/ScheduledEvalsSection.tsx    | 169 ++--
 .../settings/sections/SchedulingSection.tsx        | 381 ++------
 .../settings/sections/WorktreesSection.tsx         | 330 ++-----
 packages/i18n/locales/en/app.json                  | 698 ++++++++++++++-
 packages/i18n/locales/en/common.json               |   8 +
 packages/i18n/locales/es/app.json                  | 698 ++++++++++++++-
 packages/i18n/locales/es/common.json               |   8 +
 packages/i18n/locales/fr/app.json                  | 698 ++++++++++++++-
 packages/i18n/locales/fr/common.json               |   8 +
 packages/i18n/locales/ko/app.json                  | 698 ++++++++++++++-
 packages/i18n/locales/ko/common.json               |   8 +
 packages/i18n/locales/zh-CN/app.json               | 698 ++++++++++++++-
 packages/i18n/locales/zh-CN/common.json            |   8 +
 packages/i18n/locales/zh-TW/app.json               | 698 ++++++++++++++-
 packages/i18n/locales/zh-TW/common.json            |   8 +
 packages/i18n/src/resources.d.ts                   | 706 ++++++++++++++-
 39 files changed, 7178 insertions(+), 5097 deletions(-)

Fusion-Task-Id: FN-6771
Fusion-Task-Lineage: cdf9b36f-414e-4084-b661-b578a4c27314
2026-06-20 08:57:45 -07:00
gsxdsm
52924ba23d FN-6759: add built-in lead-generation workflow
Add a selectable business workflow for managing lead-generation tasks.

- Register a built-in lead-generation workflow with custom business columns, lead fields, and stage prompts.
- Cover workflow registration, column traits, field metadata, compilation, and IR round-tripping with core tests.
- Document the workflow catalog entry and add a minor changeset for the published CLI package.

Files changed:
 .changeset/fn-6759-lead-generation-workflow.md     |   5 +
 docs/workflow-steps.md                             |   4 +
 .../builtin-lead-generation-workflow-ir.test.ts    | 123 ++++++++++++++++++
 .../core/src/__tests__/builtin-workflows.test.ts   |  10 ++
 .../src/builtin-lead-generation-workflow-ir.ts     | 141 +++++++++++++++++++++
 packages/core/src/builtin-workflows.ts             |  20 +++
 packages/core/src/index.ts                         |   1 +
 7 files changed, 304 insertions(+)

Fusion-Task-Id: FN-6759

Fusion-Task-Lineage: 6c724f84-a6a6-4b01-93ec-cabb9387be2f
2026-06-20 08:43:35 -07:00
gsxdsm
281ce35829 FN-6761: add built-in marketing workflow
Add a content-focused workflow while preserving standard Fusion lifecycle and merge behavior.

- Register builtin:marketing in the built-in workflow catalog and default-enabled workflow order.
- Define marketing-specific columns, content brief/draft/editorial prompts, lifecycle traits, and merge primitives.
- Cover the marketing workflow in built-in workflow tests and document it in workflow-step docs.
- Add a minor changeset for the published Fusion package.

Files changed:
 .changeset/fn-6761-marketing-workflow.md           |   5 +
 docs/workflow-steps.md                             |   3 +
 .../core/src/__tests__/builtin-workflows.test.ts   |  64 +++++++++++-
 packages/core/src/builtin-marketing-workflow-ir.ts | 116 +++++++++++++++++++++
 packages/core/src/builtin-workflows.ts             |  24 +++++
 packages/core/src/index.ts                         |   1 +
 6 files changed, 209 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-6761

Fusion-Task-Lineage: 3242eceb-570f-47f8-8750-dc3acc971bbd
2026-06-20 08:20:39 -07:00
gsxdsm
d2fc70ac91 FN-6793: enforce dependency gates before review
Dependency gating now blocks executor and review recovery paths when dependencies remain unmet.

- Re-check unmet scheduling dependencies before workflow graph or authoritative executor dispatch and requeue blocked tasks with blockedBy.
- Rebound auto-merge-eligible in-review tasks with live unmet dependencies back to todo while preserving progress, worktree, and resume state.
- Add run-audit documentation, a patch changeset, and regression coverage for executor, scheduler, and self-healing behavior.

Files changed:
 .changeset/fn-6793-dependency-gating.md            |   7 +
 AGENTS.md                                          |   1 +
 docs/architecture.md                               |   2 +
 .../engine/src/__tests__/executor-core.test.ts     |  68 +++++++++
 .../in-review-unmet-dependency-reconcile.test.ts   | 115 +++++++++++++++
 packages/engine/src/__tests__/scheduler.test.ts    |  36 +++++
 packages/engine/src/__tests__/self-healing.test.ts | 159 +++++++++++++++++++++
 packages/engine/src/executor.ts                    |  46 ++++++
 packages/engine/src/self-healing.ts                | 112 +++++++++++++++
 9 files changed, 546 insertions(+)

Fusion-Task-Id: FN-6793

Fusion-Task-Lineage: b209264c-faae-41aa-a024-c33e0d8b61be
2026-06-20 08:13:33 -07:00
gsxdsm
083ebf8134 FN-6780: make i18n status check key parity
Make i18n status enforce catalog key parity while allowing empty fallback placeholders.

- Add a reusable i18n parity checker that reports missing and orphaned keys across secondary locales.
- Route pnpm i18n:status through the project parity gate and keep the upstream completeness report as i18n:status:report.
- Document that empty secondary locale strings are valid fallback placeholders and cover parity behavior with tests.

Files changed:
 docs/i18n-contributing.md                   |  18 +++-
 i18next.config.ts                           |  13 ++-
 package.json                                |   3 +-
 packages/i18n/scripts/check-i18n-parity.mjs | 110 +++++++++++++++++++++++
 packages/i18n/src/__tests__/config.test.ts  |   2 +-
 packages/i18n/src/__tests__/parity.test.ts  | 130 ++++++++++++++++++++++++++++
 packages/i18n/src/parity.ts                 | 126 +++++++++++++++++++++++++++
 7 files changed, 393 insertions(+), 9 deletions(-)

Fusion-Task-Id: FN-6780

Fusion-Task-Lineage: f687586a-bc09-4f9d-843f-b7205eb40a58
2026-06-20 06:46:35 -07:00
gsxdsm
254f31ebb6 FN-6790: quiesce deferred task-created writes on close
Rescue task-document coverage by making TaskStore teardown stop late deferred task-created filesystem work.

- Track deferred title write and task-created hook phases so close can drain active work.
- Skip late deferred task-created work once a store is closing to avoid recreating removed fixture roots.
- Update task-document regression coverage, harness teardown awaiting, and rescue documentation while keeping task-documents loaded.

Files changed:
 docs/testing.md                                    |  4 ++
 packages/core/src/__tests__/store-test-helpers.ts  |  2 +-
 packages/core/src/__tests__/task-documents.test.ts | 39 ++++++++++-
 packages/core/src/store.ts                         | 75 +++++++++++++++-------
 packages/core/vitest.config.ts                     |  3 +
 5 files changed, 96 insertions(+), 27 deletions(-)

Fusion-Task-Id: FN-6790

Fusion-Task-Lineage: c458fc4a-b2b4-4cc4-9d88-da8c43f6916d
2026-06-20 05:53:46 -07:00
gsxdsm
48e7a9d5e9 FN-6785: guard productivity metrics defaults
Productivity metrics now tolerate incomplete analytics payloads without crashing.\n\n- Default missing LOC and hours-saved metric objects to unavailable sentinels.\n- Render dash placeholders for incomplete productivity analytics payloads.\n- Add regression coverage for missing productivity metric fields.\n\nFiles changed:\n .../command-center/areas/ProductivityArea.tsx      | 13 ++++++++----\n .../command-center/areas/__tests__/areas.test.tsx  | 23 ++++++++++++++++++++++\n 2 files changed, 32 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-6785

Fusion-Task-Lineage: 0600a88e-58ae-4f81-9871-c5879b49810f
2026-06-20 05:23:05 -07:00
gsxdsm
7f3e94292c FN-6760: add built-in design workflow
Add a built-in workflow path for UI-heavy implementation work with a required design review gate.

- Register builtin:design as a selectable built-in workflow after implementation and before standard review/merge.
- Define design review criteria covering hierarchy, spacing, typography, design tokens, component reuse, responsiveness, and design-language fit.
- Add catalog coverage and update workflow documentation to list the new Design workflow.
- Add a minor changeset for the published Fusion package.

Files changed:
 .changeset/fn-6760-design-workflow.md              |  5 +++++
 docs/getting-started.md                            |  2 +-
 docs/workflow-editor.md                            |  4 ++++
 docs/workflow-steps.md                             |  1 +
 .../core/src/__tests__/builtin-workflows.test.ts   | 23 +++++++++++++++++++++
 packages/core/src/builtin-workflows.ts             | 24 ++++++++++++++++++++++
 6 files changed, 58 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-6760

Fusion-Task-Lineage: 2682ce3f-a89d-4237-b2cf-675439eea1d6
2026-06-20 05:14:25 -07:00
gsxdsm
b760fa0df9 FN-6769: localize remaining dashboard strings
Localize the remaining dashboard UI clusters and refresh the generated i18n resources.

- Replace hardcoded labels across agent, plugin, mission, workflow node, research, document, activity, and miscellaneous dashboard components with app namespace translations.
- Add and synchronize locale catalog entries for English, Spanish, French, Korean, Simplified Chinese, and Traditional Chinese.
- Update i18n lint configuration and generated resource types, with a patch changeset for the published CLI package.

Files changed:
 .changeset/fn-6769-i18n-cluster.md                 |   5 +
 i18next.config.ts                                  |  47 +--
 .../dashboard/app/components/ActiveAgentsPanel.tsx |   2 +-
 packages/dashboard/app/components/ActivityFeed.tsx |  12 +-
 .../dashboard/app/components/ActivityLogModal.tsx  |   4 +-
 packages/dashboard/app/components/AddNodeModal.tsx |   4 +-
 .../dashboard/app/components/AgentDetailView.tsx   |   6 +-
 .../app/components/AgentGenerationModal.tsx        |   2 +-
 .../dashboard/app/components/AgentImportModal.tsx  |   4 +-
 .../app/components/AgentOnboardingModal.tsx        |   4 +-
 .../app/components/AgentPromptsManager.tsx         |   2 +-
 .../dashboard/app/components/AgentRunHistory.tsx   |   2 +-
 .../dashboard/app/components/AgentsOverviewBar.tsx |   2 +-
 .../dashboard/app/components/BranchGroupCard.tsx   |   4 +-
 .../dashboard/app/components/CliBinaryPanel.tsx    |   8 +-
 .../app/components/CursorCliProviderCard.tsx       |   4 +-
 .../dashboard/app/components/DashboardLoader.tsx   |   4 +-
 .../dashboard/app/components/DevServerView.tsx     |   8 +-
 .../dashboard/app/components/DocumentsView.tsx     |   6 +-
 .../dashboard/app/components/ErrorBoundary.tsx     |   9 +-
 .../dashboard/app/components/ExecutorStatusBar.tsx |   5 +-
 .../dashboard/app/components/GitHubStarPrompt.tsx  |  14 +-
 .../dashboard/app/components/GitManagerModal.tsx   |   4 +-
 .../dashboard/app/components/GroupTaskModal.tsx    |   2 +-
 packages/dashboard/app/components/Header.tsx       |   4 +-
 .../dashboard/app/components/HermesRuntimeCard.tsx |   2 +-
 packages/dashboard/app/components/InsightsView.tsx |   2 +-
 .../dashboard/app/components/IssueMentionPopup.tsx |   5 +-
 packages/dashboard/app/components/MailboxView.tsx  |   6 +-
 .../components/MilestoneSliceInterviewModal.tsx    |   2 +-
 .../app/components/MissionInterviewModal.tsx       |   2 +-
 .../dashboard/app/components/MissionManager.tsx    |   8 +-
 .../app/components/ModelOnboardingModal.tsx        |   2 +-
 .../dashboard/app/components/NodeDetailModal.tsx   |   2 +-
 .../app/components/PiExtensionsManager.tsx         |  10 +-
 .../dashboard/app/components/ProjectSelector.tsx   |   6 +-
 packages/dashboard/app/components/QuickChatFAB.tsx |  44 +--
 packages/dashboard/app/components/ResearchView.tsx |   2 +-
 packages/dashboard/app/components/RoutineCard.tsx  |   6 +-
 .../dashboard/app/components/RoutineEditor.tsx     |   2 +-
 packages/dashboard/app/components/RoutingTab.tsx   |   2 +-
 packages/dashboard/app/components/ScheduleCard.tsx |   6 +-
 packages/dashboard/app/components/ScheduleForm.tsx |   2 +-
 packages/dashboard/app/components/ScriptsModal.tsx |   2 +-
 .../app/components/StashConflictModal.tsx          |   4 +-
 .../dashboard/app/components/TerminalModal.tsx     |   2 +-
 .../app/components/nodes/WorkflowNodeTypes.tsx     |  47 +--
 packages/i18n/locales/en/app.json                  | 274 +++++++--------
 packages/i18n/locales/es/app.json                  | 144 ++++++--
 packages/i18n/locales/fr/app.json                  | 144 ++++++--
 packages/i18n/locales/ko/app.json                  | 144 ++++++--
 packages/i18n/locales/zh-CN/app.json               | 144 ++++++--
 packages/i18n/locales/zh-TW/app.json               | 144 ++++++--
 packages/i18n/src/resources.d.ts                   | 375 +++++++++++++++++++--
 54 files changed, 1261 insertions(+), 442 deletions(-)

Fusion-Task-Id: FN-6769

Fusion-Task-Lineage: a8733dc9-3b48-47e6-88c4-020f83ab41de
2026-06-20 05:04:25 -07:00
gsxdsm
fec197afdf FN-6774: remove colored card edge accents
Remove saturated edge stripes from stuck task and agent cards while preserving state legibility.

- Keep stuck task board cards and list rows on neutral borders with tinted backgrounds and existing status badges.
- Replace agent card status edge accents with subtle state backgrounds and a selected-card inset ring.
- Add CSS regression coverage to prevent colored edge-border variants from returning.

Files changed:
 packages/dashboard/app/components/AgentsView.css   | 46 ++++++++---
 packages/dashboard/app/components/ListView.css     |  5 +-
 packages/dashboard/app/components/TaskCard.css     |  5 +-
 .../__tests__/stuck-and-agent-card-border.test.ts  | 92 ++++++++++++++++++++++
 4 files changed, 133 insertions(+), 15 deletions(-)

Fusion-Task-Id: FN-6774

Fusion-Task-Lineage: da49ca64-2c10-4594-888f-332cf4f9c8c8
2026-06-20 04:51:57 -07:00
gsxdsm
c32c925321 FN-6783: recover orphaned task dirs into the task index
Reconcile on-disk task.json records that are missing from SQLite without resurrecting tombstoned IDs.

- Add TaskStore orphaned task directory scanning with metadata validation, FTS-safe insertion, cache updates, lifecycle events, and run-audit entries.
- Run the reconcile during store init and self-healing maintenance for tasks created after startup.
- Cover recovery, skip, and maintenance behavior with core and engine regression tests.
- Document task index reconciliation and add the published package changeset.

Files changed:
 .changeset/fn-6783-orphaned-task-dir-reconcile.md  |   5 +
 AGENTS.md                                          |   1 +
 docs/architecture.md                               |   2 +
 docs/storage.md                                    |   8 +
 .../store-orphaned-task-dir-reconcile.test.ts      | 179 +++++++++++++++++++++
 packages/core/src/store.ts                         | 170 ++++++++++++++++++-
 .../self-healing-orphaned-task-dirs.test.ts        |  40 +++++
 packages/engine/src/self-healing.ts                |  14 ++
 8 files changed, 412 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-6783
Fusion-Task-Lineage: 5c8d4690-5278-4c29-8f02-32d9f01d581d
2026-06-20 04:40:31 -07:00
gsxdsm
adbb1bbaaf FN-6787: remove duplicate sidebar branding
Keep project identity controls in the Header while preserving sidebar navigation behavior.

- Remove the Fusion logo, wordmark, and project selector from the experimental left sidebar.
- Keep the sidebar collapse control reachable in expanded and collapsed modes.
- Update sidebar tests and dashboard docs to cover the simplified navigation surface.

Files changed:
 docs/dashboard-guide.md                            |  2 +-
 .../dashboard/app/components/LeftSidebarNav.css    | 35 +-----------
 .../dashboard/app/components/LeftSidebarNav.tsx    | 33 ++----------
 .../components/__tests__/LeftSidebarNav.test.tsx   | 63 +++++++++++++++++++++-
 4 files changed, 67 insertions(+), 66 deletions(-)

Fusion-Task-Id: FN-6787
Fusion-Task-Lineage: 18321939-4a68-48c2-bdbe-18e69e198a57
2026-06-20 04:19:48 -07:00
gsxdsm
3bda46dbd5 FN-6775: ignore synced mobile assets in lint
Keep generated Capacitor Android web assets out of ESLint while preserving source lint coverage.

- Add an ESLint flat-config ignore for Capacitor-synced Android public assets.
- Add a node:test regression guard proving synced mobile assets are ignored and real package source remains linted.

Files changed:
 eslint.config.mjs                                  |  6 ++++
 .../eslint-ignores-mobile-synced-assets.test.mjs   | 39 ++++++++++++++++++++++
 2 files changed, 45 insertions(+)

Fusion-Task-Id: FN-6775

Fusion-Task-Lineage: 4bab7695-70b5-4a8c-b7de-6e0055ff4b9f
2026-06-20 04:11:33 -07:00
gsxdsm
a98a0ae23e FN-6768: show actual concurrency slider values
Command Center concurrency controls now preserve persisted scheduler values and improve mobile slider handling.

- Load concurrency defaults from project settings and display persisted values without clamping the readout.
- Expand range slider maxima when existing settings exceed normal UI bounds while keeping edits bounded.
- Add mobile touch-drag affordance styling and regression coverage for actual values, overflow values, and CSS contracts.

Files changed:
 .../command-center/CommandCenterControls.css       | 26 +++++++-
 .../command-center/CommandCenterControls.tsx       | 63 +++++++++++++-----
 .../__tests__/CommandCenterControls.test.tsx       | 74 +++++++++++++++++++++-
 3 files changed, 143 insertions(+), 20 deletions(-)

Fusion-Task-Id: FN-6768

Fusion-Task-Lineage: 2508c2ab-9e57-4d29-934c-828a015bdfe1
2026-06-20 03:08:19 -07:00