import assert from "node:assert/strict"; import { test } from "node:test"; // **A pending check says where it is, and the verdict lands last** (novox/hq issue 446). This module is the one writer // of a head's mesh/merge-gate: the announcement's pending words, "building on since …" when the build seat // says a machine took the check, and the verdict. The forge keeps the newest status of a context, so a pending word // written after the verdict hides it — a pass reads pending, a failure hides under "building". const SHA = "a6b08de8507c1703528277e5cefc80548dbc9bb3"; // The build seat's `started` as a machine said it for novox/hq#309's check on 2026-10-11 (its log, read with the // controller's `builds --log build-1791680941048622697`, opens at 03:09:01 on shanks); only the forge's address // replaced. The shape is mesh-controller's link.BuildStart. const startedOnShanks = { id: "build-1791680941048622697", repository: "http://127.0.0.1:20000/novox/hq.git", ref: SHA, on: "shanks", at: "2026-10-11T01:09:01.204319Z" }; /** A forge that keeps the newest status per context, as gitea does, and whose writes take as long as a test says. */ function aForge() { const kept: Record = {}; const written: string[] = []; let hold: Promise | null = null; let release = () => {}; let readHold: Promise | null = null; let readRelease = () => {}; return { kept, written, /** The next writes wait until released: a request in flight. */ holdWrites() { hold = new Promise((r) => (release = r)); }, release() { hold = null; release(); }, async setCommitStatus(_o: string, _r: string, _sha: string, s: { state: string; context: string; description: string }) { if (hold) await hold; kept[s.context] = { state: s.state, description: s.description, updated_at: new Date().toISOString() }; written.push(`${s.state} ${s.description}`); }, /** Reads answer what the forge held when asked, as late as the reads are held: the answer of a request in flight. */ holdReads() { readHold = new Promise((r) => (readRelease = r)); }, releaseReads() { readHold = null; readRelease(); }, async gateOf(_o: string, _r: string, _sha: string) { const held = kept["mesh/merge-gate"] ? { ...kept["mesh/merge-gate"] } : undefined; if (readHold) await readHold; return held; }, }; } /** The clock of the test: the head announced at 01:08:50Z. */ const announcedAt = () => new Date("2026-10-11T01:08:50Z"); test("a build machine taking the check is said on the head: building on which machine, since the local time", async () => { const { GateWriter, buildingWords } = await import("../gate.ts"); const forge = aForge(); const gates = new GateWriter(forge, announcedAt); await gates.pending("novox", "hq", SHA); assert.equal(await gates.started("novox", "hq", SHA, startedOnShanks), true); assert.equal(forge.kept["mesh/merge-gate"].state, "pending"); assert.equal(forge.kept["mesh/merge-gate"].description, buildingWords("shanks", new Date(startedOnShanks.at))); assert.equal(buildingWords("shanks", new Date(2026, 9, 11, 3, 9, 1)), "building on shanks since 03:09"); }); test("the verdict heard while a 'building' write is in flight lands last and stays", async () => { const { GateWriter } = await import("../gate.ts"); const forge = aForge(); const gates = new GateWriter(forge, announcedAt); await gates.pending("novox", "hq", SHA); forge.holdWrites(); // the 'building' request is in flight when the verdict comes const building = gates.started("novox", "hq", SHA, startedOnShanks); await new Promise((r) => setImmediate(r)); const verdict = gates.verdict("novox", "hq", SHA, () => forge.setCommitStatus("novox", "hq", SHA, { state: "success", context: "mesh/merge-gate", description: "pass" })); forge.release(); await Promise.all([building, verdict]); assert.equal(`${forge.kept["mesh/merge-gate"].state} ${forge.kept["mesh/merge-gate"].description}`, "success pass", `the verdict is not the newest status: ${forge.written.join(" | ")}`); }); // The race the review of mesh-catalog#202 reproduced: a writer reads the forge's gate (pending), the verdict is written, // then the writer writes "building" — and the pass reads pending until the next push. A head this process did not // announce is the one case where the forge is read before writing. test("the verdict written while a start's read of the forge is in flight stays the newest status", async () => { const { GateWriter } = await import("../gate.ts"); const forge = aForge(); forge.kept["mesh/merge-gate"] = { state: "pending", description: "waiting", updated_at: "2026-10-11T01:08:50Z" }; const gates = new GateWriter(forge, announcedAt); forge.holdReads(); const building = gates.started("novox", "hq", SHA, startedOnShanks); await new Promise((r) => setImmediate(r)); const verdict = gates.verdict("novox", "hq", SHA, () => forge.setCommitStatus("novox", "hq", SHA, { state: "success", context: "mesh/merge-gate", description: "pass" })); await new Promise((r) => setImmediate(r)); forge.releaseReads(); await Promise.all([building, verdict]); assert.equal(`${forge.kept["mesh/merge-gate"].state} ${forge.kept["mesh/merge-gate"].description}`, "success pass", `the verdict is not the newest status: ${forge.written.join(" | ")}`); }); test("the verdict heard while a 'building' write still waits its turn: the 'building' is never written", async () => { const { GateWriter } = await import("../gate.ts"); const forge = aForge(); const gates = new GateWriter(forge, announcedAt); forge.holdWrites(); // the pending words are still being written const pending = gates.pending("novox", "hq", SHA); const building = gates.started("novox", "hq", SHA, startedOnShanks); const verdict = gates.verdict("novox", "hq", SHA, () => forge.setCommitStatus("novox", "hq", SHA, { state: "failure", context: "mesh/merge-gate", description: "fail: 0 of 4 compose" })); forge.release(); await Promise.all([pending, verdict]); assert.equal(await building, false); assert.equal(forge.kept["mesh/merge-gate"].state, "failure"); assert.ok(!forge.written.some((w) => w.includes("building")), forge.written.join(" | ")); }); test("a start heard after the verdict writes nothing", async () => { const { GateWriter } = await import("../gate.ts"); const forge = aForge(); const gates = new GateWriter(forge, announcedAt); await gates.pending("novox", "hq", SHA); await gates.verdict("novox", "hq", SHA, () => forge.setCommitStatus("novox", "hq", SHA, { state: "success", context: "mesh/merge-gate", description: "pass" })); assert.equal(await gates.started("novox", "hq", SHA, startedOnShanks), false); assert.equal(forge.kept["mesh/merge-gate"].state, "success"); }); test("a start from before the check now pending (a run before a recheck, the stream's history) writes nothing", async () => { const { GateWriter } = await import("../gate.ts"); const forge = aForge(); let now = announcedAt(); const gates = new GateWriter(forge, () => now); await gates.pending("novox", "hq", SHA); await gates.verdict("novox", "hq", SHA, () => forge.setCommitStatus("novox", "hq", SHA, { state: "failure", context: "mesh/merge-gate", description: "error" })); now = new Date("2026-10-11T01:30:00Z"); // checked again: pending once more await gates.pending("novox", "hq", SHA); assert.equal(await gates.started("novox", "hq", SHA, startedOnShanks), false, "the first run's start"); assert.match(forge.kept["mesh/merge-gate"].description, /^waiting in the build queue since /); assert.equal(await gates.started("novox", "hq", SHA, { ...startedOnShanks, at: "2026-10-11T01:31:00Z" }), true, "the second run's start"); }); test("a head this process did not announce (it restarted) is said only while the forge holds its gate pending", async () => { const { GateWriter } = await import("../gate.ts"); const forge = aForge(); forge.kept["mesh/merge-gate"] = { state: "success", description: "pass", updated_at: "2026-10-11T01:20:00Z" }; const gates = new GateWriter(forge, announcedAt); assert.equal(await gates.started("novox", "hq", SHA, startedOnShanks), false); forge.kept["mesh/merge-gate"] = { state: "pending", description: "waiting", updated_at: "2026-10-11T01:08:50Z" }; assert.equal(await gates.started("novox", "hq", SHA, startedOnShanks), true); }); test("a repository as the mesh clones it is told from another", async () => { const { clonedAs } = await import("../gate.ts"); assert.equal(clonedAs("http://127.0.0.1:20000/novox/hq.git", "novox", "hq"), true); assert.equal(clonedAs("http://127.0.0.1:20000/novox/mesh-hq.git", "novox", "hq"), false); assert.equal(clonedAs("http://127.0.0.1:20000/novox/mesh-controller.git", "novox", "hq"), false); });