Skip to content

Add probe-queue-contention, which prices the tail claim - #90

Open
MikeGrier wants to merge 67 commits into
mainfrom
mikegrier/probe-queue-contention
Open

MikeGrier wants to merge 67 commits into
mainfrom
mikegrier/probe-queue-contention

Conversation

@MikeGrier

@MikeGrier MikeGrier commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Peeled from mikegrier/deferred-namespace-ops, where it was written alongside work that is not ready.

It lands on its own because it is an instrument: useful before the plan that consumes it exists, and landing it first is what lets that decision be made against a measurement rather than an argument.

Scope note: this PR also edits windows-waitable-queues' README, public rustdoc, and decision D-41. Those are documentation-only, and they are here because this probe's measurement withdrew a claim that crate was publishing. See "The claim this probe withdrew" below.

What it measures

Two questions a queue-shape decision is waiting on:

  • whether the bounded array queue's tail claim contends badly enough to justify the linked and sharded MPSC shapes;
  • what reserving_mpsc's extra read of the consumer's position actually costs.

Two regimes, and the pair is the point. Isolated gives producers capacity large enough that nothing is refused and runs no consumer, so whatever curve appears against N is the claim and nothing else. Drained runs a consumer popping continuously -- the only regime that can price the read of head, because that read is cheap until a consumer is writing the line. Measuring it in isolation would report it as free.

Each row carries the refusal count from the queue's own Observable counters, so a consumer-bound plateau at high producer counts is visible as a fact rather than mistaken for contention.

Verified by running it, not by building it

Seven runs on x86_64 16p/8c smt+ L2[2,2,2,2,2,2,2,2] ec[0:16] numa[16], release, exit 0, ~65s each. Isolated, at sixteen producers, median of seven:

shape ns/push
baseline_fetch_add 15.0
permit_mpsc 21.5
reserving_mpsc 52.3
slotwise_mpsc 222.4

These are not the figures the README publishes, and that is deliberate. This
seven-run sweep was taken to size the probe's noise floor -- it is the capture
behind the 0.68-1.27x same-code control quoted below. The README's table is a
separate, fully attributed three-run capture, retaken at fecd352 once the probe
learned to carry its own dispersion; its sixteen-producer medians are
14.8 / 21.8 / 47.9 / 218.0, each published with the range across all fifteen
repetitions. Neither supersedes the other: the README's is
the attributed figure that crate ships, and this one is the evidence about how far such
a figure moves between runs. That the two disagree on the same host and
the same code is the sweep's finding, not a discrepancy to reconcile.

(An earlier revision of this paragraph cited the capture at a99108f with medians of
15.3 / 21.4 / 51.1 / 246.9. That capture was superseded when the dispersion columns
landed and the table was retaken; the README and the crate rustdoc both carry the
fecd352 figures. This description was the last copy still naming the old one.)

Gate: fmt, clippy --all-targets, lib tests and doctests for both affected crates (the latter including the compiled README), all green.

A timing defect found in review, and what it moved

The first version of the probe released a Barrier, called Instant::now() on the coordinator, and read elapsed() after thread::scope returned. Both ends were wrong:

  • a barrier releases all parties together, so a worker can run an arbitrary prefix before the coordinator is rescheduled -- understating elapsed time and overstating throughput, worst exactly where the curve is the finding;
  • thread::scope joins before returning, so exit and join cost sat inside the window.

Fixed with per-worker timestamps and a span of min(start)..max(end). Measured effect: reserving_mpsc at sixteen producers moved 35.0 -> 52.3 ns/push. An earlier review round had explicitly cleared this code as correct.

That correction shipped without a test, which a later round caught. measured_span
is now pinned by four unit tests built from constructed Instants, and the guard was
verified by sabotage: reverting min to max on the start fails three of them.
The report's four rendering helpers moved out of the binary into the library for the
same reason -- nothing could reach them where they were, so the non-finite case the
tests documented was never actually checked. Dropping format_ratio's
zero-denominator guard now renders infx and fails.

Any figure in the design notes taken before that correction is marked as predating it.

The claim this probe withdrew

The notes had said the u64 re-apportionments "track the default within noise", so Perpetual's twenty years of counter headroom was free. Re-measuring seven times says otherwise, and in a way worth stating precisely:

  • the noise floor had been quoted at 2-6%, obtained by comparing two runs -- which cannot measure a spread. Seven runs put the same-configuration spread at 7-61%.
  • the probe emits its own control: reserving_mpsc and reserving(32/32) are the same code at the same layout, measured twice per run, so their ratio is an empirical "no difference" -- and it spans 0.68-1.27x.

Against that control the 128-bit word separates decisively in isolation (3.45x / 3.81x at 16 / 32 producers); the u64 re-apportionments do not. The claim is withdrawn in both directions rather than inverted: 1.23-1.30x against a control reaching 1.12x, on one host, is a flag to measure locally, not a cost.

That withdrawal had to sweep out of this crate, because the claim had propagated into windows-waitable-queues -- its README, its public rustdoc, and ClaimLayout's own doc comment, which is what a caller reads while choosing a layout. The mechanical argument is kept (same lock cmpxchg, same u64, shift constants only, so no structural reason for one to be slower); only the claim that this was measured to cost nothing is gone.

Perpetual is not described as free, and this PR does not name a preferred layout.
What the layout does is stated; which one to pick is the caller's, per
D-no-client-prescriptions.

Why it is NOT in the CI probe job

Deliberate, and the reason is a measurement rather than a preference. In a debug build slotwise_mpsc and reserving_mpsc come out indistinguishable (249.7 vs 254.0 ns/push at sixteen producers); in release, 193.5 vs 52.2. A debug run does not merely lose precision -- it reports the two shapes as equivalent, which is a confident wrong answer.

(Those four figures predate the timing correction above and have not been retaken. The qualitative finding is unaffected -- a debug build still swamps the effect.)

It also wants more cores than a hosted runner has, and costs about a minute against a job whose other probes take seconds. So it is run by hand, on a known machine, with the numbers recorded against that machine.

A CI hole this PR opened, and closed

Adding windows-waitable-queues with dwcas + experimental-permit-claim unified those features workspace-wide. CI built that crate only via --workspace, so nothing compiled the no-dwcas path any more -- and dwcas is additive, gating Wide and ClaimLayout items that would have stopped being checked.

Restored with a dedicated default-features job, modelled on the existing placement-probe-no-serde job.

Feature flags

experimental-permit-claim is enabled on the dependency because this probe is what decides its fate -- it has to be measured against the shipping shapes on the same host, in the same run, by the same harness. dwcas is what lets it instantiate the 128-bit claim layout.

Review history

Eighteen rounds. The first four each found something in the code: the feature-unification hole, the timing window, four unguarded retry loops, and three prose sites naming mpsc for a module actually called slotwise_mpsc. The fifth ran the probe end-to-end and found nothing in the code -- only the documentation contradiction that produced the withdrawal sweep above.

The rounds after that were almost entirely restatement drift: a claim corrected in
one place and left standing in five others. The pattern held often enough to be worth
naming -- the reported site is a sample, not the population, so each round ended with a
sweep of the claim rather than a fix to the line cited. Two rounds found real evidence
problems instead: one withdrew a refusal-count argument that three re-measurements
showed does not reproduce in direction or magnitude, and the last found the two test
gaps addressed above.

…ail claim

Peeled from `mikegrier/deferred-namespace-ops`, where it was written alongside
work that is not ready. It is landed on its own because it is an INSTRUMENT: it
is useful before the plan that consumes it exists, and landing it first is what
lets that decision be made against a measurement rather than an argument.

The probe answers two questions a queue-shape decision is waiting on: whether
the bounded array queue's tail claim contends badly enough to justify the linked
and sharded MPSC shapes, and what `reserving_mpsc`'s extra read of the
consumer's position actually costs.

Two regimes, and the pair is the point. **Isolated** gives producers capacity
large enough that nothing is refused and runs no consumer, so whatever curve
appears against N is the claim and nothing else. **Drained** runs a consumer
popping continuously, which is the only regime that can price the read of
`head` -- that read is cheap until a consumer is WRITING the line, so measuring
it in isolation would report it as free. Each row carries the refusal count from
the queue's own `Observable` counters, so a consumer-bound plateau is visible as
a fact rather than mistaken for contention.

**It is deliberately absent from the CI probe job**, unlike every other probe,
and the reason is a measurement rather than a preference: that job runs
`cargo run` without `--release`, and in a debug build `mpsc` and
`reserving_mpsc` come out at 249.7 and 254.0 ns/push at sixteen producers --
indistinguishable. In release, same machine, same minute: 193.5 and 52.2. A
debug run does not merely lose precision, it reports the two shapes as
equivalent, which is a confident wrong answer. It also wants more cores than a
hosted runner has, and costs about a minute against a job whose other probes
are seconds.

Verified by running it rather than by building it: exit 0 in 64.8s on
x86_64 16p/8c, 181 lines, banner and both regimes present. At sixteen producers,
isolated: `baseline_fetch_add` 14.2 ns/push, `reserving_mpsc` 35.0,
`permit_mpsc` 22.2, `slotwise_mpsc` 198.5.

The `experimental-permit-claim` feature is enabled on the dependency because
this probe is what decides its fate -- it has to be measured against the
shipping shapes on the same host, in the same run, by the same harness. `dwcas`
is what lets it instantiate the 128-bit claim layout.

Two design-note corrections were needed on the way in, because the notes had
been written against a state that has since moved:

  - The claim-word section said the three apportionments were "built as
    duplicates in claim_layout.rs so the shipping crate was not disturbed".
    That scaffolding is gone -- the layouts SHIP now, as `ClaimLayout` with
    `Balanced`, `Enduring`, `Perpetual` and `Wide`, which is what this probe
    imports. A reader who went looking for `claim_layout.rs` would not have
    found it. The duplicate-then-decide cycle closed and the note never said so.

  - Both sections linked to checklists that do not exist in this repository
    (`CHECKLIST-io-domains.md`, `CHECKLIST-claim-word-layout.md`); they arrive
    with the rest of the queue work. The notes now name the QUESTIONS rather
    than linking to items that would dangle, and say plainly that the plans
    carrying them land later.

Every link in the added notes was checked to resolve before writing it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings September 14, 2026 19:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved benchmark timing, consumer-readiness, interpretation, and documentation issues remain.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds a standalone Windows queue-contention probe for comparing MPSC queue shapes, reservation costs, and claim layouts.

Changes:

  • Adds isolated and drained benchmark regimes with refusal counts.
  • Registers the probe binary and enables required queue features.
  • Documents methodology, rationale, and recorded measurements.
File summaries
File Reviewed change
crates/windows-platform-probes/src/queue_contention.rs Benchmark implementation and timing regimes
crates/windows-platform-probes/src/lib.rs Probe module export and documentation index
crates/windows-platform-probes/src/bin/queue_contention.rs Benchmark report rendering and comparisons
crates/windows-platform-probes/DESIGN-NOTES.md Measurement rationale and results
crates/windows-platform-probes/Cargo.toml Binary registration and dependency features
Cargo.lock Dependency graph update
Review details

Suppressed comments (6)

crates/windows-platform-probes/DESIGN-NOTES.md:525

  • The heading says the wide word costs 2-3x, but the shipping-type measurements below report 3.83x and 3.99x at 16 and 32 producers, and the later section explicitly says those values supersede the earlier stand-in results. Update the heading so it does not understate the result that this note now treats as authoritative.
## The claim word's width costs 2-3x in isolation and much less in use

crates/windows-platform-probes/DESIGN-NOTES.md:530

  • This introduction still says there are three apportionments and omits the probe's 8/56 (Perpetual) layout. The current probe measures four layouts, and the superseding table below includes 8/56, so the note's setup is inconsistent with the instrument it documents.
Three apportionments of `reserving_mpsc`'s claim word: 32/32 and 16/48 over
`AtomicU64`, and 64/64 over `AtomicU128`.

crates/windows-platform-probes/src/bin/queue_contention.rs:183

  • cmpxchg16b is x86-specific, but this binary can be built for the repository's other Windows targets and portable-atomic uses target-specific primitives for the wide operation. On ARM64 this line mislabels the instruction being measured. Use architecture-neutral wording or render the instruction conditionally.
        "     apportioned differently; 64/64 is a u128 exchange (cmpxchg16b)."

crates/windows-platform-probes/src/queue_contention.rs:31

  • Removing the consumer and backpressure does not make this "the compare-and-swap and nothing else": each timed push still performs the queue's slot-metadata/publication work, and reserving_mpsc still reads head even when no consumer is running. The resulting curve is total producer-only push-path scaling, so interpreting it as pure tail-CAS contention can misattribute the cost behind the queue-shape decision. Please narrow this description or add a matched control that holds the other push-path work constant.
//! - **Isolated** -- capacity large enough that nothing is ever refused, and no
//!   consumer running. This is the *cleanest* measurement of tail-claim
//!   contention: nothing else touches the queue, so whatever curve appears
//!   against N is the compare-and-swap and nothing else.

