Commit Graph

13418 Commits

Author SHA1 Message Date
gsxdsm
6ae9299576 FN-8953: defer terminal wedge alerts during recovery
Hold terminal wedge alerts until their recovery window has elapsed.

- Persist and settle pending wedge notifications across restarts.
- Clear pending alerts on task progress and reconcile expired holds during self-healing.
- Expose the settle window in notification settings with coverage for store and notification flows.

Files changed:
 .changeset/fn-8953-wedge-settle-window.md          |   7 +
 AGENTS.md                                          |   1 +
 docs/architecture.md                               |   3 +-
 docs/settings-reference.md                         |   1 +
 .../core/src/__tests__/store-wedge-pending.test.ts |  56 +++++
 packages/core/src/config/settings-schema.ts        |   1 +
 packages/core/src/store.ts                         |  46 ++++
 packages/core/src/types/settings/settings-scope.ts |   2 +
 packages/core/src/types/task/task-core.ts          |  15 ++
 .../app/components/settings/save-split.ts          |   1 +
 .../sections/NotificationsSection.search.ts        |   9 +
 .../settings/sections/NotificationsSection.tsx     |  15 ++
 .../settings-default-descriptions.test.tsx         |   1 +
 ...self-healing-pending-wedge-notification.test.ts | 148 ++++++++++++
 .../__tests__/notification-service.test.ts         |   7 +-
 .../__tests__/task-wedge-notification.test.ts      | 258 ++++++++++++++++++++-
 .../src/notification/notification-service.ts       | 260 +++++++++++++++++++++
 packages/engine/src/self-healing.ts                |  38 +++
 packages/i18n/locales/en/app.json                  |   2 +
 19 files changed, 850 insertions(+), 21 deletions(-)

Fusion-Task-Id: FN-8953

Fusion-Task-Lineage: fd5b5827-c69d-409f-86d5-01ff23405ee3

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-11 12:34:47 -07:00
gsxdsm
dfd88e7540 fix: resume capacity-parked workflow continuations
The planning-continuation drain skipped every due `kind: "task"` row whose
`waitReason` was not "planning", on the premise that such rows "belong to a
different drain". No such drain exists: `listDueWorkflowWorkItems` has exactly
two callers, this pass and the self-healing reclaim sweep, and the sweep
deliberately leaves `runnable`/`retrying` rows alone as "the dispatcher's own
queue". A capacity-parked continuation was therefore owned by nobody — skipped
here every poll with no state change and no audit row, and passed over there by
design.

Observed on the Fusion board: eight cards sat runnable for up to 8h with the
engine unpaused, 0 tasks in progress, and 4 of 10 worktrees used. Three carried
`waitReason: "capacity"` from the capacity-suspend path; five carried NULL. The
09:04 reclaim sweep had just moved them held -> runnable, handing them to this
drain and simultaneously putting them out of its own reach, so the auto-resume
fix tightened the strand it repaired.

Dispatch stays admission-gated by `admitPlanningContinuation`, so a
capacity-parked card resumes only when a slot is genuinely free.

Also repairs two stale path allowlists in planning-claim-single-writer.ts: the
mission stores and replan-target.ts moved into subdirectories, leaving that
ratchet red on main and accusing the two modules it exists to exclude.

Verified: the patched classifier returns `actionable` for all 8 live stranded
rows; gate + lint green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 10:36:26 -07:00
gsxdsm
eef68fe0b9 FN-8933: capture semantic memory from completed work
Add inferred graph relationships and detached recall capture across completed-work memory surfaces.

- Validate and persist deterministic inferred semantic edges with audit outcomes.
- Capture completed tasks, research findings, and insights as bounded recall entries.
- Wire memory semantics through engine, research APIs, and coverage tests.

Files changed:
 .changeset/fn-8933-memory-semantics-capture.md     |   7 +
 AGENTS.md                                          |   1 +
 docs/knowledge-graph.md                            |  10 +-
 .../src/__tests__/memory/recall-capture.test.ts    | 111 +++++++++++++
 .../__tests__/postgres/insight-store.pg.test.ts    |  25 +++
 .../postgres/research-execution.pg.test.ts         |  38 +++++
 .../__tests__/research-feature-promotion.test.ts   |  39 +++++
 .../core/src/async-stores/async-insight-store.ts   |  23 ++-
 packages/core/src/index.ts                         |   1 +
 .../__tests__/graph-builder-incremental.test.ts    |  28 ++++
 .../__tests__/inferred-edge-writer.test.ts         |  74 +++++++++
 packages/core/src/knowledge-graph/graph-builder.ts |  27 ++-
 .../src/knowledge-graph/graph-serialization.ts     |   2 +-
 packages/core/src/knowledge-graph/graph-store.ts   |  12 ++
 packages/core/src/knowledge-graph/graph-types.ts   |   2 +-
 packages/core/src/knowledge-graph/index.ts         |   1 +
 .../src/knowledge-graph/inferred-edge-writer.ts    |  96 +++++++++++
 packages/core/src/memory/index.ts                  |   1 +
 packages/core/src/memory/recall-capture.ts         | 184 +++++++++++++++++++++
 .../src/research/research-feature-promotion.ts     |  23 ++-
 packages/core/src/task-store/task-store-helpers.ts |  13 +-
 .../src/__tests__/research-routes.test.ts          |  80 ++++++++-
 packages/dashboard/src/research-routes.ts          |  27 ++-
 .../src/__tests__/agent-mission-tools.test.ts      |  60 ++++++-
 .../src/__tests__/in-process-runtime.pg.test.ts    |  28 +++-
 .../memory-consolidation-heartbeat-hook.test.ts    |   8 +-
 .../__tests__/memory-consolidation-ports.test.ts   |  17 +-
 .../src/__tests__/memory-semantics-pass.test.ts    | 115 +++++++++++++
 .../engine/src/__tests__/project-engine.test.ts    |  65 +++++++-
 packages/engine/src/agent-heartbeat.ts             |  14 +-
 packages/engine/src/agent-tools.ts                 |  12 +-
 packages/engine/src/agents/agent-reflection.ts     |   9 +-
 packages/engine/src/memory/index.ts                |   1 +
 .../src/memory/memory-consolidation-adapters.ts    |  18 +-
 packages/engine/src/memory/memory-consolidation.ts |  13 +-
 packages/engine/src/memory/memory-semantics.ts     |  67 ++++++++
 packages/engine/src/project-engine.ts              |   3 +
 .../engine/src/research/research-orchestrator.ts   |  20 ++-
 packages/engine/src/runtimes/in-process-runtime.ts |  12 ++
 packages/engine/src/util/run-audit.ts              |  11 ++
 40 files changed, 1250 insertions(+), 48 deletions(-)

Fusion-Task-Id: FN-8933

Fusion-Task-Lineage: b75a6b23-906f-4255-92f1-7684beb742b8

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-11 05:45:36 -07:00
gsxdsm
f1fe399184 FN-8991: add runtime skill-loader drift gate
Enforce the intentional Claude-to-Grok runtime skill-loader clone relationship across verification lanes.

- Add an exact rename-diff validator with fixture and live-loader coverage.
- Run the validator in pretest, fast verification, and static merge-gate checks.
- Document the loader duplication contract and expanded static-validator inventory.

Files changed:
 AGENTS.md                                          |   2 +
 docs/testing.md                                    |   4 +-
 package.json                                       |   7 +-
 .../check-runtime-skill-loader-drift.test.mjs      | 113 +++++++++++++++++++++
 scripts/__tests__/run-static-gate-checks.test.mjs  |   1 +
 scripts/__tests__/verify-fast.test.mjs             |   1 +
 scripts/check-runtime-skill-loader-drift.mjs       | 113 +++++++++++++++++++++
 7 files changed, 236 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-8991

Fusion-Task-Lineage: a3b67752-0043-4336-9a2a-ff391672b31f

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-11 05:23:02 -07:00
gsxdsm
5a1853cac6 FN-8934: add memory pre-steering across agent prompts
Add bounded memory-first guidance and consolidation observability across agent workflows.

- Apply mode-aware memory pre-steering to execution, triage, reviewer, heartbeat, and merger prompts.
- Export and test shared memory nudges while documenting memory inclusion settings.
- Expose agent memory consolidation history through dashboard API and detail UI.

Files changed:
 .changeset/fn-8934-memory-pre-steering.md          |  7 ++
 docs/agents.md                                     |  4 +
 docs/settings-reference.md                         |  2 +
 .../core/src/__tests__/memory-pre-steering.test.ts | 28 +++++++
 packages/core/src/__tests__/project-memory.test.ts | 22 ++++++
 packages/core/src/index.gate.ts                    |  7 ++
 packages/core/src/index.ts                         |  7 ++
 packages/core/src/memory/index.ts                  |  1 +
 packages/core/src/memory/memory-pre-steering.ts    | 41 ++++++++++
 packages/core/src/memory/project-memory.ts         | 19 +++++
 packages/dashboard/app/api/agents/agents.ts        | 12 +++
 packages/dashboard/app/api/legacy.ts               |  2 +
 .../dashboard/app/components/AgentDetailView.css   | 41 ++++++++++
 .../dashboard/app/components/AgentDetailView.tsx   | 56 +++++++++++++-
 ...etailView.memory-consolidation-history.test.tsx | 58 +++++++++++++++
 .../__tests__/AgentDetailView.test-helpers.ts      |  3 +
 .../register-agent-memory-consolidations.test.ts   | 87 ++++++++++++++++++++++
 .../register-agent-reflection-rating-routes.ts     | 36 +++++++++
 .../memory-pre-steering-injection.test.ts          | 50 +++++++++++++
 packages/engine/src/__tests__/reviewer.test.ts     | 18 +++++
 packages/engine/src/__tests__/triage.test.ts       | 18 ++++-
 packages/engine/src/agent-heartbeat.ts             | 14 +++-
 .../engine/src/agents/agent-heartbeat-prompts.ts   |  2 +
 packages/engine/src/agents/agent-instructions.ts   | 16 ++--
 packages/engine/src/execution/reviewer.ts          | 31 +++++---
 packages/engine/src/executor/execution-prompt.ts   |  6 +-
 packages/engine/src/merger.ts                      |  9 ++-
 packages/engine/src/triage.ts                      | 12 ++-
 28 files changed, 577 insertions(+), 32 deletions(-)

