Commit ab03be0
feat(core): add shared-capture RF admission policy (#5472)
## Summary
RTL RFC #5468 requires every receiver's complete guarded RF passband to
fit the shared capture before tuning, filter/mode changes or sample-rate
changes are accepted. Add a pure `SharedCapturePolicy` helper that
selects the nearest legal quantized tuner center, validates coherent
readback and produces a deterministic restore plan within the current
capture.
The helper validates asymmetric filter/usable margins, signed
carrier/BFO translation, transition guards, disjoint hardware domains,
bounded numeric inputs, stable slot IDs and caller-supplied receiver
capacity. It keeps an already legal center, refuses an impossible
desired set atomically, and restores fitting entries in ascending
stable-ID order without recentering or renumbering. Conservative
floating-point arithmetic rejects unrepresentable boundary fringes
rather than widening acceptance with a tolerance.
This is F2 of #5468 and is independent of P01 #5471. The helper compiles
into the static `aethercore` library; the registered test compiles that
same implementation. No live backend calls it yet.
USB/DSP/audio/viewport/UI/persistence integration and supported receiver
counts remain later RFC phases. The new contract is documented in
`docs/shared-capture-policy.md`. This PR does not close the umbrella
RFC.
## Review follow-up
An additional regression rejects a center grid whose 1e-5 Hz step is
smaller than the double spacing at 2^39 Hz while its grid indices remain
within the independent index bound. The capture and slice otherwise fit.
Disabling only the resolution guard makes this new check fail, closing
the reported mutation-coverage gap. The final readback validation
remains, with its defense-in-depth purpose made explicit.
The contract now distinguishes adapter-declared logical readback from
measured physical RF frequency. In [Osmocom librtlsdr
v2.0.2](https://github.com/osmocom/rtl-sdr/blob/v2.0.2/src/librtlsdr.c#L884-L913)
and [RTL-SDR Blog commit
aed0ea19](https://github.com/rtlsdrblog/rtl-sdr-blog/blob/aed0ea19f3a273370a13c9009b96313c75d54c7b/src/librtlsdr.c#L887-L936),
`rtlsdr_get_center_freq()` returns the cached requested frequency stored
by successful tuning; it does not measure achieved PLL frequency. Other
versions and forks need verification. Actual readback must still satisfy
the declared domains and complete-set containment checks.
## Constitution principles honored
Principle VII — invalid numeric descriptors, impossible intervals,
malformed identities, oversized collections and incoherent readback fail
at the policy boundary. Principle II — a selection is only a proposal;
the integration layer must validate coherent capture state before
publication. Logical library readback does not establish physical RF
accuracy.
## Validation
- Follow-up on macOS ARM64, Apple clang 21.0.0, standalone C++20 `-O2`:
**260 checks, 0 failures**. The test is socket-free and requires no Qt
event loop, hardware, DSP or settings.
- Follow-up mutation in a temporary source copy: disabling only `stepHz
< resolution` produces **260 checks, 1 failure**, specifically the new
unresolved-grid assertion. Production guards remain unchanged.
- `git diff --check` passes for the follow-up.
- Prior reviewed head `5cd78ad10bf3ce86c404cddf7c2aea9b4215c844`: Linux
normal engine policy object and registered CTest built with GCC 16.2.1;
all 259 then-existing assertions passed. The independent rational oracle
matched all 2,000 cases, upper-transition-guard and generation mutations
failed as expected, and the exact restored source passed. Strict
engine-boundary, test-registration, frozen CI-gate and touchpoint checks
passed on that head. Those are recorded prior-head results, not a new
Linux run of this follow-up.
- Linux follow-up: normal engine policy object and registered CTest
rebuilt; **260 checks pass**. Removing only the resolution guard
compiled and failed the new assertion. Exact source restoration, rebuild
and final CTest pass. Strict engine-boundary, registration, frozen CI
gate, touchpoint manifest and whitespace checks pass.
- Signed follow-up head `bec2815c605442864fc425133ddd887cb200680d`; full
source matches validation base
`e60c3bea2ac8e5b762be9a3c6f52aa1bab8fb9ad` plus six-file digest
`b2237190f1a875addf40557d39d9e5e8c01fcc171906908861a1c51ac46c4cf5`. All
seven PR checks passed on this follow-up head.
- Review follow-up `beb054c384c9bb1334c68ab6ecb8bc8ec96ebd93` corrects
only the Osmocom source anchor; implementation and tests are unchanged.
Independent review of `bec2815c` merged with main `f0ed969b` passed all
260 checks in native macOS ARM64 optimized and ASan/UBSan builds.
Grid-resolution, upper-guard, generation and restore-capacity mutations
all failed as expected. Engine-boundary, registration, frozen CI-gate,
touchpoint and whitespace checks passed. See the live Checks tab for the
documentation follow-up status.
No live-radio or performance claim is made for this unintegrated policy.
The test is registered in the default graph without expanding the frozen
per-PR allow-list. No dependencies, threads, settings owner,
socket-owning test, UI controls or CHANGELOG entry are added. Full
application behavior, physical RF accuracy and supported receiver
capacity remain integration gates.
---
73, Ozy **K6OZY** · GPT-6 Astra-Ultra
---------
Co-authored-by: Robbie Foust <rfoust@gmail.com>1 parent f0ed969 commit ab03be0
6 files changed
Lines changed: 1108 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
757 | 757 | | |
758 | 758 | | |
759 | 759 | | |
| 760 | + | |
760 | 761 | | |
761 | 762 | | |
762 | 763 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
0 commit comments