Commit Graph

2078 Commits

Author SHA1 Message Date
gsxdsm
b2613b7132 FN-7714: honor ~/.grok/user-settings.json apiKey when GROK_API_KEY is unset
Fall back to the Grok CLI's user-settings file for the API key so pi's $GROK_API_KEY provider reference resolves even when the env var isn't exported.

- Add hydrateGrokApiKeyFromUserSettings() in grok-provider.ts, called from registerBuiltInGrokProvider(), which hydrates process.env.GROK_API_KEY from ~/.grok/user-settings.json { apiKey } only when the env var is unset/empty
- Env var always wins; a missing (ENOENT), malformed, or empty-apiKey settings file is fail-soft (no throw, no env mutation), mirroring the grok-runtime probe's fallback behavior
- Add regression tests covering env-precedence, fallback hydration, and fail-soft error paths (grok-provider-user-settings.test.ts)
- Document the fallback in docs/settings-reference.md
- Add a patch changeset for @runfusion/fusion

Files changed:
 .changeset/fn-7714-grok-user-settings-apikey.md    |   7 +
 docs/settings-reference.md                         |   2 +-
 .../__tests__/grok-provider-user-settings.test.ts  | 156 +++++++++++++++++++++
 packages/core/src/grok-provider.ts                 |  47 +++++++
 4 files changed, 211 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7714

Fusion-Task-Lineage: 5450b480-3a32-4331-9494-867b84605464

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:03 -07:00
gsxdsm
7dc271027f FN-7711: add built-in Grok CLI provider to fix pi model registry lookup
Registers a built-in grok-cli provider so Grok CLI model executions no longer hard-fail with "not found in the pi model registry".

- Add packages/core/src/grok-provider.ts: built-in grok-cli provider config (xAI OpenAI-compatible endpoint https://api.x.ai/v1, api openai-completions, apiKey $GROK_API_KEY), mirroring the existing Z.ai provider
- Register the provider in packages/engine/src/pi.ts (registerExtensionProviders) and packages/engine/src/provider-registration.ts (seedDashboardProviders)
- Wire the provider into CLI entrypoints: packages/cli/src/commands/daemon.ts, dashboard.ts, serve.ts
- Export grok-provider from packages/core/src/index.ts and packages/core/src/index.gate.ts
- Add unit tests: packages/core/src/__tests__/grok-provider.test.ts, and extend packages/engine/src/__tests__/pi-create-fn-agent.test.ts and provider-registration.test.ts
- Document the new provider in docs/settings-reference.md
- Add changeset .changeset/fn-7711-grok-cli-model-registry.md (patch, category: fix)

Note: Grok CLI binary remains discovery/probe only; GrokRuntimeAdapter streaming is a stub (tracked follow-up).

Files changed:
 .changeset/fn-7711-grok-cli-model-registry.md      |   7 +
 docs/settings-reference.md                         |   2 +
 packages/cli/src/commands/daemon.ts                |   4 +
 packages/cli/src/commands/dashboard.ts             |   4 +
 packages/cli/src/commands/serve.ts                 |   4 +
 packages/core/src/__tests__/grok-provider.test.ts  | 130 ++++++++++++
 packages/core/src/grok-provider.ts                 | 224 +++++++++++++++++++++
 packages/core/src/index.gate.ts                    |   7 +
 packages/core/src/index.ts                         |   7 +
 .../src/__tests__/pi-create-fn-agent.test.ts       |  78 ++++++-
 .../src/__tests__/provider-registration.test.ts    |   4 +-
 packages/engine/src/pi.ts                          |   4 +
 packages/engine/src/provider-registration.ts       |   4 +
 13 files changed, 476 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7711

Fusion-Task-Lineage: ae90b54f-206e-46fd-8365-b0a4488ceb84

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-09 19:58:03 -07:00
gsxdsm
66069029a5 FN-7709: unref background integrity-check spawn and scheduling timer
Prevents short-lived CLI processes from being held open by background SQLite integrity checks.

- unref the sqlite3 child process (and its stdio) spawned by integrityCheckSqliteFileAsync via the shared unrefQmdChildProcess helper, immediately after spawn
- unref the 60s scheduling timer in scheduleBackgroundIntegrityCheck so a short-lived caller isn't pinned waiting for a background check it never asked to block on
- add regression test coverage (db-integrity-check-unref.test.ts) plus a CLI fixture (db-integrity-check-fixture.mjs) that exercises the fix in a real short-lived process
- add changeset documenting the fix and the audit of other spawn sites across @fusion/core/@fusion/engine/@fusion/dashboard/cli confirming they are safe

Files changed:
 .changeset/fn-7709-db-integrity-check-unref.md     |   7 ++
 .../src/__tests__/db-integrity-check-unref.test.ts | 135 +++++++++++++++++++++
 .../fixtures/db-integrity-check-fixture.mjs        |  28 +++++
 packages/core/src/db.ts                            |  26 ++++
 4 files changed, 196 insertions(+)

Fusion-Task-Id: FN-7709
Fusion-Task-Lineage: 6594aca4-0268-4bba-9a7f-af96d695f1e9
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-08 23:39:35 -07:00
gsxdsm
dcfbee9ae6 FN-7707: reuse hardened unref'd executor in searchWithQmd
Fixes searchWithQmd's inline promisify(execFile) copy that could hold a caller open by reusing the already-hardened, synchronously-unref'd executor established for the background refresh path.

- searchWithQmd now calls getDefaultExecFileAsync() instead of building its own promisify(execFile) executor inline
- Removes the second un-unref'd execFile executor that could keep a short-lived caller (e.g. one-shot CLI memory search) open up to the awaited timeout
- Adds regression test fixture and test coverage (qmd-search-fixture.mjs, qmd-search-unref.test.ts) asserting the shared executor is used
- Adds changeset (patch) for @runfusion/fusion

Files changed:
 .changeset/fn-7707-qmd-search-unref.md                       |   7 +
 packages/core/src/__tests__/fixtures/qmd-search-fixture.mjs  |  30 ++++
 packages/core/src/__tests__/qmd-search-unref.test.ts         | 166 +++++++++++++++++++++
 packages/core/src/memory-backend.ts                          |  16 +-
 4 files changed, 216 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7707
Fusion-Task-Lineage: 3f9f94a7-5613-4b9a-a3ba-8e9bcdd6b687
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-08 23:39:35 -07:00
gsxdsm
4fb2bf5c55 FN-7706: unref qmd child process so background refresh doesn't block exit
Replaces promisify(execFile) with a hand-rolled spawn()-based qmd executor that unrefs the child process and its stdio, so a fire-and-forget scheduleQmd* memory-index refresh never keeps a short-lived caller process (e.g. CLI) alive; long-lived callers like the dashboard server still see refresh resolve/reject normally.

- memory-backend.ts: replace promisify(execFile) qmd exec path with spawn()-based executor that unrefs child + stdio
- Add qmd-refresh-unref.test.ts covering unref behavior with a qmd-refresh-fixture.mjs test fixture
- Add changeset fn-7706-qmd-unref.md (patch, fix category)

Files changed:
 .changeset/fn-7706-qmd-unref.md                    |   7 ++
 .../src/__tests__/fixtures/qmd-refresh-fixture.mjs |  28 +++++
 .../core/src/__tests__/qmd-refresh-unref.test.ts   | 136 +++++++++++++++++++++
 packages/core/src/memory-backend.ts                | 123 ++++++++++++++++++-
 4 files changed, 291 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7706

Fusion-Task-Lineage: 713c23c2-d7da-42c4-b066-31883ba78321

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-08 23:39:34 -07:00
gsxdsm
081dae0e0f FN-7705: Add Grok CLI runtime support as a bundled plugin
Adds a new bundled Grok CLI runtime plugin, wiring it end-to-end into settings, auth routes, model discovery, and the dashboard authentication UI.

- New `fusion-plugin-grok-runtime` package with CLI spawn, probe, provider, process-manager, and runtime-adapter modules plus tests
- Bundled-plugin install list (CLI + core) updated to auto-install the grok-cli plugin
- New `useGrokCli`/`grokCliBinaryPath` settings in `settings-schema.ts` and `types.ts`
- Dashboard: `GrokCliProviderCard` component/styles, `ProviderIcon` grok entry, `AuthenticationSection` wiring
- New `grok-model-cache.ts` for caching `grok models` discovery results, registered model/auth routes for `/auth/grok-cli` and `/providers/grok-cli/status`, merged into `/api/models`
- `runtime-provider-probes.ts` extended with Grok CLI probe/model-discovery delegation
- Docs updated (`PLUGIN_AUTHORING.md`, `settings-reference.md`) and changeset added (minor, feature)
- Workspace config (`pnpm-workspace.yaml`, `pnpm-lock.yaml`) updated to register the new plugin package

Files changed:
 .changeset/fn-7705-grok-cli-runtime.md             |   7 +
 docs/PLUGIN_AUTHORING.md                           |   2 +-
 docs/settings-reference.md                         |   4 +
 packages/cli/src/plugins/bundled-plugin-install.ts |   8 +
 .../cli/src/plugins/staged-bundled-plugin-ids.ts   |   1 +
 packages/cli/vitest.config.ts                      |  12 +
 .../core/src/__tests__/grok-cli-settings.test.ts   |  34 +++
 packages/core/src/index.ts                         |   1 +
 .../core/src/plugins/bundled-plugin-install.ts     |  10 +
 packages/core/src/settings-schema.ts               |   6 +
 packages/core/src/types.ts                         |   9 +
 packages/dashboard/app/api/legacy.ts               |  40 ++++
 .../app/components/GrokCliProviderCard.css         |  65 ++++++
 .../app/components/GrokCliProviderCard.tsx         | 204 ++++++++++++++++
 packages/dashboard/app/components/ProviderIcon.tsx |   5 +
 .../__tests__/GrokCliProviderCard.test.tsx         | 105 +++++++++
 .../app/components/__tests__/ProviderIcon.test.tsx |   8 +
 .../settings/sections/AuthenticationSection.tsx    |   8 +-
 packages/dashboard/package.json                    |   1 +
 .../src/__tests__/grok-model-cache.test.ts         | 152 ++++++++++++
 .../register-model-routes-grok-cli.test.ts         | 214 +++++++++++++++++
 .../dashboard/src/__tests__/routes-auth.test.ts    | 258 ++++++++++++++++++++-
 packages/dashboard/src/grok-model-cache.ts         | 166 +++++++++++++
 packages/dashboard/src/routes.ts                   |   1 +
 .../dashboard/src/routes/register-auth-routes.ts   | 134 ++++++++++-
 .../dashboard/src/routes/register-model-routes.ts  |  51 ++++
 packages/dashboard/src/runtime-provider-probes.ts  |  43 ++++
 packages/dashboard/vitest.config.ts                |  12 +
 packages/desktop/scripts/workspace-tools.ts        |   3 +-
 plugins/fusion-plugin-grok-runtime/CHANGELOG.md    |   7 +
 plugins/fusion-plugin-grok-runtime/README.md       |  54 +++++
 plugins/fusion-plugin-grok-runtime/manifest.json   |   6 +
 plugins/fusion-plugin-grok-runtime/package.json    |  40 ++++
 .../src/__tests__/cli-spawn.test.ts                | 103 ++++++++
 .../src/__tests__/index.test.ts                    |  12 +
 .../src/__tests__/probe.test.ts                    | 135 +++++++++++
 .../src/__tests__/process-manager.test.ts          |  96 ++++++++
 .../src/__tests__/provider.test.ts                 |  57 +++++
 .../src/__tests__/runtime-adapter.test.ts          |  21 ++
 .../fusion-plugin-grok-runtime/src/cli-spawn.ts    |  50 ++++
 plugins/fusion-plugin-grok-runtime/src/index.ts    |  74 ++++++
 plugins/fusion-plugin-grok-runtime/src/probe.ts    | 107 +++++++++
 .../src/process-manager.ts                         |  86 +++++++
 plugins/fusion-plugin-grok-runtime/src/provider.ts |  25 ++
 .../src/runtime-adapter.ts                         |  25 ++
 plugins/fusion-plugin-grok-runtime/src/types.ts    |  12 +
 plugins/fusion-plugin-grok-runtime/tsconfig.json   |  10 +
 .../fusion-plugin-grok-runtime/vitest.config.ts    |  22 ++
 pnpm-lock.yaml                                     |  25 ++
 pnpm-workspace.yaml                                |   1 +
 50 files changed, 2525 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-7705

Fusion-Task-Lineage: b8194ea8-c773-4199-a52a-b0e4e7347192

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-08 23:39:34 -07:00
gsxdsm
67cc02750c FN-7692: fix misleading merger confirmation copy under active auto-merge
Correct the planner-oversight confirmation messaging so it no longer claims a hard block when the active auto-merge policy will actually advance the merge/pull-request stage unattended.

- decidePlannerRecovery accepts an additive, messaging-only `autoMergeWillProceed` flag and picks accurate reason wording (advisory vs. genuine human-approval block vs. neutral/unknown) for merger/pull-request await_confirmation decisions
- PlannerRecoveryController.tick threads `allowsAutoMergeProcessing(task, settings)` into decidePlannerRecovery as `autoMergeWillProceed`
- project-engine's requestConfirmation steering comment prefix changed from "confirmation required" to neutral "merge checkpoint" so it doesn't contradict the now-accurate reason text
- added regression tests in planner-recovery.test.ts and planner-overseer-intervention-wiring.test.ts
- added changeset and doc note

Files changed:
 .changeset/fn-7692-merger-confirmation-copy.md     |  7 +++
 docs/architecture.md                               | 10 +++-
 packages/core/src/__tests__/planner-recovery.test.ts    | 66 ++++++++++++++++++++++
 packages/core/src/planner-recovery.ts              | 36 +++++++++++-
 packages/engine/src/__tests__/planner-overseer-intervention-wiring.test.ts | 37 ++++++++++++
 packages/engine/src/planner-recovery-controller.ts | 14 ++++-
 packages/engine/src/project-engine.ts               | 11 +++-
 7 files changed, 176 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-7692

Fusion-Task-Lineage: 187684b8-1d24-425d-85d4-627587469908

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-08 15:09:26 -07:00
gsxdsm
461a4a2711 FN-7689: add opt-in Anthropic-style prompt caching for custom providers
Custom providers previously never enabled prompt-cache control, so agent turns re-billed the full context every request even on cache-capable backends.

- Add `CustomProvider.anthropicPromptCaching` opt-in flag in @fusion/core types
- Set pi-ai `compat.cacheControlFormat="anthropic"` on opted-in models in both registration paths: custom-provider-registry `toProviderConfig` and pi.ts `createFnAgent`
- Expose the new toggle in the dashboard CustomProvidersSection UI (with supporting CSS) and thread it through the legacy API + custom-provider routes
- Update docs (dashboard-guide, settings-reference) to document the new setting
- Add engine test coverage for the caching flag across provider registration and pi-create-fn-agent paths
- Add changeset for the fix

Files changed:
 .changeset/fn-7689-custom-provider-prompt-caching.md          |   7 +
 docs/dashboard-guide.md                                       |   1 +
 docs/settings-reference.md                                    |   2 +-
 packages/core/src/types.ts                                    |  15 ++
 packages/dashboard/app/api/legacy.ts                          |  12 ++
 packages/dashboard/app/components/CustomProvidersSection.css  |  24 +++
 packages/dashboard/app/components/CustomProvidersSection.tsx  |  58 +++++-
 packages/dashboard/src/routes/register-custom-provider-routes.ts |  16 ++
 packages/engine/src/__tests__/pi-create-fn-agent.test.ts      |  71 +++++++
 packages/engine/src/__tests__/provider-registration.test.ts   | 204 ++++++++++++++++++++-
 packages/engine/src/custom-provider-registry.ts               |  71 +++++--
 packages/engine/src/pi.ts                                     |  27 ++-
 12 files changed, 473 insertions(+), 35 deletions(-)

Fusion-Task-Id: FN-7689

Fusion-Task-Lineage: b4f88f32-50da-4651-a546-432a95a1ab1c

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-08 13:09:10 -07:00
gsxdsm
8ee8f15dc6 FN-7675: add agent runtime self-awareness to system prompts
Agents were composing plans (e.g. reboot/wait-and-retry loops) that assumed they could keep acting even after the Fusion platform itself shut down, since prompts never told them they run inside Fusion. This adds a shared, docs-grounded self-awareness preamble prepended to chat, heartbeat, and executor base prompts so agents know their own runtime constraints.

- Added FUSION_RUNTIME_SELF_AWARENESS shared preamble in packages/core/src/agent-prompts.ts, exported via packages/core/src/index.ts
- Prepended the preamble to the chat system prompt (packages/dashboard/src/chat.ts)
- Prepended the preamble to the heartbeat session prompt (packages/engine/src/agent-heartbeat.ts)
- Prepended the preamble to the executor base prompt (packages/engine/src/executor.ts)
- Updated docs/agents.md and CONCEPTS.md to document the new self-awareness/capability-grounding behavior
- Added regression tests across core, dashboard, and engine covering the new prompt content
- Added changeset for @runfusion/fusion (minor, fix category)

Files changed:
 .changeset/fn-7675-agent-runtime-self-awareness.md |  7 ++++
 CONCEPTS.md                                        |  4 +-
 docs/agents.md                                     | 17 ++++++++
 packages/core/src/__tests__/agent-prompts.test.ts  | 41 ++++++++++++++++++++
 packages/core/src/agent-prompts.ts                 | 32 ++++++++++++++-
 packages/core/src/index.ts                         |  1 +
 packages/dashboard/src/__tests__/chat-system-prompt.test.ts | 17 ++++++++
 packages/dashboard/src/chat.ts                     |  6 ++-
 packages/engine/src/__tests__/executor-prompt.test.ts       | 45 ++++++++++++++++++++++
 packages/engine/src/__tests__/heartbeat-session-prompt.test.ts | 35 +++++++++++++++++
 packages/engine/src/agent-heartbeat.ts             | 10 +++--
 packages/engine/src/executor.ts                    |  7 +++-
 12 files changed, 213 insertions(+), 9 deletions(-)

Fusion-Task-Id: FN-7675

Fusion-Task-Lineage: 126d04a6-2c68-4347-9789-591b274277bf

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-08 08:16:30 -07:00
gsxdsm
38d883d83e fix: surface model-lane drift when a workflow's default model changes (#1958)
## Problem

A task's model fields (`modelProvider`/`modelId` and the
planning/validator
equivalents) are snapshotted once at task-creation time from the
workflow's
model-lane default in `workflow_settings`. Nothing re-syncs, flags, or
surfaces drift when that default is later changed.

