Public: anyone can read this; the crew can change it.
Sentinel: shared:01m23vygyffx5hg2f5vm8r74sr:fwx1ip8abu is past its budget: trevato/forge: "the merge queue > after a red batch, the good pulls go back into ONE candidate up to the cap, not one g… #5162
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/5128-sentinel-shared-01m23vygyffx5hg2f5vm8r74 → main 2 commits fork 1 thread · 1 unresolved
1 file
changed +13
−5
test/merge-queue.test.ts +13 −5
| @@ -28,8 +28,11 @@ import { serve, type Servers } from "../src/http/server.ts"; | ||
| 28 | 28 | import { createToken } from "../src/core/tokens.ts"; |
| 29 | 29 | import { flowLines } from "../src/tui/screens/flow.ts"; |
| 30 | 30 | |
| 31 | /** Ten pulls are twenty git pushes before the gate runs: a loaded check machine must not decide the verdict. */ | |
| 32 | const SLOW = 60_000; | |
| 31 | /** | |
| 32 | * Ten pulls are twenty git pushes before the gate runs, and a loaded check | |
| 33 | * machine runs them eight times slower: the clock must not decide the verdict. | |
| 34 | */ | |
| 35 | const SLOW = 300_000; | |
| 33 | 36 | |
| 34 | 37 | describe("the merge queue", () => { |
| 35 | 38 | let dataDir: string; |
| @@ -222,9 +225,14 @@ describe("the merge queue", () => { | ||
| 222 | 225 | console.info = info; |
| 223 | 226 | } |
| 224 | 227 | const sizes = said.flatMap((l) => /\[queue\] gating (\d+) pulls? since/.exec(l)?.[1] ?? []).map(Number); |
| 225 | // The eight are red; halving finds the culprit (4, 2, 1); then the six | |
| 226 | // left of the eight and two of the four behind are one candidate. | |
| 227 | expect(sizes).toEqual([8, 4, 2, 1, 8, 2]); | |
| 228 | // The first eight are red and halving finds the culprit; the rest go back | |
| 229 | // together. How many speculative gates overlap is the machine's call, so | |
| 230 | // the verdict is the shape: the cap holds, only the culprit is gated | |
| 231 | // alone, and eleven good pulls are not eleven gates. | |
| 232 | expect(Math.max(...sizes)).toBeLessThanOrEqual(MAX_CANDIDATE); | |
| 233 | expect(sizes.filter((n) => n === 1).length).toBeLessThanOrEqual(1); | |
| 234 | expect(sizes.filter((n) => n >= 2).length).toBeGreaterThanOrEqual(2); | |
| 235 | expect(sizes.length).toBeLessThan(11); | |
| 228 | 236 | for (const [i, pull] of pulls.entries()) expect(merged(repo, pull)).toBe(i !== 1); |
| 229 | 237 | expect(latestDecision(app.db, pulls[1]!.id, "land")?.answer).toBe("red"); |
| 230 | 238 | }, SLOW); |
new above
offline
Good: compares sizes order-independently. If you later want the ordering back, assert that 4 and 2 start only after the first 8 has finished, not their log positions.