From 923a7c0fc991472dea3cf63c38e5223e79a41209 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Mon, 27 Jul 2026 14:44:28 -0700 Subject: [PATCH] U4 trim: delete the dead resetStepsIfWorkLost duplicate in self-healing (#2474) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stacked on #2472 (Phase B slice B3.1). Base is `feature/workflow-vocabulary-b3-stranded-todo` — do not merge before it. First output of the **U4 reshape survey**: dead code removed with reachability evidence, not a redundancy argument. ## What is deleted **`SelfHealingManager.resetStepsIfWorkLost`** — 50 lines including its docblock and a section header left with no other member. Evidence: - `private`, with **zero in-file references** beyond its own declaration. - TypeScript already reported it as `declared but its value is never read` — the compiler has been flagging this. - The **live** implementation is `executor.ts:20080`, an independent copy that `executor.ts` actually calls (12667, 14664). The self-healing copy is an orphaned duplicate of it. - Not in either sweep registry, no test of its own, no caller anywhere in engine / dashboard / cli. Safe against every U4 constraint: it enforces none of user pause, `autoMerge:false`, dependency, capacity, merge-proof, or an at-most-once safeguard. ## Why the second approved deletion is NOT here `surfaceDependencyBlockedTodos` was approved alongside this one as a 28-line orphan. It is not. On inspection it is the **tip of an entire unreachable feature**: ``` surfaceDependencyBlockedTodos (in NEITHER registry, no production caller) └─ getDependencyBlockedTodoReporter() ← sole caller └─ engine/dependency-blocked-todo-reporter.ts 223 lines ← sole caller of ↓ └─ core/dependency-blocked-todo-report.ts 184 lines ``` ≈ **450 production lines across three files, plus 684 lines of tests in four files.** The operator-visible setting `dependencyBlockedTodoReportEnabled` defaults `true` in `settings-schema.ts` and drives nothing. Deleting only the approved 28-line tip would be **strictly worse than leaving it** — it orphans the getter and field and strands 407 lines of module with no remaining reference to explain why. Escalated for a decision (delete the subtree / wire the feature up / leave it) rather than resolved unilaterally. ## Verification - `tsc --noEmit` clean, `pnpm lint` clean - self-healing suite: **415 passed**, 1 failure **pre-existing** (`archiveStaleDoneTasks` — fails identically before this change) No changeset: `@fusion/engine` is private. 🤖 Generated with [Claude Code](https://claude.com/claude-code) ## Summary by CodeRabbit * **Behavior Changes** * Removed automatic detection and reset of task steps when no unique work is found on a task branch. * Tasks with completed or in-progress steps will no longer be automatically returned to pending based on this condition. --- packages/engine/src/self-healing.ts | 52 ----------------------------- 1 file changed, 52 deletions(-) diff --git a/packages/engine/src/self-healing.ts b/packages/engine/src/self-healing.ts index 229cc22ebd..f37ffb347f 100644 --- a/packages/engine/src/self-healing.ts +++ b/packages/engine/src/self-healing.ts @@ -1986,58 +1986,6 @@ export class SelfHealingManager { } } - // ── Lost work detection ──────────────────────────────────────────── - - /** - * Check whether a task's branch has any unique commits compared to main. - * If the branch has no unique commits and the task has steps marked done, - * those steps represent lost uncommitted work — reset them to "pending" - * so the next execution doesn't skip them. - */ - private async resetStepsIfWorkLost(task: Task): Promise { - const completedSteps = task.steps.filter( - (s) => s.status === "done" || s.status === "in-progress", - ); - if (completedSteps.length === 0) return; - - const branchName = resolveTaskWorkingBranch(task); - - try { - const { stdout: mergeBaseOut } = await execAsync( - `git merge-base "${branchName}" HEAD`, - { cwd: this.options.rootDir, encoding: "utf-8", timeout: 30_000 }, - ); - const mergeBase = mergeBaseOut.trim(); - const { stdout: branchHeadOut } = await execAsync( - `git rev-parse "${branchName}"`, - { cwd: this.options.rootDir, encoding: "utf-8", timeout: 30_000 }, - ); - const branchHead = branchHeadOut.trim(); - - if (mergeBase === branchHead) { - log.warn( - `${task.id} branch has no unique commits — resetting ${completedSteps.length} step(s) to pending`, - ); - - for (let i = 0; i < task.steps.length; i++) { - if (task.steps[i].status === "done" || task.steps[i].status === "in-progress") { - await this.store.updateStep(task.id, i, "pending"); - } - } - - await this.store.logEntry( - task.id, - `Reset ${completedSteps.length} step(s) to pending — branch had no commits (uncommitted work lost with worktree)`, - ); - } - } catch (err: unknown) { - const errorMessage = err instanceof Error ? err.message : String(err); - log.warn( - `Failed to reset steps for ${task.id} after branch/worktree loss (${branchName}): ${errorMessage} — non-fatal`, - ); - } - } - // ── Periodic maintenance ────────────────────────────────────────── private async startMaintenance(): Promise {