Concretely: the `builtin:coding` workflow's execution default was
`claude-sonnet-4-6` until it was corrected on 2026-07-05. Every task
created
before that correction stayed permanently, invisibly pinned to the stale
model id — 52 tasks were found silently stuck on it.

## Fix

- `TaskStore.getModelLaneDrift(workflowId, before, after)`
(`packages/core/src/store.ts`):
read-only diff over the three model lanes
(execution/planning/validator).
  For any lane whose provider+modelId actually changed, it lists the
non-terminal (`column` not `archived`/`done`, not soft-deleted) tasks on
  that workflow still pinned to the old value. Never mutates `tasks`.
- Wired into `PATCH /workflows/:id/setting-values`
(`packages/dashboard/src/routes/register-workflow-routes.ts`): captures
a
  `before` snapshot, runs the existing `updateWorkflowSettingValues`
unchanged, then attaches an optional `modelDrift` field to the response
when a lane change orphans existing tasks. Backward compatible — the
field
  is only present when non-empty.
- Operators can act on the surfaced drift via the existing
`POST /tasks/batch-update-models` endpoint; this change intentionally
does
  not auto-rewrite any task (avoids touching tasks mid-execution).

## Testing

- New tests in `packages/core/src/__tests__/workflow-settings.test.ts`
(`TaskStore.getModelLaneDrift`): verifies a task pinned to a changed
lane's
old value is surfaced, a task already on the new value and a
`done`-column
task are excluded, and an unrelated/unchanged lane produces no drift
entry.
- `packages/core`: `npx vitest run
src/__tests__/workflow-settings.test.ts` — 24/24 pass.
- `npx tsc --noEmit` clean in both `packages/core` and
`packages/dashboard`.

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

* **New Features**
* Workflow setting updates can now return a lane-based model drift
summary (execution, planning, validator) showing task IDs still pinned
to the previous model configuration.
* The PATCH workflow setting response conditionally includes
`modelDrift` when impacted tasks are found.
* **Bug Fixes**
* Drift detection now compares a consistent “before” snapshot with the
updated values to avoid stale pairing.
* “No workflow selection” tasks are handled correctly based on the
default-workflow behavior.
* **Tests**
* Added coverage for lane drift across model changes and null-selection
inclusion rules.
* **Documentation**
  * Added a release note entry for the change.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-08 07:33:26 -07:00
gsxdsm
176222918a fix(dashboard): address model-lane drift review feedback
- getModelLaneDrift now takes an explicit includeNullSelection option; the
  setting-values route passes it when patching the project default workflow so
  no-workflow-selection tasks (which resolve through the default) are counted
  instead of silently dropped (Greptile P1).
- Add updateWorkflowSettingValuesWithPrevious so the drift baseline is captured
  inside the settings write transaction, removing the stale-read race against a
  concurrent patch of the same row (Greptile P2).
- Broaden getModelLaneDrift tests to cover planning and validator lanes and the
  null-selection/default-workflow case (FN-5893 invariant across surfaces).
- Add changeset.

CodeRabbit's effective-values suggestion is intentionally skipped: model-lane
declarations carry no declaration-level default (KTD-7), so effective == raw for
these keys and comparing effective values is a no-op.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 07:26:26 -07:00
gsxdsm
6902077972 FN-7667: add gate-scoped @fusion/core barrel to decouple engine-core gate from full barrel growth
Introduces a project-scoped @fusion/core barrel used only by the engine-core
gate project, so new feature modules added to the full barrel don't silently
inflate the gate's transform/import cost.

- Add packages/core/src/index.gate.ts, a copy of the full @fusion/core barrel
  minus export statements for modules added since the last re-audit baseline
  (i.e. it still re-exports everything the full barrel does except newly
  added, gate-irrelevant feature modules).
