Commit Graph

8038 Commits

Author SHA1 Message Date
gsxdsm
684baa0eb7 fix(FN-5852): confirm server generation state before flushing queued chat messages
Re-entering a chat flushed the restored queued message based on the
client's stale isGenerating flag (a route-level enrichment the
chat:session:updated SSE payload lacks), firing a send that aborted the
live generation server-side and could lose the message entirely. The
restore path in useChat and useQuickChat now asks the server first:
attach and defer the flush while generating, send immediately only when
no generation is in flight, and keep the bubble on a failed check.

Fixes Runfusion/Fusion#1279

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 19:54:02 -07:00
gsxdsm
07dd24e37a Merge pull request #1357 from Runfusion/gsxdsm/taskbranch
feat: branch-group single managed PR flow (planning + missions)
2026-06-03 18:24:54 -07:00
gsxdsm
39bbe48c8a test(FN-branch-group): update routes-tasks subtask expectations to real-groupId semantics
Two stale assertions still encoded the synthetic planning:<sessionId> groupId:
shared mode without a group-capable store now stamps no groupId, and
per-task-derived members never carry one.
2026-06-03 18:12:59 -07:00
gsxdsm
1557fc5a47 fix(FN-branch-group): repair CI failures — execFile mock compatibility, TaskCard narrowing, e2e memo race
- resolve execFile lazily via namespace import in coordinator/merger/
  task-lifecycle so the repo's exec-only child_process test mocks load again
  (10+ engine suites failed at import); dashboard.test.ts mock gains execFile
  so the argv-based git probes hit the mock instead of spawning real git
