Highlights
- Fix duplicate spots reaching users. Spot identity is now DX call, spotter, and frequency within 0.2 kHz instead of DX call, frequency, and comment. The comment is rewritten in transit by other cluster software and by pyCluster itself, so keying on it made the same spot render twice when it arrived by two paths; keying without the spotter silently discarded two operators spotting the same DX. The RBN and cluster ingest lanes now share one suppression cache instead of using incompatible key tuples, so a signal arriving on both lanes renders once.
- Stop a peer's clock from corrupting local suppression. The dedupe window now expires by arrival time rather than by the spot's own timestamp, so a single future-dated spot from a peer whose clock runs fast can no longer evict every other peer's cache entries. Peer-supplied timestamps are clamped against local time, and the cache is primed from stored spots at startup so a restart does not re-admit the previous 15 minutes.
- Keep operator corrections working. A spot this node originates stays comment-aware, so an operator re-sending their own spot with a corrected comment is accepted while an exact repeat is still suppressed. Historical imports spanning days are no longer collapsed, because the duplicate decision compares spot timestamps while expiry uses arrival time.
- Ensure host clock synchronization during install and upgrade. When no time service is running and package installation is enabled,
chronyis installed and enabled. An already-workingsystemd-timesyncd,chrony, orntpdis left alone rather than replaced, and hosts that inherit an accurate clock from a hypervisor warn instead of failing the deployment.deploy/doctor.shreports provider and synchronization state, and the support bundle captures measured offset throughchronyc tracking. - Add
PY14 NEIGHBORS, which reports the non-pyCluster nodes a node links to directly, so PY peers can see the network beyond the pyCluster island. It carries callsign, software family, identified version string, and link state for DXSpider, AR-Cluster, DX-NET, and CLX links. A PC18 banner outranks the configured peer profile because it is an observation rather than an assertion, and unrecognized software is reported asunknownrather than guessed at. Reported nodes appear in Topology and the known-node catalog marked Legacy and are searchable by software family.
Operational Notes
- Duplicate suppression changes what users see immediately. Spots previously shown twice because a relaying node reformatted the comment now render once, and two operators spotting the same DX on the same frequency are both delivered where the earlier key discarded the second.
PY14 NEIGHBORSis gated by theneighborscapability and the newshare_neighborscontrol, which defaults to enabled in line with the other sharing controls. Nothing is transmitted until a peer also runs 1.0.22 and advertises the capability, and the frame is never relayed, so every record carries one hop of provenance. Disable it under Node Settings if you would rather not disclose which non-pyCluster nodes this node links to.share_neighborsis not written into existingpycluster.tomlfiles.PY_DEFAULTS_VERSIONdeliberately stays at 1, because raising it would force every sharing control back to enabled and override deliberate operator choices. The runtime default supplies the value, and the first save from the SysOp sharing panel persists it.- On upgrade,
PYCLUSTER_PKG_AUTO_INSTALLstill defaults to0, so no time-synchronization package is installed. An installed-but-stopped provider is enabled, and a host with none is warned about rather than failed. UsePYCLUSTER_PKG_AUTO_INSTALL=1 ./deploy/upgrade.shif you want an upgrade to installchrony. PY15is reserved for the distributed security advisories proposed in #276 and must not be reused.docs/1.0.20-work-plan.mdis removed. Its content is covered by the issue tracker,CHANGELOG.md, and the roadmap under the maintenance rules indocs/README.md; the file remains available in git history.
Verification
- 745 default local regression tests passed, and all 49 explicitly marked network-listener tests passed in a separate run: 794 total.
- 46 tests were added: 17 for
PY14 NEIGHBORS, 17 for spot dedupe and the shared deduper, 10 for the deployment time-synchronization helpers, and 2 updated existing suites. - Duplicate suppression was verified against the real
SpotStorefor four independent failure modes reproduced before the fix: punctuation differences in a rewritten comment, 0.1 kHz frequency rounding between paths, cache eviction by a future-dated peer timestamp, and legitimate distinct spotters being discarded. - The time-synchronization helpers were exercised against this machine's live
chronydstate and against stubbedsystemctl/timedatectlfor the unsynchronized, enabled-but-converging, and absent-provider paths. - This release has not been deployed. No production validation, browser checks, or live peer exchange were performed against
PY14, and no live node has yet exchanged the frame with another 1.0.22 node.