Commit Graph

10053 Commits

Author SHA1 Message Date
gsxdsm
3ee47dec86 merge: integrate origin/main into feature/workflow-steps (FN-7039)
Resolve conflicts from 56 upstream commits:
- db.ts: renumber my migrations around main's new migration 130 (columnDwellMs) —
  enable-id normalization 130→131, drop-table 131→132, SCHEMA_VERSION→132.
- index.ts / routes.ts: take main's new MCP exports/imports; keep WORKFLOW_STEP_TEMPLATES
  array removed (kept the WorkflowStepTemplate type).
- merger.ts: keep the legacy post-merge execution path removed (U7c) over main's version.
- ci-workflow.test.ts (from main): add port-4040/process-supervisor allowlist markers to
  the gate-script assertions that reference the checker filenames (pre-existing self-match).

Gate green (engine-core 299, ci-shape 62); boot smoke PASS; migration tests + typecheck clean.
2026-06-26 08:50:22 -07:00
gsxdsm
005322eeaa fix(review): address PR #1788 review feedback
- workflow-graph-executor: wrap each post-merge walk() in try/catch so a malformed
  post-merge IR / traversal error is logged and skipped, never flipping an already-
  merged task to failed (non-blocking post-merge contract) [T9, real bug].
- Refresh stale FNXC comments now that graphNativePostMerge is default-ON and the
  legacy merger post-merge path was removed (experimental-features, workflow-graph-
  executor, workflow-graph-post-merge.test) [T6/T7/T8].
- Normalize FNXC timestamps to yyyy-MM-dd-hh:mm (TaskCard.test, taskProgress.test) [T2/T3].
- Changeset: category fix → feature to match the minor bump [T0].

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 08:40:59 -07:00
gsxdsm
7d13f880ba FN-7059: pin merge gate composition
Add CI-shape coverage that guards the trusted merge gate composition.\n\n- Load root and engine package scripts plus the engine vitest config in the CI workflow test.\n- Assert test:gate includes the audited guard scripts, engine core suite, and CLI CI-shape suite.\n- Assert engine test:core continues targeting the engine-core vitest project.\n\nFiles changed:\n packages/cli/src/__tests__/ci-workflow.test.ts | 26 ++++++++++++++++++++++++++\n 1 file changed, 26 insertions(+)

Fusion-Task-Id: FN-7059

Fusion-Task-Lineage: 47af7fdd-a812-4d03-960a-a6300d86b59e
2026-06-26 06:47:27 -07:00
gsxdsm
2b554142f5 FN-7056: guard configured commands against execSync
Add a focused engine regression guard for user-configured command paths.

- Add a static Vitest registry that slices protected configured-command helpers and fails on execSync usage.
- Assert each protected command path keeps bounded async safeguards such as timeout, maxBuffer, or maxLifetimeMs.
- Document the guard and its deliberate git-plumbing exclusions in the testing guide.

Files changed:
 docs/testing.md                                    |   5 +
 .../user-configured-command-no-execsync.test.ts    | 288 +++++++++++++++++++++
 2 files changed, 293 insertions(+)

Fusion-Task-Id: FN-7056

Fusion-Task-Lineage: b92f19cf-526e-4345-b18e-869a278e0e10
2026-06-26 04:11:04 -07:00
gsxdsm
d03d6c23d6 FN-7057: preserve workflow selections across dashboard surfaces
Add regression coverage and stale-workflow fallback for workflow-aware dashboard selection.

- Cover cached board-workflow hydration across remounted Header and Graph switchers.
- Verify Header and Graph selections remain isolated while Graph task filtering follows the Graph selection.
- Treat deleted workflow assignments as default-workflow tasks so they remain visible.
- Add hook coverage for cache hydration, project changes, selection fallbacks, disabled workflow mode, and consumer isolation.
- Add a patch changeset for the stale Graph workflow filtering fix.

Files changed:
 .changeset/fn-7057-graph-workflow-filter.md        |   7 +
 .../workflow-selection-cross-surface.test.tsx      | 184 +++++++++++++++++++++
 .../app/components/GraphWorkflowSwitcherSlot.tsx   |  11 +-
 .../__tests__/GraphWorkflowSwitcherSlot.test.tsx   |   1 +
 .../app/hooks/__tests__/useBoardWorkflows.test.ts  | 133 ++++++++++++++-
 5 files changed, 330 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-7057

Fusion-Task-Lineage: 52e6682a-576e-4ed6-92d5-03e0e9b5896c
2026-06-26 04:06:32 -07:00
gsxdsm
4e59d74920 FN-7058: refresh test velocity quarantine baseline
Refresh the test velocity report so it reflects the current quarantine ledger.

- Update the weekly baseline quarantine count from 0 to 3.
- Reflect the three new quarantines in age-bucket and delta tables.
- Update the #leads posting snippet with the new quarantine ledger total.

Files changed:
 docs/test-velocity-baseline.md | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-7058
Fusion-Task-Lineage: c8d40858-3511-4962-9f33-01d144cb6dae
2026-06-26 03:50:38 -07:00
gsxdsm
3bfdb16650 FN-7033: document MCP operator workflows
Add a canonical MCP guide with operator workflows and contract coverage.

- Add docs/mcp.md covering MCP settings resolution, transports, secret references, validation, dashboard management, CLI commands, import/export, and AI lane forwarding.
- Link the MCP guide from the docs index, CLI reference, settings reference, secrets docs, and dashboard guide.
- Add a documentation contract test that checks required guide sections and source-aligned MCP surfaces.

Files changed:
 docs/README.md                                     |   1 +
 docs/cli-reference.md                              |   2 +-
 docs/dashboard-guide.md                            |   2 +-
 docs/mcp.md                                        | 221 +++++++++++++++++++++
 docs/secrets.md                                    |   2 +-
 docs/settings-reference.md                         |   2 +
 .../src/__tests__/mcp-documentation.test.ts        |  65 ++++++
 7 files changed, 292 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7033

Fusion-Task-Lineage: 530abc69-0247-49ee-9487-54d8e2a1b988
2026-06-26 02:52:51 -07:00
gsxdsm
8131d541ca FN-7038: add live automation run output
Add configurable automation tool access with live manual-run streaming for schedules and routines.

- Add an automation tool allowlist model and dashboard selectors for AI prompt steps.
- Stream manual automation and routine run progress, output, step updates, and tool events over SSE.
- Surface live run transcripts in automation/routine cards and document the operator workflow.
- Cover validation, runner callbacks, API streaming, and UI behavior with targeted tests.

Files changed:
 .changeset/fn-7038-automation-tools-live-output.md |   7 +
 docs/dashboard-guide.md                            |   9 +
 packages/core/src/__tests__/automation.test.ts     |  27 +-
 packages/core/src/automation.ts                    |  18 +
 packages/core/src/index.ts                         |   4 +-
 packages/core/src/types.ts                         |   6 +
 packages/dashboard/app/api/legacy.ts               |  48 +++
 packages/dashboard/app/components/RoutineCard.tsx  |  16 +-
 packages/dashboard/app/components/ScheduleForm.tsx |  53 ++-
 .../app/components/ScheduleStepsEditor.tsx         |  49 ++-
 .../app/components/ScheduledTasksModal.tsx         |  72 +++-
 packages/dashboard/app/components/ScriptsModal.css |  79 ++++
 .../app/components/__tests__/RoutineCard.test.tsx  |  45 +++
 .../app/components/__tests__/ScheduleForm.test.tsx | 100 +++++-
 .../__tests__/ScheduleStepsEditor.test.tsx         |  67 +++-
 .../__tests__/ScheduledTasksModal.test.tsx         |  36 +-
 .../src/__tests__/routes-automation.test.ts        | 151 +++++++-
 packages/dashboard/src/routes.ts                   | 400 ++++++++++++++++++++-
 packages/dashboard/src/server.ts                   |   7 +-
 packages/engine/src/__tests__/cron-runner.test.ts  |  56 ++-
 .../src/__tests__/pi-create-fn-agent.test.ts       |  44 +++
 .../engine/src/__tests__/routine-runner.test.ts    |  28 ++
 packages/engine/src/cron-runner.ts                 |  20 +-
 packages/engine/src/pi.ts                          |  32 +-
 packages/engine/src/routine-runner.ts              |  39 +-
 packages/i18n/locales/en/app.json                  |   9 +
 packages/i18n/src/resources.d.ts                   |  21 ++
 27 files changed, 1374 insertions(+), 69 deletions(-)

