Skip to content

EPIC: make τ trustworthy — every consumer of an absolute latency can be one quantum wrong, undetectably #475

Description

@mkovero

why these are one epic

Nine open issues share one physical mechanism and one failure signature, and fixing them singly is how #363 happened: #347's guard shipped, looked correct, and manufactured confidence.

The mechanism. Latency on this stack moves in discrete quanta, and the quantum is invisible to the key meant to detect change:

TauConditions keys on device, backend, sample rate, period size and the port pair. Two readings a quantum apart share all six, so #281's refuse-on-mismatch design has nothing to refuse on.

The signature. Every issue below produces a number that is stable, repeatable, physically plausible, and wrong. None looks like a bug in the output. That is what makes them one problem rather than nine.

The scale. One period at 1024 / 96 kHz is 10.67 ms — 3.66 m of apparent path, larger than most geometry it would be used to measure. At period 256 it is 0.91 m. One SYT step is 5.7 cm.

measurements this epic rests on

fact provenance source
Round trip jumps exactly one period between client starts, per client, no config change measured #347, 2026-08-18
42 of 97 calibrate runs stored a value one period short — every one printed 2 readings agree measured #363, 2026-08-22, 96 kHz / 1024
24 plot_ir captures at a fixed mic position split into two clusters 1023 samples apart, each stable to ±1.5 samples measured #359, 2026-08-22
τ re-picks by a multiple of 16 samples per device enumeration, every condition field matching measured #461, pupu 2026-09-15/16
calibrate (argmax) and ir_stats (onset) no longer cancel: −0.093 m on a zero-path fake measured #351
A power cycle changes analog gain staging while ALSA readback reports the baseline (+6 dB, and +3 dB again on 2026-09-16) measured #466, docs/rigs/pupu.md

A constraint on all of it: the PipeWire mechanism behind #363 and #359 was removed from the rig on 2026-08-23, and no rig in reach reproduces the sticky one-period state today — 65 runs / 130 client lifetimes afterwards showed a single value, and pupu read 1711 on every reading on 2026-09-16. Operator, 2026-08-24: "it is very much to be expected that latency can jump… testing / awareness needs to be global enough to take this into account."

So guards written here must be verifiable without the fault present — by construction, or by synthetic injection — or the issue must say plainly that its acceptance is deferred until hardware exhibits it again. A green unit test on a FakeEngine proves nothing about a sticky state.

what is already solved, so it is not re-litigated

members

issue what it covers routing
#346 The arrival rule itself — argmax |h| reads late on a multi-way DUT; #460 made its causal bound reachable for the first time ready-to-implement
#347 The two-reading corroboration mechanism for calibrate (correct mechanism; its independence assumption is what fails) ready-to-implement
#350 TAU_MIN_HALF_WINDOW_S / TAU_EDGE_MARGIN_FRAC are assumed, not derived against a real noise floor requires-rig
#351 calibrate picks with argmax, ir_stats with onset — they no longer cancel in arrival − τ needs-design
#359 plot_ir's arrival inherits the jump with no corroboration; #347 guards only calibrate needs-design
#363 agreement_count measures how long the state persisted, not whether the value is right needs-design
#461 Stored τ re-picks per enumeration, undetectably requires-rig
#466 Stored calibration (τ and level) used across events its key cannot see; state unknown rather than stale
#467 The capture path itself can start one period early (ring clear/enable race)

sequencing

#363 ─→ #347        (what "corroborated" may claim, before the mechanism is changed)
#363 ─→ #359        (same answer, applied to plot_ir's arrival)
#351 ─→ #346        (two consumers sharing a rule, before tuning either)
#461 ─→ #466        (the measured staleness, then the general per-session check)
#350                (independent; needs a rig session, not a decision)
#467                (independent; alignment, not trust — included because its
                     failure is indistinguishable from a one-period τ error)

definition of done

  • No consumer of τ composes two separately-measured absolutes without either corroboration independent of the failure mode or an explicit uncorroborated state in the output and in the stored record.
  • The word corroborated (and agreement_count) either earns its meaning or is replaced — calibrate stores a τ one JACK period short and calls it corroborated — 42 of 97 rig runs, every one labelled "2 readings agree" #363's 42/97 evidence is the bar it must clear.
  • plot_ir's arrival carries the same protection as calibrate's τ, or states that it does not.
  • calibrate and ir_stats share a picking rule, or their non-cancellation is measured and recorded rather than left to cancel by luck.
  • Stored calibration reports unknown rather than a stale value across events the condition key cannot see.
  • Each guard has a test that can fail without a rig that reproduces the fault, or the issue records why it cannot.

deliberately not included

No "settled decisions" section. #276 carried one, and two of its decisions had to be struck through when hardware contradicted them — decision 3 survived in the body for a month after a rig comment had already falsified it, under a heading saying not to relitigate. This epic carries measurements with provenance and nothing that outranks a later measurement.

Out of scope: room-acoustic parameters; the internals of #346's estimator; the metre, settled by #391.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    epicContains sub-issuesmeasurement-accuracyH1 estimator / THD floor / windowing / calibration correctnesssoftwareac Python/Rust codebasetier-1ac-core/measurement/ — QA runs the standards check

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions