Clamp the workflow editor left sidebar and its children so long content cannot create horizontal scroll.
- Hide horizontal overflow on desktop and list-stage sidebar layouts while preserving vertical scrolling.\n- Allow nested sidebar sections, lists, palette controls, and code snippets to shrink or wrap within the sidebar.\n- Add CSS contract coverage for the sidebar overflow behavior across desktop and mobile list-stage layouts.\n\nFiles changed:\n .../app/components/WorkflowNodeEditor.css | 25 ++++++++++++\n .../__tests__/WorkflowNodeEditor.css.test.ts | 47 ++++++++++++++++++++++\n 2 files changed, 72 insertions(+)
Fusion-Task-Id: FN-6379
Fusion-Task-Lineage: 9da54129-faaf-4a81-906b-d76e9746b426
Refine the task-detail chat composer so the send action stays narrow and inline with the input.
- Replace the composer placeholder with the steering-focused copy.
- Convert the send button to an accessible icon-only control with loading state labels.
- Keep the send control inline at mobile breakpoints and cover the behavior in tests and docs.
Files changed:
docs/dashboard-guide.md | 2 +-
packages/dashboard/app/components/TaskChatTab.css | 14 +++++++----
packages/dashboard/app/components/TaskChatTab.tsx | 11 ++++++---
.../app/components/__tests__/TaskChatTab.test.tsx | 27 ++++++++++++++++++++--
4 files changed, 44 insertions(+), 10 deletions(-)
Fusion-Task-Id: FN-6369
Fusion-Task-Lineage: b7e0717f-4cba-4380-a08a-e01fc12985e3
Recover stale iOS document scroll after returning to the Fusion dashboard.
- Add an iOS-only restore hook that clears orphaned body offsets and scrolls the document back to the origin when unlocked.
- Wire the restore reset from the dashboard app shell for mobile layouts.
- Cover visible/page-show restores, platform no-ops, active-lock guards, and orphaned style cleanup.
- Document the mobile restore drift solution for future regressions.
Files changed:
.../mobile-ios-restore-document-scroll-drift.md | 59 ++++++++++
packages/dashboard/app/App.tsx | 4 +-
.../hooks/__tests__/useMobileScrollLock.test.ts | 121 ++++++++++++++++++++-
.../dashboard/app/hooks/useMobileScrollLock.ts | 61 +++++++++++
4 files changed, 243 insertions(+), 2 deletions(-)
Fusion-Task-Id: FN-6364
Fusion-Task-Lineage: 9243cab8-5fbb-4332-ac4d-aabefde4161c
Adds an in-transcript control for returning to the newest task chat output after reviewing older messages.
- Track whether the task chat transcript is near the bottom and preserve live-follow behavior.
- Render an accessible sticky Latest button when populated transcripts are scrolled up, including mobile styling.
- Cover empty/loading, desktop, mobile, and click-to-jump behavior in TaskChatTab tests.
- Document the Latest jump affordance in the dashboard guide.
Files changed:
docs/dashboard-guide.md | 2 +-
packages/dashboard/app/components/TaskChatTab.css | 40 +++++++++++
packages/dashboard/app/components/TaskChatTab.tsx | 40 ++++++++++-
.../app/components/__tests__/TaskChatTab.test.tsx | 82 ++++++++++++++++++++++
4 files changed, 162 insertions(+), 2 deletions(-)
Fusion-Task-Id: FN-6359
Fusion-Task-Lineage: 9b4a3533-2969-4f0d-a4de-6ba895662726
Reset mobile keyboard restore sampling so collapsed viewports clear stale keyboard-open metrics.
- Add a restore-specific sampling path for visibilitychange/pageshow that can reset the viewport baseline and bypass the impossible-sample hold once.
- Preserve the existing in-session impossible-sample guard and tail polling behavior for normal focus/resize updates.
- Cover iOS restore, stale offset drift, genuinely open restored keyboards, and Android-style shrink reset cases.
- Document the mobile keyboard restore stale viewport fix for future UI debugging.
Files changed:
.../mobile-keyboard-restore-stale-viewport.md | 59 ++++++++
.../app/hooks/__tests__/useMobileKeyboard.test.ts | 160 +++++++++++++++++++++
packages/dashboard/app/hooks/useMobileKeyboard.ts | 75 +++++++---
3 files changed, 275 insertions(+), 19 deletions(-)
Fusion-Task-Id: FN-6362
Fusion-Task-Lineage: 3919d892-b2d5-419a-abeb-84ac298ca2d5
Adds bounded retry handling so stale Fusion test temp roots are reclaimed instead of leaking after transient removal failures.
- Share prefix-scoped pruning between isolated HOME and worker temp roots.
- Retry rm-rf on transient busy/non-empty failures and treat ENOENT as successful cleanup.
- Warn once with bounded child diagnostics after persistent prune failures.
- Cover worker and home pruning retry, failure, and ENOENT behavior in script tests.
Files changed:
scripts/__tests__/test-changed.test.mjs | 118 ++++++++++++++++++++++++++++++++
scripts/test-changed.mjs | 84 ++++++++++++++---------
2 files changed, 168 insertions(+), 34 deletions(-)
Fusion-Task-Id: FN-6371
Fusion-Task-Lineage: a81e6849-5eb0-4bc0-8030-9f8eaed4e35a
Stabilizes memory extraction and audit route tests by restoring the expected createFnAgent mock behavior.\n\n- Add a focused helper that returns structured insight extraction output from the mocked AI session.\n- Reset the mock around memory extract and audit tests so earlier route tests cannot leak incompatible behavior.\n\nFiles changed:\n .../src/__tests__/routes-settings.test.ts | 28 ++++++++++++++++++++++\n 1 file changed, 28 insertions(+)
Fusion-Task-Id: FN-6363
Fusion-Task-Lineage: d4b93c51-3d30-4a97-90e9-72e2dd660501
Keep triage planning from advancing or continuing work after a task is paused.
- Abort active triage sessions and reviewer subagents when task updates mark the task paused.
- Skip approved-spec recovery and final approved-spec transitions while a task remains paused.
- Add regression coverage for paused planning, pause-driven aborts, and published package changeset metadata.
Files changed:
.changeset/pause-triage-planning.md | 5 +
.../src/__tests__/triage-pause-abort.test.ts | 237 +++++++++++++++++++++
packages/engine/src/triage.ts | 57 +++++
3 files changed, 299 insertions(+)
Fusion-Task-Id: FN-6361
Fusion-Task-Lineage: 33d849d5-1461-49ae-9fe0-be98b534ac35
Task-detail Chat now accepts guidance even when no steerable session is active and queues it for the next run.
- Keep the task chat composer enabled whenever there is draft text and no send is in flight.
- Replace the blocking no-session hint with active-session versus queued-for-next-session copy.
- Extend TaskChatTab coverage across idle, paused, inactive CLI, and send-in-flight states.
- Quarantine the unrelated flaky dashboard settings route test observed during broad verification.
Files changed:
packages/dashboard/app/components/TaskChatTab.tsx | 21 ++--
.../app/components/__tests__/TaskChatTab.test.tsx | 135 +++++++++++++++++----
packages/dashboard/vitest.config.ts | 5 +-
scripts/lib/test-quarantine.json | 5 +
4 files changed, 133 insertions(+), 33 deletions(-)
Fusion-Task-Id: FN-6354
Fusion-Task-Lineage: b0f0d033-bb4d-4eaa-a15d-f06b82643ade
Expose the docs README index suite as a focused CLI test lane and document its deterministic invocation.
- Add a package script for running only the docs README index Vitest file.
- Lock the package-config contract around the new script and dashboard quality runner expectations.
- Clarify the CI shard docs to pass Vitest shard flags without a bare separator.
Files changed:
docs/contributing.md | 2 +-
packages/cli/package.json | 1 +
packages/cli/src/__tests__/package-config.test.ts | 37 ++++++++++++++++++-----
3 files changed, 31 insertions(+), 9 deletions(-)
Fusion-Task-Id: FN-6355
Fusion-Task-Lineage: 2a02bc5f-2407-4bad-8aed-afa519826ce7
Stabilize the cli-agent re-entry regression test by awaiting the original run after the replacement session succeeds.
- Keep the first cli-agent run promise instead of dropping it with void.
- Assert the active task session still points at the first PTY before simulating re-entry.
- Kill and await the first session at the end so no hub or store work outlives teardown.
Files changed:
packages/engine/src/__tests__/cli-agent-executor.test.ts | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-6341
Fusion-Task-Lineage: 3e365f21-0d05-496a-adec-aa782aa83503
Updates the roadmap store schema-version expectation to match the current core migration level.
- Rename the schema-version test from 114 to 116.
- Assert the roadmap store database schema version is 116 after init.
Files changed:
.../fusion-plugin-roadmap/src/store/__tests__/roadmap-store.test.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Fusion-Task-Id: FN-6348
Fusion-Task-Lineage: 0db4a46d-1d75-4eb1-bfeb-0483eeddb689
Record stepless built-in workflow defaults so zero-step selections survive task creation.\n\n- Return an explicit workflow selection for built-in workflows that compile to zero steps.\n- Cover both normal and reserved-id task creation for coding and interpreter-deferred stepwise defaults.\n- Add a patch changeset for the published Fusion package.\n\nFiles changed:\n .changeset/FN-6335-zero-step-workflow-defaults.md | 5 +++++\n packages/core/src/__tests__/builtin-workflows.test.ts | 14 ++++++++++++++\n packages/core/src/store.ts | 4 +++-\n 3 files changed, 22 insertions(+), 1 deletion(-)
Fusion-Task-Id: FN-6335
Fusion-Task-Lineage: 521ef05d-bef7-4d26-9f6a-592363f522d1
Rescues the database recovery corruption test by reducing its fixture size and removing its quarantine.
- Reduce recovery test fixture rows so sqlite3 .recover is not overfed while still corrupting a B-tree page.
- Re-enable packages/core/src/__tests__/db.test.ts in the core Vitest config.
- Remove the db recovery test entry from the quarantine ledger.
Files changed:
packages/core/src/__tests__/db.test.ts | 5 +++--
packages/core/vitest.config.ts | 1 -
scripts/lib/test-quarantine.json | 5 -----
3 files changed, 3 insertions(+), 8 deletions(-)
Fusion-Task-Id: FN-6334
Fusion-Task-Lineage: c4555976-fe98-4f25-a1b5-e70bfd991b16
Display user steering comments alongside agent output and wake immediate-response agents when new messages are sent.
- Render persisted and optimistic user messages in the task chat transcript with mobile styling.
- Propagate updated task detail data after sends and roll back optimistic messages on failures.
- Cover steering route validation, immediate heartbeat wakeups, chat rendering, and workflow alias round-trips.
- Add a patch changeset for the published CLI package.
Files changed:
.changeset/fn-6345-task-chat-user-messages.md | 5 +
packages/dashboard/app/components/TaskChatTab.css | 32 ++++
packages/dashboard/app/components/TaskChatTab.tsx | 170 ++++++++++++++++-----
.../dashboard/app/components/TaskDetailModal.tsx | 8 +-
.../app/components/__tests__/TaskChatTab.test.tsx | 150 +++++++++++++++++-
.../app/components/__tests__/board-mobile.test.tsx | 2 +-
.../__tests__/workflow-flow-mapping.test.ts | 4 +-
.../app/components/workflow-flow-mapping.ts | 4 +-
.../src/__tests__/routes-tasks-ops.test.ts | 86 +++++++++++
9 files changed, 414 insertions(+), 47 deletions(-)
Fusion-Task-Id: FN-6345
Fusion-Task-Lineage: 0355cc67-bd23-4e90-9034-bbaae277cfd6
Classify the archive FTS churn and merge-queue hook timeouts as deterministic test-cost fixes instead of quarantines.
- Reduce the archive FTS churn fixture while preserving rebuild shrinkage and search coverage.
- Use in-memory TaskStore setup for merge-queue cases that do not require disk persistence.
- Keep disk-backed coverage for legacy migration and competing-store lease arbitration.
- Verification: targeted archive FTS + merge-queue run passed in 7.47s versus 27.69s before the fix.
Files changed:
.../core/src/__tests__/archive-db-fts-maintenance.test.ts | 6 +++---
packages/core/src/__tests__/store-merge-queue.test.ts | 15 ++++++++++-----
2 files changed, 13 insertions(+), 8 deletions(-)
Fusion-Task-Id: FN-6325
Fusion-Task-Lineage: a6191c99-f7f1-4766-9e01-ccc3f0673bcd
Keep the mobile board test API mock aligned with WorkflowSelector's optional-step loading.
- Add fetchWorkflowOptionalSteps to the dashboard API mock used by board-mobile tests.
- Return an empty optional-step list so WorkflowSelector mount effects can settle without missing mock failures.
Files changed:
packages/dashboard/app/components/__tests__/board-mobile.test.tsx | 1 +
1 file changed, 1 insertion(+)
Fusion-Task-Id: FN-6342
Fusion-Task-Lineage: 750c296d-b559-4b71-9038-1640e0ce6b68
Limits task card archiving UI to completed tasks while preserving coverage for hidden states.
- Render the archive button only when a task is in the done column.
- Update TaskCard tests to assert archive action visibility for done tasks and absence for other live columns.
- Keep the header action placement assertion focused on done task cards.
Files changed:
packages/dashboard/app/components/TaskCard.tsx | 2 +-
.../app/components/__tests__/TaskCard.test.tsx | 23 +++++++++++++++++-----
2 files changed, 19 insertions(+), 6 deletions(-)
Fusion-Task-Id: FN-6340
Fusion-Task-Lineage: e1373fd1-5e50-4784-bf04-fa13ef0a08cb
Task detail chat now renders adjacent text log chunks as continuous bubbles.
- Combine consecutive non-tool, non-thinking chat entries within each agent role group before rendering.
- Preserve tool and thinking segment boundaries while simplifying segment keys for grouped text.
- Add dashboard tests for single, consecutive, and cross-role text bubble behavior.
- Document the text chunk grouping behavior in the dashboard guide.
Files changed:
docs/dashboard-guide.md | 2 +-
packages/dashboard/app/components/TaskChatTab.tsx | 28 ++++++++-----
.../app/components/__tests__/TaskChatTab.test.tsx | 48 ++++++++++++++++++++++
3 files changed, 66 insertions(+), 12 deletions(-)
Fusion-Task-Id: FN-6344
Fusion-Task-Lineage: e88f0383-7d91-4272-8c9b-532a382074d4
Reconcile the FN-352 no-commit coordination guard skip with main's
independently-landed FN-424 work. Both branches added a no_commits
guard bypass at the same fn_task_done call site:
- FN-352 (this branch): getNoCommitEligibilityReason(task) covering
Review Level 1 coordination prompts with board-only scope and
explicit no-source intent (e.g. "Do not change product source").
- FN-424 (main): evaluatePromptDerivedNoCommitEligibility(...) plus
non-blocking audit logging of the skip.
Their prompt phrase-matching differs, so neither alone satisfies the
merged test file. Resolved by OR-ing both eligibility checks and
wrapping the skip in main's audit-logging block. Both helpers still
refuse the contradictory implementation+coordination prompt.
All 18 executor-task-done-invariant tests pass; engine typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Quarantine the flaky deferred-hook title summarization coverage while preserving focused store-create coverage.
- Extract the deferred task-created hook summarization test into its own file.
- Exclude the extracted test file from the core Vitest suite.
- Record the flake investigation and quarantine rationale in the test quarantine ledger.
Files changed:
.../store-create-summarize-deferred-hook.test.ts | 67 ++++++++++++++++++++++
packages/core/src/__tests__/store-create.test.ts | 44 --------------
packages/core/vitest.config.ts | 1 +
scripts/lib/test-quarantine.json | 5 ++
4 files changed, 73 insertions(+), 44 deletions(-)
Fusion-Task-Id: FN-6326
Fusion-Task-Lineage: a37189b3-b88b-483f-b2bf-471fde806b35
Allow the chat composer to recognize live CLI sessions as steerable agent sessions.
- Pass live CLI session state from the task detail modal into the chat tab.\n- Keep paused and user-paused tasks blocked even when a CLI session exists.\n- Cover live, ended, and missing CLI session states in chat composer tests.\n\nFiles changed:\n packages/dashboard/app/components/TaskChatTab.tsx | 18 +++--\n .../dashboard/app/components/TaskDetailModal.tsx | 22 ++++--\n .../app/components/__tests__/TaskChatTab.test.tsx | 92 ++++++++++++++++++++--\n 3 files changed, 111 insertions(+), 21 deletions(-)
Fusion-Task-Id: FN-6338
Fusion-Task-Lineage: 7229c059-e094-4be3-bfba-b15d8c5069f9
Self-healing now resumes stranded assigned in-progress work when an agent has no active run or execution.
- Add a self-healing pass that groups stale assigned in-progress tasks by durable agent and calls the executor resume seam without moving tasks backward.
- Emit run-audit telemetry for reattached orphaned executions and wire the resume hook through the in-process runtime.
- Cover grace windows, pause/active-run/active-execution guards, task filtering, and registration order with engine tests.
- Document the recovery behavior and add a patch changeset for the published CLI package.
Files changed:
.changeset/fn-6336-reattach-orphaned-executions.md | 5 +
docs/agents.md | 2 +
docs/architecture.md | 2 +
...lf-healing-reattach-orphaned-executions.test.ts | 217 +++++++++++++++++++++
packages/engine/src/run-audit.ts | 1 +
packages/engine/src/runtimes/in-process-runtime.ts | 1 +
packages/engine/src/self-healing.ts | 122 ++++++++++++
7 files changed, 350 insertions(+)
Fusion-Task-Id: FN-6336
Fusion-Task-Lineage: 6d8519b9-d8b0-4726-9b45-bfa445b7883e
Stabilize the checkout leasing AgentStore regression test setup.
- Recreate the nested checkout-leasing AgentStore with an in-memory database after replacing the TaskStore.
- Keep the disk-backed TaskStore for persistence assertions while avoiding a shared disk-backed AgentStore database lifecycle.
- Let the top-level cleanup own AgentStore closure to avoid double-closing in the nested hook.
Files changed:
packages/core/src/__tests__/agent-store.test.ts | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
Fusion-Task-Id: FN-6312
Fusion-Task-Lineage: a7f95ba4-fe8b-4367-9f65-6696b1a3867a
Reliably settles task-detail chat transcripts to the latest output after load and reactivation.
- Add a bounded animation-frame settle loop that re-pins populated transcripts while late layout growth occurs.
- Cancel pending settle frames on cleanup to avoid stale scroll writes after unmount or rerender.
- Cover async transcript height growth and settle-loop cleanup in TaskChatTab tests.
- Add a patch changeset for the published CLI package.
Files changed:
.changeset/fn-6337-chat-scroll-settle.md | 5 +
packages/dashboard/app/components/TaskChatTab.tsx | 52 +++++++++-
.../app/components/__tests__/TaskChatTab.test.tsx | 108 +++++++++++++++++++++
3 files changed, 163 insertions(+), 2 deletions(-)
Fusion-Task-Id: FN-6337
Fusion-Task-Lineage: d31de363-7ee6-4098-ac43-991dc33192e4
The embedded desktop local runtime used process.cwd() as its data root.
When a packaged build is launched from a desktop launcher or file manager
(notably the Linux AppImage), cwd is `/` or the read-only squashfs mount
point, so creating `<cwd>/.fusion/fusion.db` failed with EACCES/EROFS and
the runtime never started ("Couldn't start local Fusion").
Resolve the root from the user's home directory instead, so data lives in
`~/.fusion` (consistent with the CLI), with a `FUSION_HOME` override.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Refine task chat transcripts so collapsed tool groups summarize real invocations and expand into paired call/result details.
- Count tool calls by invocation instead of raw tool log rows.
- Show deduped tool names, overflow counts, and error badges in collapsed summaries.
- Pair tool calls with their result or error details when expanded.
- Cover the grouped summary behavior with dashboard tests and documentation.
Files changed:
docs/dashboard-guide.md | 2 +-
packages/dashboard/app/components/TaskChatTab.css | 36 +++++--
packages/dashboard/app/components/TaskChatTab.tsx | 116 +++++++++++++++++----
.../app/components/__tests__/TaskChatTab.test.tsx | 105 ++++++++++++++++---
4 files changed, 213 insertions(+), 46 deletions(-)
Fusion-Task-Id: FN-6332
Fusion-Task-Lineage: 7c14b76c-dcaa-4227-8393-cb24f99b765d