Fusion-Task-Id: FN-7038

Fusion-Task-Lineage: 7f5871d0-1de0-4d22-a9c9-ee9418658677
2026-06-26 02:45:29 -07:00
gsxdsm
c0f9f2b4a9 docs(FN-7039): rewrite workflow-steps docs to the graph-native model
Reflect the completed cutover: quality gates are optional-group IR nodes (pre- and
post-merge), results live on task.workflowStepResults (graph-written), custom gates are
authored in the Workflow Editor, plugin templates are the palette. Removed docs for the
deleted runWorkflowSteps path, WORKFLOW_STEP_TEMPLATES catalog, /api/workflow-steps CRUD,
Settings → Workflow Steps manager, and the workflow_steps table. Documented
experimentalFeatures.graphNativePostMerge (default-ON) and the FN-4343 per-step scope-gate
follow-up. settings-reference: add graphNativePostMerge, annotate workflowStepScopeEnforcement.

Plan U8.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 02:38:31 -07:00
gsxdsm
301f25da06 FN-7025: add MCP server management settings UI
Adds dashboard controls for managing MCP server configuration across global and project scopes.

- Add global and project MCP settings sections with server cards, validation, inheritance status, and import/export controls.
- Wire MCP settings into split-save behavior, browser-safe core exports, localization, and dashboard documentation.
- Cover MCP settings interactions and save routing with dashboard tests.

Files changed:
 .changeset/fn-7025-mcp-dashboard-ui.md             |   7 +
 docs/dashboard-guide.md                            |  14 +
 packages/core/src/types.ts                         |   4 +
 .../app/__tests__/settings-save-split.test.ts      |  25 +
 .../dashboard/app/components/SettingsModal.tsx     |  25 +
 .../__tests__/SettingsModal.mcp.test.tsx           | 228 +++++++++
 .../app/components/settings/save-split.ts          |   5 +
 .../settings/sections/GlobalMcpSection.tsx         |  26 ++
 .../settings/sections/McpServersCard.css           | 177 +++++++
 .../settings/sections/McpServersCard.tsx           | 515 +++++++++++++++++++++
 .../settings/sections/ProjectMcpSection.tsx        |  27 ++
 packages/i18n/locales/en/app.json                  |  10 +-
 packages/i18n/locales/es/app.json                  |  10 +-
 packages/i18n/locales/fr/app.json                  |  10 +-
 packages/i18n/locales/ko/app.json                  |  10 +-
 packages/i18n/locales/zh-CN/app.json               |  10 +-
 packages/i18n/locales/zh-TW/app.json               |  10 +-
 17 files changed, 1107 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-7025

Fusion-Task-Lineage: e4e59431-c819-464b-a04b-e470ac51c460
2026-06-26 02:30:34 -07:00
gsxdsm
347842faca refactor(FN-7039): drop the legacy workflow_steps table; remove all table readers
Final cutover — nothing reads workflow_steps at runtime, so migration 131 drops it.

- Removed the merger post-merge execution path entirely (runPostMergeWorkflowSteps,
  hasEnabledPostMergeWorkflowSteps, executePostMerge{Prompt,Script}Step, post-merge
  worktree helpers + call site). Graph owns post-merge.
- Executor recovery no longer reads getWorkflowStep().gateMode; gate-ness comes from the
  recorded WorkflowStepResult.status.
- Removed store CRUD (create/update/deleteWorkflowStep), materializeWorkflowSteps, and
  migrateLegacyWorkflowSteps; selectTaskWorkflow now seeds default-on optional-group node
  ids (consistent with create-time). KEPT the plugin step-template palette (getWorkflowStep
  plugin-only resolver / listWorkflowSteps plugin-only) — never touches the table.
  Removed the dashboard migrate-legacy-steps route + editor migration UI.
- SCHEMA_VERSION 130→131; migration 131 DROP TABLE IF EXISTS workflow_steps; SCHEMA_SQL
  table def removed; historical migrations 77/105/109/130 guarded with tableExists().

Proof nothing stranded: the graph executes IR nodes resolved from workflowId (never
stepIds/compiled rows) — materializeWorkflowSteps writes were vestigial. Full @fusion/core
suite (6290), reliability backstop (154), boot smoke, and a seed-at-130 drop test all pass
with the table gone.

Plan U7c.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 02:29:32 -07:00
gsxdsm
afa33b76d3 FN-7055: fix task workflow detail rendering
Fix task-detail workflow rendering so inherited workflow data and live results refresh reliably.

- Clear stale workflow selections and result rows while switching between tasks.
- Load inherited/default workflow graphs and avoid empty graph previews during loading.
- Alias optional template IDs to materialized workflow steps so configured details populate.
- Cover task switching, inherited workflows, and optional step detail rendering with dashboard tests.

Files changed:
 .changeset/fn-7055-workflow-tab-graph-step-details.md     |  7 +++
 docs/dashboard-guide.md                                    |  1 +
 packages/dashboard/app/components/TaskDetailModal.tsx      |  5 ++
 packages/dashboard/app/components/WorkflowResultsTab.tsx   | 35 +++++++++--
 packages/dashboard/app/components/__tests__/TaskDetailModal.models-progress-workflow.test.tsx | 56 +++++++++++++++++
 packages/dashboard/app/components/__tests__/WorkflowResultsTab.test.tsx | 72 ++++++++++++++++++++++
 6 files changed, 171 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-7055

Fusion-Task-Lineage: a28dd138-3c2f-43bc-81f9-fb47799f5251
2026-06-26 02:04:53 -07:00
gsxdsm
59fc94bc0f FN-7054: fix slash skill request matching
Normalize requested skill identifiers so slash/catalog forms load the discovered bare skill across chat and agent sessions.

- Add requested-name matching keys for slash paths, SKILL.md paths, and source-qualified skill identifiers.
- Preserve execution-skill disable/exclude behavior and not-found diagnostics while applying the new matching only to requested names.
- Cover chat/agent requested skill paths with resolver and full flow tests and document supported /skill forms.

Files changed:
 .changeset/fn-7054-skill-slash-names.md            |   7 ++
 docs/agents.md                                     |   2 +-
 docs/dashboard-guide.md                            |   2 +-
 .../engine/src/__tests__/agent-skills-flow.test.ts |  42 +++++++++
 .../engine/src/__tests__/skill-resolver.test.ts    | 101 +++++++++++++++++++++
 packages/engine/src/skill-resolver.ts              |  23 ++++-
 6 files changed, 170 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-7054
Fusion-Task-Lineage: 8d0f5c7d-9d8b-4b16-b24e-db6d2f6a464b
2026-06-26 01:38:57 -07:00
gsxdsm
9a2e8a7260 feat(FN-7039): graph is sole post-merge owner + migration 130 normalizes enable ids
Makes graph-native post-merge the default and cuts the merger's legacy post-merge
path over so post-merge runs exactly once (via the graph), with migration data prep.

- experimentalFeatures.graphNativePostMerge → default ON; merger
  hasEnabledPostMergeWorkflowSteps/runPostMergeWorkflowSteps become inert when on
  (no double-run; proven by a new no-double-run test). Merger code kept (U7c removes it).
- Migration 130 (SCHEMA_VERSION 129→130) rewrites each task's enabledWorkflowSteps
  entries that are legacy built-in pre-merge workflow_steps row ids → the optional-group
  node id (browser-verification/code-review); dedupes; idempotent; identity-stable;
  leaves node-ids/compiled/custom entries untouched. Table KEPT (U7c drops it).