- TaskCard: capture optional branchContext.groupId into a const (narrowing
  doesn't survive into the onClick closure; app tsconfig caught it in CI)
- planning e2e: bounded poll past the 2.5s listTasks startup memo that served
  a pre-landing snapshot on fast CI runs
2026-06-03 17:57:00 -07:00
gsxdsm
0be074f8c2 fix(FN-branch-group): address fourth-round PR review feedback (#1357)
- needsPrRepair no longer short-circuited by the open-state guard: legacy
  fallback rows (finalized + prState open + prNumber null) now repair by
  creating the real PR on re-promotion; regression test added
- no-PR abandon route test asserts last persisted call + response body
- goal-provenance fallback test clears missionId on its own in-memory store
  so the feature-linkage path is genuinely exercised
2026-06-03 17:42:43 -07:00
gsxdsm
318be97c56 Merge pull request #1362 from Runfusion/gsxdsm/mission-generator-does-not-respect-or-assign-to
FN-5941: stop missions stalling on incompatible/custom-role agents
2026-06-03 17:38:19 -07:00
gsxdsm
c023014b63 Merge pull request #1354 from Runfusion/gsxdsm/acp
feat: ACP (Agent Client Protocol) client runtime plugin
2026-06-03 17:37:29 -07:00
gsxdsm
64d02b5108 fix(FN-branch-group): address third-round PR review feedback (#1357)
- abandon (route + CLI) preserves prState 'none' for groups that never had a
  PR instead of falsely persisting 'closed'; regression tests both sides
- stale-snapshot write guard extracted to syncGroupPrOnLanding and covered by
  a fast in-memory unit test (FN-5048); the slow real-git duplicate removed
2026-06-03 17:22:11 -07:00
gsxdsm
3de29d7279 fix(acp): plan-only streams enforce the per-turn cap; add category frontmatter
handlePlan charged the budget but never checked the ceiling or set the
flag, so a plan-ONLY stream kept emitting after crossing the cap (caught by
both review bots). It now flags + truncates exactly like text/thinking.
Adds the plan-only flood regression test (185 total) and the category
frontmatter field to the new solutions doc.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 17:17:42 -07:00
gsxdsm
e22401995e Address PR review feedback (#1362)
- Replace dynamic await import("@fusion/engine") in the agent-import route
  with a static top-level import. The dynamic form is banned by the FN-3049
  engine-import-regression test (bundler safety); my earlier reply mistook the
  file's @fusion/core dynamic-import convention for a uniform rule — the
  regression only forbids @fusion/engine. Verified the test now passes.
- AgentImportModal: capture and render dry-run `warnings` in the preview step
  so the custom-role safeguard is shown BEFORE the import runs, not only after.
  Adds a regression test for the preview warning.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 17:14:42 -07:00
gsxdsm
cce7c0d469 Address PR review feedback (#1362)
- Cover the non-dry-run import warning path with a test (greptile P2): the
  warning is spread into both the dryRun and persist responses but was only
  exercised via dryRun.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 17:14:42 -07:00
gsxdsm
6a00dd2090 FN-5941: stop missions stalling on incompatible/custom-role agents
Importing a catalog ("company") agent assigns role "custom", which the
scheduler never auto-assigns mission/queue work to. Combined with a
model/provider that rejects the "developer" system role, this surfaced as
an invisible, repeating failure loop (GitHub #1261).

- pi.ts: treat an unsupported message-role rejection as a model-selection
  error so a configured fallback model is tried once (single-swap guarded)
  before the task is marked failed.
- mission-autopilot.ts: block a mission feature immediately on an
  operator-actionable failure instead of burning the retry budget
  re-running the same cryptic error.
- mission-routes.ts: preflight mission start — when ephemeral agents are
  disabled and no eligible executor exists, fail fast with an actionable
  message instead of queueing tasks forever.
- agent import route + AgentImportModal: warn when only custom-role agents
  are imported and no executor exists.
- agent-assignment.ts: extract shared listEligibleExecutorAgents helper.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 17:14:42 -07:00
gsxdsm
e01848c293 Merge pull request #1374 from Runfusion/gsxdsm/merge-conflict-learning
docs: capture merge-conflict learning (extraction vs semantic change)
2026-06-03 17:13:11 -07:00
gsxdsm
8787931c68 Merge pull request #1376 from Runfusion/gsxdsm/fileschanged
fix(engine): capture baseCommitSha against local main, not origin/main
2026-06-03 17:04:07 -07:00
gsxdsm
d1cd8b6ed8 merge main: unify CONCEPTS.md vocabularies and reconcile core exports
Both sides bootstrapped CONCEPTS.md — kept main's broader structure (Missions,
Merge lifecycle, CE sessions) and folded the branch-group vocabulary into its
Merge-lifecycle cluster (enriched Shared branch group + Self-healing sweep;
added Branch assignment mode, Landed, Group promotion). Union-merged core
index/store imports; took main's AGENTS.md discoverability wording. Also adds
execFile to the two child_process test mocks that only stubbed exec (the
coordinator's argv-based git calls now require it).
2026-06-03 15:57:41 -07:00
gsxdsm
3e927bc5fc fix(FN-branch-group): address second-round PR review feedback (#1357)
- syncGroupPrCallback forwards owner/repo to updatePr (multi-project daemons
  could 404 or edit an unrelated same-numbered PR via process-cwd fallback)
- merger background reconcile re-reads the group before persisting and skips
  the write when the PR snapshot changed (stale-write race vs newer open PR)
- branchContext.groupId trimmed on metadata emit/parse round-trip
- triageSlice non-shared invariant assertions (no groupId, no group row)
2026-06-03 15:46:23 -07:00
gsxdsm
c5cf52ede6 Merge branch 'main' into gsxdsm/fileschanged 2026-06-03 15:36:13 -07:00
gsxdsm
73841cd796 docs: capture origin-first base-capture learning and branching vocabulary
Document the FN-5937 files-changed inflation root cause in
docs/solutions/ and add the Branching & diff attribution cluster
(Integration branch, Fork point, Rebase-and-push, Contamination)
to CONCEPTS.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 15:32:54 -07:00
gsxdsm
866d01f532 FN-5959: bridge task goal provenance from mission links
Bridge mission-linked task provenance into goal diagnostics.

- derive task goal ids and goal records from the linked mission hierarchy with a task mission fallback
- record provenanceGoalIds in goal-injection diagnostics, run-audit metadata, and executor task logs
- add regression coverage and mission/diagnostics docs for derived task-to-goal provenance

Files changed:
 docs/diagnostics.md                                |   5 +-
 docs/missions.md                                   |  19 ++++
 packages/core/src/__tests__/mission-store.test.ts  | 123 +++++++++++++++++++++
 packages/core/src/mission-store.ts                 |  55 ++++++++-
 packages/engine/src/__tests__/goal-injection-diagnostics-wiring.test.ts      |  35 +++++-
 packages/engine/src/goal-injection-diagnostics.ts  |  21 +++-
 6 files changed, 247 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-5959

Fusion-Task-Lineage: 7c76ae98-37b1-421c-b477-a0147d034a4c
2026-06-03 15:32:29 -07:00
gsxdsm
1853459def FN-5961: document goals refinement evidence gate
Add the governance doc and regression coverage for the conditional post-v1 goals refinement gate.

- add docs/goals-refinement-gate.md defining accepted trigger evidence, activation requirements, and the no-automatic-refinement rule for Slice 4
- link the new goals refinement gate doc from docs/README.md
- add a vitest doc guard that asserts the required trigger categories and activation constraints remain documented

Files changed:
 docs/README.md                                     |   1 +
 docs/goals-refinement-gate.md                      | 104 +++++++++++++++++++++
 packages/dashboard/app/__tests__/goals-refinement-gate-docs.test.ts   |  51 ++++++++++
 3 files changed, 156 insertions(+)

Fusion-Task-Id: FN-5961

Fusion-Task-Lineage: 8e641782-93bb-470e-8bc3-14379dbd6cf6
2026-06-03 15:32:29 -07:00
gsxdsm
8aed4da764 FN-5949: add AI PR conflict resolution to Create PR flow
Add dashboard support for resolving task-branch PR conflicts with AI before PR creation.

- add a dashboard PR conflict resolver that merges the selected base into the task branch, invokes an AI merge session on conflicted files, verifies markers are removed, then commits and pushes the updated branch
- expose a POST /tasks/:id/pr/resolve-conflicts route plus client API/export wiring, docs updates, and a changeset for the published CLI package
- update the Create PR modal UI, styling, and tests to surface preflight conflicts, trigger AI resolution, and refresh preflight state after success
- add API coverage for successful and unresolved conflict-resolution paths and include the new route test in the dashboard API quality shard

Files changed:
 .changeset/fn-5949-pr-conflict-resolution.md       |   5 +
 docs/dashboard-guide.md                            |   1 +
 docs/task-management.md                            |   1 +
 packages/dashboard/README.md                       |   1 +
 packages/dashboard/app/api/legacy.ts               |  20 ++
 .../dashboard/app/components/PrCreateModal.css     |  32 ++-
 .../dashboard/app/components/PrCreateModal.tsx     |  46 ++++
 .../components/__tests__/PrCreateModal.test.tsx    |  33 +++
 ...egister-git-github.pr-resolve-conflicts.test.ts | 186 +++++++++++++++
 packages/dashboard/src/index.ts                    |   5 +
 packages/dashboard/src/pr-conflict-resolver.ts     | 258 +++++++++++++++++++++
 .../dashboard/src/routes/register-git-github.ts    | 225 ++++++++++++------
 packages/dashboard/vitest.config.ts                |   2 +-
 13 files changed, 739 insertions(+), 76 deletions(-)

Fusion-Task-Id: FN-5949

Fusion-Task-Lineage: fea35fbf-6254-415c-83cc-0bc24abc911e
2026-06-03 15:32:29 -07:00
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
c6b4897a5d Update docs/solutions/best-practices/merge-conflict-extraction-vs-semantics-and-parallel-bootstrap.md
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-06-03 15:26:49 -07:00
gsxdsm
772d08ee8d Update docs/solutions/best-practices/merge-conflict-extraction-vs-semantics-and-parallel-bootstrap.md
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-06-03 15:26:28 -07:00
gsxdsm
68e52e3c35 fix(engine): capture baseCommitSha against local main, not origin/main
In-review tasks showed other tasks' files in their "files changed"
list. Task branches fork from local main, but the base capture
measured merge-base(HEAD, origin/main) — when local main carried
merged-but-unpushed task commits, the recorded base rewound past
them, and after the post-merge rebase-and-push rewrote those SHAs,
baseCommitSha..HEAD permanently swept the predecessors' files into
the new task's diff.

Extract the capture into base-commit-capture.ts, measure local main
first (origin/main fallback) to match the contamination-base sites,
and add a real-git regression suite covering local-ahead-of-origin.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 15:24:03 -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
d188f7cb04 docs: capture merge-conflict learning (extraction vs semantic change)
Document the refactor-vs-semantics merge resolution pattern (port the
upstream semantic change into the extracted helper, never pick a side)
and the parallel-bootstrap CONCEPTS.md add/add union, with the FN-5902 /
runFeatureValidation merge as the worked example.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 15:15:19 -07:00
gsxdsm
1b83317cfe docs(solutions): document branch-group single-PR silent breakage; seed CONCEPTS.md
First docs/solutions/ learning: synthetic groupIds, mock-masked engine wiring,
and side-effect-free state flips (PR #1357 post-mortem). Seeds CONCEPTS.md with
the branch-group domain vocabulary and surfaces both knowledge stores in
AGENTS.md reference docs.
2026-06-03 15:11:19 -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
18975c6ed6 docs: capture ACP persistent-JSONRPC integration learnings
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 14:54:50 -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
f3bc757d22 fix(FN-branch-group): address PR review feedback (#1357)
- abandon route: guard already-abandoned groups (matches CLI)
- CLI branch-group list: single task fetch via filterTasksByBranchGroup (N+1)
- branch-name validator: git check-ref-format parity (//, dot-segments, .lock, @, @{, trailing /.)
- updateBranchGroup: validate renamed branchName too
- already-merged-detector: escape regex metachars in git log --grep; non-vacuous prose-mention assertion
- group PR callbacks: thread per-project cwd through SyncGroupPrFn/reconcile/github helpers (multi-project correctness)
- merger: group-PR sync is fire-and-forget (never blocks merge completion); deterministic test handle
- coordinator: sibling PR reuse only when open; reconcile skips member fetch on read-only path; argv-based git calls (no shell)
- task-lifecycle: legacy group-PR path links open PRs only; branch probes via execFile argv (injection hardening)
- mission/planning: branchContext.groupId only stamped for actual shared-mode members (groupId now optional)
- UI: Abandon reachable whenever PR is open (decoupled from completion); promote stays completion-gated
- tests: deterministic concurrency gate, real reconcile path in e2e, Surface Enumeration sections
2026-06-03 13:51:13 -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