Linear: MOR-1629
Parent GitHub: #2541
Parent: MOR-1500
Source authority: origin/main f016380
Outcome
Add the shared enforcement seat to rigctld CommandService execution so direct frequency/mode/VFO/split/RIT-XIT/raw/tuner and routed writes cannot bypass MOR-1500.
Owned paths
src/rigplane/rigctld/handler.py
tests/test_rigctld_tx_interlock.py (new focused test)
Red-first witness
Focused rigctld tests show set_freq, set_mode, set_vfo, set_split_vfo, shared RIT/XIT offset, tuner enable, and send_raw execute during known TX without the ruled disposition.
Acceptance criteria
Dependencies
Blocked by MOR-1500 A1, A2, and A3.
Scope guardrails
- Anchor: origin/main f016380.
- Maximum 3 owned files and 400 changed LOC.
- Red-first focused tests; foreground timeout 600000 ms; never run the full suite for this child.
- No refactor, new layer, model-name branch, unrelated cleanup, or scope expansion.
- Public API/CLI/config/rigctld compatibility changes must be called out explicitly.
Project fields
Priority=P1; Risk=high; Size=S; Phase=stable; Owner=codex; WorkType=bug.
Linear: MOR-1629
Parent GitHub: #2541
Parent: MOR-1500
Source authority: origin/main f016380
Outcome
Add the shared enforcement seat to rigctld CommandService execution so direct frequency/mode/VFO/split/RIT-XIT/raw/tuner and routed writes cannot bypass MOR-1500.
Owned paths
src/rigplane/rigctld/handler.pytests/test_rigctld_tx_interlock.py(new focused test)Red-first witness
Focused rigctld tests show set_freq, set_mode, set_vfo, set_split_vfo, shared RIT/XIT offset, tuner enable, and send_raw execute during known TX without the ruled disposition.
Acceptance criteria
routing.pyand no second policy table is invented.Dependencies
Blocked by MOR-1500 A1, A2, and A3.
Scope guardrails
Project fields
Priority=P1; Risk=high; Size=S; Phase=stable; Owner=codex; WorkType=bug.