test(bpsk): the #1363 gate arms, their controls, and the estimator that was wrong - #1430
Merged
Merged
Conversation
…at was wrong Test-only; no production code changes. `mod carrier_dip_tiebreak` gains the (lock x dominance) 2x2, the candidate gate arms with matched-duty controls, off-band cells (pure Doppler and AWGN down to #821's sigma 0.9), and two new default-run pins. FINDINGS, posted to #1363: * `|g_cur| < |g_next|` — that issue's own predicate — is RETIRED: fires 3.9%/4.9% where the penalty lives, 48%/84% where it does not, and costs frames in every cell. * The mechanism in the band where frames are lost is a SIGN-INVERTED effective ISI with an intact DC term (delayed-dominant == the sub-dominant echo is a pre-echo), not the deep-null tie-break, which is a different regime one bin down. * `sign_dd` recovers the fade gap (32/20/15 vs shipped 45/26/21) and costs 37 of 96 frames at sigma 0.9 through 7.7% noise-driven misfire — visible ONLY because the off-band cells were added. * "beta estimation is refuted by the mechanism" is WITHDRAWN: with exact taps, genie complex-beta is the best arm in every cell including -3.3 dB AWGN (25 vs 46). THE INSTRUMENT WAS WRONG FIRST. The original correlation tap estimator has 1/sqrt(41) ~ 0.16 of self-noise: on a CLEAN frame with no channel, no noise and genie symbols it put Re(g_next/g_cur) at p05 0.043 / p50 0.285 / p95 0.532 against a truth of 0.308, and fired the sign predicate 4.3% of the time against least-squares' 0.0%. The "genie" arms were genie SYMBOLS through a noisy ESTIMATOR, and a doc comment calling one of them "a CEILING" was backwards — it was a floor. Least-squares is now the default; the correlation estimator is kept, renamed and documented as the defective control, because the comparison between them is itself the finding. A MISLABELLING CAUGHT WHILE LANDING THIS: after flipping the default the banner still printed `estimator = correlation` while running least-squares, because it read a different env var than the selector. A label that can disagree with the instrument it names is the defect this probe exists to catch. Both now read one switch, verified in both positions. The pin that makes the arms mean anything is `the_variable_canceller_reproduces_the_shipped_one`: the per-symbol complex-beta canceller must BE `cancel_crossfade_isi` at beta = 1/3, or every arm would be measured against a re-implementation instead of the product. Side finding resolved: the clean-frame beta of 0.308 against the shipped 1/3 is the exact DISCRETE composite at n=32; 1/3 is the continuous integral. Same shape as the 8PSK crossfade fix. Residual ISI ~0.027/symbol, no action on its own. Limits: every number is bad bytes over 200 payload bytes of a 255-byte wire frame, no scrambler, RS never run — a lower bound for all arms alike and NOT a decode rate. The engine-level coded A/B is #1428's step 1. Refactors: CAP-12 Verification-objective: a probe's reported instrument must be the instrument it ran, and an alternative transform must be measured against the shipped one rather than a re-implementation of it Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0188ATCj6DZ9aRVQ2vSirua6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Apparatus for #1363. Test-only; no production code changes. It lands the measurements behind the
last three comments on that issue so the numbers stay reproducible, and it is what produced #1428
(the follow-up task) and #1429 (a live production defect).
mod carrier_dip_tiebreakgains the (lock × dominance) 2×2, the candidate gate arms withmatched-duty controls, off-band cells (pure Doppler and AWGN down to #821's σ = 0.9), a
least-squares tap estimator, and two new default-run pins.
What it established
|g_cur| < |g_next|fires 3.9 % / 4.9 % where thepenalty lives and 48 % / 84 % where it does not, and costs frames in every cell — worse than
the shipped arm, not merely useless.
DC term — delayed-ray-dominant is identical to "the sub-dominant echo is a pre-echo". The
deep-null tie-break is a different regime, one bin down.
sign_ddrecovers the fade gap (32/20/15 frames lost at 8/12/16 dB against the shipped arm's45/26/21) and costs 37 of 96 frames at σ = 0.9, through 7.7 % noise-driven misfire against the
genie's 0.0 %. Visible only because the off-band cells exist; the in-band table could not see it.
the best arm in every cell including −3.3 dB AWGN (25 against 46). That 2026-09-13 note refuted a
deep-null statement.
The instrument was wrong before any of it
The original correlation tap estimator has 1/√41 ≈ 0.16 of relative self-noise. On a clean frame
with no channel, no noise and genie symbols it put
Re(g_next/g_cur)at p05 0.043 / p50 0.285 /p95 0.532 against a truth of 0.308, and fired the sign predicate 4.3 % of the time against
least-squares' 0.0 %.
So the "genie" arms were genie symbols through a noisy estimator, and my doc comment calling one
"a CEILING, not an achievable receiver" was backwards — with that estimator it was a floor.
Least-squares is now the default. The correlation estimator is kept, renamed
estimate_taps_correlationand documented with its measured self-noise, because the comparisonbetween them is the finding.
Two defects found while landing it
env var, so correlation ran unless you asked otherwise. Flipped.
estimator = correlationwhile executing least-squares, because the label read a different envvar than the selector. A label that can disagree with the instrument it names is exactly the
defect this probe exists to catch. Both now read one switch, verified in both positions.
The pins are what make the tables trustworthy
Four run in the default suite:
the_composed_arm_matches_the_shipped_demodulator— byte identity againstbpsk_demodulatethe_same_seed_reproduces_the_same_fading_realisationthe_ray_split_agrees_with_the_envelope— sabotage-verifiedthe_variable_canceller_reproduces_the_shipped_one(new) — the per-symbol complex-β cancellermust be
cancel_crossfade_isiat β = 1/3 to 1e-5, or every arm below would be measured against are-implementation rather than the product
Side finding, resolved
The clean-frame β of 0.308 against the shipped
CROSSFADE_ISI_BETA = 1/3is the exact discretecomposite at n = 32 (
g_c1.0400,g_n0.3200). 1/3 is the continuous integral. Same shape as the8PSK crossfade fix, where β is computed from the window rather than assumed. Residual ISI
~0.027/symbol — no action on its own, but if a β path ever ships, derive it from the window.
Stated limits
Every number is bad bytes over the 200 payload bytes of a 255-byte wire frame, no scrambler, RS
never actually run — a lower bound for all arms alike and not a decode rate. The engine-level
coded A/B is #1428's step 1, and is the cheapest thing that could kill the whole direction.
Test results
All 13 steps
ok. 2578 tests againstmain's 2577 — the one new pin.Refactors: CAP-12
Verification-objective: a probe's reported instrument must be the instrument it ran, and an
alternative transform must be measured against the shipped one rather than a re-implementation
Review: none — this lands apparatus whose findings and write-ups were each reviewed before the
corresponding issue comments were posted; the design verdict it produced is recorded on #1428.
🤖 Generated with Claude Code
https://claude.ai/code/session_0188ATCj6DZ9aRVQ2vSirua6