From 8fe69ac5c8f2a5ac7596e54c237cb73ef1821d1b Mon Sep 17 00:00:00 2001 From: Phil Larson Date: Fri, 21 Aug 2026 19:31:08 -0700 Subject: [PATCH] test: align workspace callback fixtures and gate (#3500) ## Summary - update workspace worktree test stores for callback-based entry mutations - preserve validation, existing-entry, and singular-routing behavior in the fakes - canonicalize the macOS worktree path fixture before comparing persisted state - remove the stale inert-seam exception left after the review-column callback became fully supplied ## Test plan - `pnpm --filter @fusion/engine exec vitest run src/__tests__/node-worktree-isolation.test.ts src/__tests__/workspace-root-worktree-routing.test.ts src/__tests__/worktree-acquisition.test.ts --silent=passed-only --reporter=dot` - `pnpm --filter @fusion/engine exec vitest run src/__tests__/worktree-acquisition-workspace.test.ts --silent=passed-only --reporter=dot` - Directly changed engine workspace suite with PostgreSQL-dependent blocks skipped: 338 passed, 4 skipped - `pnpm --filter @fusion/engine typecheck` - `node scripts/check-inert-flag-seams.mjs` - `node --test scripts/__tests__/check-inert-flag-seams.test.mjs` - `pnpm lint` - `pnpm check:changesets` ## Summary by CodeRabbit * **Bug Fixes** * Improved recovery of orphaned worktrees by consistently using canonical paths. * Strengthened worktree assignment and updates to preserve existing entries and prevent stale task state. * Improved synchronization and validation during concurrent workspace updates. * Refined self-healing recovery so branch metadata changes only when necessary. * Improved handling of stalled tasks, retry exhaustion, and clearing obsolete worktree or branch information. --- .../src/__tests__/executor-test-helpers.ts | 57 ++++++-- .../src/__tests__/executor-worktree.test.ts | 73 ++++++++++ .../engine/src/__tests__/self-healing.test.ts | 81 ++++++----- .../workspace-root-worktree-routing.test.ts | 127 ++++++++++++++++-- .../__tests__/worktree-acquisition.test.ts | 5 +- scripts/check-inert-flag-seams.mjs | 18 +-- scripts/lib/lane-wiring-baseline.json | 1 + 7 files changed, 287 insertions(+), 75 deletions(-) diff --git a/packages/engine/src/__tests__/executor-test-helpers.ts b/packages/engine/src/__tests__/executor-test-helpers.ts index fa48f67084..b31945f505 100644 --- a/packages/engine/src/__tests__/executor-test-helpers.ts +++ b/packages/engine/src/__tests__/executor-test-helpers.ts @@ -1,5 +1,6 @@ import { vi } from "vitest"; import type { Mock } from "vitest"; +import type { Task } from "@fusion/core"; import { installTaskWorktreeIdentityGuard } from "../worktree/worktree-hooks.js"; import type * as ReviewerModule from "../execution/reviewer.js"; @@ -553,6 +554,13 @@ export function createMockStore() { `getTask`/`updateTask` implementations replace these outright and are unaffected. */ const patches = new Map>(); + /* + FNXC:EngineTests 2026-08-21-08:34: + The shared executor store fake must preserve TaskStore's per-task atomic merge contract. Queue merge + calls and re-read after an async callback so sibling merges and simulated external task updates cannot + be overwritten by a stale workspaceWorktrees snapshot. + */ + const workspaceMergeTails = new Map>(); const applyPatch = (id: string, patch: Record | undefined) => { if (!patch || typeof patch !== "object") return; patches.set(id, { ...(patches.get(id) ?? {}), ...patch }); @@ -672,17 +680,46 @@ export function createMockStore() { applyPatch(id, patch); return { ...(patches.get(id) ?? {}), id }; }), - mergeWorkspaceWorktreeEntry: vi.fn(async (id: string, repoRelPath: string, patch: Record) => { - const live = await store.getTask(id); - const workspaceWorktrees = (live?.workspaceWorktrees ?? {}) as Record; - const existing = workspaceWorktrees[repoRelPath]; - applyPatch(id, { - workspaceWorktrees: { - ...workspaceWorktrees, - [repoRelPath]: { ...(existing && typeof existing === "object" ? existing : {}), ...patch }, - }, + mergeWorkspaceWorktreeEntry: vi.fn(( + id: string, + repoRelPath: string, + patch: Partial[string]> + | ((current: Task) => Promise[string]>>), + options?: { + requireExistingEntry?: boolean; + clearSingularWorktree?: boolean; + validateBeforePersist?: (current: Task) => Promise; + }, + ) => { + const operation = (workspaceMergeTails.get(id) ?? Promise.resolve()).then(async () => { + const callbackTask = await store.getTask(id) as Task; + const callbackExisting = callbackTask.workspaceWorktrees?.[repoRelPath]; + if (options?.requireExistingEntry && !callbackExisting) return callbackTask; + const resolvedPatch = typeof patch === "function" ? await patch(callbackTask) : patch; + const current = await store.getTask(id) as Task; + const workspaceWorktrees = current.workspaceWorktrees ?? {}; + const existing = workspaceWorktrees[repoRelPath]; + if (options?.requireExistingEntry && !existing) return current; + await options?.validateBeforePersist?.(current); + applyPatch(id, { + workspaceWorktrees: { + ...workspaceWorktrees, + [repoRelPath]: { ...existing, ...resolvedPatch }, + }, + ...(options?.clearSingularWorktree + ? { + worktree: null, + branch: null, + branchWriteOrigin: "engine", + executionStartBranch: null, + baseCommitSha: null, + } + : {}), + }); + return store.getTask(id); }); - return store.getTask(id); + workspaceMergeTails.set(id, operation.then(() => undefined, () => undefined)); + return operation; }), updateWorkspaceReviewState: vi.fn(async (id: string, _revision: number, reviewRemediation: unknown) => { const current = await store.getTask(id); diff --git a/packages/engine/src/__tests__/executor-worktree.test.ts b/packages/engine/src/__tests__/executor-worktree.test.ts index d49d393449..3c4dc45b59 100644 --- a/packages/engine/src/__tests__/executor-worktree.test.ts +++ b/packages/engine/src/__tests__/executor-worktree.test.ts @@ -66,6 +66,79 @@ function createWorktreeExecutor(store: any, rootDir: string, options: any = {}) } describe("worktree workflow routing fixture", () => { + /* + FNXC:EngineTests 2026-08-21-08:34: + The shared executor fake is a production-contract seam: concurrent callback merges must preserve + every repository entry, missing required entries are no-ops, and workspace routing clears all + singular-checkout metadata. + + FNXC:EngineTests 2026-08-21-09:29: + Cleared singular-checkout metadata must use null, matching the persisted TaskStore row shape; + undefined would let fixture-only behavior diverge from production reads. + */ + it("mirrors atomic workspace worktree merge semantics", async () => { + const store = createMockStore(); + store._setRow("FN-workspace-merge", { + worktree: "/tmp/singular", + branch: "fusion/singular", + executionStartBranch: "main", + baseCommitSha: "base", + workspaceWorktrees: {}, + }); + + const missing = await store.mergeWorkspaceWorktreeEntry( + "FN-workspace-merge", + "missing", + { worktreePath: "/tmp/missing" }, + { requireExistingEntry: true }, + ); + expect(missing.workspaceWorktrees?.missing).toBeUndefined(); + + let releaseFirst!: () => void; + let markFirstStarted!: () => void; + const firstGate = new Promise((resolve) => { releaseFirst = resolve; }); + const firstStarted = new Promise((resolve) => { markFirstStarted = resolve; }); + const first = store.mergeWorkspaceWorktreeEntry( + "FN-workspace-merge", + "repo-a", + async () => { + markFirstStarted(); + await firstGate; + return { worktreePath: "/tmp/repo-a", branch: "fusion/a" }; + }, + ); + await firstStarted; + store._setRow("FN-workspace-merge", { + workspaceWorktrees: { + "repo-c": { worktreePath: "/tmp/repo-c", branch: "fusion/c" }, + }, + }); + + let secondStarted = false; + const second = store.mergeWorkspaceWorktreeEntry( + "FN-workspace-merge", + "repo-b", + async (freshTask: Task) => { + secondStarted = true; + expect(freshTask.workspaceWorktrees?.["repo-a"]?.worktreePath).toBe("/tmp/repo-a"); + return { worktreePath: "/tmp/repo-b", branch: "fusion/b" }; + }, + { clearSingularWorktree: true }, + ); + + await Promise.resolve(); + expect(secondStarted).toBe(false); + releaseFirst(); + const [, result] = await Promise.all([first, second]); + + expect(Object.keys(result.workspaceWorktrees ?? {}).sort()).toEqual(["repo-a", "repo-b", "repo-c"]); + expect(result).toEqual(expect.objectContaining({ branchWriteOrigin: "engine" })); + expect(result.worktree).toBeNull(); + expect(result.branch).toBeNull(); + expect(result.executionStartBranch).toBeNull(); + expect(result.baseCommitSha).toBeNull(); + }); + it("selects its eligible executor from the role pool", async () => { const store = createMockStore(); const fixture = createWorkflowRoutingAgentStore(store); diff --git a/packages/engine/src/__tests__/self-healing.test.ts b/packages/engine/src/__tests__/self-healing.test.ts index d751fed5d1..a566c4f89b 100644 --- a/packages/engine/src/__tests__/self-healing.test.ts +++ b/packages/engine/src/__tests__/self-healing.test.ts @@ -2673,6 +2673,11 @@ describe("SelfHealingManager", () => { expect(store.archiveTaskAndCleanup).not.toHaveBeenCalledWith("FN-100"); }); + /* + FNXC:SelfHealing 2026-08-21-08:44: + Archive retry tests must drive past the prior failure budget on one manager instance. Separate + task IDs make same-reason exhaustion and failure-class reset independently observable. + */ it("bounds same-reason archive failures and resets the budget when the failure class changes", async () => { vi.setSystemTime(new Date("2026-01-04T00:00:00.000Z")); (store.getSettings as ReturnType).mockResolvedValue({ @@ -2680,28 +2685,29 @@ describe("SelfHealingManager", () => { autoArchiveDoneAfterMs: 24 * 60 * 60 * 1000, doneAutoArchiveDays: 0, } as unknown as Settings); - const stale = [{ id: "FN-RETRY", column: "done", columnMovedAt: "2026-01-02T00:00:00.000Z", updatedAt: "2026-01-02T00:00:00.000Z" }]; + const stale = [ + { id: "FN-BOUNDED", column: "done", columnMovedAt: "2026-01-02T00:00:00.000Z", updatedAt: "2026-01-02T00:00:00.000Z" }, + { id: "FN-CHANGING", column: "done", columnMovedAt: "2026-01-02T00:00:00.000Z", updatedAt: "2026-01-02T00:00:00.000Z" }, + ]; (store.listTasks as ReturnType).mockResolvedValue(stale); - (store.archiveTaskAndCleanup as ReturnType).mockRejectedValue(new Error("disk busy")); + const changingFailures = [ + new Error("disk busy"), + new Error("disk busy"), + Object.assign(new Error("live"), { name: "TaskIsLiveError" }), + new Error("disk busy"), + new Error("disk busy"), + new Error("disk busy"), + ]; + (store.archiveTaskAndCleanup as ReturnType).mockImplementation(async (id: string) => { + if (id === "FN-BOUNDED") throw new Error("disk busy"); + throw changingFailures.shift() ?? new Error("disk busy"); + }); for (let index = 0; index < 10; index++) await manager.archiveStaleDoneTasks(); - expect(store.archiveTaskAndCleanup).toHaveBeenCalledTimes(3); - - (store.archiveTaskAndCleanup as ReturnType).mockClear(); - const taskLive = Object.assign(new Error("live"), { name: "TaskIsLiveError" }); - (store.archiveTaskAndCleanup as ReturnType) - .mockRejectedValueOnce(new Error("disk busy")) - .mockRejectedValueOnce(taskLive) - .mockRejectedValueOnce(new Error("disk busy")); - const managerWithChangingFailure = new SelfHealingManager(store, { rootDir: "/tmp/test-project" }); - - await managerWithChangingFailure.archiveStaleDoneTasks(); - await managerWithChangingFailure.archiveStaleDoneTasks(); - await managerWithChangingFailure.archiveStaleDoneTasks(); - - expect(store.archiveTaskAndCleanup).toHaveBeenCalledTimes(3); - managerWithChangingFailure.stop(); + const calls = (store.archiveTaskAndCleanup as ReturnType).mock.calls; + expect(calls.filter(([id]) => id === "FN-BOUNDED")).toHaveLength(3); + expect(calls.filter(([id]) => id === "FN-CHANGING")).toHaveLength(6); }); it("escalates an exhausted archive budget once without letting log or audit failures stop other archives", async () => { @@ -2742,23 +2748,29 @@ describe("SelfHealingManager", () => { autoArchiveDoneAfterMs: 24 * 60 * 60 * 1000, doneAutoArchiveDays: 0, } as unknown as Settings); - const stale = [{ id: "FN-RESET", column: "done", columnMovedAt: "2026-01-02T00:00:00.000Z", updatedAt: "2026-01-02T00:00:00.000Z" }]; + const successTask = { id: "FN-RESET-SUCCESS", column: "done", columnMovedAt: "2026-01-02T00:00:00.000Z", updatedAt: "2026-01-02T00:00:00.000Z" }; + const candidateTask = { id: "FN-RESET-CANDIDATE", column: "done", columnMovedAt: "2026-01-02T00:00:00.000Z", updatedAt: "2026-01-02T00:00:00.000Z" }; (store.listTasks as ReturnType) - .mockResolvedValueOnce(stale) - .mockResolvedValueOnce(stale) - .mockResolvedValueOnce([]) - .mockResolvedValueOnce(stale); - (store.archiveTaskAndCleanup as ReturnType) - .mockRejectedValueOnce(new Error("disk busy")) - .mockResolvedValueOnce({}) - .mockRejectedValueOnce(new Error("disk busy")); + .mockResolvedValueOnce([successTask, candidateTask]) + .mockResolvedValueOnce([successTask, candidateTask]) + .mockResolvedValueOnce([successTask]) + .mockResolvedValueOnce([successTask, candidateTask]) + .mockResolvedValueOnce([successTask, candidateTask]) + .mockResolvedValueOnce([successTask, candidateTask]); + let successCalls = 0; + (store.archiveTaskAndCleanup as ReturnType).mockImplementation(async (id: string) => { + if (id === "FN-RESET-SUCCESS") { + successCalls++; + if (successCalls === 3) return {}; + } + throw new Error("disk busy"); + }); - await manager.archiveStaleDoneTasks(); - await manager.archiveStaleDoneTasks(); - await manager.archiveStaleDoneTasks(); - await manager.archiveStaleDoneTasks(); + for (let index = 0; index < 6; index++) await manager.archiveStaleDoneTasks(); - expect(store.archiveTaskAndCleanup).toHaveBeenCalledTimes(3); + const calls = (store.archiveTaskAndCleanup as ReturnType).mock.calls; + expect(calls.filter(([id]) => id === "FN-RESET-SUCCESS")).toHaveLength(6); + expect(calls.filter(([id]) => id === "FN-RESET-CANDIDATE")).toHaveLength(5); }); it("skips stale done lineage parents, including complete children, without blocking unrelated archives", async () => { @@ -4251,6 +4263,11 @@ describe("SelfHealingManager", () => { worktree: null, sessionFile: null, })); + const workspacePatch = (store.updateTask as ReturnType).mock.calls + .find(([taskId]) => taskId === "FN-7802-WORKSPACE")?.[1]; + // FNXC:WorkspaceRecovery 2026-08-21-08:44: Prove recovery emitted the workspace patch before asserting that it preserves repository routing. + expect(workspacePatch).toBeDefined(); + expect(workspacePatch).not.toHaveProperty("branch"); expect(store.moveTask).toHaveBeenCalledWith("FN-7802-WORKSPACE", "todo", { preserveProgress: true, moveSource: "engine", recoveryRehome: true }); expect(store.recordRunAuditEvent).toHaveBeenCalledWith(expect.objectContaining({ mutationType: "task:reconcile-missing-worktree-merge-active", diff --git a/packages/engine/src/__tests__/workspace-root-worktree-routing.test.ts b/packages/engine/src/__tests__/workspace-root-worktree-routing.test.ts index e0a30a3785..4910e85185 100644 --- a/packages/engine/src/__tests__/workspace-root-worktree-routing.test.ts +++ b/packages/engine/src/__tests__/workspace-root-worktree-routing.test.ts @@ -19,6 +19,12 @@ const describeIfGit = hasGit ? describe : describe.skip; function makeFakeStore(task: Task): { store: TaskStore; current: () => Task } { let current = task; + /* + FNXC:WorkspaceRootRouting 2026-08-21-08:34: + This focused routing fake mirrors TaskStore's per-task merge lock and post-callback authoritative + re-read so callback-based acquisitions cannot clobber sibling entries or external task updates. + */ + let workspaceMergeTail = Promise.resolve(); const store = { async updateTask(id: string, patch: Partial): Promise { if (id === current.id) current = { ...current, ...patch }; @@ -26,20 +32,46 @@ function makeFakeStore(task: Task): { store: TaskStore; current: () => Task } { async mergeWorkspaceWorktreeEntry( id: string, repoRelPath: string, - patch: Partial[string]>, - options?: { clearSingularWorktree?: boolean }, + patch: Partial[string]> + | ((freshTask: Task) => Promise[string]>>), + options?: { + requireExistingEntry?: boolean; + clearSingularWorktree?: boolean; + validateBeforePersist?: (freshTask: Task) => Promise; + }, ): Promise { - if (id !== current.id) throw new Error(`Task ${id} not found`); - const existing = current.workspaceWorktrees?.[repoRelPath]; - current = { - ...current, - workspaceWorktrees: { - ...(current.workspaceWorktrees ?? {}), - [repoRelPath]: { ...existing, ...patch }, - }, - ...(options?.clearSingularWorktree ? { worktree: undefined, branch: undefined } : {}), - }; - return current; + const operation = workspaceMergeTail.then(async () => { + if (id !== current.id) throw new Error(`Task ${id} not found`); + const existing = current.workspaceWorktrees?.[repoRelPath]; + if (options?.requireExistingEntry && !existing) return current; + const callbackTask = current; + const resolvedPatch = typeof patch === "function" ? await patch(callbackTask) : patch; + const freshExisting = current.workspaceWorktrees?.[repoRelPath]; + if (options?.requireExistingEntry && !freshExisting) return current; + await options?.validateBeforePersist?.(current); + current = { + ...current, + workspaceWorktrees: { + ...(current.workspaceWorktrees ?? {}), + [repoRelPath]: { + ...freshExisting, + ...resolvedPatch, + } as NonNullable[string], + }, + ...(options?.clearSingularWorktree + ? { + worktree: null, + branch: null, + branchWriteOrigin: "engine" as const, + executionStartBranch: null, + baseCommitSha: null, + } + : {}), + }; + return current; + }); + workspaceMergeTail = operation.then(() => undefined, () => undefined); + return operation; }, async logEntry(): Promise {}, async getTask(id: string): Promise { @@ -65,6 +97,73 @@ function makeTask(id: string): Task { } as Task; } +describe("workspace root routing store fake", () => { + /* + FNXC:WorkspaceRootRouting 2026-08-21-08:34: + The focused routing fake must hold the same concurrent-merge invariant as the shared executor fake; + exercising both surfaces prevents one fixture from silently reverting to stale snapshot writes. + + FNXC:WorkspaceRootRouting 2026-08-21-16:42: + Clearing singular routing metadata must return null on this focused fake, matching persisted TaskStore + reads and the shared executor fake instead of exposing fixture-only undefined values. + */ + it("serializes callback merges without dropping sibling repository entries", async () => { + const task = makeTask("FN-routing-merge"); + Object.assign(task, { + worktree: "/tmp/singular", + branch: "fusion/singular", + executionStartBranch: "main", + baseCommitSha: "base", + }); + const { store, current } = makeFakeStore(task); + let releaseFirst!: () => void; + let markFirstStarted!: () => void; + const firstGate = new Promise((resolve) => { releaseFirst = resolve; }); + const firstStarted = new Promise((resolve) => { markFirstStarted = resolve; }); + + const first = store.mergeWorkspaceWorktreeEntry( + "FN-routing-merge", + "repo-a", + async () => { + markFirstStarted(); + await firstGate; + return { worktreePath: "/tmp/repo-a", branch: "fusion/a" }; + }, + ); + await firstStarted; + await store.updateTask("FN-routing-merge", { + workspaceWorktrees: { + "repo-c": { worktreePath: "/tmp/repo-c", branch: "fusion/c" }, + }, + }); + + let secondStarted = false; + const second = store.mergeWorkspaceWorktreeEntry( + "FN-routing-merge", + "repo-b", + async (freshTask) => { + secondStarted = true; + expect(freshTask.workspaceWorktrees?.["repo-a"]?.worktreePath).toBe("/tmp/repo-a"); + return { worktreePath: "/tmp/repo-b", branch: "fusion/b" }; + }, + { clearSingularWorktree: true }, + ); + + await Promise.resolve(); + expect(secondStarted).toBe(false); + releaseFirst(); + await Promise.all([first, second]); + expect(Object.keys(current().workspaceWorktrees ?? {}).sort()).toEqual(["repo-a", "repo-b", "repo-c"]); + expect(current()).toEqual(expect.objectContaining({ + worktree: null, + branch: null, + branchWriteOrigin: "engine", + executionStartBranch: null, + baseCommitSha: null, + })); + }); +}); + const settings: Partial = { worktreeNaming: "task-id", commitMsgHookEnabled: true, @@ -127,7 +226,7 @@ describeIfGit("FN-034 workspace root worktree routing", { timeout: 60_000 }, () expect(result.coordinatorWorktreePath).toBe(result.task.workspaceWorktrees?.["repo-b"]?.worktreePath); expect(result.coordinatorWorktreePath).not.toContain(join(fixture.rootDir, ".worktrees")); - expect(result.task.worktree).toBeUndefined(); + expect(result.task.worktree).toBeNull(); }); it("rejects a stale review target instead of falling back to another repository", async () => { diff --git a/packages/engine/src/__tests__/worktree-acquisition.test.ts b/packages/engine/src/__tests__/worktree-acquisition.test.ts index a01d51464a..6cda46f49c 100644 --- a/packages/engine/src/__tests__/worktree-acquisition.test.ts +++ b/packages/engine/src/__tests__/worktree-acquisition.test.ts @@ -244,6 +244,7 @@ describe("acquireTaskWorktree", () => { writeFileSync(join(orphanedPath, "preserved.txt"), "keep this checkout\n", "utf-8"); git(orphanedPath, "git add preserved.txt"); git(orphanedPath, 'git commit -m "FN-1: preserved pre-fix work"'); + const canonicalOrphanedPath = realpathSync(orphanedPath); const preservedTip = git(orphanedPath, "git rev-parse HEAD"); const createWorktree = vi.fn(); @@ -255,11 +256,11 @@ describe("acquireTaskWorktree", () => { createWorktree, }); - expect(result).toMatchObject({ worktreePath: orphanedPath, branch: "fusion/fn-1", source: "existing" }); + expect(result).toMatchObject({ worktreePath: canonicalOrphanedPath, branch: "fusion/fn-1", source: "existing" }); expect(git(orphanedPath, "git rev-parse HEAD")).toBe(preservedTip); expect(createWorktree).not.toHaveBeenCalled(); expect(store.updateTask).toHaveBeenCalledWith("FN-1", { - worktree: orphanedPath, + worktree: canonicalOrphanedPath, branch: "fusion/fn-1", branchWriteOrigin: "engine", }); diff --git a/scripts/check-inert-flag-seams.mjs b/scripts/check-inert-flag-seams.mjs index 2ed9552e20..6ae66617b4 100644 --- a/scripts/check-inert-flag-seams.mjs +++ b/scripts/check-inert-flag-seams.mjs @@ -91,23 +91,7 @@ export function effectiveArgCount(args) { const PREFILTER = /(olumnFlags|ifecycleColumns|eviewColumns|erminalColumns|lannerLanes|isplayColumnOptions)/; /** Known-unsupplied seams, each with why it is tolerated. Shrink this list; never grow it casually. */ -const ALLOWED = new Map([ - /* - TEMPORARY — real offenders in packages owned by other batches, reported to them rather than edited - from outside. Remove each entry when that batch wires or deletes the parameter; the check will then - start guarding those files too. All three are the same shape this check exists to catch. - */ - [ - "isRecoverableMissingWorktreeReviewFailure", - "No production caller; 5 test call sites. The previous entry blamed the scanner for excluding " - + "__tests__ — that reason was wrong, the scan now reads tests and the count is real. The two " - + "SIBLINGS it delegates to (`...WithProgress` / `...NoProgress`) are the live pair, called from " - + "self-healing.ts and both supplying `reviewColumns`. This is the convenience wrapper over them, " - + "kept as a public predicate and exercised only by its own tests. Engine-owned; left alone.", - ], - - -]); +const ALLOWED = new Map([]); /* PARTIAL-SUPPLY exemptions are keyed by CALL SITE, not by function name. diff --git a/scripts/lib/lane-wiring-baseline.json b/scripts/lib/lane-wiring-baseline.json index fdbec08a0e..59fc6102fb 100644 --- a/scripts/lib/lane-wiring-baseline.json +++ b/scripts/lib/lane-wiring-baseline.json @@ -7,6 +7,7 @@ "packages/core/src/task-store/task-update.ts": 1, "packages/engine/src/merge/auto-merge-finalization.ts": 1, "packages/engine/src/project-engine.ts": 1, + "packages/engine/src/self-healing.ts": 1, "packages/engine/src/runtimes/in-process-runtime.ts": 1, "packages/engine/src/self-healing.ts": 1, "packages/dashboard/src/routes/register-task-workflow-routes.ts": 1,