Commit Graph

12110 Commits

Author SHA1 Message Date
gsxdsm
dfb9ca6630 FN-8543: enforce bounded generated-fix remediation
Keep generated fix chains within their root retry budget and preserve intervention stops.

- Track retry counts and stop reasons on the canonical root feature.
- Persist project-isolated lineage stops across generated-fix removal and archive paths.
- Serialize stop recording with generated-fix admission and expose conflict-safe mission resume behavior.

Files changed:
 .changeset/fn-8543-bounded-fix-lineage.md          |   7 +
 docs/missions.md                                   |   6 +-
 .../__tests__/postgres/mission-store.pg.test.ts    |  72 +++++++
 packages/core/src/async-mission-store-queries.ts   |  91 ++++++++-
 packages/core/src/async-mission-store.ts           | 206 ++++++++++++++++++---
 packages/core/src/index.ts                         |   2 +-
 packages/core/src/mission-store.ts                 |  10 +
 packages/core/src/mission-types.ts                 |   7 +
 .../0035_fn_8543_mission_lineage_stop.sql          |  31 ++++
 packages/core/src/postgres/schema-applier.ts       |  18 +-
 packages/core/src/postgres/schema/project.ts       |  21 +++
 .../core/src/task-store/archive-lifecycle-2.ts     |  15 +-
 .../core/src/task-store/async-archive-lineage.ts   |  10 +-
 packages/dashboard/src/mission-routes.ts           |  14 +-
 packages/engine/src/mission-execution-loop.ts      |  30 ++-
 15 files changed, 495 insertions(+), 45 deletions(-)

Fusion-Task-Id: FN-8543