- Investigation (real DBs): NO custom/plugin post-merge steps exist; the only post-merge
  step is compound-engineering's 'document' graph node — so the merger no-op strands
  nothing. Custom-step re-pointing was verified unnecessary and skipped.

Safe-to-drop in U7c still blocked by live readers: merger post-merge fns, store CRUD,
migrateLegacyWorkflowSteps/readConfig materialization (executor recovery reader is
already null-safe→advisory).

Plan U7b.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 01:30:24 -07:00
gsxdsm
dbd613a529 FN-7053: catch up tasks on SSE re-entry
Reconcile task list catch-up behavior when re-entering live Board/List views.

- Move Board/List SSE re-entry refetch ownership from App into useTasks.
- Trigger exactly one catch-up fetch for each sseEnabled false-to-true transition without duplicating initial mount.
- Cover disabled, search-query, and repeated toggle cases in useTasks tests.

Files changed:
 packages/dashboard/app/App.tsx                     |  22 +----
 .../dashboard/app/hooks/__tests__/useTasks.test.ts | 110 +++++++++++++++++----
 packages/dashboard/app/hooks/useTasks.ts           |  12 +++
 3 files changed, 105 insertions(+), 39 deletions(-)

Fusion-Task-Id: FN-7053

Fusion-Task-Lineage: 7fd7a05e-deb5-4c0d-9585-288089cb9945
2026-06-26 01:24:47 -07:00
gsxdsm
c0d53530cf FN-7052: restore Agent Detail tab touch panning
Restore mobile horizontal panning from direct touches on Agent Detail tab buttons.

- Apply pan-x touch-action to Agent Detail tab buttons alongside the tab strip.
- Cover both base and mobile tab styles so the global mobile pan-y lock does not block button-origin swipes.
- Extend the mobile scroll regression test to assert tab buttons expose horizontal touch panning.
- Add a patch changeset for the published CLI package.

Files changed:
 .changeset/fn-7052-agent-detail-mobile-tab-touch-action.md        | 7 +++++++
 packages/dashboard/app/components/AgentDetailView.css             | 5 +++++
 .../components/__tests__/AgentDetailView.mobile-scroll.test.tsx   | 8 ++++++--
 3 files changed, 18 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7052

Fusion-Task-Lineage: 42921948-f940-46d6-8c86-c159e94603b5
2026-06-26 01:19:55 -07:00
gsxdsm
3f66e55505 FN-7016: keep workflow container edges connected
Keep workflow container fallback layouts connected in the editor.

- Space fallback and auto-layout columns by each node's rendered width so wide containers do not overlap adjacent handles.
- Treat incomplete top-level saved layouts as stale and fall back to a coherent graph layout.
- Cover optional-group, foreach, and mobile graph mapping with regression tests.

Files changed:
 .changeset/fn-7016-optional-group-edges.md         |   7 +
 .../__tests__/workflow-auto-layout.test.ts         |  18 +++
 .../__tests__/workflow-flow-mapping.test.ts        | 154 ++++++++++++++++++++-
 .../__tests__/workflow-mobile-graph.test.ts        |  37 ++++-
 .../app/components/workflow-auto-layout.ts         |  28 +++-
 .../app/components/workflow-flow-mapping.ts        |  40 +++++-
 6 files changed, 271 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-7016

Fusion-Task-Lineage: a009fc2d-05cb-41cc-8be1-c5522f7398ff
2026-06-26 01:15:14 -07:00
gsxdsm
29aee2196a FN-7051: restore verify:fast prerequisite builds
Restore verify:fast so fresh worktrees prepare required artifacts before boot smoke.\n\n- Bootstrap missing or stale workspace dist artifacts before scoped verification.\n- Always build @runfusion/fusion for source-checkout boot smoke, even when no package diff maps to the CLI.\n- Update verify:fast tests and docs to capture the prerequisite build flow.\n\nFiles changed:\n AGENTS.md                              |  4 +-\n docs/testing.md                        |  5 +-\n scripts/__tests__/verify-fast.test.mjs | 29 +++++++++--\n scripts/verify-fast.mjs                | 92 ++++++++++++++++++++++++++--------\n 4 files changed, 101 insertions(+), 29 deletions(-)

Fusion-Task-Id: FN-7051

Fusion-Task-Lineage: b8980f15-0103-4f40-9f8d-83907461988a
2026-06-26 01:10:00 -07:00
gsxdsm
194878dac9 feat(FN-7039): post-merge workflow steps run graph-native (flag-gated)
Adds graph-native post-merge step execution behind experimentalFeatures.graphNativePostMerge
(default OFF — byte-identical behavior until enabled). After a successful merge-attempt
(the merge seam awaits the merge Promise), the graph runs post-merge optional-group nodes
and records phase:"post-merge" results, non-blocking. The merge-region traversal hop is
inert when the flag is off, and empty for builtin:coding even flag-on (its merge exits only
reach merge-region nodes or end), so the parity oracle holds. Optional-group recording now
derives phase + log prefix from config.phase (defaults pre-merge). Adds postMergeOptionalGroupNode
factory for migration/custom workflows. Legacy merger post-merge path untouched (U7b cutover).

Plan U7a.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 01:09:45 -07:00
gsxdsm
d739223de2 FN-7049: collapse model pricing behind modal editor
Collapse the Global Models pricing editor into a compact summary with a modal table for detailed edits.

- Add a View pricing table modal with escape, overlay, and close-button dismissal.
- Keep add, edit, delete, and LiteLLM fetch workflows available while showing override counts in the collapsed settings view.
- Update model pricing tests, styling, and documentation for the collapsed summary and modal editor.

Files changed:
 docs/dashboard-guide.md                            |   2 +-
 docs/settings-reference.md                         |   4 +-
 .../settings/sections/ModelPricingSection.css      |  36 +++++-
 .../settings/sections/ModelPricingSection.test.tsx |  62 ++++++++-
 .../settings/sections/ModelPricingSection.tsx      | 144 +++++++++++++++------
 5 files changed, 198 insertions(+), 50 deletions(-)

Fusion-Task-Id: FN-7049
Fusion-Task-Lineage: 9ba63354-28e7-4717-81e6-805f1f05fd97
2026-06-26 01:04:03 -07:00
gsxdsm
6c94ee069c FN-7023: forward MCP runtime config to AI lanes
Forward enabled MCP server configuration through AI session creation and validation paths.

- Resolve and materialize effective MCP servers with secret values at runtime for triage, execution, review, merge, evaluation, reflection, mission validation, and dashboard chat/planning lanes.
- Add runtime support guards, Claude CLI MCP config generation, and a dashboard validation route for MCP server reachability probes.
- Cover MCP forwarding, provider support behavior, settings resolution, validation, and pi extension config generation with targeted tests and docs.

