Commit Graph

71 Commits

Author SHA1 Message Date
gsxdsm
283adce4d0 FN-6295: move AI merge clean rooms into worktrees
Move AI-merge clean-room worktrees into the configured worktrees directory while preserving legacy cleanup.

- Resolve AI-merge roots through the configured worktrees directory using a hidden .ai-merge container.
- Keep local git excludes and stale cleanup compatible with legacy .fusion/ai-merge and tmpdir locations.
- Exclude the .ai-merge container from worktree pool and self-healing one-level sweeps.
- Add regression coverage for path resolution, cleanup, orphan reap, and cap enforcement behavior.
- Update architecture and agent guidance for the relocated clean-room root.

Files changed:
 AGENTS.md                                          |  2 +-
 docs/architecture.md                               |  4 +-
 .../engine/src/__tests__/merger-ai-cleanup.test.ts | 50 +++++++++----
 .../__tests__/self-healing-tempdir-sweep.test.ts   | 87 +++++++++++++++++++---
 .../engine/src/__tests__/worktree-paths.test.ts    | 24 ++++++
 .../engine/src/__tests__/worktree-pool.test.ts     | 55 ++++++++++++++
 packages/engine/src/merger-ai.ts                   | 27 +++++--
 packages/engine/src/self-healing.ts                | 25 +++----
 packages/engine/src/worktree-paths.ts              | 17 +++++
 packages/engine/src/worktree-pool.ts               | 10 +--
 10 files changed, 247 insertions(+), 54 deletions(-)

