Workflow settings now keep newer pending edits when earlier save requests finish.\n\n- Snapshot pending workflow values before saving so the request cannot mutate under the save.\n- Clear only keys whose pending value still matches the completed request in Workflow Settings and Project Models.\n- Cover same-key, clear-to-default, and model-lane edits made while saves are in flight.\n- Add a patch changeset for the published Fusion package.\n\nFiles changed:\n .changeset/fn-7451-workflow-settings-save-race.md | 7 ++\n .../app/__tests__/settings-sections.test.tsx | 109 ++++++++++++++++++-\n .../app/components/WorkflowSettingsPanel.tsx | 21 +++-\n .../__tests__/WorkflowSettingsPanel.test.tsx | 121 ++++++++++++++++++++-\n .../settings/sections/ProjectModelsSection.tsx | 25 ++++-\n 5 files changed, 272 insertions(+), 11 deletions(-)
Fusion-Task-Id: FN-7451
Fusion-Task-Lineage: 82f5e1cf-fabb-4fc6-936c-f42dcd9337ac
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Collapse the mobile direct chat header into the shared top row.
- Move the mobile direct-thread back button and session switcher into ViewHeader actions.
- Hide the redundant mobile thread header while preserving desktop thread identity and context details.
- Update mobile chat styling, docs, changeset, and header contract tests for the single-row layout.
Files changed:
.changeset/fn-7450-mobile-chat-header.md | 7 +
docs/dashboard-guide.md | 3 +-
packages/dashboard/app/components/ChatView.css | 53 +++++-
packages/dashboard/app/components/ChatView.tsx | 197 +++++++++++----------
.../__tests__/ChatView.core-contracts.test.tsx | 48 ++---
.../components/__tests__/ChatView.mobile.test.tsx | 76 ++++++--
6 files changed, 256 insertions(+), 128 deletions(-)
Fusion-Task-Id: FN-7450
Fusion-Task-Lineage: c266a9b8-7fb1-410e-9c35-adad4c6a2d47
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Command Center token analytics now attributes Last 30 days model usage from durable per-model timestamps.
- Filter per-model token buckets by their own last-used timestamps while preserving legacy task-level fallback rows.
- Count unique tasks across totals, groups, and time series to avoid double-counting multi-model usage.
- Cover model/provider groups, API routing, and TokensArea rendering for Last 30 days multi-model data.
- Add a patch changeset for the published CLI package.
Files changed:
.changeset/fn-7448-token-usage-last-30-days.md | 7 ++
.../core/src/__tests__/token-analytics.test.ts | 128 +++++++++++++++++++--
packages/core/src/token-analytics.ts | 92 ++++++++++-----
.../areas/__tests__/TokensArea.test.tsx | 50 ++++++++
.../register-command-center-routes.test.ts | 86 ++++++++++++++
5 files changed, 327 insertions(+), 36 deletions(-)
Fusion-Task-Id: FN-7448
Fusion-Task-Lineage: 5d5c976b-5623-4d7a-a728-5a3959deac1d
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Return successful GitHub issue import and close flows to the issue list.
- Clear the selected GitHub issue and switch mobile preview back to the list after successful import or close actions.
- Preserve the selected preview on failures so users can retry with the existing error affordance.
- Add regression coverage for desktop and mobile import/close success and failure navigation states.
- Document the post-import list reset behavior and add a patch changeset.
Files changed:
.changeset/fn-7442-github-import-return-list.md | 7 +
docs/dashboard-guide.md | 2 +-
.../dashboard/app/components/GitHubImportModal.tsx | 20 +-
.../__tests__/GitHubImportModal.test.tsx | 210 +++++++++++++++++++--
4 files changed, 218 insertions(+), 21 deletions(-)
Fusion-Task-Id: FN-7442
Fusion-Task-Lineage: e334a7c1-68de-48f7-be31-b036ba741685
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Keep Anthropic authentication options grouped at the top of Settings while preserving auth-state sections.
- Prioritize Claude CLI, Anthropic Subscription, and Anthropic API Key before other providers in the shared card order.
- Render supported CLI and non-CLI auth cards from one sorted list so other CLI providers cannot split Anthropic entries.
- Cover the mixed CLI plus Anthropic subscription/API-key ordering case and add a patch changeset.
Files changed:
.changeset/fn-7436-auth-anthropic-order.md | 7 ++
.../__tests__/AuthenticationSection.test.tsx | 103 ++++++++++++++++++++-
.../settings/sections/AuthenticationSection.tsx | 91 ++++++++++--------
3 files changed, 160 insertions(+), 41 deletions(-)
Fusion-Task-Id: FN-7436
Fusion-Task-Lineage: 653a0126-ea2b-43a6-a829-dc72dc47bfde
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
When a task adds/removes a dependency without regenerating the lockfile,
the inferred `pnpm install --frozen-lockfile` (and yarn/bun equivalents)
in the AI-merge clean room fails with ERR_PNPM_OUTDATED_LOCKFILE, dead-
ending the merge. Detect that specific frozen-refusal and retry once
non-frozen (pnpm gets explicit --no-frozen-lockfile to override any CI
default), regenerating the lockfile and recomputing the install marker.
A configured worktreeInitCommand keeps its authoritative frozen intent
and still hard-fails. Surfaced via the merge:ai-deps-sync run-audit event.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Prevent duplicate Refine Further activations from interrupting an active completed-summary refinement stream.
- Add a synchronous single-flight guard and loading state for summary refinement.
- Preserve the connected planning stream when a same-turn generation-in-progress response is reported.
- Cover rapid desktop/mobile activation and active-stream conflict behavior with regression tests.
- Add a patch changeset for the published Fusion package.
Files changed:
.../fn-7431-planning-refine-single-flight.md | 7 +
.../dashboard/app/components/PlanningModeModal.tsx | 41 +++++-
.../PlanningModeModal.planning-flow.test.tsx | 156 +++++++++++++++++++++
3 files changed, 201 insertions(+), 3 deletions(-)
Fusion-Task-Id: FN-7431
Fusion-Task-Lineage: fc876022-da86-409e-818d-8c4798b49aa5
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Refresh the test velocity baseline and coverage so quarantine counts come from the live ledger.\n\n- Update the weekly baseline report to show zero active quarantines and a neutral delta.\n- Strengthen the report-only regression test to cover stale report and history quarantine values.\n- Document the FN-7420 requirement near the regression scenario.\n\nFiles changed:\n docs/test-velocity-baseline.md | 10 +++++-----\n scripts/__tests__/test-velocity-baseline.test.mjs | 10 +++++++---\n 2 files changed, 12 insertions(+), 8 deletions(-)
Fusion-Task-Id: FN-7420
Fusion-Task-Lineage: 9144ddb5-3a72-4a37-a1d1-471871f3cbc4
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Keep dashboard project selection in the URL so refreshing or sharing the page retains the active project.
- Hydrate current project state from the existing ?project= query parameter before falling back to cached or global defaults.
- Update project selection, setup completion, overview, and unregister flows to preserve or clear the project URL parameter without dropping other URL state.
- Cover URL-driven project persistence and query/hash preservation with hook tests.
- Document the refresh-safe project URL behavior and add a patch changeset.
Files changed:
.changeset/fn-7416-project-url-persistence.md | 7 +++
docs/dashboard-guide.md | 2 +
packages/dashboard/app/App.tsx | 2 +-
.../app/hooks/__tests__/useCurrentProject.test.ts | 64 ++++++++++++++++++++++
.../app/hooks/__tests__/useProjectActions.test.ts | 40 +++++++++++++-
packages/dashboard/app/hooks/useCurrentProject.ts | 54 ++++++++++++++++--
packages/dashboard/app/hooks/useProjectActions.ts | 5 ++
packages/dashboard/app/utils/projectUrlState.ts | 24 ++++++++
8 files changed, 190 insertions(+), 8 deletions(-)
Fusion-Task-Id: FN-7416
Fusion-Task-Lineage: 2d640ae6-629f-4632-9014-986320acfef5
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Refresh the velocity baseline artifacts so live quarantine counts are reflected consistently.
- Add regression coverage for live quarantine ledger counts overriding stale report and history values.
- Update the weekly velocity baseline report to show the current quarantine count and deltas.
- Append the latest measured velocity history row with quarantine count one.
Files changed:
docs/test-velocity-baseline.md | 22 ++---
scripts/__tests__/test-velocity-baseline.test.mjs | 75 +++++++++++++++
scripts/test-velocity-history.json | 112 ++++++++++++++++++++++
3 files changed, 198 insertions(+), 11 deletions(-)
Fusion-Task-Id: FN-7414
Fusion-Task-Lineage: 7c6cd47c-482d-426c-a714-79da33d4591d
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
## Summary
Fixes all failing tests in the non-blocking full-suite CI run
[28561416741](https://github.com/Runfusion/Fusion/actions/runs/28561416741)
on main.
## Root causes and fixes
### 1. Missing `formatModelMarkerDetails` mock export (5 files, 17
tests)
Production code in `reviewer.ts` and `triage.ts` calls
`formatModelMarkerDetails()` after resolving an agent session to build a
model-marker log line. Five test files mocked `../pi.js` without
exporting this function, so every reviewer/triage/restart path threw
`[vitest] No "formatModelMarkerDetails" export is defined` before
reaching finalization assertions.
**Files:** `reviewer-prompt-single-source`,
`plan-review-unavailable-recovery`, `triage-fast-mode-workflow-variant`,
`triage-stuck-requeue-preserve-draft`, `restart.integration`
### 2. Outdated worktree acquisition assertions (2 files, 5 tests)
A production fix added `git symbolic-ref --short
refs/remotes/origin/HEAD` resolution to ensure fresh task worktrees
never inherit the root checkout's ambient HEAD. The tests didn't account
for this new exec call or the appended start point.
**Files:** `worktree-acquisition-backend`,
`worktree-acquisition-worktrunk`
### 3. Stale workflow compiler tests (1 file, 2 tests)
FN-7360 removed the linear `WorkflowStep` compiler and `/compile`
endpoint, making `parseWorkflowIr` the sole validity gate. Branching
custom workflows are now valid on the graph interpreter. Two dashboard
tests still asserted 422 for branching IR.
**File:** `workflow-routes`
### 4. Graph cutover production fixes + test migrations (from closed PR
#1869)
- `executor.ts`: `safeLogEntry()` wrapper prevents synchronous
`store.logEntry` throws from aborting pause/abort/finalize control flow
- `workflow-authoritative-driver.ts`: built-in auxiliary custom nodes
(completion-summary, optional-groups) pass through as success instead of
throwing
- Test migrations across engine, CLI, dashboard, and desktop for
graph-native runtime paths
## Verification
- All affected tests pass: engine (87 tests across 7 files), dashboard
(53 tests), plus the cherry-picked migration tests
- Merge gate (`pnpm test:gate`): 319 engine-core + 63 CI-shape tests
green
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added support for branching workflow content in more places, including
workflow creation and selection.
* Added a new shared runtime tool available to plan/review agents for
writing task prompts.
* **Bug Fixes**
* Improved task failure handling so retries now end cleanly instead of
bouncing through extra states.
* Made pause, recovery, and worktree-related behavior more reliable
during long-running operations and restarts.
* Updated Android release automation to use JDK 21.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Missing mock export (5 files, 17 tests):
- reviewer-prompt-single-source, plan-review-unavailable-recovery,
triage-fast-mode-workflow-variant, triage-stuck-requeue-preserve-draft,
restart.integration: add formatModelMarkerDetails to the ../pi.js mock.
Production code calls this after resolving an agent session, but the test
mocks were missing the export, causing all reviewer/triage/restart paths
to throw before reaching finalization assertions.
Outdated worktree assertions (2 files, 5 tests):
- worktree-acquisition-backend, worktree-acquisition-worktrunk: update
assertions for the new git symbolic-ref origin/HEAD resolution call and
the appended start point in git worktree add (worktree isolation fix).
Stale workflow compiler tests (1 file, 2 tests):
- workflow-routes: FN-7360 removed the linear compiler /compile endpoint
and made parseWorkflowIr the sole validity gate. Branching custom
workflows are now valid on the graph interpreter. Updated the two stale
tests that asserted 422 for branching IR to assert 201/200 instead.
Restore the board/list search affordance after users dismiss an active desktop search.
- Keep the non-mobile open-search button available once a closed search has an empty query.
- Cover empty-close and parent-cleared populated search flows in Header tests.
- Add a patch changeset for the published Fusion package.
Files changed:
.changeset/restore-board-search-trigger.md | 7 ++++
packages/dashboard/app/components/Header.tsx | 13 +++++---
.../app/components/__tests__/Header.test.tsx | 38 ++++++++++++++++++----
3 files changed, 46 insertions(+), 12 deletions(-)
Fusion-Task-Id: FN-7409
Fusion-Task-Lineage: 9cb4ff80-8490-43be-8d18-a3f292603ecb
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Prevent task-bound callers from soft-deleting the task they are currently executing.
- Add a TaskSelfDeleteError guard in TaskStore.deleteTask before mutation or audit emission.
- Pass the current task id through the fn_task_delete audit context so CLI tool calls inherit the store invariant.
- Cover self-delete rejection and cross-task deletion allowance in core and CLI tests.
- Add a patch changeset for the published CLI package.
Files changed:
.changeset/fn-7411-self-delete-guard.md | 7 +++
.../task-delete-allow-resurrection.test.ts | 48 ++++++++++++++++-
packages/cli/src/extension.ts | 2 +
.../src/__tests__/store-self-delete-guard.test.ts | 60 ++++++++++++++++++++++
packages/core/src/store.ts | 22 +++++++-
5 files changed, 136 insertions(+), 3 deletions(-)
Fusion-Task-Id: FN-7411
Fusion-Task-Lineage: 50028769-5396-4435-84fb-2ae182315e81
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Reviews no longer fail on formatting. Three changes to how reviewer/gate
verdicts are parsed and how retries reset state:
- Approval leniency: a review that clearly approves in prose passes even
without a structured verdict (proseSignalsClearApproval, with a
revise/reject/negated-approval guard so a rejection is never flipped). Any
APPROVE*/APPROVAL verdict token classifies as approved. Shared by the
reviewer/plan-review parser and the code-review/browser-verification gate.
- Prose + trailing JSON: extractJsonObjectCandidates does a string-aware
balanced-brace scan and prefers the last object, so a model that emits
reasoning prose then a trailing {"verdict":...} payload parses correctly.
An explicit "Verdict:" heading/line still takes precedence over an
incidental/example JSON object.
- Malformed handling: executeWorkflowStep retries the fallback model on
malformed output (not just timeout); malformed gate output becomes a
non-blocking advisory (a genuine parsed REVISE still blocks).
- Retry clears prior terminal step failures (incl. optional gate nodes like
code-review) after the task leaves the mergeable in-review column, so a
retry starts clean without an auto-merge race.
Fail-closed merge / PR-review / mission-verification gates are unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The initial-plan textarea gated duplicate createPlanningDraft calls only
on draftSessionIdRef, which is populated after the create round-trip
resolves. Keystrokes arriving while a create was in flight each passed the
guard and spawned a fresh draft. Add a synchronous draftCreateInFlightRef
sentinel that suppresses concurrent creates and clears on failure so a
later keystroke can retry. Includes an in-flight-concurrency regression test.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>