Commit Graph

4110 Commits

Author SHA1 Message Date
Phil Larson
4d54cfea77 test(engine): repair extracted orphan-resume fixture (#3487)
## Summary
- observe the injected executor dispatch seam in the orphan-resume lane
test
- make the lane guard non-vacuous and cover every renamed non-WIP lane

## Test plan
- `corepack pnpm --filter @fusion/engine exec vitest run
src/__tests__/executor-resume-lanes-resolved.test.ts
--silent=passed-only --reporter=dot` (12 passed)
- `corepack pnpm --filter @fusion/engine typecheck`
2026-08-18 22:10:31 -07:00
gsxdsm
2556083b68 test: restore the four workspace-merge tests broken by a stale mock
project-engine.test.ts hand-writes a factory for ../merge/merger-ai.js, and
it had drifted from the module: WorkspaceMergeDispatchSupersededError was
missing. Production imports that class, so the merge-queue drain threw "No
<export> is defined on the mock" before the code under test ran — the four
Phase C hardening cases then failed on a resolved promise and an absent
updateTask call, for a reason unrelated to what they assert.

No product change. All 114 tests in the file pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 21:14:26 -07:00
gsxdsm
16e63462cc fix: audit fallout — tunnel port, orphaned dev processes, scrollback clear
Auditing for repeats of the `pnpm dev --tunnel` bugs turned up the same
mistakes elsewhere.

Remote tunnels assumed 4040. ProjectEngine's Cloudflare quick tunnel
hardcoded http://localhost:4040, so a dashboard on an explicit --port, a PORT
override, or runDashboard's EADDRINUSE rebind published a PUBLIC tunnel to
whatever else held 4040. The dashboard now records its bound port
(setLocalDashboardPort, from both runDashboard and headless serve) and the
tunnel reads it, keeping 4040 only as the pre-report default.
register-discovery-routes already derived its port from req.socket.localPort
and is untouched.

Stopping the dev wrapper orphaned everything it started. It installed no
signal handlers, so teardown only ran from the child's close handler:
signalling the wrapper left the dev server AND its cloudflared alive —
observed twice, four surviving processes each time, including a public
trycloudflare URL still serving a dev server believed to be down. Ctrl-C hid
it by signalling the whole process group.

SessionTerminal appended scrollback instead of clearing first, though the
server sends it as a separate frame precisely so the client can clear. Latent
today because every reattach builds a fresh xterm; a duplicated-history bug
the moment an in-place reconnect appears.

And BackupManager's centralDbPath is gone: written, never read, and a
leftover of the removed SQLite backup — the same class of stale artifact that
onboarding was using as evidence about a Postgres install.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 21:09:03 -07:00
gsxdsm
86950400c9 chore(release): v0.77.0-beta.2
Version bump via changesets.
2026-08-18 00:22:21 -07:00
ischindl
0540686599 fix(RUFU-073): thread a per-tick task workflow-selection cache through scheduler reads (#3470)
**Problem:** Scheduler was re-reading each task's
`task_workflow_selection` once per park-resolution (sweep, hold-release,
moved, unpause/wake), causing a nonstop PostgreSQL query storm (~232
idx_scan/s) on idle polling — a major engine CPU hot-spot.

**Fix:** Memoize the workflow selection per scheduler tick/event —
thread a shared, per-event selection cache through
`resolveWorkflowIrForTask` and all park-resolution handlers, then throw
it away. Each task resolves its parked columns with at most one read of
`task_workflow_selection` per tick. A selection write is always observed
on the next event's fresh cache (never a global/infinite LRU).

**Includes:** regression test asserting the once-per-tick read
invariant, performance changeset + per-tick-cache solution doc,
deploy+verify handoff script, and the parallel quarantine-ledger merge
(origin FN-9125 + RUFU-072 OOM entries both retained).

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

* **Performance Improvements**
* Reduced repeated workflow-selection reads during scheduler ticks and
related event processing.
* Improved scheduler and health API responsiveness through per-operation
caching and read deduplication.
* Preserved existing behavior, including retry handling for failed reads
and synchronous data-store support.

* **Documentation**
* Added architectural guidance covering workflow-selection performance,
caching behavior, and verification criteria.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Fusion <noreply@runfusion.ai>
2026-08-18 00:10:46 -07:00
gsxdsm
1da6375c68 fix(git): Fusion sets its own commit identity, per agent
Auto-merge did nothing on a fresh container: tasks reached in-review, the merge
began, and FN-001 sat at status:merging forever with no error in the UI. The
cause was that git could not commit at all — `git commit` in the container dies
with "Author identity unknown ... Please tell me who you are", because a
container has no git identity and Fusion was borrowing the environment's.

Only workspace-fence-ref.ts ever passed an explicit identity. The merge commits,
the merger's --amend, and the experiment git-ops all inherited whatever
user.name/user.email the host happened to have. The existing commitAuthor*
settings only added a Co-authored-by TRAILER; they never set the author.

resolveCommitIdentity (packages/engine/src/git-identity.ts) now resolves:
operator commitAuthor* settings > the acting agent > Fusion. An agent-derived
identity is `<Agent Name> (Fusion) <slug@agents.fusion.local>`, so history
attributes a change to the agent that made it instead of one anonymous bot, per
the operator's request.

Applied at mergerCommitEnv — the single env all eight merger commit sites share
— and via `-c user.name/-c user.email` for merger-ai and experiment git-ops,
which build their own argv and bypass that env. Author AND committer are pinned:
git fails on a missing committer just as hard as on a missing author.

`commitAuthorEnabled: false` returns undefined and restores ambient git config,
so an operator who wants commits authored as themselves keeps that.

Verified: 9 new helper tests, 95 engine auth+identity tests, pnpm test:gate green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 23:49:33 -07:00
gsxdsm
9eae6b9bc5 fix(auth): a provider's first-ever login silently saved nothing
Operator could not log in to Anthropic or Codex on a fresh container: every
attempt ended "Login did not complete. Please try again.", while the same
providers worked flawlessly on their long-lived native install.

FusionAuthStorage.modify() is the seam pi persists a COMPLETED LOGIN through
(Models.login -> credentials.modify(provider.id, ...) in pi-ai models.js:198).
It resolved its write target with `creating: false` and returned before invoking
the callback whenever the provider had no credential row yet:

    const target = this.resolveWriteTarget(provider, current, false);
    if (!target || !this.credential(target, current)) return { changed: false };

So a first login completed its browser flow, exchanged the code, took and
released the lock file, wrote NOTHING, and resolved as success — leaving the
dashboard poll to see authenticated:false and report the generic failure.

It reproduces only on a store with no existing row, which is why it looked
environment-specific: an install that has logged in before takes the same path
as a refresh over an existing row and is fine, while every new container, new
machine, or wiped ~/.fusion can never complete a first login for ANY provider.

Evidence from the operator's container: flow ended with err=None (pi resolved,
no error), nothing logged, auth.json still {}, the agent directory's mtime
bumped when the lock was taken and released while auth.json itself never
changed, and an API-key write — which goes through set(), not modify() — landed
immediately.

modify() now creates when absent and updates when present; a callback returning
undefined still writes nothing, so pi's refresh-bails-out behaviour is unchanged.

auth-storage-instances.test.ts asserted the old behaviour, grouping modify() with
remove/logout/removeInstance as "non-creating". The removal guarantees are kept;
the modify() assertion is inverted, because it encoded the defect.

Also surfaces the server's own loginError through a new describeLoginFailure()
helper instead of the generic sentence, so an OAuth state mismatch reads as the
stale-tab instruction it is. Writing its test caught a bad regex of mine:
`code.*expired` matched "OpenAI Codex ... token_expired", a different failure.

Verified: the new first-login test fails against the old `creating: false` and
passes with the fix; 86 engine auth tests, 238 dashboard auth/dialog tests, and
pnpm test:gate all pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 21:39:06 -07:00
gsxdsm
bb11e493f7 fix(auth): restore Codex login and promote outboard resize targets
Operator report from a containerized dashboard: OpenAI Codex login never opened
a browser window at all, and floating windows still needed the FN-8015 follow-up.

- pi's `AuthPrompt` is a discriminated union — text, secret, select, manual_code —
  and FusionAuthStorage.login's interaction shim flattened every variant into
  `onPrompt({message, placeholder})`, discarding `type` and a select's `options`.
  pi's Codex `login()` OPENS with `prompt({type:"select"})` (Browser vs Device
  code) before emitting any auth URL, so the dashboard answered the method picker
  with the promise that waits for a pasted code — input the UI never solicits,
  because nothing had been surfaced yet. The flow hung until the route's 30s
  kickoff timeout: "Login initiation timed out", no window. The route's
  onSelect/selectOauthOption has had the right answer since FN-5917, but the
  callback was dead code from the moment login moved to pi's ModelRuntime.
  Verified against a real container: the login endpoint now returns Codex's
  auth.openai.com URL in 0.03s instead of timing out after 30s.