Fusion-Task-Id: FN-8934

Fusion-Task-Lineage: a062cc6b-1277-4d36-9926-b3ecba4945eb

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-11 04:57:14 -07:00
gsxdsm
25e292d0e6 FN-8954: preserve CLI liveness during startup
Ensure CLI startup operations settle before process exit on supported Node runtimes.

- Keep awaited QMD probes and ephemeral port selection ref'd until completion.
- Add CLI process regressions for init persistence and exit code 13.
- Declare the Node 22.4 runtime floor and extend boot smoke coverage.

Files changed:
 .changeset/fn-8954-cli-exit-13.md                  |  7 ++
 docs/testing.md                                    |  4 +-
 package.json                                       |  3 +
 packages/cli/agent-browser.mjs                     |  6 ++
 packages/cli/bin.mjs                               |  7 ++
 packages/cli/package.json                          |  3 +
 packages/cli/src/__tests__/ci-workflow.test.ts     |  9 +++
 packages/cli/src/__tests__/cli-exit-code.test.ts   | 82 ++++++++++++++++++++++
 packages/cli/src/__tests__/package-config.test.ts  | 12 ++++
 packages/cli/src/bin.ts                            |  6 ++
 .../__tests__/postgres/embedded-free-port.test.ts  | 37 ++++++++++
 packages/core/src/memory/memory-backend.ts         | 17 +++--
 packages/core/src/postgres/embedded-lifecycle.ts   | 16 +++--
 scripts/boot-smoke.mjs                             | 62 +++++++++++-----
 14 files changed, 244 insertions(+), 27 deletions(-)

Fusion-Task-Id: FN-8954

Fusion-Task-Lineage: 05303d07-2662-48d5-a442-6d43fa0a4493

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-11 04:20:33 -07:00
gsxdsm
f038d04dc5 FN-8986: stage computer-use skill only on Darwin
Stage the bundled computer-use discovery skill exclusively for supported macOS runtimes.

- Gate Claude and Grok session skill resolution and staging by platform.
- Install the Hermes discovery skill on Darwin while preserving user overrides and non-Darwin suppression.
- Document runtime discovery behavior, add coverage, and add a minor release changeset.

Files changed:
 .../darwin-only-computer-use-skill-staging.md      |   7 +
 docs/computer-use.md                               |  10 +-
 .../custom-provider-routes-hermes-additive.test.ts |   2 +-
 .../src/__tests__/skill-loader.test.ts             | 197 +++++++++++++++++++++
 .../src/skill-loader.ts                            | 145 ++++++++++-----
 .../src/__tests__/skill-loader.test.ts             |  51 +++++-
 .../fusion-plugin-grok-runtime/src/skill-loader.ts | 145 ++++++++++-----
 .../src/__tests__/fusion-skill-install.test.ts     |  62 ++++++-
 .../src/__tests__/index.test.ts                    |  37 +++-
 .../src/fusion-skill-install.ts                    | 151 ++++++++--------
 plugins/fusion-plugin-hermes-runtime/src/index.ts  |  21 ++-
 11 files changed, 649 insertions(+), 179 deletions(-)

Fusion-Task-Id: FN-8986

Fusion-Task-Lineage: 373d558a-1d0a-4737-99be-f53189a9aeaf

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-11 04:13:35 -07:00
gsxdsm
967e98194e FN-8950: hide Promote until plan gates clear
Prevent task-card promotion shortcuts when plan review or approval holds remain.

- Mirror default-on plan-review gate and approval-hold predicates in dashboard helpers.
- Suppress Promote across planning, review, and approval states.
- Add regression coverage and a patch changeset.

Files changed:
 .changeset/fn-8950-promote-plan-gate.md            |  7 ++
 packages/dashboard/app/components/TaskCard.tsx     | 29 +++++--
 .../__tests__/TaskCard.cost-badge.test.tsx         |  2 +
 .../__tests__/TaskCard.footer-wrap.test.tsx        |  2 +
 .../app/components/__tests__/TaskCard.test.tsx     | 96 ++++++++++++++--------
 .../utils/__tests__/reviewBudgetApproval.test.ts   | 77 +++++++++++++++++
 .../dashboard/app/utils/reviewBudgetApproval.ts    | 43 ++++++++++
 7 files changed, 218 insertions(+), 38 deletions(-)

Fusion-Task-Id: FN-8950

Fusion-Task-Lineage: c587b3b4-03b4-4cd2-9588-826706788eb7

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-11 04:00:16 -07:00
gsxdsm
637854ad36 FN-8932: add durable memory consolidation agent
Add a provisioned memory agent that consolidates durable recall material through idempotent heartbeat ticks.

- Provision and configure the durable memory agent with an enabled workflow setting.
- Add consolidation adapters, material collection, recall graph references, and run-audit metadata.
- Expose the setting in the dashboard and document the memory-agent behavior.
- Cover provisioning, heartbeat, consolidation, audit, and recall graph behavior with tests.

Files changed:
 .changeset/fn-8932-memory-agent.md                 |   7 ++
 AGENTS.md                                          |   1 +
 docs/agents.md                                     |  10 ++
 docs/settings-reference.md                         |   1 +
 docs/storage.md                                    |   2 +-
 .../memoryConsolidationEnabled-default.test.ts     |  22 ++++
 .../memory-recall-graph-cross-reference.pg.test.ts | 115 +++++++++++++++++++++
 .../__tests__/memory-agent-provisioning.test.ts    |  31 ++++++
 packages/core/src/agents/agent-store.ts            |  85 +++++++++++++++
 packages/core/src/agents/memory-agent-defaults.ts  |  30 ++++++
 packages/core/src/index.gate.ts                    |   2 +
 packages/core/src/index.ts                         |   9 ++
 packages/core/src/memory/recall/index.ts           |   1 +
 packages/core/src/memory/recall/recall-dedup.ts    |   3 +
 packages/core/src/memory/recall/recall-store.ts    |  35 ++++++-
 .../src/workflows/builtin-workflow-settings.ts     |  14 +++
 .../src/workflows/workflow-settings-resolver.ts    |  12 ++-
 .../__tests__/WorkflowSettingsPanel.test.tsx       |   8 ++
 .../__tests__/workflow-setting-display.test.ts     |   6 ++
 .../app/components/workflow-setting-display.ts     |   5 +
 .../memory-consolidation-heartbeat-hook.test.ts    |  92 +++++++++++++++++
 .../__tests__/memory-consolidation-ports.test.ts   |  34 ++++++
 ...memory-consolidation-run-audit-metadata.test.ts |  19 ++++
 .../__tests__/memory-consolidation-tick.test.ts    |  62 +++++++++++
 packages/engine/src/agent-heartbeat.ts             |  55 ++++++++++
 packages/engine/src/index.ts                       |   1 +
 packages/engine/src/memory/index.ts                |   3 +
 .../src/memory/memory-consolidation-adapters.ts    |  29 ++++++
 .../src/memory/memory-consolidation-material.ts    |  22 ++++
 packages/engine/src/memory/memory-consolidation.ts |  41 ++++++++
 packages/engine/src/util/run-audit.ts              |  10 ++
 31 files changed, 764 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-8932

Fusion-Task-Lineage: b4fdec50-1f42-4120-af17-0b6f3a94586e

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-11 03:53:11 -07:00
gsxdsm
0eaa3c7b9a FN-8990: clean up plugin reload scratch files
Keep plugin hot-reload cache-busting copies ephemeral and remove legacy tracked artifacts.

- Delete tracked plugin reload scratch files.
- Remove temporary import copies after successful and failed reloads.
- Add cleanup and tracked-artifact regression coverage.

Files changed:
 .changeset/fn-8990-plugin-reload-scratch-cleanup.md       |   7 ++
 packages/core/src/__tests__/plugin-hot-reload.test.ts     |  25 ++++ -
 packages/core/src/plugins/plugin-loader.ts                |  16 ++-
 plugins/fusion-plugin-droid-runtime/src/.index.reload-1.ts |  84 ----------------
 plugins/fusion-plugin-droid-runtime/src/.index.reload-2.ts |  84 ----------------
 plugins/fusion-plugin-hermes-runtime/src/.index.reload-1.ts | 108 --------------------
 plugins/fusion-plugin-hermes-runtime/src/.index.reload-2.ts | 108 --------------------
 plugins/fusion-plugin-hermes-runtime/src/.index.reload-3.ts | 108 --------------------
 plugins/fusion-plugin-openclaw-runtime/src/.index.reload-1.ts |  95 -----------------
 plugins/fusion-plugin-paperclip-runtime/src/.index.reload-1.ts | 112 ---------------------
 scripts/__tests__/no-tracked-plugin-reload-artifacts.test.mjs |  27 +++++
 11 files changed, 72 insertions(+), 702 deletions(-)

Fusion-Task-Id: FN-8990

Fusion-Task-Lineage: 2221ebaf-b8ab-4a3c-8934-addfa348c98c

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-11 03:40:21 -07:00
gsxdsm
41bb94ba77 FN-8957: isolate PostgreSQL agents by project
Keep durable PostgreSQL agent records and analytics isolated to their bound project.

- Scope agent reads, mutations, satellite records, ratings, reassignment links, and analytics task data by project.
- Add a project-local agent-ratings migration and schema coverage.
- Exercise duplicate agent IDs, ratings, and token analytics across shared PostgreSQL projects.

Files changed:
 .changeset/fn-8957-agent-project-isolation.md      |   7 +
 docs/multi-project.md                              |   9 +
 .../postgres/agent-project-isolation.pg.test.ts    | 207 +++++++++++++++++++++
 .../src/__tests__/postgres/schema-applier.test.ts  |  13 +-
 packages/core/src/agents/agent-store.ts            |  52 +++---
 .../core/src/async-stores/async-agent-store.ts     | 118 ++++++++++--
 packages/core/src/board/team-analytics.ts          |  20 +-
 ...0054_fn_8957_agent_rating_project_isolation.sql |  32 ++++
 packages/core/src/postgres/schema-applier.ts       |  13 +-
 packages/core/src/postgres/schema/project.ts       |   6 +-
 packages/core/src/task-store/task-artifacts-ops.ts |  19 +-
 11 files changed, 443 insertions(+), 53 deletions(-)

