Commit Graph

7981 Commits

Author SHA1 Message Date
gsxdsm
de3273eba3 FN-5937: clear deadlock auto-pause on retry
Clear deadlock auto-pauses when users retry failed in-review tasks.

- add a shared core helper to clear only the in-review stall deadlock auto-pause without overriding manual or unrelated pauses
- apply the auto-pause clear patch across dashboard, CLI, and extension retry flows while preserving existing merge retry reset behavior
- add regression coverage for core, CLI, extension, and dashboard retry paths plus a patch changeset and architecture note

Files changed:
 .changeset/fn-5937-clear-auto-pause-retry.md       |   5 +
 docs/architecture.md                               |   2 +-
 packages/cli/src/__tests__/extension.test.ts       | 126 ++++++++++++++++++
 packages/cli/src/__tests__/task-retry.test.ts      |  59 +++++++++
 packages/cli/src/commands/task.ts                  |  12 +-
 packages/cli/src/extension.ts                      |  12 +-
 .../core/src/__tests__/manual-retry-reset.test.ts  |  44 ++++++-
 packages/core/src/index.ts                         |   7 +-
 packages/core/src/manual-retry-reset.ts            |  19 +++
 packages/core/src/store.ts                         |   8 +-
 .../src/__tests__/routes-tasks-ops.test.ts         | 141 +++++++++++++++++++++
 .../src/routes/register-task-workflow-routes.ts    |  12 +-
 12 files changed, 436 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-5937

Fusion-Task-Lineage: 8a15e01b-7b05-4126-ac6b-895467801f02
2026-06-03 15:32:29 -07:00
gsxdsm
da7c82ebea FN-5947: fix mobile task review header spacing
Tighten the Task Review tab layout on mobile and lock in the responsive header contract.

- override the mobile .task-review-tab__summary-wrap flex rule so the summary block stops reserving excessive blank space
- extend TaskReviewTab coverage to assert the mobile summary-wrap override and prevent regressions between empty and populated review states across reviewer-agent and pull-request sources
- keep the review header structure stable across both review sources and empty/populated states

Files changed:
 .../dashboard/app/components/TaskReviewTab.css     |  4 +
 .../components/__tests__/TaskReviewTab.test.tsx    | 98 ++++++++++++++++++++++
 2 files changed, 102 insertions(+)

Fusion-Task-Id: FN-5947
Fusion-Task-Lineage: 813e1142-bf28-4687-8510-2f93ec40e582
2026-06-03 15:32:29 -07:00
gsxdsm
f1572a3b62 FN-5946: render PR create modal through a portal
Ensure the PR creation dialog escapes transformed ancestor layout traps.

- render `PrCreateModal` with `createPortal(..., document.body)` so the overlay stays fixed to the viewport
- add regression coverage for container-type and nested-overlay portal behavior plus close interactions
- document the modal overlay portal requirement in the dashboard guide

Files changed:
 docs/dashboard-guide.md                            |  2 +-
 .../dashboard/app/components/PrCreateModal.tsx     |  6 ++-
 .../components/__tests__/PrCreateModal.test.tsx    | 63 +++++++++++++++++++++-
 3 files changed, 66 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-5946

Fusion-Task-Lineage: eb22590e-1776-49f3-82d7-ac87c5138f0b
2026-06-03 15:32:28 -07:00
gsxdsm
acc7456a5e Merge pull request #1343 from Runfusion/gsxdsm/compound
feat: Compound Engineering plugin with interactive sessions, work bridge, and bidirectional sync
2026-06-03 15:31:40 -07:00
gsxdsm
7348e35a11 docs: capture observable-agent-turns architecture pattern and seed CE session vocabulary
ce-compound learning from the live-output/steering work: push-channel-
alongside-pull-contract, void-safe detached turns, inactivity watchdog,
transient liveActivity + persisted trace, replay suppression. Also adds a
"Compound Engineering sessions" cluster to CONCEPTS.md and refreshes the
plugin reference doc's Sessions section with the new transport behaviors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 15:20:34 -07:00
gsxdsm
4aa9048909 Merge pull request #1345 from Runfusion/gsxdsm/missonsdebug
fix(engine): recover missions wedged by stranded done features
2026-06-03 15:00:08 -07:00
gsxdsm
7bfdd97f22 Merge pull request #1361 from Runfusion/gsxdsm/vitest-killguard
fix(tui): stop vitest auto-kill firing on garbage memory metric and killing non-vitest processes
2026-06-03 14:42:54 -07:00
gsxdsm
0106eee4ff feat(compound-engineering): live agent output, steering, and a real Q&A surface
Users can now watch everything the agent does while a CE stage works, steer
it mid-stage, and read the whole conversation as a proper chat surface.

Live output:
- New host capability: CreateInteractiveAiSessionOptions.onProgress — the
  engine adapter streams thinking/text deltas + tool start/end markers from
  the pi agent hooks (any plugin can use this).
- Orchestrator buffers per-session live activity (merged deltas, discrete
  tool lines, capped), emits throttled progress events over SSE, and
  GET /sessions/:id attaches it as liveActivity for the polling fallback.