- Promote FN-8766's outboard east/NE/SE resize targets from Task Detail to every
  desktop window. With FN-8015's body gutter deleted, a hosted scrollbar sits
  flush against the painted edge where those hit zones used to cover it (issue
  #2140); moving the targets outside the shell keeps it grabbable without
  insetting anything. That needs the host to stop clipping, so the body and its
  direct child inherit the corner radius — only 8 of ~30 callers set that
  themselves — and phones re-assert clipping since they hide every handle.
- Document the fixed OAuth callback ports (Anthropic 53692, Codex 1455) and
  PI_OAUTH_CALLBACK_HOST for Docker: without them the browser callback cannot
  reach the container's loopback listener, which is why subscription logins
  appeared to fail there.

Verified: 14989 dashboard tests, 58 engine auth-storage tests (4 new, covering
each prompt type), pnpm test:gate, eslint, and both typechecks all pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 17:38:26 -07:00
gsxdsm
2eae0b2507 feat: remove stuck-task tagging from the dashboard; fix liveness-ratchet scan path
Removes the dashboard's stuck-task tagging per operator request: the Stuck
card/status badges, stuck row styling, the footer Stuck segment and
stuckTaskCount stat, utils/taskStuck.ts, the isStuck agent-activity gate,
and the taskStuckTimeoutMs prop plumbing (App -> Board/Lane/Column/
WorktreeGroup/MainContent -> TaskCard/ListView/ExecutorStatusBar). Stuck-task
tests are deleted or reconciled. The taskStuckTimeoutMs setting and the
engine's recovery sweeps (including the stuck-killed status) are unchanged —
the setting is engine-side only now.

Also repoints the FN-6756 liveness-gate ratchet's facade scans at
executor/task-executor-session-facades.ts, where the wave20 extraction moved
hasLiveSessionSurface/clearPhantomExecutorBinding (the two pre-existing red
tests on main).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 15:47:43 -07:00
gsxdsm
5f29935056 fix: hold task checkouts through progress-preserving recovery rebounds
Ten self-healing rebounds passed preserveProgress without preserveWorktree, so
the reopen-into-planning move hook cleared task.worktree and the idle sweep
reaped the checkout (uncommitted work included) — the same loss mechanism as
the in-review branch-rebind incident. Those rebounds (stuck-loop park,
undeclared-column rehome, finalize-integrity blocks, stale-incomplete-review,
ghost-review, terminal-failure retry, legacy rehome, partial-progress) now pass
preserveWorktree: true; deliberate discards (branch proven merged, zero unique
commits, worktree already missing) carry an explicit worktree-discard-intended
marker.

A new static ratchet test requires every preserveProgress rebound in
self-healing.ts to either preserve the worktree or carry the marker.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 15:10:56 -07:00
ischindl
c84924b99a fix(RUFU-076): stop self-healing git storm on paused projects and bound repair sweeps (#3473)
**Problem:** Self-healing repeatedly spawned git children
(status/rev-parse/for-each-ref) for paused/idle projects on every sweep,
and certain repair sweeps ran unbounded — a spawn/git storm that spiked
CPU and I/O on the production host.

**Fix:** Bound self-healing git work for paused projects (skip/cooldown)
and cap the repair sweeps so the engine stops churning git processes
when there is nothing actionable. Includes in-process-runtime pause-gate
+ self-healing pause-storm regression tests.

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

## Summary by CodeRabbit

- **Bug Fixes**
- Paused projects no longer trigger Git-intensive self-healing
maintenance.
- Pause and unpause transitions now correctly stop and resume
maintenance scheduling.
  - Global and engine-level pauses are handled consistently.
- **Improvements**
- Active-project Git maintenance is limited to an hourly cadence,
reducing unnecessary activity.
- Merge-metadata recovery is capped at 25 items per cycle for more
predictable processing.
  - Database and filesystem housekeeping continues during pauses.
- **Documentation**
- Updated architecture and runtime documentation to describe pause-aware
maintenance behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-17 15:05:10 -07:00
gsxdsm
3e6eea5421 fix: preserve live worktree through in-review branch rebind and certify lifecycle hold
The in-review branch-rebind sweep unconditionally nulled task.worktree while
repairing a broken branch binding, making the checkout invisible to
scanIdleWorktrees' active set so the idle sweep reaped it — the reported
"worktree lost between review and in-progress" incident. The rebind now keeps
the pointer when the directory exists and is checked out on the rebound branch,
and the applied audit event records preservedWorktree.

Adds a reliability-lane certification suite pinning that worktree metadata and
the on-disk directory survive in-progress ↔ in-review transitions and
idle-in-review maintenance ticks, and that severed metadata is exactly what
makes a directory reap-eligible.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-17 14:37:49 -07:00
ischindl
5e95a930f3 fix(RUFU-075): safest scheduler queue/mission-store writes for minimal stores (#3472)
**Problem:** Scheduler writes assumed a full missionStore contract
(getSlice/getMilestone), aborting/pre-resolving mission reconciliation
when a minimal store or a genuine missing mission was present.

**Fix:** Resolve a missing `missionId` best-effort through
`missionStore.getSlice`/getMilestone when available, and make
reconciliation non-blocking — a partial missionStore must not gate the
completion advance. Includes scheduler + pre.json rebase resolution over
the latest origin.

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

## Summary by CodeRabbit

- **New Features**
  - Added Grok 4.6 to the model catalog.
- Added archive and restore views for mailbox messages and chat
conversations.
- Added manager evaluation tools for reviewing agents and follow-up
actions.
  - Updated the bundled Pi runtime.

- **Bug Fixes**
  - Improved Quick Add model searching and dropdown toggling.
  - Refined Quick Add merger labels and spacing.
- Recommendations now appear only for completed tasks with valid
recommendations.
- Improved scheduler resilience during mission updates and
reconciliation.

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

Co-authored-by: gsxdsm <gsxdsm@users.noreply.github.com>
2026-08-17 13:54:48 -07:00
ischindl
dc00bc386c fix(RUFU-078): close self-healing db-corruption test wedge stub gap (#3474)
**Problem:** The FN-8953 pending-wedge-notification reconciliation
called getActiveNotificationService() unconditionally at its top (to
read the wedge settle window), even against a healthy/empty notification
service — leaving a narrow test wedge where the service getter was
expected never to be called.

**Fix:** Guard `reconcilePendingWedgeNotifications` so the wedge
settle-window read does not fire against a healthy/empty notification
service, closing the stub gap and making the reconciliation
side-effect-free when idle.

Co-authored-by: Fusion <noreply@runfusion.ai>
2026-08-17 13:54:25 -07:00
gsxdsm
2b99b365de FN-9141: rescue plugin-runner tests and enforce quarantine lockstep
Rescue the plugin-runner suite before deletion while making quarantine records mechanically consistent.

- preserve logger assertions across worker-reused mock cleanup with a stable hoisted logger
- remove the rescued suite from the quarantine ledger and Vitest exclusion
- enforce ledger-to-exclude lockstep and cover missing or dangling quarantine entries
- document the reproduction evidence, rescue disposition, and strict checker behavior

Files changed:
 .../suite-only-flakes-observed-register.md         |  14 +-
 docs/testing.md                                    |  17 +-
 .../engine/src/__tests__/plugin-runner.test.ts     |  37 ++--
 packages/engine/vitest.config.ts                   |  14 +-
 scripts/__tests__/check-quarantine-ledger.test.mjs | 217 +++++++++---------
 scripts/__tests__/ci-test-shard-timings.test.mjs   |   5 +-
 scripts/check-quarantine-ledger.mjs                | 245 +++++++++++++--------
 scripts/lib/test-quarantine.json                   |  10 +-
 8 files changed, 314 insertions(+), 245 deletions(-)

Fusion-Task-Id: FN-9141

Fusion-Task-Lineage: 5b0549bf-3cc6-495e-bf99-a30a2dffb029

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-17 05:25:17 -07:00
Phil Larson
0159ef8784 fix: preserve gridlock notification cooldown (#3469)
## Summary
- preserve the gridlock notification wall-clock cooldown across
transient detector clears
- add a regression test for clear-then-rediscover behavior during the
cooldown
- document the cooldown contract and add a patch changeset

## Test plan
- `corepack pnpm --filter @fusion/engine exec vitest run
src/__tests__/notifier.test.ts --project=engine-default
--reporter=verbose -t 'suppresses the same gridlock after a transient
resolution during cooldown'`
- `corepack pnpm --filter @fusion/engine typecheck`
- `corepack pnpm build`
- `corepack pnpm changeset status --output
/tmp/fusion-gridlock-changeset-status.json`


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

- **Bug Fixes**
- Gridlock notifications now remain suppressed during the 15-minute
cooldown, even if the condition temporarily clears and reappears.
- Prevents repeated notifications caused by transient detector-state
changes.

- **Documentation**
- Updated gridlock notification behavior documentation to reflect the
persistent cooldown.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-16 17:46:23 -07:00
gsxdsm
1d7dd3e7b8 FN-9133: Use bounded PostgreSQL DDL for reliability fixtures
Reliability fixtures now manage PostgreSQL databases through owned, deadline-bounded maintenance connections.

- Replace psql child-process DDL with postgres.js maintenance clients and forced cleanup.
- Remove redundant pre-create drops and preserve idempotent teardown behavior.
- Add a live-connection cleanup contract test and document audit measurements and policy.

Files changed:
 .../postgres-reliability-helper-ddl-audit.md       | 48 +++++++++++
 docs/testing.md                                    |  2 +-
 packages/engine/package.json                       |  5 +-
 .../_helpers-pg-ddl-contract.pg.test.ts            | 66 +++++++++++++++
 .../__tests__/reliability-interactions/_helpers.ts | 93 +++++++++++++---------
 pnpm-lock.yaml                                     |  3 +
 6 files changed, 176 insertions(+), 41 deletions(-)

Fusion-Task-Id: FN-9133

Fusion-Task-Lineage: 5a7f511d-abb4-4468-a97a-04331f60d245

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-16 16:11:21 -07:00
gsxdsm
beb8ae67db FN-9125: document flake findings and quarantine plugin runner
Classify the suite-only failures by actual PostgreSQL dependency and preserve unresolved evidence for follow-up.

- Record non-reproduction results and assign PostgreSQL investigations to focused follow-up tasks.
- Quarantine the independent in-memory plugin runner test under the deletion ratchet.
- Document evidence requirements for future PostgreSQL flake diagnosis.

Files changed:
 .../suite-only-flakes-observed-register.md         | 32 ++++++++++++++++++++--
 docs/testing.md                                    |  4 +++
 packages/engine/vitest.config.ts                   | 10 +++++++
 scripts/lib/test-quarantine.json                   |  8 +++++-
 4 files changed, 51 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-9125

Fusion-Task-Lineage: 1dc80163-a0dc-4241-bab1-75a2cafb9abe

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-16 11:46:39 -07:00
gsxdsm
7380be699c chore(release): v0.77.0-beta.1
Version bump via changesets.
2026-08-16 08:39:57 -07:00
gsxdsm
821e036c9d fix: route all AI lanes through runtime resolution so CLI-runtime models work everywhere
createFnAgent now delegates to createResolvedAgentSession — deriving the CLI
runtime hint (cursor/claude/grok/omp/hermes), mock/test-mode forcing, and
session:runtime-resolved visibility — using a host-registered default
PluginRunner keyed by project root (published by InProcessRuntime at plugin
init). DefaultPiRuntime re-enters via a __rawPiSession marker so the seam's
own pi bridge cannot recurse, and the raw constructor survives as
createPiAgentSessionRaw for that bridge and pi-internal tests.

Mission and milestone/slice interviews additionally pass their request-scoped
pluginRunner through the seam and prompt via the engine promptWithFallback
dispatcher (plugin CLI runtime sessions have no session.prompt()). This fixes
"Configured model cursor-cli/auto ... was not found in the pi model registry"
in mission planning while chat on the same model worked, and closes the same
gap for every remaining bare createFnAgent lane.

Also updates the pi skill-filtering test that still asserted pre-FN-9114
allow-list narrowing; requested skill names are ensure-present since FN-9114.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-16 08:32:46 -07:00
gsxdsm
dd1e0f22e1 chore(release): v0.77.0-beta.0
Version bump via changesets.
2026-08-16 00:32:50 -07:00
gsxdsm
20c9e66932 test(engine): reconcile merge durable-write inventory drift
The FN-8923 drift guard was red on main: the fixture predated the FN-9047-9062
workspace wave and regeneration was blocked by 18 unclassified workspace
TaskStore methods. Classify the FN-9059 workspace coordination surface (lease
acquire/renew/release/reclaim/reconcile, land-intent record/resolve, fence-ref
recording, mergeWorkspaceWorktreeEntry, withValidWorkspaceLease as writers; the
inspect/list/find/validate reads as non-writers), regenerate the manifest, and
supply lifecycle verdicts for the 13 new call sites: lease/intent writes in the
land path are already-fenced by FN-9059 store-seam fence-token validation, the
land-failure note is benign-unfenced bookkeeping, and the remaining sites carry
their enclosing symbols' out-of-frontier verdicts. Also drops the deleted
diff-volume gate module from scannedModules.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 22:42:51 -07:00
gsxdsm
87e673baf7 feat(merge): remove the pre-commit diff-volume gate
The gate blocked approved clean-room squashes on per-file shrinkage with no
override path ("AI merge diff-volume gate blocked the approved squash").
Removed by operator decision: delete checkDiffVolume/DiffVolumeRegressionError,
the merge:diff-volume-blocked audit event, the runDiffVolumeGate call sites in
every legacy squash finalizer, the AI-merge pre-land check, and the
mergeDiffVolume* settings. File scope remains the pre-land guard; the
post-squash audit policy remains the shrinkage backstop.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 22:42:39 -07:00
gsxdsm
9f5f981e33 FN-9114: expose enabled skills and enforce agent skill reads
Make project-enabled skills available across agent sessions while preserving explicit per-agent skills as observable read-first requirements.

- resolve all enabled discovered skills without using agent metadata as an availability filter
- carry forced skill intent through PI, plugin, chat, workflow, merger, and heartbeat session paths
- report resolved and unavailable forced skills in session summaries and diagnostics
- document the updated skill model and add release notes and regression coverage

Files changed:
 .changeset/fn-9114-forced-skills.md                |   7 +
 docs/PLUGIN_AUTHORING.md                           |   2 +-
 docs/agents.md                                     |  10 +-
 docs/diagnostics.md                                |   2 +-
 docs/settings-reference.md                         |   2 +-
 packages/core/src/__tests__/skill-settings.test.ts |   9 +
 .../dashboard/src/__tests__/chat-manager.test.ts   |  26 ++-
 packages/dashboard/src/chat.ts                     |  10 +
 .../engine/src/__tests__/agent-skills-flow.test.ts |  14 +-
 .../compound-engineering-skill-resolution.test.ts  |   2 +-
 .../engine/src/__tests__/heartbeat-skills.test.ts  |  41 ++++
 .../__tests__/hermes-runtime-integration.test.ts   |  63 +++++-
 .../engine/src/__tests__/merger-skills.test.ts     |  33 ++-
 packages/engine/src/__tests__/pi.test.ts           |  35 ++-
 .../__tests__/plugin-skill-body-delivery.test.ts   |   8 +-
 .../src/__tests__/plugin-skill-integration.test.ts |   3 +-
 .../src/__tests__/session-skill-context.test.ts    |  40 ++--
 .../engine/src/__tests__/skill-resolver.test.ts    |  38 +++-
 .../__tests__/step-execute-skill-loading.test.ts   |   6 +
 packages/engine/src/agents/agent-runtime.ts        |   2 +
 .../engine/src/agents/agent-session-helpers.ts     |  88 ++++++-
 .../src/cli-runtime/session-skill-context.ts       | 117 ++++------
 packages/engine/src/cli-runtime/skill-resolver.ts  | 252 +++++++++------------
 .../engine/src/executor/execute-workflow-step.ts   |  14 ++
 packages/engine/src/executor/run-implementation.ts |   5 +
 packages/engine/src/pi.ts                          |  28 ++-
 26 files changed, 576 insertions(+), 281 deletions(-)

Fusion-Task-Id: FN-9114

Fusion-Task-Lineage: fe63ebd1-f947-40d7-be7b-c13d7f1c35c9

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 21:57:22 -07:00
flexi767
086cd0a505 fix(engine): retry transient post-merge push failures (#3468)
## What

- Retry post-merge target pushes after recognized transient Git
transport failures.
- Use a bounded schedule: the initial attempt plus two retries after 2s
and 5s.
- Apply the same helper to the unified fast path and the shared push
path used by divergence recovery and the soft-deprecated merger.
- Keep retry sleeps and subsequent attempts cancellation-aware.
- Add a patch changeset and regression coverage, including a real bare
remote that rejects the first push.

## Why

Fusion already retries non-fast-forward races, and #1942 made terminal
push failures durable, but a temporary network failure still ended
post-merge delivery after one attempt. That can leave the local
integration branch ahead of the remote even though retrying seconds
later would succeed.

The retry is deliberately provider-neutral. It uses Git error
classification and normal Fusion logs only; it does not add Telegram,
OpenClaw, or any other notification-vendor dependency.

## Behavior and impact

- Retries only transient transport signatures such as connection resets,
DNS failures, unreachable networks, selected HTTP 429/5xx RPC failures,
and unexpected disconnects.
- Permission, authentication, configuration, and ref-rejection errors
keep their existing immediate handling.
- Exhausted retries remain non-fatal to the already-landed merge and
flow through the existing audit/task-log failure reporting.
- Existing non-fast-forward pull/rebase recovery is unchanged apart from
making its backoff cancellation-aware.

## Checks

- [x] `pnpm --filter @fusion/engine exec vitest run
src/__tests__/merger-ai-push-after-merge.test.ts
src/__tests__/merger-prompt-and-utils.test.ts --silent=passed-only
--reporter=dot` (48 tests)
- [x] `pnpm --filter @fusion/engine typecheck`
- [x] `pnpm lint` (0 errors; 2 pre-existing warnings)
- [x] `pnpm check:changesets --strict`
- [x] `pnpm check:fnxc-future-dates`
- [x] `pnpm test` (changed-test gate; static checks and 688 tests
passed)


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

* **Bug Fixes**
* Improved reliability of post-merge pushes by retrying temporary Git
transport failures.
* Added bounded backoff between retries to prevent excessive repeated
attempts.
  * Push retries now stop promptly when an operation is canceled.
* Configuration, authentication, and ref-rejection errors continue to
fail immediately.
* Successful retries and canceled operations now report accurate
outcomes.
* **Tests**
* Added coverage for successful retries, cancellation, and non-retryable
failures.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: flexi767 <flexi767@users.noreply.github.com>
Co-authored-by: v <v@m5.speedport.ip>
2026-08-15 21:42:01 -07:00
gsxdsm
2a9ae0aca3 FN-9109: add resilient cross-runtime Cursor fallback
Route eligible CLI fallback failures into one bounded, auditable Cursor runtime handoff.

- defer cursor-cli fallback selection until a retryable primary prompt failure
- serialize concurrent swaps, retry the primary after failed handoffs, and dispose replacements safely
- transfer text-only conversation context within strict turn and total character limits
- document routing behavior and cover provider, runtime, concurrency, and failure cases

Files changed:
 .../fn-9109-cross-runtime-cursor-fallback.md       |   7 +
 AGENTS.md                                          |   2 +
 docs/cursor-cli-contract.md                        |   8 +
 .../src/__tests__/cli-provider-routing.test.ts     |  18 +-
 .../cli-runtime-routing-conformance.test.ts        |  64 ++++-
 .../src/__tests__/cross-runtime-fallback.test.ts   | 146 +++++++++++
 .../engine/src/agents/agent-session-helpers.ts     | 211 ++++++----------
 packages/engine/src/agents/cli-provider-routing.ts |   4 +-
 .../engine/src/agents/cross-runtime-fallback.ts    | 277 +++++++++++++++++++++
 packages/engine/src/util/run-audit.ts              |   8 +
 10 files changed, 602 insertions(+), 143 deletions(-)

Fusion-Task-Id: FN-9109

Fusion-Task-Lineage: 30664371-8410-4d6f-a263-cc86c8e0dc72

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 19:10:55 -07:00
gsxdsm
66bbeaa28d FN-9108: Restore routed workflow-principal session identity
Restore routed principal attribution throughout workflow prompt and review sessions.

- Thread the graph-selected principal into workflow-step execution.
- Resolve principal runtime configuration, skills, telemetry, and session attribution consistently.
- Fail closed when the routed principal is unavailable and add regression coverage.
- Add a patch changeset for the restored behavior.

Files changed:
 .../fn-9108-workflow-principal-session-identity.md |   7 +
 .../executor-workflow-step-principal.test.ts       | 154 +++++++++++++++++++++
 .../engine/src/executor/execute-workflow-step.ts   |  34 ++++-
 .../engine/src/executor/run-graph-custom-node.ts   |  11 +-
 4 files changed, 198 insertions(+), 8 deletions(-)

Fusion-Task-Id: FN-9108

Fusion-Task-Lineage: ec668551-8ff4-4ced-8c7f-a4aa04eb044f

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 17:45:32 -07:00
Phil Larson
81b1860f95 fix(ci): correct future FNXC stamps (#3440)
## Summary
- replaces newly added future-dated FNXC metadata with the actual UTC
change time
- tightens the FNXC future-date baseline to zero known exceptions

## Test plan
- `pnpm check:fnxc-future-dates`
- `pnpm check:lifecycle-columns`
- `pnpm check:changesets`
- `pnpm --filter @runfusion/fusion exec vitest run
src/__tests__/staged-plugin-core-imports.test.ts --silent=passed-only
--reporter=dot`
- `pnpm --filter @fusion/engine typecheck`
- `pnpm lint`
2026-08-15 17:16:05 -07:00
gsxdsm
802a4249fb FN-9106: Route non-continuable step sessions through retry recovery
Recover poisoned step-session transcripts before the generic failure sink can retain them.

- Apply bounded fresh-session recovery to incomplete step-session execution failures.
- Preserve completed-work handling ahead of retry classification.
- Add regression coverage and production-shaped executor fixtures.
- Document the published patch behavior in a changeset.

Files changed:
 .changeset/fn-9106-non-continuable-step-session.md |  7 ++++
 .../post-done-continuation-no-wedge.test.ts        | 48 +++++++++++++++++++++-
 packages/engine/src/executor/run-implementation.ts | 11 +++++
 3 files changed, 65 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-9106

Fusion-Task-Lineage: 537ea415-96dd-4b66-ab5d-84dc4603388b

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 17:13:20 -07:00
gsxdsm
43a42d8b7b FN-9107: preserve mission completion triggers after reconciliation failures
Keep scheduler mission completion handling active when best-effort reconciliation fails.

- isolate pre- and post-resolution reconciliation failures without suppressing mission execution
- cover custom completion columns, failed in-place updates, fallback behavior, and slice guards
- document the resilience contract and add a patch changeset

Files changed:
 .changeset/fn-9107-mission-trigger.md              |   7 +
 docs/missions.md                                   |   2 +-
 .../mission-validation-trigger-gap.test.ts         |  40 ++++--
 .../scheduler-mission-move-trigger.test.ts         | 153 +++++++++++++++++++++
 packages/engine/src/scheduler.ts                   |  20 ++-
 5 files changed, 203 insertions(+), 19 deletions(-)

Fusion-Task-Id: FN-9107

Fusion-Task-Lineage: a492d0c0-79ca-4dba-a7bc-c8fa54415f28

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 17:06:39 -07:00
gsxdsm
5e5b0dbb8f FN-9098: bridge scoped Fusion tools into Cursor
Publish engine-owned Fusion tools to Cursor through a crash-safe, worktree-scoped MCP bridge.

- preserve operator MCP configuration with locking, journaling, quarantine, and lease reconciliation
- enforce identity-scoped fn_* provenance so injected custom and MCP tools are never exposed
- secure loopback dispatch with per-session tokens, heartbeats, cleanup, and normalized tool events
- document the Cursor contract and cover bridge lifecycle, config hygiene, and failure handling

Files changed:
 .changeset/fn-9098-cursor-mcp-bridge.md            |   7 +
 docs/cursor-cli-contract.md                        | 140 ++-------------
 docs/mcp.md                                        |   4 +
 .../src/__tests__/agent-session-helpers.test.ts    |  24 +++
 .../src/__tests__/step-session-executor.test.ts    |  16 ++
 .../src/__tests__/web-fetch-universal.test.ts      |   4 +-
 packages/engine/src/agent-heartbeat.ts             |   3 +-
 packages/engine/src/agents/agent-runtime.ts        |   9 +
 .../engine/src/agents/agent-session-helpers.ts     |  26 +--
 packages/engine/src/execution/reviewer.ts          |   1 +
 .../engine/src/execution/step-session-executor.ts  |  31 ++--
 .../engine/src/executor/execute-workflow-step.ts   |   4 +-
 packages/engine/src/merger.ts                      |   4 +-
 plugins/fusion-plugin-cursor-runtime/README.md     |  18 +-
 plugins/fusion-plugin-cursor-runtime/package.json  |   2 +-
 .../src/__tests__/cursor-mcp-config.test.ts        | 100 +++++++++++
 .../cursor-mcp-server-failure.stream.jsonl         |   3 +
 .../fixtures/cursor-mcp-tool-call.stream.jsonl     |   4 +
 .../src/__tests__/runtime-adapter.test.ts          |  57 +++++-
 .../src/__tests__/worktree-hygiene.test.ts         |  52 ++++++
 .../src/cursor-mcp-config.ts                       | 196 +++++++++++++++++++++
 .../src/mcp-schema-server.cjs                      | 155 ++++++++++++++++
 .../src/prompt-transport.ts                        |   4 +-
 .../src/runtime-adapter.ts                         |  67 +++++--
 .../src/tool-bridge.ts                             |  48 +++++
 .../src/tool-mapping.ts                            |  11 ++
 plugins/fusion-plugin-cursor-runtime/src/types.ts  |   6 +-
 .../src/worktree-hygiene.ts                        | 117 ++++++++++++
 28 files changed, 934 insertions(+), 179 deletions(-)

Fusion-Task-Id: FN-9098

Fusion-Task-Lineage: 11b6cb10-ce0e-4f33-9007-c83f2bbf82ea

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 16:51:54 -07:00
gsxdsm
56a087dac9 fix(engine): restore shipped behaviors dropped by the wave-18 executor peel
Full-suite repair, engine harness cluster (~85 red suites). Two causes:
(1) graph dispatch now fails closed without options.agentStore
(FN-8764/FN-8821, intended) — the shared executor test harness now
provisions the workflow-routing agent-store fixture for bare
TaskExecutor constructions, with explicit opt-out for the two tests
asserting the fail-closed park; (2) the wave-18 'pure peel' (#3317)
rebuilt executor.ts from a stale base and silently deleted shipped
behaviors, restored here: FN-8864 agent-activity writers (task
started/handed-off, workflow gate pass/fail, gate principal attribution
via executor/workflow-gate-activity.ts), FN-8768 Plan Review group
recognition, convergence primer, and modified-file review scoping,
FN-6782's fire-time guard on transient resume-after-restart retries,
FN-8868 session usage telemetry boundaries, recommendation-route
withheld-tool guidance, and the per-instance worktree retry cap.
Stale expectations updated for intended changes (FN-8823 shared-member
hold, FN-9060 zero-acquire fail-closed, heartbeat tool inventory,
peeled-module seams, PG harness provisioning). Verified: 23 files /
711 tests green, engine typecheck clean, merge gate green.

Known follow-ups (not addressed here): step-session error routing may
still bypass FN-5866 non-continuable classification
(post-done-continuation-no-wedge red), scheduler mission-loop trigger
gap (mission-validation-trigger-gap red), and executeWorkflowStep lost
routed workflow-principal session identity threading (untested drop
from the same peel).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 15:52:52 -07:00
gsxdsm
374ae08d56 test(engine): repoint source-scan contracts to the peeled module layout
Full-suite repair, engine source-scan cluster. The package code
organization waves moved ~30 engine modules into subdirectories
(plugins/, execution/, scheduling/, healing/, worktree/, executor/
peels); the log-severity manifest, prompt carve-out, emit-surface,
failure-lane, and worktree-invariant scanners now read the moved
locations, verified per file via git log --follow. Two scans caught
real drift rather than moves: the lifecycle census had 12 unexamined
column guards (resolved with DELIBERATE-LITERAL markers for the mailbox
archived tab, the FN-9059 lease-owner terminality check, and the FN-9056
legacy done fallback — baseline re-recorded with zero absorbed debt),
and planning-claim gained a genuine second writer in self-healing's
FN-8998 transport-failure recovery, admitted to the allowlist with its
CAS-guarded justification. 9 files / 119 tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 15:31:58 -07:00
gsxdsm
6a2de64381 fix: normalize Anthropic storage ids at the ModelRuntime.login choke point
Third incident of the same class (#1857/FN-7391, FN-9101, GitHub #3462):
Fusion's Anthropic auth-card/storage ids (anthropic-subscription,
anthropic-api-key) leaking into pi, which only registers the execution
provider 'anthropic'. FusionAuthStorage.login is the single seam that hands
a provider id to ModelRuntime.login; it now normalizes via
toExecutionModelProviderId so a future caller bug degrades to a correct
upstream anthropic login instead of a hard 'Unknown provider' failure, with
a regression test pinning the seam. The invariant, incident history, and
guard inventory are captured in
docs/solutions/integration-issues/anthropic-storage-ids-are-never-pi-provider-ids.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 14:52:38 -07:00
gsxdsm
7fa5029ef8 fix: route Anthropic subscription instance login through upstream anthropic provider
The Authentication cards pass an explicit credential-instance id, which sent
dashboard subscription logins through loginInstance. That seam mapped the card
to the anthropic-subscription storage row id and passed it verbatim to
ModelRuntime.login, which pi rejects with 'Unknown provider:
anthropic-subscription' (GitHub #3462) — every subscription login failed while
the credential path itself was healthy. loginInstance now reuses the
Anthropic-aware login seam (upstream login as 'anthropic', credential relocated
to the anthropic-subscription row) with a regression test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 14:48:07 -07:00
gsxdsm
6401fdea89 FN-9101: normalize Anthropic auth provider selections
Route Anthropic subscription and API-key auth selections through the built-in execution provider.

- Add a shared provider-ID normalization helper and export it from core.
- Normalize persisted model selections during session creation and registry lookup.
- Hide credential-only Anthropic provider rows from the dashboard model catalog.
- Add regression coverage and a patch changeset for subscription-backed execution.

Files changed:
 ...9101-anthropic-subscription-model-resolution.md |  7 ++++
 .../__tests__/anthropic-execution-provider.test.ts | 18 ++++++++
 packages/core/src/ai/anthropic-models.ts           | 13 ++++++
 packages/core/src/index.gate.ts                    |  2 +
 packages/core/src/index.ts                         |  2 +
 .../dashboard/src/__tests__/routes-auth.test.ts    |  2 +
 .../dashboard/src/routes/register-model-routes.ts  | 14 ++++---
 ...-session-helpers-anthropic-subscription.test.ts | 49 ++++++++++++++++++++++
 .../src/__tests__/pi-create-fn-agent.test.ts       | 25 +++++++++++
 .../engine/src/agents/agent-session-helpers.ts     | 26 ++++++++----
 packages/engine/src/pi.ts                          | 14 +++++--
 11 files changed, 154 insertions(+), 18 deletions(-)

Fusion-Task-Id: FN-9101

Fusion-Task-Lineage: 72e70e67-b291-44fc-ba3f-12b54d06eba9

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 14:19:23 -07:00
gsxdsm
b6efd89ae5 FN-9097: add Cursor CLI execution runtime
Add a supervised Cursor CLI runtime for routed Cursor model sessions.

- Stream Cursor prompt output into Fusion session callbacks with resume support.
- Support Windows Cursor shims, inactivity-based supervision, and cursor-agent to cursor fallback execution.
- Route Cursor CLI models through the bundled plugin and document the runtime contract.

Files changed:
 .changeset/fn-9097-cursor-cli-runtime.md           |   7 ++
 docs/cursor-cli-contract.md                        |  21 ++++
 docs/settings-reference.md                         |   4 +-
 .../cli-runtime-routing-conformance.test.ts        |  11 +-
 .../engine/src/agents/agent-session-helpers.ts     |   6 +-
 packages/engine/src/agents/cli-provider-routing.ts |  27 ++---
 plugins/fusion-plugin-cursor-runtime/README.md     |  21 ++++
 plugins/fusion-plugin-cursor-runtime/package.json  |   1 +
 .../src/__tests__/cli-spawn.test.ts                |  25 ++++-
 .../src/__tests__/prompt-transport.test.ts         |  58 ++++++++++
 .../src/__tests__/runtime-adapter.test.ts          |  44 +++++---
 .../src/__tests__/stream-parser.test.ts            |  12 +++
 .../fusion-plugin-cursor-runtime/src/cli-spawn.ts  |  57 +++++++++-
 plugins/fusion-plugin-cursor-runtime/src/index.ts  |   4 +-
 .../src/prompt-transport.ts                        | 120 +++++++++++++++++++++
 .../src/runtime-adapter.ts                         |  59 ++++++----
 .../src/stream-parser.ts                           |  43 ++++++++
 plugins/fusion-plugin-cursor-runtime/src/types.ts  |  18 ++--
 pnpm-lock.yaml                                     |   3 +
 19 files changed, 458 insertions(+), 83 deletions(-)

Fusion-Task-Id: FN-9097

Fusion-Task-Lineage: a4eed861-6059-4528-9f80-3426f5ccad58

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 08:51:35 -07:00
gsxdsm
1d3f6c198c FN-9096: route CLI models through installed runtimes
Route every CLI-provider selection through an explicit installed-runtime policy.

- Centralize CLI provider classifications, runtime hints, fallback behavior, and actionable missing-runtime errors.
- Validate routing coverage statically and add conformance and integration tests for CLI runtime paths.
- Document runtime routing behavior and add a published CLI changeset.

Files changed: .changeset/fn-9096-cli-runtime-routing.md          |   7 +
 docs/settings-reference.md                         |  29 +++
 docs/testing.md                                    |   6 +-
 package.json                                       |   6 +-
 .../src/__tests__/cli-provider-routing.test.ts     |  74 ++++++++
 .../__tests__/cli-runtime-routing-check.test.ts    |  25 +++
 .../cli-runtime-routing-conformance.test.ts        | 210 +++++++++++++++++++++
 .../__tests__/hermes-runtime-integration.test.ts   |  28 +++
 .../engine/src/agents/agent-session-helpers.ts     | 166 ++++------------
 packages/engine/src/agents/cli-provider-routing.ts | 174 +++++++++++++++++
 scripts/check-cli-runtime-routing.mjs              |  26 +++
 scripts/lib/cli-runtime-routing-check.mjs          |  84 +++++++++
 12 files changed, 701 insertions(+), 134 deletions(-)

Fusion-Task-Id: FN-9096

Fusion-Task-Lineage: f9f6a434-b28d-4ebb-816a-53ca75efc2c4

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 07:19:29 -07:00
gsxdsm
8d8ea26cb2 FN-9094: omit unsupported Grok auto-update flag
Align Grok ACP expectations with the released CLI contract.

- Update runtime routing and adapter assertions to omit --no-auto-update by default.
- Cover explicit false and default argument behavior in ACP settings tests.
- Document the released CLI incompatibility and opt-in escape hatch.

Files changed:
 docs/grok-cli-contract.md                                  |  7 ++++---
 packages/engine/src/__tests__/grok-runtime-routing.test.ts | 14 +++++++++-----
 .../src/__tests__/acp-settings.test.ts                     |  2 ++
 .../src/__tests__/runtime-adapter.test.ts                  | 14 ++++++++++----
 4 files changed, 25 insertions(+), 12 deletions(-)

Fusion-Task-Id: FN-9094

Fusion-Task-Lineage: f776e401-8473-45b2-a8b2-8d8251b4713e

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 05:58:36 -07:00
gsxdsm
9fa8b386ee FN-9059: add durable workspace coordination leases
Prevent overlapping multi-node workspace operations and duplicate repository landings.

- Add durable coordination leases, fence tokens, and land-intent persistence.
- Fence workspace merge dispatches and repository publication across engine nodes.
- Reconcile expired coordination state safely and cover lease lifecycle behavior.

Files changed:
 .../fn-9059-workspace-durable-coordination.md      |   7 +
 AGENTS.md                                          |   1 +
 docs/architecture.md                               |   2 +
 docs/multi-project.md                              |  48 ++++
 .../workspace-coordination-leases.pg.test.ts       |  56 ++++
 .../__tests__/postgres/workspace-leases.pg.test.ts | 112 ++++++++
 packages/core/src/engine-node-identity.ts          |  22 ++
 packages/core/src/index.ts                         |   3 +
 .../0060_fn_9059_workspace_coordination_leases.sql |  10 +
 packages/core/src/postgres/schema-applier.ts       |  13 +-
 packages/core/src/postgres/schema/project.ts       |  31 ++
 packages/core/src/store.ts                         |  18 ++
 packages/core/src/task-store/workspace-leases.ts   | 261 +++++++++++++++++
 packages/core/src/tasks/workspace-lease-types.ts   |  24 ++
 .../engine/src/__tests__/project-engine.test.ts    |  69 ++++-
 .../src/__tests__/self-healing-workspace.test.ts   |  63 ++++-
 .../workspace-durable-coordination.test.ts         |  49 ++++
 .../src/__tests__/workspace-merger-lease.test.ts   | 312 ++++++++++++++++++++-
 packages/engine/src/merge/merger-ai.ts             | 277 ++++++++++++++++--
 packages/engine/src/merge/workspace-fence-ref.ts   | 171 +++++++++++
 packages/engine/src/project-engine.ts              | 175 ++++++++++--
 packages/engine/src/runtimes/in-process-runtime.ts |   4 +-
 packages/engine/src/self-healing.ts                | 191 ++++++++++++-
 packages/engine/src/util/run-audit.ts              |   2 +
 .../engine/src/worktree/worktree-acquisition.ts    |  43 ++-
 25 files changed, 1901 insertions(+), 63 deletions(-)

Fusion-Task-Id: FN-9059

Fusion-Task-Lineage: e51e3f54-69ee-4337-a218-4895d87474aa

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 03:22:13 -07:00
gsxdsm
2f99a8fb59 FN-9052: add atomic workspace worktree entry merges
Serialize per-repository workspace worktree state updates across concurrent Fusion processes.

- Add advisory-locked store-level per-entry workspace worktree merges.
- Route acquisition, landing, failure, and recovery updates through atomic merges.
- Cover concurrent sibling repository writes and document the invariant.

Files changed:
 .../fn-9052-workspace-worktree-atomic-merge.md     |  7 ++
 docs/architecture.md                               |  1 +
 ...workspace-worktrees-concurrent-merge.pg.test.ts | 90 ++++++++++++++++++++++
 packages/core/src/store.ts                         | 10 ++-
 packages/core/src/task-store/task-mutation-ops.ts  | 52 ++++++++++++-
 packages/core/src/types.ts                         |  2 +
 packages/core/src/types/task/task-core.ts          | 17 +++-
 .../merge-orphan-body-durable-writes.test.ts       |  8 ++
 .../src/__tests__/self-healing-workspace.test.ts   | 49 +++++++++---
 .../src/__tests__/workspace-merger-lease.test.ts   | 12 +++
 .../engine/src/__tests__/workspace-merger.test.ts  | 12 +--
 .../worktree-acquisition-workspace.test.ts         | 82 +++++++++++++++++++-
 packages/engine/src/merge/merger-ai.ts             | 21 ++---
 .../engine/src/merge/workspace-land-failure.ts     | 19 +++--
 packages/engine/src/self-healing.ts                | 15 +++-
 .../engine/src/worktree/worktree-acquisition.ts    | 25 +++---
 16 files changed, 370 insertions(+), 52 deletions(-)

Fusion-Task-Id: FN-9052

Fusion-Task-Lineage: 2168085a-74a7-4a0f-954e-50db99eb98b7

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 01:14:43 -07:00
gsxdsm
7bb7d450e6 FN-9062: surface workspace repository land status
Expose per-repository workspace landing progress and failures in Task Detail.

- Persist display-only repository land failure breadcrumbs during merge and recovery
- Render landed, pending, and failed repository statuses with partial-land detail
- Document the workspace status behavior and add coverage for UI and recovery paths

Files changed:
 .changeset/fn-9062-workspace-land-status.md        |   7 ++
 docs/dashboard-guide.md                            |   4 +
 packages/core/src/types/task/task-core.ts          |  11 ++-
 .../dashboard/app/components/TaskDetailModal.css   |  33 +++++++
 .../app/components/WorkspaceWorktreesSummary.tsx   | 106 ++++++++-------------
 .../__tests__/WorkspaceWorktreesSummary.test.tsx   |  46 ++++++++-
 .../src/__tests__/self-healing-workspace.test.ts   |  19 ++++
 .../engine/src/__tests__/workspace-merger.test.ts  |   6 ++
 packages/engine/src/merge/merger-ai.ts             |   7 +-
 .../engine/src/merge/workspace-land-failure.ts     |  21 ++++
 packages/engine/src/self-healing.ts                |  16 ++++
 11 files changed, 208 insertions(+), 68 deletions(-)

Fusion-Task-Id: FN-9062

Fusion-Task-Lineage: 8c12b9f9-f6ed-4766-a6f1-49cdf9ea8926

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 00:48:23 -07:00
gsxdsm
43889bc684 FN-9058: block workspace main-checkout edits
Prevent workspace tasks from completing after task-era edits in configured sub-repository main checkouts.

- Detect dirty and recent commit evidence across every workspace main checkout before invariant checks.
- Block attributable edits with bounded retries while warning safely for inconclusive evidence.
- Add audit telemetry, documentation, changeset, and real-git regression coverage.

Files changed:
 .../fn-9058-workspace-main-checkout-guard.md       |   7 +
 AGENTS.md                                          |   1 +
 docs/architecture.md                               |   1 +
 .../engine/src/__tests__/_workspace-fixture.ts     |   3 +-
 .../executor-workspace-main-checkout-guard.test.ts | 164 +++++++++++++++++++++
 packages/engine/src/executor/execution-prompt.ts   |   3 +-
 .../src/executor/workspace-main-checkout-guard.ts  | 128 ++++++++++++++++
 .../src/executor/worktree-verify-invariants.ts     |  45 +++++-
 packages/engine/src/util/run-audit.ts              |   2 +
 9 files changed, 351 insertions(+), 3 deletions(-)

Fusion-Task-Id: FN-9058

Fusion-Task-Lineage: b5dd58bd-4bd9-41fd-b3d5-e07270f3abca

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 00:41:44 -07:00
gsxdsm
c7779e44ac FN-9055: guard archive disposal of live workspace worktrees
Prevent archive cleanup from removing worktrees that still belong to live tasks.

- Add shared archive liveness evaluation and transactional refusal guards.
- Require CLI and extension archive operations to refuse live tasks unless a human uses --force.
- Protect baseline archive worktree disposal and cover CLI, core, and engine paths with tests.

Files changed:
 .changeset/fn-9055-archive-live-worktree-guard.md  |  7 ++
 docs/cli-reference.md                              |  4 +-
 docs/task-management.md                            |  4 +-
 .../extension-task-archive-live-guard.test.ts      | 82 +++++++++++++++++++
 packages/cli/src/bin.ts                            |  6 +-
 packages/cli/src/commands/__tests__/task.test.ts   | 66 ++++++++++++++-
 packages/cli/src/commands/task.ts                  | 49 +++++++++---
 packages/cli/src/extension.ts                      | 25 ++++--
 .../src/__tests__/archive-live-task-guard.test.ts  | 70 ++++++++++++++++
 .../postgres/archive-live-task-fence.pg.test.ts    | 69 ++++++++++++++++
 .../src/__tests__/task-archive-liveness.test.ts    | 19 +++++
 packages/core/src/index.ts                         | 10 +++
 packages/core/src/store.ts                         |  4 +-
 .../core/src/task-store/archive-lifecycle-2.ts     | 27 +++++--
 packages/core/src/task-store/archive-lifecycle.ts  | 20 ++---
 .../src/task-store/async/async-archive-lineage.ts  | 17 +++-
 packages/core/src/tasks/task-archive-liveness.ts   | 56 +++++++++++++
 ...chive-baseline-disposer-live-task-guard.test.ts | 93 ++++++++++++++++++++++
 .../healing/archive-worktree-disposer-install.ts   | 15 +++-
 19 files changed, 592 insertions(+), 51 deletions(-)

Fusion-Task-Id: FN-9055

Fusion-Task-Lineage: 08644626-cc61-4854-abb9-5b415ddc9491

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 00:35:12 -07:00
gsxdsm
6adcab3b0e FN-9057: bound workspace trailer fallback scans
Bound degraded workspace landing checks to recent task evidence.

- Pass task creation time through workspace landing and recovery paths
- Limit branch-gone trailer scans by time and commit count
- Cover recycled task-id fallback behavior with real-git tests

Files changed:
 ...fn-9057-workspace-land-predicate-recycled-id.md |  7 +++
 ...ace-land-predicate-recycled-id.real-git.test.ts | 58 ++++++++++++++++++++++
 .../workspace-merger-idempotency.slow.test.ts      | 19 +++++++
 packages/engine/src/merge/merger-ai.ts             |  6 +++
 .../engine/src/merge/workspace-land-predicate.ts   | 39 +++++++++++++--
 packages/engine/src/self-healing.ts                |  5 +-
 6 files changed, 127 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-9057

Fusion-Task-Lineage: e522a33e-0f11-49ad-af88-3fa29129fad2

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 00:25:04 -07:00
gsxdsm
1372218b1f FN-9047: invalidate stale workspace landing proof after revert
Preserve workspace landing attribution while allowing cleanly reverted work to land again.

- Record a per-repository revert boundary after clean git-mode workspace reverts.
- Reject recorded and trailer landing proof at or behind that boundary, then clear it on a fresh landing.
- Persist boundaries through the revert route and cover re-land behavior with git tests.

Files changed:
 .changeset/fn-9047-workspace-revert-landed-sha.md  |  7 +++
 docs/architecture.md                               |  2 +
 packages/core/src/types/task/task-core.ts          |  7 ++-
 .../src/routes/register-session-diff-routes.ts     |  2 +-
 .../src/routes/register-task-workflow-routes.ts    | 11 ++++
 .../task-revert.workspace.real-git.test.ts         | 27 ++++++++++
 ...orkspace-land-predicate.revert-boundary.test.ts | 60 ++++++++++++++++++++++
 packages/engine/src/execution/task-revert.ts       | 42 +++++++++++++--
 packages/engine/src/index.ts                       |  1 +
 packages/engine/src/merge/merger-ai.ts             |  5 +-
 .../engine/src/merge/workspace-land-predicate.ts   | 25 +++++++--
 packages/engine/src/self-healing.ts                |  9 +++-
 12 files changed, 185 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-9047

Fusion-Task-Lineage: 8ac41347-3c76-4f54-8d69-f16f82084305

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 00:02:52 -07:00
gsxdsm
4bc0a32d60 FN-9050: enforce AI squash scope and diff-volume gates
Validate approved AI squashes before any integration ref advances.

- Enforce task file scope and diff-volume checks for single-repo and workspace lands.
- Reset rejected clean rooms to the integration tip so invalid approved squashes cannot be recovered on retry.
- Add audit events, documentation, a changeset, and regression coverage for land gates.

Files changed:
 .changeset/fn-9050-ai-merge-scope-gates.md         |   7 +
 docs/architecture.md                               |   2 +
 docs/workflow-steps.md                             |   4 +-
 .../src/__tests__/merger-ai-squash-gates.test.ts   | 188 +++++++++++++++++++++
 .../__tests__/merger-file-scope-invariant.test.ts  |  29 ++++
 .../__tests__/workspace-merger-scope-gates.test.ts | 118 +++++++++++++
 .../engine/src/merge/merger-ai-squash-gates.ts     |  66 ++++++++
 packages/engine/src/merge/merger-ai.ts             |  21 ++-
 .../engine/src/merge/merger-diff-volume-gate.ts    |  14 +-
 packages/engine/src/merge/merger-file-scope.ts     |  33 +++-
 packages/engine/src/util/run-audit.ts              |   1 +
 11 files changed, 474 insertions(+), 9 deletions(-)

Fusion-Task-Id: FN-9050

Fusion-Task-Lineage: 9ecd8b8c-5c00-45ea-98e9-2aa8a8040c53

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-14 23:42:52 -07:00
gsxdsm
6896f1d7f3 FN-9045: wire workspace mode toggle to workspace config
Connect workspace-mode settings updates to the runtime workspace configuration lifecycle.

- Synchronize workspace.json and config.json when workspace mode changes.
- Reconcile settings events and executor state after successful or failed toggles.
- Add dashboard route, UI copy, localization, documentation, and regression coverage.

Files changed:
 .changeset/fn-9045-workspace-mode-toggle.md        |   7 +
 docs/settings-reference.md                         |   2 +-
 .../settings-workspace-toggle-side-effect.test.ts  | 178 +++++++++++++++++++++
 .../src/__tests__/workspace-mode-toggle.test.ts    |  71 ++++++++
 packages/core/src/git/git-repository.ts            | 147 ++++++++++++++++-
 packages/core/src/index.gate.ts                    |   6 +
 packages/core/src/index.ts                         |   6 +
 packages/core/src/task-store/settings-ops.ts       |  86 +++++++++-
 packages/core/src/types/settings/settings-scope.ts |  11 +-
 .../settings/sections/GeneralSection.tsx           |  10 +-
 .../settings-workspace-mode-route.test.ts          | 148 +++++++++++++++++
 .../src/routes/register-settings-memory-routes.ts  |  18 +++
 .../executor-workspace-toggle-invalidation.test.ts |  64 ++++++++
 .../engine/src/executor/task-executor-state.ts     |   6 +
 .../src/executor/workspace-config-resolver.ts      |  16 +-
 packages/engine/src/runtimes/in-process-runtime.ts |  12 ++
 packages/i18n/locales/en/app.json                  |   2 +-
 packages/i18n/locales/es/app.json                  |   4 +-
 packages/i18n/locales/fr/app.json                  |   4 +-
 packages/i18n/locales/ko/app.json                  |   4 +-
 packages/i18n/locales/pt-BR/app.json               |   4 +-
 packages/i18n/locales/zh-CN/app.json               |   4 +-
 packages/i18n/locales/zh-TW/app.json               |   4 +-
 23 files changed, 791 insertions(+), 23 deletions(-)

Fusion-Task-Id: FN-9045

Fusion-Task-Lineage: e382726f-8409-4983-94ef-93f341a6adbf

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-14 23:33:36 -07:00
gsxdsm
892afaaf03 FN-9048: clear disposed workspace state on unarchive
Prevent disposed workspace metadata from being revived when archived tasks return.

- Reconcile missing workspace and singular worktree paths during archive restore.
- Preserve surviving workspace entries and cover archive-to-restore recovery behavior.
- Document the restore lifecycle and add a patch changeset.

Files changed:
 .changeset/fn-9048-workspace-unarchive.md          |   7 ++
 docs/task-management.md                            |   2 +-
 .../archive-restore-workspace-worktrees.pg.test.ts |  70 +++++++++++++
 .../core/src/task-store/archive-lifecycle-2.ts     |   8 +-
 .../src/task-store/async/async-archive-lineage.ts  |  43 ++++++++
 .../src/__tests__/self-healing-workspace.test.ts   | 111 ++++++++++++++++++++-
 6 files changed, 236 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-9048

Fusion-Task-Lineage: fa9b9359-5fab-497f-87ce-0174d8069d99

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-14 23:22:05 -07:00
gsxdsm
db8e715452 FN-9056: reclaim safe terminal workspace worktrees
Reclaim safely abandoned workspace worktrees and canonical task branches without disrupting live or recoverable tasks.

- Tear down eligible complete, idle failed, and soft-deleted per-repository worktrees with bounded retries.
- Veto live, paused, scheduled-recovery, ambiguous, and unsafe-path cleanup candidates.
- Verify failed-task landing evidence against each repository integration branch before deleting canonical branches.
- Cover liveness and stale landed-SHA safety regressions.

Files changed:
 .changeset/fn-9056-workspace-terminal-teardown.md  |   7 +
 AGENTS.md                                          |   2 +-
 docs/architecture.md                               |   1 +
 .../src/__tests__/self-healing-workspace.test.ts   | 319 ++++++++++++++++++++-
 .../engine/src/executor/cleanup-task-worktree.ts   |   8 +-
 packages/engine/src/self-healing.ts                | 268 ++++++++++++-----
 packages/engine/src/util/run-audit.ts              |   7 +-
 7 files changed, 525 insertions(+), 87 deletions(-)

Fusion-Task-Id: FN-9056

Fusion-Task-Lineage: 4353f7d9-063b-442b-88d3-6f3da1c9aae8

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-14 23:14:19 -07:00