Files changed:
 .changeset/fn-7023-mcp-runtime-forwarding.md       |   7 +
 docs/agents.md                                     |   2 +
 docs/secrets.md                                    |   1 +
 docs/settings-reference.md                         |   6 +-
 .../src/__tests__/mcp-lane-forwarding.test.ts      |  79 +++++++++++
 .../src/__tests__/mcp-validate-route.test.ts       | 111 ++++++++++++++++
 packages/dashboard/src/chat.ts                     |   3 +
 packages/dashboard/src/planning.ts                 |   5 +
 packages/dashboard/src/routes.ts                   |  90 ++++++++++++-
 .../src/__tests__/mcp-lane-forwarding.test.ts      |  95 ++++++++++++++
 .../engine/src/__tests__/mcp-resolution.test.ts    | 104 +++++++++++++++
 .../src/__tests__/mcp-runtime-support.test.ts      |  44 +++++++
 .../src/__tests__/mcp-validation-service.test.ts   |  69 ++++++++++
 packages/engine/src/__tests__/pi.test.ts           |  65 +++++++++
 packages/engine/src/agent-reflection.ts            |   3 +
 packages/engine/src/agent-runtime.ts               |  36 ++++-
 packages/engine/src/agent-session-helpers.ts       |   2 +
 packages/engine/src/evaluator.ts                   |   3 +
 packages/engine/src/executor.ts                    |  14 ++
 packages/engine/src/index.ts                       |   3 +
 packages/engine/src/mcp-resolution.ts              |  81 ++++++++++++
 packages/engine/src/mcp-runtime-support.ts         |  41 ++++++
 packages/engine/src/mcp-validation-service.ts      | 146 +++++++++++++++++++++
 packages/engine/src/merger-ai.ts                   |   5 +
 packages/engine/src/merger.ts                      |  14 ++
 packages/engine/src/mission-execution-loop.ts      |   3 +
 packages/engine/src/pi.ts                          |  44 +++++--
 packages/engine/src/reviewer.ts                    |   3 +
 packages/engine/src/runtime-resolution.ts          |   8 +-
 packages/engine/src/step-session-executor.ts       |   6 +-
 packages/engine/src/triage.ts                      |   5 +
 packages/pi-claude-cli/index.ts                    |  20 ++-
 packages/pi-claude-cli/src/mcp-config.ts           |  65 ++++++++-
 33 files changed, 1150 insertions(+), 33 deletions(-)

Fusion-Task-Id: FN-7023
Fusion-Task-Lineage: ea09c6c7-b3c3-4af6-9ca6-0ebbfec17139
2026-06-26 00:57:32 -07:00
gsxdsm
93da87dc5d FN-7048: enable mobile detail tab swiping
Allow task detail tabs to keep horizontal touch scrolling on mobile surfaces.

- Add pan-x touch-action overrides on detail tab buttons for modal, embedded, mobile, and tablet contexts.
- Extend responsive CSS coverage to assert each task-detail tab target allows horizontal panning.
- Add a patch changeset documenting the mobile task-detail tab scroll fix.

Files changed:
 .changeset/fn-7048-task-detail-mobile-tab-touch-action.md  |  7 +++++++
 packages/dashboard/app/components/TaskDetailModal.css      | 14 ++++++++++++++
 .../TaskDetailModal.responsive-and-dependencies.test.tsx   | 14 +++++++++++++-
 3 files changed, 34 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7048

Fusion-Task-Lineage: bb07b72f-8843-4ed4-a45b-ea8172bc4957
2026-06-26 00:48:51 -07:00
gsxdsm
f3f20accbb FN-7031: preview binary media files in dock Files viewer
Render browser-native previews for right-dock file selections while preserving text editing behavior.

- Add image, video, audio, and PDF preview rendering through the workspace download URL.
- Keep previewable and known binary files out of the text editor, with a read-only fallback for unsupported binaries.
- Cover compact and two-pane dock preview behavior with tests, docs, and a patch changeset.

Files changed:
 .changeset/fn-7031-dock-files-binary-preview.md    |   7 +
 docs/dashboard-guide.md                            |   2 +-
 .../dashboard/app/components/DockFilesView.css     |  45 ++++++
 .../dashboard/app/components/DockFilesView.tsx     |  85 ++++++++++-
 .../components/__tests__/DockFilesView.test.tsx    | 170 ++++++++++++++++++++-
 5 files changed, 303 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-7031

Fusion-Task-Lineage: a52bdd57-bb3e-494e-85a8-81326a1548e2
2026-06-26 00:43:55 -07:00
gsxdsm
2ce208e36d FN-7036: make Automations popup movable and resizable
Render the Automations modal in the shared floating-window shell while preserving embedded and mobile behavior.

- Wrap the modal presentation in FloatingWindow with persisted geometry, drag handle, and resize sizing.
- Update Automations modal CSS so desktop fills the floating shell and mobile remains full-screen with resize handles hidden.
- Cover floating-window rendering, dragging, resizing, mobile CSS contract, and embedded mode in ScheduledTasksModal tests.
- Add a minor changeset for the published Fusion package.

Files changed:
 .changeset/fn-7036-automation-modal-floating.md    |   7 ++
 .../app/components/ScheduledTasksModal.tsx         |  43 +++++----
 packages/dashboard/app/components/ScriptsModal.css |  78 +++++++++-------
 .../__tests__/ScheduledTasksModal.test.tsx         | 103 +++++++++++++++++++--
 4 files changed, 172 insertions(+), 59 deletions(-)

Fusion-Task-Id: FN-7036

Fusion-Task-Lineage: 3d6926b7-ec6d-4179-ad17-573bcfef297f
2026-06-26 00:35:41 -07:00
gsxdsm
98a5052b65 FN-6706: add signal connector incident ingestion
Connect external signal ingestion routes to Command Center incident analytics.\n\n- Add connector status reporting and incident upsert/resolution support for webhook, Sentry, Datadog, and PagerDuty sources.\n- Move signal aggregation through shared activity analytics and expose connector-aware empty states in Command Center.\n- Document connector setup, settings, and dashboard behavior with a published changeset.\n- Extend route, analytics, and Command Center UI tests for scoped signal data and configured-but-quiet connectors.\n\nFiles changed:\n .changeset/fn-6706-signal-connectors.md            |   7 +\n AGENTS.md                                          |   1 +\n docs/dashboard-guide.md                            |   4 +-\n docs/settings-reference.md                         |  16 +\n docs/signals-connectors.md                         | 140 ++++++++\n .../core/src/__tests__/signals-analytics.test.ts   |  37 ++-\n packages/core/src/activity-analytics.ts            | 185 ++++++++++-\n packages/core/src/index.ts                         |  11 +-\n packages/core/src/signals-analytics.ts             | 209 +-----------\n .../command-center/areas/SignalsArea.tsx           |  47 ++-\n .../areas/__tests__/areas.github-signals.test.tsx  | 120 +++++--\n .../command-center/areas/__tests__/areas.test.tsx  |   3 +-\n .../register-command-center-routes.test.ts         |  72 +++-\n .../src/__tests__/register-signal-routes.test.ts   | 369 ++++++++++++++++++++-\n .../src/routes/register-command-center-routes.ts   |  29 +-\n .../dashboard/src/routes/register-signal-routes.ts |  55 +++\n packages/dashboard/src/signal-source.ts            |   8 +\n packages/dashboard/src/signal-sources/datadog.ts   |   8 +\n packages/dashboard/src/signal-sources/pagerduty.ts |  14 +-\n packages/dashboard/src/signal-sources/sentry.ts    |  19 +-\n packages/dashboard/src/signal-sources/webhook.ts   |   8 +\n 21 files changed, 1094 insertions(+), 268 deletions(-)

Fusion-Task-Id: FN-6706

Fusion-Task-Lineage: 09003e9b-481b-4393-926b-44907d13bcf9
2026-06-26 00:28:31 -07:00
gsxdsm
142bce0b93 fix(review): apply code-review fixes — dead code, step output/notes, seam-contract sync
From the U1-U6 code review (correctness/adversarial/reliability/maintainability):
- Delete dead code left by the runWorkflowSteps removal: parkTaskAfterWorkflowStepPause,
  handleWorkflowRevisionRequest (+ createWorkflowRevisionFollowUpTask,
  injectWorkflowRevisionInstructions), handleWorkflowStepFailure, the dead
  partitionWorkflowRevisionFeedback export + its test, and 2 orphaned jsdocs;
  reword 2 stale comments (executor.ts FN-6722, self-healing.ts jsdoc).
- Record step output/notes on graph workflow-step results: runGraphCustomNode now
  emits contextPatch:{output,notes} so the Workflow tab shows real review feedback
  and [pre-merge] revision logs carry detail (was always the fallback before).