- Update packages/engine/vitest.config.ts to add a project-scoped
  resolve.alias mapping @fusion/core -> packages/core/src/index.gate.ts for
  the engine-core project only; engine-default/engine-reliability/engine-slow
  and @fusion/engine continue to resolve the full barrel.
- Document the gate-safe barrel and its audit procedure in docs/testing.md.

Files changed:
 docs/testing.md                  |    3 +
 packages/core/src/index.gate.ts  | 2102 ++++++++++++++++++++++++++++++++++++++
 packages/engine/vitest.config.ts |   17 +
 3 files changed, 2122 insertions(+)

Fusion-Task-Id: FN-7667

Fusion-Task-Lineage: 054ec89a-d973-44dd-b9ac-ad266f553f01

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-08 03:28:37 -07:00
gsxdsm
03161adfb9 FN-7659: paginate and sort the Archived column newest-first
Adds server-side pagination for the Archived task column, sorted by most-recently-archived first, with a Show more control on the dashboard.

- Add ArchiveDatabase.listPage and TaskStore.listArchivedTasks for a bounded SQL LIMIT/OFFSET read ordered by archivedAt DESC
- Add GET /tasks/archived route for paged archive fetches, leaving the legacy merged listTasks({includeArchived}) path unchanged
- Wire useTasks.loadArchivedTasks to fetch page 1 on first Archived-column expand and loadMoreArchivedTasks for subsequent pages
- Add a "Show more" affordance in Column.tsx/Board.tsx/MainContent.tsx to trigger loading additional archived pages
- Extend taskSorting.ts to keep archived task ordering stable with the new paged data
- Add core and dashboard tests covering archive pagination and store/route behavior
- Add changeset for @runfusion/fusion (minor) and update docs/storage.md and docs/dashboard-guide.md

Files changed:
 .changeset/FN-7659-archived-pagination.md          |   7 +
 docs/dashboard-guide.md                            |   4 +-
 docs/storage.md                                    |   7 +
 packages/core/src/__tests__/archive-db-pagination.test.ts    |  94 ++++++++
 packages/core/src/__tests__/store-archive-search.test.ts     |  63 ++++++
 packages/core/src/archive-db.ts                    |  18 ++
 packages/core/src/store.ts                         |  32 +++
 packages/dashboard/app/App.tsx                     |   5 +-
 packages/dashboard/app/api/legacy.ts               |  19 ++
 packages/dashboard/app/components/Board.tsx        |  19 +-
 packages/dashboard/app/components/Column.tsx       |  48 ++++-
 packages/dashboard/app/components/__tests__/Column.test.tsx       |  41 ++++
 packages/dashboard/app/components/__tests__/taskSorting.test.ts   |  27 +++
 packages/dashboard/app/components/dashboard/MainContent.tsx       |   9 +
 packages/dashboard/app/components/dashboard/types.ts    |   6 +
 packages/dashboard/app/components/taskSorting.ts   |  16 ++
 packages/dashboard/app/hooks/__tests__/useTasks.test.ts | 236 ++++++++++++++++++++-
 packages/dashboard/app/hooks/useTasks.ts           | 173 ++++++++++++++-
 packages/dashboard/app/test/mockApi.ts             |   3 +
 packages/dashboard/src/routes/__tests__/tasks-archived-pagination.test.ts |  94 ++++++++
 packages/dashboard/src/routes/register-task-workflow-routes.ts  |  32 +++
 21 files changed, 930 insertions(+), 23 deletions(-)

Fusion-Task-Id: FN-7659

Fusion-Task-Lineage: 7a5a1f62-277c-4f29-883c-62e75b269bc5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-08 01:29:56 -07:00
gsxdsm
f7d9509294 FN-7658: gate same-agent duplicate auto-archiving behind opt-in setting
Duplicate tasks created by the same agent are no longer auto-archived by default; they are flagged for review instead, controlled by a new opt-in project setting.

- Add project setting `autoArchiveDuplicateTasksEnabled` (default false) gating the FN-4892 same-agent duplicate intake path
- Add `flagSameAgentDuplicate` path and `nearDuplicateOf` metadata used when auto-archive is disabled; tombstone-resurrection blocking is unchanged
- Wire the setting through core settings schema/types/store, dashboard SchedulingSection UI, and i18n strings
- Update docs (settings-reference.md, task-management.md) to describe the new default-off behavior
- Add a changeset for the @runfusion/fusion minor release
- Extend duplicate-intake, tombstone-window, store-parent-task-dedup, and reliability-interaction tests to cover both flag states

Files changed:
$(cat /tmp/fn7658_stat.txt)

Fusion-Task-Id: FN-7658

Fusion-Task-Lineage: 7d0d1074-1020-48a8-b96f-186154c2c408

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-08 00:23:32 -07:00
fusion-merge-train
83a9cf15d0 fix: surface model-lane drift when a workflow's default model changes
Task model fields (execution/planning/validator provider+modelId) are
snapshotted once at task-creation time from the workflow's model-lane
default and never re-synced. Changing a workflow's default (e.g. fixing
a stale model id) silently leaves already-created tasks pinned to the
old value with no visibility — this is exactly how 52 tasks stayed
pinned to a stale claude-sonnet-4-6 default after it was corrected.

Add TaskStore.getModelLaneDrift(workflowId, before, after), a read-only
diff over the three model lanes that lists non-terminal tasks still
pinned to a lane's old value. Wire it into
PATCH /workflows/:id/setting-values so the response includes
`modelDrift` whenever a lane change orphans existing tasks. Operators
can then act via the existing POST /tasks/batch-update-models.
2026-07-08 09:10:49 +02:00
gsxdsm
ac719d1203 fix: add usage_events to operational-log retention
usage_events was absent from Database.pruneOperationalLogs, so the
per-tool telemetry log grew unbounded (~187k rows / ~28MB observed) and
became a dominant driver of .fusion DB bloat once runAuditEvents was
already 30-day capped. Prune it on the same operationalLogRetentionDays
cadence, keyed off its `ts` column (not `timestamp`), alongside the other
column-name exceptions. Adds a regression test and changeset.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 22:58:11 -07:00
gsxdsm
4e8c621e9c FN-7641: fix cards stranded after out-of-band/workspace merges by allowing proven-merge rehome
Fixes a state-machine bug family where cards got stranded after out-of-band or workspace merges landed: store.moveTask now allows a proven-merge recoveryRehome to cross legacy columns (e.g. todo→done), and nodeId='end' finalize no longer silently no-ops — it finalizes on durable merge proof or returns an explicit error, consistently across the dashboard route, the CLI task-update tool, and store.updateTask.

- packages/core/src/store.ts: allow proven-merge recoveryRehome moves across legacy columns (e.g. todo→done) instead of rejecting them
- packages/core/src/node-override-guard.ts: nodeId='end' finalize now checks for durable merge proof and returns an explicit error instead of silently no-op'ing
- packages/dashboard/src/routes/register-task-workflow-routes.ts: dashboard workflow route surfaces the new explicit finalize error/behavior
- packages/cli/src/extension.ts: CLI task-update tool surfaces the same explicit finalize error/behavior
- docs/task-management.md: documented the updated finalize/rehome behavior
- Added regression tests across core (node-override-guard, store-movement, task-node-override), dashboard (register-task-workflow-routes.nodeid-finalize), engine (merger-merge-lifecycle), and CLI (extension) covering the stranded-card invariant
- Added changeset for @runfusion/fusion (patch)

Files changed:
 .changeset/fn-7641-stranded-cards-after-merge.md   |  7 ++
 docs/task-management.md                            |  2 +
 packages/cli/src/__tests__/extension.test.ts       | 59 ++++++++++++++
 packages/cli/src/extension.ts                      | 10 +++
 .../core/src/__tests__/node-override-guard.test.ts | 93 +++++++++++++++++++++
 packages/core/src/__tests__/store-movement.test.ts | 94 ++++++++++++++++++++++
 .../core/src/__tests__/task-node-override.test.ts  | 73 +++++++++++++++++
 packages/core/src/node-override-guard.ts           | 69 +++++++++++++++-
 packages/core/src/store.ts                         | 69 +++++++++++++++-
 ...er-task-workflow-routes.nodeid-finalize.test.ts | 90 +++++++++++++++++++++
 .../src/routes/register-task-workflow-routes.ts    | 10 +++
 .../src/__tests__/merger-merge-lifecycle.test.ts   | 58 +++++++++++++
 12 files changed, 631 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7641

Fusion-Task-Lineage: 48ea7851-ee68-48f1-92f9-302d0da5acff

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-07 22:06:20 -07:00
gsxdsm
6777eea5d2 FN-7631: add content search to Chat sidebar with title-only toggle
Chat sidebar search now matches message content by default, not just the conversation title/agent, with an opt-out toggle to restore title-only filtering.

- Add ChatStore.searchSessionsByMessageContent (parameterized LIKE ... ESCAPE) for server-side content search across sessions
- GET /chat/sessions route (register-chat-routes.ts, legacy.ts) gains q/titleOnly query params, debounced server-side content lookup merged with local title/agent matches
- useChat hook exposes searchInTitleOnly state and wires debounced content search into session list results
- ChatView renders a "Search in title only" toggle beside the search box (desktop + mobile) and shows a "Matched: ..." preview snippet on content-matched rows
- Task-planner sessions remain excluded from content matches via the same common-feed visibility guard used for the normal session list
- Add unit/integration tests: chat-store content-search, chat-routes API test, ChatView content-search test
- Update docs/dashboard-guide.md to document the new content search behavior and toggle
- Add changeset fn-7631-chat-content-search.md (@runfusion/fusion minor)

Files changed:
 .changeset/fn-7631-chat-content-search.md          |   7 +
 docs/dashboard-guide.md                            |   2 +
 .../__tests__/chat-store.content-search.test.ts    | 157 +++++++++++++++++++++
 packages/core/src/chat-store.ts                    |  64 +++++++++
 packages/core/src/chat-types.ts                    |   8 ++
 packages/dashboard/app/api/legacy.ts               |  23 ++-
 packages/dashboard/app/components/ChatView.css     |  30 ++++
 packages/dashboard/app/components/ChatView.tsx     |  26 ++++
 .../__tests__/ChatView.autosize.test.tsx           |   2 +
 .../__tests__/ChatView.content-search.test.tsx     | 114 +++++++++++++++
 .../components/__tests__/ChatView.draft.test.tsx   |   2 +
 .../__tests__/ChatView.hash-mention.test.tsx       |   2 +
 .../__tests__/ChatView.mobile-render.test.tsx      |   2 +
 .../components/__tests__/ChatView.rooms.test.tsx   |   2 +
 .../__tests__/ChatView.scroll-to-top.test.tsx      |   2 +
 .../components/__tests__/ChatView.test-harness.tsx |   2 +
 packages/dashboard/app/hooks/useChat.ts            | 105 ++++++++++++--
 .../dashboard/src/__tests__/chat-routes.test.ts    |  78 ++++++++++
 .../dashboard/src/routes/register-chat-routes.ts   |  39 ++++-
 packages/i18n/locales/en/app.json                  |   2 +
 packages/i18n/locales/es/app.json                  |   2 +
 packages/i18n/locales/fr/app.json                  |   2 +
 packages/i18n/locales/ko/app.json                  |   2 +
 packages/i18n/locales/zh-CN/app.json               |   2 +
 packages/i18n/locales/zh-TW/app.json               |   2 +
 25 files changed, 667 insertions(+), 12 deletions(-)

