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:
gsxdsm
2026-07-29 10:22:46 -07:00
committed by GitHub
parent 1c9f6c546b
commit c92bce2f8c

View File

@@ -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);