Fusion-Task-Id: FN-6295
Fusion-Task-Lineage: d95d32c2-3253-4964-b68a-252b4cb65109
2026-06-12 12:49:34 -07:00
gsxdsm
0b1c8fb56b fix(ci): widen Column to ColumnId in plugins + drop unused import after #1403 widening
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 08:40:10 -07:00
gsxdsm
afc72b6bb0 fix(core): widen Task.column to ColumnId across packages; v1-preserving IR persistence for rollback safety (#1403 #1405) 2026-06-04 08:00:33 -07:00
gsxdsm
b154844286 FN-5772: re-anchor nested task worktree paths
Fix executor worktree invariant handling by re-anchoring nested task worktree paths to the actual git top-level.

- add nested worktree root detection that only re-anchors when the top-level is a registered worktree inside the configured worktrees directory
- update executor liveness gating and verifyWorktreeInvariants to persist re-anchored task.worktree values and retry checks safely
- emit a new run-audit git mutation (worktree:reanchored) and add reliability tests/docs coverage plus a patch changeset

Files changed:
 .changeset/fn-5772-worktree-reanchor.md            |  7 +++
 docs/architecture.md                               |  4 +-
 packages/engine/src/__tests__/reliability-interactions/executor-liveness-gate.test.ts                 | 33 ++++++++++
 packages/engine/src/__tests__/verify-worktree-invariants-missing.test.ts     | 62 +++++++++++++++++-
 packages/engine/src/__tests__/worktree-reanchor-nested-root.test.ts          | 73 ++++++++++++++++++++++
 packages/engine/src/executor.ts                    | 54 ++++++++++++++--
 packages/engine/src/run-audit.ts                   |  1 +
 packages/engine/src/worktree-pool.ts               | 63 +++++++++++++++++++
 8 files changed, 290 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-5772

Fusion-Task-Lineage: 475de161-7bc1-4359-bb76-20c4c07196d9
2026-05-31 08:32:01 -07:00
gsxdsm
4fee2c1324 FN-5671: add branch-strategy selection to new task creation
Add branch-strategy based task branch handling from modal through task creation routes.

- add branch strategy dropdown + validation in New Task modal and TaskForm, including required branch-name handling for existing/custom-new modes
- send structured branchSelection payload from dashboard API client and cover UI/API behavior with new tests
- add server-side branch selection mode parsing, auto-new branch derivation (fusion/<task-id>-<slug>), and response updates when auto branch is generated
- update engine/worktree and dashboard route tests plus dashboard guide documentation
- add a changeset for @runfusion/fusion patch release

Files changed:
 .changeset/fn-5671-branch-strategy-dropdown.md     |  7 ++
 docs/dashboard-guide.md                            | 16 +++++
 packages/dashboard/app/__tests__/api-tasks.test.ts | 21 ++++++
 packages/dashboard/app/api/legacy.ts               |  9 +++
 packages/dashboard/app/components/NewTaskModal.css |  8 +++
 packages/dashboard/app/components/NewTaskModal.tsx | 41 +++++++++---
 packages/dashboard/app/components/TaskForm.tsx     | 30 ++++++++-
 .../app/components/__tests__/NewTaskModal.test.tsx | 77 +++++++++++++++++++---
 .../src/__tests__/branch-selection.test.ts         | 13 ++++
 .../dashboard/src/__tests__/routes-tasks.test.ts   | 72 ++++++++++++++++++++
 packages/dashboard/src/routes/branch-selection.ts  | 45 ++++++++-----
 .../src/routes/register-task-workflow-routes.ts    | 22 +++++--
 .../engine/src/__tests__/worktree-pool.test.ts     | 41 ++++++++++++
 packages/engine/src/worktree-pool.ts               |  2 +-
 14 files changed, 361 insertions(+), 43 deletions(-)

Fusion-Task-Id: FN-5671
Fusion-Task-Lineage: 7f2e7b68-050d-4a2c-af0b-cb895de35576
2026-05-29 09:44:17 -07:00
gsxdsm
dc944949b1 fix(engine,dashboard): close 7 review findings on merger auto-sync
Data-loss fixes in syncWorktreeToHead:
  - Untracked-restore checks `git ls-tree -r --name-only HEAD` to skip
    paths the new tip added as tracked files; user bytes stay in the
    stage dir instead of clobbering merged content.
  - Apply-failure on a deleted/renamed file: conflictedFiles falls back
    to parsing `diff --git a/<p> b/<p>` headers when --diff-filter=U
    returns nothing.
  - All git invocations pass `-c core.quotePath=false` so non-ASCII
    paths round-trip through copyFileSync.
  - Stash-and-ff re-verifies rev-parse HEAD === newSha right before
    each `reset --hard HEAD` (TOCTOU). On mismatch we bail with patch
    preserved on disk.
  - Stage dir lifecycle moved into try/finally with preserveStageDir
    flag — kept whenever the user's edits live only in patchPath; rm'd
    on all clean exits.
  - Patch written to disk before the apply attempt, not only on
    failure, so a crash between snapshot and apply doesn't lose edits.

Multi-worktree-same-branch fix:
  - New getRegisteredWorktreeBranches returns Array<{branch,path}>
    instead of collapsing into a Map. Multiple worktrees can share a
    branch via `git worktree add --force -b`; merger now syncs all of
    them rather than silently skipping all but the last.

Contract + surfacing fixes:
  - JSDoc on merge:auto-sync GitMutationType now lists the actually-
    emitted outcome strings + stage enum.
  - GET /api/tasks/merge-advance-events joins merge:auto-sync events
    within ±5min of the advance and returns them in a new
    `autoSync: AutoSyncOutcome[]` field; useMergeAdvanceNotice exposes
    the same shape so the banner can surface pop-conflicts (including
    patchPath) instead of dropping them.

Hygiene:
  - Merger now reads the setting via normalizeMergeAdvanceAutoSyncMode
    instead of an inline check + `as unknown` cast.

New tests:
  - Untracked-collides-with-tracked preserves merged content.
  - Apply failure on deleted file populates conflictedFiles from
    patch header.
  - Route surfaces autoSync outcomes (clean-sync + pop-conflict)
    joined within the time window.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 15:13:17 -07:00
Fusion (runfusion.ai)
1bffa22ca9 feat(FN-5479): fix identity-guard merger bypass on detached HEAD and gate l
The merge delivers the FN-5483 identity-guard bypass for merger-driven commits on detached HEAD, plus Steps 2 and 6 of FN-5479 which gate the limbo counter by enqueue acceptance and document the associated invariant. It also restores the dashboard's PWA and theme-boot contract in index.html. New reg

Fusion-Task-Id: FN-5479
2026-05-22 08:31:12 -07:00
gsxdsm
2d661df870 fix(engine): harden worktree-pool branch creation and auto-reanchor foreign-only contamination
WorktreePool.prepareForTask now rejects empty/"HEAD" base values and verifies
that the worktree's HEAD actually landed at the resolved base SHA after
`git checkout --detach`. This closes the FN-5432 / FN-5255 contamination
pattern where a recycled worktree branched from a stale HEAD (reflog:
"branch: Created from HEAD") and pinned the new task's tip to the previous
occupant's commit.

SelfHealingManager.tryReanchorForeignOnlyContamination is invoked from both
PR-conflict and self-owned-branch-conflict catch sites before the
unrecoverable-pause path. When the conflicted branch carries only foreign
commits (no own work), the branch is reset to base via the existing
recoverForeignOnlyContamination flow instead of being escalated for human
adjudication.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 04:13:15 -07:00
Fusion (runfusion.ai)
79850b233f feat(FN-5349): add integration branch resolver with auto-recovery fallback
FN-5349 adds a dedicated integration branch resolution module (`packages/engine/src/integration-branch.ts`) replacing ad-hoc dynamic fallbacks, routes merger branch conflict resolution through it, wires auto-recovery handlers (branch-worktree, contamination) to use integration branch fallback, and w

Fusion-Task-Id: FN-5349
2026-05-21 12:04:58 -07:00
Fusion (runfusion.ai)
fd202e9356 feat(FN-5329): remove orphan rescue and branch-recovery primitives from eng
Removes the branch-recovery CLI surface, orphan-rescue engine primitives, and their associated tests (over 1,500 lines deleted), while restoring a minimal prune-only orphan branch sweep with proper git audit mutation types. Documentation across `cli-reference.md`, `task-management.md`, and `AGENTS.m

Fusion-Task-Id: FN-5329
2026-05-20 16:43:27 -07:00
Fusion (runfusion.ai)
c56e0cf814 feat(FN-5083): complete Step 3 — canonicalize fusion branch naming 2026-05-18 18:26:52 -07:00
gsxdsm
46d09285d5 feat(FN-5058): merge fusion/fn-5058 2026-05-18 11:01:32 -07:00
Fusion (runfusion.ai)
d702231adc feat(FN-4938): complete Step 2 — add helper and wire cleanup
Fusion-Task-Id: FN-4938
Fusion-Task-Lineage: 8b53a5da-1321-4796-9775-ff043efdcef3
2026-05-18 01:50:22 -07:00
Fusion (runfusion.ai)
48caf28148 test(FN-4912): complete Step 9 — add env materialization verification coverage
Fusion-Task-Id: FN-4912
Fusion-Task-Lineage: 943d0651-052a-41b5-8069-4c60f4db1ba7
2026-05-17 23:29:21 -07:00
Fusion (runfusion.ai)
59023b7f50 feat(FN-4912): complete Step 7 — add orphan cleanup env teardown
Fusion-Task-Id: FN-4912
Fusion-Task-Lineage: 943d0651-052a-41b5-8069-4c60f4db1ba7
2026-05-17 23:29:20 -07:00
Fusion (runfusion.ai)
7e90bce8bb feat(FN-4954): harden pool leasing invariants and wire runtime auditing
Fusion-Task-Id: FN-4954
Fusion-Task-Lineage: b3dd2d2f-3aa3-48f1-8a56-56e66518d139
2026-05-17 21:17:38 -07:00
Fusion (runfusion.ai)
40f9aa99e6 feat(FN-4962): complete Step 3 — reconcile stale worktree metadata
Fusion-Task-Id: FN-4962
Fusion-Task-Lineage: de4ce54b-c5e4-40f9-a048-677adac3e1a0
2026-05-17 15:55:18 -07:00
Fusion (runfusion.ai)
3bbc5077b8 feat(FN-4935): complete Step 7 — testing and verification
Ref: Runfusion/Fusion#601
Fusion-Task-Id: FN-4935
Fusion-Task-Lineage: 8c842b69-1427-47be-9ba5-8ec66449cc7c
2026-05-17 15:02:35 -07:00
Fusion (runfusion.ai)
0f69412c20 feat(FN-4935): complete Step 1 — structured liveness classifier
Ref: Runfusion/Fusion#601
Fusion-Task-Id: FN-4935
Fusion-Task-Lineage: 8c842b69-1427-47be-9ba5-8ec66449cc7c
2026-05-17 15:02:35 -07:00
Fusion (runfusion.ai)
2cb141a511 feat(FN-4917): complete Step 2 — add worktree classification helper
Fusion-Task-Id: FN-4917
Fusion-Task-Lineage: 1422a545-f4b5-4e1f-a347-8be2a4202f45
2026-05-17 14:10:42 -07:00
Fusion
86237c9a50 fix(FN-4811): unblock @fusion/engine typecheck so verification bootstrap can run
Symptom found while investigating 'tasks are still struggling': every
in-review task hitting pre-merge deterministic verification failed with

  [verification:bootstrap] bootstrap preamble failed (exit 2):
  [test-bootstrap] FAILED: workspace dist artifact rebuild did not complete.
  [test-bootstrap] command: pnpm --filter @fusion/engine build

Because pnpm --filter @fusion/engine build hit 17 TS errors from a prior
autonomous-agent refactor introducing a RemovalReason enum-like object
and two new audit event types. The bootstrap preamble is run by the
merger before every direct-merge verification, so a broken engine
typecheck blocked EVERY task from merging.

Fixes:

1. Duplicate RemovalReason re-export in worktree-pool.ts

   Both  and
    were present for the same identifier,
   producing TS2300 'Duplicate identifier'. RemovalReason is a const
   object with derived type (typeof-keyof pattern), so a single value
   export covers both kinds; the type-only re-export was redundant.

2. GitMutationType union missing the FN-4811 audit event types

   merger.ts and worktree-backend.ts were emitting
   'worktree:removal-refused-active-session' and
   'worktree:removal-forced-over-active-session' audit events, but the
   union in run-audit.ts didn't include them. Added both.

3. self-healing.test.ts vi.mock had wrong RemovalReason keys

   The mock only exposed 5 keys (SelfHealing*) but production code
   references HardCancel, Executor*, Merger*, PoolPrune, etc. Calls
   like removeWorktree({ reason: RemovalReason.MergerPostMerge }) were
   getting reason=undefined, producing confusing 'cannot remove
   worktree: [vitest] No RemovalReason export is defined on mock'
   error messages. Updated the mock to mirror the production const
   exactly.

4. worktree-backend.test.ts removeWorktree calls missing required reason

   The new contract makes reason: RemovalReason a required field on
   removeWorktree's input. Five existing test cases were missing it;
   added reason: RemovalReason.MergerCleanup to each.

5. integrity-warning-persisted-dedup.test.ts Settings cast

   The test's makeStore helper cast a partial settings object to
   Settings; TS rejected the narrowed type. Cast through unknown.

Verification:

  - pnpm --filter @fusion/engine build: clean
  - pnpm lint: clean
  - pnpm build (full workspace): clean
  - pnpm --filter @fusion/engine test: 5045 pass, 1 pre-existing
    aiMergeTask real-git timeout flake, 1 skipped

With this fix, the verification bootstrap can complete and the merger
can finalize tasks again.

Fusion-Task-Id: FN-4811
2026-05-16 17:23:15 -07:00
Fusion (runfusion.ai)
8fd47b619f feat(FN-4811): complete Step 3 — update removeWorktree call sites
Fusion-Task-Id: FN-4811
Fusion-Task-Lineage: f3dac123-cb46-4d31-8a7e-dfc664bfdc5f
2026-05-16 16:55:04 -07:00
Fusion (runfusion.ai)
e2de8fed6d feat(FN-4742): complete Step 4 — migrate pool and self-healing removals
Fusion-Task-Id: FN-4742
Fusion-Task-Lineage: 59bca56e-c9d9-4066-9f5a-6d8ee252a100
2026-05-16 10:08:02 -07:00
Fusion (runfusion.ai)
36645bdb84 fix(FN-4717): complete Step 4 — align worktrunk source union types
Fusion-Task-Id: FN-4717
Fusion-Task-Lineage: a2533cd8-52c4-43a0-9daf-e0a49745306b
2026-05-16 01:58:16 -07:00
Fusion (runfusion.ai)
156392410a feat(FN-4678): add removeWorktree helper to worktree-backend
Adds a `removeWorktree` helper to the worktree backend with corresponding unit tests, and wires it into the worktree pool.

Fusion-Task-Id: FN-4678
2026-05-15 22:49:36 -07:00
Fusion (runfusion.ai)
3defcbe849 feat(FN-4706): complete Step 2 — disable worktrunk auto-install path
Fusion-Task-Id: FN-4706
Fusion-Task-Lineage: 00e9207c-d2dc-4bc4-ae92-4604339bcbc2
2026-05-15 21:23:05 -07:00
Fusion (runfusion.ai)
5e6d420d71 fix(FN-4624): fix scheduler test mocks for createLogger and lint in worktree-pool
Fusion-Task-Id: FN-4624
Fusion-Task-Lineage: 854e6033-bc17-45be-8d04-18bcb66b31c4
2026-05-15 20:24:58 -07:00
Fusion (runfusion.ai)
af93673bda feat(FN-4624): complete Step 4 — wire getWorktrunkBinary into worktree-pool
Fusion-Task-Id: FN-4624
Fusion-Task-Lineage: 854e6033-bc17-45be-8d04-18bcb66b31c4
2026-05-15 20:24:57 -07:00
Fusion (runfusion.ai)
bf97042b61 feat(FN-4687): complete Step 3 — export backend selector surface
Fusion-Task-Id: FN-4687
Fusion-Task-Lineage: d646a4dc-e28e-4b1f-ac07-c4ab79e893d5
2026-05-15 18:23:50 -07:00
Fusion (runfusion.ai)
332fab63a1 feat(FN-4686): complete Step 3 — add backend selector and exports
Fusion-Task-Id: FN-4686
Fusion-Task-Lineage: a1e58bd8-fd94-471a-b164-c396c5512fea
2026-05-15 17:52:54 -07:00
Fusion (runfusion.ai)
3ddbbea991 feat(FN-4684): complete Step 3 — add selector surface and audit types
Fusion-Task-Id: FN-4684
Fusion-Task-Lineage: 142e512b-8189-4029-9df4-4bd40b69ed2a
2026-05-15 16:44:49 -07:00
Fusion (runfusion.ai)
58aa411077 test(FN-4682): add worktree liveness regression coverage
Fusion-Task-Id: FN-4682
Fusion-Task-Lineage: f37fb4a1-878b-4d0c-85c8-0f005ab0fe7b
2026-05-15 15:59:34 -07:00
Fusion (runfusion.ai)
3af4cb77ee fix(FN-4682): make worktree liveness assertion language-agnostic
Fusion-Task-Id: FN-4682
Fusion-Task-Lineage: f37fb4a1-878b-4d0c-85c8-0f005ab0fe7b
2026-05-15 15:59:34 -07:00
Fusion
2799c101ac feat(FN-4606): complete Step 3 — route engine call sites
Ref: Runfusion/Fusion#321
Fusion-Task-Id: FN-4606
Fusion-Task-Lineage: 94b23f37-944e-4bcd-bfa1-67d0a8c0a267
2026-05-15 09:19:58 -07:00
Fusion
f00df58eb7 feat(FN-4606): complete Step 2 — add worktree path resolver
Ref: Runfusion/Fusion#321
Fusion-Task-Id: FN-4606
Fusion-Task-Lineage: 94b23f37-944e-4bcd-bfa1-67d0a8c0a267
2026-05-15 09:19:58 -07:00
Fusion
473ea373b8 feat(FN-4508): complete Step 2 — handle tip-already-merged recovery paths
Fusion-Task-Id: FN-4508
Fusion-Task-Lineage: 948a9cae-3975-4f15-bd47-2f88b379171d
2026-05-14 16:33:27 -07:00
Fusion
e01d2ef04f feat(FN-4485): complete Step 2 — tighten branch conflict classifier
Fusion-Task-Id: FN-4485
Fusion-Task-Lineage: 034088dc-ebc4-4e12-8314-39419d41b23f
2026-05-14 11:23:43 -07:00
Fusion
d8255c2bb0 fix(FN-4476): handle fully-subsumed branch conflicts across reclaim paths
Fusion-Task-Id: FN-4476
Fusion-Task-Lineage: 8673c1d9-f47e-4d02-89e6-646040b9be32
2026-05-14 08:49:37 -07:00
gsxdsm
86f8caf14e chore(FN-4428): import dependency content from fusion/fn-4410
Squash-imported the working tree of fusion/fn-4410 as a single commit so this branch carries the dep's content without inheriting its individual commits. If the dep is later squash-merged to main, this commit's patch-id should match the merge and rebase cleanly.

Fusion-Task-Id: FN-4428
Fusion-Task-Lineage: ea174f50-49ac-4105-b6cf-db3bab0984fd
2026-05-14 02:28:56 -07:00
Fusion
d39430b344 feat(FN-4409): add branch contamination assertions in worktree flows
Fusion-Task-Id: FN-4409
Fusion-Task-Lineage: c608c942-fec7-4489-9970-b8dc314f8be2
2026-05-13 17:44:46 -07:00
gsxdsm
22fee60aee chore(FN-4350): import dependency content from fusion/fn-4326
Squash-imported the working tree of fusion/fn-4326 as a single commit so this branch carries the dep's content without inheriting its individual commits. If the dep is later squash-merged to main, this commit's patch-id should match the merge and rebase cleanly.

Fusion-Task-Id: FN-4350
Fusion-Task-Lineage: 11fff2c2-1cd1-4562-9b01-032a15217479
2026-05-13 12:30:45 -07:00
Fusion
7cdba43908 fix(FN-4350): complete Step 4 — pass verification gates
Fusion-Task-Id: FN-4350
Fusion-Task-Lineage: 11fff2c2-1cd1-4562-9b01-032a15217479
2026-05-13 12:26:07 -07:00
Fusion
fd0cd93192 feat(FN-4214): fix live-log empty-state when agent logs become stale
Fixes a live-log empty-state regression in the workflow results tab by adding test coverage for the stale agent-log case, with a changeset prepared to publish the patch.

Fusion-Task-Id: FN-4214

Fusion-Task-Lineage: da180434-6d1d-497e-8f5a-f29d07a874f2
2026-05-13 06:29:35 -07:00
Fusion
b8b119ad8c feat(FN-4114): complete Step 1 — add worktree invariant helper
Fusion-Task-Id: FN-4114
Fusion-Task-Lineage: 44fd5718-42dc-44d1-8f5a-97b67dd05d13
2026-05-13 06:29:35 -07:00
Fusion
bddcc3a931 feat(FN-4068): add branch conflict detection and recovery for stale worktre
Implements branch conflict detection and recovery across the Fusion engine, CLI, and dashboard — surfacing git worktree conflicts when tasks conflict with unrelated branch state, and providing a recovery workflow to resolve them. The executor and worktree pool now integrate typed branch conflict che

Fusion-Task-Id: FN-4068
2026-05-12 17:14:29 -07:00
Fusion
1772572191 feat(FN-4027): memoize startup slim list reads to avoid redundant fresh fet
Added memoization for startup slim task list reads (`store.ts`), with dashboard server routing startup reads through the memo window and tests covering the store watcher consumers in scheduler and worktree-pool, plus performance documentation.

Fusion-Task-Id: FN-4027
2026-05-11 21:48:26 -07:00
gsxdsm
6d4408c179 fix(FN-3305): preserve task branch on worktree conflict retry 2026-05-03 17:24:19 -07:00
Fusion
8e969bd72e feat(FN-3026): use Nerd Font terminal stack with font fallback migration
Adds Nerd Font as the terminal font stack default with a migration to update existing user settings, updates the terminal and settings modals to reflect the new font choice, and includes corresponding tests plus a patch changeset for `@runfusion/fusion`.

Fusion-Task-Id: FN-3026
2026-04-30 14:49:10 -07:00
gsxdsm
400be4487f feat(engine): preserve branches on auto-requeue + add fn_run_verification
Three coordinated fixes for the FN-2978 incident class — auto-requeues
that orphaned committed work and watchdog kills on long verification runs.

**Auto-requeue branch reuse** (executor.ts, worktree-pool.ts)
- executor.ts:1782 now uses `task.branch || fusion/<id>` so persisted
  branches are honored on requeue. Previously the hardcoded fallback
  always tried to re-create the original branch, hit a conflict with
  the prior run's ref, and got suffix -2/-3. Other call sites already
  honor task.branch — this aligns the worktree-acquisition path.
- worktree-pool.ts:181 prepareForTask now probes existing branches with
  `git rev-parse --verify` and checks them out as-is. Falls through to
  suffixed creation only when the branch is genuinely in use by another
  live worktree. Previously force-reset with `checkout -B`, destroying
  prior commits.
- New private reconcileStepsFromGitHistory walks `git log
  baseCommitSha..HEAD` for `feat(FN-X): complete Step N` commits and
  marks matching steps[] as done so resumes don't redo committed work.

**Manual reset endpoint + UI** (dashboard)
- POST /api/tasks/:id/reset (requires `confirm: true`) — clears worktree,
  branch, all retry counters, resets steps[] to pending, moves to todo.
  Distinct from /retry which is the soft-resume path.
- Reset button alongside Retry in TaskDetailModal with confirm dialog,
  wired through useTasks → AppModals → API.

**fn_run_verification tool** (run-verification-tool.ts, executor.ts)
- New custom tool wrapping test/lint/build commands with a heartbeat
  callback (per-line + 60s synthetic), 200KB head+tail output cap, hard
  timeout with SIGTERM→SIGKILL escalation, and auto-bootstrap detection
  for missing node_modules. Prevents the inactivity watchdog from
  killing sessions during long compiles.
- Cross-platform via `shell: true` (Node picks /bin/sh on POSIX,
  cmd.exe on Windows). Prompt section in EXECUTOR_SYSTEM_PROMPT and
  EXECUTOR_PROMPT_TEXT instructs agents to prefer package-scoped
  verification first and reserve workspace-scoped runs for final
  integration.

**Tests** (64 passing)
- detect-pseudo-pause.test.ts (27 tests) — covers all 7 regex patterns,
  structural fallback, FN-2978 regression text.
- reconcile-step-regex.test.ts (25 tests) — pins the commit-message
  regex against a wide variant set.
- run-verification-command.test.ts (12 tests) — basic execution, output
  capture, heartbeat callbacks, timeout, error handling. POSIX-specific
  cases (multi-cmd `;`, `>&2`, `\$USER`) gated behind itPosix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 10:19:54 -07:00
Fusion
163a4c734c feat(FN-2621): guard execution for non-git project directories
- Add isGitRepository utility in worktree-pool using git rev-parse checks
- Fail fast in TaskExecutor with actionable non-git errors before worktree creation starts
- Classify not-a-git-repository worktree add failures as non-retryable in recovery flows
- Warn from in-process runtime startup when the working directory is not a Git repository
- Expand executor and worktree-pool tests to cover non-git, missing-dir, and conflict-classification paths
2026-04-26 22:20:17 -07:00