Files
alkstore/tasks/pg-suite-infra-hardening.md
T
glm-5.3-flash 5c03fb2130 pg suite-infra hardening (task pg-suite-infra-hardening): the wave-4 review's F-1 defense-in-depth candidates — must_recv_event re-shaped from the 20 ms try_recv polling loop to a parked recv().await under the 15 s timeout wrapper (stream_tests.rs, the sole pg copy — SQLite twin untouched; the poll loop's wake-subscription interaction surface the F-1 flake suspected is out of the hot path, and the deadline assert still bounds the property). The parked form's terminal arms are explicit: Some(Err(e)) keeps the errored-instead-of-idling panic, None gets a receiver-closed panic the poll form never saw. The deadline miss self-diagnoses (the small-honest realization of candidate (b)'s discriminator): read_since(offset, 1000) over rows beyond the receiver's position names the residual class — rows durable undelivered (wake/re-drain class) vs no rows (publish-visibility class); with the parked recv a wake-arrived-but-re-drain-missed arm is structurally implausible (only a read error could miss, and it surfaces Err). Candidate (b)'s literal bridge-side counter skipped, reason recorded in the task (surfacing the bridge wake count across the dyn EventReceiver boundary needs downcast/keyed-global machinery beyond the small-honest bar); the small honest piece did land: wait_wake's Lagged(n) arm now logs (eprintln, house posture matching notify.rs's bridge_loop — and forwarder.rs's 'the receiver bridge's Lagged arm logs / recovers' doc claim now true at both bridges), stream name threaded into wait_wake's signature so the log attributes the lag. Verified: pg stream module 21/21 vs harness server (full module run), tx_publishes_compose_with_the_handle 5 solo re-runs green (determinism re-check under the parked shape), two consecutive full pg harness runs green (121 lib + 25 suite + 9 schema, ~72 s each), cargo test -p alkstore-postgres green server-less (skips clean), workspace cargo test green (12 binaries), clippy -D warnings, fmt clean
2026-10-10 08:00:29 +00:00

5.4 KiB

id, name, status, depends_on, scope, risk, impact, level, tags
id name status depends_on scope risk impact level tags
pg-suite-infra-hardening Postgres test-infra hardening — F-1's defense-in-depth candidates completed
single low isolated implementation
wave-5
postgres-engine
tests

Description

Land the defense-in-depth test-infra hardening the wave-4 review recorded for F-1 (tasks/review-wave-4.md Notes) — explicitly not load-bearing since pg-fix-tx-wake retired F-1's engine-side root cause (the compose test is deterministic, 20/20 solo runs green at the fix-batch gate). This task exists because wave 5 was the named home ("wave 5's suite hardening, or a wave-5-adjacent test-infra task") and the candidates are cheap; if the wave-5 window gets tight, cancelling this task loses nothing but insurance.

Work (the review's candidate dispositions, cheapest first):

  • (a) Harden must_recv_event's deadline — replace the 20 ms polling loop with a parked recv().await under a timeout wrapper; the deadline assert still bounds the property, the poll-loop's wake-subscription interaction surface goes away.
  • (b) A LOG_LAGGED-style diagnostic counter on the bridge — discriminates "wake never arrived" from "wake arrived, re-drain missed" if a wake-shaped flake ever recurs. Land only if it is a small, honest addition (a test-observation counter, #[cfg(test)]- gated or eprintln-postured per the house test style); skip and record if it wants more machinery than that.

Candidate (c) (leave the skip-posture as-is) is the do-nothing arm — adopted by default for anything not landed.

Acceptance Criteria

  • must_recv_event parks on recv().await under a timeout wrapper (no polling loop); the pg stream tests stay green against the harness server (a full stream-module run)
  • Candidate (b) either landed small or recorded as skipped with the reason
  • cargo test -p alkstore-postgres green (server-less skips clean); clippy -D warnings; fmt clean

References

  • tasks/review-wave-4.md (F-1's Notes — the candidate dispositions)
  • tasks/review-wave-4-fixes.md (F-1 retired; defense-in-depth posture)
  • tasks/pg-fix-tx-wake.md (the engine-side fix that made this non-load-bearing)

Notes

Decisions of record:

  • (a) landed as specified: must_recv_event is now timeout(15 s, receiver.recv()) — parked, no polling loop. The old helper's try_recv-loop Err arm split into the parked shape's two failure arms: Some(Err(e)) → the same "receiver errored instead of idling" panic (an error during the wait surfaces immediately, as before), and None → a new "receiver closed before the event arrived" panic (the parked form makes the terminal arm visible, the poll form never saw it). try_recv is otherwise untouched as a test tool (other pg test modules still drain with it).
  • (b): the wait_wake's Lagged(n) arm now logs (eprintln, house posture — matching notify.rs's bridge_loop; it also makes forwarder.rs's "the receiver bridge's Lagged arm logs / recovers" doc claim true at both bridges — that claim was half-wrong on the stream side). The arm still treats lag as a wake (re-drain). The stream name is threaded into wait_wake's signature so the log attributes lag to the stream, not anonymous.
  • (b)'s full bridge-side counter — skipped, recorded: surfacing the bridge's wake-observation count into the deadline panic would require plumbing a counter Arc across the dyn EventReceiver trait boundary (a test downcast or a keyed global registry) — more machinery than the small-honest bar. The discriminator's job is covered test-side instead: with the parked recv, a "wake arrived, re-drain missed" arm is structurally implausible (the re-drain reads exactly what a re-read reads; only a read error could miss, and it surfaces Err), so the deadline panic self-diagnoses: it reads the durable rows beyond the receiver's position via read_since(offset, 1000) and names the residual class — rows undelivered (wake/re-drain class; wait_wake's Lagged log speaks to feed lag there) vs no rows (publish-visibility class). Test harness only; no engine-state change.
  • The deadline stays 15 s (the review's bound of record; unchanged — only the wait shape moved from poll to park).

Summary

Landed: must_recv_event re-shaped from the 20 ms try_recv polling loop to a parked recv().await under a 15 s timeout wrapper (stream_tests.rs — the sole pg copy; the SQLite twin untouched, this task is pg-specific), with a self-diagnosing deadline panic (read_since presence check naming the failure class); the stream bridge's Lagged(n) arm now logs the lag (stream.rs wait_wake, stream name threaded in — the surfaced-not-silent posture now true at all wake-feed bridges); the literal bridge-side diagnostic counter skipped with reason above (the deadline diagnosis covers the discrimination test-side).

Verified: the pg stream module 21/21 green against the harness server (one full module run, ~19 s at --test-threads=4); tx_publishes_compose_with_the_handle 5 solo re-runs green (determinism re-check under the new parked shape); two consecutive full pg harness runs green (121 lib + 25 contract-suite + 9 schema, ~72 s each); cargo test -p alkstore-postgres green server-less (harness rows skip cleanly); workspace cargo test green (12 test binaries); cargo clippy --all-targets -- -D warnings clean; cargo fmt --check clean.