Fusion-Task-Id: FN-8957

Fusion-Task-Lineage: 02cb3f13-e5d1-4cea-8afb-72bcd9fae890

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-11 03:32:16 -07:00
gsxdsm
34e74d2fe4 perf(verify:fast): run independent steps concurrently
verify:fast ran every step serially, so its wall clock was the sum of steps with no
ordering relationship between them. Static checks and per-package typechecks are
each independent, so they now run as bounded-concurrency groups.

  static checks   ~6.0s -> ~1.6s   (11 validators, mostly node startup)
  typecheck       11.0s -> 7.4s    (engine + dashboard)
  no-change run   28.1s -> 22.3s

Ordering that matters is untouched: bootstrap, builds, and boot smoke stay serial
and in plan order, and each group is a barrier. A failing group awaits its in-flight
siblings before throwing rather than abandoning partial tsbuildinfo/dist state, and
reports the first failure in plan order so the message does not depend on which
sibling lost the race. FUSION_VERIFY_FAST_SERIAL=1 restores the old behavior when
interleaved child output makes a failure hard to read.

Boot smoke is now 84% of a no-change run (18.8s); it re-runs initdb into a throwaway
HOME every time. Left alone -- caching that would change what the gate proves.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 03:06:02 -07:00
gsxdsm
cb4d94104a docs(engine): correct the prune-before-remove rationale
The comment cited 89 registered worktrees against 20 on disk as evidence of stale
registrations. That comparison was against .worktrees/ alone; all 89 registrations
exist, spread across kb-worktrees, orca workspaces and .claude/worktrees. Prune
still belongs before removal on ordering grounds -- a dangling registration fails
the removal, and the throw skips the trailing prune so the retry never clears it --
but the false measurement should not stand as the justification.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 02:49:01 -07:00
gsxdsm
2b228383d5 test: cover model-target chat creation and non-conflict cleanup failures
Both suites are mutation-verified: reverting the corresponding fix fails 4 of the
chat tests and exactly the 3 new self-healing park tests.

The self-healing tests carry a positive control asserting the sweep actually
reached the tip-already-merged arm -- without it the park assertions passed
vacuously against a task shape the candidate filter rejected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 02:47:24 -07:00
gsxdsm
fd68bb1bea fix: model-target chats 404, and worktree rmdir races misreported as branch conflicts
Two unrelated production failures with a shared symptom of an opaque error.

Chat: FN-8869 hoisted the agent-existence check out of its else branch, so it ran
even when the client supplied an explicit model pair. Model-target chats send the
client-only sentinel `__fn_agent__`, which is never an agent row, so every one of
them 404'd behind the generic "Failed to create chat session" toast. The agent is
now required only when it is the source of model resolution.

Self-healing: a failed `tip-already-merged` cleanup was rethrown and classified
`branch-conflict-unrecoverable`, failing and pausing tasks whose branch was already
an ancestor of the integration ref. Every one of the 78 logged parks carried a
`git worktree remove --force` / `ENOTEMPTY rmdir node_modules` message -- a pnpm
race, not a conflict. Cleanup failure now retries on the next sweep, and prune runs
before removal so a stale registration stops causing the failure it would prevent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 02:39:56 -07:00
gsxdsm
06ea444339 fix: uncap workflow principals and auto-resume stranded continuations
Two independent wedges kept cards silently stuck on the board.

1. Workflow principals were capped. `WorkflowAgentCapacity.acquire` enforced
   `settings.maxConcurrent` as a project session budget plus an optional
   per-agent `maxWorkflowSessions`, and `routeWorkflowPrincipal`'s availability
   test applied the same per-agent ceiling. The workflow roles stand in for
   STAGES, not workers, and there is typically one agent per role - so the cap
   serialized the entire board behind a single Workflow Executor regardless of
   maxConcurrent/maxWorktrees. Admission now always succeeds; the lease survives
   as bookkeeping (it is what activeSessions counts and what the renewal timer
   keeps warm). `maxProjectSessions` is removed from the input rather than
   defaulted, so it cannot be reintroduced without deleting the contract, and
   the agent-capacity re-route loops in triage and graph admission are deleted
   with the refusal they existed to work around.

2. Continuations that stop in `running` or `held` were never re-polled. The
   scheduler's due-poll takes only `runnable`/`retrying`; a row claimed through
   a path that leaves `leaseExpiresAt` NULL keeps `state: "running"` forever
   after its process dies, and `acquireWorkflowWorkItemLease` can only re-take a
   `held` row whose blockedReason matches workflow-principal-%. Observed live:
   seven cards `running` behind leases from a process that exited ~9h earlier,
   two `held` with a NULL blockedReason for 46h, none emitting a single
   run-audit row while stranded. A further 33 active-state rows belonged to
   archived+soft-deleted tasks (the FK cascade only fires on hard delete).

   New sweep `reconcileStrandedWorkflowContinuations` (startup + periodic)
   re-queues both stranded shapes and retires dead tasks' rows, gated by the
   canonical liveness triple, a 10-minute grace matching the capacity lease
   duration, and a compare-and-set on the scanned state so a real claim wins.
   The decision is the pure `evaluateStrandedContinuationReclaim`, shared with
   its tests so coverage cannot drift from behavior - the drift that let the
   FN-8923 sweep ship covering one ninth of this problem.

Verified: pnpm lint, engine typecheck, pnpm test:gate (606 tests), verify:fast,
and the new suite under mutation (removing either guard fails 3 cases). The two
pre-existing failures in self-healing-orphaned-pending-step-results.test.ts
reproduce identically at HEAD without these changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 02:02:51 -07:00
gsxdsm
62979d8796 FN-8985: centralize CLI version resolution
Centralize CLI self-version discovery without widening the early boot import graph.

- Reuse one bounded manifest resolver for the CLI binary, updater, and plugin scaffold.
- Add regression coverage for manifest lookup bounds, malformed manifests, and scaffold version fallback.
- Preserve update command test isolation after the core i18n module relocation.

Files changed:
 packages/cli/src/__tests__/cli-version.test.ts     | 136 +++++++++++++++++++++
 .../plugin-scaffold-caret-fallback.test.ts         |  91 ++++++++++++++
 packages/cli/src/bin.ts                            |  45 +------
 packages/cli/src/cli-version.ts                    |  51 ++++++++
 packages/cli/src/commands/__tests__/update.test.ts |   2 +-
 packages/cli/src/commands/plugin-scaffold.ts       |  40 +-----
 packages/cli/src/commands/update.ts                |  37 +-----
 7 files changed, 292 insertions(+), 110 deletions(-)

Fusion-Task-Id: FN-8985

Fusion-Task-Lineage: dd95b651-3578-4c5f-957a-5af7b85129d7

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-11 01:51:22 -07:00
gsxdsm
8f6190910d FN-8971: add mission blocked-status clearing tool
Add an operator-only CLI tool for repairing stale mission blocked badges.

- Register and document fn_mission_clear_blocked with PostgreSQL and status-error handling.
- Withhold the repair action from agent principals and deny it in readonly workflow steps.
- Classify the tool consistently across engine permission gates and add coverage.
- Add a minor CLI changeset for the new operator capability.

Files changed:
 .changeset/fn-8971-mission-clear-blocked-tool.md   |  7 +++
 docs/missions.md                                   |  7 ++-
 packages/cli/skill/fusion/SKILL.md                 |  2 +-
 .../cli/skill/fusion/references/extension-tools.md |  9 ++++
 .../skill/fusion/references/fusion-capabilities.md |  1 +
 .../__tests__/extension-permission-gates.test.ts   | 26 ++++++++++
 packages/cli/src/__tests__/extension.test.ts       | 56 +++++++++++++++++++++-
 packages/cli/src/extension.ts                      | 54 +++++++++++++++++++++
 .../src/__tests__/agent-mission-tools.test.ts      |  5 +-
 .../src/__tests__/gating-classifications.test.ts   |  8 ++++
 .../workflow-step-readonly-allowlist.test.ts       |  5 +-
 .../engine/src/execution/gating-classifications.ts |  7 +++
 12 files changed, 182 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-8971

Fusion-Task-Lineage: 650c13b3-c6c4-4dc5-a0b5-9c71d3b94fc5

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-11 01:45:08 -07:00
gsxdsm
7ddcf7e2a6 FN-8979: remove legacy mission resume blockers
Retire the deprecated v0 mission-resume blocker payload in favor of canonical descriptors.

- Remove legacy blocker types, conversions, exports, and HTTP payload mirrors.
- Deduplicate canonical blocker descriptors and update clients, tests, and documentation.
- Add a major changeset for the breaking API removal.

Files changed:
 .changeset/fn-8979-removal.md                      |  7 +++++
 docs/missions.md                                   |  4 +--
 .../suite-only-flakes-observed-register.md         | 14 +++++++++
 .../src/__tests__/mission-blocked-clear.test.ts    | 23 ++++++++++++++-
 .../core/src/__tests__/mission-blockers.test.ts    | 26 +++++++++++------
 .../__tests__/postgres/mission-store.pg.test.ts    |  5 +---
 .../core/src/async-stores/async-mission-store.ts   |  7 +----
 packages/core/src/index.gate.ts                    |  3 +-
 packages/core/src/index.ts                         |  3 +-
 packages/core/src/missions/mission-blockers.ts     | 34 +++++++++++++---------
 packages/core/src/missions/mission-types.ts        |  9 ++----
 packages/core/src/types.ts                         |  2 +-
 packages/dashboard/app/api/missions/missions.ts    | 25 +++++-----------
 .../MissionManager.blocked-repair.test.tsx         | 17 +++++++----
 .../MissionManager.resume-conflict.test.tsx        |  9 ++++--
 .../src/__tests__/mission-resume-conflict.test.ts  | 11 ++++---
 packages/dashboard/src/mission-routes.ts           | 10 +++----
 17 files changed, 127 insertions(+), 82 deletions(-)

Fusion-Task-Id: FN-8979
Fusion-Task-Lineage: 2a0dd0b6-43ca-44ad-b992-79f4ef8eda67
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-11 01:30:04 -07:00
gsxdsm
eacd6687bc FN-8961: add computer-use skill and version-matched guide
Ship the computer-use skill across bundled clients and surface its matching guide through the CLI.

- add the computer-use skill, computer command descriptor, and `fn skills get computer-use` guide
- reconcile all shipped Claude skills at project and startup entry points
- cover both skills' reconciliation outcomes and every required call site

Files changed:
 .changeset/fn-8961-computer-use-skill.md           |   7 +
 docs/cli-reference.md                              |   6 +-
 docs/computer-use.md                               |   8 +
 packages/cli/skill/computer-use/SKILL.md           |  31 +++
 packages/cli/src/__tests__/package-config.test.ts  |  20 ++
 packages/cli/src/bin.ts                            |  14 +-
 .../__tests__/claude-skills-callsites.test.ts      |  64 ++++++
 .../src/commands/__tests__/claude-skills.test.ts   | 221 ++++++++-------------
 .../__tests__/computer-surface-descriptor.test.ts  | 108 ++++++++++
 .../commands/__tests__/computer-use-guide.test.ts  |  36 ++++
 .../commands/__tests__/computer-use-skill.test.ts  |  20 ++
 packages/cli/src/commands/__tests__/daemon.test.ts |  36 +++-
 .../__tests__/dashboard-claude-skills.test.ts      |  19 ++
 packages/cli/src/commands/__tests__/init.test.ts   |  48 ++++-
 .../cli/src/commands/__tests__/project.test.ts     |  38 ++++
 packages/cli/src/commands/__tests__/serve.test.ts  |  36 +++-
 .../commands/__tests__/skill-installation.test.ts  |  12 ++
 .../cli/src/commands/__tests__/skills-get.test.ts  |  67 ++++++
 packages/cli/src/commands/claude-skills-runner.ts  |  55 ++---
 packages/cli/src/commands/claude-skills.ts         |  47 +++--
 packages/cli/src/commands/computer.ts              |   6 +-
 packages/cli/src/commands/computer/contract.ts     |  52 +++++
 packages/cli/src/commands/computer/guide.ts        |  62 ++++++
 packages/cli/src/commands/init.ts                  |   4 +-
 packages/cli/src/commands/skill-installation.ts    |  45 +++--
 packages/cli/src/commands/skills.ts                |  24 +++
 26 files changed, 853 insertions(+), 233 deletions(-)

Fusion-Task-Id: FN-8961
Fusion-Task-Lineage: b6baaebb-bf72-4991-8239-eb9bcf9cbcf1
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-11 01:16:59 -07:00
gsxdsm
3eec1338c5 FN-8970: add mission reconcile controls
Add a dry-run mission reconciliation control with explicit apply feedback.

- Add the dashboard reconcile API client and exported result type.
- Present preview, apply, empty, and archived reconciliation states in Mission Manager.
- Guard reconcile requests across direct selection and target-mission deep-link changes.
- Cover reconcile interactions, stale requests, and deep-link intent updates.

Files changed:
 .changeset/fn-8970-mission-reconcile-control.md    |   7 +
 docs/missions.md                                   |   6 +
 packages/dashboard/app/api/legacy.ts               |   2 +
 packages/dashboard/app/api/missions/missions.ts    |  31 +++
 packages/dashboard/app/components/MissionManager.css    |  48 +++++
 packages/dashboard/app/components/MissionManager.tsx    | 184 +++++++++++++-
 packages/dashboard/app/components/__tests__/MissionManager.mobile-css.test.ts    |   8 +
 packages/dashboard/app/components/__tests__/MissionManager.reconcile.test.tsx    | 277 +++++++++++++++++++++
 8 files changed, 557 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-8970

Fusion-Task-Lineage: 62802129-a7ea-43cb-8068-5ce2c2c21b77

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-11 00:23:10 -07:00
gsxdsm
79502c67a0 FN-8978: fix CLI TypeScript external packaging
Keep TypeScript available as a runtime external in the published CLI package.

- Remove the duplicate TypeScript devDependency declaration.
- Assert tsup externals are published runtime dependencies.
- Document the runtime external packaging invariant.

Files changed:
 .changeset/fn-8978-typescript-dedup.md            |  7 +++++
 packages/cli/package.json                         |  1 -
 packages/cli/src/__tests__/package-config.test.ts | 31 +++++++++++++++++++++++
 packages/cli/tsup.config.ts                       |  6 +++++
 4 files changed, 44 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-8978

Fusion-Task-Lineage: b9630c4a-73a9-414f-9a78-25c689359509

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 23:04:32 -07:00
gsxdsm
844512ed3e FN-8976: prevent concurrent automatic validator runs
Prevent automatic validation from running alongside a fresh manual or non-memoized validator.

- Serialize validator admission around a feature-scoped fresh-running check.

- Report feature-versus-fingerprint blocking scope and preserve memoization semantics.

- Add regression coverage, documentation, and a patch changeset.

Files changed:

 .changeset/fn-8976-validator-admission.md          |   7 ++
 docs/missions.md                                   |   4 +-
 .../__tests__/postgres/mission-store.pg.test.ts    | 110 +++++++++++++++++++--
 .../core/src/async-stores/async-mission-store.ts   |  61 ++++++++++--
 packages/core/src/missions/mission-types.ts        |   2 +
 .../src/__tests__/mission-execution-loop.test.ts   |  10 +-
 6 files changed, 171 insertions(+), 23 deletions(-)

Fusion-Task-Id: FN-8976
Fusion-Task-Lineage: 61b487e8-5542-4cce-94f7-58d5295fe177
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 22:57:21 -07:00
gsxdsm
918a4c4bfa FN-8973: add versioned mission resume blockers
Expose versioned mission resume blockers across API and UI.

- Add versioned blocker descriptors with fail-closed legacy normalization and v0 compatibility projections.
- Return typed resume-conflict envelopes and render root stop details in Mission Manager.
- Cover descriptor behavior, route conflicts, UI handling, and PostgreSQL persistence.

Files changed:
 .changeset/fn-8973-mission-blocker-descriptor.md   |  7 ++
 docs/missions.md                                   |  2 +-
 .../src/__tests__/mission-blocked-clear.test.ts    | 18 ++---
 .../core/src/__tests__/mission-blockers.test.ts    | 43 ++++++++++++
 .../__tests__/postgres/mission-store.pg.test.ts    | 22 ++++--
 .../core/src/async-stores/async-mission-store.ts   | 23 +++---
 packages/core/src/index.gate.ts                    |  4 ++
 packages/core/src/index.ts                         |  4 ++
 packages/core/src/missions/mission-blockers.ts     | 43 ++++++++++++
 packages/core/src/missions/mission-types.ts        | 81 ++++++++++------------
 packages/core/src/types.ts                         |  4 +-
 packages/dashboard/app/api/legacy.ts               |  1 +
 packages/dashboard/app/api/missions/missions.ts    | 46 +++++++-----
 .../dashboard/app/components/MissionManager.tsx    | 11 +--
 .../MissionManager.blocked-repair.test.tsx         | 10 +--
 .../MissionManager.resume-conflict.test.tsx        | 24 +++++++
 .../__tests__/mission-blocked-clear-routes.test.ts |  2 +-
 .../src/__tests__/mission-resume-conflict.test.ts  | 42 +++++++++++
 packages/dashboard/src/mission-routes.ts           | 12 +++-
 19 files changed, 297 insertions(+), 102 deletions(-)

Fusion-Task-Id: FN-8973
Fusion-Task-Lineage: 5d36c9c9-dc0f-4cb0-bd0c-ad41c8dde5c0
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 22:36:01 -07:00
gsxdsm
79206c3f31 FN-8977: unify CLI Vitest mock resolution
Route CLI test mocks through dashboard and engine runtime imports.

- Anchor pi-coding-agent resolution to the CLI package instance
- Preserve real session exports while overriding runtime dependencies
- Add a regression test and document cross-package mock scoping

Files changed:
 docs/testing.md                                    |  6 ++
 .../__tests__/extension-permission-gates.test.ts   | 10 ++-
 .../vitest-cross-package-mock-scope.test.ts        | 75 ++++++++++++++++++++++
 packages/cli/vitest.config.ts                      | 12 ++++
 4 files changed, 101 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-8977
Fusion-Task-Lineage: a652cdf4-463e-4603-8d71-87db91d0b846
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 22:12:15 -07:00
gsxdsm
9571f73666 FN-8972: preserve blocked mission status during rollups
Protect explicitly blocked or archived hierarchy statuses from automatic recomputation.

- Restrict mission and milestone rollups to statuses they own.
- Make asynchronous recomputations transactional and preserve status events.
- Cover guarded rollups in SQLite and PostgreSQL tests.

Files changed:
 .../fn-8972-mission-recompute-blocked-guard.md     |   7 ++
 docs/missions.md                                   |   2 +
 .../mission-status-recompute-guard.test.ts         |  85 +++++++++++++++++
 .../__tests__/postgres/mission-store.pg.test.ts    | 105 +++++++++++++++++++++
 .../core/src/async-stores/async-mission-store.ts   |  67 +++++++++++--
 packages/core/src/missions/mission-store.ts        |  12 ++-
 packages/core/src/missions/mission-types.ts        |  21 +++++
 7 files changed, 286 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-8972

Fusion-Task-Lineage: 07ede656-dec0-4d3e-b35c-06e0f6304b74

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 22:03:57 -07:00
gsxdsm
1da61f35f7 FN-8960: add macOS computer automation CLI
Add a snapshot-backed macOS computer-use surface to the Fusion CLI.