crates/windows-platform-probes/src/queue_contention.rs:410

  • All participants are released at the same barrier, but that does not make the consumer ready to pop. The scheduler can run producers first, fill the 1024-slot queue, and record refusal/retry cycles before the consumer writes head; that startup delay is included in started, so the drained rows are not guaranteed to represent a continuously draining consumer, especially at low producer counts. Add a consumer-readiness handshake before starting the producers and clock, and apply it to each drained helper.
    let consumer = thread::spawn(move || {
        consumer_gate.wait();
        // Spin rather than park: the doorbell's cost is `doorbell_cost`'s
        // question, and parking here would measure that instead of the claim.
        while !consumer_done.load(Ordering::Relaxed) {

crates/windows-platform-probes/src/queue_contention.rs:281

  • The barrier only releases the workers; it does not synchronize their first operation with the timestamp taken afterward. Once gate.wait() releases everyone, a worker can run (or finish) before the main thread is scheduled to execute Instant::now(), so the elapsed interval is too short and the reported throughput can be inflated, especially for the one-producer rows. This release-then-timestamp pattern is repeated throughout the timed functions; use a ready barrier plus a separate release barrier (or another timestamp handoff) so the timestamp is established before workers enter the loop.
        gate.wait();
        Instant::now()
  • Files reviewed: 5/6 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread crates/windows-platform-probes/src/bin/queue_contention.rs
Comment thread crates/windows-platform-probes/src/lib.rs
Comment thread crates/windows-platform-probes/src/queue_contention.rs Outdated
…features took away

Four findings from a code review of this PR, one of them a real regression the
PR introduced.

**Enabling `dwcas` and `experimental-permit-claim` on a workspace member
unifies them across the whole workspace.** `windows-platform-probes` did not
depend on `windows-waitable-queues` at all before this branch, so every
`--workspace` step built that crate at its default features. With the probe's
dependency added, `cargo tree --workspace -e features -i windows-waitable-queues`
now reports both features on, sourced solely from here -- and since CI builds
that crate only through `--workspace` steps, with no `-p windows-waitable-queues`
job anywhere, NOTHING was left compiling it without `dwcas`.

That is the configuration that can break unnoticed, because `dwcas` is additive:
`Wide` and its `ClaimLayout` impl exist only under it. The queue crate's own
manifest calls `dwcas` "non-default so nothing depends on it by accident" and
"the only thing in this crate that costs a third-party dependency" -- claims that
are only true while something still builds without it.

Fixed by adding a `windows-waitable-queues (default features)` job, modelled on
the existing `placement-probe-no-serde` job, which exists for exactly this shape
of problem. Verified locally before committing: build, clippy `-D warnings`, and
304 + 12 + 1 tests all clean at default features.

Not fixed by making the probe's dependency optional: the probe must stay
buildable by a plain `cargo build`, and a feature that has to be remembered
before it compiles is a worse trade than a job that cannot be forgotten.

**The design note's stated reason for keeping the probe out of CI was false**,
and it was the load-bearing half. It said the job "runs `cargo run` without
`--release`" -- but `probe-doorbell-cost` and `probe-request-cost` already run
there WITH `--release`, under a comment establishing the very rule this probe
would fall under. It also said "unlike every other probe", and `probe-cancel-io`
is likewise absent. And it said the run "costs about two minutes" against the
64.8s this PR's own commit message reports.

The decision is unchanged and still right; the argument for it was wrong.
Rewritten around what is true -- core count and wall time -- with the release
requirement kept as a constraint on HOW it runs rather than as a reason to
exclude it. Re-measured: 60.2s.

**Two prose defects, both mine and both the same class as ones this PR already
fixed elsewhere.** The module doc still named `CHECKLIST-io-domains.md`, a file
in no branch -- I swept the design notes for dangling links and did not sweep
the source beside them. And three sites named `mpsc`, a module the queue crate
does not have; it is `slotwise_mpsc`, which is what the probe measures and
labels. That is residue of exactly the rename this probe's own comments record
as having caused one silent failure already.

Re-ran the probe after changing its output text rather than assuming: exit 0,
60.2s, 181 lines, and the reworded passage renders as intended.

Swept every path-shaped `.md`/`.rs` reference in the PR's files for
resolvability: zero unresolvable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 14, 2026 19:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved critical and moderate findings remain around target support, timing synchronization, and measurement safeguards.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (5)

Previously missed (1) — in code that hasn't changed since the last review.

crates/windows-platform-probes/DESIGN-NOTES.md:537

  • The heading and opening count are stale relative to the replacement results later in this same note: the shipping-type section reports 3.83x/3.99x at 16/32 producers and the probe now measures four layouts, including 8/56. Leaving 2-3x and Three apportionments here makes the canonical heading present the superseded stand-in result as current; update this opening to the final result or label the old block as historical.

crates/windows-platform-probes/src/bin/queue_contention.rs:16

  • The PR's measurement notes state that debug timings make the relevant queue shapes look equivalent, but this entry point accepts a normal debug cargo run and emits an authoritative-looking report. Add a release-build guard before measuring so a manual invocation cannot produce numbers that are used for the queue decision despite being known-invalid.
fn main() {

crates/windows-platform-probes/src/lib.rs:151

  • The crate-level “What each probe establishes” table enumerates the probe functions, but the new queue_contention::measure binary-only probe is not added to it. The public crate documentation therefore omits this new probe and its claim, leaving the inventory stale. Add a row for it alongside the other binary-only probes.
pub mod queue_contention;

crates/windows-platform-probes/src/queue_contention.rs:245

  • This warm-up calls timer, but every timer call allocates and drops its own queue. The untimed pass therefore does not pre-touch the backing storage used by any timed repetition; first-use page faults or initialization can still occur after Instant::now(), contrary to the comment and making the reported time depend on allocator/page reuse. Reuse the allocation being timed or explicitly pre-touch that allocation before starting the clock.
    // One untimed pass first: the first touch of a fresh allocation faults
    // pages in, and that cost belongs to the allocator rather than the queue.
    let _ = timer(producers);

    let mut results: Vec<Repetition> = (0..REPETITIONS).map(|_| timer(producers)).collect();

crates/windows-platform-probes/src/queue_contention.rs:406

  • This barrier only proves that the consumer reached wait(), not that it has entered the drain loop. After release, the scheduler can run producers long enough to fill the 1024-slot queue before the consumer executes pop; that startup delay and its refusals are then included in the supposedly continuously-drained timing. Add a consumer-ready handshake before releasing and timing the producers, and apply the same synchronization to the other drained variants.
    let gate = start_barrier(producers + 1);
  • Files reviewed: 6/7 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread crates/windows-platform-probes/Cargo.toml
Comment thread crates/windows-platform-probes/src/queue_contention.rs Outdated
Copilot AI review requested due to automatic review settings September 14, 2026 20:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It has unresolved portability, timing-correctness, documentation, and rationale issues.

Review details

Suppressed comments (7)

.github/workflows/ci.yml:510

  • The PR description still says the probe is excluded because the CI probe job runs cargo run without --release, but this workflow already runs the timing probes with --release at lines 317-324. The new design note also identifies that premise as false; please update the description to the actual reasons for exclusion (host core count and runtime) so the stated rationale matches the workflow.
    # **This job exists because adding `probe-queue-contention` took the default
    # configuration away from every other job.** That probe needs `dwcas` and
    # `experimental-permit-claim`, and enabling them on a workspace member
    # unifies them across the whole workspace -- so the `--workspace` steps that
    # deliberately omit `--all-features` stopped being a default-features build

crates/windows-platform-probes/Cargo.toml:158

  • This normal dependency enables dwcas for every Windows build of windows-platform-probes, so reserving_mpsc::Wide and portable_atomic::AtomicU128 are compiled even when the probe is built for a target without native double-width CAS. The queue crate's own dwcas documentation records that AtomicU128 is unavailable on i686 with default-features = false, so a normal cargo build -p windows-platform-probes loses the Windows-wide buildability this crate otherwise has. Keep the wide experiment x64-only (for example, target-gate the probe/dependency or split the binary) while leaving the ordinary probe crate buildable on other Windows targets.
windows-waitable-queues = { path = "../windows-waitable-queues", features = [
	"experimental-permit-claim",
	# So the probe can instantiate the 128-bit layout. The 64-bit ones need no
	# feature; this is the only one that costs the queue crate a dependency.
	"dwcas",

crates/windows-platform-probes/DESIGN-NOTES.md:650

  • CW-1.6 is still an unresolvable work-item reference: it has no definition elsewhere in this checkout, while the preceding section explicitly says the queue checklists are not present yet. This leaves the provenance of the deletion unavailable to readers; either link the eventual checklist when it lands or state the current fact without the missing item ID.
`CW-1.6` deleted the duplicated protocol in this crate once
`windows-waitable-queues` took the layout as a parameter, so the probe now
instantiates the real type at each layout. The numbers below supersede the ones
above, which were taken from the stand-in.

crates/windows-platform-probes/DESIGN-NOTES.md:533

  • The heading still presents the old stand-in result as the current decision, even though the later section says the shipping-type measurements supersede it and reports a 3.83-3.99x wide-word cost at 16-32 producers. Mark this section explicitly as historical (or update/remove the stale title), otherwise readers can stop here and carry forward the obsolete 2-3x conclusion.
## The claim word's width costs 2-3x in isolation and much less in use

crates/windows-platform-probes/src/bin/queue_contention.rs:186

  • The report hard-codes cmpxchg16b, but Wide is backed by portable-atomic and this binary is not restricted to x86_64. On aarch64-pc-windows-msvc the same 128-bit operation uses the ARM atomic sequence (ldxp/stxp), so running the probe there would attach the wrong instruction to the measurement. Make the description target-dependent or describe it generically instead of presenting an x86-specific name as universal.
        "     apportioned differently; 64/64 is a u128 exchange (cmpxchg16b)."

crates/windows-platform-probes/src/lib.rs:151

  • The crate-level # What each probe establishes table is the inventory for this crate and currently ends at request_cost::measure; adding the public queue_contention module without a row leaves the new instrument undiscoverable in the API documentation and omits its binary-only/release-only constraints. Add a queue_contention::measure entry describing the two measured regimes.
pub mod queue_contention;

crates/windows-platform-probes/src/queue_contention.rs:308

  • Barrier::wait() only releases the parties; it does not make the following Instant::now() atomic with that release. Every caller returns the workers from this barrier and only then takes the timestamp, so a worker can execute an arbitrary prefix of its loop before timing starts, biasing the producer-count curves (especially when the main thread is descheduled). Use a second start barrier/flag so the timestamp is established before workers can enter the timed loop.
/// The count includes this thread: the workers arrive and block, this thread
/// arrives last, and the clock starts as the barrier releases them together.
fn start_barrier(participants: usize) -> Arc<Barrier> {
    Arc::new(Barrier::new(participants + 1))
  • Files reviewed: 6/7 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

… a spin on a dead queue

Three findings from a second review of this PR. The first changes the numbers.

**The timing window was wrong at both ends, and the error was not small.** Every
timer released a barrier, called `Instant::now()` on THIS thread, and read
`elapsed()` after `thread::scope` returned:

  - `Barrier::wait` releases every party together and this thread is just
    another party, so a worker could return from `wait` and run an arbitrary
    prefix of its pushes before this thread was scheduled again to read the
    clock. That understates the interval, which OVERSTATES throughput -- and it
    bites hardest at high producer counts, where this thread is competing with
    N busy workers for a core. Which is exactly where the curve is the finding.

  - `thread::scope` joins before it returns, so thread exit and join sat inside
    the measured interval. That overstates it, and dominates at one producer
    where a whole run is only hundreds of microseconds.

Each worker now timestamps itself either side of its own pushes, and the span is
the earliest start to the latest finish. A previous review had explicitly
cleared this, concluding the clock "genuinely starts at release"; it does not.

**Measured, with a control, because a benchmark correction that is not measured
is just a rewrite.** On x86_64 16p/8c, `reserving_mpsc` at sixteen producers:
35.0 ns/push before, 49.8-52.8 after. Two runs of the same build put the
run-to-run spread at 2-6%, so this is signal: the probe was reporting roughly
45% more throughput than the producers actually achieved, at the producer counts
the decision turns on. The one-producer rows moved the other way and slightly
(2.4 -> 2.3, 6.5 -> 6.0), which is the join overhead leaving the window.

The four figures recorded in DESIGN-NOTES predate this and are now marked as
such rather than quietly left standing. The qualitative finding they support --
a debug build swamps the effect -- is unaffected.

**A dead queue was retried forever.** The drained producers looped on every
`PushError`, but only `Full` is retryable; the queue crate's own documentation
says "retrying the first is sensible and retrying the second is a spin". If the
consumer panicked and dropped the receiver, every producer would spin
indefinitely, and because the consumer is joined only after the producer scope
completes, the panic could never surface -- the probe would hang rather than
fail. All four loops now assert `is_retryable()` first. Joining the producers
inside the scope, which the timing fix required anyway, means a producer panic
now surfaces too.

**The isolated regime does not isolate the compare-and-swap**, and both the
module doc and the design note said it did: "whatever curve appears against N is
the compare-and-swap and nothing else". What is timed is each shape's whole push
path -- tail claim, slot-sequence load, item write, publication store, doorbell
fence -- and `permit_mpsc` takes two shared read-modify-writes where the others
take one. A difference here is a difference in push cost. Narrowed to that.

Gate: fmt, clippy --all-targets, 236 lib + 12 integration, and the probe run end
to end (exit 0, 63.6s and 64.8s across two runs).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 14, 2026 20:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Moderate issues remain around target support, drained-regime synchronization, report validation, and platform-correct output.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (9)

crates/windows-platform-probes/Cargo.toml:158

  • Enabling dwcas unconditionally makes this package fail to build for i686-pc-windows-msvc: queue_contention.rs imports and instantiates Wide, but the queue crate's AtomicU128 implementation is unavailable on i686. The queue crate explicitly preserves i686 support, and this probe is not target-gated, so a workspace check for that supported target now breaks. Gate the wide rows and dependency feature on targets with 128-bit atomics, or explicitly exclude this probe from unsupported targets.
windows-waitable-queues = { path = "../windows-waitable-queues", features = [
	"experimental-permit-claim",
	# So the probe can instantiate the 128-bit layout. The 64-bit ones need no
	# feature; this is the only one that costs the queue crate a dependency.
	"dwcas",

crates/windows-platform-probes/DESIGN-NOTES.md:545

  • This heading is stale relative to the re-measured shipping-type results later in the same section: lines 669-670 report 3.83x and 3.99x at 16 and 32 producers, and explicitly supersede the earlier 2.37x/2.99x figures. Leaving "2-3x" in the heading makes the current design note contradict its own authoritative table.
## The claim word's width costs 2-3x in isolation and much less in use

crates/windows-platform-probes/DESIGN-NOTES.md:545

  • The later "Re-measured on the shipping type" section explicitly says that its numbers supersede this section, but this heading has no adjacent superseded-status marker. Add the required marker immediately below the heading so readers do not mistake the earlier 2-3x table and conclusions for the current measurement.
## The claim word's width costs 2-3x in isolation and much less in use

crates/windows-platform-probes/src/bin/queue_contention.rs:186

  • The report hard-codes cmpxchg16b, but this binary is not x86_64-only; the same Wide layout is available on ARM64, where the exchange uses ldxp/stxp. Running the probe there therefore emits an incorrect instruction description. Use a target-neutral description or select the instruction name with target-specific code.
        "     apportioned differently; 64/64 is a u128 exchange (cmpxchg16b)."

crates/windows-platform-probes/src/bin/queue_contention.rs:114

  • These lookups intentionally turn a missing row into None and then into --, so a wiring regression can produce a plausible report with an absent column. The new probe has no deterministic test for the expected shape/producer matrix or ratio rows, even though its module documentation calls out this exact rename failure mode. Add a synthetic Observation/renderer test in a sibling test module that asserts every expected row is present.
        let plain = observation.find(&observation.drained, shapes::SLOTWISE_MPSC, producers);
        let reserving = observation.find(&observation.drained, shapes::RESERVING_MPSC, producers);
        let permit = observation.find(&observation.drained, shapes::PERMIT_MPSC, producers);
        let ratio = format_ratio(reserving, plain);

crates/windows-platform-probes/src/lib.rs:151

  • The crate-level What each probe establishes inventory has no entry for the newly registered queue_contention module. Because this probe is binary-only and deliberately omitted from CI, leaving it out makes the public crate documentation an incomplete inventory and hides the claim this instrument supports. Add a queue_contention row with its binary-only tier and measurement claim.
pub mod queue_contention;

crates/windows-platform-probes/src/queue_contention.rs:558

  • This second drained setup has the same readiness gap: the barrier releases the consumer and producers together, but does not ensure the consumer has executed a pop before producer timers begin. Consequently this row can measure startup scheduling as well as the intended head contention. Use an explicit consumer-ready handshake before starting the producers.
    let gate = start_barrier(producers + 1);
    let consumer_gate = Arc::clone(&gate);

    let consumer = thread::spawn(move || {
        consumer_gate.wait();
        while !consumer_done.load(Ordering::Relaxed) {

crates/windows-platform-probes/src/queue_contention.rs:623

  • The barrier does not establish that the permit consumer is actually draining when the producers start; it only establishes that all parties reached the barrier. A producer can run and fill/refuse against the queue before the consumer's first pop, so the measured cost includes an uncontrolled startup phase. Add a consumer-ready handshake before the timed producer work.
    let gate = start_barrier(producers + 1);
    let consumer_gate = Arc::clone(&gate);

    let consumer = thread::spawn(move || {
        consumer_gate.wait();
        while !consumer_done.load(Ordering::Relaxed) {

crates/windows-platform-probes/src/queue_contention.rs:731

  • This layout-specific drained row also releases the consumer and producers simultaneously, without proving that the consumer has started its drain loop. The resulting initial backlog/refusals depend on scheduling and can bias the layout comparison. Gate producer timing on an explicit consumer-ready signal instead of using this barrier as a readiness guarantee.
    let gate = start_barrier(producers + 1);
    let consumer_gate = Arc::clone(&gate);

    let consumer = thread::spawn(move || {
        consumer_gate.wait();
        while !consumer_done.load(Ordering::Relaxed) {
  • Files reviewed: 6/7 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread crates/windows-platform-probes/src/queue_contention.rs
Comment thread crates/windows-platform-probes/DESIGN-NOTES.md Outdated
Mike Grier and others added 2 commits September 14, 2026 18:52
The queue-contention section said the u64 re-apportionments "track the default
within noise", so twenty years of counter headroom was "free". The table
directly beneath it showed 1.21x and 1.13x against a noise floor the same file
put at 2-6% -- the prose contradicted its own evidence in adjacent lines.

Re-measured seven times on x86_64 16p/8c after the timing correction in
d49a71f, which the original figures predate. Two findings:

- The 2-6% floor was obtained by comparing two runs, which cannot measure a
  spread. Seven runs put the same-configuration spread at 7-61%.
- The probe already emits its own control: `reserving_mpsc` and
  `reserving(32/32)` are the same code at the same layout, measured twice per
  run, so their ratio is an empirical "no difference" -- 0.68-1.27x. That is a
  derived control rather than an asserted floor.

Against that control the 128-bit word separates decisively (3.45x/3.81x at
16/32 producers) and the u64 re-apportionments do not. The claim is withdrawn
in BOTH directions rather than inverted: 1.23-1.30x against a control reaching
1.12x, on one host, is a flag to measure locally, not a cost.

Swept the class rather than the reported line: the same claim appeared three
times (the stand-in section, the headroom section's "at no measured cost", and
the re-measured section). All three corrected.

Records D-observations-not-verdicts: figures are published with their capture
parameters, and fine-grained layout choices belong to the client. Windows
exposes no NUMA distance table, so the processor-to-node assignment in the
banner is the analog used in its place; the measurement host's `numa[16]` is a
single domain, so these figures say nothing about cross-domain behaviour.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…dance

The withdrawn claim had propagated out of the probe's design note into this
crate's consumer-facing documentation, where it told callers that `Perpetual`
buys twenty years of headroom "at no measured cost". Three restatements plus
the decision they derive from:

- README.md, the "What to do about it" bullet
- src/lib.rs, the same text as public rustdoc on docs.rs
- README.md, the "Start here" chooser
- DESIGN-NOTES.md D-41, "measured indistinguishable outside noise"

The recurrence arithmetic is unaffected -- time-to-wrap follows from the field
width and a rate, not from a throughput measurement -- so the recommendation
stands. What is removed is the unsupported claim about what it costs to run.
Re-measured, the deeper layouts are indistinguishable from `Balanced` up to
eight producers and near 1.26x at sixteen and thirty-two, against a same-code
control reaching 1.12x, on a single host.

This is CONTRACT INTEGRITY rule 3: the reported site was a sample, not the
population, and a correction to a shipped rule obliges a re-check of what was
written against the old one.

Verified: 13 doctests pass, including the compiled README.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 14, 2026 22:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved moderate findings affect measurement reporting, probe discoverability, and helper-test coverage.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (6)

crates/windows-platform-probes/DESIGN-NOTES.md:782

  • The table immediately above is unlabeled, but it contains the 64/64 ratios 1.37x, 3.45x, and 3.81x at 1, 16, and 32 producers, while this sentence says the drained 128-bit word stays inside the control band. As written, the note either contradicts its table or omits the drained table needed to support the claim; label the table's regime and correct the conclusion to match the actual measurements.
In the drained regime nothing separates at all -- every u64 layout *and* the
128-bit word sit inside the control band at every producer count (the widest
median is 1.13x at one producer, against a control that reaches 1.27x).

crates/windows-platform-probes/DESIGN-NOTES.md:746

  • These capture details are not emitted by the new binary: it runs five repetitions and reports only the median, does not retain or print the observed range, and prints no release/debug marker. Because this probe is intentionally manual rather than CI-gated, stdout is the measurement record; add those fields to the observation/report or revise this promise before relying on the ratios.
Seven runs, median of the per-run ratios with the observed range beside it,
release build. **The banner's `numa[16]` is load-bearing here: it means a single
NUMA node holding all sixteen processors**, so every figure below was taken

crates/windows-platform-probes/src/bin/queue_contention.rs:50

  • This label duplicates DRAINED_CAPACITY from the measurement module. If the benchmark capacity changes, execution will use the new value while the captured report still says capacity 1024, making the observation self-contradictory; share/export the constant (or expose it through the observation) and interpolate it here.
        "\n-- drained: a consumer popping continuously, capacity 1024 --"

crates/windows-platform-probes/src/bin/queue_contention.rs:57

  • This heading overstates what the measurement isolates. scaling is computed from Run.pushes_per_second, and each timed run includes slot-sequence loads, the item write, publication, and the doorbell fence, as the module documentation notes; it is not a tail-CAS-only measurement. Rename the heading to describe producer push-path scaling/contended push cost so readers do not attribute the whole curve to the tail claim.
    let _ = writeln!(out, "  1. tail-claim contention (isolated regime)\n");

crates/windows-platform-probes/src/lib.rs:151

  • Please add queue_contention::measure to the What each probe establishes table above. That table is the crate's canonical inventory of probe tiers and claims (src/lib.rs:110-136), but the new module is currently only exported below, so this binary-only probe is undiscoverable in the documented inventory.
pub mod queue_contention;

crates/windows-platform-probes/src/queue_contention.rs:167

  • The new pure observation helpers have no tests: a missing shape/producer lookup silently becomes --, and an incorrect scaling calculation would directly change the conclusions printed by this probe. Add sibling unit tests for find and scaling (including missing and one-producer cases) without invoking the long host measurement; the repository already keeps focused sibling tests for comparable probe logic.
    pub fn scaling(&self, regime: &[Run], shape: &str, producers: usize) -> Option<f64> {
        let one = self.find(regime, shape, 1)?;
        let many = self.find(regime, shape, producers)?;
        Some(many.pushes_per_second / one.pushes_per_second)
  • Files reviewed: 10/11 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread crates/windows-waitable-queues/README.md Outdated
Comment thread crates/windows-waitable-queues/src/lib.rs Outdated
…not a wider ruler

The queue-contention repair derived a noise control from the probe's own output
-- `reserving_mpsc` and `reserving(32/32)` are the same code at the same layout,
measured twice per run -- and immediately used it to withdraw an unsupported
claim. But it then used it only as a yardstick, which quietly promoted a symptom
into a tool.

Two measurements of identical code in the same run differing by 27%, with
same-configuration spread reaching 61%, is first a finding about the METHOD.
Recording it as merely a coarser ruler and carrying on is how a methodological
problem becomes permanent.

Records D-variance-is-a-finding. The candidate causes are not separable from the
dispersion itself, so the note refuses to guess among them: wrong instrument for
the variable, a residual probe defect (one was already found and fixed in
d49a71f, invisible in the numbers and worth ~45%), too few runs or too short a
span, or a nanosecond-scale measurement on a shared loaded desktop.

The calibration is recorded rather than assumed, because it cuts both ways: a
spread this wide would be disqualifying in a benchmark or marketing document,
which exist to carry a comparative claim. These figures exist to support planning
for deployment environments resembling the measured one -- an ordinary machine
under ordinary load -- so the treatment is neither suppression nor promotion.
Publish the data, publish the dispersion, and publish that the dispersion is
unexplained.

Queues M4.2 as a diagnosis item rather than leaving the work in a design note,
per "design notes are not a work queue". It names a negative result as a valid
outcome that must still be recorded, and forbids resolving it by suppressing the
ranges.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 14, 2026 23:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved moderate and nit findings remain in probe reporting, inventory, and documentation.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (8)

Previously missed (3) — in code that hasn't changed since the last review.

crates/windows-platform-probes/src/bin/queue_contention.rs:32

  • This report includes a host banner, but fingerprint::banner_line() formats only host identity and does not say whether the binary is debug or release. The probe's documentation shows that debug and release can make the queue shapes look equivalent, so a captured report cannot establish whether its figures were produced under the required profile. Add an explicit build-profile line before the measurements.
    crates/windows-waitable-queues/README.md:185
  • The earlier README paragraph at lines 142-147 still says deeper positions cost nothing measurable, while this later changed paragraph correctly says the cost is unknown. A reader of this document gets both conclusions; update the earlier statement and the matching API/manifest docs too.
    crates/windows-waitable-queues/src/lib.rs:155
  • This new bullet says the throughput cost is not established, but the preceding public module docs at lines 110-116 still say that a deeper position costs nothing measurable; the same stale claim remains in reserving_mpsc.rs:186-188 and Cargo.toml:60-62. That leaves the published API guidance contradictory, so update all of those restatements in the same change.

crates/windows-platform-probes/DESIGN-NOTES.md:620

  • The PR description still says the existing probe job runs cargo run without --release, but the workflow already runs the nanosecond probes in release at .github/workflows/ci.yml:317-324. This paragraph correctly attributes exclusion to core count and runtime; align the PR description with that reason so release is not reported as the job-wide blocker.
**That is a constraint on HOW it runs, not an argument for keeping it out**, and an earlier draft of this
paragraph confused the two -- it said the CI job "runs `cargo run` without `--release`", which is not true
of the job it describes: `probe-doorbell-cost` and `probe-request-cost` already run there with `--release`,
under a comment establishing exactly the rule this probe would fall under. It also said "unlike every other
probe", and `probe-cancel-io` is likewise absent. Corrected by a review. The release precedent exists; what
keeps this one out is that it costs an order of magnitude more than the two probes that use it, on hardware
that cannot answer the question anyway.

crates/windows-platform-probes/DESIGN-NOTES.md:688

  • This subsection still presents cmpxchg16b as 2-3x in isolation and 5-12% in the drained regime, but the shipping-type remeasurement below reports 3.45-3.81x isolated at 16/32 producers and says all layouts fall within the control band when drained. The later section says it supersedes these numbers; mark this heading/conclusion as historical or move it to the rationale so the current design note does not expose two incompatible conclusions.
**Widening the word is not free, and how much it costs depends entirely on the
regime.** Isolated, where the claim is the only thing happening, `cmpxchg16b`
costs 2-3x and the penalty *grows* with contention. Drained, with a consumer
running, it is 5-12%. This is the one conclusion in this section that the
seven-run re-measurement strengthened rather than withdrew.

crates/windows-platform-probes/src/bin/queue_contention.rs:50

  • DRAINED_CAPACITY is defined as 1024 in the library, but this report repeats 1024 as a string literal. If the benchmark capacity changes, the output will describe the wrong regime, which is especially harmful because refusal counts are interpreted relative to this capacity. Render the heading from the shared constant instead.
        "\n-- drained: a consumer popping continuously, capacity 1024 --"

crates/windows-platform-probes/src/lib.rs:151

  • The module-level "What each probe establishes" table at src/lib.rs:110-136 is the crate's exhaustive probe inventory, but this addition only declares queue_contention and adds no row for probe-queue-contention. Add its binary-only tier and supported claim there so the new instrument is discoverable and the inventory remains complete.
pub mod queue_contention;

crates/windows-platform-probes/src/queue_contention.rs:11

  • These module docs say the probe exists to force two decisions, but the implementation and renderer also measure and report a third decision about claim-word layout (the output's "Question 3"). Update the module-level contract to mention that comparison, or explain why it is subordinate to one of the two decisions, so users can reconcile the documented scope with the report.
//! # The two decisions this exists to force
//!
//! **1. Are the linked and sharded MPSC shapes needed at all?** They are parked
  • Files reviewed: 11/12 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread crates/windows-platform-probes/src/queue_contention.rs
…ere the floor is

Extends D-variance-is-a-finding with the practical half, and re-scopes M4.2 from
"diagnose the variance" to "give the probes the controls that make diagnosing it
possible" -- the judgement stays with the person, the probe stops being the
obstacle.

What the note now says:

- Gather more of the same before gathering anything different. Lengthening the
  span and raising the repetition count is the only step that changes nothing
  about what is measured, so it is the only one whose result is interpretable
  before the others have been tried. Pinning, quiescing, or altering the probe
  all move the measurement as well as the noise.
- A warmup separates transient cost from ongoing noise. Recorded with the
  objection it invites: if noise were inherent, warming could not remove it. It
  does not -- warming removes front-loaded transients (page faults, cold caches,
  frequency ramp) while tenant contention runs for the whole measurement. So
  warming uncovers the inherent floor rather than hiding it, and the expected
  signature is a spread that narrows and then plateaus.
- There is always a floor, and recognising it is the skill. Past it more runs buy
  nothing.
- The floor is NOT necessarily a fraction of the measured value. It can be set by
  the sampling regime -- clock granularity, independent sample count, how the span
  is built. This probe takes two timestamps per worker per repetition, so what
  limits resolution at small values is the pass count, not a percentage of the
  nanoseconds printed. The two readings prescribe opposite actions, which is why
  "small numbers are just noisy" is a guess and not a diagnosis.

M4.2's software scope, verified against the source: PUSHES_PER_PRODUCER (50_000)
and REPETITIONS (5) are private consts and measure() takes no arguments, so the
prescribed first move currently requires a source edit and a rebuild. Defaults
must not change, and whatever settings a run used have to be reported beside the
host banner -- they are capture parameters now, per D-observations-not-verdicts.

Note the warmup is partly present already: one untimed pass exists, but only to
fault in the allocation's pages.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 14, 2026 23:27
…meters

This PR added D-observations-not-verdicts, which requires every published figure
to carry the parameters of its capture, and then published figures missing two of
them. The block recorded the host banner, the build profile, and "seven runs" --
but not what a run consists of.

Each run is a whole probe invocation, within which every configuration is
measured REPETITIONS (5) times and the median reported, each measurement being
PUSHES_PER_PRODUCER (50,000) pushes per producer thread, preceded by one untimed
pass that faults in the fresh allocation's pages. So each published figure rests
on 35 timed passes per configuration, and "seven runs" alone does not let anyone
reproduce it.

Also names where the two constants live and points at M4.2, which makes them
adjustable -- the note now prescribes lengthening the span and raising the
repetition count as the first response to a wide control, and the probe cannot
currently do either without a source edit. Recording the gap is what this PR
owes; closing it is follow-up.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Six sites said the reservation-count field is what limits `Enduring` and
`Perpetual`, full stop. It is not. The achievable count is the lesser of the
queue's capacity and the field ceiling, so a `Perpetual` queue of capacity 64
admits 64 reservations rather than 255 -- and the README's own worked example
uses exactly that capacity, so it stood as a counterexample to the sentence three
paragraphs above it.

The crate had this right where it was tested and wrong where it was described.
An earlier sabotage on this branch already demonstrated it: the same test that
fills Perpetual to 255 at capacity 1024 stops at 128 when the capacity is 128.
The evidence was in the branch and the prose contradicted it.

Corrected in the README, the crate rustdoc, `ClaimLayout`'s table note, the
`Balanced` comparison, and both the `Enduring` and `Perpetual` type docs, which
said "Holds 65,535" and "Holds 255" as though every instance could.

Three corrections in the root design note, all to claims about its own analysis
rather than about the code:

  - "validate the first three rows" named an ordinal position; the table's second
    row is a time row, so the sentence contradicted the one before it. Named the
    three rows instead of counting them.
  - "converting 19 hand-written 255s into checked derivations" overstated the
    proposed check: the 19 spans all five figures and includes prose occurrences
    a table parser never sees. Now says it reaches the tabular occurrences and
    only those.
  - the note pointed at `M30` in the root checklist, which does not exist on this
    branch -- it is queued on another. Removing the branch-status qualifier last
    round for durability turned a stale reference into a broken one. The note now
    says a survey is queued separately without naming an ID it cannot resolve.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@MikeGrier

Copy link
Copy Markdown
Owner Author

Sweep of outstanding review feedback, and the response to it

I scanned every Copilot review on this PR rather than only the ones surfaced to me, and found three review rounds I had never seen5218035835, 5218176020, 5218215827 — plus one unresolved inline thread. Two of the three turned out to duplicate rounds already handled. One did not, and neither did the thread.

Everything below is now addressed in a8d4c7f and 3761c63.

The unresolved thread: ratio_bounds returned the inverse of its contract

Changed, and this was a real API defect in code I added two commits ago. The function documented the interval for a numerator / denominator cost ratio and returned the rate ratio instead. Both internal callers compensated by passing their rows in the opposite order.

That is why it was invisible: every rendered figure was correct, because the two swaps cancelled. It was only wrong for someone calling the function directly — which is the whole point. A public contract that is only correct if you read the implementation is not a contract.

The arithmetic now matches the documentation, and each caller passes its rows in the order matching what it wants: format_ratio_bounded wants a cost ratio and passes them straight; scaling_bounds wants a rate ratio — the cost ratio of one-producer over many — and says so at the call site.

No published figure changes, verified by rebuilding and reading the report. What changed is that the drained table's first row is now checkable by hand from its own columns: 25.9 / 13.0 = 1.99x. It always was; nobody could tell.

The field does not bind — six sites, and a counterexample already in the README

Changed. This is the one I am least comfortable about, because the crate had it right where it was tested and wrong where it was described.

The achievable reservation count is min(capacity, field ceiling). Six places said the field is simply what limits Enduring and Perpetual:

  • README.md and src/lib.rs — "For the others the field binds on either"
  • ClaimLayout's table note — "the field binds first, and the column is the real limit"
  • Balanced's comparison — "both reachable because capacity does not bind there"
  • Enduring's type doc — "Holds 65,535 outstanding reservations"
  • Perpetual's type doc — "Holds 255 outstanding reservations"

The README's own worked example is bounded_as::<u32, Perpetual>(64) — capacity 64, so 64 reservations, not 255. The counterexample was three paragraphs below the sentence.

And the evidence was already in this branch: a sabotage run earlier in the review history fills Perpetual to exactly 255 at capacity 1024 and stops at 128 when capacity is 128. I had run that, seen the result, and left the prose saying otherwise.

Report header: ns/pu

Changed. It abbreviated one unit while every other table and test in the crate says ns/op, and it had been hand-truncated to fit a column that the bounded ratios then outgrew. The drained table now has a two-line header naming the unit per column and marking the ratio columns as carrying a bound.

Three corrections in the root design note

All to claims about its own analysis rather than about the code:

  • "validate the first three rows" named an ordinal; the table's second row is a time row, so the sentence contradicted the one immediately before it. Named the three rows instead of counting them.
  • "converting 19 hand-written 255s into checked derivations" overstated the proposed check — the 19 spans all five figures and includes prose occurrences a table parser never sees.
  • The note pointed at M30 in the root checklist, which does not exist on this branch. Removing the branch-status qualifier last round for durability turned a stale reference into a broken one. It now says a survey is queued separately, without naming an ID it cannot resolve.

What the sweep itself taught

I had been answering the rounds I was handed, not the rounds that existed. Three reviews had accumulated unseen, and the one that mattered contained a six-site logic error in public documentation. Checking the review list directly takes one API call and I had never made it.

The pattern is the same one this PR keeps producing in other forms: the reported instance is a sample, not the population — applied here to the reports themselves.

This PR adds the rule that a number belongs in one place and prose should carry the claim. The section stating it opened with a prose-to-code ratio, three workspace line counts and a five-row census table, all hand-maintained and none reproducible. It was a counterexample to itself, which a review said plainly.

It had also already failed twice. The table drifted within days when a rustdoc qualifier added an occurrence -- recorded in a parenthetical rather than fixed -- and re-running the census while making this change shows the ceiling at 22 occurrences where the table says 19, because corrections landed in this same session. A census of restatements had become a restatement needing maintenance.

Now qualitative, with the command that computes the counts. A reader gets current numbers instead of a snapshot of someone else's, which is what 'let findings be findings computed directly' means when applied to this section rather than only recommended by it. The command was run before committing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Unresolved renderer validation and duplicated benchmark provenance concerns remain.

Review details

Suppressed comments (8)

Previously missed (1) — in code that hasn't changed since the last review.

DESIGN-NOTES.md:1877

  • These workspace line counts and restatement counts are the quantitative evidence for this decision, but no committed capture, command, or provenance is provided. A later recount cannot be verified or detected, recreating the hand-transcription problem this note identifies; please add a checked-in capture/provenance or state the conclusion qualitatively without these digits.

DESIGN-NOTES.md:1932

  • D-31 says the queue ships without machine-checked memory orderings and that model checking is planned; this repository has no TLA+ or loom run producing a result. The preceding section correctly says the absence of findings is because no instrument exists, so saying these tools “have produced no findings” turns an unmeasured property into a result. Please describe them as planned/not run and keep the absence of evidence explicit.
- **Policy** -- client prescriptions surviving [D-no-client-prescriptions](crates/windows-platform-probes/DESIGN-NOTES.md#d-no-client-prescriptions).
  Only a reviewer catches these.
- **Algorithm properties** -- **zero findings, in any round.**

DESIGN-NOTES.md:1978

  • A digit-free prose claim can still drift from its measurement: if the artifact or host data changes, “measured faster” can become stale while containing no numbers, and a reader cannot see that without checking the artifact. This should say that prose reduces transcription drift, not that it cannot drift.
README and the crate rustdoc disagreeing because one was retaken; an attribution naming a capture
the figures no longer came from; one recurrence horizon left unqualified across seven sites in three
wordings; a withdrawn magnitude surviving in two public rustdocs. The most instructive was a
proportion that restated two counts **given four words earlier in the same sentence** and got one of

crates/windows-platform-probes/src/queue_contention.rs:350

  • The guard here only checks the denominator. Because Run fields and this renderer are public, a caller can pass a Run whose numerator or span contains NaN/inf; this then formats as NaNx/infx (and possibly NaN bounds) instead of the non-finite-safe -- output used by format_scaling. Please make the ratio path reject non-finite values consistently, including the span values used by ratio_bounds, and add a regression test for a non-finite numerator.
pub fn format_ratio_bounded(numerator: Option<Run>, denominator: Option<Run>) -> String {
    match (numerator, denominator) {
        (Some(numerator), Some(denominator)) if denominator.nanos_per_op > 0.0 => {
            let point = numerator.nanos_per_op / denominator.nanos_per_op;
            match ratio_bounds(numerator, denominator) {

crates/windows-platform-probes/src/queue_contention.rs:432

  • The same denominator-only check leaves this public helper able to emit NaNx or infx when a caller constructs a Run with a non-finite numerator. That is especially inconsistent with the new renderer contract, which explicitly maps non-finite scaling values to --; please apply the same finite-input policy here and cover it in the renderer tests.
pub fn format_ratio(numerator: Option<Run>, denominator: Option<Run>) -> String {
    match (numerator, denominator) {
        (Some(numerator), Some(denominator)) if denominator.nanos_per_op > 0.0 => {
            format!("{:.2}x", numerator.nanos_per_op / denominator.nanos_per_op)
        }

crates/windows-waitable-queues/README.md:413

  • This table is a second hand-maintained copy of the same fecd352 capture that is also embedded in the crate rustdoc (src/lib.rs). Because neither copy is generated from a single data artifact, a later retake can update one table and leave the other publishing stale values—the exact transcription drift this PR documents. Please make one capture/table canonical and derive or otherwise mechanically validate the other.
**What was measured**, in ns per operation, isolated regime (producers only,
capacity large enough that nothing is refused). Each cell is the median of three
whole-probe runs, followed by the full range across all fifteen repetitions those
runs contain. An operation is one successful push for the three queue shapes;
for `baseline_fetch_add` it is one `fetch_add`, which is why the column is
labelled per operation rather than per push:

| producers | `slotwise_mpsc` | `reserving_mpsc` | `permit_mpsc` | `baseline_fetch_add` |
|---|---|---|---|---|
| 1 | 6.3 (6.3-7.5) | 5.4 (5.4-6.4) | 7.9 (7.9-8.3) | 2.3 (2.3-2.7) |
| 2 | 50.6 (19.3-59.5) | 31.9 (22.5-35.2) | 44.2 (37.4-45.9) | 12.1 (5.8-14.3) |
| 4 | 91.6 (89.7-99.9) | 37.2 (31.6-41.5) | 31.8 (30.4-32.9) | 13.8 (12.6-17.6) |
| 8 | 138.6 (126.9-157.6) | 37.8 (34.3-41.7) | 25.9 (25.0-27.4) | 14.7 (13.9-15.9) |
| 16 | 218.0 (188.9-272.7) | 47.9 (44.9-56.0) | 21.8 (20.9-25.6) | 14.8 (14.4-15.9) |
| 32 | 224.7 (131.4-268.3) | 51.3 (40.7-55.4) | 21.9 (20.7-39.0) | 15.0 (14.7-15.7) |

crates/windows-waitable-queues/src/lib.rs:343

  • This rustdoc table duplicates the same fecd352 capture maintained separately in README.md, so the two public surfaces can silently diverge on the next measurement retake. Please make one capture/table canonical and derive or mechanically validate the other instead of keeping two numeric copies by hand.
//! | producers | `slotwise_mpsc` | `reserving_mpsc` | `permit_mpsc` | `baseline_fetch_add` |
//! |---|---|---|---|---|
//! | 1 | 6.3 (6.3-7.5) | 5.4 (5.4-6.4) | 7.9 (7.9-8.3) | 2.3 (2.3-2.7) |
//! | 2 | 50.6 (19.3-59.5) | 31.9 (22.5-35.2) | 44.2 (37.4-45.9) | 12.1 (5.8-14.3) |
//! | 4 | 91.6 (89.7-99.9) | 37.2 (31.6-41.5) | 31.8 (30.4-32.9) | 13.8 (12.6-17.6) |
//! | 8 | 138.6 (126.9-157.6) | 37.8 (34.3-41.7) | 25.9 (25.0-27.4) | 14.7 (13.9-15.9) |
//! | 16 | 218.0 (188.9-272.7) | 47.9 (44.9-56.0) | 21.8 (20.9-25.6) | 14.8 (14.4-15.9) |
//! | 32 | 224.7 (131.4-268.3) | 51.3 (40.7-55.4) | 21.9 (20.7-39.0) | 15.0 (14.7-15.7) |

crates/windows-waitable-queues/src/reserving_mpsc.rs:263

  • This public ClaimLayout rustdoc still publishes the exact 1.23-1.30x and 1.12x measurements without the host, run count, dispersion, or a capture link. That conflicts with the probe's own D-observations-not-verdicts requirement that every published figure carry its sampling context, and makes these numbers another unattributed copy even though the surrounding text correctly withdraws the performance conclusion. Please remove the figures from this API documentation or attach the same provenance as the attributed probe results.
/// slower. **What that costs in throughput is not established**: a probe
/// comparing them found them indistinguishable at low producer counts, and at high counts ran 1.23-1.30x the default against a same-code control that itself reaches 1.12x -- outside the control, but too close to it to establish an ordering or a cost on this host. The settled trade is the
/// reservation ceiling; throughput is target-dependent and this crate does not
/// characterise it beyond the one host in the note above.
  • Files reviewed: 21/22 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Unresolved documentation claims still describe a finite 2^64 horizon as unreachable and retain an unqualified performance recommendation.

Review details

Suppressed comments (4)

crates/windows-waitable-queues/README.md:133

  • The table makes 2^64 pushes look unreachable even though this column is explicitly computed from a finite sustained rate. At the stated 116 million pushes/second, this is about 5,000 years; please publish the finite practical horizon rather than an absolute impossibility claim.
| `Wide` (needs `dwcas`) | 4,294,967,295 | 2^64 | unreachable |

crates/windows-waitable-queues/src/lib.rs:102

  • This compiled copy of the layout table repeats the unsupported unreachable value for a finite 2^64 position. The surrounding text says the horizon is arithmetic at 116 million pushes/second, which is roughly 5,000 years; please keep this public rustdoc consistent with the README and describe it as a practical, rate-dependent horizon.
//! | `Wide` (needs `dwcas`) | 4,294,967,295 | 2^64 | unreachable |

crates/windows-waitable-queues/src/reserving_mpsc.rs:37

  • 2^64 is a finite position bound, so saying no deployment reaches it is stronger than the arithmetic documented immediately below and is not portable across sustained rates or deployment lifetimes. Please describe this as a practical horizon that depends on the caller's rate.
//! the recurrence to 2^64 pushes, which no deployment reaches.

crates/windows-waitable-queues/src/reserving_mpsc.rs:70

  • The public rustdoc still ends with slotwise_mpsc being for a caller who wants the “cheapest possible push” (lines 97-99). That remains an unqualified performance recommendation, even though this updated paragraph says the complete-path measurement found reserving_mpsc faster on the tested hosts and the crate documentation deliberately avoids choosing a winner. Please remove or qualify that stale prescription as an unmeasured design trade-off so the withdrawn claim is not still published through this module’s API docs.
//! **What that read costs is not established, and this comparison cannot
//! establish it.** This shape measured *faster* than `slotwise_mpsc` under
//! contention on the hosts tried -- an end-to-end result over the complete push
//! path, in which the consumer-position read is one term among the protocol,
//! metadata and retry costs and is not separated from them. So the honest
//! statement is that the extra read did not stop this shape being the faster of
//! the two here; it is **not** that the read is cheap, nor that it is "not what
  • Files reviewed: 21/22 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Seven sites called `Wide`'s recurrence unreachable, or said no deployment
reaches it -- two as the table cell "unreachable", five as prose. The column
those cells sit in is explicitly arithmetic over a finite rate, and the rows
beside them read 37 seconds, 28 days and 20 years. Computed at the same rate the
table documents, 2^64 pushes is about 5,000 years.

So the crate published an absolute claim in a column of finite arithmetic, three
cells away from the arithmetic that contradicts it. All seven now give the
figure, and say it is a longer horizon rather than the absence of one, moving
with the caller's rate like every other entry in that column. Verified by
computing all four rows: 2^32 gives 37 seconds and 2^56 gives 19.7 years, which
match what was already published, so the rate model is the same one.

This is the table-cell form of a claim already withdrawn twice in this branch as
prose -- "Wide removes it" went through the same correction rounds ago. A cell is
a restatement like any other and the sweeps that fixed the sentences did not
reach it, because a one-word cell does not read like a claim.

The module docs also still said `slotwise_mpsc` is "for a caller who wants the
cheapest possible push". That asserts a cost ordering this crate does not
establish and that its own end-to-end measurement did not find -- the same
measurement whose causal reading was withdrawn earlier in this branch. The two
shapes are now distinguished by what each offers rather than by which is quicker,
with the withdrawn phrasing recorded rather than silently dropped.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@MikeGrier

Copy link
Copy Markdown
Owner Author

Response to this round (4 suppressed findings)

Addressed in 893a279. Three were one claim, and I found it in seven places rather than the three reported.

2^64 is not unreachable — it is about 5,000 years

Changed at all seven sites. The finding is right and the reason it is right was sitting three cells away: that column is explicitly arithmetic over a finite rate, and the rows beside it read 37 seconds, 28 days, 20 years. Computed at the same rate the table documents:

position pushes to recurrence at the documented rate
32 bits 2^32 37 seconds
48 bits 2^48 28 days
56 bits 2^56 19.7 years
64 bits 2^64 ~5,039 years

I computed all four rather than just the disputed one, because the first three matching what was already published is what confirms the rate model is the same one — the fourth figure is only trustworthy if the arithmetic reproduces the others.

So the crate published an absolute claim inside a column of finite arithmetic. All seven sites now give the figure and say it is a longer horizon rather than the absence of one, scaling with the caller's rate like every other entry.

Two of the seven were table cells reading unreachable. That matters beyond the count: this is the cell form of a claim already withdrawn twice in this branch as prose — "Wide removes it" went through exactly this correction rounds ago. The sweeps that fixed the sentences did not reach the cells, because a one-word cell does not read like a claim. Worth naming: my instruments scan for sentences.

slotwise_mpsc "for a caller who wants the cheapest possible push"

Changed. Correct — that asserts a cost ordering this crate does not establish, and that its own end-to-end measurement did not find. It is also a survivor of the same withdrawal: the causal reading of that comparison was retracted earlier in this branch, and this sentence was the conclusion left standing after its premise went.

The two shapes are now distinguished by what each offers — one for a caller who can treat refusal as backpressure, one for a caller with a message it must not lose — rather than by which is quicker. The withdrawn phrasing is recorded rather than silently dropped.


What the round taught

A table cell is a restatement, and it does not look like one. Every instrument I have built in this PR searches prose: flattened multi-line regexes, claim-based rather than phrasing-based, swept across .rs, .md and .toml. All of them walk straight past | unreachable |, because a cell has no verb, no hedge, and nothing that reads as an assertion — while being, in this case, the strongest assertion on the page.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The queue-contention formatting guard and documentation consistency nits remain unresolved.

Review details

Suppressed comments (7)

Previously missed (1) — in code that hasn't changed since the last review.

crates/windows-platform-probes/src/queue_contention.rs:349

  • This guard only rejects a zero denominator. If the numerator row is zero (the same failure sentinel used by the formatter tests), this renders 0.00x; ratio_bounds correctly rejects that span, but the fallback still publishes a numeric ratio that looks measured. Require a positive numerator as well (and cover that case) before formatting the point estimate.

This issue also appears on line 430 of the same file.

DESIGN-NOTES.md:1910

  • This paragraph says there are “two time figures,” but the layout tables carry more than two arithmetic horizons (37 seconds, 28 days, 20 years, and the Wide 5,000-year row). The proposed constants-versus-table check should not describe its uncovered set with a count that is already inconsistent with the table; refer to “the time figures” (or enumerate the intended subset precisely).
**All of these are restated by hand with nothing checking them.** Three of those facts -- the
ceiling, the span and the field ceiling -- follow from `ClaimLayout`'s associated constants. The two
time figures follow from a field width *and* an assumed sustained push rate, so a
constants-versus-table check would validate those three outright and the time figures only once the
rate is pinned somewhere single. That distinction bounds what the cheapest remedy below can do -- an

crates/windows-platform-probes/CHECKLIST.md:146

  • This completion link introduces another bare date. The repository's timestamp convention requires dates written in tracked documents to be UTC or carry an explicit offset; please include UTC in the link text (the archive already has the precise completion timestamp).
- [x] **M4.5** -- Emit the dispersion, not just the median. -> [completed 2026-09-15](COMPLETED-CHECKLIST.md#m45)

crates/windows-platform-probes/COMPLETED-CHECKLIST.md:1118

  • The new archive group header records only a local calendar date even though the repository requires newly written dates to be UTC or carry an explicit offset. Use the existing completion timestamp, including its offset, in the group heading.
## Moved 2026-09-15 -- M4.5: the probe carries its own dispersion

crates/windows-platform-probes/src/queue_contention.rs:431

  • The same sentinel handling is incomplete here: a zero numerator passes this predicate and produces 0.00x, even though the function's contract says an unmeasurable row should render --. The existing test only exercises a zero denominator, so add the numerator check and regression case too.
        (Some(numerator), Some(denominator)) if denominator.nanos_per_op > 0.0 => {
            format!("{:.2}x", numerator.nanos_per_op / denominator.nanos_per_op)

crates/windows-waitable-queues/README.md:435

  • This capture date is written without a timezone, but repository documentation requires dates in tracked files to be UTC or carry an explicit offset so the recorded instant is unambiguous. Please label it as 2026-09-15 UTC (and keep the mirrored rustdoc entry consistent).
| Taken | 2026-09-15 |

crates/windows-waitable-queues/src/lib.rs:356

  • The mirrored capture attribution repeats a bare local date. Repository documentation requires dates in tracked files to be UTC or carry an explicit offset; please use the same explicit UTC/offset form as the README so the two published attributions cannot be interpreted differently.
//! | Taken | 2026-09-15 |
  • Files reviewed: 21/22 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Mike Grier and others added 2 commits September 15, 2026 21:43
… a result

Both ratio formatters guarded only the denominator, on the reasoning that
division is what breaks. Zero is this probe's sentinel for "this shape did not
run", and it means that on either side of the division: a zero denominator
printed `inf`, which the guard caught, and a zero numerator printed `0.00x`,
which nothing caught.

The second is the worse of the two and is why this is a fix rather than
tidying. `inf` announces itself as broken. `0.00x` reads as a shape that was
immeasurably fast -- a plausible number, in a column of measurements, produced by
a row that never ran.

Both formatters now require a positive numerator and denominator. Three tests
cover it, including one that asserts the two functions agree about what is
unmeasurable in every position: they are separate functions with separate
guards, which is precisely how one of them came to guard half the cases.
Verified by sabotage -- restoring the denominator-only guard renders `0.00x` and
fails two tests.

Also corrects two dates this branch wrote without an offset, against the
"timestamps carry their offset" rule: M4.5's archive group heading and its stub
link. The archive's own completion stamp already carried `UTC-07:00`, so the
group heading contradicted the entry beneath it. Swept the dates this branch
added rather than the two reported; the rest of the repository's bare dates are
filenames, directory names and pre-existing history, which that rule does not
govern.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Both published copies of the capture attribution wrote a bare 2026-09-15. The timestamps-carry-their-offset rule exists so two readers in different zones agree on the instant; a capture attribution is exactly the place that matters, since its whole purpose is to make a figure reusable by someone else.

The root design note said the layout tables carry 'two time figures'. They now carry four -- 37 seconds, 28 days, 20 years and the 5,000-year Wide row -- and the fourth is one I added last round while correcting the unreachable claim. My own fix invalidated the sentence counting the thing it changed, two paragraphs away. Reworded to name the constant-derived facts and the time figures without counting either.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@MikeGrier

Copy link
Copy Markdown
Owner Author

Response to this round (7 suppressed findings)

Addressed in f3d5757 and 10ef5fc.

A zero numerator rendered 0.00x — the real finding

Changed in both formatters. Both guarded only the denominator, on the reasoning that division is what breaks. Zero is this probe's sentinel for "this shape did not run", and it means that on either side:

rendered caught?
zero denominator inf yes
zero numerator 0.00x no

And the uncaught one is the more dangerous, which is why this is a fix rather than tidying. inf announces itself as broken. 0.00x reads as a shape that was immeasurably fast — a plausible number, in a column of measurements, produced by a row that never ran.

Three tests cover it, including one asserting the two functions agree about what is unmeasurable in every position. That test exists because of how the defect arose: they are separate functions with separate guards, so fixing one said nothing about the other. Verified by sabotage — restoring the denominator-only guard renders 0.00x and fails two tests.

You also noted the existing test only exercised a zero denominator. That is exactly right, and it is the same shape as the refusals: 0 fixture problem from an earlier round: a test that only ever supplies the failure sentinel in one position cannot discover that the other position is unguarded.

The four bare dates

Changed. The convention is explicit — "when you write a date into a repository file, make it UTC or give it its offset" — and I broke it in four places this branch introduced.

The archive entry is the one worth noting: its completion stamp already read 2026-09-15 20:04:09 UTC-07:00, while the group heading immediately above it read a bare 2026-09-15. The correct form was sitting one line below the incorrect one.

I swept the dates this branch added rather than the two reported, and deliberately left the rest: the repository's other bare dates are filenames, directory names, and pre-existing history, which that rule does not govern. Churning them would be noise in a PR about something else.

DESIGN-NOTES: "two time figures"

Changed, and this one is entirely self-inflicted. The tables now carry four arithmetic horizons — 37 seconds, 28 days, 20 years, and the 5,000-year Wide row — and the fourth is one I added last round, while correcting the "unreachable" claim.

So my fix invalidated a sentence two paragraphs away that counted the thing the fix changed. Reworded to name the constant-derived facts and the time figures without counting either, since a count is the part that goes stale.


What the round taught

Three of these are the same failure at different scales: a count or a guard that was correct for the case in front of me and silent about its siblings. The denominator guard did not know about the numerator. The test fixture put the sentinel in one position only. The sentence counting time figures did not know a fourth had arrived.

None of them are restatements, so none would be caught by the claim-sweeping I have been building all through this PR. What they share is that each was written while looking at one instance of a set — which is the same root as the reported site is a sample, not the population, turned inward on my own edits rather than outward on the codebase.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Unresolved documentation issues remain, including duplicated measurement sources and stale or restated benchmark figures.

Review details

Suppressed comments (10)

DESIGN-NOTES.md:1981

  • This paragraph computes 57 / 61 as 93% immediately after presenting the two counts, but the new documentation rule explicitly says not to restate proportions over data already shown because the hand-computed copy can drift. Please describe this review finding without repeating the ratio (or link to a single artifact that owns the measurement).
wordings; a withdrawn magnitude surviving in two public rustdocs. The most instructive was a
proportion that restated two counts **given four words earlier in the same sentence** and got one of
them wrong -- "in both cases roughly 60%", against 57 of 61, which is 93%. The data was adjacent and
the summary of it was false, because prose is not checkable and nobody checks it.

DESIGN-NOTES.md:1997

  • 15.3 and 246.9 are medians from the superseded pre-correction capture that this PR says was removed from the documentation. Leaving them as bare examples here reintroduces stale benchmark figures without attribution, and conflicts with the immediately stated rule that measured numbers belong only in a provenance-carrying artifact; use non-numeric placeholders instead.
- **A number belongs in an artifact.** `15.3`, `246.9`, `fecd352`, a count of occurrences: one copy,
  with its provenance travelling *with* it rather than in a hand-maintained attribution table
  beside it.

crates/windows-platform-probes/COMPLETED-CHECKLIST.md:1146

  • This archived checklist entry repeats the same hand-computed "factor of three" immediately after showing 19.3 and 59.5. The new repository rule says proportions over already-shown data are restatements, so retain the observed range but remove the derived ratio here as well.
The dispersion justified itself on first capture. `slotwise_mpsc` at two producers spans 19.3 to
59.5 ns/op -- a factor of three within one configuration on one host -- which the median alone had
concealed entirely, in a table that had already been published twice.

crates/windows-waitable-queues/DESIGN-NOTES.md:78

  • This decision row says the figures are in the probe note "rather than restated here", but it still embeds 1.23-1.30x and 1.12x in the row itself. That leaves the measurement with two prose homes and contradicts the single-source rule added in this PR. Remove the numeric ratios here and point readers to the probe note instead.
| <a id="d-41"></a>D-41 | **The claim word's apportionment is a caller's choice, and the recurrence behind SH-14.1 is a number the caller sets rather than one this crate imposes.** Supersedes [D-36](#d-36), whose premise was that the only fix was the [D-35](#d-35) claim-protocol replacement, gated on an open question -- so disclosing beat delaying. That premise was false, and measurement is what showed it: the 32/32 split followed from requiring the reservation half to hold the *entire capacity*, because every slot could be reserved at once. Capping outstanding reservations instead leaves the capacity bounded only by the ring, and the position is free to take 48 or 56 bits. `Balanced` (32/32), `Enduring` (16/48) and `Perpetual` (8/56) issue the **same** atomic compare-exchange on the same `u64`, differing only in shift and mask constants -- so the recurrence moves from about 37 seconds to about 20 years without a dependency. **An earlier version of this row added "and measured indistinguishable outside noise", and that clause is withdrawn**: it rested on a single probe run read against a noise floor of 2-6% that seven runs put at 7-61%. Re-measured, the deeper layouts are indistinguishable from `Balanced` at low producer counts, and at high counts ran 1.23-1.30x the default against a same-code control that itself reaches 1.12x -- outside the control, but too close to it to establish an ordering or a cost on this host: a flag to measure locally, not a finding. The figures are in the probe's note rather than restated here. The layout is the caller's choice and the throughput question belongs on the caller's hardware; see the queue-contention section of [DESIGN-NOTES.md](../windows-platform-probes/DESIGN-NOTES.md#d-queue-layout-observations). Which half the bits go to is the trade this decision exposes rather than settles: a 32-bit reservation field, whose count the shipping type caps at `u32::MAX` and whose achievable value capacity caps lower still, against a position whose width sets the recurrence horizon. The bound that matters on the reservation side is how many reservations a caller holds at once -- the lesser of the ring capacity and the field, reachable by one producer alone, since `reserve` takes `&self`. Which of the two a deployment needs is the deployment's question. **An earlier version of this row said the real bound was "however many producers are mid-send", and that is withdrawn as false**: one producer fills `Perpetual`'s 255 in a loop and is then refused, which `one_producer_alone_can_exhaust_the_reservation_field` pins. The correction matters because the false premise made the narrower fields look unreachable, which is the argument for spending bits on the position. `Wide` (64/64 over a `u128`) is offered behind the non-default `dwcas` feature, because it is the one thing here that costs a third-party crate -- the standard library has no 128-bit atomic -- and the whole push path was measured as slower under it as producer count rises in the isolated regime -- near parity at one or two, several times by thirty-two -- while falling inside the same-code control when drained. The probe times the complete push, so that is the layout's effect on that path rather than a measurement of the exchange alone; it buys a guarantee rather than a lifetime argument. **The default stays `Balanced`** so introducing the choice changed no existing caller's behaviour, and its documentation states the defect outright -- that past 2^32 pushes from two or more producers the queue can silently lose an item -- rather than leaving the status quo to look safe by inertia. It states the defect rather than recommending against the layout, per [D-no-client-prescriptions](../windows-platform-probes/DESIGN-NOTES.md#d-no-client-prescriptions): a caller told what the layout does can decide; a caller told what to prefer has been handed our judgement about their deployment. |

crates/windows-waitable-queues/DESIGN-NOTES.md:78

  • D-41 now says the pre-correction figures belong only in the probe note, but the decision index still presents D-35 as a current measured result ("2.7x" at 16–32 producers and "1.45x" at one) without marking those values as predating the timing correction. A reader using the index can therefore still take the withdrawn magnitudes as current; mark the D-35 index entry as historical/pre-correction as part of this withdrawal sweep.
| <a id="d-41"></a>D-41 | **The claim word's apportionment is a caller's choice, and the recurrence behind SH-14.1 is a number the caller sets rather than one this crate imposes.** Supersedes [D-36](#d-36), whose premise was that the only fix was the [D-35](#d-35) claim-protocol replacement, gated on an open question -- so disclosing beat delaying. That premise was false, and measurement is what showed it: the 32/32 split followed from requiring the reservation half to hold the *entire capacity*, because every slot could be reserved at once. Capping outstanding reservations instead leaves the capacity bounded only by the ring, and the position is free to take 48 or 56 bits. `Balanced` (32/32), `Enduring` (16/48) and `Perpetual` (8/56) issue the **same** atomic compare-exchange on the same `u64`, differing only in shift and mask constants -- so the recurrence moves from about 37 seconds to about 20 years without a dependency. **An earlier version of this row added "and measured indistinguishable outside noise", and that clause is withdrawn**: it rested on a single probe run read against a noise floor of 2-6% that seven runs put at 7-61%. Re-measured, the deeper layouts are indistinguishable from `Balanced` at low producer counts, and at high counts ran 1.23-1.30x the default against a same-code control that itself reaches 1.12x -- outside the control, but too close to it to establish an ordering or a cost on this host: a flag to measure locally, not a finding. The figures are in the probe's note rather than restated here. The layout is the caller's choice and the throughput question belongs on the caller's hardware; see the queue-contention section of [DESIGN-NOTES.md](../windows-platform-probes/DESIGN-NOTES.md#d-queue-layout-observations). Which half the bits go to is the trade this decision exposes rather than settles: a 32-bit reservation field, whose count the shipping type caps at `u32::MAX` and whose achievable value capacity caps lower still, against a position whose width sets the recurrence horizon. The bound that matters on the reservation side is how many reservations a caller holds at once -- the lesser of the ring capacity and the field, reachable by one producer alone, since `reserve` takes `&self`. Which of the two a deployment needs is the deployment's question. **An earlier version of this row said the real bound was "however many producers are mid-send", and that is withdrawn as false**: one producer fills `Perpetual`'s 255 in a loop and is then refused, which `one_producer_alone_can_exhaust_the_reservation_field` pins. The correction matters because the false premise made the narrower fields look unreachable, which is the argument for spending bits on the position. `Wide` (64/64 over a `u128`) is offered behind the non-default `dwcas` feature, because it is the one thing here that costs a third-party crate -- the standard library has no 128-bit atomic -- and the whole push path was measured as slower under it as producer count rises in the isolated regime -- near parity at one or two, several times by thirty-two -- while falling inside the same-code control when drained. The probe times the complete push, so that is the layout's effect on that path rather than a measurement of the exchange alone; it buys a guarantee rather than a lifetime argument. **The default stays `Balanced`** so introducing the choice changed no existing caller's behaviour, and its documentation states the defect outright -- that past 2^32 pushes from two or more producers the queue can silently lose an item -- rather than leaving the status quo to look safe by inertia. It states the defect rather than recommending against the layout, per [D-no-client-prescriptions](../windows-platform-probes/DESIGN-NOTES.md#d-no-client-prescriptions): a caller told what the layout does can decide; a caller told what to prefer has been handed our judgement about their deployment. |

crates/windows-waitable-queues/README.md:411

  • This PR adds the same hand-maintained measurement table to the README and the crate rustdoc, while the new documentation rule says a figure should have exactly one home and public prose should point to a committed artifact instead of duplicating it. A future retake can update one surface and leave the other stale. Please make the capture authoritative in one place and have both public surfaces reference that source.
| producers | `slotwise_mpsc` | `reserving_mpsc` | `permit_mpsc` | `baseline_fetch_add` |
|---|---|---|---|---|
| 1 | 6.3 (6.3-7.5) | 5.4 (5.4-6.4) | 7.9 (7.9-8.3) | 2.3 (2.3-2.7) |
| 2 | 50.6 (19.3-59.5) | 31.9 (22.5-35.2) | 44.2 (37.4-45.9) | 12.1 (5.8-14.3) |
| 4 | 91.6 (89.7-99.9) | 37.2 (31.6-41.5) | 31.8 (30.4-32.9) | 13.8 (12.6-17.6) |

crates/windows-waitable-queues/README.md:418

  • The new repository rule says not to restate a proportion over values already shown in the same document. This sentence turns the displayed range into the hand-computed claim "a factor of three"; please leave the range itself as the evidence and remove the derived proportion.
**The ranges are the point, not a footnote.** `slotwise_mpsc` at two producers
spans 19.3 to 59.5 -- a factor of three within one configuration on one host --
and at thirty-two, 131.4 to 268.3. A median quoted without that is an anecdote,

crates/windows-waitable-queues/README.md:449

  • This sentence derives and restates a 1.33x spread from the displayed 181.5-242.3 range. That is the exact hand-computed proportion the new documentation rule says not to duplicate; retain the observed range and omit the derived multiplier.
-- a fourth, separate invocation of the same build gave that row a median of
226.5 over a 181.5-242.3 range, a spread of 1.33x across its five repetitions.

crates/windows-waitable-queues/src/lib.rs:332

  • This duplicates the README's "factor of three" summary from the same displayed endpoints. The new documentation rule explicitly rejects hand-computed proportions over data already present; keep the range as the evidence instead of repeating the ratio in the rustdoc copy.
//! half: `slotwise_mpsc` at two producers spans a factor of three within one
//! configuration on one host.

crates/windows-waitable-queues/src/lib.rs:373

  • This rustdoc copy also derives 1.33x from the immediately displayed 181.5-242.3 range. Please keep the sampled range as the evidence and remove the hand-computed proportion, consistent with the new repository rule.
//! spread -- a fourth, separate invocation of the same build gave that row a
//! median of 226.5 over a 181.5-242.3 range, a spread of 1.33x across its five
//! repetitions. The parenthesised ranges in the table above are the wider
  • Files reviewed: 21/22 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Ten findings, all of them this PR's new documentation rule turned on the PR that
added it. That is the right outcome and most of them are correct.

The measurement table had two hand-maintained homes -- the README and the crate
rustdoc -- which is precisely what the rule forbids, and this branch had already
demonstrated the failure: a retake updated the README and left the rustdoc
carrying the superseded capture for two commits. The rustdoc copy is gone. It now
carries the claims that do not drift (one host's observation, not a ranking; the
ranges matter more than the medians; what an operation is in each row; the host
is a single NUMA node so nothing there speaks to cross-domain behaviour) and
links to the README, which owns the figures and their attribution. The README's
measurement section gained a real heading so the link has a stable anchor.

Six derived proportions removed, each restating data shown beside it:

  "a factor of three"     over 19.3 to 59.5, in three files
  "a spread of 1.33x"     over 181.5-242.3, in two
  "which is 93%"          over 57 of 61 -- inside the paragraph explaining why
                          not to do this

The last one is the one to sit with. The rule's own worked example computed a
ratio over the counts it was citing as a cautionary tale about computing ratios
over counts. Removing it costs nothing: the counts were already there, and the
reader can see 57 of 61 without being told what fraction that is.

Two stale figures were serving as illustrative examples of "a number" in the rule
itself -- both medians from the superseded pre-correction capture this PR removed
from the documentation. Using withdrawn measurements as decoration reintroduces
them without attribution. Replaced with descriptions of the kinds of number.

D-41 said the figures live in the probe's note "rather than restated here" and
then restated them. Removed. Sweeping that claim found it in five more places --
the README twice, the crate rustdoc twice, and ClaimLayout's rustdoc -- all now
stating the qualitative conclusion and leaving the magnitudes to the probe note
that owns them.

D-35 presented pre-correction magnitudes as current, in its index row and in its
section. Both now carry the status adjacent to the claim. The review asked only
about the index row; marking the section too is the same pairing D-17 and D-27
needed, and missing the section half is a mistake this branch has now made three
times.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@MikeGrier

Copy link
Copy Markdown
Owner Author

Response to this round (10 suppressed findings)

Addressed in 9340fcf. This round is the PR's new documentation rule turned on the PR that added it, and most of it lands.

The table had two hand-maintained homes

Changed — the rustdoc copy is gone. This is the finding that matters, and the evidence for it is in this branch's own history: a retake updated the README and left the rustdoc carrying the superseded capture for two commits, which a review had to catch. The rule was written from that experience and then the same PR shipped the duplication intact.

The rustdoc now carries only what does not drift — one host's observation rather than a ranking; the ranges matter more than the medians; what an operation means in each row; the host is a single NUMA node so nothing there speaks to cross-domain behaviour; permit_mpsc is outside the semver promise — and links to the README, which owns the figures and their attribution. The README's measurement section gained a real heading so the link has a stable anchor (it was bold text, so the obvious anchor would not have resolved).

This does not decide the committed-artifact question, which is deliberately still open. It does reduce two hand-maintained copies to one, which is the part of the rule that can be satisfied today.

Six derived proportions, including one inside the rule's own example

All removed.

restated over data shown in
"a factor of three" 19.3 to 59.5 three files
"a spread of 1.33x" 181.5-242.3 two files
"which is 93%" 57 of 61 the paragraph explaining why not to

The last is worth sitting with rather than laughing off. The rule's cautionary example computed a ratio over the counts it was citing as a cautionary tale about computing ratios over counts. Removing it costs nothing — the counts were already there, and a reader can see 57 of 61 without being told what fraction that is.

Stale figures used as decoration

Changed. Two medians from the superseded pre-correction capture were serving as illustrative examples of "a number" inside the rule itself. Using withdrawn measurements as decoration reintroduces them without attribution — they read as current to anyone who does not already know the capture was retired. Replaced with descriptions of the kinds of number.

D-41 restated what it said it did not

Changed, and sweeping it found the same claim in five more places — the README twice, the crate rustdoc twice, and ClaimLayout's rustdoc. All now state the qualitative conclusion and leave the magnitudes to the probe note that owns them.

D-41 literally said "the figures are in the probe's note rather than restated here" with the figures restated in the same sentence.

D-35 presented pre-correction magnitudes as current

Changed in both the index row and the section. You asked about the index row; the section needed it too, and marking only the index would have left a reader who scrolls past the row taking the body as current.

That pairing — index row and section — is the third time on this branch. D-17 and D-27 each needed the same correction after I marked one half and not the other. It is a reliable enough mistake that it belongs in the convention rather than in my attention.


What the round taught

A rule written from experience does not retroactively fix the document that states it. Every one of these ten was in prose that either introduced the rule or sat beside it, written before the rule existed and left unswept when it did. Adding a rule is a contract change, and the blast-radius sweep it obliges includes the text that added it — which is the one place nobody thinks to look, because it is where the thinking just happened.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Copilot was unable to run its full agentic suite in this review.

Pull request overview

Copilot reviewed 21 out of 22 changed files in this pull request and generated 2 comments.

Comment thread crates/windows-platform-probes/src/queue_contention/tests.rs
Comment thread crates/windows-platform-probes/src/queue_contention.rs
Mike Grier and others added 2 commits September 15, 2026 22:41
`Run::spread()` returned `0.0` when a row measured nothing, on the reasoning
that zero is not a plausible spread so it could serve as a sentinel. The report
renders it through `format_scaling`, which rejects only non-finite values, so
that row printed `1.00x`'s more flattering neighbour: **`0.00x`**, the most
reassuring value the column can hold, meaning every repetition agreed exactly --
produced by a shape that never ran.

This is the third time on this branch that a zero sentinel reached a reader as a
plausible number, after `format_ratio` and `format_ratio_bounded` two commits
ago. Fixing those two and leaving this one is the same sibling-blindness the
round before flagged: I corrected the functions the review named and not the
accessor feeding a third call site.

`spread()` now returns `Option<f64>`, which removes the sentinel rather than
guarding it. Every neighbouring accessor -- `scaling`, `scaling_bounds`,
`ratio_bounds` -- already returns `Option` for exactly this situation; `spread`
was the one exception, and the exception is what a renderer got wrong. A type
that cannot express "no measurement" forces every caller to remember a
convention, and one of them will not.

Two tests: the accessor answers `None`, and the renderer marks it `--`. The
second exists because the accessor is not where the damage happened. Verified by
sabotage -- restoring the sentinel behind the `Option` renders `Some(0.0)` and
fails.

Report re-rendered from a release build; measured rows are unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The previous commit edited these two lines through PowerShell and pushed without re-running cargo fmt, so CI's rustfmt job failed on line length. The repository's pre-commit gate requires fmt then clippy whenever a staged file is .rs; I ran the encoding and commit-scope checks and skipped that one, because the change looked like a test edit rather than a code edit. The gate does not make that distinction and is right not to.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved critical and moderate findings, along with documentation corrections, remain before approval.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (7)

DESIGN-NOTES.md:1867

  • This adds a substantial new canonical design principle to Tier 1, but the repository's Tier 1/Tier 2 split keeps current decisions in DESIGN-NOTES.md and historical alternatives and measurement rationale in the root DESIGN-RATIONALE.md (see its opening contract). This section is mostly review history, measurements, and alternatives, yet no matching Tier 2 section is added, so the new design record does not follow the repository's documentation structure. Keep a compact current principle here and move the historical material into DESIGN-RATIONALE.md in the same change.
## <a id="prose-volume-and-error-surface"></a>Prose volume is not the error surface; restatement count is

[Restatement drift](#restatement-drift) explains the mechanism and gives the remedy. This note
records something that section does not: a measurement of **where** the drift actually lives, taken
after PR #90's eighteenth review round, and what follows from it about formal specification.

DESIGN-NOTES.md:1984

  • This is a repository path in a Markdown document, so it should be a relative clickable link rather than inline code. The capture directory exists; linking it lets readers open the artifact directly and follows the repository's Markdown cross-reference convention.
`mutation-sweeps/2026-09-02/` is a dated, committed capture directory: data as an artifact, cited

crates/windows-platform-probes/COMPLETED-CHECKLIST.md:1139

  • This archived M4.5 entry now contradicts the implementation: Run::spread() returns None for an unmeasured row, and the renderer prints --; it no longer returns zero. Because this archive is meant to preserve the completed work accurately, update the text so it does not document the sentinel behavior that this change explicitly removed.
`Run` gained `fastest_nanos_per_op` and `slowest_nanos_per_op`, taken from the ends of the sort that
already existed, plus a `spread()` accessor that returns zero rather than infinity when a shape
failed to run -- the same guard `format_ratio` carries for the same reason. `render_table` publishes
an `ns/op range` column and a `spread` column.

crates/windows-platform-probes/src/queue_contention.rs:345

  • The positivity checks here do not reject non-finite Run values: f64::INFINITY > 0.0, so ratio_bounds can return Some((NaN, NaN)) for an infinite span. format_ratio_bounded then publishes strings such as infx [NaNx-NaNx] instead of the -- marker used for unmeasurable values. Since Run and these helpers are public, reject non-finite medians/spans consistently in this path (and its sibling ratio formatter) and add regression cases.
pub fn ratio_bounds(numerator: Run, denominator: Run) -> Option<(f64, f64)> {
    if numerator.fastest_nanos_per_op <= 0.0
        || numerator.slowest_nanos_per_op <= 0.0
        || denominator.fastest_nanos_per_op <= 0.0
        || denominator.slowest_nanos_per_op <= 0.0
    {
        return None;
    }
    // Widest is the numerator at its worst over the denominator at its best;
    // narrowest is the reverse.
    let low = numerator.fastest_nanos_per_op / denominator.slowest_nanos_per_op;
    let high = numerator.slowest_nanos_per_op / denominator.fastest_nanos_per_op;
    Some((low, high))

crates/windows-waitable-queues/DESIGN-NOTES.md:870

  • The qualification here is contradicted by the still-active D-26 text below: it continues to state “up to 4x faster,” that reserving_mpsc is cheaper at every producer count, and quotes the pre-correction drained values. Those are precisely the magnitudes and causal/ordering claims this PR withdraws; the section needs the same qualified end-to-end wording as D-41/README instead of leaving the old decision text normative.
**That "within noise" rests on a floor this workspace has since measured to be far
wider.** The figure was read against a 2-6% run-to-run spread; seven runs of the
same probe later put the same-configuration spread at 7-61% depending on producer
count, and the probe's own same-code control spans 0.68-1.27x. The figures below
are not retracted -- the direction of `D-26` survived a re-measurement on the
shipping type -- but "agreed within noise" is a weaker statement than it reads as,
and any difference here smaller than that control should not be treated as
established. See

crates/windows-waitable-queues/DESIGN-NOTES.md:923

  • This newly qualified paragraph correctly says the probe cannot isolate or bound the sequence read, but the next paragraph still concludes “the reserving shape's extra read is cheaper than the read it replaces.” That conclusion is an unsupported causal attribution and directly contradicts the limitation just stated; remove or rewrite it as an explicitly historical hypothesis, as D-41 now does.
**The causal mechanism below is a hypothesis this workspace has not established, and the figures in it
predate a correction to the probe's timing window.** Read the whole section as the historical argument
that made `D-26`'s result explicable rather than as a measured finding. What survives is the end-to-end
observation -- `reserving_mpsc` measured faster than `slotwise_mpsc` under contention on the hosts tried
-- and the fact that the difference is a property of the two *protocols* rather than of two
implementations of one. What does not survive is the attribution: the probe times the complete push and
so cannot isolate or bound the sequence read, which is the quantity this explanation rests on. The
padding experiment below is a real measurement and still rejects the false-sharing hypothesis; its
numbers, being pre-correction, should be read as optimistic.

crates/windows-waitable-queues/src/reserving_mpsc.rs:28

  • This caveat is not propagated to the Perpetual rustdoc below: it still says the 2^56 recurrence is “beyond any real deployment.” The horizon is explicitly rate-dependent here, so a faster caller can reach it much sooner; please replace that universal deployment claim with the qualified planning-rate/floor wording used in this section and the README.
//! *sustained* pushing at this crate's disclosed rates, roughly two minutes at
//! two producers. Those rates predate a correction to the probe's timing window,
//! so they are a floor rather than a forecast -- the correction lowers the rate
//! and lengthens the horizon, which is the conservative direction for a hazard;
//! see [`ClaimLayout`]. The wrap alone is not enough -- a producer must also stall
  • Files reviewed: 21/22 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment on lines +1100 to +1104
assert!(
error.is_retryable(),
"the consumer is gone, so this push can never \
succeed: {error}"
);

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Unresolved documentation nits remain across the reviewed files.

Review details

Suppressed comments (9)

DESIGN-NOTES.md:1882

  • This paragraph hard-codes the exact file count (five separate files) even though the new principle says such counts drift and deliberately avoids recording them. Any later documentation or test mention will make this design note stale in the same way it describes; please remove the tally or make it a derived artifact rather than prose.
any of them. The ceiling is the worst: it appears in five separate files.

DESIGN-NOTES.md:1981

  • This paragraph hard-codes the 60%/57-of-61 example in prose even though the new section's stated principle is that measured numbers belong in one attributed artifact. Keeping the figures here creates the same transcription/restatement surface this decision is meant to remove; please move the example to a committed capture or describe it qualitatively and link to that artifact.
proportion that restated two counts **given four words earlier in the same sentence** and got one of
them wrong -- it said "in both cases roughly 60%" where one of the two cases was 57 of 61. The data
was adjacent and the summary of it was false, because prose is not checkable and nobody checks it.

crates/windows-platform-probes/COMPLETED-CHECKLIST.md:1139

  • This archived completion note describes the new Run::spread() contract incorrectly: the implementation returns Option<f64> and the renderer prints -- for an unmeasured row; it does not return zero (or infinity). Please update the historical record so it does not teach the old sentinel behavior.
`Run` gained `fastest_nanos_per_op` and `slowest_nanos_per_op`, taken from the ends of the sort that
already existed, plus a `spread()` accessor that returns zero rather than infinity when a shape
failed to run -- the same guard `format_ratio` carries for the same reason. `render_table` publishes
an `ns/op range` column and a `spread` column.

crates/windows-waitable-queues/DESIGN-NOTES.md:1302

  • The updated status paragraph still overstates the retained D-35 direction: its own table below shows permit_mpsc slower than reserving_mpsc at two producers (1.26x), so “faster where contention exists and slower at one producer” is false if contention means more than one producer. Please describe the crossover as four-or-more producers versus one-or-two, matching the table.
[D-29](#d-29) no current public figure derives from that capture. The direction the section
establishes -- that the permit claim is faster where contention exists and slower at one producer --
survives the correction; the multipliers do not.

crates/windows-waitable-queues/DESIGN-NOTES.md:72

  • The D-35 index row repeats the same inaccurate scope: the retained ratio table shows permit_mpsc is still 1.26x slower at two producers, so the faster result begins at four producers rather than at every producer count above one. Please keep this summary consistent with the corrected paragraph below.
| <a id="d-35"></a>D-35 | **The magnitudes below predate the timing correction and are retained as the record of what the measurement showed, not as current figures.** **Measured: the permit claim is faster than `reserving_mpsc` at high producer counts and slower at one** -- originally recorded as 2.7x and 1.45x respectively, from a capture taken before the probe's timing window was corrected; per [D-29](#d-29) no current public figure derives from that capture. The direction survives the correction; the magnitudes do not. The safer claim is also the faster one everywhere contention exists, which was not the expected result -- it touches *two* shared lines where the shipping shape touches one plus a read, and [D-26](#d-26) had established that the shared line is what collapses. The mechanism is that both of its operations are unconditional read-modify-writes that never retry, where the shipping shape's compare-exchange retries once per lost race; the retries dominate long before the second line does. It is the only shape measured that gets *faster* per push as producers are added (42.8 ns at two to 19.5 at thirty-two) and the only one that stays within 1.5x of a bare contended `fetch_add`. **This decides the shape of the fix but not the fix**: the drained regime's refusal counts differ by orders of magnitude in a way this harness cannot attribute, which SH-15.5.1 exists to settle before SH-15.6 adopts anything. |

crates/windows-waitable-queues/README.md:379

  • This new guidance still inherits the obsolete “in one run” framing from the surrounding bullet: the recurrence exposure is accumulated over the lifetime of one queue, as the earlier section now correctly states. Please make this heading describe a queue lifetime so readers do not treat a long-lived queue as safe merely because no single run crosses the threshold.
  Under its default layout `reserving_mpsc` can lose an item past that volume.

crates/windows-waitable-queues/src/reserving_mpsc.rs:27

  • This says the disclosed rates are a floor, but a rate that was overstated by the timing defect is an upper bound; the resulting wrap horizon is the floor. Please make the subject of “floor” the horizon so callers do not invert the conservative direction.
//! two producers. Those rates predate a correction to the probe's timing window,
//! so they are a floor rather than a forecast -- the correction lowers the rate
//! and lengthens the horizon, which is the conservative direction for a hazard;

crates/windows-waitable-queues/src/slotwise_mpsc.rs:555

  • This sentence is missing its subject: “Why is not established” is ungrammatical and makes the comment harder to read. Please say “The reason is not established.”
        // slower than `reserving_mpsc` under contention despite it. Why is not

crates/windows-waitable-queues/src/slotwise_mpsc.rs:88

  • The same wording mistake appears here: the disclosed rate is not a floor after a correction that lowers it; the time-to-wrap computed from that rate is. Please name the horizon as the floor.
/// which at this crate's disclosed rates is a matter of minutes -- a floor,
/// since those rates predate a timing correction that lowers them: the stalled
  • Files reviewed: 21/22 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Mike Grier and others added 2 commits September 15, 2026 23:12
A row that did not run reports zero, and zero is not an obviously broken
value in any of this report's columns: `0.0` ns/op reads as immeasurably
fast, `0.00x` as a ratio of one, `0.0-0.0` as perfect stability. Three
renderers guarded the sentinel and four did not, so the same row was
refused a ratio and granted a cost.

That asymmetry is the residue of fixing `Run::spread` at the instance
rather than the class: the guard was a convention each renderer restated,
so a renderer could omit it by saying nothing. `Run::is_measured` makes it
a definition every renderer asks, and `render_table` now marks every
measured cell of an unmeasured row rather than only its spread. The
producer count and shape survive, being configuration rather than
measurement.

Also widens the layout table's ratio columns, which allocated 10
characters to a formatter whose ordinary output is 19. A Rust width is a
minimum, so the value was not truncated -- it pushed the next two columns
out of line with their headers, silently, in every report the probe has
emitted. The width is now derived from a named constant that a test holds
against the formatter, and the value columns say `ns/op` rather than `ns`,
which is the unit they carry.

Verified by sabotage: reverting `is_measured` to `true` fails 8 tests,
reverting either scaling guard fails 2, and restoring the old column width
fails with `"10.00x [6.67-15.00]" is 19 characters ... which allows 10`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Every claim-position layout recurs. `Wide` moves the horizon to 2^64
pushes rather than removing it, which the `Wide` rustdoc already said
outright -- "Longer, not unbounded" -- while three other sites still
stated the withdrawn claim in words that shared no keyword with it:

- D-41's index row: "it buys a guarantee rather than a lifetime
  argument", which is exactly what a longer horizon is not.
- `Perpetual`: 20 years "puts the recurrence beyond any real deployment
  rather than merely far away" -- an absolute claim about the *shortest*
  of the deferred horizons, and one a caller pushing an order of
  magnitude faster falsifies in two years.
- `permit_mpsc`: a wider field "moves the recurrence out of reach",
  immediately before claiming the shape "addresses the structure rather
  than the interval" -- which "out of reach" contradicts, since it is an
  interval claim.

The earlier sweep that corrected "unreachable" and "no deployment
reaches" missed all three because it swept the phrasings that had been
written rather than the proposition they encode. Swept the proposition
this time: "Wide/Perpetual is qualitatively different" across both
crates. 4 sites found, 4 corrected; the `Wide` rustdoc and the probe's
horizon table already agreed. The fourth site is the probe report's
"8/56 merely deferring it", which lives in the probes crate and so
landed in the preceding commit to keep the release scope clean.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@MikeGrier

Copy link
Copy Markdown
Owner Author

Self-review round (GPT Sol), ad2491b -> eb807ca

Ran a full review of origin/main...HEAD before asking for another pass. Three findings, all valid, all fixed.

1. A shape that never ran was publishing figures. The did-not-run sentinel is zero, and zero is not an obviously broken value in any of this report's columns: 0.0 ns/op reads as immeasurably fast, 0.00x as a ratio of one, 0.0-0.0 as perfect stability. Three renderers guarded it and four did not, so the same row was refused a ratio and granted a cost.

That asymmetry was the residue of fixing Run::spread at the instance rather than the class -- the guard was a convention each renderer restated, so a renderer could omit it by saying nothing. It is now a definition (Run::is_measured) that every renderer asks, and render_table marks every measured cell of an unmeasured row rather than only its spread. Shape and producer count survive, being configuration rather than measurement.

2. The layout table was misaligned in every report the probe has emitted. The three ratio columns allocated 10 characters to a formatter whose ordinary output is 19. A Rust width is a minimum, so the value was not truncated -- it pushed the next two columns out of line with their headers, silently. The width is now derived from a named constant held against the formatter by a test, and the value columns say ns/op rather than ns, which is the unit they carry.

3. Three sites still called a finite recurrence horizon an absolute one. Wide's own rustdoc already said "Longer, not unbounded", while D-41's index row said it "buys a guarantee rather than a lifetime argument", Perpetual said 20 years puts recurrence "beyond any real deployment", and permit_mpsc said a wider field "moves the recurrence out of reach" -- immediately before claiming the shape "addresses the structure rather than the interval", which that contradicts.

The earlier sweep that corrected "unreachable" and "no deployment reaches" missed all three because it swept the phrasings that had been written rather than the proposition they encode. Swept the proposition this time; the review reported two sites, the sweep found four.

Verification

Every guard was proven load-bearing by re-injecting the defect:

Sabotage Result
is_measured -> true 8 tests fail
either format_scaling* zero guard removed 2 tests fail
RATIO_COLUMN_WIDTH back to 10 fails with "10.00x [6.67-15.00]" is 19 characters ... which allows 10

Gate: cargo fmt, clippy --all-targets (both crates, --all-features on the queue crate), 294 probe tests + 345 queue tests + doctests, cargo doc -D warnings, encoding check 646 files clean.

Split into fix(probes) and docs(queues) so the queue crate takes no unearned version bump.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

An unresolved moderate spread() validation issue and two documentation nits remain.

Review details

Suppressed comments (4)

Previously missed (1) — in code that hasn't changed since the last review.

crates/windows-platform-probes/src/queue_contention.rs:246

  • The > 0.0 guard does not reject non-finite public span values: NaN compares false, while an infinite fastest/slowest value can produce Some(NaN) or Some(inf). Since Run and these fields are public, spread() can return a numeric-looking result for an unmeasurable row despite its documented None contract, and the direct API is inconsistent with the finite checks in the renderers. Require both span endpoints to be finite and positive before dividing, and add a NaN/infinity regression case.

This issue also appears on line 355 of the same file.

DESIGN-NOTES.md:1985

  • This new design-note section names the committed capture directory as inline code, so readers cannot Ctrl+Click to inspect the evidence. Repository Markdown requires paths whose purpose is to direct readers to another file or artifact to be relative clickable links; please link this directory (or its README) here.
`mutation-sweeps/2026-09-02/` is a dated, committed capture directory: data as an artifact, cited
rather than retyped. `windows-platform-probes`, which produces the most-cited numbers in the

DESIGN-NOTES.md:2044

  • This says a formal-methods survey is queued in the root CHECKLIST.md, but that checklist has no item for a formal-methods/TLA+/loom/specification survey. As written, the note points readers to work that does not exist; please add the actual checklist item (and its plan entry if required) or remove/reword this claim.
rather than an oversight. A formal-methods survey is queued separately in the root
[CHECKLIST.md](CHECKLIST.md) and bears on the same question. If the table-versus-constants test or a

crates/windows-platform-probes/src/queue_contention.rs:358

  • These guards only reject non-positive values; NaN bypasses every comparison and infinity is accepted, so a public Run with a non-finite span makes ratio_bounds return Some containing NaN/inf. format_ratio_bounded then publishes that as a bounded ratio, unlike format_scaling_bounded which explicitly rejects non-finite bounds. Reject non-finite span endpoints here and cover NaN/infinity in the API/formatter tests.
    if numerator.fastest_nanos_per_op <= 0.0
        || numerator.slowest_nanos_per_op <= 0.0
        || denominator.fastest_nanos_per_op <= 0.0
        || denominator.slowest_nanos_per_op <= 0.0
  • Files reviewed: 21/22 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

The archived M4.5 entry described `spread()` as returning "zero rather
than infinity when a shape failed to run -- the same guard `format_ratio`
carries for the same reason". Both halves are false as shipped, and the
sentence is the discredited behaviour presented as the delivered feature.

Ordering the branch's own commits: `fecd352` added `spread()` returning
`0.0`; `bd82bf9` archived M4.5 with that description; `28978ba` then
established that `0.0` renders as `0.00x`, reads as perfect stability, and
was itself the defect -- changing `spread()` to return `Option`. `format_ratio`
no longer carries a zero-returning guard either; it routes through
`Run::is_measured`. The archive was not revisited, so it shipped teaching
that returning zero was the fix.

That is premise-removed/conclusion-kept, arising wholly inside this branch,
in the one document written to be read later for *why* a thing was done.
The intermediate state never existed on main and never will, so correcting
it before merge records the only state that ships rather than rewriting
landed history.

The archive is append-only, so the correction is appended rather than
substituted: the original wording is named in the note, because it did not
merely go stale, it inverted the lesson.

Swept the proposition across the crate and the root design notes before
committing: one site stated it, this one. The code, the tests and the
`spread()` rustdoc all already said `None`.

Nothing detected the drift, which is what `M2.13` (lint the completed
checklist archive mechanically in CI) is already queued to fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@MikeGrier

Copy link
Copy Markdown
Owner Author

Review round (Claude Opus, fresh model), eb807ca -> eee03aa

Deliberately used a different model from the previous round -- same-model review tends to re-find the same things, and the point was fresh eyes on the code that round had just changed.

It cleared the areas that round touched (is_measured, the render_table rewrite, RATIO_COLUMN_WIDTH and the non-vacuity of its test, measured_span, median_run, the ratio/scaling bound arithmetic, barrier participant counts, the ClaimLayout ceilings and horizons, feature gating) and found one genuine issue.

The M4.5 archive entry inverted its own lesson. It described spread() as returning "zero rather than infinity when a shape failed to run -- the same guard format_ratio carries for the same reason". As shipped, spread() returns Option and format_ratio routes through Run::is_measured; neither returns zero.

The provenance is entirely inside this branch: fecd352 added spread() -> 0.0, bd82bf9 archived M4.5 describing it, and 28978ba then established that 0.0 renders as 0.00x, reads as perfect stability, and was itself the defect. The archive was never revisited.

So this is not a stale figure -- it is the discredited behaviour presented as the delivered feature, in the one document written to be read later for why something was done. A future contributor consulting it would have learned the opposite of what the branch concluded.

On the append-only question: the intermediate state never existed on main and never will, so correcting before merge records the only state that ships rather than rewriting landed history. The correction is appended rather than substituted, and names the original wording, because it did not merely go stale -- it inverted the lesson.

Swept the proposition across the crate and the root design notes first: one site stated it, this one. Code, tests, and the spread() rustdoc all already said None.

The systemic point

This is the third instance in this PR of premise removed, conclusion kept, and the second where a correction was applied to a reported instance while a restatement elsewhere survived. Nothing detected it -- there is no oracle over the archive, only a reader.

M2.13 ("Lint the completed-checklist archive mechanically in CI") is already queued against this crate and is the right home for the mechanical answer. Flagging it here so the connection is on the record rather than rediscovered.

Docs-only; no .rs changed. Encoding check clean (646 files), archive verified 7-bit ASCII.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Two moderate findings and two documentation nits remain unresolved.

Review details

Suppressed comments (4)

DESIGN-NOTES.md:2009

  • This section explicitly records a new repository-wide principle, but the matching Tier 2 rationale is missing. The root DESIGN-RATIONALE.md identifies itself as the rationale for decisions in this file, and the repository's tiering convention requires a new decision to be recorded in both tiers in the same change; please add the corresponding rationale or move this material out of the canonical decision notes.
**The mechanism is undecided and no work is scheduled here.** The reader-experience trade is real --
a figure behind a link is a figure most readers will not look at -- and it has not been settled.
Recorded as a principle so the next person choosing where to paste a number has the argument in front
of them, not as a queued change. Per "design notes are not a work queue", the absence of a checklist
item is deliberate.

DESIGN-NOTES.md:1882

  • The new section says exact counts, including file counts, are deliberately computed rather than quoted, but this sentence still hard-codes that the ceiling appears in five files. That is the same drift-prone restatement this section is documenting; please remove the number or keep the census in a single authoritative artifact.
any of them. The ceiling is the worst: it appears in five separate files.

crates/windows-platform-probes/src/queue_contention.rs:359

  • Run and its fields are public, so a row with a positive median but a NaN or infinite repetition bound can reach this function. The <= 0.0 checks do not reject NaN; ratio_bounds then returns Some((NaN, ...)) and format_ratio_bounded publishes a misleading ... [NaN-NaN] interval instead of the -- marker used for unmeasured data. Validate the span values as finite (and reject malformed spans) before rendering the bounded ratio.
    if numerator.fastest_nanos_per_op <= 0.0
        || numerator.slowest_nanos_per_op <= 0.0
        || denominator.fastest_nanos_per_op <= 0.0
        || denominator.slowest_nanos_per_op <= 0.0
    {

crates/windows-waitable-queues/src/reserving_mpsc.rs:604

  • This sentence is incomplete: "about two" does not state the unit, so the public documentation does not explain the resulting horizon. Since the preceding value is 20 years and the example is a tenfold rate increase, this should say "about two years."
/// it scales with the caller's rate: a deployment pushing an order of magnitude
/// faster reaches it in about two.
  • Files reviewed: 21/22 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Mike Grier and others added 2 commits September 16, 2026 02:37
…ts cells

Two renderer defects, both cases of a guard that stops one step short of
where the value is actually used.

`layouts_measured` asked whether a row was *present*, not whether it ran.
A row can be present and carry the did-not-run sentinel, so the report
could state "4 apportionments ... measured" directly above a table in
which `render_table` marked one of them `--` in every measured cell. The
count is now `Observation::count_measured`, which asks `Run::is_measured`
and is testable, rather than a `find(..).is_some()` in the binary that no
test could reach.

`RATIO_COLUMN_WIDTH` was treated as a bound when it is only a floor. The
interval endpoints `format_ratio_bounded` prints come from measured spans,
so the cell's width is a function of data: a slow repetition against a
fast one renders `10.00x [6.67-1500.00]`, 21 characters, which a width of
20 does not truncate -- it pushes the next two columns out of line with
their headers, silently. Outliers of that size are ordinary on a loaded or
virtualized host, and surviving them is why `median_run` takes a median at
all. The width is now derived per table by `ratio_column_width` from the
cells it must hold, with the constant as a floor so a narrow table still
looks right. That requires rendering every cell before emitting the
header, which is the only ordering that can get it right.

The previous test asserted `cell.len() <= RATIO_COLUMN_WIDTH` and passed
only because its fixtures were narrow -- it pinned an invariant that was
never available. It now pins the derivation, and carries an assertion that
the overrunning fixture still overruns, so the case cannot stop being
exercised without failing.

Verified by sabotage: reverting `count_measured` to `.is_some()` and
`ratio_column_width` to the bare constant fails exactly the two tests
written for them, and nothing else.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Third sweep of the same proposition, and the third to find sites the
previous one missed -- because each swept the phrasings already written
rather than the claim they encode. These three share no keyword with
"unreachable" or "no deployment reaches", which is what the earlier
sweeps grepped for:

- The probe's own horizon table gives 8/56 twenty years and 64/64 5,039
  at the same rate, while the paragraph above it said 8/56 "reaches the
  same practical headroom a 128-bit word gives". They differ by a factor
  of 250.
- The same section called 12/52 "the first row that is not" reachable.
  The table gives it 202 days at the conservative floor, which a
  long-lived process reaches comfortably.
- `Balanced`'s rustdoc said `Wide` moves the recurrence to 2^64 pushes
  "rather than to a horizon in years", contradicting `Wide`'s own
  rustdoc twenty lines below, which says 2^64 is about 5,000 years and
  calls it "Longer, not unbounded".

Every layout recurs. What changes down the column is how long it takes
and at what rate, so the prose now says that and leaves the durations to
the table that computes them.

Worth noting where these survived: the table is correct and always was.
It was the prose around it drawing conclusions the table contradicts --
the argument for a figure having one home, made against itself.

Swept across both crates: 3 sites found, 3 corrected. The remaining
"unreachable" hits are a different proposition (a capacity ceiling of
2^31 slots, which is tens of gigabytes) or describe prior art's claims
rather than ours, and are left alone.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@MikeGrier

Copy link
Copy Markdown
Owner Author

Review round (GPT Sol), eee03aa -> 0510b92

Three findings, all valid, all fixed. Two were guards that stop one step short of where the value is used.

1. A present row was counted as a measured one. layouts_measured asked whether a row existed, not whether it ran. A row can be present and carry the did-not-run sentinel, so the report could state "4 apportionments ... measured" directly above a table where render_table marked one of them -- in every measured cell. The count is now Observation::count_measured, which asks Run::is_measured -- and, being in the library rather than the binary, is reachable by a test at all.

This is the same conversion that fixed the other renderers last round, applied one call site short of completion. The renderers were swept; a sentence counting them was not.

2. RATIO_COLUMN_WIDTH was treated as a bound when it is only a floor. The interval endpoints format_ratio_bounded prints come from measured spans, so the cell's width is a function of data and has no compile-time bound. A slow repetition against a fast one renders 10.00x [6.67-1500.00] -- 21 characters, which a width of 20 does not truncate but silently pushes the next two columns out of line. Outliers that size are ordinary on a loaded or virtualized host, and surviving them is precisely why median_run takes a median.

The width is now derived per table by ratio_column_width from the cells it must hold, with the constant demoted to an explicit floor. That requires rendering every cell before emitting the header, which is the only ordering that can be correct.

Worth being plain about this one: the test I added last round to guard this was itself the weaker-than-its-name pattern. It asserted cell.len() <= RATIO_COLUMN_WIDTH and passed only because its fixtures happened to be narrow -- pinning an invariant that was never available. It now pins the derivation, and asserts that the overrunning fixture still overruns, so the case cannot quietly stop being exercised.

3. Three more sites stating a finite horizon as an absolute one. This is the third sweep of this proposition and the third to find sites the previous one missed, for the same reason each time: the sweep greps the phrasings already written rather than the claim they encode. These three share no keyword with "unreachable" or "no deployment reaches".

  • The probe's horizon table gives 8/56 twenty years and 64/64 5,039 at the same rate; the paragraph above it called them "the same practical headroom". A factor of 250.
  • The same section called 12/52 "the first row that is not" reachable. The table gives it 202 days.
  • Balanced's rustdoc said Wide moves recurrence to 2^64 "rather than to a horizon in years" -- contradicting Wide's own rustdoc twenty lines below.

The table was correct throughout. It was the prose around it drawing conclusions the table contradicts -- which is the argument for a figure having one home, made against itself.

Verification

Sabotage: reverting count_measured to .is_some() and ratio_column_width to the bare constant fails exactly the two tests written for them, and nothing else.

Gate: cargo fmt, clippy --all-targets on both crates (--all-features on the queue crate), 296 probe tests + 345 queue tests + doctests, cargo doc -D warnings, encoding check 646 files clean, design notes verified 7-bit ASCII.

Split fix(probes) / docs so the queue crate takes no unearned bump.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Public probe helpers need non-finite span validation, and one documentation cross-reference remains unresolved.

Review details

Suppressed comments (3)

DESIGN-NOTES.md:1984

  • This new reference points readers at a repository capture directory but leaves it as inline code, so it is not navigable under the repository's Markdown cross-reference convention. Link it to the directory's README (or to the specific capture) so the stated artifact can be opened directly.
`mutation-sweeps/2026-09-02/` is a dated, committed capture directory: data as an artifact, cited

crates/windows-platform-probes/src/queue_contention.rs:243

  • Run and all of its timing fields are public, so callers can construct a row with a non-finite span. When slowest_nanos_per_op is NaN or infinity, this > 0.0 check still passes if the fastest value is positive, and spread() returns Some(NaN)/Some(inf) instead of the documented absence of a measurable spread. That value can then leak into public callers; require both span endpoints to be finite and positive before returning Some.
        if self.fastest_nanos_per_op > 0.0 {
            Some(self.slowest_nanos_per_op / self.fastest_nanos_per_op)

crates/windows-platform-probes/src/queue_contention.rs:381

  • The four <= 0.0 checks do not reject NaN, because every comparison with NaN is false. Since Run is public, a caller can pass a non-finite span and make ratio_bounds return Some((NaN, NaN)); format_ratio_bounded then renders NaNx [NaN-NaN] rather than --, contradicting the renderer's non-finite-value handling. Reject non-finite endpoints here as well as non-positive ones.
    if numerator.fastest_nanos_per_op <= 0.0
        || numerator.slowest_nanos_per_op <= 0.0
        || denominator.fastest_nanos_per_op <= 0.0
        || denominator.slowest_nanos_per_op <= 0.0
  • Files reviewed: 21/22 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants