test: delete 2 project-engine-manager tests for the deleted cross-project cap (#2575)
**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) <noreply@anthropic.com>
This commit is contained in:
@@ -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<typeof vi.fn>).mockImplementationOnce(async () => {
|
||||
scopeA.returnAllHeldSlots();
|
||||
});
|
||||
(engineB.stop as ReturnType<typeof vi.fn>).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<typeof vi.fn>).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);
|
||||
|
||||
Reference in New Issue
Block a user