- Routes detach turn execution: start/answer/resume return immediately
  (status active) and clients converge via push/poll — the turn is watchable
  instead of hidden inside a blocking POST.
- Turn timeout is now INACTIVITY-based: an actively-working long turn is
  never killed; a quiet one interrupts with its working trace preserved.
- On settle the trace persists into history as a condensed record.

Steering:
- Stage protocol: responses may be a direct answer, {value, comment}
  (answer + guidance), or {feedback} (guidance without answering); the
  system prompt instructs agents to treat steering as first-class input.
- CeFlow: guidance textarea alongside selectable questions — attach to the
  clicked answer, or "Send guidance" on its own.

Q&A UI:
- Transcript no longer hides control records: past questions/answers render
  as chat bubbles (option ids → labels), steering turns marked, working
  traces as collapsible "Agent work" blocks, completion marker.
- Live working pane (pulse + streaming thinking/tool lines) while a turn runs.

Tests: 130 plugin tests green (14 new: live buffer/flush ordering, inactivity
watchdog survives active work, detached convergence, steering payload shapes,
transcript rendering, live pane). Engine seam tests green; plugin/core/
engine/dashboard tsc clean. Core full suite OOMs locally (known orchestrator-
shell issue) — covered by CI shards.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 14:17:40 -07:00
gsxdsm
a9e16cedf8 Merge pull request #1348 from Runfusion/gsxdsm/fix-branch-group-collision
fix(core): reuse same-name branch group instead of colliding on mission triage
2026-06-03 13:49:38 -07:00
gsxdsm
580c9005cc Update packages/core/src/vitest-processes.ts
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-06-03 13:48:02 -07:00
gsxdsm
cff0dee87c Merge branch 'gsxdsm/compound' of https://github.com/Runfusion/Fusion into gsxdsm/compound 2026-06-03 13:47:22 -07:00
gsxdsm
7f8db9f892 feat(compound-engineering): manage and work across multiple CE sessions
The store/orchestrator were already multi-session (independent rows + live
handles per session); this surfaces it end to end:

- Sessions panel in the dashboard view: lists every session with stage,
  status badge ("needs your input" for awaiting_input), and last activity;
  stays visible while a flow is open so switching is one click. Closing a
  flow returns to the overview without stopping the session.
- useCeSession.open(): adopt an existing session (pins its projectId for
  answer/resume/poll); useCeSessions list hook with push-event refresh and
  poll fallback while any session is mid-turn.
- DELETE /sessions/:id + orchestrator.discard(): dispose the live handle
  before deleting the row (pipeline-link rows kept for task provenance);
  Discard affordance on settled sessions.
- Tests: cross-session independence through one orchestrator, store delete,
  route list/delete, hook open/list/remove/push/poll, view panel
  open/switch/discard. 116 tests green; plugin + dashboard tsc clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 13:47:02 -07:00
gsxdsm
60c307320d Merge main: adopt FN-5902 lazy assertion linkage in shared runFeatureValidation
- runFeatureValidation now lazy-ensures a linked assertion (FN-5902) instead
  of the removed zero-assertion auto-pass, for both task-completion and the
  stranded-feature recovery path
- CONCEPTS.md: union of main's Merge-lifecycle cluster and this branch's
  Missions clusters; Contract Assertion entry updated for FN-5902 semantics
- AGENTS.md: take main's docs/solutions + CONCEPTS.md pointer wording

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 13:45:11 -07:00
gsxdsm
614bec2126 fix(tui): stop vitest auto-kill firing on garbage memory metric and killing non-vitest processes
Two compounding bugs made the memory-pressure vitest auto-kill a
30-second SIGKILL sweep of anything mentioning vitest:

1. False pressure: getAvailableMemory probed os.availableMemory, which
   does not exist, and silently fell back to os.freemem() — on macOS
   that reads ~99% used on an idle 256GB machine, permanently above the
   90% threshold. Now reads process.availableMemory() (Node 22+) and
   refuses to auto-kill when only the unreliable freemem fallback is
   available.

2. Overbroad targeting: pgrep -f vitest matches full command lines, so
   the sweep also killed wrapper shells (zsh -c '... npx vitest run'),
   monitor loops, and anything else whose argv mentions vitest —
   stranding exit handlers and taking out unrelated process trees.
   New shared findVitestProcessIds (@fusion/core) filters matches to
   actual node executables.

Surface enumeration (all vitest-process kill/count surfaces):
- TUI memory-pressure auto-kill (controller.killVitestProcesses)
- TUI manual kill-vitest command (same method)
- dashboard POST /api/kill-vitest
- dashboard GET /api/system-stats vitestProcessCount (display)
All four now route through findVitestProcessIds.
2026-06-03 13:33:38 -07:00
gsxdsm
fa7da2bdfd Merge branch 'main' into gsxdsm/compound 2026-06-03 13:29:20 -07:00
gsxdsm
3a62b6820f update agents 2026-06-03 13:20:17 -07:00
gsxdsm
1761a7ffd2 FN-5940: stop logging no-op task:moved activity rows
Prevent same-column task move noise from bloating the activity log.

