#431 landed the CCX pair (clm busy-airtime + nhm_env) and #432 landed the
vendor-neutral ChannelBusy contract plus src/sensing/. Both stopped short of
the same line on purpose: the new sensors are emitted, not scored, and two of
the five backends plus the whole MediaTek path are unmeasured. This is the
list of what was deliberately left out, so it stays visible instead of living in
merged PR descriptions.
Nothing here is urgent and nothing blocks anything. They are independent — take
one, or close this if the direction changes.
1. The MediaTek busy path is written but never measured
mt7612u_ch_time() reads MT_CH_BUSY (0x1134) / MT_CH_IDLE (0x1130) and
GetChannelBusy maps it, but there is no MT7612U on the bench, so
busy_airtime_measured ships false. Two things need measuring before that
flag flips:
- that
busy/(busy+idle) tracks real occupancy beyond repetition noise;
- the real risk — that polling it at dwell cadence does not disturb
mt7612u_phy_tick()'s gain tracking. The accessor was deliberately narrowed
to those two registers to avoid the read-and-clear false-CCA field the AGC
loop owns, but "should not disturb it" is an argument, not a measurement.
Methodology: frame rate against a steady peer, with and without the poller,
and the no-tick control alongside — the tick's own favourable figure is
meaningless without it.
Also unmeasured on the Realtek side: Jaguar1 clm / nhm_env. Jaguar2 and
Jaguar3 are the two validated generations.
2. Kestrel discards clm_ratio it already computes
src/kestrel/kestrel_halbb_glue.c:193 drops clm_ratio, nhm_ratio and the
ifs_clm_* products the vendor env-monitor engine has already produced. That is
roughly three lines to un-discard — the reason busy_airtime_ok is currently
false on Kestrel is that NhmReader's maps are 11AC + JGR3 only, not that the
silicon lacks the facility. Worth doing on its own, before anything below
depends on it.
3. ChannelScore still ranks on a false-alarm proxy
src/chanmig/ChannelScore.cpp derives occupancy from fa_rate/(fa_rate+200) —
a proxy for busy airtime, now that real busy airtime exists as a number.
Rewiring it is not a refactor: it changes the migration law, so it needs its
own 14-row failure-matrix re-validation plus an on-air soak, and it should not
happen while clm is measured on only two of five generations.
Three caveats that must survive into whatever scoring law consumes these, all
from docs/rx-spectrum-sensing.md and none of them chip-specific:
- plain
fa_ofdm outperformed both new sensors on every part measured — the
pair buys an airtime unit and a non-railing ratio, not a new detection;
nhm_env is IGI-referenced, so it is blind wherever DIG is free to walk the
gain out from under it;
- the ~2 ms window makes one dwell a sample, not a measurement (single-read
sd 4–24). chanscout takes exactly one per dwell today; a naive one-shot
ranking across channels is the failure mode a neutral interface invites.
4. examples/tx still carries its own copy of the sense window
hopset_sense_window in examples/tx/main.cpp predates src/sensing/SenseWindow.h
and duplicates the same settle → barrier → observe → read discipline — its own
comment says so. SenseWindow was shaped to make this a mechanical drop-in, and
it would gain the counter-plausibility check tx has a flag for but never sets.
Left out of #432 because it is the TX hot path: it runs inside the slot-timed
hop loop holding g_hopset_mu across ingest, and its correctness criterion is
on-air FHSS lockstep, which headless tests cannot see. Anyone taking this needs
the lockstep harness, not just ctest.
#431landed the CCX pair (clmbusy-airtime +nhm_env) and#432landed thevendor-neutral
ChannelBusycontract plussrc/sensing/. Both stopped short ofthe same line on purpose: the new sensors are emitted, not scored, and two of
the five backends plus the whole MediaTek path are unmeasured. This is the
list of what was deliberately left out, so it stays visible instead of living in
merged PR descriptions.
Nothing here is urgent and nothing blocks anything. They are independent — take
one, or close this if the direction changes.
1. The MediaTek busy path is written but never measured
mt7612u_ch_time()readsMT_CH_BUSY(0x1134) /MT_CH_IDLE(0x1130) andGetChannelBusymaps it, but there is no MT7612U on the bench, sobusy_airtime_measuredshipsfalse. Two things need measuring before thatflag flips:
busy/(busy+idle)tracks real occupancy beyond repetition noise;mt7612u_phy_tick()'s gain tracking. The accessor was deliberately narrowedto those two registers to avoid the read-and-clear false-CCA field the AGC
loop owns, but "should not disturb it" is an argument, not a measurement.
Methodology: frame rate against a steady peer, with and without the poller,
and the no-tick control alongside — the tick's own favourable figure is
meaningless without it.
Also unmeasured on the Realtek side: Jaguar1
clm/nhm_env. Jaguar2 andJaguar3 are the two validated generations.
2. Kestrel discards
clm_ratioit already computessrc/kestrel/kestrel_halbb_glue.c:193dropsclm_ratio,nhm_ratioand theifs_clm_*products the vendor env-monitor engine has already produced. That isroughly three lines to un-discard — the reason
busy_airtime_okis currentlyfalseon Kestrel is thatNhmReader's maps are 11AC + JGR3 only, not that thesilicon lacks the facility. Worth doing on its own, before anything below
depends on it.
3.
ChannelScorestill ranks on a false-alarm proxysrc/chanmig/ChannelScore.cppderives occupancy fromfa_rate/(fa_rate+200)—a proxy for busy airtime, now that real busy airtime exists as a number.
Rewiring it is not a refactor: it changes the migration law, so it needs its
own 14-row failure-matrix re-validation plus an on-air soak, and it should not
happen while
clmis measured on only two of five generations.Three caveats that must survive into whatever scoring law consumes these, all
from
docs/rx-spectrum-sensing.mdand none of them chip-specific:fa_ofdmoutperformed both new sensors on every part measured — thepair buys an airtime unit and a non-railing ratio, not a new detection;
nhm_envis IGI-referenced, so it is blind wherever DIG is free to walk thegain out from under it;
sd 4–24).
chanscouttakes exactly one per dwell today; a naive one-shotranking across channels is the failure mode a neutral interface invites.
4.
examples/txstill carries its own copy of the sense windowhopset_sense_windowinexamples/tx/main.cpppredatessrc/sensing/SenseWindow.hand duplicates the same settle → barrier → observe → read discipline — its own
comment says so.
SenseWindowwas shaped to make this a mechanical drop-in, andit would gain the counter-plausibility check tx has a flag for but never sets.
Left out of
#432because it is the TX hot path: it runs inside the slot-timedhop loop holding
g_hopset_muacross ingest, and its correctness criterion ison-air FHSS lockstep, which headless tests cannot see. Anyone taking this needs
the lockstep harness, not just
ctest.