DUNIN7 · LOOMWORKS · RECORD
record.dunin7.com
Status Current
Path session-handoffs/cr-2026-198-checkpoint-a-v0_1.md

CR-2026-198 — Checkpoint A — v0.1

Date. 2026-08-10 · Author. Claude Code (execution). Operator: Marvin Percival. CR. change-requests/cr-2026-198-loomworks-b84-polling-determinism-v0_1.md (filed, record de3ef78; number confirmed non-colliding). Baseline confirmed. Engine f338f3f, tree clean at Step 0. Working tree now holds one modified file: tests/test_external_polling.py. Nothing committed, tagged, or pushed.


Step 1 — which case, and does production depend on the interleaving

Case (1): the property is real and the test's grip on it was loose. No halt.

The property — per-poll session boundaries: a slow specialist's poll cannot block its peers, and peers' event writes commit independently while it hangs — is deliberately built (_tick's asyncio.gather over _poll_one, each opening its own session; both docstrings state it as the design intent) and production depends on it: one hung external rendering service must not stall polling for every other specialist. Not incidental behaviour.

The loose grip, mechanically: the test waited for "both fast specialists called" (poll_call_count, incremented inside the specialist call) and then asserted "≥2 events committed" — but the commit happens when _poll_one's session context exits, after the specialist returns. The assertion ran inside that call-to-commit gap; on a loaded runner the commits lose the race. A second, masked instance of the same race sat one layer down: the slow specialist's poll_call_count == 1 assert could run before its _poll_one task was scheduled at all.

Step 2 — the remedy (not a timeout, not a retry)

The bounded wait's condition became the property itself: "two fast events committed and the slow poll entered." The positive assertion can no longer race — it is the condition the loop reached. The negative half was already deterministic: the slow poll awaits an asyncio.Event only the test sets, so it cannot complete regardless of elapsed time. The bound is therefore a pure liveness guard — it trips only on a genuine hang, and its failure message says so in those terms. This is not §3's forbidden widening: no assertion depends on timing anymore; the bound converts "never happens" into a clean, named failure.

The mid-flight assertion also strengthened from >= 2 to == 2: exactly the two fast events exist while the slow poll blocks, provably — the third cannot be written until the Event is set.

Step 3 — observed failing first, break distinguished from flake

Deliberate break: a module lock serializing _poll_one — destroying the per-poll-independence property itself. Result: 5 of 5 runs failed, every failure at the new message ("Liveness bound: the fast polls' events were never committed … per-poll sessions are not committing independently of a blocked peer"). Distinguished from the flake on three axes: message (the flake's signature was the old "Expected ≥2 … got 1"; it never emitted "Liveness bound"), rate (5/5 versus ~1 in 3), and mechanism (produced under a change that provably serializes the sessions). Break reverted; production file verified pristine.

Steps 4–5 — evidence

Seed-mutability impact

Kind C — checked, no contact. The polling loop reads external_production_records, current_memory_objects (specialist and render-type payloads), and job rows; no seed accessor (get_current_seed, _load_seed_by_ref, any seed_ref read) appears in engagement/external_polling.py, and this CR changed only the test. A null finding, recorded as an entry.

Awaiting Step 6

Tag cr-2026-198-b84-polling-determinism, push, watch the CI run and report its result — this CR is about the gate, so its own gate result is part of the evidence.


DUNIN7 — Done In Seven LLC — Miami, Florida CR-2026-198 — Checkpoint A — v0.1 — 2026-08-10 The wait condition is now the property; the bound only catches a hang.