- Sync the workflow-step seam contract: core (workflow-compiler SEAM_NAMES/order,
  workflow-ir column map, builtin-workflow-prompts) now rejects the workflow-step
  seam to match the engine's resolveSeamName, preventing a latent run-time crash on
  a persisted/cloned def that core would otherwise parse.

Residual (tracked in the PR): re-introduce the FN-4343 per-step scope gate on the
graph path; the parked-failed recovery log wording; malformed-advisory->passed edge
case; recording for non-optional-group/split-branch step realizations.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 00:26:03 -07:00
gsxdsm
a7eb3c4dd8 refactor(FN-7039): delete WORKFLOW_STEP_TEMPLATES + legacy workflow-step management surface
U6: delete the built-in WORKFLOW_STEP_TEMPLATES catalog + its materializer
(getBuiltInWorkflowTemplate/ensureWorkflowStepForTemplate/toBuiltInWorkflowStep);
inline the browser-verification + code-review name/prompt/toolMode/gateMode into
their optional-group IR builders (node bytes unchanged); simplify
resolveEnabledWorkflowSteps to an identity-stable pass-through (no materialization,
so the optionalGroupIdSet collision guard is no longer needed). Plugin-contributed
step templates are kept as the editor palette.

U5: remove the legacy /api/workflow-steps REST surface (GET/POST/PATCH/DELETE +
/refine + /workflow-step-templates/:id/create), the dead client fns, and the
Settings management UI; GET /api/workflow-step-templates now serves plugin
templates only. The create-time optional-step toggles remain.

Scope: the workflow_steps store CRUD + table are intentionally KEPT — still consumed
by the engine (merger/recovery) and needed by U7's migration; their removal + the
table drop land in U7.

Plan U5 + U6.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 00:06:31 -07:00
gsxdsm
4dab2b6986 FN-7011: Exclude engine downtime from task timing
Exclude proven engine-process downtime from active task duration stats and badges.

- Persist a throttled engineLastActiveAt heartbeat while the scheduler is running and unpaused.
- Reconcile in-progress execution segment anchors on startup when downtime exceeds the poll threshold.
- Emit run-audit events for shifted and no-action downtime reconciliation outcomes.
- Cover core timing, dashboard badge behavior, scheduler heartbeat throttling, and self-healing audit metadata.
- Add a patch changeset for the published CLI package.

Files changed:
 .changeset/fn-7011-engine-downtime-timing.md       |  7 +++
 AGENTS.md                                          |  1 +
 .../src/__tests__/store-execution-timing.test.ts   | 51 ++++++++++++++++++++++
 packages/core/src/settings-schema.ts               |  1 +
 packages/core/src/store.ts                         | 28 ++++++++++++
 packages/core/src/types.ts                         |  5 +++
 .../app/utils/__tests__/taskTiming.test.ts         | 16 +++++++
 .../__tests__/scheduler-workflow-cutover.test.ts   | 29 +++++++++++-
 packages/engine/src/__tests__/self-healing.test.ts | 23 ++++++++++
 packages/engine/src/run-audit.ts                   |  4 ++
 packages/engine/src/scheduler.ts                   | 11 +++++
 packages/engine/src/self-healing.ts                | 21 +++++++++
 12 files changed, 196 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7011

Fusion-Task-Lineage: 44225b0a-0fa1-40be-812d-33fd5e446944
2026-06-25 23:35:31 -07:00
gsxdsm
da69e03d29 FN-7047: remove quick-entry keyboard hint
Remove the retired quick-entry keyboard hint and its empty UI shell from task creation.

- Drop the quick-entry hint element and associated responsive styles.
- Remove the retired quickEntryHint locale key from all app locales and generated resources.
- Add coverage asserting the hint and shell stay absent across expanded and collapsed quick-entry modes.
- Add a patch changeset for the published Fusion package.

Files changed:
 .changeset/fn-7047-quick-entry-hint-removal.md         |  7 +++++++
 packages/dashboard/app/components/QuickEntryBox.css    | 18 ------------------
 packages/dashboard/app/components/QuickEntryBox.tsx    |  4 +---
 .../app/components/__tests__/QuickEntryBox.test.tsx    | 18 ++++++++++++++++++
 packages/i18n/locales/en/app.json                      |  1 -
 packages/i18n/locales/es/app.json                      |  1 -
 packages/i18n/locales/fr/app.json                      |  1 -
 packages/i18n/locales/ko/app.json                      |  1 -
 packages/i18n/locales/zh-CN/app.json                   |  1 -
 packages/i18n/locales/zh-TW/app.json                   |  1 -
 packages/i18n/src/resources.d.ts                       |  1 -
 11 files changed, 26 insertions(+), 28 deletions(-)

Fusion-Task-Id: FN-7047

Fusion-Task-Lineage: c838f25b-a3cf-4c2c-b214-511df12dd423
2026-06-25 23:34:08 -07:00
gsxdsm
3c66c33cd9 FN-7050: repair route and executor line ceilings
Repair the line-count ratchet baseline for focused route and executor drift.

- Add FN-7050 context to the line-count guardrail comments.
- Raise only the routes.ts and executor.ts grandfathered ceilings to match current drift.
- Preserve unrelated baseline entries for separate scoped repairs.

Files changed:
 scripts/check-file-line-count.mjs | 3 +++
 scripts/line-count-baseline.json  | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7050

Fusion-Task-Lineage: 8a57d331-4abf-42bd-a4c9-2f55607a6262
2026-06-25 23:34:08 -07:00
gsxdsm
ea5e12e8eb FN-7042: stop refocusing quick task input after submit
Prevent successful quick task creation from stealing focus back to the quick-entry textarea.

- Remove the post-submit focus restoration request/effect from QuickEntryBox.\n- Update desktop, mobile, duplicate-confirm, and image-upload tests to assert no automatic refocus.\n- Add a patch changeset documenting the quick-entry focus fix.\n\nFiles changed:\n .changeset/fn-7042-quick-entry-no-refocus.md       |  7 +++\n .../dashboard/app/components/QuickEntryBox.tsx     | 46 +------------------\n .../components/__tests__/QuickEntryBox.test.tsx    | 53 ++++++++++++----------\n 3 files changed, 39 insertions(+), 67 deletions(-)

Fusion-Task-Id: FN-7042

Fusion-Task-Lineage: 7c8e26a6-3a6b-463f-bfb7-8310682584f8
2026-06-25 23:34:08 -07:00
gsxdsm
cc67df9e61 FN-7046: re-ratchet core line-count baselines
Repair the scoped core store/type baseline drift without broadening unrelated line-count debt.

- Add the FN-7046 CI note explaining the scoped re-ratchet for store.ts and types.ts.
- Raise only the core store.ts and types.ts grandfathered ceilings to their current generated sizes.

Files changed:
 scripts/check-file-line-count.mjs | 3 +++
 scripts/line-count-baseline.json  | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7046

Fusion-Task-Lineage: 1c64b426-9c51-427d-bacc-e527dffa9d90
2026-06-25 23:34:08 -07:00
gsxdsm
9bd0853667 FN-7044: split Command Center area tests
Split the oversized Command Center area test suite into focused files while preserving shared fixtures and coverage.

- Extract shared date ranges, fixtures, and helpers into areas.test-harness.tsx.
- Move GitHub and Signals area assertions into a dedicated sibling suite.
- Keep the remaining areas.test.tsx below the 2000-line cap with existing coverage intact.

Files changed:
 .../areas/__tests__/areas.github-signals.test.tsx  | 406 +++++++++++++
 .../areas/__tests__/areas.test-harness.tsx         | 302 ++++++++++
 .../command-center/areas/__tests__/areas.test.tsx  | 648 +--------------------
 3 files changed, 730 insertions(+), 626 deletions(-)

Fusion-Task-Id: FN-7044

Fusion-Task-Lineage: 63886ec9-e9c3-410e-bbc6-c5116cddb168
2026-06-25 23:34:08 -07:00
gsxdsm
07209a4732 FN-7045: capitalize Code Review step name
Normalize the built-in Code Review workflow label and cover the display-name invariant.

