feat: centralised TX kill-switch URL poller (PR 3/3) - #128
Merged
Conversation
PR 3 of the master TX-stop work. Fills the ITxKillSwitchSignal seam
introduced in PR 2 with a real BackgroundService that polls a
configurable URL and gates TX on the result.
- SystemOptions adds TxKillSwitchUrl (empty=disabled), PollSeconds
(default 60, min 5), FailOpen (default true), StaleSeconds
(default 600, min 30). Round-trip through SystemOptionsStore.
- TxKillSwitchPoller IS the ITxKillSwitchSignal (singleton) AND a
hosted service. Reads IOptionsMonitor on every tick so a /Config
flip of the URL takes effect without restart.
- Wire shape: {"txAllowed": bool, "reason": string?, "appliesTo": ["*"|"M0LTE-*"|"M0LTE-2"]}.
appliesTo is a glob-ish callsign filter so one URL can stop one
site without affecting the whole fleet. Empty/missing = applies
to everyone.
- Fail modes: HTTP/parse failure keeps the last successful state
until StaleSeconds elapses, then applies FailOpen (default
permits TX so a network outage doesn't gag a working node;
operators can flip to fail-closed).
- Errors swallowed - same posture as UpdateChecker.
Manual smoke: dotnet watch + python http.server hosting a JSON
file confirms the gate flips to BLOCK within one poll, banner
shows the remote reason without a Resume button (since only the
remote closed the gate), and reverses on its own when the JSON
is flipped back.
Test suite: 639/639 green (20 new poller tests covering JSON
contract, callsign targeting, staleness fail-open/fail-closed,
never-fetched-yet boot states).
This was referenced May 6, 2026
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.
Summary
PR 3 of 3 for the master TX-stop work. Fills the `ITxKillSwitchSignal` seam from #127 with a real `BackgroundService` that polls a configurable URL and gates TX on the result.
Wire shape
{ "txAllowed": false, "reason": "contest QRM", "appliesTo": ["M0LTE-*", "GB7RDG"] }`appliesTo` is a glob-ish callsign filter so one URL can stop one site without affecting the whole fleet:
Empty / missing list = applies to everyone.
Fail modes
HTTP / parse failure keeps the last successful state until `StaleSeconds` elapses, then applies `FailOpen`:
Errors are swallowed by design - poller crash mustn't take down the daemon.
Test plan
Stacked on PRs 1-2
#126 and #127 land first; this branch is rebased on master post-merge.
🤖 Generated with Claude Code