- Register fn computer commands for app state, permission, capability, and UI actions.
- Implement macOS JXA automation with locator replay and persisted snapshot safety checks.
- Document the CLI surface, add contract coverage, and include a release changeset.

Files changed:
 .changeset/fn-8960-computer-use-cli.md             |   7 +
 docs/README.md                                     |   1 +
 docs/cli-reference.md                              |  21 ++
 docs/computer-use.md                               | 156 +++++++++++++
 packages/cli/src/bin.ts                            |  11 +
 .../__tests__/computer-adapter-registry.test.ts    | 154 ++++++++++++
 .../commands/__tests__/computer-commands.test.ts   |  71 ++++++
 .../commands/__tests__/computer-contract.test.ts   |  34 +++
 .../__tests__/computer-snapshot-index.test.ts      |  87 +++++++
 packages/cli/src/commands/computer.ts              | 182 +++++++++++++++
 .../cli/src/commands/computer/adapter-macos.ts     | 211 +++++++++++++++++
 .../cli/src/commands/computer/adapter-registry.ts  |  42 ++++
 .../src/commands/computer/adapter-unsupported.ts   |  44 ++++
 packages/cli/src/commands/computer/adapter.ts      |  97 ++++++++
 packages/cli/src/commands/computer/contract.ts     |  83 +++++++
 packages/cli/src/commands/computer/exec-seam.ts    |  61 +++++
 .../cli/src/commands/computer/scripts/macos-jxa.ts |  37 +++
 .../cli/src/commands/computer/snapshot-store.ts    | 257 +++++++++++++++++++++
 18 files changed, 1556 insertions(+)

Fusion-Task-Id: FN-8960

Fusion-Task-Lineage: 5870bf69-b751-4879-bf9d-5f5396cc0f55

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 21:56:18 -07:00
gsxdsm
90573e31b0 FN-8963: prevent concurrent mission validation runs
Prevent duplicate manual validation runs while preserving recovery from stale validator state.

- Add atomic mission-store claims and release handling for manual validator runs.
- Return a conflict response and disable the validation action while a run is active.
- Cover concurrent claims, API behavior, UI state, and stale-window parity.

Files changed:
 .changeset/fn-8963-validate-inflight-guard.md      |   7 ++
 docs/missions.md                                   |   2 +
 .../__tests__/postgres/mission-store.pg.test.ts    | 129 +++++++++++++++++++++
 .../core/src/async-stores/async-mission-store.ts   |  87 ++++++++++++--
 packages/core/src/index.ts                         |   2 +
 packages/core/src/missions/mission-store.ts        |  69 ++++++++++-
 packages/core/src/missions/mission-types.ts        |  13 +++
 packages/dashboard/app/api/legacy.ts               |   2 +
 packages/dashboard/app/api/missions/missions.ts    |  11 +-
 .../dashboard/app/components/MissionManager.tsx    |  15 ++-
 .../MissionManager.validate-inflight.test.tsx      |  77 ++++++++++++
 .../mission-validate-inflight-guard.test.ts        |  55 +++++++++
 packages/dashboard/src/mission-routes.ts           |  32 +---
 .../src/__tests__/mission-execution-loop.test.ts   |  61 +++++++++-
 .../validator-run-stale-window-parity.test.ts      |   9 ++
 15 files changed, 549 insertions(+), 22 deletions(-)

Fusion-Task-Id: FN-8963
Fusion-Task-Lineage: 7e5d0ae4-98ac-4f79-99ca-45fd1450362d
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 21:41:47 -07:00
gsxdsm
5dd3031e34 FN-8962: add mission blocked status repair controls
Add explicit diagnostics and repair paths for stale mission blocked badges.

- Expose audited core and REST APIs that recompute and clear stale mission blocked status without resuming automation.
- Add mission-manager controls, blocker diagnostics, responsive styling, and operator documentation.
- Cover clear conflicts, persistence, routes, and desktop/mobile UI behavior.

Files changed: .changeset/fn-8962-mission-blocked-clear.md        |   7 ++
 docs/missions.md                                   |  12 ++-
 .../src/__tests__/mission-blocked-clear.test.ts    |  40 ++++++++
 .../__tests__/postgres/mission-store.pg.test.ts    |  71 ++++++++++++++
 .../core/src/async-stores/async-mission-store.ts   |  90 +++++++++++++++--
 packages/core/src/index.gate.ts                    |   4 +
 packages/core/src/index.ts                         |   5 +-
 packages/core/src/missions/mission-types.ts        |  62 ++++++++++++
 packages/dashboard/app/api/legacy.ts               |   3 +
 packages/dashboard/app/api/missions/missions.ts    |  29 ++++++
 .../dashboard/app/components/MissionManager.css    |   6 ++
 .../dashboard/app/components/MissionManager.tsx    |  90 ++++++++++++++++-
 .../MissionManager.blocked-repair.test.tsx         | 106 +++++++++++++++++++++
 .../__tests__/MissionManager.mobile-css.test.ts    |   8 ++
 .../__tests__/mission-blocked-clear-routes.test.ts |  71 ++++++++++++++
 packages/dashboard/src/mission-routes.ts           |  49 ++++++++++
 16 files changed, 638 insertions(+), 15 deletions(-)

Fusion-Task-Id: FN-8962

Fusion-Task-Lineage: 38cab277-a0c3-4c60-af3e-dd25d2f88dea

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 20:41:11 -07:00
gsxdsm
cef07527f6 FN-8948: reconcile mission state from task ground truth
Centralize mission and feature state repair around deterministic task lifecycle evidence.

- Add a reusable mission reconciliation authority with task-move, API, tool, and maintenance callers.
- Repair unambiguous title links while preserving terminal, validation, and audit safeguards.
- Route scheduler moves through the authority and reject duplicate feature-title ownership.
- Expose reconcile controls and document the operator workflow.

Files changed:
 .changeset/fn-8948-mission-auto-reconcile.md       |   7 +
 AGENTS.md                                          |   1 +
 docs/missions.md                                   |   8 +-
 packages/cli/skill/fusion/SKILL.md                 |   2 +-
 .../cli/skill/fusion/references/extension-tools.md |   9 +
 .../skill/fusion/references/fusion-capabilities.md |   1 +
 .../extension-experiment-finalize.test.ts          |   2 +
 .../__tests__/extension-gitlab-tracking.test.ts    |   2 +
 .../cli/src/__tests__/extension-web-fetch.test.ts  |   2 +
 packages/cli/src/extension.ts                      |  14 +
 packages/dashboard/src/mission-routes.ts           |  24 +-
 .../src/__tests__/agent-mission-tools.test.ts      |   2 +-
 .../engine/src/__tests__/mission-autopilot.test.ts |   8 +-
 .../src/__tests__/mission-state-reconcile.test.ts  |  67 +++++
 packages/engine/src/agent-tools.ts                 |   6 +
 .../engine/src/execution/gating-classifications.ts |   1 +
 packages/engine/src/index.ts                       |   6 +
 packages/engine/src/missions/index.ts              |   8 +-
 packages/engine/src/missions/mission-autopilot.ts  | 106 +------
 .../engine/src/missions/mission-feature-sync.ts    |   1 +
 .../engine/src/missions/mission-state-reconcile.ts | 169 +++++++++++
 packages/engine/src/runtimes/in-process-runtime.ts |   4 +-
 packages/engine/src/scheduler.ts                   | 331 +++++----------------
 packages/engine/src/util/run-audit.ts              |   2 +
 24 files changed, 426 insertions(+), 357 deletions(-)

Fusion-Task-Id: FN-8948
Fusion-Task-Lineage: 0fbccef3-eeac-46d2-b3d8-aca679b3657e
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 20:32:26 -07:00
gsxdsm
33d4fa46c5 FN-8969: fix plan evidence version collisions
Prevent plan writes from permanently failing when durable and snapshot evidence versions diverge.

- Centralize conflict-tolerant plan-evidence appends with durable version allocation
- Reuse the helper for prompt, lineage, and project evidence writes
- Cover version drift, retry, deduplication, and concurrent PostgreSQL writes

Files changed:
 .../fn-8969-plan-evidence-version-collision.md     |  7 ++
 .../__tests__/plan-evidence-next-version.test.ts   | 49 ++++++++++++++
 .../plan-evidence-version-collision.pg.test.ts     | 72 ++++++++++++++++++++
 packages/core/src/store.ts                         | 40 ++++++-----
 .../core/src/task-store/async/async-lifecycle.ts   | 49 +++++++-------
 packages/core/src/task-store/plan-evidence.ts      | 77 ++++++++++++++++++++++
 packages/core/src/task-store/project-store-ops.ts  | 47 +++++++------
 7 files changed, 276 insertions(+), 65 deletions(-)

Fusion-Task-Id: FN-8969

Fusion-Task-Lineage: 5fba0bc8-bcf6-42ea-b617-3484919ed2fa

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 19:43:13 -07:00
gsxdsm
b82f1a41f3 FN-8947: add repairable mission validation controls
Add repairable mission-validation badges with clear and re-run flows.

- Persist repair metadata and audit events for mission validation state changes.
- Expose validation repair through dashboard routes, UI controls, engine tools, and CLI capabilities.
- Add database, API, UI, engine, and extension coverage plus operator documentation.

