tx.report coverage attribution: fw emission ceiling, interleaved drops, dead MISSED_RPT_NUM (#363 step 1) - #368
Conversation
…nterleaved per-report drops, MISSED_RPT_NUM stuffed constant tests/txrpt_coverage_attrib.py walks a recorded run's report stream and prints coverage, the tag-gap run-length histogram, and the missed-field distribution — the three facts that attribute a coverage collapse. Measured (8812CU TX, arq_e2e ledgers, envelope sweep 1.0-2.4k fps): full coverage to ~1.25k fps, then coverage ≈ ceiling/fps with the CCX emission path saturating at ~1.3-1.4k reports/s (99.4% @ 1.26k, 77.2% @ 1.82k, 53-56% @ 2.39k). The excess drops per-report and interleaved — 99.3% of unreported frames sit in tag gaps <= 2, the signature of an emission-time rate limiter, not of transport-batch loss (a dropped C2H aggregate would lose contiguous dozens). And the CCX MISSED_RPT_NUM field is stuffed with a constant (4) on this fw, drops or no drops — parse verified bit-exact against the 8822B/C/E vendor headers, so the fw offers no drop accounting and SW_DEFINE tag gaps are the only drop signal. TxReport.h documents the dead field; docs/scheduled-mac.md carries the envelope and the consequence: above the ceiling, sample SPE_RPT 1-in-N or account report-less frames as unknown. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PR Summary by QodoAttribute tx.report coverage loss to fw emission ceiling; add analysis tool + docs
AI Description
Diagram
High-Level Assessment
Files changed (3)
|
Code Review by Qodo
1.
|
- tx.report events carry t (monotonic ms) — the CCX emission ceiling is a reports-per-second quantity and was previously unmeasurable from the stream itself (the envelope numbers were derived by hand from run spans). Verified on air: the attribution tool now computes achieved rpt/s live. - txrpt_coverage_attrib.py prints the literal fw-acknowledged-drops vs tag-gap reconciliation whenever a fw actually populates MISSED_RPT_NUM (with the 3-bit saturation caveat), keeps the constant-field diagnosis shortcut, and gains the main() guard. - docs/logging.md: tx.report row carries t + the dead-missed-field note. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…der the fw emission ceiling (#363 step 2) (#369) Step 2 of #363 (step 3, windowed RX receipts, remains). ## What it does The report knob becomes the sampling divisor N: SPE_RPT is requested on every Nth frame (0 = off, 1 = every frame — previous semantics unchanged), while the halmac SW_DEFINE tag still stamps **every** frame. Received-tag deltas are therefore exact multiples of N; any other delta is a dropped report (k·N = k−1 sampled reports lost, non-multiples are anomalies). On the 8812 report format (no tag echo) sampling only relieves the rate, via a new per-device counter. Spec derived in #368: the CCX emission path saturates at ~1.3–1.4 k reports/s, so pick **N ≥ fps/1300** and coverage of the sampled frames is deterministic instead of load-collapsed. ## Measured (on air, 2.4 k fps) | run | coverage | achieved rpt/s | note | |---|---|---|---| | N=1 control | 56.4% | 1,329 | the collapse persists — fifth independent ceiling measurement | | **N=2** | **100.0% of sampled** (191,298/191,323) | 1,107 | **zero lost, zero off-modulo anomalies** | | N=1 @ 1 k fps | 99.9%, no tag gaps | 749 | old behaviour byte-for-byte; arq_e2e verdict stays acked_undelivered=0 | Statistical-accounting check: the N=2 sampled ok-rate read **99.71% against a 99.99% ledger ground truth** — pessimistic by the known ACK-loss asymmetry (`ok=0`-but-delivered), the safe direction for a delivery-accounting consumer. ## Changes - `DeviceConfig::Tx::report` bool → int (doc-tagged with the ceiling + the N ≥ fps/1300 rule); env parse clamps 0..255 (tag-unwrap ambiguity bound). - J2/J3: tag every frame, request every Nth (both fields inside the checksummed span, re-checksum unchanged). J1: new `_tx_ccx_ctr` drives the cadence. - `tests/txrpt_coverage_attrib.py --sample-n` — expected-delta accounting for sampled ledgers. - `tests/arq_e2e_delivery.sh` — `DRONE_REPORT_N` passthrough. - `docs/scheduled-mac.md` — the knob documented next to the measured envelope, favourable and adversarial numbers together. ## Validation Three fresh on-air runs (money/control/regression above); `ctest` 48/48; existing matrix scripts unaffected (they pin `DEVOURER_TX_REPORT=1`, whose semantics are unchanged). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Step 1 of #363 (the issue stays open for SPE_RPT sampling and windowed RX receipts, steps 2–3).
What the recorded #359/#366/#367 ledgers + a 3-point envelope sweep establish
The 53% coverage collapse is a fw-side CCX emission ceiling, and the fw does not account its own drops.
coverage ≈ min(1, ceiling/fps)with ceiling ≈ 1.3–1.4 k reports/s fits every measured point (8812CU TX).Attribution to emission-time, not transport: 99.3% of unreported frames sit in SW_DEFINE tag gaps ≤ 2 (95 k singles + 47 k doubles at 2.39 k fps, max gap 28) — interleaved per-report loss, the signature of a rate limiter at report generation. Transport-batch loss (a dropped C2H aggregate) would lose contiguous dozens per event; the data shows the opposite. The tag-unwrap ground truth is trusted because the same runs' ledger joins matched 203,799/203,799 ok-frames in #359.
MISSED_RPT_NUM is dead on this fw: constant 4 on every report across all runs — including 100%-coverage runs where nothing was dropped. Parse verified bit-exact against the 8822B/8822C/8822E vendor headers (
CCX_RPT_GET_MISSED_RPT_NUM: dword +0x4, bits [15:13] — identical in all three trees), so this is fw behaviour, not a devourer bug. Tag gaps are the only drop signal available.What's in the PR
tests/txrpt_coverage_attrib.py— coverage, gap-shape histogram, missed-field distribution per recorded run (refuses tag-less J1 ledgers loudly).src/TxReport.h— themissed_rptfield documents its measured deadness.docs/scheduled-mac.md— the envelope + the consequence for accounting layers: keep the demanded report rate under ~1.3 k/s (SPE_RPT 1-in-N — step 2) or treat report-less frames as "unknown".Validation
Three fresh on-air envelope runs (1.5 k/2 k/3 k fps demanded) + re-analysis of four recorded runs; tool parity-checked against the exploratory pass;
ctest48/48 (comment-only library change).🤖 Generated with Claude Code