Commit Graph

2783 Commits

Author SHA1 Message Date
gsxdsm
f06281961e fix(workspace): persist workspaceWorktrees and isolate concurrent session leases
Multiworkspace tasks could not complete due to two independent bugs:

1. task.workspaceWorktrees had no SQLite column / rowToTask mapping, so
   fn_acquire_repo_worktree's updateTask write was dropped on every persist
   (applyTaskPatch writes the DB-round-tripped task back to task.json). Every
   later getTask returned undefined, so fn_task_done's scope verifier read {}
   and blocked with "acquired no sub-repo worktrees", and isWorkspaceTask()
   consumers misfired. Persist it mirroring mergeDetails (schema column + v129
   migration + db-migrate + defineTaskColumn + TaskRow + rowToTask).

2. In workspace mode every task ran rooted at the shared browse-only root, and
   setActiveSession registered that path keyed only by path — so a second
   concurrent workspace task was rejected by the foreign-task guard
   ("active-session path ... is held by ..."). Give each task a task-scoped
   synthetic session key (sessionRegistryPath), applied at all register and
   unregister sites; the in-memory worktree Set still holds the real root.

Regression tests assert the persistence invariant across getTask/listTasks/
store-reopen and concurrent session registration across all three session
surfaces; both verified to fail without the fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 15:13:43 -07:00
gsxdsm
038ac3060b FN-6963: disable tool output log details by default
Agent logs now keep tool timeline rows while requiring an explicit opt-in to persist verbose tool payloads.

- Default persistAgentToolOutput to false in global settings and direct AgentLogger construction.
- Update the settings UI, API expectations, documentation, and changeset to describe opt-in tool payload persistence.
- Adjust engine and dashboard tests for the new default-off behavior while preserving explicit opt-in coverage.

Files changed:
 .changeset/FN-6963-tool-output-default-off.md      |  5 ++++
 docs/settings-reference.md                         |  2 +-
 packages/core/src/settings-schema.ts               |  6 ++++-
 .../components/__tests__/SettingsModal.test.tsx    | 22 +++++++++++++---
 .../settings/sections/GlobalGeneralSection.tsx     |  2 +-
 .../src/__tests__/routes-settings.test.ts          |  4 +--
 packages/engine/src/__tests__/agent-logger.test.ts | 30 ++++++++++++++++++----
 .../src/__tests__/heartbeat-executor.test.ts       |  4 +--
 .../src/__tests__/merger-merge-details.test.ts     |  2 +-
 .../src/__tests__/merger-verification.test.ts      |  2 +-
 .../src/__tests__/step-session-executor.test.ts    |  4 +--
 packages/engine/src/__tests__/triage.test.ts       |  2 +-
 packages/engine/src/agent-logger.ts                |  8 ++++--
 13 files changed, 71 insertions(+), 22 deletions(-)

Fusion-Task-Id: FN-6963