Fusion-Task-Id: FN-7631

Fusion-Task-Lineage: bc68b489-26a7-453e-901b-bda816af364e

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-07 22:06:17 -07:00
gsxdsm
26f22861fa FN-7637: port bundled-plugin auto-install into @fusion/core for the desktop runtime
Move the host-agnostic bundled-plugin auto-install logic (manifest loading, entry-path
resolution, install/update/enable flow) out of the CLI package into @fusion/core so the
desktop embedded runtime can auto-install bundled runtime plugins without depending on
the CLI package; the CLI module becomes a thin adapter that supplies its own bundle-dir
resolution to the shared helper.

- Add packages/core/src/plugins/bundled-plugin-install.ts with the shared, host-agnostic
  ensureBundledPluginInstalled / ensureBundledDependencyGraphPluginInstalled /
  ensureBundledCursorRuntimePluginInstalled implementation and BUNDLED_PLUGIN_IDS/
  isBundledPluginId/resolvePluginEntryPath, exported from @fusion/core's index.
- Slim packages/cli/src/plugins/bundled-plugin-install.ts to a CLI-specific
  candidate-bundle-dir resolver that delegates to @fusion/core and re-exports the same
  public surface dashboard.ts/serve.ts/daemon.ts already depend on.
- Remove the now-redundant packages/cli/src/plugins/__tests__/resolve-plugin-entry-path-sync.test.ts
  (coverage moved with the implementation to @fusion/core).
- Add packages/desktop/src/bundled-plugin-dirs.ts to resolve each bundled plugin's staged
  package directory via import.meta.resolve, mirroring the CLI's dist/plugins/<id> resolver.
- Wire local-runtime.ts and local-server.ts to call ensureBundledPluginInstalled before
  loadAllPlugins() and expose a lazy-install callback for PUT /api/plugins/:id/settings,
  mirroring the CLI dashboard command's startup auto-install pass.
- Update docs/PLUGIN_AUTHORING.md to describe the shared bundled-plugin-install location.

Files changed:
 docs/PLUGIN_AUTHORING.md                           |  11 +
 .../__tests__/bundled-plugin-install.test.ts       | 619 ++-------------------
 .../resolve-plugin-entry-path-sync.test.ts         |  97 ----
 packages/cli/src/plugins/bundled-plugin-install.ts | 250 +--------
 packages/core/src/index.ts                         |   8 +
 .../__tests__/bundled-plugin-install.test.ts       | 391 +++++++++++++
 .../core/src/plugins/bundled-plugin-install.ts     | 186 +++++++
 .../src/__tests__/bundled-plugin-dirs.test.ts      |  59 ++
 .../desktop/src/__tests__/local-runtime.test.ts    | 183 +++++-
 .../desktop/src/__tests__/local-server.test.ts     |  96 +++-
 packages/desktop/src/bundled-plugin-dirs.ts        |  61 ++
 packages/desktop/src/local-runtime.ts              |  66 ++-
 packages/desktop/src/local-server.ts               |  36 +-
 13 files changed, 1171 insertions(+), 892 deletions(-)

Fusion-Task-Id: FN-7637

Fusion-Task-Lineage: 953c5b82-a079-4600-b3af-45c974cd5014

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-07 22:06:16 -07:00
gsxdsm
42009cfdb9 FN-7628: allow editing sent chat messages and rewinding agent responses
Adds the ability to edit a previously sent message in an agent chat, which rewinds the session/task room and regenerates the response from the edited message.

- Add chat-store support for locating/replacing a message and truncating subsequent history for a rewind
- Add a chat-manager rewind-session flow and a new register-chat-routes endpoint to rewind a room to an edited message
- Add legacy API route wiring and useChat hook support for issuing an edit request
- Add ChatView/StandardChatSurface/TaskPlannerChatTab UI affordances (edit control, styling) to trigger message edits
- Add a changeset documenting the new chat message-edit capability
- Add unit/integration tests covering chat-store rewind logic, chat-manager rewind-session behavior, chat routes, useChat, and ChatView edit UI

Files changed:
 .changeset/fn-7628-chat-message-edit.md            |   7 +
 docs/dashboard-guide.md                            |   4 +
 packages/core/src/__tests__/chat-store.test.ts     | 171 ++++++++++++++
 packages/core/src/chat-store.ts                    |  95 ++++++++
 packages/dashboard/app/api/legacy.ts               |  22 ++
 packages/dashboard/app/components/ChatView.css     |  78 ++++++
 packages/dashboard/app/components/ChatView.tsx     |  14 ++
 .../app/components/StandardChatSurface.tsx         |  87 ++++++-
 .../app/components/TaskPlannerChatTab.tsx          |   8 +
 .../__tests__/ChatView.autosize.test.tsx           |   1 +
 .../__tests__/ChatView.default-model-icon.test.tsx |   1 +
 .../components/__tests__/ChatView.draft.test.tsx   |   1 +
 .../__tests__/ChatView.hash-mention.test.tsx       |   1 +
 .../__tests__/ChatView.message-edit.test.tsx       | 262 +++++++++++++++++++++
 .../__tests__/ChatView.mobile-render.test.tsx      |   1 +
 .../components/__tests__/ChatView.rooms.test.tsx   |   1 +
 .../__tests__/ChatView.scroll-to-top.test.tsx      |   1 +
 .../components/__tests__/ChatView.test-harness.tsx |   1 +
 .../dashboard/app/hooks/__tests__/useChat.test.ts  |  98 ++++++++
 packages/dashboard/app/hooks/useChat.ts            |  60 +++++
 .../__tests__/chat-manager-rewind-session.test.ts  | 185 +++++++++++++++
 .../dashboard/src/__tests__/chat-manager.test.ts   |  12 +
 .../dashboard/src/__tests__/chat-routes.test.ts    | 124 ++++++++++
 packages/dashboard/src/chat.ts                     | 147 +++++++++++-
 .../dashboard/src/routes/register-chat-routes.ts   |  52 ++++
 25 files changed, 1429 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-7628

Fusion-Task-Lineage: 36d98989-1b75-428c-baf1-b2c7e8e78013

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-07 22:06:15 -07:00
gsxdsm
0f2bfa546c FN-7629: add enable/disable control for built-in runtime plugins
Adds a durable Plugin Manager toggle to enable/disable built-in runtime plugins (Hermes, Paperclip, OpenClaw, Droid) that persists across restarts, replacing the dead-end "Built-in metadata only" CTA.