- skip task:moved activity logging and event emission when a task stays in the same column
- add a one-time TaskStore cleanup migration that deletes existing same-column task:moved rows
- cover listener, moveTask, polling replication, and migration behavior with focused core tests
- document the no-op cleanup invariant and manual VACUUM guidance for reclaimed SQLite space

Files changed:
 docs/storage.md                                    |   8 ++
 packages/core/src/__tests__/activity-log-no-op-moved.test.ts | 122 +++++++++++++++++++++
 packages/core/src/__tests__/no-op-moved-cleanup-migration.test.ts          | 108 ++++++++++++++++++
 packages/core/src/store.ts                         |  51 ++++++++-
 4 files changed, 286 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-5940

Fusion-Task-Lineage: f34cf8d0-3639-44d5-8a90-8ba461636eaa
2026-06-03 13:20:17 -07:00
gsxdsm
76c18efa92 FN-5939: expose operational log retention setting
Expose operational log retention as a project setting in the dashboard.

- add an Operational log retention selector to the Project General settings section with supported retention options
- validate operationalLogRetentionDays in the settings API and cover accepted and rejected values in tests
- document the constrained retention values and assert project-scope/default parity for the setting

Files changed:
 docs/settings-reference.md                         |  2 +-
 packages/core/src/__tests__/settings-parity.test.ts |  7 ++++
 packages/dashboard/app/components/SettingsModal.tsx | 47 ++++++++++------------
 packages/dashboard/app/components/__tests__/SettingsModal.test.tsx |  8 ++++
 packages/dashboard/src/__tests__/routes-settings.test.ts | 21 ++++++++++
 packages/dashboard/src/routes/register-settings-memory-routes.ts | 10 +++++
 6 files changed, 69 insertions(+), 26 deletions(-)

Fusion-Task-Id: FN-5939

Fusion-Task-Lineage: 2148dd88-1cef-4c6d-9696-31148fce97d3
2026-06-03 13:20:17 -07:00
gsxdsm
ac92174cba FN-5907: harden planning task creation side effects
Keep Planning Mode task creation responses successful when follow-up work fails.

- catch and log planning create-task/create-tasks side-effect failures so the API can still return 201 after task creation succeeds
- safely handle async task lifecycle listener failures in the core store to avoid leaking unhandled rejections during follow-up updates
- add regression coverage for single-task and multi-task Planning Mode creation across live/persisted sessions, branch selection surfaces, and GitHub tracking failures

Files changed:
 .changeset/fn-5907-planning-create-fetch.md        |   5 +
 .../core/src/__tests__/task-creation-hook.test.ts  |  25 ++
 packages/core/src/store.ts                         |  38 ++-
 .../src/__tests__/routes-planning-tracking.test.ts | 108 ++++++++-
 .../src/__tests__/routes-planning.test.ts          | 267 +++++++++++++++++++++
 .../src/routes/register-planning-subtask-routes.ts |  69 +++++-
 6 files changed, 496 insertions(+), 16 deletions(-)

Fusion-Task-Id: FN-5907

Fusion-Task-Lineage: d9f6574b-e19b-4459-a612-7a3d2510836f
2026-06-03 13:20:17 -07:00
gsxdsm
419f688afb FN-5936: fix auto-merge board stabilization on mobile
Keep the dashboard board visible when auto-merge toggles across viewport changes.

- keep board stabilization subscribed to visualViewport resize events instead of removing the listener after the first resize
- add regression coverage for Android, iOS, tablet, desktop, empty-column, rollback, and error-boundary auto-merge toggle paths
- relax settings hydration assertions and expand app-settings tests for auto-merge rollback and coercion behavior

Files changed:
 .changeset/fn-5936-auto-merge-mobile-fix.md        |   7 +
 packages/dashboard/app/components/Board.tsx        |  19 +-
 packages/dashboard/app/components/__tests__/App.test.tsx          |   8 +-
 packages/dashboard/app/components/__tests__/auto-merge-toggle-blank.mobile.test.tsx        | 418 +++++++++++++++++++++
 packages/dashboard/app/hooks/__tests__/useAppSettings.test.ts     |  53 ++-
 5 files changed, 489 insertions(+), 16 deletions(-)

Fusion-Task-Id: FN-5936