- Rename the compound-engineering built-in code-review node to "Code Review".
- Add regression coverage that rejects lowercase built-in Code review node names.
- Add a patch changeset for the published CLI package.

Files changed:
 .changeset/fn-7045-code-review-step-name.md           | 7 +++++++
 packages/core/src/__tests__/builtin-workflows.test.ts | 9 +++++++++
 packages/core/src/builtin-workflows.ts                | 6 +++++-
 3 files changed, 21 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7045

Fusion-Task-Lineage: 4608df38-dc5f-4d16-b33e-9f4ce00fe96d
2026-06-25 23:34:07 -07:00
gsxdsm
429143ecf0 FN-7024: add MCP server management CLI
Add CLI support for managing MCP server configuration without exposing secret values.

- Add fn mcp list/add/edit/remove/enable/disable/import/export/validate subcommands.
- Store MCP env and header values as Fusion secret references, including Claude Desktop import conversion.
- Document MCP CLI usage and add command coverage for scoped configuration, import, export, and validation.
- Add a minor changeset for the published CLI feature.

Files changed:
 .changeset/fn-7024-mcp-cli.md                   |   7 +
 docs/cli-reference.md                           |  49 +++
 packages/cli/src/bin.ts                         | 124 +++++++
 packages/cli/src/commands/__tests__/mcp.test.ts | 182 ++++++++++
 packages/cli/src/commands/mcp.ts                | 455 ++++++++++++++++++++++++
 5 files changed, 817 insertions(+)

Fusion-Task-Id: FN-7024

Fusion-Task-Lineage: e3d98bfa-b883-4b9e-86d5-f0416808d6f2
2026-06-25 23:34:07 -07:00
gsxdsm
2c46cdc1e2 FN-7041: fix optional workflow step descriptions
Fix the workflow results settings display for configured optional steps.

- Treat workflow step definitions as missing only when the lookup has no entry.
- Preserve empty descriptions for found optional-group steps such as Code Review.
- Add regression coverage for configured, checkbox, and ordering displays.
- Add a patch changeset for the published Fusion package.

Files changed:
 .../fn-7041-workflow-step-definition-not-found.md  |  7 +++++
 .../app/components/WorkflowResultsTab.tsx          |  9 +++++-
 .../__tests__/WorkflowResultsTab.test.tsx          | 36 ++++++++++++++++++++++
 3 files changed, 51 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7041

Fusion-Task-Lineage: 84698437-d4d3-4b68-9c5f-c8b15f513230
2026-06-25 23:34:07 -07:00
gsxdsm
c7cbae147c FN-7040: align task-detail model displays
Unify task-detail model resolution so Chat, Agent Log, and Workflow settings display the same effective model.

- Add a shared dashboard resolver for executor, validator, and planning model display precedence.
- Reuse the resolver in TaskDetailModal and WorkflowResultsTab instead of duplicating fallback logic.
- Cover log marker, assigned runtime model, task override, and settings fallback cases with focused tests.
- Add a patch changeset for the published Fusion package.

Files changed:
 .../FN-7040-align-task-detail-model-display.md     |   7 +
 .../dashboard/app/components/TaskDetailModal.tsx   | 158 +--------------------
 .../app/components/WorkflowResultsTab.tsx          |  15 +-
 .../__tests__/WorkflowResultsTab.test.tsx          |  74 +++++++++-
 .../__tests__/effective-model-resolution.test.ts   | 111 +++++++++++++++
 .../app/components/effective-model-resolution.ts   | 149 +++++++++++++++++++
 6 files changed, 354 insertions(+), 160 deletions(-)

Fusion-Task-Id: FN-7040

Fusion-Task-Lineage: 05ec3ae7-5063-4219-a515-da16168e9a19
2026-06-25 23:34:07 -07:00
gsxdsm
9a2709dde9 FN-6969: show provider icons beside Command Center models
Show inferred provider icons beside model names across Command Center bar and table surfaces.

- Add dashboard-side provider-icon inference for model/provider strings.
- Render provider icons on Command Center model bar rows and token table rows while keeping pie chart labels text-only.
- Cover overview, token, and ecosystem model-icon surfaces with tests and add a changeset.

Files changed:
 .changeset/fn-6969-provider-icons.md               |   7 ++
 .../components/command-center/CommandCenter.tsx    |  15 ++-
 .../__tests__/CommandCenter.test.tsx               |  33 ++++++-
 .../command-center/areas/EcosystemArea.tsx         |  15 ++-
 .../components/command-center/areas/TokensArea.tsx |  37 +++++++-
 .../areas/__tests__/TokensArea.test.tsx            | 105 +++++++++++++++++++++
 .../command-center/areas/__tests__/areas.test.tsx  |  42 ++++++++-
 .../app/components/command-center/charts/Bar.tsx   |  25 ++++-
 .../components/command-center/charts/charts.css    |  42 +++++++++
 .../app/utils/__tests__/providerIconKey.test.ts    |  32 +++++++
 packages/dashboard/app/utils/providerIconKey.ts    |  45 +++++++++
 11 files changed, 377 insertions(+), 21 deletions(-)

Fusion-Task-Id: FN-6969