- renderBuiltinPluginSection now renders an enable/disable toggle for runtime built-ins regardless of installed status
- Disabling a not-yet-installed built-in first installs it (mirroring CLI's ensureBundledPluginInstalled) then immediately disables it, so a plugin_installs row + disabled project state exists with no new persistence primitive needed
- HermesRuntimeCard/OpenClawRuntimeCard/PaperclipRuntimeCard now show "Disabled in Plugin Manager" instead of a stale detected/connected status when disabled
- Added i18n strings across all locales and updated docs
- Added changeset for @runfusion/fusion (minor)
- Expanded plugin-loader and PluginManager test coverage for the new disable/enable flows

Files changed:
 .changeset/fn-7629-builtin-runtime-disable.md      |   7 +
 docs/dashboard-guide.md                            |   1 +
 docs/plugin-management.md                          |   4 +
 packages/core/src/__tests__/plugin-loader.test.ts  |  46 ++++++
 .../dashboard/app/components/HermesRuntimeCard.tsx |  40 ++++-
 .../app/components/OpenClawRuntimeCard.tsx         |  32 +++-
 .../app/components/PaperclipRuntimeCard.tsx        |  32 +++-
 .../dashboard/app/components/PluginManager.css     |  34 +++++
 .../dashboard/app/components/PluginManager.tsx     | 167 +++++++++++++++------
 .../components/__tests__/PluginManager.test.tsx    |  12 +-
 .../__tests__/PluginManager.toggle.test.tsx        | 104 ++++++++++++-
 packages/i18n/locales/en/app.json                  |   4 +
 packages/i18n/locales/es/app.json                  |   4 +
 packages/i18n/locales/fr/app.json                  |   4 +
 packages/i18n/locales/ko/app.json                  |   4 +
 packages/i18n/locales/zh-CN/app.json               |   4 +
 packages/i18n/locales/zh-TW/app.json               |   4 +
 packages/i18n/src/resources.d.ts                   |   4 +
 18 files changed, 440 insertions(+), 67 deletions(-)

Fusion-Task-Id: FN-7629
Fusion-Task-Lineage: 2a25bb1f-3f73-4273-8769-af05c61778f9
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-07 22:04:53 -07:00
gsxdsm
9e5c025113 FN-7608: block executors on pending approvals instead of allowing workarounds
Executors could previously treat a pending approval as a normal turn end and go hunt for ungated workarounds instead of stopping. This change makes wait-for-approval a hard suspend point.

- wait-for-approval now suspends the in-flight executor session via awaitAbortInFlightTaskWork
- Dedupe identical pending approvals so repeated waits don't pile up
- Executor prompts now carve out awaiting-approval as a legitimate turn end (agent-prompts.ts)
- Extend provisioning-gate and agent-action-gate coverage for the new suspend/carveout behavior
- Add changeset (patch) documenting the fix for release notes
- Update docs/agents.md and docs/architecture.md to describe the new blocking behavior

Files changed:
 .changeset/fn-7608-awaiting-approval-blocking.md   |   7 ++
 docs/agents.md                                     |   1 +
 docs/architecture.md                               |   1 +
 packages/core/src/agent-prompts.ts                 |   5 +
 .../engine/src/__tests__/agent-action-gate.test.ts |  82 +++++++++++++
 .../executor-approval-gate-suspend.test.ts         | 128 +++++++++++++++++++++
 .../executor-approval-prompt-carveout.test.ts      |  61 ++++++++++
 packages/engine/src/agent-heartbeat.ts             |  13 +++
 packages/engine/src/executor.ts                    |  28 +++++
 packages/engine/src/pi.ts                          |  22 +++-
 .../sandbox/__tests__/provisioning-gate.test.ts    |  29 +++++
 packages/engine/src/sandbox/provisioning-gate.ts   |  11 ++
 12 files changed, 384 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-7608

Fusion-Task-Lineage: 9e42d8ee-bda7-4ef1-b159-46c2100bbc48

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-06 19:03:07 -07:00
gsxdsm
e44458119c FN-7616: make the Planning Mode deepening prompt plan-specific
Replace the fixed generic "Would you like to go deeper?" theme buckets with AI-proposed, plan-specific topics, falling back to the existing regex-derived themes when the AI supplies none.

- Add optional PlanningSummary.deepeningThemes (id/label/description) to the completion payload contract in @fusion/core.
- Instruct the planning AI prompt to propose 2-5 concrete, plan-aligned deepening themes tied to the plan's actual title/description/deliverables.
- Add normalizeDeepeningThemes to validate/sanitize untrusted AI-supplied theme data (dedupe, cap at 6, trim, drop malformed entries) and omit the field entirely when nothing valid remains.
- Update buildDeepeningCheckpointOptions to prefer AI-supplied deepeningThemes over the generic CHECKPOINT_THEME_CANDIDATES regex fallback, keeping the reserved 'Proceed to final plan' option first and deterministic in both branches.
- Update docs/dashboard-guide.md to describe the new plan-specific deepening behavior and its generic fallback.
- Add unit test coverage for the new normalization and checkpoint-option-building logic.
- Add a minor changeset for @runfusion/fusion.

Files changed:
 .changeset/fn-7616-planning-deepening-themes.md    |   7 +
 docs/dashboard-guide.md                            |   3 +-
 packages/core/src/types.ts                         |  11 ++
 .../planning-interview-formatters.test.ts          | 176 +++++++++++++++++++++
 .../src/__tests__/routes-planning.test.ts          |  61 +++++++
 packages/dashboard/src/planning.ts                 |  86 +++++++++-
 6 files changed, 341 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7616

Fusion-Task-Lineage: f6c1d0d7-f0ca-45c9-85cd-d57958ad94c7

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-06 19:03:07 -07:00
gsxdsm
44442622c5 FN-7609: show gated action payload details on approval requests
Approval cards previously showed only a generic gating message with no visibility into the underlying command/arguments being approved, and repeated pending requests for the same action could pile up as duplicates.

- Add GatedActionApprovalDetails component to render the gated command/arguments payload on agent-gating approval cards in MailboxView
- Persist approvalDedupeKey in targetAction.context and a payload-bearing summary via buildAgentGatedActionSummary in permanent-agent-gating
- Wire agent-heartbeat, executor, and pi to pass through the richer gated-action context/summary
- Add changeset (patch) documenting the fix
- Update docs/dashboard-guide.md
- Add/extend tests: GatedActionApprovalDetails, MailboxView, permanent-agent-gating, pi-create-fn-agent

Files changed:
 .changeset/FN-7609-gated-action-approval-payload.md            |  7 ++
 docs/dashboard-guide.md                                        |  1 +
 packages/core/src/types.ts                                     |  8 +++
 .../app/components/GatedActionApprovalDetails.css              | 50 ++++++++++++++
 .../app/components/GatedActionApprovalDetails.tsx              | 72 +++++++++++++++++++
 packages/dashboard/app/components/MailboxView.tsx               | 12 ++++
 .../__tests__/GatedActionApprovalDetails.test.tsx               | 66 ++++++++++++++++++
 .../app/components/__tests__/MailboxView.test.tsx                | 41 +++++++++++
 .../src/__tests__/permanent-agent-gating.test.ts                 | 31 +++++++++
 .../src/__tests__/pi-create-fn-agent.test.ts                     | 80 ++++++++++++++++++++++
 packages/engine/src/agent-heartbeat.ts                           | 19 ++++-
 packages/engine/src/executor.ts                                  | 19 ++++-
 packages/engine/src/permanent-agent-gating.ts                    | 53 ++++++++++++++
 packages/engine/src/pi.ts                                        |  6 ++
 14 files changed, 461 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-7609

Fusion-Task-Lineage: 80a6bb5b-79f7-4b78-9204-402c2dea6171

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-06 19:03:06 -07:00
Phil Larson
3d60f67fab fix(missions): address generated fix review blockers 2026-07-05 22:14:22 -07:00
Phil Larson
3744fbcc2f fix(missions): supersede stale generated fix features 2026-07-05 21:50:28 -07:00
gsxdsm
dc447304a9 fix(FN-7591): allow moving tasks out of custom workflow columns (Coding (Ideas))
Moving a card out of a non-legacy workflow column — e.g. Coding (Ideas)
"ideas" → "todo" — was rejected with "Invalid transition: 'ideas' → 'todo'.
Valid targets: none".

Workflow columns graduated to always-on but moveTaskInternal's compat-flag
legacy branch (the default path, since no experimental flag is emitted)
validated every move against the legacy VALID_TRANSITIONS table, which is
keyed only by the built-in column ids. Default-workflow moves survived by
coincidence (its ids ARE the legacy ids); a task in a custom column had no
key so every move was rejected.

The legacy branch now resolves a non-legacy source column's targets from the
task's own workflow adjacency (resolveAllowedColumns), while keeping the
legacy bare-Error contract intact for legacy columns (transition-parity /
characterization suites unchanged). Adds a regression test covering the
ideas -> todo -> in-progress -> in-review chain and non-adjacent rejection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 19:06:32 -07:00
gsxdsm
e0f3d3d14c FN-7599: rename triage column label to Planning in default workflows
Renames the default-workflow intake column's display label from "Triage" to "Planning" across the built-in coding, stepwise-coding, and PR workflows, while keeping the column id as `triage` for lifecycle/DB/type stability.

- builtin-coding-workflow-ir.ts: intake column name "Triage" -> "Planning"
- builtin-pr-workflow-ir.ts: intake column name "Triage" -> "Planning"
- builtin-stepwise-coding-workflow-ir.ts: intake column name "Triage" -> "Planning"
- Added regression tests asserting the intake column is labeled "Planning" with id "triage" in builtin-coding and hand-authored default workflows (stepwise-coding, pr-workflow)
- Added changeset (patch) documenting the label change for @runfusion/fusion

Files changed:
 .changeset/fn-7599-planning-column-rename.md                 |  7 +++++++
 .../core/src/__tests__/builtin-coding-workflow-ir.test.ts    |  7 +++++++
 packages/core/src/__tests__/builtin-workflows.test.ts        | 12 ++++++++++++
 packages/core/src/builtin-coding-workflow-ir.ts              |  3 ++-
 packages/core/src/builtin-pr-workflow-ir.ts                  |  2 +-
 packages/core/src/builtin-stepwise-coding-workflow-ir.ts     |  2 +-
 6 files changed, 30 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7599

Fusion-Task-Lineage: 5de8abc4-2407-4f9a-b97c-bd5b900d8fd9

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 16:58:42 -07:00
gsxdsm
09a1c9d843 FN-7596: regression-test the Coding (Ideas) manual-intake lifecycle end-to-end
Adds cross-layer regression coverage for the manual-intake parking lifecycle (create -> parked -> operator Start promotion -> poll-time todo-discovery), and clarifies the workflow-steps doc to describe the tested lifecycle.

- packages/core: covers store create -> moveTask promotion out of the parked intake column
- packages/engine: covers triage poll ordering/discovery of the still-unplanned bootstrap-stub card
- packages/dashboard: covers TaskCard's Start affordance for parked cards
- docs: documents the full regression-tested lifecycle for manual-intake column parking (FN-7596)

Files changed:
 docs/workflow-steps.md                             |   2 +-
 .../__tests__/store-create-intake-column.test.ts   |  26 ++++
 .../app/components/__tests__/TaskCard.test.tsx     | 153 +++++++++++++++++++++
 packages/engine/src/__tests__/triage.test.ts       | 119 +++++++++++++++-
 4 files changed, 298 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7596

Fusion-Task-Lineage: 267c3d9a-6181-4ca5-b871-7009c0204372

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 16:33:21 -07:00
gsxdsm
f30d55fae7 FN-7593: move Before/After Transformation section to top of task definitions
Reorders task-definition prompt templates so the Before -> After Transformation section appears before other sections, making the expected change visible first.

- Move the Before -> After Transformation section ahead of other sections in agent-prompts.ts task-definition templates
- Update docs/task-management.md to reflect the new section order
- Add/extend tests in agent-prompts.test.ts and triage.test.ts covering the new ordering
- Add changeset fn-7593-before-after-top.md documenting the change

Files changed:
 .changeset/fn-7593-before-after-top.md            |  7 +++++++
 docs/task-management.md                           |  2 +-
 packages/core/src/__tests__/agent-prompts.test.ts | 20 ++++++++++++++++++++
 packages/core/src/agent-prompts.ts                | 20 +++++++++++++-------
 packages/engine/src/__tests__/triage.test.ts      | 17 +++++++++++++++++
 5 files changed, 58 insertions(+), 8 deletions(-)

Fusion-Task-Id: FN-7593

Fusion-Task-Lineage: d0d5eb4d-2fe0-456c-b061-5c078b78911b

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 13:44:50 -07:00
gsxdsm
cf3fe8b485 FN-7591: make dashboard create surfaces resolve intake column from workflow instead of hard-coding triage
Fixes dashboard task creation so new cards land in the selected/default workflow's intake column instead of always forcing legacy triage, letting workflows like Coding (Ideas) park new cards in 'ideas' until an operator promotes them.

- InlineCreateCard, QuickEntryBox, and NewTaskModal no longer hard-code column:"triage"; InlineCreateCard now forwards workflowId at create time instead of applying it post-create.
- Fixed a glue-layer regression in useTaskHandlers.ts (handleBoardQuickCreate/handleModalCreate) that re-forced column:"triage" even after UI surfaces stopped sending it.
- Added/updated tests covering the store's intake-column resolution and the dashboard create surfaces/hooks.
- Documented the new manual-intake-column parking behavior in dashboard-guide.md and workflow-steps.md.
- Added a patch changeset for @runfusion/fusion.

Files changed:
 .changeset/fn-7591-coding-ideas-intake.md          |  7 +++
 docs/dashboard-guide.md                            |  4 ++
 docs/workflow-steps.md                             |  1 +
 packages/core/src/__tests__/store-create-intake-column.test.ts   | 20 ++++++++
 packages/dashboard/app/App.tsx                     |  5 +-
 packages/dashboard/app/components/InlineCreateCard.tsx  | 28 ++++------
 packages/dashboard/app/components/NewTaskModal.tsx |  5 +-
 packages/dashboard/app/components/QuickEntryBox.tsx     |  5 +-
 packages/dashboard/app/components/TodoView.tsx     |  7 ++-
 packages/dashboard/app/components/__tests__/InlineCreateCard.test.tsx | 59 +++++++++++++++++++++-
 packages/dashboard/app/components/__tests__/QuickEntryBox.test.tsx    | 14 +++--
 packages/dashboard/app/components/__tests__/TodoView.test.tsx | 10 ++--
 packages/dashboard/app/components/__tests__/board-quickcreate-workflow-lane-visibility.test.tsx | 45 ++++++++++++++++-
 packages/dashboard/app/hooks/__tests__/useTaskHandlers.test.ts    | 27 ++++++++--
 packages/dashboard/app/hooks/useTaskHandlers.ts    |  8 ++-
 15 files changed, 207 insertions(+), 38 deletions(-)

Fusion-Task-Id: FN-7591

Fusion-Task-Lineage: 510f0e6a-89e7-468f-a6df-ad6aebd5c33a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 13:15:56 -07:00
gsxdsm
53fe0d71b9 FN-7584: register builtin:brainstorming workflow with ask-user/exit-gate loop
Adds a discoverable built-in Brainstorming workflow composing the ask-user + exit-gate reach-out loop ahead of the standard coding plan/execute/review/merge spine, plus a WorkflowNodeEditor fix so clearing the ask-user question textarea deletes the config key instead of persisting an empty string.

- Add packages/core/src/builtin-brainstorming-workflow-ir.ts registering builtin:brainstorming (non-default, default-enabled): ask-user -> refine prompt -> exit-gate-on-approval ahead of the unmodified Coding plan/execute/review/merge spine
- Wire the new builtin into packages/core/src/builtin-workflows.ts and extend the builtin-workflows parity test suite
- Add builtin-brainstorming-workflow-ir.test.ts covering the new workflow's IR shape and validation
- Fix WorkflowNodeEditor.tsx ask-user question textarea onChange to delete the config.question key when cleared to empty (validateAskUserAndExitGateNodes rejects present-but-empty question; only an absent key falls back to the engine default)
- Update docs/workflow-steps.md to document builtin:brainstorming as a selectable built-in composition
- Add .changeset/fn-7584-brainstorming-builtin.md (minor, feature)

Files changed:
 .changeset/fn-7584-brainstorming-builtin.md        |   7 ++
 docs/workflow-steps.md                             |   2 +-
 .../builtin-brainstorming-workflow-ir.test.ts      |  79 ++++++++++++++++
 .../core/src/__tests__/builtin-workflows.test.ts   |  66 +++++++++++++
 .../core/src/builtin-brainstorming-workflow-ir.ts  | 103 +++++++++++++++++++++
 packages/core/src/builtin-workflows.ts             |  46 +++++++++
 .../app/components/WorkflowNodeEditor.tsx          |  18 +++-
 7 files changed, 319 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7584

Fusion-Task-Lineage: 2c0258c2-9a35-403a-8688-ee49393a7231

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 11:31:48 -07:00
gsxdsm
42bbe58c03 FN-7579: add ask-user and exit-gate workflow nodes
Add workflow nodes for mid-flow user reach-out and early exit from a workflow run.

- Add `ask-user` IR node kind that reuses the await-input park/resume mechanism and surfaces the question in the task chat for brainstorming/clarification.
- Add `exit-gate` IR node kind that terminates the workflow early, with an optional condition.
- Wire both node kinds through the engine executor and workflow-node-handlers, including a new exit-gate-runner.
- Update the WorkflowNodeEditor palette, node summaries, and node help text for the two new node types.
- Extend workflow-flow-mapping to support the new node kinds.
- Keep `prompt`+`awaitInput` as a back-compat alias.
- Add core/engine/dashboard tests covering the new node kinds.
- Document the new nodes in docs/workflow-steps.md.
- Add changeset for the new minor feature.

Files changed:
 .changeset/fn-7579-ask-user-exit-gate-nodes.md     |   7 +
 docs/workflow-steps.md                             |  28 ++++
 packages/core/src/__tests__/workflow-ir.test.ts    | 120 ++++++++++++++
 packages/core/src/workflow-ir-types.ts             |  12 +-
 packages/core/src/workflow-ir.ts                   |  47 ++++++
 .../app/components/WorkflowNodeEditor.tsx          | 181 ++++++++++++++++++++-
 .../app/components/__tests__/node-summary.test.ts  |  43 +++++
 .../__tests__/workflow-flow-mapping.test.ts        |  49 ++++++
 .../app/components/nodes/WorkflowNodeTypes.tsx     |  14 +-
 .../dashboard/app/components/nodes/node-help.ts    |  24 +++
 .../dashboard/app/components/nodes/node-summary.ts |  28 ++++
 .../app/components/workflow-flow-mapping.ts        |   4 +
 .../workflow-graph-executor-handlers.test.ts       | 115 +++++++++++++
 .../src/__tests__/workflow-node-handlers.test.ts   |  66 ++++++++
 packages/engine/src/executor.ts                    |  23 ++-
 packages/engine/src/workflow-node-handlers.ts      |  18 +-
 .../src/workflow-node-runners/exit-gate-runner.ts  |  81 +++++++++
 17 files changed, 849 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-7579
Fusion-Task-Lineage: 9a89ff49-200d-4a6c-b97c-15d219349ee5
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 11:31:48 -07:00
gsxdsm
b173f76adb fix(FN-7577): stop planner overseer from "recovering" healthy in-progress tasks
decidePlannerRecovery fell through to inject_guidance for any non-failed
executor/workflow-gate signal, including the healthy `progressing` signal.
Under autonomous oversight this dispatched steering into the live agent of
every healthy task — flipping the card badge to "recovering", burning a
bounded-attempt slot, and consuming AI usage for no reason.

- Only problem signals (`stuck`/`blocked`, plus the existing `failed` path)
  now trigger autonomous steering; healthy (`progressing`/`complete`) and
  human-wait (`awaiting-human`) signals return `none`.
- PlannerRecoveryController.tick clears stale attempt/last-action records for
  a (taskId, stage) once its signal is healthy, so a recovered task drops
  from "recovering" back to "watching" and a later problem gets a fresh budget.
- PlannerOverseerMonitor dedupes the activity-feed heartbeat: an unchanged
  (stage, signal, reason) observation logs once per change, not every tick.

Invariant tests added across all signals for both fall-through stages.

Fusion-Task-Id: FN-7577

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 11:31:48 -07:00
gsxdsm
94e9d15e38 FN-7556: auto-select review-heavy workflow for AI-undo tasks
AI-undo tasks now default to a configurable, stricter review workflow instead of always inheriting the project default.

- Add project setting `aiUndoTaskWorkflowId` (default `builtin:review-heavy`) to ProjectSettings type and DEFAULT_PROJECT_SETTINGS
- `POST /api/tasks/:id/revert` resolves and validates the configured workflow id (via `isBuiltinWorkflowId`/`getWorkflowDefinition`), falling back to inherit-with-warning on a blank/unknown value
- `createAiUndoTask` engine helper gains an optional `workflowId` param, forwarded verbatim to `createTask` only when non-blank, staying pure (no settings/store access itself)
- Add regression tests for the route resolution logic and the engine helper's workflow forwarding
- Update docs (`settings-reference.md`, `task-management.md`) and add changeset

Files changed:
 .changeset/fn-7556-ai-undo-workflow.md             |  7 +++
 docs/settings-reference.md                         |  1 +
 docs/task-management.md                            |  1 +
 packages/core/src/settings-schema.ts               |  4 ++
 packages/core/src/types.ts                         | 14 +++++
 .../settings-default-descriptions.test.tsx         |  2 +
 .../src/__tests__/task-revert-route.test.ts        | 52 ++++++++++++++++-
 .../src/routes/register-task-workflow-routes.ts    | 31 +++++++++-
 .../src/__tests__/task-revert-ai-undo.test.ts      | 67 ++++++++++++++++++++++
 packages/engine/src/task-revert.ts                 | 16 ++++++
 10 files changed, 192 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-7556
Fusion-Task-Lineage: dec5603c-10a8-4780-a1b8-8a836a0de4c1
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 11:31:47 -07:00
gsxdsm
9592e3ac5c FN-7569: skip re-asking manual plan approval for unchanged re-specified plans
Manual plan approval now skips re-asking for approval when a re-specification produces an identical plan to one already approved.

- Add nullable Task.approvedPlanFingerprint field with DB migration 139 to track the approved PROMPT.md fingerprint
- Skip re-parking at awaiting-approval when replan/plan-review-retry/self-healing rebound yields the same plan fingerprint as before
- Require fresh approval when the plan content changes or when a plan is rejected
- Leave Release Authorization, Workflow Plan Review, and auto-approve-all behavior unchanged
- Add/extend tests across core (db, plan-approval, store-persistence), engine (triage), and dashboard (routes-github) to cover fingerprint comparison and idempotent re-approval
- Update docs (settings-reference.md, workflow-steps.md) to describe the idempotent approval behavior
- Add changeset for @runfusion/fusion (patch)

Files changed:
 .changeset/fn-7569-plan-approval-idempotent.md     |   7 +
 docs/settings-reference.md                         |   2 +-
 docs/workflow-steps.md                             |   2 +
 packages/core/src/__tests__/db.test.ts             |  54 +++++++
 packages/core/src/__tests__/plan-approval.test.ts  |  31 +++-
 .../core/src/__tests__/store-persistence.test.ts   |  39 +++++
 packages/core/src/db.ts                            |  22 ++-
 packages/core/src/index.ts                         |   2 +-
 packages/core/src/plan-approval.ts                 |  23 +++
 packages/core/src/store.ts                         |  20 ++-
 packages/core/src/types.ts                         |  13 ++
 .../dashboard/src/__tests__/routes-github.test.ts  |  69 +++++++-
 .../src/routes/register-task-workflow-routes.ts    |  37 ++++-
 packages/engine/src/__tests__/triage.test.ts       | 178 ++++++++++++++++++++-
 packages/engine/src/triage.ts                      |  58 +++++--
 15 files changed, 527 insertions(+), 30 deletions(-)

Fusion-Task-Id: FN-7569

Fusion-Task-Lineage: 7d3855ae-6f45-4571-90db-cf1ae3b541dd

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 11:31:46 -07:00
gsxdsm
c08498efc6 FN-7563: explain the planner-overseer awaiting-confirmation badge
Replace the raw kebab-case planner-overseer badge state and bare tooltip with a human-readable label and an explanatory tooltip built from the existing runtime snapshot.

- Add packages/dashboard/app/components/plannerOverseerBadge.ts: pure, type-only helper exposing plannerOverseerStateLabel() and plannerOverseerBadgeTooltip(), composing the tooltip from reason/watchedStage/signal/pendingConfirmation with graceful fallbacks
- Re-export PlannerOverseerState and PlannerOverseerRuntimeSnapshot as type-only from packages/core/src/types.ts so the dashboard's @fusion/core vite alias can resolve them
- Update TaskCard.tsx to render the new label/tooltip instead of the raw state string
- Add unit tests for the new badge helper and extend TaskCard tests for the updated label/tooltip behavior
- Add a patch changeset documenting the operator-facing fix

Files changed:
 .changeset/fn-7563-overseer-badge-explanation.md   |   7 ++
 packages/core/src/types.ts                         |   7 ++
 packages/dashboard/app/components/TaskCard.tsx     |   7 +-
 .../app/components/__tests__/TaskCard.test.tsx     |  72 ++++++++++++++
 .../__tests__/plannerOverseerBadge.test.ts         | 103 ++++++++++++++++++++
 .../app/components/plannerOverseerBadge.ts         | 104 +++++++++++++++++++++
 6 files changed, 296 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-7563

Fusion-Task-Lineage: 64ed011b-5486-4272-abd1-a6123c60785f

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 11:31:44 -07:00
gsxdsm
6e4c207a7f FN-7559: disambiguate release-authorization holds from manual plan-approval holds
Disambiguate release-authorization approval holds from manual plan-approval holds so auto-approve no longer appears broken.

- Add `Task.awaitingApprovalReason` (`"release-authorization" | null`) to distinguish the release-authorization gate from the independent manual plan-approval gate, both of which set `status: "awaiting-approval"`.
- Stamp `awaitingApprovalReason: "release-authorization"` when the release gate blocks a task, and explicitly clear it (`null`) when the manual plan-approval gate parks the task, so a stale reason never survives a replan.
- Add DB migration/persistence support for the new column in `db.ts`/`store.ts`/`types.ts`.
- TaskCard/TaskDetailModal now render a distinct status for release-authorization holds and suppress the generic manual Approve/Reject affordance for them.
- Add i18n string and docs updates (`settings-reference.md`, `workflow-steps.md`) plus a changeset.
- Extend regression tests in db, triage, TaskCard, and TaskDetailModal to cover the new reason field and disambiguated UI.

Files changed:
$(git diff --cached --stat)

Fusion-Task-Id: FN-7559
Fusion-Task-Lineage: 0b37cbf0-40a4-4165-8088-482ed365ba19
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 11:31:44 -07:00
gsxdsm
c4d81fe5cc FN-7524: add AI-undo fallback task for reverting done/archived tasks
Adds an AI-undo fallback to the revert route: when a git-based revert conflicts or is unsupported, an ordinary board task is created to perform the undo via AI instead of a forced/failed git write.

- POST /tasks/:id/revert now accepts an optional `{ mode?: "git" | "ai" | "auto" }` body (default "auto"); unknown values reject with 400.
- "git" preserves the FN-7523 git-only contract unchanged; "ai" always creates the AI-undo task; "auto" tries git first and falls back to AI only on a conflicting or unsupported (e.g. workspace) result — needsHuman (autoMerge:false) never triggers the fallback.
- New engine helpers in task-revert.ts: `createAiUndoTask`, `buildAiUndoTaskDescription`, `REVERT_OF_METADATA_KEY`, plus `AiUndoTaskResult`/`CreateAiUndoTaskDeps` types, exported from packages/engine/src/index.ts.
- The AI-undo task is created via the normal triage-column `store.createTask` path with no dependency on the source task, referencing the source task's mission, id, and landed files, and instructing an undo commit using the `revert(FN-xxxx): ...` convention.
- New core `TaskStore.findOpenRevertTaskForSource` backs an idempotency guard: a repeated call while an AI-undo task is still open returns the same `createdTaskId` with `alreadyOpen: true` instead of creating a duplicate.
- Updated docs/task-management.md's revert section to document the git path + AI-undo fallback contract.
- Added a minor changeset for the @runfusion/fusion release notes.
- Added/extended tests: packages/engine/src/__tests__/task-revert-ai-undo.test.ts (new) and packages/dashboard/src/__tests__/task-revert-route.test.ts (extended) covering mode validation, auto-fallback-on-conflict, forced "ai" mode, and the duplicate-open-task guard.

Files changed:
 .changeset/fn-7524-ai-undo-revert.md               |   7 +
 docs/task-management.md                            |  13 +-
 packages/core/src/store.ts                         |  31 +++++
 packages/dashboard/src/__tests__/task-revert-route.test.ts | 143 ++++++++++++++++++++-
 packages/dashboard/src/routes/register-task-workflow-routes.ts |  75 +++++++++--
 packages/engine/src/__tests__/task-revert-ai-undo.test.ts |  114 ++++++++++++++++
 packages/engine/src/index.ts                       |   5 +
 packages/engine/src/task-revert.ts                 | 117 ++++++++++++++++-
 8 files changed, 487 insertions(+), 18 deletions(-)

Fusion-Task-Id: FN-7524

Fusion-Task-Lineage: 64dfedcf-c286-4c46-8cf8-51ec5e668bf7

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-05 11:31:43 -07:00
gsxdsm
3dd227b945 FN-7557: default plan approval mode to auto-approve-all
Changes the project-wide plan approval default from deferring to per-workflow settings to auto-approving all task plans, so new/unset projects skip the manual awaiting-approval gate by default.

- Change DEFAULT_PROJECT_SETTINGS.planApprovalMode default from "workflow" to "auto-approve-all" in settings-schema.ts, with FNXC comments documenting the requirement change
- Update ProjectSettings.planApprovalMode JSDoc in types.ts to reflect the new default
- Update useAppSettings hook's initial state and hydration fallback to default to "auto-approve-all" while still honoring an explicit stored "workflow" value
- Update MergeSection UI: move the "(default)" label from the "Use workflow setting" option to "Auto-approve all tasks", keeping the select's fallback value in sync
- Update settings-reference.md docs and i18n locale/resource strings to match the new default label
- Update existing tests (MergeSection legacy auto-merge cleanup, settings default descriptions, useAppSettings) to assert the new default, and add coverage for the updated hydration/fallback behavior
- Add changeset fn-7557-plan-auto-approve-default.md documenting the behavior change

Files changed:
 .changeset/fn-7557-plan-auto-approve-default.md    |  7 +++++
 docs/settings-reference.md                         |  2 +-
 packages/core/src/settings-schema.ts               |  6 +++-
 packages/core/src/types.ts                         |  3 ++
 .../dashboard/app/components/SettingsModal.tsx     |  3 +-
 .../components/settings/sections/MergeSection.tsx  |  9 ++++--
 .../MergeSection.legacy-automerge-cleanup.test.tsx |  4 +--
 .../settings-default-descriptions.test.tsx         |  3 +-
 .../app/hooks/__tests__/useAppSettings.test.ts     | 35 +++++++++++++++++++---
 packages/dashboard/app/hooks/useAppSettings.ts     | 12 ++++++--
 packages/i18n/locales/en/app.json                  |  4 +--
 packages/i18n/src/resources.d.ts                   |  2 +-
 12 files changed, 71 insertions(+), 19 deletions(-)

Fusion-Task-Id: FN-7557

Fusion-Task-Lineage: 7dcfe339-6088-4ebc-8387-eb81258a693d

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-04 21:28:19 -07:00
gsxdsm
883c73e2f1 FN-7544: emit artifact:registered for cross-instance artifact writes
Fix agent-created artifacts not showing live in the dashboard because a second TaskStore instance (e.g. engine writing while dashboard polls) never detected or re-emitted artifact:registered for rows it did not insert itself.

- Track a per-instance lastArtifactRowId cursor seeded from the max artifacts rowid at watch() startup
- In checkForChanges(), pick up artifact rows with rowid > cursor written by other instances and re-emit artifact:registered, advancing the cursor
- Advance the cursor on local inserts (insertArtifactRow) so this instance never double-emits its own writes
- Call db.bumpLastModified() in registerArtifact() so other instances' pollers actually look at the artifacts table
- Add regression tests covering cross-instance artifact registration in core store and dashboard artifacts route integration
- Add changeset and doc note for the cross-instance live-refresh fix

Files changed:
 .changeset/fn-7544-artifact-cross-instance-live-refresh.md         |   7 ++
 docs/storage.md                                                    |   1 +
 packages/core/src/__tests__/artifacts.test.ts                      |  85 +++++++++++++++
 packages/core/src/store.ts                                         |  63 ++++++++++-
 packages/dashboard/src/routes/__tests__/artifacts-route-integration.test.ts | 120 ++++++++++++++++++++-
 5 files changed, 274 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7544

Fusion-Task-Lineage: 76570505-082e-4f9a-8b06-29591c06c435

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-04 21:28:19 -07:00
gsxdsm
f992e6aefa FN-7553: add dedicated keyboard shortcuts settings section
Adds a standalone Keyboard Shortcuts settings section with an easier-to-use capture input and support for more shortcut actions.
- Introduce a new KeyboardShortcutsSection with a dedicated ShortcutCaptureInput component for recording key combos
- Split keyboard-shortcut settings out of the general settings section into their own settings tab
- Extend the shortcut schema/types and useDashboardKeyboardShortcuts hook to support additional actions
- Update settings save-split, section-keys, and defaults/parity tests to cover the new section
- Update dashboard docs and add a changeset for the new settings section

Files changed:
 .changeset/fn-7553-keyboard-shortcuts-section.md   |   7 +
 docs/dashboard-guide.md                            |  22 ++-
 packages/core/src/__tests__/global-settings.test.ts     |   9 +-
 packages/core/src/__tests__/settings-defaults.test.ts   |   4 +
 packages/core/src/__tests__/settings-parity.test.ts     |   2 +-
 packages/core/src/settings-schema.ts               |   6 +-
 packages/core/src/types.ts                         |  12 ++
 packages/dashboard/app/App.tsx                     |  26 +++-
 packages/dashboard/app/__tests__/App.keyboard-shortcuts.test.tsx  |  47 ++++++-
 packages/dashboard/app/components/SettingsModal.css     |  56 ++++++--
 packages/dashboard/app/components/SettingsModal.tsx     |  30 +++-
 packages/dashboard/app/components/__tests__/SettingsModal.general.test.tsx |  63 ---------
 packages/dashboard/app/components/__tests__/SettingsModal.keyboardShortcuts.test.tsx |  156 +++++++++++++++++++++
 packages/dashboard/app/components/settings/__tests__/section-keys.test.ts |   1 +
 packages/dashboard/app/components/settings/save-split.ts |   6 +-
 packages/dashboard/app/components/settings/sections/GlobalGeneralSection.tsx |  38 -----
 packages/dashboard/app/components/settings/sections/KeyboardShortcutsSection.tsx |  78 +++++++++++
 packages/dashboard/app/components/settings/sections/ShortcutCaptureInput.tsx |  118 ++++++++++++++++
 packages/dashboard/app/components/settings/sections/__tests__/KeyboardShortcutsSection.test.tsx |  113 +++++++++++++++
 packages/dashboard/app/hooks/__tests__/useDashboardKeyboardShortcuts.test.tsx |  73 +++++++++-
 packages/dashboard/app/hooks/useDashboardKeyboardShortcuts.ts |  38 ++++-
 packages/dashboard/app/utils/__tests__/keyboardShortcuts.test.ts |  37 ++++-
 packages/dashboard/app/utils/keyboardShortcuts.ts  |  54 ++++++-
 23 files changed, 854 insertions(+), 142 deletions(-)

Fusion-Task-Id: FN-7553

Fusion-Task-Lineage: 51c1ad69-fbd3-45ce-8d2d-45d9962d7b76

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-04 21:28:19 -07:00
gsxdsm
654375723f FN-7521: add test coverage for planner oversight levels, overrides, and UI controls
Adds targeted regression tests covering plannerOversightLevel resolution/precedence, per-task overrides, TaskCard/TaskDetailModal oversight UI (including desktop+mobile breakpoints), lifecycle-stage monitoring, bounded recovery, confirmation gates, and human-control safeguards in the planner overseer.

- store-update.test.ts: covers remaining plannerOversightLevel enum values and per-task override precedence
- workflow-settings-resolver.test.ts: covers additional plannerOversightLevel resolution cases
- TaskCard.oversight.test.tsx: adds desktop+mobile (@media max-width: 768px) breakpoint coverage for the oversight badge, and reconciles a new mobile-breakpoint case with the FN-7542 active-overseer-state indicator removal already on main
- TaskDetailModal.oversight-controls.test.tsx: adds desktop+mobile breakpoint coverage for oversight UI controls
- planner-recovery-controller-human-control.test.ts: adds hard-cancel inertness test and verifies existing engine coverage for confirmation gates and human-control safeguards

Files changed:
 packages/core/src/__tests__/store-update.test.ts   | 25 ++++++
 .../__tests__/workflow-settings-resolver.test.ts   | 14 ++++
 .../__tests__/TaskCard.oversight.test.tsx          | 67 +++++++++++++++
 .../TaskDetailModal.oversight-controls.test.tsx    | 96 ++++++++++++++++++++++
 ...anner-recovery-controller-human-control.test.ts | 27 ++++++
 5 files changed, 229 insertions(+)

Fusion-Task-Id: FN-7521

Fusion-Task-Lineage: 87d7755b-e242-4f68-8783-835531c8d105

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-04 21:28:18 -07:00
gsxdsm
bf688394a2 FN-7520: add run-audit emission facade for planner-overseer decision points
Adds a canonical emission layer over recordPlannerIntervention so overseer decision points (observation, steering, recovery attempt, retry, confirmation, escalation) emit consistent overseer:intervention run-audit events without inlining action/outcome logic at each call-site.

- Add packages/core/src/planner-overseer-events.ts with emitOverseerObservation, emitOverseerSteering, emitOverseerRecoveryAttempt, emitOverseerRetry, emitOverseerConfirmation, and emitOverseerEscalation, each fixing its category's intervention action/default outcome and delegating to recordPlannerIntervention.
- Export the new emitters and OverseerEventInput type from packages/core/src/index.ts.
- Add unit tests covering each emitter's action/outcome mapping and metadata pass-through.
- Add a minor changeset documenting the new run-audit emission facade for planner-overseer events.
- Update docs/architecture.md's Run Audit API section to describe the FN-7520 emission facade and its relationship to FN-7519's overseer:intervention mutation type.

Files changed:
 .changeset/fn-7520-planner-overseer-events.md      |   7 +
 docs/architecture.md                               |   2 +-
 packages/core/src/__tests__/planner-overseer-events.test.ts | 236 +++++++++++++++++++++
 packages/core/src/index.ts                         |   9 +
 packages/core/src/planner-overseer-events.ts       | 128 +++++++++++
 5 files changed, 381 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7520

Fusion-Task-Lineage: 85e0d761-e4f3-437e-abe2-031e6cf89c1c

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-04 21:28:17 -07:00
gsxdsm
d10ea9aef1 FN-7519: add planner-overseer intervention timeline model and UI
Introduces a persisted planner-overseer intervention timeline surfaced in the task-detail Planner Oversight cluster, recording stage, reason, action taken, outcome, attempt count/limit, and source links for each intervention.

- Add core `PlannerInterventionEntry` type plus `recordPlannerIntervention`/`getPlannerInterventionTimeline` helpers that persist entries via the run-audit store under the `overseer:intervention` mutation
- Add `PlannerInterventionTimeline` dashboard component rendering the timeline (stage/reason/action/outcome/attempts/links) with associated styles
- Wire the new API route/legacy handler and TaskDetailModal integration to expose and render the timeline
- Add unit tests for the core helpers and the new UI component
- Add changeset for the new minor feature and update architecture/dashboard-guide docs

Files changed:
$(cat /tmp/diffstat_7519.txt)

Fusion-Task-Id: FN-7519

Fusion-Task-Lineage: 3c4fcda3-9eb2-46d3-b142-b0c7d6334cd0

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-04 21:28:17 -07:00
gsxdsm
aae603b871 FN-7518: add configurable planner-overseer notification verbosity setting
Adds a workflow-native plannerOversightNotificationLevel enum setting so operators can control how noisy planner-overseer notifications are.

- Declare BUILTIN_OVERSIGHT_SETTINGS entry `plannerOversightNotificationLevel` (silent/errors/important/all, default important)
- Document the new setting alongside plannerOversightLevel in docs/settings-reference.md
- Add regression coverage in builtin-workflow-settings-triage.test.ts and workflow-settings-resolver.test.ts
- Add changeset (minor) describing the new operator-facing verbosity control

Files changed:
 .changeset/fn-7518-oversight-notification-verbosity.md            |  7 +++++
 docs/settings-reference.md                                       |  3 +-
 packages/core/src/__tests__/builtin-workflow-settings-triage.test.ts | 36 +++++++++++++++++++++-
 packages/core/src/__tests__/workflow-settings-resolver.test.ts    |  1 +
 packages/core/src/builtin-workflow-settings.ts                    | 17 ++++++++++
 5 files changed, 62 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7518

Fusion-Task-Lineage: fe6e2bde-0e58-4f29-b5cc-efdf81efcfa5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-04 21:28:16 -07:00
gsxdsm
6498d028f2 FN-7517: add task detail oversight quick-controls (level change, manual nudge, stop, explain-current-action)
Adds task detail modal controls that let an operator quickly change a task's
oversight level, nudge the planner with a manual instruction, stop oversight
entirely, and request an explanation of the overseer's current action,
backed by new dashboard API routes and engine/core plumbing.

- Add oversight quick-controls UI (level change, manual nudge, stop
  oversight, explain-current-action) to TaskDetailModal with supporting
  styles in TaskDetailModal.css and TaskCard.css
- Add dashboard legacy API + task-workflow routes to handle the new
  oversight actions (register-task-workflow-routes.ts, api/legacy.ts)
- Extend planner-overseer-state and planner-overseer-runtime-snapshot to
  track/report manual nudge and stop-oversight state
- Extend PlannerRecoveryController and project-engine to apply manual
  oversight actions (level change, nudge, stop, explain) end-to-end
- Add tests: TaskDetailModal.oversight-controls.test.tsx,
  tasks-overseer-controls.test.ts,
  planner-recovery-controller-manual-action.test.ts, plus updates to
  planner-overseer-runtime-snapshot.test.ts and test-helpers
- Update docs/dashboard-guide.md and docs/settings-reference.md

Files changed:
 docs/dashboard-guide.md                            |   2 +
 docs/settings-reference.md                         |   2 +-
 packages/core/src/planner-overseer-state.ts        |  18 +
 packages/dashboard/app/api/legacy.ts               |  33 ++
 packages/dashboard/app/components/TaskCard.css     |  13 +
 packages/dashboard/app/components/TaskDetailModal.css   | 122 +++++++
 packages/dashboard/app/components/TaskDetailModal.tsx   | 374 ++++++++++++++++++++-
 packages/dashboard/app/components/__tests__/TaskDetailModal.oversight-controls.test.tsx | 290 ++++++++++++++++
 packages/dashboard/app/components/__tests__/TaskDetailModal.test-helpers.ts      |  11 +
 packages/dashboard/src/routes/__tests__/tasks-overseer-controls.test.ts      | 191 +++++++++++
 packages/dashboard/src/routes/register-task-workflow-routes.ts    |  68 ++++
 packages/engine/src/__tests__/planner-overseer-runtime-snapshot.test.ts      |  24 +-
 packages/engine/src/__tests__/planner-recovery-controller-manual-action.test.ts |  84 +++++
 packages/engine/src/planner-overseer-runtime-snapshot.ts       |  11 +
 packages/engine/src/planner-recovery-controller.ts |  40 +++
 packages/engine/src/project-engine.ts              | 102 ++++++
 16 files changed, 1380 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-7517

Fusion-Task-Lineage: eded7ff5-d126-429d-acbb-9f4bfff5ae2a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-04 21:28:16 -07:00
gsxdsm
df0be88482 FN-7534: fix branch-group completion for archived unlanded members
Branch-group completion no longer silently drops archived-but-unlanded members, which previously let genuinely-incomplete groups be flagged complete and promoted.

- listTasksByBranchGroup now scans with includeArchived:true so archived members stay counted in the group's total instead of dropping out silently
- ArchivedTaskEntry gains a persisted mergeDetails snapshot so an archived member that had already landed is still distinguished from one that never landed
- store.ts archival paths (task->archive projection) now carry mergeDetails through so isBranchGroupMemberLanded keeps working post-archival
- Added regression coverage in branch-group-store.test.ts and group-merge-coordinator.test.ts for archived-landed and archived-unlanded gating
- Added changeset documenting the fix as a patch-level bug fix

Files changed:
 .changeset/fn-7534-branch-group-archived-member.md              |   7 +
 docs/dashboard-guide.md                                         |   2 +
 packages/core/src/__tests__/branch-group-store.test.ts          |  77 +++++++++++
 packages/core/src/store.ts                                      |  30 ++++-
 packages/core/src/types.ts                                      |  11 ++
 packages/engine/src/__tests__/group-merge-coordinator.test.ts   | 148 ++++++++++++++++++++-
 6 files changed, 273 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7534
Fusion-Task-Lineage: 510af857-ce08-49a0-a2a1-41b3ad473804
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-04 21:28:16 -07:00
gsxdsm
726cbf89cc FN-7531: expose planner overseer state to task cards
Expose transient planner overseer runtime snapshots to board task payloads and cards.

- Add core planner overseer state types and deterministic state derivation.
- Assemble read-only engine runtime snapshots from overseer observations and recovery registries.
- Enrich GET /api/tasks with best-effort planner overseer state and render non-idle TaskCard badges.
- Cover state derivation, API enrichment, runtime snapshot assembly, and card rendering with tests.

Files changed:
 .../fn-7531-planner-overseer-state-exposure.md     |   7 ++
 docs/architecture.md                               |  36 +++++++
 .../src/__tests__/planner-overseer-state.test.ts   |  85 +++++++++++++++
 packages/core/src/index.ts                         |   7 ++
 packages/core/src/planner-overseer-state.ts        |  78 ++++++++++++++
 packages/core/src/types.ts                         |  12 +++
 packages/dashboard/app/components/TaskCard.tsx     |  27 ++++-
 .../app/components/__tests__/TaskCard.test.tsx     |  29 ++++++
 .../__tests__/tasks-planner-overseer-state.test.ts | 114 +++++++++++++++++++++
 .../src/routes/register-task-workflow-routes.ts    |  23 ++++-
 .../planner-overseer-runtime-snapshot.test.ts      | 104 +++++++++++++++++++
 packages/engine/src/index.ts                       |   8 ++
 .../src/planner-overseer-runtime-snapshot.ts       |  67 ++++++++++++
 packages/engine/src/project-engine.ts              |  17 +++
 14 files changed, 612 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7531

Fusion-Task-Lineage: b7659ed2-bf33-4312-a5ab-818ad37049b9

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-04 21:28:15 -07:00
gsxdsm
5ad8ec8cb6 FN-7528: capture post-task agent performance reflections
Capture deterministic post-task reflection metrics for completed agent tasks.

- Add non-LLM task performance capture with duration, touched files/packages, verification scope, and retry/rework metrics.
- Wire executor completion paths to fire best-effort reflection capture once per completed task when reflections are enabled.
- Extend reflection/run-audit types, docs, changeset, and regression coverage for capture behavior.

Files changed:
 .changeset/fn-7528-task-performance-capture.md     |   7 +
 AGENTS.md                                          |   1 +
 docs/diagnostics.md                                |  12 +-
 .../core/src/__tests__/reflection-store.test.ts    |  96 +++++++++
 packages/core/src/types.ts                         |  28 ++-
 .../engine/src/__tests__/agent-reflection.test.ts  | 202 +++++++++++++++++++
 .../executor-post-task-reflection-capture.test.ts  | 135 +++++++++++++
 packages/engine/src/agent-reflection.ts            | 215 ++++++++++++++++++++-
 packages/engine/src/executor.ts                    |  63 +++++-
 packages/engine/src/run-audit.ts                   |  29 +++
 10 files changed, 776 insertions(+), 12 deletions(-)

Fusion-Task-Id: FN-7528

Fusion-Task-Lineage: 153090e1-681b-4445-83e8-097bc70dcdb4

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-04 21:28:15 -07:00