Fusion-Task-Lineage: 6e937d0e-dc60-4863-a884-001228dd0cd1
2026-06-03 13:20:17 -07:00
gsxdsm
ad740775b3 Merge pull request #1356 from Runfusion/gsxdsm/automerge
fix(engine): honor per-task auto-merge override when global auto-merge is off
2026-06-03 13:19:03 -07:00
gsxdsm
e00bc0235b Address PR review feedback (#1356)
- Add behavior-level tests for the shared merge-enqueue funnel
  (enqueueEligibleInReviewTasks) with a Surface Enumeration of all
  in-review entry surfaces, per review
- Seed real stale in-review fixtures in the FN-5147 no-mutation
  regression block so sweeps enumerate candidates and the assertions
  are non-vacuous
- Keep per-task auto-merge gating uniform across reclaim/contamination
  candidate columns: the suggested in-review-only scoping broke the
  FN-5704 regression contract (reclaim short-circuits when autoMerge
  is off); documented the tension in code comments and the learning doc
- Drop hardcoded commit hash from the learning doc
2026-06-03 13:08:06 -07:00
gsxdsm
ff1bb20b8f docs: capture per-task auto-merge override learning and seed CONCEPTS.md
Document the trigger-layer gating bug fixed in this PR under
docs/solutions/logic-errors/, seed CONCEPTS.md with the merge-lifecycle
vocabulary, and surface both knowledge stores in AGENTS.md's reference
docs index.
2026-06-03 10:55:26 -07:00
gsxdsm
ad468813d5 fix(engine): honor per-task auto-merge override when global auto-merge is off
Tasks with autoMerge explicitly enabled never auto-merged when the
project-level setting was disabled: the merge enqueue gate
(allowInReviewMergeProcessing) and all 19 in-review self-healing sweeps
checked only settings.autoMerge, and the board stall-signal hydration
passed the raw global into the diagnostic gates.

Introduce allowsAutoMergeProcessing(task, settings) in core — additive
relative to the global setting so configs with global auto-merge ON are
unchanged (explicit autoMerge:false tasks still flow to the merger's
manual-required parking) — and use it at the enqueue gate, every
self-healing sweep, and the store's stall/stalled signal contexts.
2026-06-03 10:18:24 -07:00
gsxdsm
56a0001c45 docs: capture learning for branch-group-collision triage stall
Document the UNIQUE(branch_groups.branchName) collision that silently
stranded mission triage, in docs/solutions/logic-errors/, cross-linked to
the sibling PR #1345 mission-stall learning.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 08:51:57 -07:00
gsxdsm
314411c497 fix(core): reuse same-name branch group instead of colliding on triage
branch_groups.branchName is globally UNIQUE, but ensureBranchGroupForSource
only looked up an existing group by (sourceType, sourceId). When a second
mission's shared-branch triage resolved to a base branch (e.g. "main") that
another mission already owned a group for, createBranchGroup threw
"UNIQUE constraint failed: branch_groups.branchName". That error escaped
triageFeature and was swallowed by both callers (validation-failure
auto-triage and the reconcile sweep), leaving the mission's "defined"
features — including generated fix features — permanently un-triaged.

ensureBranchGroupForSource now reuses an existing open group for the same
branch name before attempting to create one, matching the established
getBranchGroupByBranchName(...) ?? ensureBranchGroupForSource(...) idiom.

Confirmed by reproducing against a snapshot of the affected mission DB:
triageFeature threw the UNIQUE error before, succeeds after.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 08:40:01 -07:00
gsxdsm
04a5cd196c Merge pull request #1347 from Runfusion/gsxdsm/activitydebug
fix(dashboard): show missing Minimax usage rows and weekly windows
2026-06-03 08:09:32 -07:00
gsxdsm
e37c57305d fix(dashboard): load CE plugin view via @vite-ignore so tsc doesn't compile plugin source
With @fusion/dashboard removed from the CE plugin's deps (cycle fix), a literal
import() of its dashboard-view made the dashboard typecheck the plugin source and
fail to resolve the plugin's type-only @fusion/dashboard import. Use the
moduleId-variable + @vite-ignore pattern (as cli-printing-press does) so tsc
treats it as dynamic; Vite still resolves it at runtime.
2026-06-03 08:02:03 -07:00
gsxdsm
8c170480dd fix(compound-engineering): break dashboard dependency cycle
A new workspace-acyclicity invariant on main (run via the PR merge) flagged
compound-engineering -> @fusion/dashboard -> compound-engineering: the plugin is
listed in @fusion/dashboard's deps (for view loading) AND declared @fusion/dashboard
as a runtime dependency, which the cycle check (deps+devDeps) and the
'bundled plugins must not depend on host packages' check both reject.

The plugin's only @fusion/dashboard use is the type-only PluginDashboardViewContext
import. Drop the @fusion/dashboard dependency and resolve that type via an ambient
dashboard-interop.d.ts + tsconfig paths mapping (the fusion-plugin-dependency-graph
interop pattern). Breaks the cycle; the host passes the real context at runtime.
2026-06-03 07:59:20 -07:00
gsxdsm
c431c0e55d docs: capture learning for the mission auto-progress wedge
Document the stranded done+implementing feature stall in
docs/solutions/logic-errors/, seed CONCEPTS.md with the mission domain
vocabulary, and surface both from AGENTS.md's reference-docs list.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 07:51:48 -07:00
gsxdsm
6f378067f4 fix(dashboard): show missing Minimax usage rows and weekly windows
The Minimax usage panel only rendered one model row. The primary `general`
model meters quota purely via `current_interval_remaining_percent` (its
`current_interval_total_count` is 0), so the count-based `total > 0` visibility
filter dropped it entirely. The percent was also derived from count fields
rather than the authoritative `*_remaining_percent` field.

fetchMinimaxUsage now builds windows via a helper that prefers
`*_remaining_percent` (count-based fallback when absent) and skips a window only
when no quota signal exists. Each model's separate weekly quota window is now
surfaced as its own indicator alongside the interval window.

Verified against the live coding_plan/remains endpoint: 2 models (general,
video) now produce 4 windows (interval + weekly each) instead of 1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 07:51:38 -07:00
gsxdsm
db0cf7d415 docs(solutions): capture plugin bundled-skill loading learning
Document why PluginSkillContribution.skillFiles silently fails to load bundled
skills in live sessions (resolver only filters disk-discovered skills) and the
physical-install + additionalSkillPaths-forwarding fix, as a searchable
docs/solutions/ learning. Surface docs/solutions/ in AGENTS.md so agents
discover it.
2026-06-03 07:26:15 -07:00
gsxdsm
1cf0521a0a fix(compound-engineering): validate parsed JSON shape in rowToSession
safeParse() previously only caught JSON syntax errors, so a semantically-wrong
but valid column ('null', '{}', a string) would rehydrate a non-array
conversationHistory that later crashed appendHistory's spread (and a bogus
currentQuestion). safeParse now takes a shape validator and falls back to []/null
on invalid shapes too. + regression test covering 'null'/'{}'.
2026-06-03 07:10:10 -07:00
gsxdsm
59cd9ea66c Planning fixes 2026-06-03 07:10:02 -07:00
gsxdsm
c2604d5e52 fix(engine): recover missions wedged by stranded done features
A mission feature could be left status="done" while its loopState never
advanced past "implementing" and it had no linked board task, so it was
never validated. The slice-completion gate (computeSliceStatus) correctly
refuses to count an assertion-linked done feature until its validator
passes, but nothing re-drove a task-less feature — so the slice, milestone,
and whole mission could never auto-progress.

