Commit Graph

8022 Commits

Author SHA1 Message Date
gsxdsm
dbb8adeff1 feat: surface dual-observe flag + parity summary (CU-U5 #3)
- Settings → Experimental gains a 'Workflow Graph Engine — dual-observe parity
  (diagnostic)' toggle for the workflowInterpreterDualObserve flag.
- store.getWorkflowParitySummary() aggregates the workflow:parity-observed /
  workflow:parity-drift run-audit events into the graduation signal: agree-rate,
  per-field drift counts, and recent drift samples. Covered by
  workflow-parity-summary.test.ts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 18:54:39 -07:00
gsxdsm
6c0ea28f42 feat(core): workflow parity observation builders (CU-U5 #1)
Add buildWorkflowObservationFromTask (legacy authoritative side, from a task's
terminal column/status/review/mergeDetails + recorded column history) and
buildWorkflowObservation (interpreter/shadow side, from explicit parts), plus
deriveStageTransitions (maps the task-move column history to execute/review/
merge stages) and DEFAULT_WORKFLOW_INVARIANTS. These let both sides of the
dual-observe seam produce a comparable WorkflowRunObservation without
hand-rolling the shape. Covered by workflow-parity.test.ts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 18:51:27 -07:00
gsxdsm
d8b88f3f84 test(dashboard): mock useToast in PlanningModeModal.ui-interactions
These tests render PlanningModeModal bare; it calls useToast() which throws
without a ToastProvider. Mirror the mock already in PlanningModeModal.autosize.
test.tsx. (Pre-existing failure on main; the test is excluded from the CI
quality shards but fails under `--project dashboard-app`/`test:app`.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 18:37:01 -07:00
gsxdsm
e954f1a720 test(dashboard): mock workflow API in board-mobile and settings-mobile tests
InlineCreateCard now renders WorkflowSelector and SettingsModal renders
ProjectDefaultWorkflowField → WorkflowSelector, both of which call
fetchWorkflows / fetchProjectDefaultWorkflow on mount. These two tests mock
"../../api" with a fixed object that omitted those exports, so the components
threw "No fetchWorkflows export is defined" during render (the failures behind
test shards 1/2; masked earlier by the build break). Add the workflow API
mocks, matching the set already present in InlineCreateCard.test.tsx.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 18:27:34 -07:00
gsxdsm
e5386dc7ee docs(skill): document fn_workflow_list / fn_workflow_select engine tools
skill-sync.test.ts ("engine-tools.md documents all engine session-scoped
tools") scans the engine sources for `name: "fn_*"` and requires each to appear
in packages/cli/skill/fusion/references/engine-tools.md. The two new workflow
tools were added to agent-tools.ts/executor without a doc entry, so the sync
test failed (masked earlier by the dashboard build break). Add both to the
shared agent-tools table.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 18:15:43 -07:00
gsxdsm
05f2d49bf6 test: bump hardcoded schema-version assertions 102 → 105
This PR advanced @fusion/core's SCHEMA_VERSION 102 → 105 (migrations 103
workflows, 104 task_workflow_selection, 105 orphaned-selection cleanup) but
the "reaches current version after init/migrate" assertions across the core
test suite — and the roadmap plugin's mirror test — still hardcoded 102. The
dashboard build break was masking this: the test shards never ran until the
build was fixed, then all four failed on `expected 105 to be 102`.

Updated every getSchemaVersion()).toBe(102) current-version assertion to 105
(db, db-migrate, goals-schema, insight-store, mission-store, run-audit,
store-merge-queue, merge-request-record, task-documents) plus the roadmap
plugin. agent-log-migration already asserts against the imported SCHEMA_VERSION
constant (the robust pattern); central-db asserts its own version 13 and is
unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 18:10:53 -07:00
gsxdsm
d5397d3f69 fix(dashboard): inline isBuiltinWorkflowId — unbreak the app build
The dashboard app build aliases "@fusion/core" to its types-only entry
(core/src/types.ts), which doesn't re-export builtin-workflows, so the Vite/
Rollup bundle failed on `import { isBuiltinWorkflowId } from "@fusion/core"`
(tsc/vitest resolve it via source/dist, so they passed — only the production
build caught it). Inline the one-line "builtin:" prefix check in the editor
instead of pulling the eager BUILTIN_WORKFLOWS construction into the browser
bundle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 17:59:29 -07:00
gsxdsm
8bb02f7d3c fix(engine,core): merge-seam multi-waiter + autoMerge gate; selection lock; settings toggle
Resolve the two needs-human findings from PR #1363 review, plus surface the flag.

Merge seam (project-engine.ts):
- manualMergeResolvers is now a per-task LIST of waiters. Both the dashboard
  "merge now" path and the interpreter merge seam call onMerge, so a single
  resolver per task let the second caller overwrite (and strand) the first.
  All resolve/reject/requeue/late-resolver/shutdown sites drain the whole list.
- New requestInterpreterMerge() honors auto-merge eligibility: when autoMerge
  is off (or the task isn't merge-ready) it returns merged:false instead of
  forcing the merge, so a graph merge node can't override an autoMerge-off
  project — it parks the task in review for a human. setMergeRequester now wires
  the interpreter to this gate rather than the human bypass.

Selection race (store.ts):
- selectTaskWorkflow/clearTaskWorkflowSelection now hold one withTaskLock across
  their whole mutate sequence. Extracted updateTaskUnlocked() (the per-task lock
  is non-reentrant, so they couldn't wrap the public updateTask without
  deadlocking) and call that inside the lock.

Settings:
- Add "Workflow Graph Engine (run custom workflows)" to the Experimental
  Features list so the workflowGraphExecutor flag is a labeled toggle in
  Settings → Experimental, not just a raw key.

Tests: interpreter-merge-seam.test.ts (multi-waiter resolve/reject + autoMerge
eligibility gate); existing merge lifecycle/bypass/selection suites still pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 17:53:40 -07:00
gsxdsm
eb67d08213 Address PR review feedback (#1363)
Greptile + CodeRabbit findings across core/engine/dashboard. Stale findings
(written against earlier commits) verified and skipped; valid ones fixed.

Engine:
- await-input: do not clear pausedReason in the /input route (the node's
  marker must survive unpause); the node clears it after consuming input.
  Embed a colon-free epoch watermark in the marker so only post-pause steering
  comments count as the reply (ISO timestamps collided with the colon
  separator and the dashboard question parser).
- gate nodes without a registered runner now fail closed (throw) instead of
  silently passing.
- a thrown interpreter error in maybeExecuteWorkflowGraph now falls back to the
  legacy pipeline instead of stranding the task in-progress.
- approved-CLI path clears the stale awaiting-cli-approval status/marker.

Core:
- persist+cascade workflow selection: purge task_workflow_selection rows and
  compiled workflow_steps on physical task deletes; migration 105 cleans
  already-orphaned rows; catch-cleanup for materialized steps when the owner
  write fails; WF-id allocation now in a BEGIN IMMEDIATE transaction.
- compiler validates the canonical execute->review->merge seam order (rejects
  duplicate/misordered seams).
- disk-backed reopen round-trip + tightened updatedAt/list assertions.

Dashboard:
- WorkflowSelector clears stale default/options across project changes and on
  fetch failure; InlineCreateCard/NewTaskModal reset the workflow on all
  clear/discard paths and include it in dirty-state.
- WorkflowNodeEditor: config-key deletion now persists; removed an invalid
  eslint-disable that was itself a hard lint error.
- TaskCard: single status badge for awaiting-input (no duplicate).
- WorkflowResultsTab: reset paused-action UI between pauses; surface
  resume/approve failures inline.
- TaskDetailModal: treat awaiting-user-input/awaiting-cli-approval/paused as
  not-in-progress for the live-log subscription.
- workflow-flow-mapping: don't write synthetic node names back into IR.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 17:32:12 -07:00
gsxdsm
46f525bd28 Merge main: reconcile duplicate pausedReason persistence fix + dashboard deps
Main independently landed the same pausedReason persistence fix (column in
the task INSERT/upsert, TaskRow type, rowToTask mapping) with the column
ordered between paused and userPaused; adopt main's ordering and drop this
branch's duplicate entries so the values array stays aligned. Union the
dashboard package.json deps (main's compound-engineering plugin alongside
this branch's sorted pi-coding-agent/cli-printing-press/cursor-runtime).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 16:37:18 -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
b4d9afa0af docs(changeset): note agent tools, read-only built-ins, autoApprove
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 15:32:18 -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
5c02271551 feat(engine): add fn_workflow_list and fn_workflow_select agent tools
Agent-native parity: users can list workflows and select one for a task in
the dashboard, so agents should be able to as well. Adds two task-session
tools — fn_workflow_list (read: built-ins + user definitions) and
fn_workflow_select (assign a workflow to a task, defaulting to the current
one) — wired into the executor's customTools and exported from the engine
index. Covered by unit tests against mock stores.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 15:31:11 -07:00
gsxdsm
291072446d feat(workflows): enforce node autoApprove by bypassing the CLI approval pause
The node "Auto-approve requests" toggle was captured but unused. The only
human-approval pause reachable from a custom node is the CLI first-run
trust-on-first-use gate (review-style nodes run as ephemeral readonly agents
with no permission gate), so autoApprove now bypasses that pause — a superset
of the CLI-specific cliSkipApproval flag. The inspector explains the effect
when the toggle is on.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 15:26:29 -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
bd8f0fd23c feat(dashboard): make built-in workflows read-only in the node editor
Built-in (builtin:*) workflows are read-only at the store layer; reflect
that in the editor so users aren't misled into editing changes that can't
save. For a built-in: the node palette is disabled, the inspector fields are
wrapped in a disabled fieldset, Save/Delete are replaced by a "Read-only
built-in" label, and a "Duplicate to edit" action clones it into an editable
user workflow. handleSave/handleDeleteWorkflow also early-return for built-ins
as defense-in-depth.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 15:19:27 -07:00
gsxdsm
0435fefd86 fix(workflows): persist pausedReason + harden CLI approval, await-input, and node isolation
Address PR #1363 review findings:

- core: pausedReason was written in-memory and read by SELECT but never
  persisted by the task upsert (missing column/value) nor mapped back in
  rowToTask — so it was lost on every reload. Add it to both. This is the
  root cause behind the workflow CLI-approval / await-input pause cycle and
  also fixes token-budget / worktrunk pause reasons silently vanishing.
- dashboard: approve-cli now derives the approved command exclusively from
  the task's pausedReason; a caller-supplied body.command is ignored, closing
  a trust-on-first-use bypass.
- engine: await-input nodes resume only when THIS node paused the task (its
  marker on pausedReason), not on any pre-existing steering comment.
- engine: write-capable custom nodes (coding/script/CLI) are refused until a
  task worktree exists, so they never mutate the shared repo root before the
  execute seam.
- engine: document cliSkipApproval as an intentional workflow-author-only
  escape hatch; scriptName is now const (ESLint).
- tests: pausedReason round-trip coverage in store-persistence; approve-cli
  body-command-ignored + no-pending-command coverage; built-in-aware list
  assertion in workflow-routes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 15:16:16 -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
e685dc54e1 feat(dashboard): select a custom workflow when creating a task
New-task modal and the quick-add card (expanded) now expose a workflow picker;
the chosen workflow is applied to the new task via selectTaskWorkflow right
after creation, non-blocking on failure.
2026-06-03 14:00:59 -07:00
gsxdsm
62aba2c095 feat(core): built-in workflow templates incl. compound engineering
Ship read-only built-in workflows surfaced in the workflow list and selectable
like any workflow: 'Coding' (the existing execute->review->merge pipeline as a
graph), 'Quick fix' (no review), 'Review-heavy' (extra security gate), and
'Compound engineering' (plan -> implement -> review -> code-review gate ->
merge -> document, invoking ce-plan/ce-code-review/ce-compound skills). Built-ins
lead the list, resolve by id for selection, and reject edit/delete.
2026-06-03 13:54:57 -07:00
gsxdsm
a98d14c252 feat: per-node option to skip CLI first-run approval
A CLI node can set cliSkipApproval to bypass the trust-on-first-use pause and
run its command immediately. Exposed as a checkbox in the node inspector.
2026-06-03 13:52:42 -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
d6763e589c feat(dashboard): CLI command field + interactive input/approval banner
Node inspector: CLI executor toggles between a raw command textarea and a named
script. Task modal workflow tab: the await-input banner is now interactive
(reply textarea + Submit & resume), and a new awaiting-cli-approval banner shows
the pending command with an Approve & run action.
2026-06-03 13:48:28 -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
ddde3c5b57 feat(engine,core,api): CLI nodes run arbitrary commands with trust-on-first-use approval
CLI prompt nodes now accept a raw cliCommand (any command + args), not just
named scripts. A raw command must be explicitly approved by the user before it
runs: an unapproved command pauses the task (status awaiting-cli-approval) with
the command shown; the user approves via POST /tasks/:id/workflow/approve-cli,
which records the exact command string in settings.approvedWorkflowCliCommands
and resumes. Named scripts (settings.scripts) still never require approval.
Adds POST /tasks/:id/workflow/input to answer await-input nodes (records a
steering comment + resumes).
2026-06-03 13:44:13 -07:00
gsxdsm
5a318bfe57 feat(dashboard): execution profiles + await-input UI for workflow nodes
Inspector for prompt nodes: executor picker (model via CustomModelDropdown,
agent, skill from discovered skills, CLI named script), auto-approve toggle,
per-node max retries, and a wait-for-user-input mode with a User input palette
preset. Task card shows a 'Needs input' badge for awaiting-user-input status;
the task modal workflow tab shows the node's question as a banner.
2026-06-03 13:34:05 -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
fd94d0f5f2 feat(engine): prompt-node execution profiles + await-input nodes
Prompt nodes now support an executor kind: model (provider/model override),
agent (adopts a named agent's model + custom instructions), skill (prompt
becomes a skill invocation), and cli (named project script with the prompt in
FUSION_NODE_PROMPT — raw commands still never accepted). Per-node maxRetries
overrides the executor-wide default (capped at 10). Await-input nodes pause the
task with status 'awaiting-user-input' and the question as pausedReason; on
unpause the newest steering comment is consumed as the answer and exposed in
graph context.
2026-06-03 13:26:01 -07:00
gsxdsm
6bb5eebf38 fix(engine,core): code-review safety fixes for the graph interpreter
- liveness: graph-routed tasks count as executing in getExecutingTaskIds/
  isTaskActive and are skipped by recoverCompletedTask + the completed-task
  resume fast-path — recovery can no longer drive a parallel lifecycle (P0)
- handleGraphFailure: sets status 'failed' (self-healing revival exemption,
  prevents FN-5704-style re-run loop) and leaves paused tasks untouched
- execute seam distinguishes pause/abort from implementation failure
- merge seam: 30-minute timeout so a wedged queue cannot strand the run
- awaitAbortInFlightTaskWork: defensive interceptor/routing cleanup
- deleteWorkflowDefinition: cascades to selections, materialized steps,
  affected tasks' enabledWorkflowSteps, and the project default
2026-06-03 13:21:54 -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
5502025001 fix: apply safe_auto code-review fixes
- runner: report visited nodes on mid-run interpreter errors
- handleGraphFailure: clear completed-task watchdog + untrack stuck detector
- getDefaultWorkflowId: use getSettingsFast (drop per-create listWorkflowSteps read)
- db: index workflows(createdAt) in base schema + migration 103
- store: hoist workflow-definition type imports; mapping: single editorKind call
- executor: drop backwards TaskDetail->Task cast in execute seam
2026-06-03 12:26:49 -07:00
gsxdsm
44e77fda5c feat(engine): graph interpreter owns the full task lifecycle behind the flag (CU-U3, CU-U4)
Real engine seams: execute delegates to the legacy implementation phase via a
completion interceptor that stops execute() at the implementation-complete
boundary (no double review/merge); review performs the in-review handoff; merge
resolves through ProjectEngine.onMerge over the same serialized merge queue
(wired via a late-bound setMergeRequester, mirroring setMergeEnqueuer). Custom
graph nodes run on the proven WorkflowStep machinery (readonly tool policy,
verdict parsing). Adds a 'planning' seam to the vocabulary (no-op for
pre-specified tasks; custom planning is a prompt node today).

Entry point: execute() routes graph-selected tasks through the runner when
experimentalFeatures.workflowGraphExecutor is on, with process-wide routing
claims (FN-4811 posture), duplicate-dispatch dropping, pre-run errors falling
back to legacy, and mid-run errors parking the task in review (never re-running
the implementation, never stranding the task).

Flag off by default: all 587 executor tests pass unchanged.
2026-06-03 11:07:30 -07:00