spec
type: bug
depends on: #340 (same layer, different mechanism — that one is the window ceiling, this one survives fixing it)
problem statement
Round-trip latency for a fixed path on this stack varies by exactly one period between client starts, with no configuration change of any kind. Measured on the rig 2026-08-18 (work/rig/rig-243-343-results.md, PR #345), jack_iodelay on an unchanged leg:
4262.064 frames
5286.064 ← +1024.000
5286.063
5286.064
The fractional part survives the jump untouched, which identifies it as an integer number of periods added in software rather than anything analogue. It is per client, not per graph: at one point jack_iodelay measured its own clients at +1024 while ac-daemon's workers, minutes apart on the same machine, sat at the unshifted value.
Why this layer cannot see it
TauConditions (shared/calibration.rs:128-138) keys on device, backend, sample rate, period size, output port and input port. Two τ readings a period apart share all six. Nothing changed about the configuration, so there is no mismatch for the refuse-on-mismatch logic to catch, and #340's fix does not help: a measure_tau that refuses a pinned peak and admits a 50 ms round trip will still happily store a value that is 10.67 ms wrong at 96 kHz.
#281's premise — "τ is a property of (device, backend, sample rate, period size, port pair)" — is not quite true here. It is also a property of which client measured it, and when.
Within-run consistency proves nothing. Each state is internally stable to 0.001 frames. A measure_tau that sampled its own peak a hundred times in one worker would get the same answer every time and still be a period out.
acceptance criteria
stretch
out of scope
- Fixing PipeWire. The instrument has to be correct on the stack it runs on.
transfer_stream, which is immune and shows why: both legs live in one client for one session, so an added period is common-mode and cancels. It held 378 samples across three sessions and 378/378/379/379/379 across five more while this was happening. Any τ scheme that composes two separately-measured absolutes inherits the problem; one that measures a difference within a single client does not — worth weighing before more is built on the absolute.
files likely affected
ac-rs/crates/ac-daemon/src/handlers/calibrate.rs — measure_tau
ac-rs/crates/ac-core/src/shared/calibration.rs — the stored entry, if corroboration count joins it
needs architect review yes — it questions whether τ should be an absolute at all, which is #281's shape.
estimated complexity medium
Found while running #243. Related: #276 (settled decision 3 rests on the same false premise), #340.
spec
type: bug
depends on: #340 (same layer, different mechanism — that one is the window ceiling, this one survives fixing it)
problem statement
Round-trip latency for a fixed path on this stack varies by exactly one period between client starts, with no configuration change of any kind. Measured on the rig 2026-08-18 (
work/rig/rig-243-343-results.md, PR #345),jack_iodelayon an unchanged leg:The fractional part survives the jump untouched, which identifies it as an integer number of periods added in software rather than anything analogue. It is per client, not per graph: at one point
jack_iodelaymeasured its own clients at +1024 whileac-daemon's workers, minutes apart on the same machine, sat at the unshifted value.Why this layer cannot see it
TauConditions(shared/calibration.rs:128-138) keys on device, backend, sample rate, period size, output port and input port. Two τ readings a period apart share all six. Nothing changed about the configuration, so there is no mismatch for the refuse-on-mismatch logic to catch, and #340's fix does not help: ameasure_tauthat refuses a pinned peak and admits a 50 ms round trip will still happily store a value that is 10.67 ms wrong at 96 kHz.#281's premise — "τ is a property of (device, backend, sample rate, period size, port pair)" — is not quite true here. It is also a property of which client measured it, and when.
Within-run consistency proves nothing. Each state is internally stable to 0.001 frames. A
measure_tauthat sampled its own peak a hundred times in one worker would get the same answer every time and still be a period out.acceptance criteria
period_sizesamples is reported as this — a graph-buffering shift — and not as noise or as hardware drift. A disagreement that is not a multiple of the period is a different fault and should say so.period_sizeapart are refused, with the period named in the message. A test that only checks "readings differ" would pass on noise and miss the point.ac calibrateprints says which route produced τ and whether it was corroborated, per Interface latency (τ) captured duringac calibrate, with scoped validity and history #281's existing requirement that a reader a year later can tell.stretch
out of scope
transfer_stream, which is immune and shows why: both legs live in one client for one session, so an added period is common-mode and cancels. It held 378 samples across three sessions and 378/378/379/379/379 across five more while this was happening. Any τ scheme that composes two separately-measured absolutes inherits the problem; one that measures a difference within a single client does not — worth weighing before more is built on the absolute.files likely affected
ac-rs/crates/ac-daemon/src/handlers/calibrate.rs—measure_tauac-rs/crates/ac-core/src/shared/calibration.rs— the stored entry, if corroboration count joins itneeds architect review yes — it questions whether τ should be an absolute at all, which is #281's shape.
estimated complexity medium
Found while running #243. Related: #276 (settled decision 3 rests on the same false premise), #340.