Active-mission recovery now detects these stranded done features and re-runs
assertion validation directly (read-only judge, no board task): on pass the
feature becomes legitimately complete, on fail the normal fix-feature flow
takes over. Extracted the feature-validation path into a shared
runFeatureValidation helper used by both task-completion and recovery.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 07:06:30 -07:00
gsxdsm
d72cb2ab2b FN-5911: move agent logs to per-task JSONL storage
Store agent logs in per-task JSONL files instead of the legacy SQLite table.

- add a file-backed agent log store with JSONL append/read/prune helpers and task-scoped source refs
- migrate legacy SQLite agentLogEntries data into task files, rewrite goal citation references, and preserve soft-deleted logs for forensics
- update task store, settings, docs, dashboard route coverage, and add regression tests for migration, retention, and log access

Files changed:
 .changeset/fn-5911-agent-log-jsonl.md              |   5 +
 AGENTS.md                                          |   2 +-
 docs/diagnostics.md                                |   2 +-
 docs/settings-reference.md                         |   2 +
 docs/soft-delete-verification-matrix.md            |   7 +-
 docs/storage.md                                    |   8 +-
 .../src/__tests__/agent-log-file-store.test.ts     | 123 ++++++
 .../core/src/__tests__/agent-log-migration.test.ts | 186 +++++++++
 .../core/src/__tests__/agent-log-retention.test.ts | 208 ++++++++++
 packages/core/src/__tests__/db-migrate.test.ts     |  14 +-
 packages/core/src/__tests__/db.test.ts             |  39 +-
 .../src/__tests__/goal-citations-store.test.ts     |  38 +-
 packages/core/src/__tests__/goals-schema.test.ts   |   2 +-
 packages/core/src/__tests__/insight-store.test.ts  |  10 +-
 .../src/__tests__/merge-request-record.test.ts     |   2 +-
 packages/core/src/__tests__/mission-store.test.ts  |   2 +-
 packages/core/src/__tests__/run-audit.test.ts      |   2 +-
 packages/core/src/__tests__/secrets-schema.test.ts |   6 +-
 .../src/__tests__/soft-delete-agent-logs.test.ts   |  71 ++--
 .../src/__tests__/store-agent-log-file.test.ts     |  91 +++++
 .../core/src/__tests__/store-merge-queue.test.ts   |   2 +-
 packages/core/src/__tests__/store-test-helpers.ts  |  43 +-
 packages/core/src/__tests__/store-upsert.test.ts   |  37 +-
 packages/core/src/__tests__/task-documents.test.ts |   2 +-
 packages/core/src/agent-log-constants.ts           |  25 ++
 packages/core/src/agent-log-file-store.ts          | 267 ++++++++++++
 packages/core/src/db.ts                            |  51 ++-
 packages/core/src/settings-schema.ts               |   1 +
 packages/core/src/store.ts                         | 453 ++++++++++++---------
 packages/core/src/types.ts                         |  10 +-
 .../__tests__/agent-log-routes.integration.test.ts |  48 +++
 .../src/__tests__/evaluator-evidence.test.ts       |  47 ++-
 packages/engine/src/self-healing.ts                |  12 +
 .../src/store/__tests__/roadmap-store.test.ts      |   4 +-
 34 files changed, 1477 insertions(+), 345 deletions(-)

Fusion-Task-Id: FN-5911

Fusion-Task-Lineage: 07c42f3a-87cf-4558-8f01-ac8460b5558b
2026-06-03 01:10:18 -07:00
gsxdsm
1962bea0fc FN-5934: replace undefined dashboard spacing token
Replace dashboard CSS uses of the undefined --space-2xs token with supported spacing values.