Files changed: .changeset/fn-8947-mission-validation-repair.md    |   7 +
 docs/missions.md                                   |  15 +-
 packages/cli/skill/fusion/SKILL.md                 |   2 +-
 .../cli/skill/fusion/references/extension-tools.md |  10 +
 .../skill/fusion/references/fusion-capabilities.md |   1 +
 .../extension-experiment-finalize.test.ts          |   2 +
 .../__tests__/extension-gitlab-tracking.test.ts    |   2 +
 .../cli/src/__tests__/extension-web-fetch.test.ts  |   2 +
 packages/cli/src/__tests__/extension.test.ts       |  24 +++
 packages/cli/src/extension.ts                      |  40 ++++
 .../mission-status-event-metadata.test.ts          |  23 +++
 .../postgres/mission-validation-repair.pg.test.ts  | 187 ++++++++++++++++++
 .../core/src/async-stores/async-mission-store.ts   | 216 ++++++++++++++++++---
 packages/core/src/index.gate.ts                    |   5 +
 packages/core/src/index.ts                         |   5 +-
 packages/core/src/missions/mission-types.ts        |  49 +++++
 packages/core/src/types.ts                         |   7 +
 packages/dashboard/app/api/legacy.ts               |   1 +
 packages/dashboard/app/api/missions/missions.ts    |  13 ++
 .../dashboard/app/components/MissionManager.css    |  26 ++-
 .../dashboard/app/components/MissionManager.tsx    | 207 +++++++++++++++++---
 .../__tests__/MissionManager.mobile-css.test.ts    |   8 +
 .../MissionManager.validation-repair.test.tsx      |  83 ++++++++
 .../__tests__/mission-task-prefix-routes.test.ts   | 162 +++++++++++++++-
 packages/dashboard/src/mission-routes.ts           | 104 +++++++++-
 .../src/__tests__/agent-mission-tools.test.ts      | 119 +++++++++++-
 .../__tests__/mission-feature-sync-lanes.test.ts   |  59 +++++-
 .../workflow-step-readonly-allowlist.test.ts       |   1 +
 packages/engine/src/agent-tools.ts                 |  36 ++++
 .../engine/src/execution/gating-classifications.ts |   1 +
 packages/engine/src/index.ts                       |   1 +
 .../engine/src/missions/mission-feature-sync.ts    |  79 ++++++++
 32 files changed, 1430 insertions(+), 67 deletions(-)

Fusion-Task-Id: FN-8947

Fusion-Task-Lineage: b93e5ab6-021c-4d32-bffb-f89f4c3894bc

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 19:36:31 -07:00
gsxdsm
4c9f14e21a FN-8965: restore explicit intake owner routing
Restore deliberate engineer and authorized override assignments while preserving executor-only automatic routing.

- Accept eligible engineers as explicit intake owners through normal and reserved-ID task creation.
- Honor metadata-authorized role overrides without weakening runtime, state, or assignment-policy gates.
- Add resolver and PostgreSQL coverage plus release and architecture documentation.

Files changed:
 .../fn-8965-intake-owner-explicit-routing.md       |  7 +++
 docs/architecture.md                               |  2 +-
 .../postgres/create-task-reserved-id.pg.test.ts    | 29 ++++++++++++
 .../__tests__/task-intake-owner-resolver.test.ts   | 51 ++++++++++++++++++++--
 packages/core/src/task-store/task-creation.ts      |  7 +++
 .../core/src/tasks/task-intake-owner-resolver.ts   | 38 ++++++++++++----
 6 files changed, 121 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-8965

