fix(android): the phase reporter actually sends the v2 circular statistic
ci / rust-arm64 (push) Successful in 2m45s
ci / web (push) Successful in 1m15s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 11s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Successful in 11s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 12s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 12s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 11s
ci / docs-site (push) Successful in 1m29s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 18s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Successful in 37s
docker / builders-arm64cross (push) Successful in 18s
android / android (push) Successful in 6m17s
ci / rust (push) Successful in 9m44s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Canceled after 12m57s
docker / deploy-docs (push) Canceled after 0s

The v2 client edit missed its anchor against rustfmt's reshaping and the
reporter kept sending the v1 median — caught by the arm64 build the moment
the tuple signature landed. Sends (circular mean, coherence) now.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-31 10:58:19 +02:00
co-authored by Claude Fable 5
parent 1d31e4c565
commit fe552a50bb
@@ -380,11 +380,12 @@ pub(super) fn run_async(
if p.pump(&codec, clock, &tracker, &stats, now_monotonic_ns()) {
rendered += 1;
}
// The 1 Hz window flush doubles as the phase-lock report tick: the measured latch
// p50 is the arrival-lead error signal the host's capture controller drives toward
// its target (design/phase-locked-capture.md §6). Timestamps convert
// monotonic→realtime→host here — the skew offset lives only client-side.
if let (Some(latch_p50_ns), Some(c)) = (p.flush_log(&meter, clock), clock) {
// The 1 Hz window flush doubles as the phase-lock report tick: the CIRCULAR
// (vector-mean) latch phase + coherence are the host capture controller's v2 error
// signal (design/phase-locked-capture.md §6; a median is immovable under jitter).
// Timestamps convert monotonic→realtime→host — the skew offset lives client-side.
if let (Some((circ_latch_ns, coherence)), Some(c)) = (p.flush_log(&meter, clock), clock)
{
let period = c.panel_period_ns().max(c.period_ns());
if period > 0 {
if let Some(t) = c.next_target(now_monotonic_ns(), 0) {
@@ -398,7 +399,8 @@ pub(super) fn run_async(
latch_host_ns,
period.clamp(0, u32::MAX as i64) as u32,
1_000_000, // skew residual + latch jitter — conservative 1 ms
latch_p50_ns.min(u32::MAX as u64) as u32,
circ_latch_ns.min(u32::MAX as u64) as u32,
coherence,
);
}
}