issue #3391 · alpha.10 · 2026-08-10

Same commit, same command, opposite verdicts.

Six context-gate tests failed for me and passed in CI. I filed it as a defect at main and cited "reproduced in two worktrees" as confirmation. Both reproductions were worktrees — one environmental cause, not two observations. main was green the whole time, and the real defect is that the suite's verdict depends on which directory you run it from.

The measurement

v10.0.0-alpha.10 · 130efc328 · identical command

primary checkout   ~/orchestkit/src/hooks                30 passed (30)
git worktree       ~/orchestkit/.worktrees/cg/src/hooks   6 failed | 24 passed

Why

The hook reads the filesystem to pick its limits

function isInWorktree() {                       // context-gate.ts:41
  const cwd = process.cwd();
  return cwd.includes('.claude/worktrees/') || cwd.includes('/.worktrees/');
}
function getEffectiveLimits() {                 // :46
  if (isInWorktree()) return { maxBackground: 10, maxPerResponse: 12 };
  return { maxBackground: 6, maxPerResponse: 8 };
}

Raising the caps inside a worktree is deliberate and correct — parallel agents are routine there. The problem is that the test never mocked process.cwd(). It mocks node:fs, atomic-write and node:child_process, but not the process, so the real working directory decided which regime ran.

How six failures follow from one leak

test seeds 8 response spawns, expects the per-response advisory

base regime      8 >= 8   ✓ fires   "Too many agents in one response (8/8)"
worktree regime  8 <  12  ✗ skipped  falls through to the generic warning
                                     "⚠ Context Budget Warning … (limit: 10)"

Every one of the six is that single fall-through, including the one asserting '6' — the base maxBackground, which the raised regime reports as 10. The window logic was never wrong.

The part that makes this a milestone-#164 bug

The mandated workflow was the one that saw red

Global CLAUDE.md mandates git worktrees whenever concurrent sessions are live, and this estate currently has 19 of them. So a developer following the documented process sees six red tests, while CI — a plain checkout — stays green. A suite whose verdict depends on undeclared environment is not measuring what it claims, and the practical effect is training people to ignore red.

Compounding it: the raised-limits branch had zero coverage. The suite only ever exercised the base regime, and switched away from it by accident rather than by assertion.

Fix

changewhy
Pin process.cwd() in beforeEachbase regime becomes deterministic; the leak cannot decide the verdict
Cover the raised regime, both layouts<repo>/.worktrees/<task> and .claude/worktrees/<name> — #3310 had to fix a detector that matched neither
Assert .git/worktrees/ does NOT raise capsthat is git metadata, never a checkout; it is the exact string the pre-#3310 detector wrongly matched, so this pins the bug shut

Verification, in both environments

primary checkout   33 passed (33)
git worktree       33 passed (33)
biome check src/   exit 0
tsc --noEmit -p tsconfig.test.json   clean

Both runs matter and neither alone is sufficient: passing only in a worktree would mean I had inverted the bug rather than removed the dependence.

What I got wrong, recorded deliberately. "Reproduced in two worktrees" felt like independent confirmation and was not — it was the same cause twice, and it let me file a green-at-main suite as a main-branch defect and carry that claim into two PR descriptions and a roadmap page. The generalisable rule: when a failure reproduces, vary the thing you are least suspicious of. Here the unvaried variable was the one that mattered, and the cheapest possible check — run it in the primary checkout — would have caught it immediately.