Fusion-Task-Lineage: 6caf8864-1ecc-46e3-b7fa-bfa8e9a70aaa
2026-06-25 23:34:07 -07:00
gsxdsm
433ccce0b5 fix: stop global settings resetting via project-local central DBs (#1787)
## Problem

Operators intermittently saw **"all my global settings reset"** —
including the global concurrency cap surfacing as `gate=semaphore` with
a low value in scheduler queue logs.

## Root cause

`CentralCore` is supposed to live at `~/.fusion/fusion-central.db`, but
`resolveGlobalDir(dir)` returns an explicit dir **verbatim**, and
several production call sites passed the **project** `.fusion/` dir:

- `store.getSecretsStore()` → `new CentralCore(store.getFusionDir())`
- dashboard secrets/proxy/node/secrets-sync/settings-sync routes → `new
CentralCore(store.getFusionDir())`

Each spawned a **stray per-project central DB**
(`<project>/.fusion/fusion-central.db`) seeded with **default** global
state (`globalMaxConcurrent=4`, empty secrets, default
`centralSettings`) that shadowed the real global DB whenever a
read/write hit one of those paths. Confirmed on disk: 14+ stray DBs at
default `4` vs the real `~/.fusion` at the operator's actual value.

## Fix

- Add `TaskStore.getGlobalSettingsDir()` returning the **resolved global
dir** (`string`); route the secrets store + all the affected dashboard
routes through it instead of `getFusionDir()`.
- `getSecretsStore()` also passes the global dir to `MasterKeyManager`
(co-locates the master key; makes the path test-exercisable).
- Add a `resolveGlobalDir()` **guard** that throws on a project-local
`.fusion/` dir (basename `.fusion` with a `.git` parent), with an
explicit `FUSION_ALLOW_PROJECT_LOCAL_GLOBAL_DIR` opt-out for
legitimately version-controlled custom global dirs. Inert under VITEST.

## Tests

- `global-settings-guard.test.ts` — guard rejects project/worktree
`.fusion` dirs, allows home + custom non-repo dirs.
- `store-secrets-store-global-dir.test.ts` — **symptom-based**:
`getSecretsStore()` creates the central DB in the global dir and
**never** spawns a stray project-local `fusion-central.db`.
- Added `getGlobalSettingsDir()` to route-test mock stores (the new
getter is now called by the routes).

## Operator note

Existing stray project-local `fusion-central.db` files (all
default/empty in practice) should be removed; on the affected machine
they were quarantined to `.legacy-central-db-backup-*` folders.

## Verification

- `pnpm --filter @fusion/core run typecheck` / `@fusion/dashboard`
typecheck — clean
- core guard + regression tests pass; previously-affected route suites
(proxy, nodes-sync, browse-directory, secrets-sync) pass (313/313)
- `pnpm check:changesets` — clean; eslint on changed files — clean

Companion to #1786 (global concurrency slider UI), which is independent.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- stage-review-badge-begin -->

---

<a href="https://stagereview.app/Runfusion/Fusion/pull/1787">
  <picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://stagereview.app/assets/gh-open-in-stage-dark.svg">
<img src="https://stagereview.app/assets/gh-open-in-stage-light.svg"
alt="Open in Stage">
  </picture>
</a>

<!-- stage-review-badge-end -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Fixed intermittent resets of global settings (including the global
concurrency cap).
* Ensured global settings/secrets are read from and written to the
correct global storage location rather than a project-local one.
* Added a safeguard to prevent using a project-local settings directory
when running inside a repository.

* **Tests**
* Added regression coverage for global directory resolution/guard
behavior.
* Updated route and secrets sync tests to validate the global directory
selection used for proxying and sync.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-25 23:33:43 -07:00
gsxdsm
e335acc235 feat: global concurrency slider (footer + dashboard) and scoped settings (#1786)
## What

Adds a **Global Max Concurrent** slider to two operator surfaces and
groups the Scheduling settings by scope.

- **Footer engine menu** (`EngineControlMenu`) and **Command Center →
Concurrency card** (`CommandCenterControls`) each get a global-cap
slider.
- **Settings → Scheduling** (`SchedulingSection`) now groups fields
under labeled **"Global — applies to all projects"** and **"This
project"** subheadings with scope badges (clearer on mobile, and
surfaces the existing `globalMaxConcurrent` field that was easy to
miss).

## How

Both sliders are backed by a single shared `useGlobalConcurrency` hook
(module-level store + subscribers), so they read/write **one source of
truth** and **revalidate after every `PUT /api/global-concurrency`**.
This avoids the last-writer-wins / stale-clobber races that two
independent per-component caches would cause (which would ironically
re-create a "global cap resets" symptom). The hook also:

- treats a fetch error as **non-interactive** (slider disabled, not
stuck showing `1` and persistable),
- surfaces a **save-state** indicator (Saving…/Saved/Save failed)
mirroring the project sliders,
- **flushes a pending edit on menu close / unmount** so a quick
drag-then-dismiss isn't silently dropped.

## Review

These race/feedback behaviors were hardened in response to a multi-agent
`/code-review` (correctness, adversarial, reliability, frontend-races
all flagged the per-component-cache approach). Independent of the
companion fix PR (global-settings reset).

## Verification

- `pnpm --filter @fusion/dashboard run typecheck` — clean
- eslint on changed files — clean
- Not yet browser-verified (next step).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- stage-review-badge-begin -->

---

<a href="https://stagereview.app/Runfusion/Fusion/pull/1786">
  <picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://stagereview.app/assets/gh-open-in-stage-dark.svg">
<img src="https://stagereview.app/assets/gh-open-in-stage-light.svg"
alt="Open in Stage">
  </picture>
</a>

<!-- stage-review-badge-end -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Added a global concurrency slider that applies across all projects.
* Global and per-project scheduling controls are now clearly separated
with scope labels and badges.
* The concurrency setting now stays in sync across different dashboard
views and saves automatically after brief pauses.

* **Bug Fixes**
  * Improved feedback for loading, saving, and error states.
* Prevented confusion between global settings and project-specific
settings, especially on smaller screens.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-25 23:27:23 -07:00
gsxdsm
f987470e6d refactor(FN-7039): delete legacy runWorkflowSteps execution path; graph is sole executor
Removes the legacy workflow-step EXECUTION path now that the graph records results
(U2): delete runWorkflowSteps(), the workflow-step seam + runWorkflowStep primitive
(runtime-primitives, workflow-node-handlers, authoritative-driver), and the legacy
execute() step blocks. Keeps task.workflowStepResults + its store write path (the
graph's sink) and executeWorkflowStep/executeScriptWorkflowStep (reused by the graph).

- Watchdog recoverCompletedTask now re-enters via maybeExecuteWorkflowGraph so the
  graph re-runs pending gates, records results, and owns the in-review/back-for-fix
  transition (KTD-2).
- maybeExecuteWorkflowGraph fails CLOSED (parks) when a store lacks
  getTaskWorkflowSelection AND the task has enabled pre-merge steps — closing the
  FN-7039 silent-skip class without changing minimal-store implementation runs (KTD-5).

KNOWN GAP (follow-up): the FN-4343 per-step workflowStepScopeEnforcement leak check
lived only in runWorkflowSteps and is NOT yet replicated on the graph path. Merge-time
File Scope enforcement (FileScopeViolationError, squash overlap) is unaffected.

Plan U4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 23:25:23 -07:00
gsxdsm
9fd4dedcae fix(review): resolve PR feedback on resolveGlobalDir guard
- Avoid the legacy-migration side effect on the hot path: run the cheap,
  read-only checks (basename === ".fusion" && parent has .git) FIRST, and
  only call resolveGlobalDirForHome() (which can perform a one-time rename)
  when a dir actually looks project-local.
- Normalize paths before the home-dir comparison (realpathSync when present,
  else resolve) so a trailing slash, doubled separator, or symlinked home
  doesn't make the legitimate home global dir trip the guard.
- Harden the browse-directory regression test: the mock returns a global dir
  DISTINCT from getFusionDir() and asserts CentralCore is constructed with the
  global dir, so a revert to getFusionDir() now fails the test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 23:17:02 -07:00
gsxdsm
1ebb518698 fix(review): resolve PR feedback on global concurrency hook
- Double-commit race: null pendingValueRef synchronously at commit() start
  so the close-flush + unmount-cleanup guards can't both fire and send a
  duplicate PUT for the same value.
- Clamp ceiling: clamp setValue against max(SLIDER_BASE_MAX, currentValue)
  instead of Number(raw) (which had no effective upper bound for
  programmatic callers).
- Out-of-band staleness: force-revalidate on each activate so a Settings-modal
  save (which writes globalMaxConcurrent directly, bypassing this store) is
  reflected when a slider surface reopens.
- Load-error label: add an explicit error branch in both EngineControlMenu
  and CommandCenterControls so a failed initial load shows "Load failed"
  instead of "Ready" while the slider is disabled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 23:05:56 -07:00
gsxdsm
795963bcf6 fix: land stranded test-minimality follow-ups (core bounding, watchdog, gate-aware delegation) (#1785)
## Why this exists

PR #1780 was merged while its head was only the first commit
(`c5fbe08c0`, the original bounded-lane fix). Two follow-up commits were
pushed to the branch **after** that merge and never landed on `main`.
This PR lands them.

Confirmed absent from `main`: `existingChangedTestFilesInPackage`,
`GATE_COVERED_MEMORY_ENVELOPE_PACKAGES`, `CORE_SCOPED_AFFECTED_PACKAGE`,
the 13-min watchdog ceiling, and `workers=4` — all 0 occurrences on
origin/main.

## What's in here (the two stranded commits)

**1. Greptile P1/P2 review fixes (`8297762`)**
- **P2:** filter directly-changed test files to paths that still exist
on disk (`existingChangedTestFilesInPackage`) so deleted/renamed `.test`
paths never reach `vitest run` positionally; all-deletions diff falls
into the delegate path.
- **P1:** gate-coverage-aware delegation
(`GATE_COVERED_MEMORY_ENVELOPE_PACKAGES`) — engine delegation keeps its
accurate "curated subset ran above" note; dashboard/core delegation now
`console.warn`s that the gate doesn't cover them (CI full-suite is the
backstop) instead of a silent false-green.

**2. Core bounding + watchdog + workers (`2cff1864c`) — the actual
remedy for the remaining timeouts**
- **`@fusion/core` is now a bounded memory-envelope package.** It was
the remaining timeout path: core is the hub ~everything imports (~354
test files), so a core source edit made `vitest --changed` expand to
~the whole core suite and blow past the engine's 15-min kill → SIGKILL +
task restart. PR #1780 only covered engine/dashboard.
- **Watchdog `changed` ceiling 20min → 13min** so the script fails a
runaway lane itself (exit 124, no restart) *before* the engine's 15-min
kill restarts the whole task.
- **Scoped-affected workers 1 → 4** (operator decision) — the fan-out
guard now bounds the set, so the OOM scenario that justified `=1` is
prevented at the source. Heap stays 6144MB/worker.

## Verification
- `scripts/__tests__/test-changed.test.mjs` 117/117;
`run-vitest-watchdog.test.mjs` 15/15; eslint clean. (Re-confirmed on
this branch.)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- stage-review-badge-begin -->

---

<a href="https://stagereview.app/Runfusion/Fusion/pull/1785">
  <picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://stagereview.app/assets/gh-open-in-stage-dark.svg">
<img src="https://stagereview.app/assets/gh-open-in-stage-light.svg"
alt="Open in Stage">
  </picture>
</a>

<!-- stage-review-badge-end -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Increased parallel test execution for scoped runs in engine and
dashboard areas.
* Added dedicated scoped test handling for core with bounded resources.

* **Bug Fixes**
* Test selection now ignores deleted or renamed test files, preventing
failed runs on missing paths.
* Improved fallback handling when no directly changed tests remain in a
package.
* Adjusted watchdog timing for changed-test runs to better match
expected limits.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-25 23:00:37 -07:00
gsxdsm
1699c60033 fix: anchor rootDir at the git toplevel so subdir runs don't skip tests (#1785)
greptile: my earlier existence-check anchor was necessary but insufficient.
`rootDir` (= process.cwd() when FUSION_PROJECT_DIR is unset) drives ALL workspace
discovery (readWorkspacePatterns / listWorkspacePackageInfos /
packageHasVitestConfig). Launched from a package subdir, cwd-based discovery
found no packages, so decideExecutionPlan saw "no affected package", ran only the
gate, and exited successfully WITHOUT running the live changed package tests.

Fix the root cause: resolveRepoRoot() resolves the git toplevel as the fallback
(FUSION_PROJECT_DIR still the explicit override; cwd only when git can't report a
toplevel). This is correct from any cwd inside the repo, including a git worktree
(how the engine runs per-task verification). repoRootForExistence is now
redundant and removed; the existence check defaults back to rootDir.

Demonstrated: resolveRepoRoot() from packages/core (no FUSION_PROJECT_DIR) now
resolves the repo root and finds the workspace. +1 regression test. 121/121.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 22:56:10 -07:00
gsxdsm
7b358b74b5 feat(FN-7039): drive progress bar + Workflow tab from graph-written results
getUnifiedTaskProgress reads task.workflowStepResults (graph-written in U2) and
no longer needs workflowStepNameLookup — names come from result.workflowStepName.
Removed the lookup prop + fetchWorkflowSteps-name plumbing end-to-end (App,
MainContent, RightDock, Board, Column, Lane, WorktreeGroup, TaskCard). Added the
running state (pending + startedAt) and a distinct advisory_failure (amber, non-
blocking) vs failed (red) treatment; advisory_failure counts as complete.

Plan U3.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 22:48:50 -07:00
gsxdsm
e29954e50d Merge remote-tracking branch 'origin/main' into feature/tasks-take-too-long
# Conflicts:
#	scripts/__tests__/test-changed.test.mjs
2026-06-25 22:41:18 -07:00
gsxdsm
c61164853c test(FN-7039): update stale visitedNodeIds fixtures for code-review optional-group
Prior WIP added a default-on code-review optional-group to builtin:coding on the
success path (execute -> browser-verification -> code-review -> review). 9 exact
visitedNodeIds expectations across 3 suites predated that node and were failing.
Updated expectations to match the real traversal (insert code-review in position).
No product code touched; no assertions weakened.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 22:38:12 -07:00
gsxdsm
7b19f9796c test: remove real-time waits from the slowest test files (FN-5048) (#1784)
Removes real wall-clock waits and per-test rebuilds from the slowest
test files, replacing them with deterministic seams. **No assertions
weakened, no timeouts widened, no retries added** — this is anti-pattern
removal per FN-5048, verified by re-running each file.

## Changes

| File | What | Result |
|---|---|---|
| `dashboard/.../insights-routes.test.ts` | Boot server+store **once**
in `beforeAll` (was `createServer` + `TaskStore.init` per test ×24);
reset insight tables per test for isolation; drive sweeper via fake
timers | test-exec **~3.7s → ~0.8s** |
| `core/.../db.test.ts` | Fixed 150ms write-lock hold → manual stdin
signal-release (keeps the real OS-lock contention under test); fixed a
real EPIPE on redundant release | 152 pass, non-flaky / 8 runs; −300ms
dead wait |
| `core/.../mission-store.test.ts` | 4 real `setTimeout` sleeps (only
there to force distinct timestamps) → `vi.setSystemTime` controlled
clock | anti-pattern removed |
| `core/.../agent-store.test.ts` | 1 real ordering-sleep → injected
`renewedAt` clock; **assertions strengthened** to pin exact timestamp
values | anti-pattern removed |
| `engine/.../in-process-runtime.test.ts` | Fake the one real 25ms
sleep; drop its inflated 30s per-test timeout | anti-pattern removed |

## Honest accounting
- The **real wins** are `insights-routes` (per-test server boot
eliminated, ~75% execution-time cut) and `db` (dead lock-hold removed).
- The **timestamp-sleep removals** (mission-store, agent-store,
in-process-runtime) are small absolute wins — the headline per-file
durations (16–25s) were **full-suite shard contention, not in-file dead
time** (each runs in 3–10s isolated). But they eliminate the FN-5048
real-wait anti-pattern, so a hub edit no longer drags real sleeps into
every `--changed` selection.
- **`workflow-routes.test.ts` was evaluated for splitting and
deliberately NOT split.** A measured A/B showed the 4-way split
*regressed* wall-clock (6s → 11s): the file is import/transform-bound
(per-file esbuild + `@fusion/core`/express import ≈ 5s > the ~4.3s test
runtime), and per-test store migration was already amortized by
`installInMemoryDbSnapshot`. Splitting only multiplies the dominant
fixed cost. Left intact.

## Verification
- `core` 612/612, `dashboard` 24/24, `engine` 78/78 (file-scoped).
- `tsc --noEmit` clean on all 3 packages; eslint clean.

Follow-up (not in this PR): `scripts/test-timings.json` is stale (its
former #1 file no longer exists) — refresh via `pnpm test:velocity --
--measure --write-report` so the watchdog budgets and velocity report
reflect reality.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- stage-review-badge-begin -->

---

<a href="https://stagereview.app/Runfusion/Fusion/pull/1784">
  <picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://stagereview.app/assets/gh-open-in-stage-dark.svg">
<img src="https://stagereview.app/assets/gh-open-in-stage-light.svg"
alt="Open in Stage">
  </picture>
</a>

<!-- stage-review-badge-end -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Tests**
* Made several test suites more deterministic by replacing real-time
delays with controlled timers and fixed timestamps.
* Improved lock and task checkout tests to use manual release signals,
reducing timing-related flakiness.
* Streamlined route test setup/teardown for faster, more reliable runs.
* Added safer cleanup around timer-based tests to avoid intermittent
failures.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-25 22:35:53 -07:00
gsxdsm
cb1691f473 feat(FN-7039): record graph workflow-step results into task.workflowStepResults
Enabled optional-group nodes now upsert their outcome into the existing
task.workflowStepResults field keyed by node id, and emit [pre-merge] logs at
parity with the legacy runWorkflowSteps path. Disabled groups stay byte-inert.
Reuses the existing WorkflowStepResult type + store.updateTask path (no new
table/type/store method). Unblocks the unified progress bar for graph-run steps.

Plan U2.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 22:33:08 -07:00