From c92bce2f8ca6638923bd9c3ed17b5d1ddae9892d Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Wed, 29 Jul 2026 10:22:46 -0700 Subject: [PATCH] test: delete 2 project-engine-manager tests for the deleted cross-project cap (#2575) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Test-only.** One file, 2 obsolete tests + 1 dead import removed. No production change. `project-engine-manager.test.ts` has been **red on main: 2 failed / 44 passed** → now **44 passed**. ## The failures Both threw `TypeError: Cannot read properties of undefined (reading 'acquire')`, because both reach `(manager as any).globalSemaphore` — a private field that no longer exists. `project-engine-manager.ts:88` records why (`FNXC:CapacityModel 2026-07-28-20:10`, *"drop the cross-project cap"*): > The shared cross-project semaphore, its mutable limit and the `concurrency:changed` subscription are **DELETED**. Capacity is two numbers per project; a machine-wide cap was a third limiter with its own separate authority (a central-DB singleton row), and reconciling it against the per-project gates is exactly the multi-limiter arbitration this simplification removes. So both tests assert residual-slot accounting on a shared pool that was **deliberately** removed — not a regression. ## Why deleted rather than repaired There is no shared semaphore left for them to describe. Reconstructing one inside the test would assert a capacity model the engine no longer has — a test that passes while describing fiction, which is worse than the red it replaces. Also drops the now-dead `ScopedAgentSemaphore` import (these were its only uses). Lint does not flag unused imports here, so it would otherwise have sat as quiet dead code. ## What I did NOT take, and why `workflow-graph-optional-step-fix.test.ts` — the other red file adjacent to this lane, 5 failures. Its failures are **U11 column-vocabulary drift**: the replan rebound now resolves to `todo` where the test expects `triage`, and one case gets a hard-cancel pause-abort log instead of the Plan Review replan message. That is the U11/U12 owner's semantics to settle. Picking whichever column makes the assertion pass could silently encode the wrong lifecycle target — and per the graph-entry contract doc, a rebound landing in a column the workflow does not declare is precisely the failure mode that "does not fail a test; it disables a recovery path in production." Flagging it rather than guessing. ## Running tally of this cleanup thread | File | Before | After | |---|---|---| | 27 logger mocks (#2573) | 206 failed | 4 failed | | `merge-error-recovery` (#2559) | 10 failed | 0 | | `reviewer` (#2547) | 2 failed | 0 | | `project-engine-manager` (this) | 2 failed | 0 | Every one was a test describing behavior that had moved or been deleted, or a mock that had drifted from its real shape — none was a product defect. That pattern is worth naming: on this repo a red non-blocking suite has mostly meant *stale tests*, which is exactly what makes it easy to ignore, and exactly why it silently corrupted my own safeguard measurements in #2511. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5 (1M context) --- .../__tests__/project-engine-manager.test.ts | 58 ------------------- 1 file changed, 58 deletions(-) diff --git a/packages/engine/src/__tests__/project-engine-manager.test.ts b/packages/engine/src/__tests__/project-engine-manager.test.ts index f6906bf7d7..a283545674 100644 --- a/packages/engine/src/__tests__/project-engine-manager.test.ts +++ b/packages/engine/src/__tests__/project-engine-manager.test.ts @@ -42,7 +42,6 @@ import { EngineAlreadyRunningError, } from "../engine-singleton-lock.js"; import type { RegisteredProject, CentralCore } from "@fusion/core"; -import { ScopedAgentSemaphore } from "../concurrency.js"; function createMockCentralCore(projects: RegisteredProject[]): CentralCore { const projectMap = new Map(projects.map((p) => [p.id, p])); @@ -322,33 +321,6 @@ describe("ProjectEngineManager", () => { expect(offlineOrder).toBeLessThan(engineStopOrder); }); - it("stopAll frees residual slots from each stopped project scope", async () => { - const manager = new ProjectEngineManager(centralCore); - await manager.startAll(); - const engineA = manager.getEngine("proj_aaa")!; - const engineB = manager.getEngine("proj_bbb")!; - const sharedSemaphore = (manager as any).globalSemaphore; - const scopeA = new ScopedAgentSemaphore(sharedSemaphore); - const scopeB = new ScopedAgentSemaphore(sharedSemaphore); - - await scopeA.acquire(); - await scopeB.acquire(); - expect(sharedSemaphore.activeCount).toBe(2); - - (engineA.stop as ReturnType).mockImplementationOnce(async () => { - scopeA.returnAllHeldSlots(); - }); - (engineB.stop as ReturnType).mockImplementationOnce(async () => { - scopeB.returnAllHeldSlots(); - }); - - await manager.stopAll(); - - expect(scopeA.heldCount).toBe(0); - expect(scopeB.heldCount).toBe(0); - expect(sharedSemaphore.activeCount).toBe(0); - expect(sharedSemaphore.availableCount).toBe(4); - }); it("handles stop errors gracefully", async () => { const manager = new ProjectEngineManager(centralCore); @@ -420,36 +392,6 @@ describe("ProjectEngineManager", () => { expect(manager.getEngine("proj_aaa")).toBeUndefined(); }); - it("frees only the paused project's residual shared semaphore slots", async () => { - const manager = new ProjectEngineManager(centralCore); - const engineA = await manager.ensureEngine("proj_aaa"); - await manager.ensureEngine("proj_bbb"); - const sharedSemaphore = (manager as any).globalSemaphore; - const scopeA = new ScopedAgentSemaphore(sharedSemaphore); - const scopeB = new ScopedAgentSemaphore(sharedSemaphore); - - await scopeA.acquire(); - await scopeA.acquire(); - await scopeB.acquire(); - expect(sharedSemaphore.activeCount).toBe(3); - expect(sharedSemaphore.availableCount).toBe(1); - - (engineA.stop as ReturnType).mockImplementationOnce(async () => { - scopeA.returnAllHeldSlots(); - }); - - await manager.pauseProject("proj_aaa"); - - expect(scopeA.heldCount).toBe(0); - expect(scopeB.heldCount).toBe(1); - expect(sharedSemaphore.activeCount).toBe(1); - expect(sharedSemaphore.availableCount).toBe(3); - expect(scopeB.tryAcquire()).toBe(true); - expect(scopeB.tryAcquire()).toBe(true); - expect(scopeB.tryAcquire()).toBe(true); - expect(scopeB.tryAcquire()).toBe(false); - scopeB.returnAllHeldSlots(); - }); it("removes from starting set to prevent stalled starts from completing", async () => { const manager = new ProjectEngineManager(centralCore);