- swap var(--space-2xs) for var(--space-xs) in confirm dialog, merge advance notice, and PR checks styles
- add a dashboard test that scans component stylesheets for undefined --space-2xs references
- assert shared token sources continue to omit an intentional --space-2xs definition

Files changed:
 .../app/__tests__/space-token-defined.test.ts      | 45 ++++++++++++++++++++++
 .../dashboard/app/components/ConfirmDialog.css     |  2 +-
 .../app/components/MergeAdvanceNotice.css          |  8 ++--
 packages/dashboard/app/components/PrChecksList.css |  2 +-
 4 files changed, 51 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-5934

Fusion-Task-Lineage: aa77df19-3f76-4ede-aa42-0396230edde5
2026-06-03 01:08:09 -07:00
gsxdsm
5336ad1071 FN-5923: remove duplicate merger fixture key
Remove the duplicate merger override from the SettingsModal test fixture.

- delete the earlier legacy merger object from the mocked settings payload
- keep the deterministic merger override as the single effective fixture value

Files changed:
 packages/dashboard/app/components/__tests__/SettingsModal.test.tsx | 1 -
 1 file changed, 1 deletion(-)

Fusion-Task-Id: FN-5923

Fusion-Task-Lineage: 206239b0-af4a-4e45-93b8-2940a42d431a
2026-06-03 01:04:04 -07:00
gsxdsm
43c3fa9edc FN-5935: fix dashboard interop plugin context types
Align the dependency graph plugin's dashboard interop declarations with the current dashboard contract.

- import ReactNode for plugin task card rendering support
- add DetailTaskTab, PluginToastType, and PluginTaskView type exports
- update PluginDashboardViewContext to require workflowSteps and the expanded openTaskDetail signature
- add optional renderTaskCard and addToast hooks to match dashboard expectations

Files changed:
 .../src/dashboard-interop.d.ts                            | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-5935

Fusion-Task-Lineage: 32313a96-1008-4de6-a7cb-e6bfbc385534
2026-06-03 00:53:24 -07:00
gsxdsm
38ff2ef86d FN-5932: fix research settings containment layout
Keep research settings controls inside their containment wrappers so inputs stay onscreen across breakpoints.

- wrap advanced provider controls in a dedicated research settings body container
- tighten research grid and field min-width behavior in desktop and mobile styles
- add regression coverage for global and project research sections on desktop and mobile

Files changed:
 packages/dashboard/app/components/SettingsModal.css                  |  37 +++++++-
 packages/dashboard/app/components/SettingsModal.tsx                  | 104 +++++++++++----------
 packages/dashboard/app/components/__tests__/SettingsModal.test.tsx   |  65 +++++++++++++
 packages/dashboard/app/components/__tests__/settings-mobile.test.tsx |  48 ++++++++++
 4 files changed, 201 insertions(+), 53 deletions(-)

Fusion-Task-Id: FN-5932

Fusion-Task-Lineage: 22dff41f-b563-40d0-97ea-1ca6d1e09466
2026-06-03 00:49:22 -07:00
gsxdsm
de7847c44d FN-5927: categorize pnpm build scripts for install
Document and enforce pnpm build-script review decisions to prevent ignored-script install warnings.

- add reviewed ignoredBuiltDependencies entries to the root pnpm config and mirror the effective policy in pnpm-workspace.yaml
- add a regression test that verifies reviewed dependencies are categorized exactly once and stay aligned across both config files
- document the pnpm build-script approval policy in contributing docs and link plugin authoring guidance from AGENTS.md and PLUGIN_AUTHORING.md

Files changed:
 AGENTS.md                                          |  5 ++
 docs/PLUGIN_AUTHORING.md                           |  3 +-
 docs/contributing.md                               | 14 ++++
 package.json                                       |  9 +++
 pnpm-workspace.yaml                                | 14 ++++
 scripts/__tests__/pnpm-build-scripts-config.test.mjs   | 74 ++++++++++++++++++++++
 6 files changed, 118 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-5927

Fusion-Task-Lineage: 192bbed9-c5ed-45cb-b4bd-fb18514e2783
2026-06-03 00:28:41 -07:00
gsxdsm
7be377da0c FN-5926: break bundled plugin dashboard dependency cycle
Remove direct dashboard package dependencies from bundled plugins while preserving typed dashboard interop.

- add a workspace acyclic dependency regression test for all packages and dashboard-bundled plugins
- expose dashboard app aliases in dashboard TS/Vite/Vitest configs for plugin interop imports
- replace bundled plugin @fusion/dashboard dependencies with local dashboard interop declarations and updated tsconfig path mappings