Fusion-Task-Lineage: 4ecf7fc8-e966-49c8-abf6-e50ae26d8224

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 19:31:21 -07:00
ischindl
f775039f5b feat(engine): add typed delivery-pipeline run-audit catalogue (#3410)
## What
Adds a typed, queryable catalogue for engine run-audit events as the
first step of the delivery-pipeline reliability & observability effort.

- **New module** `packages/engine/src/run-audit/run-audit-catalogue.ts`
— a typed registry describing run-audit event kinds (scheduler,
self-healing, merger, worktree, symbol-lock, …) so pipeline
observability can ingest and reason about them consistently.
- **Parity test** `run-audit-catalogue.test.ts` — asserts the catalogue
matches the emitted run-audit event space.
- **Docs** `docs/run-audit.md` + index pointer.

## Why
Run-audit events are currently emitted ad-hoc without a typed contract.
A catalogue gives:
- a single source of truth for event kinds/names,
- a parity guard so any new or renamed event is caught,
- a foundation for delivery-pipeline reliability dashboards.

## Verification
- `@fusion/engine` `tsc` build → **PASS**
- `vitest run run-audit-catalogue.test.ts` → **3 tests passed**
- No production behavior change outside the new module.

## Scope
New isolated module + its test + docs. No changesets/release artifacts.

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

* **Documentation**
* Added a run-audit catalogue covering delivery-pipeline finalization,
self-healing reconciliation, and durable-agent error events.
* Documented recorded outcomes, emission conditions, audit-store
querying, and event catalogue maintenance.
  * Added a documentation index entry linking to the new catalogue.
* **Tests**
* Added validation to ensure documented audit events remain complete,
consistently formatted, and synchronized with the supported event
catalogue.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Fusion <noreply@runfusion.ai>
2026-08-10 15:19:43 -10:00
gsxdsm
8c055a6695 fix: keep self-healing sweeps alive across stale task links (#3417)
## Summary
Supersedes #3405 — the fork head is not writable from maintainers, so
this branch carries the same fix rebased/merged onto current `main`.

## Conflict resolution
- Main already landed the equivalent fail-open path as **FN-8919**
(`readLinkedTaskOrUndefined` + per-agent try/catch).
- Kept the additional `recoverAgentsRunningOnInactiveTasks` regression
that covers task-gone races plus transient lookup isolation.
- Dropped the duplicate changeset (main already has
`fn-8919-agent-link-sweep-fail-open`).

## Test plan
- [x] `git merge-tree` clean against `main`
- [ ] CI green

Closes context from #3405.

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

## Summary by CodeRabbit

* **Bug Fixes**
  * Improved recovery handling when task lookups fail.
* Agents linked to deleted or missing tasks are now unlinked, while
agents affected by temporary errors remain preserved.
* Recovery continues for other eligible agents instead of stopping after
an individual lookup failure.

* **Tests**
* Added regression coverage for deleted, missing, and temporarily
unavailable tasks.

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

Co-authored-by: Codex <codex@openai.com>
2026-08-10 15:19:08 -10:00
gsxdsm
d749a11a5b FN-8923: document orphan merge durable-write fences
Record the bounded cancellation frontier for orphaned AI merge bodies.

- Add AST-derived durable-writer inventory and drift guard for the pinned merge closure.
- Characterize orphan and successor merge-lane writes with production-path fixtures.
- Document unresolved follow-ups and link the fence from the architecture guide.

Files changed:
 docs/architecture.md                               |    2 +-
 .../merge-orphan-body-durable-write-fences.md      |   92 +
 .../__tests__/_merge-durable-write-callsites.ts    |  938 ++
 .../merge-orphan-durable-write-inventory.json      | 9965 ++++++++++++++++++++
 .../merge-orphan-body-durable-writes.test.ts       |  348 +
 ...ge-orphan-durable-write-inventory-drift.test.ts |   56 +
 packages/engine/src/merge/merger-ai.ts             |    6 +
 packages/engine/src/project-engine.ts              |    6 +
 8 files changed, 11412 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-8923

Fusion-Task-Lineage: 5b2d278c-1626-439a-affd-077f2de2aef1

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 17:55:46 -07:00
gsxdsm
a839c61929 FN-8926: expose graph and recall through MCP
Expose Fusion knowledge graph and durable recall through a built-in MCP transport.

- Add the reserved fusion-memory server with graph and recall MCP tools.
- Resolve built-in availability and enable/disable tombstones across configuration and UI.
- Add CLI transport, documentation, release metadata, and lane coverage tests.

Files changed:
 .changeset/fn-8926-memory-mcp-server.md            |   7 +
 docs/cli-reference.md                              |   4 +
 docs/mcp.md                                        |  10 ++
 packages/cli/src/bin.ts                            |   6 +
 .../__tests__/mcp-memory-server-spawn.test.ts      |  79 ++++++++++
 .../commands/__tests__/mcp-memory-server.test.ts   |  83 +++++++++++
 packages/cli/src/commands/__tests__/mcp.test.ts    |  27 +++-
 packages/cli/src/commands/mcp-memory-server.ts     | 104 +++++++++++++
 packages/cli/src/commands/mcp.ts                   |  64 ++++++--
 packages/core/package.json                         |  10 ++
 .../core/src/__tests__/mcp-builtin-servers.test.ts |  17 +++
 packages/core/src/__tests__/mcp-config.test.ts     |  12 ++
 packages/core/src/config/mcp-builtin-descriptor.ts |  16 ++
 packages/core/src/config/mcp-builtin-servers.ts    |  18 +++
 packages/core/src/config/mcp-config.ts             |  40 +++--
 packages/core/src/config/mcp-discovery.ts          |   3 +-
 packages/core/src/index.ts                         |   6 +
 packages/core/src/memory/index.ts                  |   1 +
 .../mcp/__tests__/memory-mcp-handler.test.ts       |  36 +++++
 .../mcp/__tests__/memory-mcp-serialization.test.ts |  23 +++
 packages/core/src/memory/mcp/index.ts              |   4 +
 .../core/src/memory/mcp/memory-mcp-backends.ts     |  39 +++++
 packages/core/src/memory/mcp/memory-mcp-handler.ts |  54 +++++++
 .../src/memory/mcp/memory-mcp-serialization.ts     |  48 ++++++
 packages/core/src/memory/mcp/memory-mcp-tools.ts   |  64 ++++++++
 packages/core/src/types.ts                         |  10 ++
 .../settings/sections/GlobalMcpSection.tsx         |  14 +-
 .../settings/sections/McpServersCard.tsx           |  67 +++++++--
 .../settings/sections/ProjectMcpSection.tsx        |  15 +-
 .../__tests__/McpServersCard.builtin.test.tsx      |  45 ++++++
 .../dashboard/src/__tests__/chat-manager.test.ts   |  24 +++
 .../register-config-mcp-pi-settings-routes.ts      |  20 ++-
 packages/dashboard/vitest.config.ts                |   2 +
 .../__tests__/mcp-builtin-lane-coverage.test.ts    | 163 +++++++++++++++++++++
 packages/engine/src/mcp/mcp-resolution.ts          |  10 +-
 packages/engine/vitest.config.ts                   |   2 +
 36 files changed, 1097 insertions(+), 50 deletions(-)

Fusion-Task-Id: FN-8926
Fusion-Task-Lineage: b2861491-33da-4b05-b9f8-a7c1448c1c8c
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 17:50:27 -07:00
gsxdsm
a1b56f11e3 test(dashboard): flush SettingsModal auto-save debounce with fake timers
Convert the SettingsModal.general 'saves X via settings payload' tests from
real-timer waitFor (each burning a real ~500ms auto-save debounce) to the
FN-7506 fake-timer pattern already used by the auto-save tests in this file.
Payload-routing/coalescing assertions are unchanged; only the artificial
wall-clock wait is removed (Standing Rule: prefer fake timers over real time
waits). Isolated test-execution time drops ~21.7s -> ~15.0s (82 tests, all
green across repeated runs).
2026-08-10 17:50:26 -07:00
ischindl
8cba8d3e92 fix(core): make TaskStore.emit override assignable to EventEmitter<TaskStoreEvents> signature (#3407)
## Problem
Dashboard typecheck fails with **TS2416** in `@fusion/core`'s
`TaskStore`:

```
Property 'emit' in type 'TaskStore' is not assignable to the same property in base type 'EventEmitter<TaskStoreEvents>'.
```

The `override emit<E extends string | symbol>(event, ...args)` generic
conflicts with the base class's generic `emit<K>(eventName: keyof
TaskStoreEvents | K, ...)`. This breaks the dashboard typecheck / CI
merge gate.

## Fix
Change the override to:

```ts
override emit(event: unknown, ...args: any[]): boolean {
  return EventEmitter.prototype.emit.call(this, event as string, ...args);
}
```

`event: unknown` remains assignable to the base's generic signature
while still forwarding non-typed runtime keys (`agent:log`,
`settings:updated`, …). Internal `EventEmitter.prototype.emit` calls
cast `event as string`. Behavior-preserving.

## Verification
- `@fusion/dashboard` `tsc --noEmit` → **PASS** (previously failed with
TS2416)
- `eslint` on touched file → clean
- Single-file change (`packages/core/src/store.ts`, +6/−3)

## Scope
No behavior change, no changesets required.

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

* **Bug Fixes**
* Improved task event handling to support a broader range of event
identifiers.
* Preserved cached-lane information for single-argument task update
events.
* Maintained support for custom and arbitrary event names without
disrupting existing behavior.
* Improved classification of workflow roles, session purposes, and
outcome-related status checks in lifecycle analysis, producing more
accurate findings and reducing misleading results.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-10 14:10:26 -10:00
gsxdsm
3143f9536f FN-8908: auto-recover terminal task failures
Recover generic terminal task failures through a bounded, durable retry budget before escalating them to operators.

- add fenced task-store recovery claims, retries, budget resets, and audit events
- defer terminal-failure notifications until recovery is exhausted while preserving a single escalation
- expose operator retry budget reset and cover recovery lifecycle behavior

Files changed:
 .../fn-8908-terminal-failure-auto-recovery.md      |   7 +
 AGENTS.md                                          |   1 +
 docs/agents.md                                     |   2 +
 docs/architecture.md                               |   2 +
 packages/cli/src/commands/task.ts                  |   2 +
 packages/cli/src/extension.ts                      |   2 +
 ...terminal-failure-auto-recovery-store.pg.test.ts | 108 +++++++++
 .../terminal-failure-auto-recovery.test.ts         |  60 +++++
 packages/core/src/index.gate.ts                    |   1 +
 packages/core/src/index.ts                         |   1 +
 packages/core/src/store.ts                         | 179 ++++++++++++++-
 .../core/src/task-store/archive-lifecycle-2.ts     |  15 ++
 packages/core/src/task-store/moves.ts              |  48 +++-
 packages/core/src/task-store/persistence.ts        |  18 +-
 packages/core/src/task-store/project-store-ops.ts  |   4 +-
 .../src/task-store/workflow-task-create-ops.ts     |   4 +-
 packages/core/src/tasks/index.ts                   |   1 +
 .../src/tasks/terminal-failure-auto-recovery.ts    | 114 ++++++++++
 packages/core/src/types/task/task-core.ts          |  24 ++
 .../src/routes/register-task-workflow-routes.ts    |   2 +
 ...-healing-terminal-failure-auto-recovery.test.ts | 199 ++++++++++++++++
 .../__tests__/notification-service.test.ts         |  86 ++++++-
 .../__tests__/task-wedge-notification.test.ts      |   2 +-
 .../src/notification/notification-service.ts       | 103 +++++++--
 .../src/notification/task-wedge-notification.ts    |  30 ++-
 packages/engine/src/self-healing.ts                | 251 ++++++++++++++++++++-
 packages/engine/src/util/run-audit.ts              |   7 +
 27 files changed, 1240 insertions(+), 33 deletions(-)

Fusion-Task-Id: FN-8908

Fusion-Task-Lineage: 99e96b16-0306-41f1-87da-8623d69735f7

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 16:53:51 -07:00
gsxdsm
55fd20e5f8 fix(engine): bound spec-drift reconciliation so boot cannot exhaust the connection pool
Fusion wedged on "starting" and never brought the engine up. The dashboard bound
the migration holding server on 4040, then every query behind it failed with
"sorry, too many clients already", so the card never progressed and the
supervisor crash-looped.

Root cause: each spec-drift reconcile costs a DEDICATED PostgreSQL connection.
persist -> appendSpecDriftReport -> withPlanningLifecycleLock opens its own
postgres(directUrl, { max: 1 }) session, because the planning advisory lock is
session-scoped and deliberately fences a stale report against a newer plan.

enqueue() released every id straight into its own microtask, and project-engine
enqueues every task at runtime-boundary setup (listTasks includeArchived). On a
1,082-task project that opened ~1,082 lock sessions simultaneously against
max_connections = 500. The cluster saturated ~25s into boot and stayed saturated.

The flat 1s retry then made it self-sustaining rather than transient: once
saturated, every task failed for the same shared reason and re-armed in lockstep
once per second, re-opening the whole fleet of sessions and pinning the very
resource it was waiting on. Measured 4,777 lock sessions in 17 seconds.

Fix, contained to the reconciler — the advisory lock and its fencing semantics
are load-bearing and unchanged:
- concurrency bound (maxConcurrent, default 4) drained by a fair
  insertion-ordered pump, so fan-out can no longer exceed a known connection cost
- per-task in-flight dedupe; two passes on one task would contend on that task's
  own advisory lock while holding two connections
- exponential backoff with jitter capped at 60s, and retries re-enter through
  enqueue so a retry storm is bounded by the same limit as a first pass

Verified against the real 1,082-task project: connections stay flat at 3-10
across a 70s boot that previously reached 1,109 and saturated, and the engine
boots through to executing tasks and shuts down cleanly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 16:44:19 -07:00
gsxdsm
67cdb33a92 chore: gitignore the knowledge-graph build artifact
`.fusion-knowledge/` is `fn knowledge-graph build` output (FN-8920 memory epic):
~85MB of generated JSON, rewritten on every build. edges.json alone is 43MB,
past GitHub's 50MB warning threshold.

It is deterministic and fully regenerable from source — the manifest's SHA-256
fingerprints drive incremental rebuilds — so tracking it preserves nothing a
rebuild cannot reproduce, while adding irreversible, compounding history bloat to
every clone and CI checkout.

docs/knowledge-graph.md previously left this to the operator ("it is not
ignored"); that guidance is updated here so the doc and .gitignore agree. An
operator who explicitly wants a snapshot in history can still force one with
`git add -f .fusion-knowledge/graph`.

Nothing under the path was ever tracked, so no index purge is needed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 13:49:37 -07:00
gsxdsm
7b3bd75268 fix(engine): wire the Plan Review replan cap and tombstone its dead predecessor
Investigating the "dead cap" turned up the opposite of what it looked like, plus a
worse problem next to it.

The Plan Review replan loop was NOT unbounded. U3 re-owned the cap-park in the
graph: requestPreMergeOptionalStepFix parks via parkPlanReviewReplanCapExhausted
at awaiting-approval with reason plan-review-replan-cap, on both an explicit
finite budget and the unbounded default. That capability has been live throughout.

What was actually dead:

1. PLAN_REVIEW_GATE_REPLAN_CAP = 8 — an unread constant belonging to the
out-of-graph triage gate (runPlanReviewBeforeExecution) that U10/R4 deleted. Its
companion column Task.planReviewReplanCount was persisted, serialized and reset
but never incremented or compared. A constant and a column that look like a live
safety ceiling while enforcing nothing are worse than no ceiling: they answer "is
this loop bounded?" with a confident yes. Deleted, ratcheted in
legacy-tombstones.test.ts, and the column documented as legacy/never-written with
the live owner named.

2. planReviewReplanCap — an operator-facing setting, declared, validated,
documented in settings-reference.md and editable in the Workflow Editor, that
NOTHING read. Lowering it changed nothing. The unbounded backstop was instead
hardcoded to PLAN_REVIEW_FEEDBACK_HISTORY_LIMIT — a bound on how much reviewer
PROSE is replayed into the next planning prompt, whose own comment says it is
"bounded independently of persistence and retry accounting". Two unrelated
concerns shared one number, so trimming prompt history would have silently
tightened a safety ceiling.

The backstop now resolves from the setting, defaulting to the new
DEFAULT_PLAN_REVIEW_REPLAN_CAP = 15 — the previously-effective value, so this is a
pure re-wiring rather than a silent behavior change. The existing 15-attempt
regression test passes unchanged, which is the evidence for that. 0 is honored as
park-on-first-REVISE. An explicit planReviewMaxRevisions / node maxRevisions
budget remains a stricter, earlier gate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 13:39:55 -07:00
gsxdsm
c05d44d44a fix(engine): bound planning retries and cap the planning turn
Three changes to the triage planning path.

1. Unclassified planning failures are bounded. specifyTask's catch-all branch —
the one reached by every error the classifiers above do not recognize — restored
the card's claimable status and wrote nothing else: no counter, no
nextRecoveryAt, no park. Triage rediscovery re-admitted the card on the very next
poll, and replaceActiveTaskWorkflowContinuation replaced the terminal work item
with a fresh one carrying no attempt count, so nothing recorded that the task had
already failed N times. It now consumes the same recoveryRetryCount/nextRecoveryAt
budget the transient branch uses (MAX_RECOVERY_RETRIES = 3, 60s/120s/300s jittered
backoff) and parks status:"failed" with a PLANNING_FAILED_EXHAUSTED: error once
spent — status:"failed" is what suppresses rediscovery. Classifying one error
string fixes one symptom; this budget is what makes the NEXT unrecognized error
fail safely instead of looping for a day.

2. The planning turn has a ceiling. Fusion set no timeout on it at all:
workflowStepTimeoutMs covers pre-merge workflow steps only, and the provider SDK's
300s APIConnectionTimeoutError caps time-to-first-byte and is cleared once headers
arrive, after which the stream is uncapped. configureHttpDispatcher, which would
install undici idle timeouts, is only called from pi's CLI entrypoints and never
in the in-process engine. Observed consequence: single attempts ran to 126 minutes,
with failed-attempt durations spread smoothly from 1 to 126 min and no clustering —
the signature of nothing enforcing a bound. New workflow-native planningTimeoutMs
(default 90 min) aborts the session; the failure consumes one bounded attempt.

The default is deliberately generous rather than tight. Successful planning work
items measured over 7 days ran p50 12.7 / p90 39.5 / p99 105.7 minutes, so a
tighter bound would abort legitimate plans and pay for the restart — the churn
this work exists to remove. It bounds hung turns, not slow ones.

3. [event:task:moved] executor tracing dropped from log to debug. It fires on
every dispatch, rebound, requeue, archive and self-healing move across every task,
which made it the loudest line in engine output and buried operator-actionable
events. No test pins the level; the information remains at debug.

Also fixes a test break shipped in 963dba6f80: the review blocking-severity
settings landed inside BUILTIN_REVIEW_REVISION_SETTINGS, whose contents
builtin-workflow-settings-triage.test.ts asserts exactly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 13:27:10 -07:00
gsxdsm
e0af6ddd93 FN-8952: derive Quick Add Save smoke fixtures from locales
Keep 300px Quick Add Save browser smoke coverage synchronized with shipped translations.

- Derive board and list Save fixtures from supported locale catalogs.
- Escape fixture labels and reject missing Save translations.
- Add fast fixture parity, derivation, and escaping coverage.

Files changed:
 docs/testing.md                                    |   3 +
 .../__tests__/browser-layout-smoke-fixture.test.ts |  75 +++++++++++++-
 .../dashboard/scripts/browser-layout-smoke.mjs     | 110 ++++++++++++++-------
 3 files changed, 147 insertions(+), 41 deletions(-)

Fusion-Task-Id: FN-8952
Fusion-Task-Lineage: 31daec25-5d9a-43bb-9ccf-667702006e76
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 12:38:00 -07:00
gsxdsm
878db6dca7 FN-8951: repair script-test governance drift
Keep test-shard timing governance aligned with the current workspace and workflow seams.

- Add a safe timing-snapshot pruning mode with coverage.
- Align Todo plugin Vitest isolation and Docker dependency manifests.
- Refresh workflow reliability evidence and remove deleted test timings.

Files changed:
 Dockerfile                                         |  7 ++-
 docs/testing.md                                    |  9 ++-
 plugins/fusion-plugin-todos/vitest.config.ts       | 26 ++++++--
 scripts/__tests__/ci-test-shard-timings.test.mjs   | 71 ++++++++++++++++++++++
 scripts/ci-test-shard.mjs                          | 65 ++++++++++++++++++--
 .../lib/workflow-reliability-release-check.json    | 22 +++----
 scripts/test-timings.json                          | 21 -------
 7 files changed, 175 insertions(+), 46 deletions(-)

Fusion-Task-Id: FN-8951

Fusion-Task-Lineage: fbf7e79f-4cb2-43e2-9982-09f3f94de70d

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 12:09:20 -07:00
gsxdsm
81139dbbd0 fix(engine): classify provider request timeouts as transient
"Request timed out." is the literal default message of the Anthropic and OpenAI
SDKs' APIConnectionTimeoutError, surfaced to Fusion by checkSessionError after
pi-coding-agent exhausts its in-session retries. It matched none of the
connection-scoped timeout patterns, which deliberately excluded "general
timeouts", so it fell through to specifyTask's generic failure branch — the one
that restores status: null and writes no counter, no nextRecoveryAt, and no park.
Triage rediscovery then re-admitted the card on the very next poll, forever.

Measured before this change: 48 "Specification failed: Request timed out." events
across 10 tasks in 30 hours with zero backoff between attempts. FN-8950 alone
burned 8 consecutive attempts over ~8 hours and never reached implementation.
Across 2 days, 91 failed planning attempts averaged 33 minutes each — ~50 hours of
wall-clock producing nothing, 24% of all planning time.

Classifying these as transient routes them into the bounded recovery policy
(MAX_RECOVERY_RETRIES = 3, 60s/120s/300s jittered backoff) already used by the
connection-level patterns, so a provider blip costs three spaced retries instead
of an unbounded loop.

The pattern is anchored to "request timed out" rather than a bare timeout match:
agent log prose and verification output legitimately contain "timed out"
("BuildKit timed out", "stuck-kill unwind timeout"), and a broad pattern would
reclassify real permanent failures as retryable — the mistake the connection-only
rule was written to avoid. Regression tests pin both directions.

This does not affect model fallback, which pi decides internally and Fusion only
observes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 12:01:25 -07:00
gsxdsm
00ddafd5fe FN-8845: persist deterministic spec alignment
Persist approved-plan drift alignment on linked mission features.

- Store spec alignment across PostgreSQL and SQLite mission feature projections
- Reconcile and render durable alignment instead of browser-side task joins
- Preserve migration identities and cover drift persistence regressions

Files changed:
 docs/architecture.md                               |  2 +
 docs/missions.md                                   |  2 +-
 .../core/src/__tests__/planner/spec-lock.test.ts   |  1 +
 .../src/__tests__/postgres/schema-applier.test.ts  |  9 ++++-
 .../async-stores/async-mission-store-queries.ts    |  5 +++
 packages/core/src/missions/mission-store.ts        |  9 ++++-
 packages/core/src/missions/mission-types.ts        | 10 +++++
 packages/core/src/planner/spec-lock.ts             |  7 +++-
 .../0053_mission_feature_spec_alignment.sql        |  3 ++
 packages/core/src/postgres/schema-applier.ts       | 13 +++++-
 packages/core/src/postgres/schema/project.ts       |  2 +
 packages/dashboard/app/api/missions/missions.ts    |  2 +
 .../dashboard/app/components/MissionManager.tsx    | 40 ++++++------------
 packages/dashboard/app/components/mission-types.ts |  2 +
 .../src/__tests__/plan-approval-status.pg.test.ts  |  4 +-
 .../src/__tests__/mission-feature-sync.test.ts     | 37 ++++++++++++++++-
 .../src/__tests__/spec-drift-reconciler.test.ts    | 14 +++++++
 packages/engine/src/missions/mission-autopilot.ts  | 17 +++++---
 .../engine/src/missions/mission-feature-sync.ts    | 47 +++++++++++++++++++++-
 packages/engine/src/project-engine.ts              |  3 +-
 packages/engine/src/scheduler.ts                   | 40 +++++++++++-------
 packages/engine/src/spec-drift-reconciler.ts       |  5 +++
 22 files changed, 215 insertions(+), 59 deletions(-)

Fusion-Task-Id: FN-8845

Fusion-Task-Lineage: d4a30472-f1c3-41ba-a61b-3f2be1ad32ab

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-10 11:50:56 -07:00
gsxdsm
963dba6f80 feat: gate review verdicts on finding severity and preserve remediation sessions
Review remediation loops were the dominant cost of task wall-clock: over 14 days,
tasks with >=5 post-review fix rounds were 22% of tasks but consumed 78% of all
task active time, and 311 of 331 recorded findings were spec-internal-consistency
complaints that changed no delivered behavior.

Two causes compounded. Plan/Code Review remediation was unbounded by default, and
the review policy ordered a full re-derivation of the artifact after every edit
("distrust the edit ... fresh holistic pass"), so each round surfaced a fresh crop
of previously-acceptable observations as new blockers.

Make the already-persisted WorkflowReviewFinding.severity load-bearing instead of
decorative: a REVISE only blocks when it carries a finding at or above the review
kind's threshold (plan: P0+P1, code: P0). Non-blocking findings are still parsed,
persisted, and handed to the implementer as advisory notes in PROMPT.md. Fails
closed — a REVISE with no findings, or with any unclassified finding, still blocks,
so prose-only and custom reviewers keep full blocking power. The gate only ever
relaxes a verdict, never promotes one.

Reviewer prompts now request the structured findings schema (Plan Review emitted
none before), define severity by consequence as P0/P1/P2, omit nits entirely rather
than filing them as low-severity findings, and use an incremental re-review contract.
Remediation renders findings grouped by priority and sanctions an explicit decline
with rationale, so a disputed finding has a terminal state.

Also preserve the implementation session across a review bounce: sendTaskBackForFix
no longer nulls sessionFile when preserving resume state, and the executor's finally
no longer clears it on a review handoff. Remediation rounds continue the conversation
instead of re-reading the repo and re-deriving the change they just wrote. The resume
prompt now directs a PROMPT.md re-read, without which a resumed agent would never see
the new findings.

New per-workflow settings planReviewBlockingSeverity / codeReviewBlockingSeverity;
set either to "any" to restore the previous behavior.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 11:28:32 -07:00
gsxdsm
e6b6223d30 fix(engine): stop per-poll symbol-lock renewal log and activityLog spam
Renewal runs every poll for every implementation-column task with declared
symbols, and a lost lock never recovers by renewing — renewSymbolLocks reports
the same lost set on each pass, so the warning and its store.logEntry companion
repeated forever: log-pane spam plus unbounded activityLog growth for a stuck
task. The two error paths had the same shape on any persistent failure.

Extract the executor's suppression into a shared createRepeatSuppressedLog and
use it in both: first occurrence per task/signature logs at full level, repeats
drop to debug(), a changed lost set or error message logs again, and a clean
renewal clears the memo. The logEntry write is gated on the same decision.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 10:33:35 -07:00