Fusion-Task-Lineage: 7db32871-f539-4a27-a324-02c55ce5bd04
2026-06-23 23:35:33 -07:00
gsxdsm
59d5e81a95 Merge remote-tracking branch 'origin/main' into latest4-1718
# Conflicts:
#	packages/engine/src/__tests__/merge-error-recovery.test.ts
#	packages/engine/src/merger-ai.ts
2026-06-23 20:58:31 -07:00
gsxdsm
b464f7d7d4 Merge remote-tracking branch 'origin/main' into latest3-1717 2026-06-23 19:58:12 -07:00
gsxdsm
4a1fd88d57 Merge remote-tracking branch 'origin/main' into latest3-1718 2026-06-23 19:58:03 -07:00
gsxdsm
216f910524 Merge remote-tracking branch 'origin/main' into latest2-1718
# Conflicts:
#	packages/engine/src/agent-tools.ts
#	packages/engine/src/worktree-acquisition.ts
2026-06-23 18:15:24 -07:00
gsxdsm
cd178261ec Merge remote-tracking branch 'origin/main' into latest2-1717
# Conflicts:
#	packages/engine/src/__tests__/executor-workspace.test.ts
#	packages/engine/src/agent-tools.ts
#	packages/engine/src/base-commit-capture.ts
#	packages/engine/src/worktree-acquisition.ts
2026-06-23 18:13:41 -07:00
gsxdsm
078723febb Merge remote-tracking branch 'origin/main' into latest2-1714
# Conflicts:
#	packages/engine/src/agent-tools.ts
#	packages/engine/src/base-commit-capture.ts
#	packages/engine/src/worktree-acquisition.ts
2026-06-23 18:11:26 -07:00
gsxdsm
0ebc9ea252 Merge branch 'main' into feature/add-request-headers-x-session-id-and-x-session-a 2026-06-23 18:03:33 -07:00
gsxdsm
1293f3432d Merge remote-tracking branch 'origin/main' into latest-1718
# Conflicts:
#	packages/engine/src/executor.ts
2026-06-23 17:41:30 -07:00
gsxdsm
9fbc93c8b1 Merge remote-tracking branch 'origin/main' into latest-1717
# Conflicts:
#	packages/engine/src/executor.ts
2026-06-23 17:40:35 -07:00
gsxdsm
0b111bbb03 Merge remote-tracking branch 'origin/main' into latest-1714
# Conflicts:
#	packages/engine/src/executor.ts
2026-06-23 17:39:37 -07:00
gsxdsm
fa622721e8 Merge remote-tracking branch 'origin/main' into latest-1713
# Conflicts:
#	packages/engine/src/executor.ts
2026-06-23 17:38:37 -07:00
gsxdsm
8d343b87b3 Merge branch 'main' into feature/add-request-headers-x-session-id-and-x-session-a 2026-06-23 17:37:57 -07:00
gsxdsm
e17e9bc867 feat(#1675): add X-Session-Id and X-Session-Affinity routing headers to LLM requests
Add X-Session-Id and X-Session-Affinity headers to all outbound LLM chat
completion requests so LLM gateways can sticky-route consecutive requests
from the same conversation and observability tools (Langfuse, Arize) can
group stateless API calls into a single multi-turn trace.

The headers carry a stable identifier: the task id when available (stable
across pause/resume), otherwise the pi session id. The implementation wraps
modelRegistry.getApiKeyAndHeaders -- the single chokepoint pi-coding-agent
uses for both the main stream and compaction -- merging routing headers into
the resolved output. This covers all HTTP-based providers (built-in, custom,
and HTTP-streaming extensions) without disturbing auth resolution.

Also propagates taskId to four secondary executor sessions (retry,
verification-fix, workflow-step, child-agent) that previously fell back to
a per-instance pi id, fragmenting per-task observability grouping.

Closes #1675
2026-06-23 17:31:52 -07:00
gsxdsm
37b2cb38ac Merge branch 'main' into feature/workflow-branch-group 2026-06-23 17:16:16 -07:00
gsxdsm
9822fbd6a8 Merge remote-tracking branch 'origin/main' into conflict-resolution-1718
# Conflicts:
#	packages/engine/src/__tests__/executor-recovery.test.ts
#	packages/engine/src/agent-tools.ts
#	packages/engine/src/executor.ts
#	packages/engine/src/merger-ai.ts
#	packages/engine/src/project-engine.ts
#	packages/engine/src/run-audit.ts
#	packages/engine/src/self-healing.ts
#	packages/engine/src/worktree-acquisition.ts
2026-06-23 16:23:28 -07:00
gsxdsm
0dea25061d Merge remote-tracking branch 'origin/main' into conflict-resolution-1717
# Conflicts:
#	packages/engine/src/__tests__/executor-recovery.test.ts
#	packages/engine/src/agent-tools.ts
#	packages/engine/src/executor.ts
#	packages/engine/src/merger-ai.ts
#	packages/engine/src/project-engine.ts
#	packages/engine/src/worktree-acquisition.ts
2026-06-23 16:12:10 -07:00
gsxdsm
941343f483 Merge remote-tracking branch 'origin/main' into conflict-resolution-1714
# Conflicts:
#	packages/engine/src/__tests__/executor-recovery.test.ts
#	packages/engine/src/agent-tools.ts
#	packages/engine/src/executor.ts
#	packages/engine/src/worktree-acquisition.ts
2026-06-23 16:01:38 -07:00
gsxdsm
dcee0d3172 Merge remote-tracking branch 'origin/main' into conflict-resolution-1713
# Conflicts:
#	packages/engine/src/__tests__/executor-recovery.test.ts
#	packages/engine/src/agent-tools.ts
#	packages/engine/src/executor.ts
#	packages/engine/src/worktree-acquisition.ts
2026-06-23 15:56:06 -07:00
gsxdsm
4faadd4f75 Merge remote-tracking branch 'origin/main' into conflict-resolution-1712
# Conflicts:
#	packages/dashboard/app/components/WorkflowNodeEditor.tsx
#	packages/engine/src/__tests__/executor-fast-mode-workflows.test.ts
2026-06-23 15:44:52 -07:00
gsxdsm
a8abecd043 Merge remote-tracking branch 'origin/main' into conflict-resolution-1711
# Conflicts:
#	packages/engine/src/executor.ts
2026-06-23 15:37:29 -07:00
gsxdsm
905a877954 Merge pull request #1710 from MichaelHoughtonDeBox/feat/workspace-multi-repo
Workspace mode: open a folder of git repos as one project (foundation + design Q)
2026-06-23 15:08:15 -07:00
gsxdsm
bac7049822 chore(release): v0.46.0
Version bump via changesets.
2026-06-23 12:27:50 -07:00
gsxdsm
fe536b2af8 FN-6954: reconcile stale parked task assignments
Reconcile agent/task drift when durable agents remain linked to queued tasks without live execution proof.

- clear stale Agent.taskId links for parked todo/triage tasks while preserving task leases and queue state
- report stale parked assignments as active/no-live-run in Reports Health Check before reconciliation completes
- add scheduler and self-healing coverage for queued lease drift, overlap starvation, and audit events
- document the reconciliation behavior and add a published package patch changeset

Files changed:
 .changeset/fn-6954-agent-task-state-drift.md       |   5 +
 docs/architecture.md                               |   2 +
 .../src/__tests__/heartbeat-executor.test.ts       |  68 ++++++++++++
 .../__tests__/scheduler-overlap-starvation.test.ts |  68 +++++++++++-
 .../self-healing-agent-link-drift.test.ts          |  97 ++++++++++++++++-
 .../engine/src/__tests__/task-agent-sync.test.ts   |  33 +++++-
 packages/engine/src/agent-heartbeat.ts             | 121 +++++++++++++++++++--
 packages/engine/src/run-audit.ts                   |   5 +
 packages/engine/src/runtimes/in-process-runtime.ts |   1 +
 packages/engine/src/scheduler.ts                   |  24 +++-
 packages/engine/src/self-healing.ts                | 102 ++++++++++++++---
 packages/engine/src/task-agent-sync.ts             |  65 ++++++++++-
 12 files changed, 555 insertions(+), 36 deletions(-)

Fusion-Task-Id: FN-6954
Fusion-Task-Lineage: 24b8a2eb-5a33-4539-ab64-ae2bbfc2d195
2026-06-23 10:30:50 -07:00
gsxdsm
81f43e0e89 Merge pull request #1730 from Runfusion/feature/memory-fix
[codex] Dispose completed spawned child sessions
2026-06-23 10:29:30 -07:00
gsxdsm
a46800128a Address PR review feedback (#1730)
- Await async spawned child session disposal

- Use own-key iteration for structured tool result previews

- Add FNXC requirement comments for new regression assertions
2026-06-23 09:57:49 -07:00
gsxdsm
e59b1fa07d Merge pull request #1726 from plarson/fix/triage-spec-review-fallback
fix(triage): pass fallback model settings to spec review
2026-06-23 09:52:58 -07:00
gsxdsm
36b7ad90fd fix(engine): bound structured tool result log previews 2026-06-23 09:19:32 -07:00
gsxdsm
466cf9ca8d fix(engine): dispose completed spawned child sessions 2026-06-23 09:12:28 -07:00
Phil Larson
823623e1c6 fix(triage): address spec review fallback PR comments 2026-06-23 08:51:58 -07:00
Phil Larson
40bef6dfce fix(triage): pass fallback model settings to spec review 2026-06-23 08:39:27 -07:00
gsxdsm
a670f5ce98 FN-6952: repair workflow-column lifecycle regressions
Restores core lifecycle compatibility while keeping workflow-column scheduling on the graduated runtime.\n\n- Split raw compatibility-flag checks from public workflow-column runtime enablement.\n- Keep scheduler and hold-release sweeps on workflow columns despite stale persisted false flags.\n- Preserve legacy moveTask guard bypass and invalid-transition behavior for compatibility paths.\n- Isolate the startup watch recovery fixture and add a patch changeset.\n\nFiles changed:\n .changeset/fn-6952-core-lifecycle-regressions.md |  5 ++++\n packages/core/src/__tests__/store-create.test.ts |  6 +++++\n packages/core/src/store.ts                       | 32 +++++++++++++++++-------\n packages/core/src/workflow-columns-settings.ts   |  8 ++----\n packages/engine/src/hold-release.ts              |  6 +++--\n packages/engine/src/scheduler.ts                 | 10 +++++++-\n 6 files changed, 49 insertions(+), 18 deletions(-)

Fusion-Task-Id: FN-6952

Fusion-Task-Lineage: cfd7ad99-db00-4454-b3d7-a07a72a7bbe7
2026-06-23 08:21:10 -07:00
gsxdsm
b599b6ab41 chore(release): v0.45.0
Version bump via changesets.
2026-06-23 01:07:59 -07:00
gsxdsm
9218613552 FN-6949: fix auto-merge lifecycle finalization
Make auto-merge completion idempotent when landed tasks are left outside done.

- Add shared auto-merge finalization logic that refreshes task rows, clears stale queue/blocker state, and recovery-rehomes proven landed tasks to done.
- Route direct AI merge, merge-confirmed fast paths, and self-healing recovery through the shared finalizer with run-audit events for reconciled or blocked column mismatches.
- Extend lifecycle and recovery tests to cover todo/in-review mismatches, finalization failures, stale blockers, and cleanup idempotency.
- Add the required patch changeset for the published Fusion package.

Files changed:
 .changeset/fn-6949-auto-merge-lifecycle.md         |   5 +
 .../src/__tests__/merge-error-recovery.test.ts     |  50 ++++-
 packages/engine/src/__tests__/merger-ai.test.ts    |   8 +-
 .../src/__tests__/merger-merge-lifecycle.test.ts   | 155 +++++++++++++++
 .../ai-merge-cleanup-enoent-idempotent.test.ts     |   2 +-
 packages/engine/src/__tests__/self-healing.test.ts | 194 +++++++++++--------
 packages/engine/src/auto-merge-finalization.ts     | 208 +++++++++++++++++++++
 packages/engine/src/merger-ai.ts                   |  47 +++--
 packages/engine/src/project-engine.ts              |  87 +++++----
 packages/engine/src/run-audit.ts                   |   4 +
 packages/engine/src/self-healing.ts                |  92 ++++-----
 11 files changed, 663 insertions(+), 189 deletions(-)

Fusion-Task-Id: FN-6949

Fusion-Task-Lineage: db784ec0-68e9-4a37-9728-daa6f133e294
2026-06-22 23:18:28 -07:00
gsxdsm
acf0fff413 test(engine): cover workflow cutover recovery guards 2026-06-22 22:22:37 -07:00
gsxdsm
e60b1378b8 fix(engine): address workflow cutover review feedback 2026-06-22 22:17:30 -07:00
gsxdsm
65c4dc5438 fix(engine): harden workflow runtime cutover 2026-06-22 21:45:05 -07:00
gsxdsm
bf3276295c fix(engine): complete workflow runtime cutover 2026-06-22 20:45:29 -07:00
gsxdsm
f9043d733e fix(dashboard): polish workflow and chrome defaults 2026-06-22 19:48:50 -07:00
gsxdsm
ec1d29e818 FN-6922: guard worktree acquisition returns from repo root
Prevent task worktree acquisition from handing the project root back to executors.

- Add a repo-root return guard across resume, pool, and fresh acquisition paths.
- Clear invalid repo-root task assignments and create a fresh worktree fallback when safe.
- Share repo-root canonicalization and expand regression coverage for acquisition liveness.
- Document the acquisition guard and add a patch changeset.

Files changed:
 .changeset/fn-6922-repo-root-acquisition-guard.md  |   5 +
 .../repo-root-task-worktree-requeue-loop.md        |   9 +-
 .../__tests__/executor-worktree-liveness.test.ts   |  35 +++
 .../worktree-acquisition-secrets-env.test.ts       |   9 +-
 .../src/__tests__/worktree-acquisition.test.ts     |  91 ++++++-
 packages/engine/src/worktree-acquisition.ts        | 272 +++++++++++++--------
 packages/engine/src/worktree-pool.ts               |   8 +-
 7 files changed, 304 insertions(+), 125 deletions(-)

Fusion-Task-Id: FN-6922

Fusion-Task-Lineage: c16cee1b-de16-4d5f-90e0-132f94fa8377
2026-06-22 19:11:08 -07:00
gsxdsm
4fd8d444fb fix(dashboard): polish app chrome and workflow defaults 2026-06-22 18:21:06 -07:00
gsxdsm
c229a15e20 FN-6934: restrict agent workflow reassignment
Clarify agent workflow-routing prompts so agents do not reassign tasks they did not create unless directed.

- Add executor guardrails against changing the current task workflow without explicit user instruction.
- Update triage workflow-routing guidance to distinguish existing tasks from agent-created tasks.
- Cover workflow ownership policy in prompt and engine tests, docs, and a patch changeset.

Files changed:
 .changeset/fn-6934-workflow-movement-policy.md     |  5 +++++
 docs/agents.md                                     |  6 ++++++
 docs/custom-workflow-reliability-acceptance-map.md |  7 +++++--
 docs/settings-reference.md                         |  9 +++++++--
 docs/workflow-steps.md                             |  9 +++++++--
 packages/core/src/__tests__/agent-prompts.test.ts  | 15 ++++++++++++++
 packages/core/src/agent-prompts.ts                 | 23 ++++++++++++++++------
 .../src/__tests__/executor-review-verdicts.test.ts |  3 +++
 .../__tests__/triage-threshold-settings.test.ts    |  3 +++
 packages/engine/src/__tests__/triage.test.ts       |  2 +-
 packages/engine/src/executor.ts                    |  5 +++++
 11 files changed, 74 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-6934

Fusion-Task-Lineage: cc583806-b160-4a08-b1a7-e798a575dbd5
2026-06-22 17:58:27 -07:00
gsxdsm
0b410d54e1 FN-6915: surface user comments in agent prompts
User task chat and steering comments now flow into planning, review, and merge agent context.

- Add a shared user-comment formatter and selector for prompt context.
- Inject latest user comments into planner-triggered review, reviewer, merger, and clean-room AI merge prompts.
- Cover comment selection, prompt formatting, review/merge propagation, and docs updates with targeted tests.

Files changed:
 docs/architecture.md                               |  1 +
 docs/dashboard-guide.md                            |  1 +
 .../src/__tests__/agent-user-comments.test.ts      | 81 ++++++++++++++++++++++
 .../executor-review-step-indexing.test.ts          | 28 +++++++-
 packages/engine/src/__tests__/merger-ai.test.ts    | 54 +++++++++++++++
 .../src/__tests__/merger-prompt-and-utils.test.ts  | 29 ++++++++
 packages/engine/src/__tests__/reviewer.test.ts     | 37 ++++++++--
 packages/engine/src/__tests__/triage.test.ts       | 23 ++++++
 packages/engine/src/agent-user-comments.ts         | 60 ++++++++++++++++
 packages/engine/src/executor.ts                    | 14 ++--
 packages/engine/src/merger-ai.ts                   | 23 +++++-
 packages/engine/src/merger.ts                      | 22 +++++-
 packages/engine/src/reviewer.ts                    | 13 ++++
 13 files changed, 372 insertions(+), 14 deletions(-)

Fusion-Task-Id: FN-6915

Fusion-Task-Lineage: 02de0c12-481a-4489-b495-70c9c00619bc
2026-06-22 03:34:15 -07:00
gsxdsm
af06170a51 FN-6778: add agent artifact registry tools
Adds engine and chat tools for registering, discovering, and viewing artifacts with inbox notifications.

- Add fn_artifact_register, fn_artifact_list, and fn_artifact_view tools for heartbeat, executor, and chat sessions.
- Send best-effort dashboard system inbox notifications when artifacts are registered.
- Classify artifact tools for action gating and coordination exemptions, with coverage for executor, heartbeat, permanent agent, and chat flows.
- Document the artifact registry behavior and update package metadata, quarantine ledger, and line-count baseline.

Files changed:
 .changeset/fn-6778-artifact-agent-tools.md         |   5 +
 CONCEPTS.md                                        |   3 +
 docs/agents.md                                     |   1 +
 packages/core/src/db.ts                            |   1 +
 .../src/__tests__/session-error-recovery.test.ts   |   1 +
 .../session-persistence-roundtrip.test.ts          |   1 +
 .../src/__tests__/session-reconnect.test.ts        |   1 +
 .../src/__tests__/session-resume-history.test.ts   |   1 +
 packages/dashboard/src/chat.ts                     |   6 +-
 packages/dashboard/src/planning.ts                 |   4 +
 packages/dashboard/src/test/mockCoreEngine.ts      |   1 +
 .../engine/src/__tests__/agent-action-gate.test.ts |   3 +
 .../src/__tests__/agent-artifact-tools.test.ts     | 458 +++++++++++++++++++++
 .../src/__tests__/executor-step-session.test.ts    |  48 +++
 .../src/__tests__/gating-classifications.test.ts   |   3 +
 .../src/__tests__/heartbeat-executor.test.ts       |  40 +-
 .../src/__tests__/heartbeat-session-prompt.test.ts |  25 +-
 .../src/__tests__/permanent-agent-gating.test.ts   |   6 +
 packages/engine/src/agent-heartbeat.ts             |   6 +-
 packages/engine/src/agent-tools.ts                 | 288 ++++++++++++-
 packages/engine/src/executor.ts                    |  25 ++
 packages/engine/src/gating-classifications.ts      |   7 +
 packages/engine/src/index.ts                       |   9 +
 scripts/lib/test-quarantine.json                   |   8 +-
 scripts/line-count-baseline.json                   |  54 +--
 25 files changed, 945 insertions(+), 60 deletions(-)

Fusion-Task-Id: FN-6778
Fusion-Task-Lineage: 7eb4afcb-8140-4f86-9540-eb3b83e64148
2026-06-22 03:34:14 -07:00
gsxdsm
3a71237624 fix(review): address PR #1717 Phase C merge-loop review feedback
- merger-ai: resolve+persist concrete landedSha when a sub-repo is recognized
  already-landed via the Fusion-Task-Id trailer fallback, so finalize no longer
  drops it and mis-finalizes a fully-landed workspace task as a no-op
- project-engine: manual-merge land-lease busy errors reject the resolver without
  burning mergeRetries; clear stale busy-reenqueue counter on real partial land;
  persist retry count before arming the backoff timer (fail closed on write error)
- cli/dashboard + task: use shared isWorkspaceTask predicate instead of inlining
- base-commit-capture: POSIX single-quote shell escaping for integration ref
- git-repository: validate workspace.json repos elements are strings
- merger-ai: drop dead store param from landOneRepo
- tests: assert the 60s backoff cap across cycles; exercise the real runAiMerge
  merge door; fix non-git-root assertion; re-export real workspace error classes
  in the merger-ai mock (fixes 24 pre-existing instanceof-undefined failures);
  remove generic fake-timer smoke test now covered by the live engine assertion

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 03:04:21 -07:00
gsxdsm
3fd7d12439 fix(review): address PR #1713 review feedback
Wrap the fatal-path acquisition observability writes (logEntry + audit.git)
in safeObserve so a store/audit throw can't replace the original
acquisition error, keeping WorkspaceRepoAcquireBusyError instanceof checks
reliable upstream.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 02:54:23 -07:00
gsxdsm
8e70d69601 fix(review): Phase D self-healing hardening — finalize-site audit, lease/TOCTOU safety
4-persona review of the Phase-D workspace self-healing. The headline: the P0
single-commit-finalize guard had to be applied across ALL surfaces, not just the
one reconciler U1 patched (FN-5893).

Finalize-site audit (A): gated every site where a workspace task could be
single-commit-finalized on one repo's commit — recoverStuckMergeDeadlocks (the
twin of the U1-patched reconciler, reachable via blocked-dependents),
recoverOrphanOnlyScopeViolations, recoverAlreadyMergedReviewTasks,
recoverBranchMisboundInReviewTasks (workspace tasks carry task.branch so the
Boolean(branch) filter didn't exclude them), plus a defensive filter on
finalizeNoOpReviewTasks. recoverMergedReviewTasks confirmed safe (mergeConfirmed
gate). Each is an isWorkspaceTask early-skip; single-repo behavior unchanged.

Reliability/concurrency:
- The partial-land reconciler now captures enqueueMerge's boolean and bounds
  re-enqueues (mergeStarvationDrops → fail after N) instead of looping silently
  forever on a full queue.
- The phantom-lease reclaim only acts on a terminal owner (null/done/failed) — it
  no longer reclaims the lease of an in-progress executing task that registered it
  early (shared isWorkspaceOwnerLive predicate).
- A new isMergePending(taskId) = mergeActive ∪ mergeQueue seam (exposed from
  ProjectEngine, wired through the runtime) guards both reconcilers against the
  merge-queue dispatch window — a task dequeued-but-not-yet-merging is no longer
  re-enqueued (which, since a same-task land lease isn't contention, could have
  caused a concurrent double-squash).
- FORK-A: a repo whose branch is gone and which isn't landed is parked, not
  re-enqueued forever. Orphan-worktree removal failures log.warn + bound.
  recoverDoneTaskMergeMetadata skips workspace tasks.

Maintainability: dissolved the self-healing↔merger-ai import cycle by moving
isRepoLanded into a dependency-free workspace-land-predicate.ts; removed a
redundant cast.

Gate green: build, typecheck, lint, test:gate (649+58); self-healing + e2e +
project-engine + merger 724.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 02:19:17 -07:00
gsxdsm
78d7a28f16 test(workspace): Phase D U2 — e2e merge + recovery harness (no-push invariant)
A real two-repo workspace lifecycle test in the engine-default lane (describeIfGit,
not the merge gate). Test 1 drives landWorkspaceTask on two acquired sub-repos and
asserts the NO-PUSH invariant directly: each sub-repo gets a real bare origin, and
the test snapshots every origin + remote-tracking ref before/after and asserts
byte-for-byte equality while the local refs/heads advance — a leaked push would
move an origin ref and fail. Plus per-repo landedSha and finalize-exactly-once.
Test 2 forces a repo-B conflict (repo A lands, task not done), then invokes the U1
reconcileWorkspacePartialLands reconciler under fake timers (enqueueMerge wired to
the real in-process route) and asserts recovery completes with no double-land of
repo A (its ref is unchanged from the first pass — proving the isRepoLanded skip).

Engine-default lane confirmed: test:gate stays 649+58 (did not enter engine-core).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 01:45:43 -07:00
gsxdsm
7cd204e4e5 feat(workspace): Phase D U1 — workspace-aware self-healing
Makes the self-healing layer workspace-aware and adds recovery for the states
Phase C introduced. No reconciler may wrongly finalize, skip, or move a workspace
task backward.

Existing reconcilers (the P0/P1 the feasibility check caught):
- recoverInterruptedMergingTasks no longer single-commit-finalizes a workspace
  task: a workspace candidate clears the transient "merging" status and re-enqueues
  via enqueueMerge (which routes to the idempotent landWorkspaceTask), never
  reaching findLandedTaskCommit / moveTask(done) / task:merged — so a partial-landed
  task (repo A landedSha, repo B not) is never marked fully merged on one repo's
  commit. recoverStaleMergingStatus confirmed single-commit-free.
- recoverMergeableReviewTasks relaxes its Boolean(t.worktree) gate to also admit
  isWorkspaceTask(t), so a zero-landed mergeable workspace task (null worktree) is
  re-enqueued instead of silently skipped forever.

New reconcilers:
- reconcileWorkspacePartialLands: re-enqueues stuck non-done workspace merges via
  enqueueMerge (idempotent skip of landed repos), guarded by allowsAutoMergeProcessing
  (FN-5147), user-pause, and a workspace-aware liveness predicate (any sub-repo path
  active via pathsForTask+isPathActive — triple-proof isn't workspace-aware). A repo
  with its fusion/<id> branch gone AND landedSha unset is parked failed; branch-gone
  but landed is skipped. Emits task:reconcile-workspace-partial-land(+-no-action).
- reclaimPhantomWorkspaceLandLeases: enumerates the new activeSessionRegistry
  entriesByKind("workspace-repo-land"), age-gated by the FN-6736 floor, and clears a
  lease whose owner is terminal/dead (live merging owners untouched). Emits
  task:reclaim-phantom-workspace-land-lease.
- reconcileOrphanedWorkspaceWorktrees: removes a done workspace task's recorded
  per-repo worktreePaths (isPathActive-guarded) with NO temp-root walk (AGENTS.md).
  Emits task:reconcile-orphaned-workspace-worktree.

New activeSessionRegistry.entriesByKind seam; four DatabaseMutationType literals +
the AGENTS.md Run Audit list. Single-repo behavior byte-for-byte unchanged (every
path branches on isWorkspaceTask). 13 new fixture tests; 558 self-healing tests +
test:gate (649+58) green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 01:37:59 -07:00