Files changed:
 .../workspace-dependency-acyclicity.test.ts        | 174 +++++++++++++++++++++
 packages/dashboard/tsconfig.app.json               |   6 +-
 packages/dashboard/tsconfig.test-check.json        |   6 +-
 packages/dashboard/vite.config.ts                  |   4 +
 packages/dashboard/vitest.config.ts                |   4 +
 .../fusion-plugin-cli-printing-press/package.json  |   1 -
 .../src/dashboard-interop.d.ts                     |  19 +++
 .../fusion-plugin-cli-printing-press/tsconfig.json |   7 +-
 .../fusion-plugin-dependency-graph/package.json    |   1 -
 .../src/dashboard-interop.d.ts                     |   6 +
 .../fusion-plugin-dependency-graph/tsconfig.json   |   3 +-
 plugins/fusion-plugin-roadmap/package.json         |   1 -
 .../src/dashboard-interop.d.ts                     |  19 +++
 plugins/fusion-plugin-roadmap/tsconfig.json        |   7 +-
 pnpm-lock.yaml                                     |   9 --
 15 files changed, 248 insertions(+), 19 deletions(-)

Fusion-Task-Id: FN-5926

Fusion-Task-Lineage: 1b39c08a-1415-407d-90cc-b3de89af0316
2026-06-03 00:12:13 -07:00
gsxdsm
0971eced30 FN-5920: prefer mission detail event count for activity tab
Use mission detail event counts as the authoritative pre-load source for mission activity.

- add mission hierarchy eventCount support in core and dashboard mission types
- return mission eventCount from mission detail APIs and document the field
- prefer the detail eventCount over stale list summaries before activity events load
- add coverage for store, API, and MissionManager pre-load count behavior

Files changed:
 docs/missions.md                                   |  2 +-
 packages/core/src/__tests__/mission-store.test.ts  | 18 +++++++++
 packages/core/src/mission-store.ts                 |  6 +++
 packages/core/src/mission-types.ts                 |  2 +
 packages/dashboard/app/api/legacy.ts               |  2 +
 packages/dashboard/app/components/MissionManager.tsx    | 12 +++++-
 packages/dashboard/app/components/__tests__/MissionManager.test.tsx   | 46 +++++++++++++++++++++-
 packages/dashboard/app/components/mission-types.ts |  1 +
 packages/dashboard/src/__tests__/mission-e2e.test.ts    |  2 +
 9 files changed, 86 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-5920

Fusion-Task-Lineage: a0269499-d34a-495d-89fc-0534bb62a94e
2026-06-02 23:47:32 -07:00
gsxdsm
fb1f726f39 fix(compound-engineering): address code review feedback
- session-store: rowToSession parses JSON columns via a safeParse helper, so a
  corrupted currentQuestion/conversationHistory column degrades to null/[] instead
  of throwing and crashing reads of an otherwise-valid row (+regression test)
- session-routes: validate the ?status= list filter against CE_SESSION_STATUSES
  (asCeSessionStatus) instead of casting an arbitrary query string with 'as never'
- _harness: makeScriptedSession throws on an empty script rather than yielding
  undefined, surfacing test mistakes loudly
- useCeSession tests: use fake timers (advanceTimersByTimeAsync) instead of real
  setTimeout waits for deterministic poll-interval assertions

