feat(spot): POTA as a polled spot source (FR-SPOT-08) - #196
Merged
Merged
Conversation
Read the four networks FR-SPOT-08 names (R-EXT-05) and built POTA. - k4-spot::pota: strict parser for the observed reply (kHz string to Hz, UTC time, park in the comment); a bad record costs only itself, anything that is not a list of flat records is an error shown to the operator. - k4-spot::polled: source for polled networks; the request runs on its own thread so a slow server never delays the other sources; injected fetcher, interval, backoff, hung-request deadline, window and per-reply caps. - app/src/http_fetch.rs: anonymous bounded GET (timeout, size cap, no redirects) on the existing ureq/rustls. - Fourth worker slot, PotaPrefs (off by default, 30 s..1 h, default 60 s), a POTA section in Networks, green nameplates, demo spots. - The worker now rests between passes; with only a polled source it would have spun a core. SOTA, WSPRnet and FreeDV Reporter are not built; each is blocked on a decision or prerequisite recorded in OP-7 (items 5-7). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma4bQKqGNFTYyVSEKPcXRk
An earlier note said FreeDV Reporter needs TLS. That was an assumption. SDRoxide's public source (read for interface facts only, per R-EXT-04) connects over plain ws:// in a read-only view role. Also records what it does about POTA (same endpoint), SOTA (a different, unstable host; no credential) and WSPRnet (own callsign only). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma4bQKqGNFTYyVSEKPcXRk
This was referenced Sep 21, 2026
Merged
…stants The boundary inputs of the POTA parser tests were built from the constants they test (MAX_BODY + 1, MAX_SPOTS + 1), so changing a constant moved the test with it and nothing noticed. Mutating the constants themselves showed MAX_BODY, MAX_SPOTS, the frequency ceiling and the default poll interval all unpinned. The limits are now written as numbers (512 KiB, 2000 spots, 64-character text, 300 GHz plus one hertz, 30 s / 60 s / 1 h). MAX_TOKEN stays an equivalent mutation: the same 64 is applied again downstream by sanitise_text, and a string there is a borrowed slice; documented in the code. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ma4bQKqGNFTYyVSEKPcXRk
4 tasks
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.
What
Reads the four networks FR-SPOT-08 names (R-EXT-05) and builds POTA. SOTA, WSPRnet and FreeDV Reporter are not built: each is blocked on a decision or prerequisite recorded in
OP-7items 5–7.k4-spot::pota— strict parser for the observed reply (kHz string → Hz, UTC time, park in the comment). A bad record costs only itself; anything that is not a list of flat records is an error shown to the operator.k4-spot::polled— source for polled networks. The request runs on its own thread so a slow server never delays RBN/PSK; injected fetcher, interval, backoff, hung-request deadline, window and per-reply caps.app/src/http_fetch.rs— anonymous bounded GET (timeout, size cap that refuses rather than truncates, no redirects) on the existingureq/rustls.PotaPrefs(off by default, 30 s–1 h, default 60 s), a POTA section in Networks, green nameplates, demo spots,K4_POTA_URLtest hook (http(s) only, otherwise ignored).Findings worth a look
ureqtreats a body that reaches its limit as over it; the worker spin above.Verified
fmt, clippy
--all-features, full workspace tests (bounded),cargo xtasktrace gate OK. Run end to end in--demoagainst a local stand-in: 2 requests in 40 s at a 30 s interval, expected headers only, green nameplate drawn, out-of-view spot not drawn.Validation parked with DC0SK (not done here)
spotTimeis UTC (compare a spot's age against pota.app).expireandinvalidmean in practice.🤖 Generated with Claude Code
https://claude.ai/code/session_01Ma4bQKqGNFTYyVSEKPcXRk