Fusion-Task-Lineage: 24c03d63-5914-4072-aa17-16862432fc78

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 16:12:44 -07:00
Victor Canô
0c085bf444 fix(engine): pushAfterMerge no longer strands approved merges when the remote diverges (#2407)
## Problem

With `pushAfterMerge` enabled (and `mergeStrategy` other than
`pull-request`), if `origin/<integration-branch>` advances externally
between the local squash-merge and the push, the divergence path opens a
clean-room `git pull --rebase` and an AI agent resolves and stages the
conflicts — but the flow could end there: no `git rebase --continue`, no
push, and no surfaced error.

Because finalize runs *before* the push, the task is already `done`, so
a reviewed, approved merge is silently left container-only, and every
subsequent merge on the project stalls the same way. Separately, an
abort mid-push (`MergeAbortedError`) was swallowed with only a
process-log warning — no task-log entry, no run-audit event.

## Change

- **Deterministic regression coverage** for the conflicting-divergence
path (real-git fixture) proving the rebase runs to completion and the
push lands (refs converge), plus abort/termination scenarios.
- **Recovery-branch safety net:** before the clean-room rebase starts,
the pre-rebase local squash is force-pushed to a per-task remote branch
`fusion/<task-id>-stranded`, so approved content is never container-only
— even across process death or abort. Deleted after a successful target
push; retained on failure/abort as the recovery source.
- **Never-silent outcomes:** every non-pushed outcome (failure or abort)
writes a durable task-log entry and a `push:origin` run-audit event. The
audit contract now documents `push:origin` as polymorphic (dashboard
Smart Push vs. automated post-merge push) and enumerates the automated
path's outcomes, including the new `"aborted"` shutdown case.
- **Cleanup hardening:** `isRebaseInProgress` now probes Git's
worktree-specific `rebase-merge`/`rebase-apply` state directories
(async, timeout-guarded) so a completed rebase can't receive a spurious
second `--continue`; unfinished rebases are cleaned up.

Out of scope by design: withholding the "merge confirmed" state until
the push succeeds — the `FNXC:MergePush` invariant ("a push problem can
never park or roll back a landed merge") is deliberate; the recovery
branch + surfacing satisfy the data-preservation intent without breaking
it.

## Files
`packages/engine/src/merger-ai.ts`, `packages/engine/src/merger.ts`,
`packages/engine/src/run-audit.ts`, new/updated tests under
`packages/engine/src/__tests__/`, `docs/settings-reference.md`,
`docs/dashboard-guide.md`, `AGENTS.md`, and a labeled changeset.

## Validation
`tsc --noEmit` clean; engine divergence + merger suites pass (41 tests);
rebased onto current `main` with no conflicts.

---

_Developed with Claude Code, under human supervision and review._


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

* **Bug Fixes**
* Prevented approved post-merge pushes from becoming stranded when the
remote diverges by using a recovery-branch workflow and safer cleanup.
* Improved behavior and reporting when pushes are aborted or fail after
merge, including clearer non-fatal status and audit outcomes.
* **Documentation**
* Expanded push-after-merge and dashboard Smart Push documentation with
recovery-branch and `push:origin`/`push:recovery-branch` outcome
semantics.
* **Tests**
* Added end-to-end regression tests for divergent/conflicting AI
push-after-merge flows, including abort and worktree cleanup
verification.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Victor Cano <victortroz@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-07-23 15:55:03 -07:00
Phil Larson
9f79b22d51 fix(i18n): restore secondary locale key parity (#2430)
## Summary
- synchronize all five secondary app locale catalogs with the authored
English key structure
- restore fallback entries for heartbeat controls, release-channel
settings, report targeting, and task provenance labels
- add a patch changeset for the catalog parity fix

## Test Plan
- `pnpm i18n:status`
- `pnpm --filter @fusion/i18n test` (29 tests)
- `pnpm --filter @fusion/dashboard exec vitest run
app/components/__tests__/AgentsView.test.tsx --silent=passed-only
--reporter=dot` (138 tests)
- `pnpm check:changesets`
- `pnpm build`


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

## Summary by CodeRabbit

- **Bug Fixes**
- Improved localization consistency for heartbeat controls, capability
settings, release-channel configuration, reporting guidance, and task
provenance details.
- Added missing translation entries across Spanish, French, Korean,
Simplified Chinese, and Traditional Chinese locales.
- Untranslated values now fall back cleanly to the authored English text
structure, preventing missing or inconsistent labels in supported
interfaces.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-23 15:54:41 -07:00
Umut
2b9131ba7c Fix broken anchor in README Workflow Steps link (#2431)
The Workflow Steps bullet in README.md links to
`./docs/workflow-steps.md#workflow-declared-optional-steps`, but the
target heading is `#### Workflow-declared optional steps
(`optional-group` nodes)`, which GitHub slugifies (including the
parenthesized text) to
`#workflow-declared-optional-steps-optional-group-nodes`. As a result
the link lands at the top of the page instead of the intended section.

The correct anchor is already used by a self-link elsewhere in the same
file (docs/workflow-steps.md, the "Optional groups and default-on gates"
row), confirming the expected slug.

This is a one-line fix: append `-optional-group-nodes` to the anchor in
README.md.

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

## Summary by CodeRabbit

* **Documentation**
* Updated the Workflow Steps documentation link to direct readers to the
more specific “optional group nodes” section.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-23 15:54:16 -07:00
gsxdsm
11fab37379 feat(ci): incremental caching for the PR merge-gate jobs (Gate, Build, Typecheck) (#2421)
## Summary

Every PR's blocking checks were dominated by redundant full rebuilds,
not by tests. Measured on recent runs: the Gate job spent ~6 of its ~7.5
min on a cold `pnpm build` (the exact-key dist cache missed on virtually
every PR) for ~45s of actual boot smoke + gate tests; Build ran ~8 min
and Typecheck ~4 min, both fully cold every time. Expected end state
once the warm job has run on main: all four blocking checks in roughly
2–4 min wall-clock.

### Gate job
- New `gate-dist-*` cache namespace with `restore-keys`, additionally
caching `.fusion/cache/plugin-build-cache.json` (build-workspace's
per-package content-hash skip cache) and `packages/cli/dist`. The
always-run `pnpm build` reconciles a near-match restore by content hash
and rebuilds only the packages the PR touched. This is safe *because*
the gate builds after restoring — the shard jobs' "no restore-keys" rule
(FN-4232/FN-4605 stale-dist incidents) still stands there, since they
consume dist without building.
- `FUSION_CLI_FULL_PACKAGE=0` on the gate build: skips the multi-minute
CLI desktop/plugins/DTS packaging tail nothing in the gate consumes
(same shape `pnpm verify:fast` proves locally). Full CLI packaging
coverage stays blocking in the Build job.

### Build job
- Restore-only tap (`actions/cache/restore`) of the same warmed cache.
Restore-only because this job runs FULL CLI packaging (`CI=true`) and
saving that shape would swap the cache's canonical fast-CLI contents out
from under the Gate job. Its distinctive coverage is preserved:
`ensureFullPackageCliPlanned` force-plans the CLI in full mode
regardless of cache state.

### Typecheck job
- Caches per-package tsc incremental buildinfo — self-validating (tsc
hashes every input against it and re-checks whatever changed), so
`restore-keys` is correctness-neutral by construction.
- **Fixes a real incrementality bug:** `tsconfig.json` and
`tsconfig.app.json` in the dashboard both inherited
`${configDir}/dist/.tsbuildinfo` from `tsconfig.base.json`, so the two
typecheck programs clobbered each other's buildinfo and re-checked the
full program every run — incremental typechecking never worked for the
dashboard, in CI or locally. `tsconfig.app.json` now writes
`dist/.tsbuildinfo-app`. Measured: dashboard typecheck 44s cold → 5.6s
warm.

### Warm job (full-suite.yml, push to main)
- New `warm-gate-build-cache` job saves both caches from main on every
push. Caches saved on a PR merge ref are invisible to other PRs, so
without this every PR's *first* run would still build/check cold.

## Guardrails

`ci-workflow.test.ts` pins the coupled invariants so they can't drift
apart silently:
- restore-keys requires the reconciling `pnpm build` after restore,
before boot smoke
- the mtime-defeating seed step stays exact-hit-only
- byte-identical cache path lists between the Gate/Build/warm blocks
(actions/cache versions caches by path list — a drifted list makes
caches mutually invisible)
- Build stays restore-only and must NOT opt out of full CLI packaging
- Typecheck cache shape + the distinct dashboard app buildinfo path

## Notes

- First PR runs after this lands still build cold until the warm job has
run once on main.
- No changeset: CI config + test-only per AGENTS.md.

## Verification

- `ci-workflow.test.ts` + `package-config.test.ts`: 106 tests pass
- Dashboard typecheck run twice locally: 44s cold → 5.6s warm, both
`.tsbuildinfo` and `.tsbuildinfo-app` written, exit 0
- Cache block path/key parity verified programmatically across both
workflow files

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

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

## Summary by CodeRabbit

* **Performance**
* Improved CI build and type-check performance through incremental
caching.
* Added cache warming from the main branch to speed up pull request
checks.
* Enabled faster CLI packaging during gate validation while retaining
full packaging coverage elsewhere.

* **Bug Fixes**
* Prevented dashboard TypeScript build information from being
overwritten, preserving incremental type-checking reliability.

* **Tests**
* Added coverage to verify CI cache behavior, build ordering, cache
paths, and packaging modes.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:53:31 -07:00
gsxdsm
94644ef849 fix(planning): mark session complete after Proceed-with-plan task creation
Proceed with plan called /api/planning/create-task without the legacy
/validate step, so the persisted AI session stayed awaiting_input and the
session list/needs-input banner kept advertising a finished session. The
create-task route now terminalizes the session via validateSession on every
path that ends with a created task, including alreadyCreated reconciliation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:45:39 -07:00
gsxdsm
d3f15f92bf docs: rewrite 0.73.0 beta changelog sections to per-beta deltas
The root CHANGELOG's beta sections (and the matching GitHub prerelease bodies, now edited in place) carried full-cycle aggregates because every beta distilled all preserved pre-mode changesets. Rebuilt each section from packages/cli/CHANGELOG.md's incremental per-beta entries so each beta lists only its own changes; future releases are handled by the channel-scoped selection in release.mjs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:41:09 -07:00
gsxdsm
e5caea542a FN-8544: gate mission remediation behind autopilot
Keep mission validation report-only until an operator explicitly enables autopilot.

- Gate validator-created remediation features and task dispatch behind mission autopilot.
- Audit attributed status and autopilot transitions atomically across mission stores.
- Expose mission autonomy controls and document the opt-in lifecycle.

Files changed:
 .changeset/fn-8544-mission-autonomy-audit.md       |   7 ++
 docs/missions.md                                   |  10 +-
 packages/cli/src/extension.ts                      |  26 ++++-
 .../__tests__/postgres/mission-store.pg.test.ts    |  27 +++++
 packages/core/src/async-mission-store.ts           |  70 +++++++++++--
 packages/core/src/index.gate.ts                    |   3 +
 packages/core/src/index.ts                         |   3 +
 packages/core/src/mission-store.ts                 | 113 +++++++++++++--------
 packages/core/src/mission-types.ts                 |  22 ++++
 .../dashboard/app/components/MissionManager.tsx    |   1 +
 packages/dashboard/src/mission-routes.ts           |  25 +++--
 .../src/__tests__/agent-mission-tools.test.ts      |  17 +++-
 .../src/__tests__/mission-execution-loop.test.ts   |  21 ++++
 packages/engine/src/agent-heartbeat.ts             |   4 +-
 packages/engine/src/agent-tools.ts                 |  30 +++++-
 packages/engine/src/executor.ts                    |   5 +-
 packages/engine/src/mission-autopilot.ts           |  51 +++++-----
 packages/engine/src/mission-execution-loop.ts      |  49 ++++++---
 packages/engine/src/triage.ts                      |   5 +-
 19 files changed, 377 insertions(+), 112 deletions(-)

Fusion-Task-Id: FN-8544

Fusion-Task-Lineage: 23a69923-5a19-407e-9fe2-8973c166ee9a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 15:25:09 -07:00
gsxdsm
e7c9b2ac80 FN-8542: separate milestone acceptance from feature validation
Keep feature validation scoped to linked feature assertions while evaluating milestone acceptance at rollup.

- Add assertion scope and origin provenance with database migration support
- Synchronize milestone acceptance prose to a canonical milestone assertion
- Prevent milestone assertions from affecting feature verdicts and document the completion contract
- Cover scoped validation and milestone rollup behavior with core and engine tests

Files changed:
 .changeset/fn-8542-feature-validation-scope.md     |   7 +
 docs/missions-completion-contract.md               |  25 +-
 docs/missions.md                                   |   6 +-
 .../mission-store.sync-loop-transition.test.ts     |  53 +++++
 packages/core/src/async-mission-store-queries.ts   |  17 +-
 packages/core/src/async-mission-store.ts           |  58 ++++-
 packages/core/src/mission-store.ts                 | 118 +++++++++-
 packages/core/src/mission-types.ts                 |  25 ++
 .../core/src/postgres/migrations/0000_initial.sql  |   2 +
 .../0034_milestone_assertion_provenance.sql        |  30 +++
 packages/core/src/postgres/schema-applier.ts       |  24 +-
 packages/core/src/postgres/schema/project.ts       |   1 +
 .../src/__tests__/mission-execution-loop.test.ts   | 161 ++++++++++++-
 packages/engine/src/mission-execution-loop.ts      | 262 ++++++++++++++++-----
 14 files changed, 700 insertions(+), 89 deletions(-)

Fusion-Task-Id: FN-8542

Fusion-Task-Lineage: cf112d31-376a-456e-be08-225eab5de393

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 14:39:44 -07:00
gsxdsm
2978ec4973 FN-8551: add accessible agent heartbeat controls
Add per-agent and project-wide heartbeat enablement controls.

- Add preserved runtime configuration helpers and heartbeat controls across agent list, board, and org-chart views.
- Add bulk enable/disable actions, accessible labels, localized copy, documentation, and release metadata.
- Cover heartbeat mutations through dashboard, route, scheduler, and layout smoke tests.

Files changed:
 .changeset/fn-8551-agent-heartbeat-controls.md     |   7 +
 docs/dashboard-guide.md                            |   2 +
 packages/dashboard/app/api/agents.ts               |  12 ++
 packages/dashboard/app/api/legacy.ts               |   2 +
 .../dashboard/app/components/AgentDetailView.tsx   |  14 +-
 packages/dashboard/app/components/AgentsView.css   |  11 ++
 packages/dashboard/app/components/AgentsView.tsx   | 186 ++++++++++++++++-----
 .../AgentDetailView.advanced-settings.test.tsx     |  29 ++++
 .../__tests__/AgentDetailView.test-helpers.ts      |   2 +
 .../app/components/__tests__/AgentsView.test.tsx   |  68 ++++++++
 .../dashboard/scripts/browser-layout-smoke.mjs     |  54 ++++++
 .../src/routes/__tests__/agent-core-routes.test.ts |  69 ++++++++
 .../src/__tests__/heartbeat-scheduler.test.ts      |  21 +++
 packages/i18n/locales/en/app.json                  |  19 ++-
 packages/i18n/locales/es/app.json                  |  19 ++-
 packages/i18n/locales/fr/app.json                  |  19 ++-
 16 files changed, 484 insertions(+), 50 deletions(-)

Fusion-Task-Id: FN-8551

Fusion-Task-Lineage: 2d4c8a15-a444-47b6-b57c-f41fc4163155

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 14:32:58 -07:00
gsxdsm
3d0ce2ed3a FN-8545: enforce mission lineage task admission
Protect feature bootstrap task creation with mission-lineage admission rules.

- Restrict supervised agents to linked autonomous mission features
- Atomically claim defined feature tasks and preserve duplicate ownership
- Lock defined feature claims to prevent concurrent bootstrap inserts
- Document admission behavior and add PostgreSQL and delegation coverage

Files changed:
 .changeset/fn-8545-mission-admission.md            |   7 +
 docs/agents.md                                     |   6 +
 docs/missions.md                                   |  12 +-
 .../__tests__/postgres/mission-store.pg.test.ts    | 119 ++++++++++++
 packages/core/src/async-mission-store.ts           | 203 +++++++++++++++++++--
 packages/core/src/duplicate-guard.ts               |  14 +-
 packages/core/src/mission-store.ts                 |  15 ++
 packages/core/src/task-store/task-creation.ts      | 152 ++++++++++-----
 .../src/__tests__/agent-tools-delegation.test.ts   | 152 ++++++++++++++-
 packages/engine/src/agent-tools.ts                 | 151 ++++++++++++++-
 10 files changed, 753 insertions(+), 78 deletions(-)

Fusion-Task-Id: FN-8545

Fusion-Task-Lineage: c6e1b46d-f434-4b07-93bc-27e1f6b491b1

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 14:21:29 -07:00
gsxdsm
ffbda3fb52 FN-8550: theme agent Settings controls
Apply token-driven styling and responsive behavior across Agent Settings controls.

- Theme configuration inputs, runtime tabs, avatar actions, policy editor, model combobox, and skill multiselect states
- Add coverage for Settings styling contracts, runtime/avatar semantics, and skill selection states
- Correct the model-filter clear control sizing with a valid themed font token

Files changed:
 .../agent-detail-settings-theme-styling.test.ts    | 103 ++++++++++++
 .../dashboard/app/components/AgentDetailView.css   | 113 +++++++++++++
 .../dashboard/app/components/AgentDetailView.tsx   |   8 +-
 .../app/components/AgentPermissionPolicyEditor.css |  44 +++++-
 .../app/components/CustomModelDropdown.css         |  84 +++++-----
 .../dashboard/app/components/SkillMultiselect.css  | 174 ++++++++++++++-------
 .../dashboard/app/components/SkillMultiselect.tsx  |   4 +
 .../AgentDetailView.advanced-settings.test.tsx     |  36 +++++
 .../components/__tests__/SkillMultiselect.test.tsx |  57 +++++++
 9 files changed, 518 insertions(+), 105 deletions(-)

Fusion-Task-Id: FN-8550

Fusion-Task-Lineage: 5a55ded8-2cd7-4364-855a-3763d5d8af95

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 13:38:41 -07:00
gsxdsm
15b5441afc FN-8548: keep GitHub import actions on one mobile row
Keep all selected GitHub issue actions touch-safe and visible on a single mobile row.

- Group detail action controls separately from the comment composer and make their mobile tracks shrinkable.
- Add responsive browser-smoke coverage at 320px, 390px, and 412px plus modal structure tests.
- Document the mobile behavior and add a patch changeset.

Files changed:
 .changeset/fn-8548-mobile-github-import-actions.md |   7 +
 docs/dashboard-guide.md                            |   8 +-
 .../dashboard/app/components/GitHubImportModal.css |  42 +++++-
 .../dashboard/app/components/GitHubImportModal.tsx |  80 ++++++------
 .../__tests__/GitHubImportModal.test.tsx           |  50 ++++++++
 packages/dashboard/app/styles.css                  |  11 +-
 .../dashboard/scripts/browser-layout-smoke.mjs     | 142 ++++++++++++++++++++-
 7 files changed, 290 insertions(+), 50 deletions(-)

Fusion-Task-Id: FN-8548

Fusion-Task-Lineage: 8fab6a1d-0ca9-4246-9707-e1fc84ca58e5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 13:28:19 -07:00
gsxdsm
e734ed8a48 FN-8541: expose actionable validator diagnostics
Surface normalized, secret-safe validator evidence and assertion verdicts across mission events and remediation work.

- Normalize, redact, bound, and render per-assertion validation diagnostics in shared core APIs.
- Attach verdict-driven diagnostics to failure events and generated fixes while suppressing duplicate triage noise.
- Display validator evidence in Mission activity and document the operator workflow.
- Add core and engine coverage for evidence, mixed blocked verdicts, and triage behavior.

Files changed:
 .changeset/fn-8541-validator-diagnostics.md        |   7 ++
 docs/missions.md                                   |  17 +++
 .../mission-store.validation-diagnostics.test.ts   |  65 ++++++++++
 packages/core/src/async-mission-store.ts           |   8 +-
 packages/core/src/index.gate.ts                    |  10 ++
 packages/core/src/index.ts                         |  10 ++
 packages/core/src/mission-store.ts                 |  10 +-
 packages/core/src/mission-types.ts                 | 136 +++++++++++++++++++++
 .../dashboard/app/components/MissionManager.css    |  21 ++++
 .../dashboard/app/components/MissionManager.tsx    |  56 +++++++++
 packages/dashboard/app/components/mission-types.ts |   3 +
 .../src/__tests__/mission-execution-loop.test.ts   |  44 +++++++
 .../mission-validator-behavioral-posture.test.ts   |  37 +++++-
 packages/engine/src/mission-execution-loop.ts      | 117 +++++++++++++-----
 14 files changed, 501 insertions(+), 40 deletions(-)

Fusion-Task-Id: FN-8541

Fusion-Task-Lineage: b226fc34-f35c-4ce5-bcb5-e418529caaa7

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 13:21:10 -07:00
gsxdsm
47d2d176ef FN-8552: add disabled heartbeat scheduling option
Allow agent heartbeat scheduling to be paused and resumed without losing its configured cadence.

- Add a Disabled heartbeat interval dropdown option that persists runtime enablement.
- Re-enable scheduling when preset or custom intervals are selected.
- Cover disabled, legacy, desktop/mobile, and configuration-preservation flows.
- Document the heartbeat control and add a patch changeset.

Files changed:
 .changeset/fn-8552-heartbeat-disabled-option.md    |   7 ++
 README.md                                          |   2 +-
 packages/dashboard/app/components/AgentsView.tsx   |  41 +++++++-
 .../app/components/__tests__/AgentsView.test.tsx   | 115 +++++++++++++++++++++
 4 files changed, 162 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-8552

Fusion-Task-Lineage: 07f78005-4ac0-4210-9dd3-6c5b06ab7bc5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 13:04:17 -07:00
gsxdsm
2021d5679b FN-8540: render mission hierarchies in agent lookup
Render complete mission hierarchy details from the fn_mission_show agent tool.

- Format mission, linked-goal, milestone, slice, and feature metadata with IDs and statuses
- Link features to their tasks and bound verbose acceptance and verification text
- Cover populated and empty hierarchy responses with regression tests
- Add a patch changeset for the agent lookup fix

Files changed:
 .changeset/fn-8540-mission-show-hierarchy.md       |  7 ++
 .../src/__tests__/agent-mission-tools.test.ts      | 68 +++++++++++++++++++
 packages/engine/src/agent-tools.ts                 | 77 +++++++++++++++++++++-
 3 files changed, 150 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-8540

Fusion-Task-Lineage: f2282226-3f4e-4d9f-bd8e-d18ad9639c03

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 12:46:09 -07:00
gsxdsm
a69e66b54b FN-8553: prevent agent card badge overlap
Keep agent identities and status badges readable across card widths.

- Wrap desktop and split-sidebar card headers without permitting text overflow.
- Stack identity and badge regions on narrow mobile cards.
- Cover long identities and populated badge layouts with regression tests.

Files changed:
 packages/dashboard/app/components/AgentsView.css   | 38 +++++++++++++++++++++
 .../app/components/__tests__/AgentsView.test.tsx   | 39 ++++++++++++++++++++++
 .../__tests__/agents-view-mobile.test.tsx          | 12 +++++++
 3 files changed, 89 insertions(+)

Fusion-Task-Id: FN-8553

Fusion-Task-Lineage: b0015f41-44e6-4cc9-8ec9-d9c0c61f7f18

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 12:40:10 -07:00
gsxdsm
0d355f371c FN-8547: add local OpenAI-compatible provider onboarding
Add guided onboarding for OpenAI-compatible local model providers.

- Add custom/local provider prompts and atomic models registry updates.
- Preserve registry fields, validate endpoint configuration, and support Qwen thinking compatibility.
- Document setup and cover registry persistence with onboarding tests.

Files changed:
 .changeset/fn-8547-local-provider-onboarding.md    |   7 +
 docs/cli-reference.md                              |  13 ++
 docs/settings-reference.md                         |  35 ++++-
 packages/cli/src/commands/__tests__/onboard.test.ts |  55 ++++++-
 packages/cli/src/commands/onboard.ts               | 161 ++++++++++++++++++++-
 5 files changed, 261 insertions(+), 10 deletions(-)

Fusion-Task-Id: FN-8547

Fusion-Task-Lineage: 740221de-fce8-43ae-a095-13b8abf1904a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 12:31:55 -07:00
gsxdsm
84d7306bd3 FN-8546: fix ideation candidate discovery
Expose persisted ideation candidate identities so agents can select a candidate for convergence.

- Render candidate IDs, provenance, source references, and content in show and diverge responses.
- Cover discover-to-converge behavior, duplicate content, empty sessions, and missing sessions.
- Document the direct candidate-ID convergence workflow and add a patch changeset.

Files changed:
 .changeset/fn-8546-ideation-candidate-ids.md       |  7 ++
 docs/agent-tool-surface-full-loop.md               |  4 +-
 docs/ideation/persisted-diverge-converge.md        |  6 +-
 .../src/__tests__/agent-ideation-tools.test.ts     | 93 +++++++++++++++++++---
 packages/engine/src/agent-tools.ts                 | 23 +++++-
 5 files changed, 116 insertions(+), 17 deletions(-)

Fusion-Task-Id: FN-8546

Fusion-Task-Lineage: 7232701f-5c6b-40fc-8d46-d65b97af9c0a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 12:26:02 -07:00
gsxdsm
ff165ecb5a fix: scope beta release notes to that beta's changesets; stable keeps full-cycle rollup
Pre-mode preserves consumed changeset .md files, so every beta's distilled notes and GitHub prerelease body aggregated the entire cycle since the last stable (v0.73.0-beta.4 shipped the full 0.72.0→0.73.0 aggregate). Betas now distill only changesets not yet recorded in pre.json's consumed ledger, and fail loudly when a beta would ship nothing new. Stable promotion still feeds the full preserved set, keeping its notes an explicit rollup of every beta in the cycle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 12:18:24 -07:00
gsxdsm
c4292b25ef FN-8539: make Planning Mode selection-driven
Make Planning Mode refine repository-grounded plans through successive operator choices.

- Offer concrete directions and Other for vague planning openers
- Rebuild running plans around selected options, multi-selections, and Other responses
- Add selection-loop coverage and operator documentation

Files changed:
 .changeset/fn-8539-option-driven-planning.md       |   7 ++
 docs/dashboard-guide.md                            |   2 +-
 .../__tests__/planning-infinite-interview.test.ts  | 131 ++++++++++++++++++++-
 .../planning-interview-formatters.test.ts          |  37 ++++--
 packages/dashboard/src/planning.ts                 |  34 +++---
 5 files changed, 185 insertions(+), 26 deletions(-)

Fusion-Task-Id: FN-8539

Fusion-Task-Lineage: 585bae1e-6d9e-4733-b787-77b70a7d1259

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 12:08:58 -07:00
gsxdsm
3f976e3dca FN-8538: give Planning Mode a dedicated collaborative prompt
Planning Mode now uses a standalone collaborative prompt rather than inherited task-triage instructions.

- Resolve the Planning Mode default independently of workflows and triage assignments.
- Preserve explicit full-system prompt overrides and update prompt-setting documentation.
- Cover dedicated prompt behavior and add the published-package changeset.

Files changed:
 .changeset/fn-8538-planning-prompt.md              |  7 +++
 docs/dashboard-guide.md                            |  3 +-
 .../core/src/__tests__/prompt-overrides.test.ts    |  7 +++
 packages/core/src/prompt-overrides.ts              |  8 ++-
 packages/dashboard/app/utils/builtinPrompts.ts     |  8 ++-
 .../__tests__/planning-infinite-interview.test.ts  | 60 +++++++++++++++++++++-
 .../__tests__/planning-prompt-resolution.test.ts   | 47 ++++++++++-------
 packages/dashboard/src/planning.ts                 | 46 +++++------------
 8 files changed, 130 insertions(+), 56 deletions(-)

Fusion-Task-Id: FN-8538

Fusion-Task-Lineage: 36e0665d-7995-4bc5-9c73-948f7f4e9131

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 11:41:15 -07:00
gsxdsm
d6d8a5e919 FN-8537: keep planning actions visible on mobile
Keep Planning Refine and Proceed controls visible across mobile plan-review hosts.

- Make the plan document pane the responsive scroll owner while preserving its action rail.
- Cover portrait and short-landscape embedded and modal layouts with CSS and browser tests.
- Add a patch changeset for the mobile planning action fix.

Files changed:
 .changeset/fn-8537-mobile-planning-actions.md      |  7 ++++++
 .../dashboard/app/components/PlanningModeModal.css | 25 ++++++++++++++++++++++
 .../__tests__/PlanningModeModal.css.test.ts        | 17 +++++++++++++++
 .../src/__tests__/planning-browser-e2e.test.ts     | 20 +++++++++++++++--
 4 files changed, 67 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-8537

Fusion-Task-Lineage: 7a53aa74-859d-4c76-bf26-ab6ea72873dd

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 11:03:33 -07:00
gsxdsm
2499803c73 fix: guard CE sessions against concurrent-turn displacement and harden JSON-protocol parsing
Port the planning turn-admission invariant (FNXC:PlanningTurnAdmission,
2026-07-22) into the Compound Engineering orchestrator: at most one turn
(opening/answer/resume-rehydration) is admitted per CE session, reserved
synchronously and held until the turn settles — a re-entered mobile view
re-submitting a turn now gets CeTurnInProgressError (HTTP 409) instead of
displacing the in-flight turn's live agent, which surfaced as "Failed to
parse agent response: AI returned no valid JSON". cancel()/discard()
force-clear the reservation; releases are token-scoped so a stale release
can't drop a newer turn's slot.

In the engine interactive-ai-session seam: bump the reformat retry from
one to two attempts (non-Anthropic default models comply less reliably
with the JSON-only protocol), and log every failed parse with a bounded
raw-response snippet plus resolved provider/model — including a distinct
empty-assistant-message marker — so support can diagnose these reports
without a repro.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 10:31:22 -07:00
gsxdsm
492d375e8f FN-8536: fix planning retry ownership after failure
Release a settled retry token so a later planning error can start the next bounded attempt.

- Clear only the matching retry owner before scheduling its successor.
- Cover distinct stream errors after retry settlement.
- Add a patch changeset for the recovery fix.

Files changed:
 .changeset/fn-8536-planning-retry.md                           |  7 +++++++
 packages/dashboard/app/components/PlanningModeModal.tsx        | 10 ++++++++++
 .../__tests__/PlanningModeModal.planning-flow.test.tsx         |  5 +++++
 3 files changed, 22 insertions(+)

Fusion-Task-Id: FN-8536

Fusion-Task-Lineage: cccb0793-390e-4bdb-b459-939760e644bb

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 10:25:16 -07:00
gsxdsm
2df0c7e90b fix(#2411): recover from a stale postmaster.pid instead of joining a dead port
After a hard host crash (SIGKILL, power loss), postmaster.pid survives with no
postmaster behind it. The optimistic join handed every subsequent boot a URL to
the dead port, so the dashboard could never start again without a manual pid
delete. Probe the recorded pid with signal 0: provably dead (ESRCH) rebuts the
live-lock presumption and the boot takes an owned start — PostgreSQL itself
re-validates and reclaims the stale lock file, so a recycled live pid keeps the
old join-then-fail behavior and a genuinely live postmaster still surfaces the
lock collision we already join on. EPERM counts as alive (fail-closed).

Verified end to end: real cluster started, postmaster SIGKILLed leaving the pid
file + interrupted WAL, fresh lifecycle detected the stale lock, ran an owned
start, and crash recovery preserved the marker row.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 10:00:09 -07:00
gsxdsm
5a5796bca2 fix: show session loader instead of Generating while planning mode hydrates from DB
Reloading Planning re-entered the generation view ("Generating initial
plan…", Stop button, elapsed timer, 8s watchdog) while merely fetching a
persisted session. A new session_loading view state renders a neutral
"Loading session…" spinner during hydration; the generating view is
reserved for sessions the server reports as generating. Unrecognized
persisted session shapes now land in the retryable error view instead of
spinning forever.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 09:55:52 -07:00
gsxdsm
b4856e3c1e fix: separate Docker app root from project mount so -v host mounts work (#2414)
The runner stage installed the application at /project, which was also the
documented bind-mount point — mounting a host project there shadowed the CLI
and the container exited with MODULE_NOT_FOUND on packages/cli/dist/bin.js.

- Install the app under /app and run the entrypoint by absolute path.
- Reserve /workspace (empty in the image, container workdir) as the project
  mount point.
- Update docs/docker.md: mount at /workspace, and document that embedded
  Postgres/global state lives in /home/node/.fusion with a named-volume
  example so persistence actually captures it.

Verified: image builds; `docker run -v host:/workspace` boots, embedded
Postgres initializes, /api/health returns ok.

Fixes #2414

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 09:50:24 -07:00
gsxdsm
42fe154abe FN-8533: add mobile planning comment actions
Make contextual plan comments reachable from the mobile action rail and restore focus after editing.

- Add responsive desktop and mobile comment triggers with contextual styling and documentation.
- Preserve the selected quote and restore the remounted trigger after canceling or adding a comment.
- Cover action placement, focus restoration, and browser interaction behavior.

Files changed:
 .changeset/fn-8533-mobile-planning-comments.md     |   7 ++
 docs/dashboard-guide.md                            |   2 +-
 .../dashboard/app/components/PlanningModeModal.css |  20 ++++
 .../dashboard/app/components/PlanningModeModal.tsx |  44 ++++++-
 .../__tests__/PlanningModeModal.css.test.ts        |  10 ++
 .../PlanningModeModal.planning-flow.test.tsx       |  40 +++++--
 .../PlanningModeModal.ui-interactions.test.tsx     |   5 +
 .../dashboard/app/planning-browser-e2e-fixture.tsx |   3 +-
 .../src/__tests__/planning-browser-e2e.test.ts     | 133 +++++++++++++++++++--
 packages/dashboard/vitest.config.ts                |  11 +-
 scripts/lib/test-quarantine.json                   |   5 -
 11 files changed, 242 insertions(+), 38 deletions(-)

Fusion-Task-Id: FN-8533
Fusion-Task-Lineage: e0d561be-ecc8-456e-807e-a1dc677b5d9c
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 09:33:25 -07:00
gsxdsm
75e1e735a5 FN-8535: stabilize planning modal retry tests
Stabilize PlanningModeModal retry-flow coverage by isolating shared state and awaiting delayed claims.

- Add a test-only reset seam for persistent planning retry budgets.
- Reset modal test state and timers between cases.
- Cover delayed active-create claims before a new session starts.

Files changed:
 packages/dashboard/app/components/PlanningModeModal.tsx | 11 +++
 packages/dashboard/app/components/__tests__/PlanningModeModal.planning-flow.test.tsx | 83 ++++++++++++++++++++--
 2 files changed, 89 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-8535

Fusion-Task-Lineage: dd770632-d73c-4d18-9bb3-d8f0a7eec397

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 09:16:39 -07:00
gsxdsm
dc132071d5 fix(#2411): let embedded PostgreSQL crash recovery finish instead of racing it
beta.4 follow-up from the issue thread: on an interrupted (not-cleanly-shut-down)
cluster, the elevated Windows launcher declared readiness on a bare TCP accept
while crash recovery still rejected every connection with 57P03, so
ensureDatabase failed and the start cleanup fast-shutdown the recovering
postmaster ~0.2s after launch; the retry then joined the instance it had just
told to stop, got ECONNREFUSED, and parked the dashboard in a dead shell. The
30s ".pgrunner sharing violation" stall was recovery's SyncDataDirectory fsync
walk hitting Fusion's own pgctl log inside the data dir.

- Move the pgctl runner dir to a sibling .pgrunner-<dataDirName> outside the
  data dir (and sweep the legacy in-dataDir .pgrunner), so recovery's fsync
  walk can never contend with the postmaster's inherited log handle.
- Ignore 57P03 recovery rejections in the elevated readiness fatal scan.
- Owned starts wait for the cluster to genuinely accept connections (retrying
  57P03/socket errors, bounded by the start timeout) before ensureDatabase —
  never stop a postmaster that is still in recovery.
- Join-path database verify retries the 57P03 recovery signal for up to 15s;
  socket errors keep the instant optimistic-join contract for stale pids.
- startup-factory's joined-instance-unreachable retry backs off across ~15s
  instead of a single 500ms attempt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 09:13:21 -07:00
gsxdsm
d2e41e490f FN-8534: honor workflow planning-model precedence
Honor selected workflow planning models for Planning Mode sessions.

- Resolve selected workflow planning lanes against the project baseline.
- Route complete request and workflow pairs through canonical planning-model resolution.
- Cover new and draft planning sessions, test mode, and settings documentation.

Files changed:
 .changeset/fn-8534-planning-workflow-model.md      |  7 ++
 docs/settings-reference.md                         |  2 +
 .../__tests__/workflow-settings-resolver.test.ts   | 73 ++++++++++++++++
 packages/core/src/index.gate.ts                    |  1 +
 packages/core/src/index.ts                         |  1 +
 packages/core/src/workflow-settings-resolver.ts    | 80 +++++++++++-------
 .../src/__tests__/routes-planning.test.ts          | 97 ++++++++++++++++++++++
 .../src/routes/register-planning-subtask-routes.ts | 48 ++++++++---
 8 files changed, 267 insertions(+), 42 deletions(-)

Fusion-Task-Id: FN-8534

Fusion-Task-Lineage: e6b5b546-b9f1-49c5-b680-90f24e856458

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 08:53:06 -07:00
gsxdsm
575171c54c FN-8532: fix planning stream validation state
Keep planning streams non-terminal until explicit validation.

- Clear stale generation metadata when validating a planning session
- Cover replay and response flows that defer completion until validation

Files changed:
 .../src/__tests__/routes-planning.test.ts          | 113 ++++++++++++++++-----
 packages/dashboard/src/planning.ts                 |  10 ++
 2 files changed, 97 insertions(+), 26 deletions(-)

Fusion-Task-Id: FN-8532

Fusion-Task-Lineage: 8c0ec4fc-c438-47c9-b0b0-12b116a2debd

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 01:46:50 -07:00
gsxdsm
3b45364180 FN-8531: fix planning route test plugin store setup
Restore planning route fixtures for the plugin-store context binding and current validation checkpoint flow.

- provide inert plugin-store and durable planning creation mocks
- update planning stream and response assertions for validation questions
- keep terminal stream fixtures settled before completion events

Files changed:
 .../src/__tests__/routes-planning-tracking.test.ts | 13 ++++
 .../src/__tests__/routes-planning.test.ts          | 73 ++++++++++++++++------
 2 files changed, 66 insertions(+), 20 deletions(-)

Fusion-Task-Id: FN-8531

Fusion-Task-Lineage: e1e2fae5-2410-4b02-a2e6-6994f936ee56

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 01:28:41 -07:00
gsxdsm
ebbb5948ab FN-8529: add contextual plan review comments
Enable operators to submit selected-plan suggestions through the existing Planning Mode revision flow.

- Capture text selections, batch suggestions, and retain retryable comment submissions in the Planning Mode UI.
- Validate bounded comment payloads and format them for the existing planning session update path.
- Document the workflow and add coverage for ordering, retry behavior, and selection boundaries.

Files changed:
 .changeset/fn-8529-planning-comments.md            |   7 +
 docs/dashboard-guide.md                            |   4 +
 packages/dashboard/app/api/legacy.ts               |   1 +
 packages/dashboard/app/api/planning.ts             |   9 +-
 .../dashboard/app/components/PlanningModeModal.css |  86 ++++++++++++
 .../dashboard/app/components/PlanningModeModal.tsx | 144 ++++++++++++++++++++-
 .../PlanningModeModal.planning-flow.test.tsx       |  39 ++++++
 .../PlanningModeModal.ui-interactions.test.tsx     |  10 ++
 .../__tests__/planning-infinite-interview.test.ts  |  62 +++++++++
 packages/dashboard/src/planning.ts                 |  76 ++++++++++-
 .../src/routes/register-planning-subtask-routes.ts |  27 +++-
 11 files changed, 455 insertions(+), 10 deletions(-)

Fusion-Task-Id: FN-8529

Fusion-Task-Lineage: c7064d76-effd-4597-a2b4-03f344dd59b9

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 00:56:47 -07:00
gsxdsm
5f3f7709da FN-8530: link GitHub Import to source issues
Make GitHub import provenance a direct, single source-issue link.

- Link the GitHub Import label whenever source metadata contains a URL.
- Preserve a plain provenance label when no source URL is available.
- Cover desktop, compact, nonstandard URL, and absent URL rendering.

Files changed:
 .../dashboard/app/components/TaskDetailModal.tsx   | 38 +++++++------
 .../__tests__/TaskDetailModal.rendering.test.tsx   | 66 ++++++++++++++--------
 2 files changed, 64 insertions(+), 40 deletions(-)

Fusion-Task-Id: FN-8530

Fusion-Task-Lineage: 03f899c2-2a3b-4b27-9bb6-b4db12667bb0

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-23 00:38:18 -07:00
gsxdsm
a45d82d09b chore(release): v0.73.0-beta.4
Version bump via changesets.
2026-07-23 00:16:34 -07:00
gsxdsm
616653588c refactor: package code organization wave 15 (#2394)
## Summary

Wave 15 of package code organization.

### Peels
- `types/settings-scope.ts` — global/project settings (~2.2k lines)
- `types/archive-planning.ts` — archive, mesh/multi-project, planning
sessions
- `task-store/project-store-ops.ts` — rename of `remaining-ops-1` (last
numbered ops module)

### LOC
- `types.ts` ~5872 → ~3074

## Test plan
- [x] `@fusion/core` typecheck
- [ ] CI merge gate

**Stack:** this PR → #2397 → #2398

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

* **Refactor**
* Reorganized and expanded the core public type surface into dedicated
modules for settings, archive/planning, board, tasks, todo lists, plugin
activation, and multi-project setup.
* Improved the browser-safe type exports to keep the public contracts
consistent.
* Updated internal project-level operation wiring to use the correct
project implementations.
* **Bug Fixes**
* Fixed a workflow creation test hook to inject the correct pre-insert
behavior for workflow-definition collision/allocator scenarios.
* **Chores**
  * Refreshed internal headers and updated line-count baselines.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-23 00:01:24 -07:00
gsxdsm
6111a6e3f2 fix(ci): full-suite bookkeeping v31 after origin/main (#2408)
## Summary

Restore full-suite green after latest `origin/main` landings. PR #2392
already merged; this branch starts from current main.

- **ExecutorStatusBar mobile utility test:** assert `Waiting` (product
rename from Queued) and that the In Review segment is gone.
- **AppearanceSection task-popup help:** assert FN-8478 fallback copy
(board deep-tab chips + List row/card + right-dock → movable popup).
- **Changeset format gate:** shorten
`mobile-board-pointercancel-settle.md` summary to ≤120 chars (was
blocking `pnpm test:gate` on main).

## Context

Latest main Full Suite run failed primarily on dashboard app quality
backfill:
- https://github.com/Runfusion/Fusion/actions/runs/29970703115

## Test plan

- [x] `pnpm test:gate` ×2
- [x] `utility-mobile.test.tsx` + `AppearanceSection.test.tsx`
- [x] `settings-default-descriptions.test.tsx`
- [ ] CI PR checks / Full Suite on this branch

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

## Summary by CodeRabbit

* **Bug Fixes**
* Improved mobile board column snapping when resting mid-screen,
flinging past columns, or making unintended swipes.
* Updated task status labels to show “Waiting,” “Running,” and
“Blocked.”
* Refined help text for opening tasks as popups, including click-target
and subsequent-task behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-23 00:00:45 -07:00
gsxdsm
016221c6a8 feat(chat): ground agent chat answers in live codebase investigation (#2416)
## Summary

- Add `CHAT_CODEBASE_ACCURACY_GUIDANCE` so agent chat (direct +
multi-agent rooms) investigates the live checkout with tools before
answering code/architecture questions.
- Soften chat’s pure brevity default for repo questions: still lead
short, but keep real path/symbol evidence (parity with the investigation
pressure that makes Planning Mode more accurate).
- Cover the constant and assembly via unit tests; include a patch
changeset for `@runfusion/fusion`.

## Why

Users reported Planning Mode was more accurate about the codebase than
agent chat. Plan mode inherits the triage seam’s “read/grep first, name
real files” contract; chat only had a short helpful-assistant persona
plus a brevity default, so models often answered from priors.

## Test plan

- [x] `pnpm --filter @fusion/dashboard exec vitest run
src/__tests__/chat-system-prompt.test.ts
src/__tests__/chat-manager.test.ts`
- [ ] Manually ask agent chat a project-specific architecture question
and confirm it greps/reads before answering with real paths
- [ ] Confirm non-code chat still stays short/crisp
- [ ] Confirm multi-agent room responders also receive the new guidance

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

* **Improvements**
* Improved repository/code answers by investigating the live codebase
first and prioritizing verified paths and symbols over speculation.
* Refined response-length behavior so code questions stay
evidence-focused, while non-code questions remain concise.
* Applied consistent accuracy guidance across both direct and room-based
conversations.
* **Bug Fixes**
* Prevented chat instructions from depending on unavailable mailbox
functionality, improving reliability for agentless/room flows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-23 00:00:22 -07:00
gsxdsm
fc4f5aa0e4 fix(dashboard): stop Planning Mode duplicate generations, 'AI returned no valid JSON' errors, and context-overflow failures (#2417)
## Symptom

Users reported Planning Mode regularly failing with **"AI returned no
valid JSON.. Retry this planning session or start a new one."**, and
that leaving and returning to the interface mid-generation **duplicates
the generation — infinitely**. Every app-tab switch unmounts the
Planning view, so the leave/return path is the *normal* path, not an
edge case.

## Root causes

1. **Check-then-act turn admission.** `activeGenerations.has()` was
checked at turn entry, but the record was only created inside
`runGenerationWithTimeout`, after several awaits. Overlapping turn
entries (remounted view re-submitting, racing auto-retries, duplicate
start of an existing session) both passed the guard; the second
displaced the first, and the displaced teardown disposed the
**session-shared agent the surviving turn was actively prompting** —
which then read an empty assistant message and failed parse with "AI
returned no valid JSON".
2. **Per-mount auto-retry budget.** The client reset its 3-attempt
auto-retry budget on every mount, so each return to an errored session
re-ran a full-turn regeneration (agent rebuild + complete history
replay) — forever.
3. **SSE replay appended onto existing output.** Fresh stream
connections replay buffered thinking; the client pre-seeded from
persisted `thinkingOutput` (or kept prior output on silent reconnect)
and then appended the replay — visibly doubling the generation on every
reconnect. The 100-event buffer only held a suffix of a turn, forcing
that pre-seed.
4. **Raw `session.prompt()` at context limits.** A long interview that
overflowed the model's context window errored terminally, and auto-retry
replayed the full history into a fresh agent — overflowing again,
unrecoverably.

## Fix

- Synchronous per-session **turn reservation** shared by
`submitResponse`, `retrySession`, `startExistingSession`, and the
initial turn; losers get `GenerationInProgressError` instead of
displacing the winner. Duplicate starts of a generating session are
no-ops. Rewind aborts an active generation through its own teardown
first.
- Client auto-retry budget is **module-scoped per session** (survives
remounts); exhausted budget shows the error view instead of a stuck
spinner. Retry rejections for "already in progress" rejoin the live run.
- Fresh SSE connections **clear streamed output before the buffered
replay**; buffer deepened to a full turn (2000 events); rejoin paths
reconnect cleanly instead of seeding persisted thinking.
- All six planning prompt sites route through the engine's
**`promptWithFallback`**, recovering context-window overflows via
prompt/memory compaction and `session.compact()`.
- Cosmetic: no more doubled period in the retryable parse error message.

## Symptom Verification

- **Original symptom:** "AI returned no valid JSON" after answering
questions; generations duplicating on leave/return.
- **Exact reproduction:** concurrent turn entries on one session
(submit×2, retry×2, start-while-generating) — previously
displaced/disposed the live agent mid-prompt.
- **Assertion it is gone:** `planning-turn-admission.test.ts` asserts
exactly one turn is admitted per race, the winner completes with a
question and no session error, and the shared agent is never disposed;
`planning-context-compaction.test.ts` asserts every planning prompt
routes through `promptWithFallback` (signal forwarded) and that a
recovered context overflow leaves the turn healthy.

## Verification

- `vitest run` on all 7 planning server test files + the 2 new
regression files: **40/40 pass**.
- `routes-planning*` failures at main tip are pre-existing (identical
103/126 + 3/6 counts with and without this diff; main is mid-refactor on
route wiring). `planning-answered-question-reemit` 3 timeouts also
reproduce on clean main.
- `pnpm verify:fast` green; dashboard `tsconfig.json` +
`tsconfig.app.json` typechecks clean; eslint clean on touched files.

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

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

* **Bug Fixes**
* Prevented Planning Mode from duplicating generations and triggering
“AI returned no valid JSON” errors when leaving and re-entering mid-run.
* Made planning turn handling concurrency-safe and idempotent across
submit, retry, rewind, and duplicate start actions.
* Improved SSE reconnect recovery: clearer replay after reconnect, no
duplicated “thinking” output, and preserved auto-retry limits across
remounts.
* Improved long-context recovery via fallback prompting and cleaned up
retry error formatting.

* **Tests**
* Expanded coverage for concurrent Planning actions, reconnect replay,
context compaction, rewind behavior, and retry formatting; improved
parallel test-harness reliability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 23:59:31 -07:00
gsxdsm
e5d6be4123 Fix Windows embedded PostgreSQL 0xC0000142 crashes (issue #2411) (#2418)
## Summary

Two-part fix for #2411 — Windows embedded PostgreSQL backends dying with
exception `0xC0000142` and taking the whole dashboard down.

### 1. Crash hardening + recovery (FN-8522)
- Child-only native `PATH` hardening so forked backends can always
resolve their runtime DLLs.
- Non-blocking `.pgrunner` log monitoring (shared read), eliminating the
self-inflicted ~30s `sharing violation` retry window at boot.
- Detection of the ordered 0xC0000142 shutdown sequence with a single
automatic restart of owned clusters on their resolved port, plus
operator diagnostics.

### 2. Platform-aware `max_connections` default (follow-up from
[operator
report](https://github.com/Runfusion/Fusion/issues/2411#issuecomment-5054900702))
On Windows every PostgreSQL connection is a separate process; the
embedded cluster's unconfigured `max_connections=500` cap lets backend
spawn bursts exhaust the non-interactive desktop heap, which kills
forked backends with exactly `0xC0000142`. The reporter confirmed
stability after lowering the cap.

- `embeddedPostgresMaxConnections` is now schema-unset so the server can
distinguish "operator never set it" from an explicit choice
(`getSettings()` merges schema defaults, which previously pinned 500
unconditionally and made the runtime fallback dead code).
- New `resolveEmbeddedMaxConnections()` resolves the unset default
platform-aware: **150 on win32, 500 elsewhere**. Explicit settings are
honored on every platform, clamped to [32, 2000] as before.
- Settings UI renders the cap empty ("auto") with platform-aware help
copy across all six locales.
- Fixed a latent reset bug this exposed: global "Reset this menu" wrote
`undefined` for undefined-default keys, which JSON serialization drops —
the stored value silently survived reset. Now uses null-as-delete.

## Testing
- New unit tests for `resolveEmbeddedMaxConnections` (platform defaults,
clamping, non-integer handling).
- Updated settings-defaults, default-descriptions, and SettingsModal
tests; embedded lifecycle + recovery coverage from FN-8522.
- `@fusion/core` builds clean; changesets included for both parts.

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 23:41:48 -07:00
gsxdsm
7a552832f4 FN-8528: normalize Settings navigation icon sizing
Normalize Settings navigation icons into uniform fixed slots across desktop rows.

- Move scope-icon styling into the Settings modal component stylesheet.
- Reserve consistent non-shrinking icon dimensions for custom and fallback section icons.
- Add desktop and mobile regression coverage for icon-slot behavior.

Files changed:
 .../dashboard/app/components/SettingsModal.css     | 14 +++++++++----
 .../__tests__/SettingsModal.navResize.test.tsx     | 24 ++++++++++++++++++++++
 .../components/__tests__/settings-mobile.test.tsx  |  3 ++-
 packages/dashboard/app/styles.css                  | 12 -----------
 4 files changed, 36 insertions(+), 17 deletions(-)

Fusion-Task-Id: FN-8528

Fusion-Task-Lineage: fd78495d-a2d3-4786-bc1a-919d51049e66

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-22 23:11:47 -07:00
Victor Canô
64661c3ae1 feat(dashboard): stable theme token contract and plugin overlay layering (#2415)
## Summary

Gives dashboard integrators (plugin views, embedded panels, theming
tools) a supported way to match the dashboard's look and to layer
overlay UI correctly — instead of scraping computed styles and guessing
z-index values. This implements the CSS-token bridge slice of
`docs/proposals/2026-07-01-dashboard-theme-plugin-system.md`.

Two additions, both inert unless used:

1. **Documented theme-token contract.** A "Theme tokens" section in
`docs/dashboard-guide.md` (referenced from `docs/PLUGIN_AUTHORING.md`)
declares the stable set of CSS custom properties — colors, surfaces,
status colors — that integrators may read. Tokens resolve to raw color
strings (e.g. `#161b22`) in every theme, including the newer ones. A
sync test (`theme-token-contract-docs.test.ts`) parses the doc's token
table and asserts each documented token has a real definition in the
dashboard CSS, so the contract cannot silently drift from the code.

2. **Overlay layering surface.** Overlay-style UI (palettes, pickers,
floating panels) currently has no supported way to sit above the
floating-window stack — the effective max z-index is runtime state
inside `floatingWindowStack.ts`. This PR exposes it:
- `--fusion-max-z` on `:root` — kept in sync by `floatingWindowStack`
(written at module load and after every `nextFloatingZ()` claim), so it
always reflects the true top of the dashboard-managed stack. Boot/floor
value is `11001`, chosen to clear the highest statically-declared layer
(the body-portaled model-combobox dropdown at `z-index: 11000`).
- `#plugin-overlay-root` — an empty, `pointer-events: none` sibling of
`#root` stacked at `calc(var(--fusion-max-z) + 1)`. React never renders
into it, so it is hydration-safe; integrators portal into it and
re-enable pointer events on their own elements.
- The layer bands (base UI / floating windows / toasts / dropdown /
overlay root) are documented in `styles.css` and the guide, and a guard
test (`dashboard-max-z-guard.test.ts`) scans the structural + component
CSS and fails if any static `z-index` is ever introduced above the floor
— keeping the contract honest as the codebase evolves.

## Behavior

No visual or behavioral change for existing users: `floatingWindowStack`
still returns the same values from `nextFloatingZ()`; the overlay root
is empty and click-through; tokens were already defined — this only
documents and guards them.

## Tests

- `theme-token-contract-docs.test.ts` — docs ↔ CSS sync
(non-tautological: anchored matching against real definitions).
- `floatingWindowStack.max-z.test.ts` — `--fusion-max-z` boot value and
live tracking as the stack claims z-indexes.
- `dashboard-max-z-guard.test.ts` — no static dashboard z-index above
the floor (decorative `public/theme-data.css` INT_MAX scanline overlay
deliberately excluded; it's non-interactive grain, documented in the
test).
- Changeset included (`minor`, `category: feature`). Typecheck clean.

## Open question for maintainers

The token is named `--fusion-max-z`. The existing scale uses `--z-*`
names (`--z-dropdown`, `--z-modal`) on a lower band — happy to rename to
`--z-max` / `--z-plugin-overlay` or anything that fits your convention;
the name is the only bikeshed here, the sync mechanism is independent of
it.

## AI assistance disclosure

Parts of this change were authored with AI assistance (Anthropic's
Claude); the commit carries a `Co-authored-by` trailer accordingly.
Everything was human-reviewed before submission, and the test suite and
typecheck were run locally against the current `main`.

If squash-merging with a rewritten message, please keep the attribution:

```
Co-authored-by: Claude <noreply@anthropic.com>
```


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

- **New Features**
- Added stable dashboard theme tokens for consistent plugin/integration
styling.
- Introduced a dedicated plugin overlay mount point with click-through
defaults and an overlay stacking ceiling.
- Overlay z-index now stays in sync with floating window layering
automatically.

- **Documentation**
- Added an explicit stable “theme token contract” and “overlay layering
contract,” including interaction and z-index usage rules and deprecation
expectations.

- **Bug Fixes**
- Improved reliability of plugin overlay stacking so overlay content
renders above intended dashboard layers.

- **Tests**
- Added guards validating CSS z-index ceilings and enforcing the
documented theme token contract.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-22 23:04:33 -07:00
gsxdsm
a224c11110 fix(dashboard): keep chat Latest button centered while pressed
The jump-to-latest button is centered via transform: translateX(-50%), and
the global .btn:active scale transform replaced it wholesale on mousedown,
shifting the button out from under the cursor mid-click. Compose both
transforms on :active (same fix as the DevServer new-logs button).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 23:01:51 -07:00
gsxdsm
4ef94e667d FN-8523: gate retained SQLite scans by completion marker
Keep completed SQLite migration sources inert across PostgreSQL startups.

- Gate core, central identity, and plugin reads on independent completion markers.
- Preserve PostgreSQL project identity before recording a legacy-central migration as complete.
- Cover completed backup and pending-core central-marker startup paths.

Files changed:
 .changeset/fn-8523-skip-completed-sqlite-rescan.md |   7 ++
 docs/storage.md                                    |   2 +
 .../src/__tests__/postgres/sqlite-migrator.test.ts |  15 +++
 .../postgres/startup-factory-integration.test.ts   | 111 ++++++++++++++++++++-
 packages/core/src/postgres/sqlite-migrator.ts      |  28 ++++--
 packages/core/src/postgres/startup-factory.ts      |  86 +++++++++++-----
 6 files changed, 212 insertions(+), 37 deletions(-)

Fusion-Task-Id: FN-8523

Fusion-Task-Lineage: 1a05b90d-23df-4423-8346-abd6ef35f4df

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-22 22:57:41 -07:00
gsxdsm
e16204deef FN-8522: fix Windows embedded PostgreSQL crash recovery
Harden Windows embedded PostgreSQL startup and recover once from owned-cluster DLL initialization crashes.

- Provide child-only native PATH hardening and non-blocking runner-log monitoring.
- Detect the ordered 0xC0000142 shutdown sequence and restart only owned clusters on their resolved port.
- Add lifecycle coverage and operator diagnostics for recovery behavior.

Files changed:
 .../fn-8522-windows-embedded-postgres-recovery.md  |   7 ++
 docs/diagnostics.md                                |  10 ++
 docs/storage.md                                    |   6 +
 .../__tests__/postgres/embedded-lifecycle.test.ts  |  87 ++++++++++++++
 .../postgres/embedded-windows-elevated.test.ts     |  49 ++++++++
 packages/core/src/postgres/embedded-lifecycle.ts   | 128 ++++++++++++++++++---
 .../core/src/postgres/embedded-windows-elevated.ts | 119 +++++++++++++++++--
 7 files changed, 382 insertions(+), 24 deletions(-)

Fusion-Task-Id: FN-8522

Fusion-Task-Lineage: f256e421-d82e-4afb-9f81-b5c18f1c7100

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-22 22:43:51 -07:00
gsxdsm
de5d446b5c FN-8526: add custom workflow column descriptions
Enable custom workflow authors to define and display descriptions for board columns.

- Persist optional descriptions in workflow column definitions and API responses.
- Add editor controls and board tooltips for column descriptions.
- Cover validation, API, and dashboard behavior with tests and documentation.

Files changed:
 .changeset/fn-8526-workflow-column-descriptions.md |  7 +++
 docs/dashboard-guide.md                            |  4 ++
 .../src/__tests__/workflow-ir-validation.test.ts   | 30 +++++++++++
 packages/core/src/workflow-ir-types.ts             |  4 ++
 packages/core/src/workflow-ir.ts                   |  9 ++++
 packages/dashboard/app/api/board-workflows.ts      |  2 +
 packages/dashboard/app/components/Board.tsx        |  3 ++
 packages/dashboard/app/components/Column.tsx       | 14 +++--
 .../app/components/WorkflowColumnPanel.tsx         | 31 ++++++++++++
 .../app/components/WorkflowNodeEditor.css          | 41 +++++++++++++++
 .../app/components/__tests__/Column.test.tsx       | 19 +++++++
 .../__tests__/WorkflowColumnPanel.test.tsx         | 38 ++++++++++++++-
 .../app/components/__tests__/WorkflowNodeEditor.test.tsx | 19 +++++++
 .../app/components/workflow-flow-mapping.ts        |  1 +
 packages/dashboard/app/styles.css                  |  8 +++
 .../src/__tests__/board-workflows.test.ts          | 59 ++++++++++++++++++++++
 packages/dashboard/src/routes/board-workflows.ts   |  3 ++
 17 files changed, 288 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-8526

Fusion-Task-Lineage: df26b7c0-301c-4875-b100-d63d0cfecf85

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-22 22:37:51 -07:00
gsxdsm
25cd42d020 FN-8527: theme imported task stats links
Make imported-source links in the shared Stats panel follow the active dashboard theme.

- Style imported task links with the dashboard accent and accessible focus treatment.
- Cover safe themed external links across shared Stats surfaces.
- Add a patch changeset for the user-facing visual fix.

Files changed:
 .changeset/fn-8527-themed-stats-link.md            |  7 +++++
 .../app/components/TaskTokenStatsPanel.css         | 15 +++++++++++
 .../app/components/TaskTokenStatsPanel.tsx         |  7 ++++-
 .../__tests__/TaskTokenStatsPanel.test.tsx         | 30 ++++++++++++++++++++++
 4 files changed, 58 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-8527

Fusion-Task-Lineage: c7ee16ea-23e7-462d-a5c6-799fe0ede62d

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-22 22:20:03 -07:00
gsxdsm
adf51e21d7 fix(dashboard): dispatch plugin routes dynamically per request
Plugin-defined HTTP routes were a boot-time snapshot of the launch
project's PluginLoader, while dashboard views/UI slots resolve a
project-scoped loader live per request. Two failure modes survived the
961edf214 no-engine mount fix: a plugin enabled after boot rendered its
view while every API route 404'd until restart, and a plugin enabled
only in a non-launch project never got routes mounted at all (Compound
Engineering "Failed to load sessions: Not found" on v0.73.0-beta.3).

Routes are now dispatched per request through the same
getProjectPluginLoader cache (moved from the plugins registrar into
routes/context.ts) that serves dashboard-views and enable/disable, with
the host loader + PluginRunner tables unioned in (project entries win,
loader beats runner). The compiled dispatch sub-router is cached per
resolved loader and rebuilt only when the route signature changes, so
views and routes agree by construction.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 22:11:31 -07:00