Skipped: 3 doc nits in src/skills/ce-*/references/** — those are pinned upstream
ce-* skill copies (KTD5 vendored snapshot), not this repo's content.
2026-06-02 23:38:43 -07:00
gsxdsm
6d3b1c9810 FN-5931: fix board viewport fill on narrow widths
Keep the board stretched between the header and footer across narrow layouts.

- make .project-content and .board flex-aware with min-size guards so board columns fill the remaining viewport space
- keep the board resize stabilization cleanup defensive when visualViewport lacks removeEventListener
- extend board mobile regression coverage and document footer-safe fill layout guidance

Files changed:
 docs/dashboard-guide.md                            |  2 +
 packages/dashboard/app/components/Board.tsx        |  8 ++-
 packages/dashboard/app/components/ProjectSelector.css   |  2 +
 packages/dashboard/app/components/__tests__/board-mobile-initial-render.test.tsx | 81 ++++++++++++++++++++--
 packages/dashboard/app/styles.css                  |  7 +-
 5 files changed, 89 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-5931

Fusion-Task-Lineage: 0031ad20-82e5-465d-9326-2b6c2d45de69
2026-06-02 23:33:11 -07:00
gsxdsm
8b450506fc FN-5925: polish task review tab layout
Refine the task review tab layout for clearer hierarchy and better mobile behavior.

- group the review summary and decision badge into a stacked header layout
- reorganize review items with dedicated selection, status, and metadata regions
- restyle review cards, status badges, auto-merge controls, and body containers for improved spacing and overflow handling
- extend TaskReviewTab coverage for populated layout hooks and mobile CSS regressions

Files changed:
 packages/dashboard/app/components/TaskReviewTab.css     | 220 +++++++++++++++------
 packages/dashboard/app/components/TaskReviewTab.tsx     |  24 ++-
 packages/dashboard/app/components/__tests__/TaskReviewTab.test.tsx    |  32 ++-
 3 files changed, 206 insertions(+), 70 deletions(-)

Fusion-Task-Id: FN-5925

Fusion-Task-Lineage: fdb9d882-abda-48b0-aed0-a1ff4262af8f
2026-06-02 23:26:59 -07:00
gsxdsm
a1b7556c7b FN-5924: throttle OAuth expiry alerts across restarts
Persist OAuth expiry alert state so repeated provider expiry warnings are suppressed for 12 hours across engine restarts.

- add a persisted OAuth alert state store under ~/.fusion/agent and share it between the expiry monitor and startup validity logger
- throttle repeated oauth-token-expired notifications and startup expiry warnings per provider for 12 hours, while clearing stale state when providers disappear or change
- cover persisted throttling, restart behavior, failure handling, and wiring updates in engine notification tests
- document the persisted 12-hour OAuth alert throttle and add a patch changeset for @runfusion/fusion

Files changed:
 .changeset/fn-5924-oauth-alert-throttle.md         |   5 +
 docs/settings-reference.md                         |   4 +-
 packages/engine/src/__tests__/project-engine-soft-delete-merge-abort.test.ts |   3 +
 packages/engine/src/__tests__/project-engine.test.ts    |  17 ++-
 packages/engine/src/__tests__/reliability-interactions/soft-delete-in-flight-abort.test.ts            |   3 +
 packages/engine/src/auth-storage.ts                |   6 +-
 packages/engine/src/notification/__tests__/oauth-alert-state.test.ts            |  72 ++++++++++
 packages/engine/src/notification/__tests__/oauth-expiry-monitor.test.ts         | 148 ++++++++++++++++---
 packages/engine/src/notification/__tests__/oauth-validity-logger.test.ts        | 159 ++++++++++++++++++---
 packages/engine/src/notification/index.ts          |   3 +
 packages/engine/src/notification/oauth-alert-state.ts   | 144 +++++++++++++++++++
 packages/engine/src/notification/oauth-expiry-monitor.ts       |  12 +-
 packages/engine/src/notification/oauth-validity-logger.ts      |  16 ++-
 packages/engine/src/project-engine.ts              |  13 +-
 14 files changed, 554 insertions(+), 51 deletions(-)

Fusion-Task-Id: FN-5924
Fusion-Task-Lineage: 83255a25-40c7-44d4-8302-b068ae51250e
2026-06-02 23:13:16 -07:00
gsxdsm
669a6ecfdc FN-5929: track hidden usage windows by instance
Store hidden usage windows with per-instance identities while keeping legacy labels restorable.

- persist hidden usage windows with an index-qualified identity instead of label-only keys
- treat legacy label-only entries as matches for restore/show-hidden behavior
- guard hidden-window counts when provider windows are empty or undefined
- add regression coverage for duplicate labels, multiple hidden windows, and legacy persistence

Files changed:
 packages/dashboard/app/components/UsageIndicator.tsx    |  71 +++++++++----
 packages/dashboard/app/components/__tests__/UsageIndicator.test.tsx   | 113 ++++++++++++++++++++-
 2 files changed, 159 insertions(+), 25 deletions(-)

Fusion-Task-Id: FN-5929

Fusion-Task-Lineage: eb48988e-80b8-4d6c-90b9-0d324564f1aa
2026-06-02 22:46:12 -07:00
gsxdsm
fab2377fd1 FN-5921: persist queued chat messages across navigation
Keep queued chat composer state when users move between sessions and only clear it when the session is truly discarded.

- stop clearing persisted pending chat messages during session switches in useChat and useQuickChat
- clear persisted queued messages only when creating a fresh session or archiving/deleting an existing session
- add regression coverage for navigation, reselection, pre-session queueing, and cleanup behavior across chat and quick chat hooks

Files changed:
 .../dashboard/app/hooks/__tests__/useChat.test.ts  | 246 ++++++++++++++++++++-
 .../app/hooks/__tests__/useQuickChat.test.ts       | 150 +++++++++++++
 packages/dashboard/app/hooks/useChat.ts            |   9 +-
 packages/dashboard/app/hooks/useQuickChat.ts       |   5 +-
 4 files changed, 396 insertions(+), 14 deletions(-)

Fusion-Task-Id: FN-5921

Fusion-Task-Lineage: 8916f862-77f5-4d5b-be9a-412e8a71a47d
2026-06-02 22:42:19 -07:00
gsxdsm
941a3297bc FN-5922: fix(FN-5922): use default model fallback in new chat dialog when no model is explicitly selected
Fix NewChatDialog to resolve the model from the dropdown default when the user has not
explicitly picked a model, allowing chat creation with the default model.

- Introduce `resolvedModel` that falls back to `defaultModelValue` when `selectedModel` is empty
- Use `resolvedModel` in submit handler and submit-disabled guard so the default model is accepted
- Add test for creating a session with the default model ("Use default" selected)
- Add test for creating a session with an explicitly chosen non-default model
- Update existing no-default test to verify the submit button stays disabled and no session is created

Files changed:
 packages/dashboard/app/components/ChatView.tsx     | 12 ++--
 packages/dashboard/app/components/__tests__/ChatView.test.tsx | 69 ++++++++++++++++++++--
 2 files changed, 72 insertions(+), 9 deletions(-)

Fusion-Task-Id: FN-5922

Fusion-Task-Lineage: 30b2aecb-af73-4f6d-b697-cc0b5630d5d8
2026-06-02 22:29:21 -07:00