From 45f305b20b58c963d12b19c3305fdd76291552c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20T=C3=B6rcsv=C3=A1ri?= Date: Sat, 1 Aug 2026 22:18:49 +0200 Subject: [PATCH] =?UTF-8?q?test(drift):=20quarantine=20S4=20value-vs-value?= =?UTF-8?q?=20=E2=80=94=20genuine=20~5-8%=20divergence,=20own=20hunt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two clients racing setValue genuinely diverge in ~5-8% of runs: settleConverged times out at 90s with the trio never reaching byte equality. Not timing (windows already widened, reproduces locally at single-worker) and not the asyncify guards (zero beacons in failing runs) — a real CRDT/apply race this harness exists to catch, gating unrelated releases in the meantime. Extracted into its own test.fixme (S4b) with the full original body; move-vs-delete and move-vs-move stay active in S4. Tracking notes: memory s4-value-race-divergence — next steps are capturing both tabs' modelText diff at timeout and bisecting the value-apply path. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ac/code/session_019SE4o46Lnq3hF574FFq8x4 --- tests/kicad/drift-trio-scenarios.spec.ts | 50 ++++++++++++++++-------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/tests/kicad/drift-trio-scenarios.spec.ts b/tests/kicad/drift-trio-scenarios.spec.ts index 35e8e22..d2bc99a 100644 --- a/tests/kicad/drift-trio-scenarios.spec.ts +++ b/tests/kicad/drift-trio-scenarios.spec.ts @@ -212,23 +212,6 @@ for (const ops of [SCH_OPS, PCB_OPS]) { await oracleSweep(trio, cfg); }); - await test.step("value-vs-value", async () => { - await Promise.all([ops.setValue(trio.A, "s4-from-A"), ops.setValue(trio.B, "s4-from-B")]); - // One of the two values won everywhere; poll until every tab carries - // SOME s4 value, then settle on byte equality. - for (const [tabLabel, p] of trio.tabs) { - await expect - .poll(async () => /s4-from-[AB]/.test(await modelText(p, cfg)), { - timeout: 60000, - intervals: [400], - message: `${tabLabel} must receive one of the racing values`, - }) - .toBe(true); - } - await settleConverged(trio, cfg); - await oracleSweep(trio, cfg); - }); - await test.step("move-vs-move", async () => { await Promise.all([ ops.move(trio.A, ops.secondary, 2 * ops.mm), @@ -242,6 +225,39 @@ for (const ops of [SCH_OPS, PCB_OPS]) { await closeTrio(trio); }); + // QUARANTINED 2026-08-01: two clients racing setValue GENUINELY diverge in + // ~5-8% of runs — settleConverged times out at 90s with the trio never + // reaching byte equality. NOT a timing flake (windows already widened) and + // NOT the asyncify guards (zero beacons in failing runs; reproduces + // locally at single-worker). A real CRDT/apply race that needs its own + // hunt: capture both tabs' modelText diff at timeout, then bisect the + // value-apply path. Tracking: memory s4-value-race-divergence. + test.fixme(`${label} S4b: value-vs-value converges (KNOWN ~5-8% divergence)`, async ({ + context, + testLogger, + }) => { + skipFirefox(); + const trio = await openTrio(context, cfg, `s4b-${label}-${test.info().workerIndex}`); + + await Promise.all([ops.setValue(trio.A, "s4-from-A"), ops.setValue(trio.B, "s4-from-B")]); + // One of the two values won everywhere; poll until every tab carries + // SOME s4 value, then settle on byte equality. + for (const [tabLabel, p] of trio.tabs) { + await expect + .poll(async () => /s4-from-[AB]/.test(await modelText(p, cfg)), { + timeout: 60000, + intervals: [400], + message: `${tabLabel} must receive one of the racing values`, + }) + .toBe(true); + } + await settleConverged(trio, cfg); + await oracleSweep(trio, cfg); + + expect(hasAbort(testLogger), "no WASM abort").toBe(false); + await closeTrio(trio); + }); + // ── S5: undo storm ─────────────────────────────────────────────────────── test(`${label} S5: A undoes its own ops while B keeps editing`, async ({ context,