9 Commits
47 changed files with 2152 additions and 126 deletions
@@ -0,0 +1,90 @@
---
name: kst4contest-change
description: Analyze or implement KST4Contest Java/JavaFX changes, bug fixes, refactorings, protocol handling, contest workflow behaviour, callsign/band logic, AirScout/logging/rotor/DXCluster integrations, threading and state management. Use current code as source of truth and follow the mandatory concept-and-question gate before edits.
---
# KST4Contest change workflow
Read the relevant reference files before proposing a concept.
## Phase 1: read-only analysis
- Inspect the current code and tests.
- Identify the current data flow and thread ownership.
- Identify user-visible and protocol-visible behaviour.
- Check relevant `docs/PROJECT_CONTEXT.md` sections when they exist.
- Check whether the task overlaps a known invariant in the references.
- Do not modify files.
## Phase 2: report understanding in German
Explain:
- what Marc wants changed;
- what must remain unchanged;
- which components appear affected;
- what evidence in the current code supports that understanding;
- any conflict between current code and historical project context.
Never resolve a conflict by guessing.
## Phase 3: questions and final concept in German
Before finalizing the concept:
- identify all material implementation choices;
- ask Marc questions that are not already answered by code, project instructions or prior confirmed decisions;
- wait for answers when needed.
Then present:
- intended data/control flow;
- exact behavioural changes;
- compatibility impact;
- thread/UI impact;
- persistence impact;
- test strategy;
- likely documentation impact;
- likely durable project-context impact;
- related-project impact when relevant.
Ask for explicit concept approval and wait before editing.
## Phase 4: implementation
After approval:
- implement the smallest coherent change;
- preserve unrelated behaviour;
- keep comments/Javadoc in English;
- add/update focused tests;
- keep external protocol parsing defensive;
- avoid hidden defaulting for unknown values.
## Phase 5: verification and documentation impact
Run focused checks, then appropriate broader checks.
Because KST4Contest build configuration may ignore failures/findings, inspect summaries and reports rather than only command exit status.
Then use `$software-project-context`:
- do a low-cost documentation-impact classification;
- inspect only likely affected manual/README/website sections;
- update targeted documentation when clearly required by the approved implementation;
- update `docs/PROJECT_CONTEXT.md` for significant durable technical decisions/state changes;
- do not perform a full manual audit unless there is a specific trigger.
## Phase 6: report
Report in German:
- files changed;
- implementation summary;
- tests/checks;
- warnings/findings;
- documentation-impact result;
- documentation/context updates or why none were required;
- related-project impact when relevant;
- unresolved issues;
- no Git publication action unless explicitly requested.
@@ -0,0 +1,7 @@
interface:
display_name: "KST4Contest Change"
short_description: "Plan and implement KST4Contest changes safely"
default_prompt: "Analyze the requested KST4Contest change, explain your understanding and concept in German, ask implementation questions, and wait for approval before editing."
policy:
allow_implicit_invocation: true
@@ -0,0 +1,102 @@
# Architecture context
## Current package shape
The repository currently contains major packages under `src/main/java/kst4contest/` including:
- `controller`
- `locatorUtils`
- `logic`
- `model`
- `service`
- `test`
- `utils`
- `view`
Do not treat package names alone as proof of clean MVC boundaries. Inspect actual dependencies.
## Preferred message/member data flow
The established target architecture for active chat members is:
```text
ON4KST / network
|
v
MessageBusManagementThread
|
v
ChatController
|
v
thread-safe active-member domain state
(ConcurrentMap; identity includes callsign + category)
|
v
JavaFX ObservableList UI mirror
|
v
FilteredList / SortedList / TableView / selection
```
Key rule:
`ObservableList` is a JavaFX UI projection, not the canonical store for worker-thread logic.
`MessageBusManagementThread` must not directly read or modify the UI list.
## JavaFX boundary
UI-visible mutations belong on the JavaFX Application Thread.
Prefer controller-owned helpers such as an existing `runOnFxThread` abstraction when available; otherwise use `Platform.runLater` consistently.
Do not move business/data access into the FX thread merely to silence a threading problem.
## Parser/service separation
For protocol receivers, the preferred direction is:
```text
Receiver (I/O only)
-> Parser (wire data -> DTO)
-> Service (domain/persistence logic)
-> Controller (UI coordination)
-> Observable UI model
-> View
```
A previous concrete example for UCXLog was:
```text
UcxUdpReceiver
-> UcxPacketParser
-> DTO
-> UcxLogService
-> ChatController
-> UI projection
```
This is architectural guidance, not permission for a broad refactor. Apply only when it is in scope and approved.
## DTO preference
Prefer explicit DTO classes over records when introducing protocol/transport data structures in this project, unless the approved concept intentionally changes that convention.
## Null safety
Chat members can be incomplete, especially:
- fallback members;
- historic message senders;
- server-derived partial members.
Values such as QRB and QTF can be absent.
Rules:
- absence stays absence;
- do not map `null` to numeric zero;
- UI must render unavailable state safely;
- sorting/filtering/calculation code must tolerate missing values;
- unexpected missing values must not terminate worker or UI threads.
@@ -0,0 +1,42 @@
# Automated messaging, beacons and skeds
## General
Automated replies/beacons must be conservative because they interact with the live ON4KST service.
## Established safety behaviour
Historical confirmed rules include:
- beacon/autoanswer scheduling shares controlled timing rather than spawning uncontrolled independent timers;
- minimum interval has been tightened to avoid spam;
- automated text length is bounded;
- invalid or incomplete replies are rejected before transmission;
- a cooldown is not consumed unless a complete valid reply enters the TX queue;
- QRG/frequency requests take precedence where the current implementation defines that;
- automated-message markers are ignored to prevent response loops.
Recent logic used a two-minute cooldown keyed by complete callsign plus chat category and ignored the project's own automated-message marker.
Treat exact marker strings and timing constants as current-code facts to verify, not values to recreate from memory.
## Monitoring
Station monitoring is intentionally base-call-wide:
Entering a variant such as:
```text
DN9APW-2
DN9APW-70
```
monitors:
```text
DN9APW
```
This reduces manual configuration for sked monitoring.
Keep this separate from chat-member identity, which may require full suffix + category.
@@ -0,0 +1,87 @@
# Domain, callsigns and bands
## Chat-member identity
Full callsign variants can be distinct chat identities.
Examples:
```text
DN9APW
DN9APW-2
DN9APW-70
```
Do not globally strip suffixes when identifying chat members.
Category is also part of identity. A practical key is conceptually equivalent to:
```text
FULL_CALLSIGN|CATEGORY
```
Do not allow messages from one category to attach to a same-looking member in another category.
## Base-call operations
Some features intentionally operate on the base callsign.
Confirmed examples:
### Worked state
Worked status is shared across suffix variants of the same base call.
If the base station has been worked on the relevant basis, variants such as `CALL-2`, `CALL-70`, `CALL-144`, `CALL-432` should not become independent worked identities merely because of the suffix.
### Monitoring
Monitoring a station entered as `DN9APW-2` or `DN9APW-70` should monitor the base call `DN9APW`.
This is intentional: a user monitoring another station's skeds should not have to create one monitor entry per SSID.
Do not extend base-call matching to unrelated features without approval.
## Suffix semantics
Do not assume a suffix always means a band or category.
Historical examples have shown the same base calls with different suffix conventions in different chat categories.
Therefore:
- preserve exact full-call identity where needed;
- normalize only for explicitly approved base-call features;
- never infer missing band/category semantics from the suffix alone.
## Categories
KST4Contest's central VHF/UHF usage focuses on ON4KST categories 2 and 3.
However, other categories can occur.
Rules:
- unsupported/uninteresting categories must be ignored or handled safely;
- they must not produce index, switch or null errors;
- do not let their values contaminate category-2/category-3 band logic.
## Band availability
Band activity can be derived from several signals including name/text parsing and explicit/manual information.
Confirmed invariant:
`NOT-QRV` overrides positive availability indications.
Known-active-band and `B+` handling should use one consistent interpretation across the program.
Do not implement separate slightly different parsers in multiple UI/features if a shared existing mechanism is available.
## Current QRG
Features that depend on propagation/band/frequency should use the current relevant QRG or the approved band calculation.
Never silently reintroduce a universal hardcoded 144 MHz fallback.
When a frequency is ambiguous and no approved fallback exists, ask rather than guessing.
@@ -0,0 +1,115 @@
# Known edge cases and regression patterns
This file is a regression-awareness list. Reproduce/inspect current code before deciding a historical bug still exists.
## Incomplete ChatMember
Known failure pattern:
```text
Cannot invoke "java.lang.Double.intValue()" because
ChatMember.getQrb() is null
```
Lesson:
- QRB can be absent;
- UI/calculation code must not blindly unbox/convert;
- unavailable is not zero.
Apply the same reasoning to QTF and other server/fallback-derived fields.
## Callsign suffix collisions
A historical issue caused messages/identity problems between:
```text
DN9APW
DN9APW-2
```
The corrective model is not "strip all suffixes".
Instead:
- keep full-call chat identities distinct;
- include category;
- use base call only for explicitly base-call-wide features such as worked state/monitoring.
## Unsupported chat categories
The ON4KST ecosystem can expose categories outside the two central ones.
A parser/switch/filter must not throw because the category is irrelevant to KST4Contest.
Safe ignore/fallback beats fake band assignment.
## AirScout higher-band queries
A historical observation showed aircraft visible in AirScout while API results for a 432 MHz case were empty.
Potential causes included frequency-string formatting.
Lesson:
- verify the exact upstream contract;
- compare request produced by KST4Contest with a known-working request;
- do not "fix" by guessing a string format or falling back to an unrelated band.
## Second airplane-scatter result / missing aircraft
A known UI failure involved missing/partial airplane-scatter data and a `TextInputControl` range error (`start must be <= end`).
Lesson:
- empty/partial AP results must be validated before text-range highlighting/selection;
- second-result paths need the same null/range checks as primary results.
## Historic/unknown user message
A user/message record can refer to a callsign not present in the current member list.
Do not require current login membership to render or classify historic messages.
## UM3-style handling
Historical message handling included cases that should be ignored safely if the user is not in the chat/member state.
Lesson:
- external message types must tolerate missing member references.
## CR/LF and disconnect suspicion
Do not treat line endings as harmless text formatting in socket code.
When diagnosing a disconnect:
- inspect transmitted bytes;
- inspect server response/EOF;
- compare Windows versions only after proving the application sends different bytes;
- avoid duplicated LF/CRLF terminators.
## Filter reset
A reset button that clears control values but leaves predicates active is not a valid reset.
Verify final predicate composition, not only UI state.
## Map render flicker
Leaflet/WebView render fragmentation under Java 21 was mitigated by:
```text
window.L_DISABLE_3D = true
```
before Leaflet load.
Do not remove as "obsolete CSS cleanup" without a visual regression check.
## Network start/reconnect loop
Initial connection failure must not spin indefinitely or block controlled recovery.
Connection state must be based on actual I/O lifecycle rather than only `Socket.isConnected()`-style historical state.
@@ -0,0 +1,183 @@
# Project behaviour catalog
This catalog summarizes behaviour established during prior KST4Contest work. It is context for analysis, not permission to overwrite newer code. Always inspect the current implementation before modifying a listed area.
## Core purpose
KST4Contest is an ON4KST-oriented desktop client optimized for VHF/UHF/microwave contest workflows.
Core areas developed over time include:
- simultaneous ON4KST chat handling;
- priority candidates;
- sked workflow and timeline;
- worked-state synchronization;
- logging integrations;
- DXCluster;
- AirScout / airplane-scatter assistance;
- rotor/control integrations;
- map/path visualization;
- automated replies/beacons;
- user filtering and reachability;
- documentation and website/update-feed integration.
## Two chat categories
The application is designed around two simultaneous relevant chat categories in normal operation.
Important consequences:
- same-looking calls in different categories are not automatically the same chat identity;
- category is part of message/member identity;
- category-specific QRG/band settings must not leak into the other category;
- unsupported categories must not crash shared logic.
## Priority candidates
Priority scoring has included factors such as:
- QTF match;
- recent activity;
- message count;
- positive signal indications;
- sked rate.
Do not change weighting/meaning as collateral work. Treat it as user-facing contest logic.
## Timeline / skeds
The sked timeline has used 30-minute lanes and visualized airplane-scatter probability windows.
Known historical AP strength levels:
- 100%;
- 75%;
- 50%.
Sked reminder presets have covered short contest-relevant lead times.
Do not hardcode historical display constants into new code without verifying the current view/model.
## Worked state
Worked state is loaded from persistence and updated live from supported logging inputs.
The simplified UI meaning has been "worked any" where the locator/worked indicator is concerned.
Worked state is base-call-wide across suffix variants where established.
When changing persistence or logging synchronization, verify:
- startup DB load;
- live update;
- suffix/base-call mapping;
- band mapping;
- 50/70 MHz support where applicable;
- UI projection.
## Known active bands / B+
Known-active-band information is derived consistently across the application from available hints.
Historical work unified:
- band mentions in user names;
- band mentions in text;
- manual/global band information;
- `B+`-style availability.
Explicit `NOT-QRV` overrides positive hints.
Avoid introducing a second parser with different semantics.
## Selection and send workflow
Established fast-workflow behaviour includes:
- selecting a new station prefills `/cq callsign`;
- send text is geared toward minimal contest interaction;
- if no target chat category is selected, Main is the established fallback.
These are intentional workflow decisions, not incidental UI details.
## DXCluster
DXCluster support has included:
- integrated display;
- copyable lines;
- `/cq` workflow support;
- beacon monitoring;
- QTF/bearing-related presentation.
Preserve locator semantics and avoid sender/receiver field confusion.
## Map / path view
Map work has included:
- Leaflet 1.9.4 in JavaFX WebView;
- terrain/path information;
- airplane-scatter integration;
- target-station selection;
- path-analysis visibility;
- station-count/status information;
- target reset that does not reset zoom.
A persistent right-side station-information panel has been reduced/removed in favour of more compact presentation in later UI work.
Before changing layout, inspect the current version because this area has been actively iterated.
## Reachability and filters
Filter work has separated reachability concerns from generic filters.
A Reset Filter control must reset the actual filter predicates, not just visual controls.
UI sorting/filtering must remain stable when backing data changes.
## Autoanswer and beacons
Automated messaging exists to reduce repetitive contest chat work without creating spam or feedback loops.
Important principles:
- conservative timing;
- bounded text;
- no loop on own automated markers;
- only consume cooldown after a valid queued reply;
- category/callsign-safe identity;
- QRG requests handled with the intended precedence.
## Connection handling
Network reliability is contest-critical.
Work has explicitly targeted:
- accurate connected/disconnected state;
- server disconnect detection;
- reconnect behaviour on unstable links;
- no infinite loop on initial connection failure;
- visible connection-state indication in the UI.
Do not regress connection state into "socket object exists therefore connected".
## Historic messages
Historic/non-current chat senders may not have a complete live `ChatMember`.
Highlighting, display and parsing must tolerate users not currently logged in.
## Website and documentation
The application repository also contains:
- bilingual manual content;
- documentation images;
- automated documentation PDF build;
- Eleventy website;
- download/update metadata generation;
- release-oriented website automation.
A user-visible feature change may therefore affect more than Java source.
@@ -0,0 +1,101 @@
# Protocols and external integrations
This file records stable rules plus historical context. For exact current wire formats, ports and frequency strings, inspect the current code and authoritative upstream documentation.
## ON4KST
KST4Contest depends on long-lived server communication where malformed commands or framing can lead to disconnects.
Rules:
- preserve exact protocol framing;
- treat CR/LF changes as protocol changes, not formatting cleanup;
- do not append extra line terminators without verification;
- detect actual socket/server disconnects reliably;
- initial connection failure must not create an uncontrolled infinite loop;
- reconnect logic must tolerate unstable Internet access;
- the UI should make disconnected state clearly visible where implemented.
If Windows-specific behaviour is suspected, do not assume Win10/Win11 line-ending semantics explain it without reproducing or tracing the bytes.
## UCXLog / DXLog UDP XML
`contactreplace` must be handled equivalently to `contactinfo` for whole-log broadcasts where applicable.
Historical raw-packet XML start detection included:
```text
<?xml
<contactinfo
<contactreplace
<RadioInfo
```
DOM handling also included a fallback to `contactreplace`.
Before changing this path, inspect the current parser because the code may have been refactored since this behaviour was introduced.
Preferred layering:
```text
UDP receiver -> parser -> DTO -> service/domain/DB -> controller -> UI
```
## Win-Test
Historical integration uses UDP port 8721 for Win-Test information.
Do not hardcode this fact into unrelated logic. Verify current configuration before changing listener setup or band mapping.
Changes involving 50/70 MHz, worked state or frequency mapping must be consistent with other logging inputs.
## AirScout
KST4Contest integrates with AirScout path/airplane-scatter information.
Stable principles:
- propagation/path queries must reflect the current relevant frequency/band;
- do not fall back to 144 MHz merely because older code did;
- unsupported chat categories must fail safely;
- frequency-string formatting is an external API contract and must be checked, not guessed.
Historical work included a temporary 430 MHz approximation for ambiguous higher-band handling. Treat that as historical context, not a permanent invariant. Inspect the current implementation before using or changing it.
## PSTRotator
The integration has evolved.
Historical project notes mention more than one control approach, and recent work included UDP control/feedback behaviour around a configurable control port and feedback on the next port, including SPID movement retry logic.
Therefore:
- inspect the current implementation before assuming TCP vs UDP;
- inspect current settings/defaults;
- do not copy an old port/transport assumption into new code;
- preserve asynchronous JavaFX-safe handling;
- preserve any verified retry sequence only if it still exists in current code/tests.
If current code and historical notes conflict, ask Marc after showing the conflict.
## DXCluster
DXCluster is integrated into the contest workflow.
Preserve:
- copyable/usable cluster lines;
- correct sender/receiver locator semantics;
- safe handling of missing locator data.
A historical bug copied sender and receiver locators as equal; do not reintroduce that behaviour.
## Protocol-wide error handling
External data is not trusted to be complete.
Rules:
- validate before dereferencing;
- unknown categories/bands/tags should degrade safely;
- malformed packets must not kill long-running receiver/management threads;
- logging should make the rejected input diagnosable without flooding normal operation.
@@ -0,0 +1,22 @@
# Deferred and roadmap context
This file is background only. Do not implement these items merely because they are mentioned here.
## Propagation model
After the manual audit, Marc intends to revisit and improve KST4Contest propagation modelling.
Exploration areas include:
- higher-density Copernicus GLO-30 terrain sampling;
- Fresnel-zone analysis;
- diffraction modelling;
- simplified ray tracing / multi-segment paths;
- VHF/UHF/microwave contest applicability, including around 1296 MHz and above;
- practical contest-oriented prediction rather than academic complexity for its own sake.
This requires a fresh concept before implementation.
## Rule
Roadmap context must never silently enlarge the scope of a current task.
@@ -0,0 +1,80 @@
# Settings and data context
Inspect `Config`/settings classes and current UI before using these names; this list records important settings/concepts encountered during prior work.
## Band / station settings
Important concepts have included:
- `MYQRGFirstCat`;
- `MYQRGSecondCat`;
- manual station band information;
- current/actual QTF;
- known-active bands;
- selected/current QRG.
Band-dependent features must use the correct category/station context.
## Antenna / path settings
Important concepts have included:
- `actualQTF`;
- `antennaBeamWidthDeg`;
- maximum QRB;
- AirScout/path-analysis settings.
Missing QRB/QTF must remain unknown, not numeric zero.
## UI settings
Persisted UI behaviour has included:
- dark mode;
- map/path-analysis visibility;
- filters/reachability controls;
- column visibility;
- divider/layout state where implemented.
Do not reset persisted user choices as an incidental effect of a feature change.
## Logging / worked persistence
Worked information is persisted and updated through multiple input paths.
Before changing one path, compare semantics across:
- DB load on startup;
- simple/manual log integration where present;
- UCXLog/DXLog;
- Win-Test;
- other current logging inputs.
The goal is one worked-state interpretation regardless of source.
## Chat/message automation
Configuration has included:
- beacon/autoanswer enablement;
- beacon defaults;
- message limits/timers;
- category-specific communication.
Do not duplicate timers or create per-feature scheduling that bypasses the shared safety model.
## Connection state
Connection-state UI must reflect actual ON4KST connection lifecycle.
Any new state enum/property should have a clear owner and thread boundary.
## Persistence rule
Do not change persisted keys/schema/semantics simply to make new code easier.
If a schema/key migration is required:
1. explain current and new format;
2. describe backward compatibility;
3. ask for approval before implementing.
@@ -0,0 +1,100 @@
# Build, tests, static analysis and release safety
## Maven
Use the repository Maven wrapper.
Windows:
```text
.\mvnw.cmd test
.\mvnw.cmd package
```
Run narrower tests first when possible.
## Important Surefire behaviour
The project has used:
```xml
<testFailureIgnore>true</testFailureIgnore>
```
Therefore an exit code of zero is not sufficient evidence that all tests passed.
Always inspect:
- test counts;
- failures;
- errors;
- skipped tests;
- Surefire report output when necessary.
State exact results in the completion report.
## PMD and SpotBugs
PMD and SpotBugs are integrated, but their findings have historically not always failed the build.
Do not say "static analysis clean" unless the relevant reports/output were actually checked.
## Packaging
The build contains packaging/module-list consistency logic.
Changes involving modules, JavaFX modules, jpackage or `module-info.java` must check:
- `pom.xml`;
- `packaging/` helpers;
- module requirements;
- packaging verification output.
Do not manually update only one copy of a generated/synchronized module list.
## Website
The website is Eleventy-based and has Node tests.
Inspect `website/package.json`, `website/test/` and current scripts before choosing exact commands.
Historical website validation included Node tests for generated version/update information.
## Documentation build
GitHub Actions generates documentation/PDF and site artefacts.
A local code build does not prove documentation/site CI will pass.
## Versioning
Do not change project version, semantic version, update feed, tag or release metadata unless explicitly requested.
## Git
Each of these needs separate authorization:
- stage;
- commit;
- push;
- PR;
- merge;
- tag;
- release.
When asked to commit, use a concise English commit message.
Do not stage unrelated files.
## Release communication
When a release is explicitly in scope, check:
- current changelog;
- GitHub release/tag;
- website download/update feed;
- documentation;
- HamRadioOnline download/manual destinations;
- any SourceForge publication workflow currently used.
Do not assume an older deployment pipeline is still active.
@@ -0,0 +1,73 @@
# Threading and state management
## Canonical state vs UI state
Use a thread-safe canonical state for data consumed by worker/network threads.
The active-member UI list is only a projection.
Preferred conceptual model:
```text
ConcurrentMap<MemberKey, ChatMember> activeMembers
|
| FX-thread projection/update
v
ObservableList<ChatMember> activeMembersUi
```
`MemberKey` semantics must preserve full callsign plus category unless the specific operation is intentionally base-call-wide.
## MessageBusManagementThread
Do not:
- iterate JavaFX `ObservableList` from the worker thread;
- add/remove JavaFX-list entries directly from the worker thread;
- use the FX thread as a substitute for proper domain state ownership.
Do:
- pass domain events/data to the controller/service boundary;
- modify canonical thread-safe state outside UI code as appropriate;
- project changes to JavaFX state on the FX thread.
## Controller boundary
`ChatController` is the preferred coordination boundary for UI-visible state.
Keep view-specific operations out of protocol receiver code.
## External receiver design
For receiver refactors, separate:
- socket/UDP/TCP I/O;
- parsing;
- DTO;
- domain/persistence;
- UI coordination.
## Error containment
Long-running threads must survive:
- malformed server records;
- incomplete members;
- unknown bands/categories;
- missing locators;
- null QRB/QTF;
- temporary socket failure.
Catch errors at meaningful boundaries and include enough context in English diagnostic logs/comments to trace the input and stage of failure.
Do not swallow errors silently.
## JavaFX selection/sorting
When updating backing data:
- preserve current selection where the feature expects it;
- avoid invalidating `FilteredList`/`SortedList` assumptions;
- do not create recursive UI updates;
- avoid accessing control state from worker threads.
@@ -0,0 +1,65 @@
# UI behaviour and workflow invariants
These are known user-experience decisions. Verify the current implementation before changing them.
## Selection and send text
A new station selection should prefill the established command form:
```text
/cq callsign
```
This behaviour is deliberate even when prior input text existed, according to the established workflow.
If no category is selected for sending, the established fallback is the Main category.
Do not change either behaviour as a side effect of unrelated refactoring.
## Map view
Known decisions:
- reset clears the target/station selection;
- reset does not change the current zoom level;
- selected-station information was moved toward the compact status line rather than requiring a persistent right-side detail panel;
- path-analysis visibility is user-controllable and should not become undiscoverable;
- map controls must remain usable in dark/light modes.
## Leaflet / JavaFX WebView
With Leaflet 1.9.4 under Java 21, fragmented rendering/flicker was fixed by disabling Leaflet CSS 3D transforms before Leaflet loads:
```text
window.L_DISABLE_3D = true
```
Do not remove/reorder this workaround without reproducing the rendering problem and proving the replacement.
## Filters
Known UI direction:
- Reset Filter must actually clear relevant filter predicates;
- reachability controls are conceptually separate from generic filter controls;
- reset control should remain visually discoverable;
- truncated text should remain accessible through tooltips where implemented;
- clickable links should remain functional in both themes.
## Priority / timeline
The contest workflow includes:
- priority candidate presentation;
- sked timeline;
- activity/AP windows;
- sked reminders.
Avoid UI changes that damage quick contest operation merely to make layout code simpler.
## Null display
Missing data is not `0`.
For QRB/QTF/locator/derived values, follow the current UI convention for unavailable/empty state.
Do not show a plausible-looking number when the model value is actually unknown.
@@ -0,0 +1,74 @@
---
name: kst4contest-documentation
description: Perform targeted KST4Contest documentation-impact checks and update affected German/English manuals, README, website feature text, changelog, release notes and durable project context. Avoid full audits by default; keep documentation aligned with implemented behaviour and use the praktimarc-writing-style skill.
---
# KST4Contest documentation workflow
Use `$software-project-context` and `$praktimarc-writing-style`.
## Default behaviour
Do not read the complete manual or website after every code change.
Start with a documentation-impact classification and search for the affected feature, setting, UI label, protocol/integration or operational concept.
Escalate to a broader audit only when:
- Marc explicitly requests it;
- a major release is being prepared;
- the change is broad across UI/workflows;
- multiple targeted checks reveal wider drift.
## Before editing documentation
1. Inspect the actual implementation or approved specification.
2. Explain in German what documentation is probably affected.
3. Ask only unresolved behaviour/scope questions.
4. If documentation updates are already part of an approved implementation concept, no second approval is required for obvious synchronisation.
5. If documentation reveals a new material product decision, stop and ask Marc.
## Manuals
When user-facing behaviour is affected:
- search English and German manual content under `github_docs/` for the relevant feature/labels first;
- inspect surrounding sections only;
- keep both language versions semantically equivalent;
- do not translate mechanically; English must be idiomatic;
- preserve exact UI labels, values, callsigns, ports and protocol terminology;
- document current behaviour only;
- if code and manual disagree and it is unclear which behaviour is intended, report the conflict;
- identify outdated/missing screenshots explicitly.
## README / website
Check only when the changed feature, installation, configuration, capability or compatibility is represented there or should reasonably be represented there.
- Keep feature descriptions concise.
- Explain real contest/operating benefit, not marketing slogans.
- Avoid duplicating large manual sections on the website.
- Keep the main manual/download destinations consistent with the current site strategy.
## Durable project context
Update `docs/PROJECT_CONTEXT.md` for significant:
- architectural decisions;
- threading/state ownership;
- callsign/category semantics;
- protocol/integration contracts;
- persistence/configuration changes;
- durable workarounds;
- deployment/website relationships;
- cross-project dependencies;
- planned propagation/API architecture when it becomes concrete.
Keep current-state sections current rather than using the file as a raw changelog.
## Changelog / release notes
- Compact factual bullets.
- Include user-visible changes and important reliability/compatibility fixes.
- Do not invent version scope; derive it from actual commits/changelog/release context.
- Keep release posts short and operationally relevant.
@@ -0,0 +1,7 @@
interface:
display_name: "KST4Contest Documentation"
short_description: "Keep KST4Contest manuals, website and release text aligned"
default_prompt: "Review the implemented KST4Contest behaviour, explain the documentation impact in German, propose a concept, ask questions, and wait for approval before editing."
policy:
allow_implicit_invocation: true
@@ -0,0 +1,26 @@
# User-facing feature context
This is a documentation coverage reminder, not a canonical feature list. Verify each item in current code before documenting it.
Areas repeatedly documented or changed include:
- simultaneous ON4KST chat categories;
- priority candidates;
- sked timeline/reminders;
- known active bands / B+ / NOT-QRV;
- worked indicators;
- DXCluster;
- AirScout integration;
- map/path analysis;
- filtering and reachability;
- PSTRotator/rotor integration;
- UCXLog/DXLog and Win-Test log synchronization;
- beacon/autoanswer behaviour;
- connection status/reconnect behaviour;
- dark/light UI behaviour;
- QTF/bearing workflow;
- download/update behaviour.
When one of these changes, search both language manuals and website copy for affected references.
Do not specialize documentation beyond actual behaviour. A useful example from prior work is callsign monitoring: entering an SSID-style variant can intentionally monitor the base call rather than requiring every suffix to be configured individually.
@@ -0,0 +1,47 @@
# Manual and website context
## Manual location
KST4Contest documentation is maintained in `github_docs/` with English and German Markdown pages plus screenshots.
The documentation build is automated through repository workflows.
## Audit workflow established with Marc
The normal review method is:
1. compare documentation with actual code/behaviour;
2. propose exact changes;
3. note missing/outdated screenshots and their intended repo location;
4. if code must change to match the manual, stop and confirm that code change first;
5. keep German and English content aligned;
6. prefer one thorough update over many cosmetic iterations.
With Codex editing locally, the old copy/paste insertion-guide step is replaced by direct edits, but the approval logic remains.
## Examples and easter eggs
Deliberate examples/test strings must not be "cleaned up" merely because they are informal.
A known example uses:
```text
DO5AMF
Testing DXC-Spot: Congrats, you donated $100!
```
Preserve such deliberate easter eggs unless Marc explicitly asks to remove or replace them.
## Website
The website under `website/` uses Eleventy/Nunjucks.
Style direction:
- modern and concise;
- technically focused;
- no promotional tone;
- English primary where appropriate;
- documentation remains the detailed source; website text should not duplicate entire manual sections.
Current website architecture/scripts must be inspected before changes.
@@ -0,0 +1,35 @@
# Release communications
## Changelog
Write concise English change descriptions.
Prioritize:
- behaviour users notice;
- contest workflow impact;
- protocol/integration compatibility;
- bug/reliability fixes;
- documentation improvements.
Avoid internal refactor trivia unless it materially changes reliability or maintainability relevant to the release.
## Social release post
Use `$praktimarc-writing-style`.
Typical structure:
- version;
- short statement of what the release contains;
- compact highlights;
- operational context where relevant, e.g. preparation for a VUSHF contest or planned use at DM5M;
- one clear download/manual destination.
Do not oversell.
## Download/manual direction
Marc has preferred routing users to the HamRadioOnline/KST4Contest download/manual pages rather than scattering multiple download links.
Before publishing new text, inspect the current website URLs and release setup instead of copying an old link.
@@ -0,0 +1,52 @@
---
name: kst4contest-review
description: Review current KST4Contest local changes or a proposed diff before commit. Check regressions, null safety, JavaFX threading, callsign/category semantics, band handling, protocol compatibility, tests, targeted documentation impact, durable project context and unintended scope. Report findings in German and do not modify files unless explicitly asked after the review.
---
# KST4Contest review
Review first; do not edit during the review.
Read the relevant KST4Contest change references.
## Review priorities
1. Behaviour matches the approved concept.
2. No unrelated changes.
3. Full callsign/category identity remains correct.
4. Base-call normalization is used only where intended.
5. Null/unknown values are not converted to fake defaults.
6. Worker threads do not manipulate JavaFX UI collections.
7. FX-thread boundaries are correct.
8. Protocol framing, CR/LF, XML and frequency formatting are unchanged unless explicitly intended.
9. External malformed input cannot kill long-running threads.
10. Tests cover the changed behaviour.
11. Maven test output was interpreted correctly despite ignored-failure settings.
12. A documentation-impact assessment was performed.
13. Any likely affected manual/README/website sections match the implementation.
14. `docs/PROJECT_CONTEXT.md` is updated when the change introduces a durable architectural/protocol/state/operational/integration decision.
15. Comments/Javadoc are English.
16. No unintended dependency/version/release changes.
Do not demand a full manual audit for an internal-only change when the impact assessment reasonably concludes there is no documentation effect.
## Report format
Report in German, ordered by severity.
For each finding include:
- affected file/location;
- concrete problem;
- consequence;
- recommended correction.
Then include:
- verification gaps;
- documentation-impact result;
- durable-context gaps;
- related-project gaps when relevant;
- overall assessment.
Do not fix findings until Marc explicitly asks for implementation and the normal concept gate has been satisfied for the fixes.
@@ -0,0 +1,7 @@
interface:
display_name: "KST4Contest Review"
short_description: "Review KST4Contest diffs before commit"
default_prompt: "Review the current KST4Contest changes only. Report findings in German and do not edit files."
policy:
allow_implicit_invocation: true
@@ -0,0 +1,61 @@
# Review checklist
## Scope
- Is every changed file necessary?
- Did unrelated formatting or refactoring slip in?
- Were user-authored local changes preserved?
## Architecture/threading
- Is canonical state owned outside JavaFX controls/lists?
- Does worker code avoid `ObservableList` access?
- Are UI mutations routed to the FX thread?
- Are parser/I/O/domain/UI responsibilities clearer or at least not more coupled?
## Domain
- Full callsign + category identity preserved?
- Base-call matching restricted to worked/monitoring or another explicitly approved feature?
- Unknown category/band values safe?
- NOT-QRV precedence preserved?
- Missing QRB/QTF remains unavailable rather than zero?
## Protocols
- ON4KST framing unchanged unless approved?
- CR/LF exact?
- UCX `contactreplace` compatibility preserved?
- Frequency strings verified rather than guessed?
- PSTRotator/AirScout transport/API assumptions checked against current code?
- Malformed input contained?
## UI
- Selection/focus/zoom/sorting preserved?
- `/cq callsign` prefill behaviour preserved where relevant?
- Main send-category fallback preserved where relevant?
- map WebView workaround preserved?
- null values displayed safely?
## Tests/build
- Focused regression test added or updated?
- Test summary checked?
- Ignored failures explicitly reported?
- PMD/SpotBugs output considered?
- packaging/module-list checks considered if modules changed?
## Documentation
- DE and EN manual both checked?
- website/README/changelog checked if user-visible?
- screenshot impact reported?
- writing style applied?
- no undocumented implementation or documented-but-unimplemented behaviour?
## Git/release
- No version bump unless requested?
- No generated release/update-feed changes by accident?
- No staging/commit/push without explicit authorization?
+4
View File
@@ -0,0 +1,4 @@
model_reasoning_effort = "high"
approval_policy = "on-request"
sandbox_mode = "workspace-write"
web_search = "live"
+74 -27
View File
@@ -16,8 +16,12 @@ on:
options: ["false", "true"] options: ["false", "true"]
default: "false" default: "false"
permissions:
contents: read
env: env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
AUR_SSH_DIR: /tmp/aur-ssh
jobs: jobs:
publish-aur: publish-aur:
@@ -38,6 +42,11 @@ jobs:
uses: actions/checkout@v4.1.7 uses: actions/checkout@v4.1.7
with: with:
fetch-depth: 0 fetch-depth: 0
ssh-key: ${{ secrets.WEBSITE_DEPLOY_KEY }}
- name: Mark workspace as safe Git directory
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Resolve release version - name: Resolve release version
id: ver id: ver
@@ -118,52 +127,74 @@ jobs:
cat "packaging/aur/${pkg}/.SRCINFO" cat "packaging/aur/${pkg}/.SRCINFO"
done done
- name: Commit updated PKGBUILDs to repo
if: inputs.dry_run != 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config user.name "github-actions[bot]"
git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}.git"
git add packaging/aur/
git diff --cached --quiet && echo "No PKGBUILD changes to commit." && exit 0
git commit -m "chore: update AUR packages to ${{ steps.ver.outputs.tag }} [skip ci]"
git push
- name: Set up AUR SSH - name: Set up AUR SSH
if: inputs.dry_run != 'true' if: inputs.dry_run != 'true'
env: env:
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }} AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
run: | run: |
mkdir -p ~/.ssh mkdir -p "${AUR_SSH_DIR}"
printf '%s\n' "${AUR_SSH_PRIVATE_KEY}" > ~/.ssh/aur_ed25519
chmod 600 ~/.ssh/aur_ed25519 printf '%s\n' "${AUR_SSH_PRIVATE_KEY}" \
ssh-keyscan -t ed25519 aur.archlinux.org >> ~/.ssh/known_hosts > "${AUR_SSH_DIR}/aur_ed25519"
cat >> ~/.ssh/config << 'EOF'
Host aur.archlinux.org sed -i 's/\r$//' "${AUR_SSH_DIR}/aur_ed25519"
IdentityFile ~/.ssh/aur_ed25519 chmod 600 "${AUR_SSH_DIR}/aur_ed25519"
User aur
EOF ssh-keygen -y \
-f "${AUR_SSH_DIR}/aur_ed25519" \
> /dev/null
ssh-keyscan \
-T 10 \
-t ed25519 \
aur.archlinux.org \
> "${AUR_SSH_DIR}/known_hosts"
if [ ! -s "${AUR_SSH_DIR}/known_hosts" ]; then
echo "::error::No SSH host key was received from aur.archlinux.org."
exit 1
fi
echo "Received AUR host-key fingerprint:"
ssh-keygen -lf "${AUR_SSH_DIR}/known_hosts"
if ! ssh-keygen -lf "${AUR_SSH_DIR}/known_hosts" \
| grep -Fq "SHA256:RFzBCUItH9LZS0cKB5UE6ceAYhBD5C8GeOBip8Z11+4"; then
echo "::error::The AUR SSH host-key fingerprint does not match the official fingerprint."
exit 1
fi
printf '%s\n' \
"Host aur.archlinux.org" \
" HostName aur.archlinux.org" \
" User aur" \
" IdentityFile ${AUR_SSH_DIR}/aur_ed25519" \
" IdentitiesOnly yes" \
" StrictHostKeyChecking yes" \
" UserKnownHostsFile ${AUR_SSH_DIR}/known_hosts" \
> "${AUR_SSH_DIR}/config"
chmod 600 "${AUR_SSH_DIR}/config"
chmod 600 "${AUR_SSH_DIR}/known_hosts"
- name: Push to AUR - name: Push to AUR
if: inputs.dry_run != 'true' if: inputs.dry_run != 'true'
env: env:
TAG: ${{ steps.ver.outputs.tag }} TAG: ${{ steps.ver.outputs.tag }}
GIT_SSH_COMMAND: ssh -F /tmp/aur-ssh/config
run: | run: |
git config --global user.email "philipp@wagnersnetz.de" git config --global user.email "philipp@wagnersnetz.de"
git config --global user.name "Philipp Wagner" git config --global user.name "Philipp Wagner"
mkdir -p /tmp/aur
push_to_aur() { push_to_aur() {
local pkg="$1" local pkg="$1"
local msg="$2" local msg="$2"
local aur_dir="/tmp/aur/${pkg}" local aur_dir="/tmp/aur/${pkg}"
git clone "ssh://aur@aur.archlinux.org/${pkg}.git" "${aur_dir}" 2>/dev/null || { git -c init.defaultBranch=master clone \
mkdir -p "${aur_dir}" "ssh://aur@aur.archlinux.org/${pkg}.git" "${aur_dir}"
git -C "${aur_dir}" init
git -C "${aur_dir}" remote add origin "ssh://aur@aur.archlinux.org/${pkg}.git"
}
cp "packaging/aur/${pkg}/PKGBUILD" "${aur_dir}/" cp "packaging/aur/${pkg}/PKGBUILD" "${aur_dir}/"
cp "packaging/aur/${pkg}/.SRCINFO" "${aur_dir}/" cp "packaging/aur/${pkg}/.SRCINFO" "${aur_dir}/"
@@ -179,3 +210,19 @@ jobs:
push_to_aur kst4contest "Update to ${TAG}" push_to_aur kst4contest "Update to ${TAG}"
push_to_aur kst4contest-git \ push_to_aur kst4contest-git \
"Update pkgver to $(grep '^pkgver=' packaging/aur/kst4contest-git/PKGBUILD | cut -d= -f2)" "Update pkgver to $(grep '^pkgver=' packaging/aur/kst4contest-git/PKGBUILD | cut -d= -f2)"
- name: Commit updated PKGBUILDs to repo
if: inputs.dry_run != 'true'
run: |
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config user.name "github-actions[bot]"
git add packaging/aur/
git diff --cached --quiet && echo "No PKGBUILD changes to commit." && exit 0
git commit -m "chore: update AUR packages to ${{ steps.ver.outputs.tag }} [skip ci]"
if ! git push; then
echo "::warning::PKGBUILD bookkeeping commit could not be pushed to main."
echo "The AUR packages were published; only the in-repo copy stays behind."
echo "Check that WEBSITE_DEPLOY_KEY still has write access and may bypass"
echo "the branch ruleset, or commit packaging/aur/ by hand."
fi
+180
View File
@@ -0,0 +1,180 @@
# KST4Contest agent instructions
These project instructions extend Marc's global Codex working agreements.
## Project identity
KST4Contest is a Java/JavaFX desktop client for ON4KST chat with contest-oriented workflows and integrations including logging software, AirScout, rotor control, DXCluster and local persistence.
Primary repository areas:
- `src/main/java/kst4contest/`
- `src/test/` where present;
- `github_docs/`
- `website/`
- `docs/`
- `packaging/`
- `.github/`
- `pom.xml`
Inspect the current tree before assuming an exact class/path still exists.
## Mandatory interaction rule
For every planned code or documentation implementation:
1. inspect first;
2. explain the task understanding in German;
3. identify and ask all relevant implementation questions;
4. wait for answers when needed;
5. present the final concept in German;
6. state what must remain unchanged;
7. request explicit concept approval;
8. wait;
9. implement only after approval.
If an answer is uncertain, do not interpolate it. Check current code/tests/docs/project context first and ask Marc when the uncertainty can affect behaviour.
## Language
- Communicate with Marc in German.
- Write source-code comments and Javadoc exclusively in English.
- Keep log/protocol/API literals in their canonical form.
- Commit messages are concise English when a commit is explicitly requested.
- User-facing DE/EN documentation follows `$praktimarc-writing-style`.
## Java and JavaFX architecture
- Preserve or improve separation between network/parsing/service/controller/UI responsibilities.
- Do not solve architecture problems by letting worker/model code directly manipulate JavaFX UI collections.
- Active chat-member domain state is conceptually thread-safe state; JavaFX `ObservableList` data is a UI projection, not the canonical worker-thread store.
- `MessageBusManagementThread` must not directly read or mutate the JavaFX `ObservableList` used by the UI.
- Route UI-visible mutations through the controller and the JavaFX Application Thread (`Platform.runLater` or the project's equivalent helper).
- Prefer explicit DTOs over records when introducing transport/parser DTOs in this codebase unless the approved concept says otherwise.
- Handle incomplete external/historical data defensively.
- `qrb`, QTF and related external values can be absent. `null` means unavailable, not zero.
- Unexpected input must not terminate message-processing or UI threads.
## Callsign and category identity
- Preserve full callsign variants as distinct chat-member identities where the server exposes them separately.
- Category is part of chat identity. Do not merge messages across categories.
- Base-call normalization may be used only for explicitly base-call-wide features such as worked status or monitoring rules.
- Worked status is shared across suffix variants of the same base call.
- Monitoring a callsign variant such as `DN9APW-2` or `DN9APW-70` is intended to monitor the base call `DN9APW`, so users do not need to enter every SSID.
- Do not generalize suffix semantics beyond behaviour explicitly established by the current code/specification.
## Bands and availability
- ON4KST categories 2 and 3 are central to the normal VHF/UHF workflow, but other category values can occur and must fail safely.
- Do not let unsupported categories produce exceptions.
- Known-active-band logic and `B+` interpretation must remain consistent across the application.
- Band information parsed from names/text must respect explicit `NOT-QRV` information; NOT-QRV overrides positive availability hints.
- Do not silently fall back to a fixed band/frequency when a required decision is ambiguous unless an approved fallback exists.
- Manual band settings and actual current QRG must remain consistent with features that depend on frequency.
## External protocols and integrations
Before changing ON4KST, AirScout, UCXLog/DXLog, Win-Test, PSTRotator or DXCluster handling:
- inspect the current implementation;
- preserve exact framing and compatibility;
- inspect current tests;
- check authoritative upstream documentation when the protocol detail is uncertain;
- ask Marc if more than one behaviour is plausible.
Specific invariants and historical context are in `$kst4contest-change` references.
Never change CR/LF, XML framing, callsign normalization, frequency formatting or port/transport assumptions casually.
## UI behaviour
- Preserve contest workflow speed and discoverability.
- Do not change zoom, selection, focus, sorting, tab choice or prefilled text as an incidental side effect.
- Map reset behaviour should clear the selected target without changing the zoom unless a new task explicitly changes this.
- New station selection should preserve the established `/cq callsign` prefill behaviour.
- If no send category is selected, preserve the established Main-category fallback unless explicitly changed.
- Null/unknown data must render as unavailable/empty according to current UI conventions, not as fake zero values.
## WebView / map compatibility
- The Leaflet WebView workaround that disables problematic CSS 3D transforms before Leaflet loads is a known Java 21 stability measure. Do not remove or reorder it without reproducing and understanding the original rendering/flicker problem.
## Autoanswer / beacon safety
- Prevent automated-message loops.
- Respect the established minimum interval/cooldown logic.
- Do not consume a cooldown for a reply that is rejected before a complete valid TX item is queued.
- Preserve priority of frequency/QRG requests where established.
- Cooldown identity must not accidentally collapse unrelated callsign/category identities.
- Treat the current implementation/tests as the source of truth for exact message markers and timer details.
## Build and verification
Use the Maven wrapper.
Windows:
```text
.\mvnw.cmd ...
```
Read the current `pom.xml` before relying on version numbers.
At the package creation snapshot the project uses Java 21 / JavaFX 21.x and JUnit 5/Mockito, with PMD and SpotBugs integrated.
Important: Maven/Surefire configuration has historically allowed test failures to be ignored, and static-analysis findings may not fail the build. Therefore:
- inspect the Maven test summary;
- inspect Surefire results when needed;
- do not infer "all tests passed" from exit code 0;
- report PMD/SpotBugs findings that are visible in the relevant build.
Run focused tests first, then normally the relevant broader test/build command for the scope.
## Documentation and durable project context
Use `$software-project-context`, `$kst4contest-documentation`, and `$praktimarc-writing-style` as relevant.
Do not perform a full manual or website audit after every implementation.
After a completed change:
1. perform a short documentation-impact classification;
2. if user-visible behaviour is plausibly affected, search only the relevant German and English manual sections under `github_docs/`;
3. keep both language versions semantically aligned when an update is required;
4. check README and website feature text only when the changed feature/configuration is represented there or is likely to need representation;
5. identify screenshots that are likely stale instead of fabricating replacements;
6. update `docs/PROJECT_CONTEXT.md` for significant architectural, protocol, state/persistence, operational, integration, deployment, workaround, or long-lived behavioural decisions;
7. keep `Related Projects / Integration Points` current when KST4Contest, its website, hamradioonline infrastructure or planned propagation services affect one another.
A full documentation audit is reserved for explicit audit requests, major release preparation, broad UI/workflow changes, or evidence that documentation is broadly stale.
## Website
The repository contains an Eleventy-based website under `website/` with its own tests/build logic.
Do not assume website deployment/update-feed details; inspect current scripts/workflows before changing them.
## Change scope and Git
- No unrelated refactoring.
- No production dependency without prior approval.
- No automatic version bump.
- No commit/push/merge/tag/release/deploy without separate explicit authorization.
- Preserve deliberate test data and easter eggs unless explicitly changed.
- Never overwrite unrelated working-tree changes.
## Completion
After implementation, report in German:
- understanding fulfilled;
- changed files;
- important design decisions;
- tests/builds and exact results;
- documentation-impact classification;
- manual/website/README/context updates made or why none were necessary;
- related-project impact when relevant;
- remaining uncertainty;
- suggested next action, without performing it automatically.
+159
View File
@@ -0,0 +1,159 @@
# KST4Contest Project Context
Last reviewed: 2026-08-25
This file is the durable technical project context for KST4Contest. It is not a user manual and not a replacement for the changelog. Current code, tests and authoritative external specifications remain the source of truth when this document is stale or ambiguous.
## Purpose
KST4Contest is a Java/JavaFX desktop client for ON4KST chat focused on VHF/UHF/microwave contest workflows. It combines chat handling with contest-oriented station prioritisation, sked/timeline workflows and integrations with logging, aircraft-scatter, rotor and DX-cluster tooling.
## Current Architecture
- Java 21 / JavaFX desktop application built with Maven.
- Main code is under `src/main/java/kst4contest/`.
- Responsibilities are separated across controller, service, logic, model, utility and view areas.
- Network/parser/service/controller/UI boundaries should remain explicit.
- Long-running network/message processing must tolerate malformed or incomplete external input without terminating processing threads.
- JavaFX `ObservableList` state is a UI projection, not the canonical worker-thread domain store.
## Important Invariants
### Chat identity
- Full callsign variants can be distinct chat-member identities.
- Category is part of chat identity.
- Base-call normalization is permitted only for explicitly base-call-wide functions.
- Worked status is shared across suffix variants of the same base call.
- Monitoring a variant such as `DN9APW-2` or `DN9APW-70` intentionally monitors the base call `DN9APW`.
- Suffixes must not be globally interpreted as a band/category/frequency.
### Band and availability semantics
- ON4KST categories 2 and 3 are the main operational categories, but unexpected category values must fail safely.
- `NOT-QRV` overrides positive inferred band-availability hints.
- Unknown/missing frequency, QRB, QTF or similar external data must remain unavailable rather than becoming a fabricated zero/default.
- Features that depend on frequency should use the current/actual QRG according to current implemented rules; do not silently revert to a fixed 144 MHz default.
### JavaFX/threading
Conceptually:
```text
thread-safe canonical domain state
|
| projection on JavaFX Application Thread
v
JavaFX ObservableList / UI state
```
`MessageBusManagementThread` must not directly iterate or mutate UI-bound JavaFX collections. UI-visible changes should cross the controller/UI boundary and run on the JavaFX Application Thread.
## External Interfaces
Treat current implementation/tests and authoritative upstream documentation as source of truth before modifying any interface.
Known integration areas include:
- ON4KST chat;
- AirScout;
- UCXLog / DXLog UDP XML (`contactinfo`, `contactreplace`);
- Win-Test UDP;
- PSTRotator TCP;
- DXCluster;
- local SQLite persistence.
CR/LF framing, XML framing, ports/transports, callsign normalization and frequency formatting are protocol behaviour and must not be changed as incidental cleanup.
## User Workflow / UI Invariants
- Contest operating speed and low-friction interaction are primary goals.
- Incidental code changes must not unexpectedly change selection, focus, sorting, tab state, map zoom or prefilled text.
- Map reset clears the selected target without changing zoom unless explicitly redesigned.
- Station selection preserves the established `/cq callsign` prefill behaviour.
- Sending without an explicitly selected send category preserves the established Main-category fallback unless explicitly changed.
## Autoanswer / Beacon
- Automated-message loops must be prevented.
- Cooldown/minimum-interval rules must be preserved.
- A reply rejected before a complete valid TX item is queued must not consume cooldown.
- Current implementation/tests define the exact message markers and timer details.
## Build / Verification
- Use the repository Maven wrapper (`.\mvnw.cmd` on Windows).
- The project uses Java 21 / JavaFX 21.x at this context snapshot.
- JUnit 5/Mockito, PMD and SpotBugs are part of the verification environment.
- Build/test configuration has historically allowed some test/static-analysis failures not to fail the process exit code. Always read actual summaries/reports.
## Documentation Surfaces
- German and English manuals under `github_docs/`.
- Repository README.
- Eleventy-based project website under `website/`.
- Changelog/release communication.
- This technical project context under `docs/PROJECT_CONTEXT.md`.
After implementation use targeted documentation-impact checks. Do not run a complete manual audit unless explicitly requested, release preparation is broad, or targeted checks indicate systematic drift.
## Website / Deployment Relationship
The repository contains the KST4Contest website under `website/`, published separately from the desktop application build.
Current website/deployment scripts and update-feed behaviour must be inspected before changes; do not rely on historical assumptions.
## Important Decisions and Workarounds
- Preserve full callsign/category identity while applying base-call normalisation only to specifically defined features.
- Keep canonical worker-thread domain state separate from JavaFX UI projections.
- Preserve the established JavaFX WebView/Leaflet workaround that avoids problematic CSS 3D transforms unless the original rendering/flicker issue has been reproduced and the replacement is validated.
- Deliberate test data, comments and Easter eggs are preserved unless explicitly changed.
## Planned Technical Direction
These are planned directions, not necessarily implemented behaviour:
- improve propagation/path modelling using higher-resolution terrain data, including Copernicus GLO-30;
- increase terrain/path sampling through a dedicated service/API;
- support high-precision station locations (e.g. extended Maidenhead locators or direct GPS coordinates) while preserving compatible standard display;
- improve terrain/Fresnel/diffraction/refraction modelling for VHF/UHF/microwave use;
- evaluate/implement richer tropospheric/scatter models;
- continue integration of aircraft-scatter and propagation data into reachability/contest workflows.
Before implementing planned items, re-check current decisions and obtain a fresh concept approval.
## Known Limitations / Maintenance Notes
- Historical project context is useful but may be stale; current code/tests win.
- External service/API behaviour must be verified against current upstream documentation when uncertain.
- Screenshots in manuals/website may need targeted replacement after visible UI changes; never fabricate them.
## Recent Significant Changes
### 2026-08-25 Durable project context introduced
- Added a persistent technical context layer so future agents/developers can understand architecture, invariants and cross-project dependencies without replaying chat history.
- Documentation maintenance uses targeted impact assessment rather than a full audit after every implementation.
## Related Projects / Integration Points
### KST4Contest website
- Source is maintained inside this repository under `website/`.
- User-facing feature/configuration changes may require a targeted website check.
### hamradioonline.de
- Serves as the broader amateur-radio umbrella site/infrastructure context.
- KST4Contest content/download/manual links and related knowledge content may intersect with the broader site strategy.
### Webserver / hosting infrastructure
- KST4Contest website and other hamradioonline services depend on the hosting environment.
- Operational details should be maintained in a private infrastructure context rather than duplicated into this public project context when sensitive.
### Planned propagation / terrain service
- Intended to provide richer terrain/propagation data (including higher-resolution Copernicus GLO-30-based processing) to KST4Contest and potentially related hamradioonline tooling.
- Interface contracts must be documented on both provider and consumer sides when they become concrete.
+4 -3
View File
@@ -8,10 +8,9 @@ Die veröffentlichten Stable-Versionen und ihre Programmpakete stehen unter [Git
--- ---
## v1.42 Nightly / in Entwicklung ## v1.42.0 (2026-08-22)
> Stand dieses Abschnitts: 14. August 2026. **Gemeinsamer Bandkontext, sitzungsbasierte ON4KST-Verbindung und signierte macOS-Pakete**
> v1.42 ist noch kein veröffentlichtes Stable-Release. Bis zur Freigabe können weitere Änderungen hinzukommen.
v1.42 führt mehrere bisher getrennte Auswertungen zusammen. Bandinformationen, Worked-Status, NOT-QRV-Markierungen, Rufzeichensuffixe und Frequenzen werden dadurch konsistenter in der Benutzerliste, der Stationskarte, der Prioritätsberechnung und den externen Schnittstellen verwendet. v1.42 führt mehrere bisher getrennte Auswertungen zusammen. Bandinformationen, Worked-Status, NOT-QRV-Markierungen, Rufzeichensuffixe und Frequenzen werden dadurch konsistenter in der Benutzerliste, der Stationskarte, der Prioritätsberechnung und den externen Schnittstellen verwendet.
@@ -139,6 +138,8 @@ v1.42 führt mehrere bisher getrennte Auswertungen zusammen. Bandinformationen,
- Eine genauere Konfiguration von Stationshöhe, Frequenz und K-Faktor wird in [Issue #74](https://github.com/praktimarc/kst4contest/issues/74) weiterverfolgt. - Eine genauere Konfiguration von Stationshöhe, Frequenz und K-Faktor wird in [Issue #74](https://github.com/praktimarc/kst4contest/issues/74) weiterverfolgt.
Die veröffentlichte Version ist als [Release v1.42.0](https://github.com/praktimarc/kst4contest/releases/tag/v1.42.0) verfügbar.
--- ---
## v1.41.1 (2026-07-08) ## v1.41.1 (2026-07-08)
+1 -1
View File
@@ -320,7 +320,7 @@ Für ausgewählte Stationen in der Benutzerliste gibt es direkte Buttons, um das
## Skeds und Sked-Erinnerungen ## Skeds und Sked-Erinnerungen
> Verfügbar ab v1.40; Band-, Rufzeichen- und Win-Test-Behandlung erweitert in Nightly / v1.42. > Verfügbar ab v1.40; Band-, Rufzeichen- und Win-Test-Behandlung erweitert in v1.42.
Ein Sked ist mehr als eine Erinnerung an eine Uhrzeit. Er muss während des laufenden Contestbetriebs rechtzeitig sichtbar werden, die vereinbarte Station priorisieren und sofern gewünscht die Gegenstation noch einmal an den Termin erinnern. Ein Sked ist mehr als eine Erinnerung an eine Uhrzeit. Er muss während des laufenden Contestbetriebs rechtzeitig sichtbar werden, die vereinbarte Station priorisieren und sofern gewünscht die Gegenstation noch einmal an den Termin erinnern.
+1 -1
View File
@@ -52,7 +52,7 @@ Download, unterstützte Betriebssysteme und Installationswege sind im Kapitel [I
Dieses Handbuch unterscheidet zwischen der veröffentlichten Stable-Version und dem aktuellen Entwicklungsstand. Dieses Handbuch unterscheidet zwischen der veröffentlichten Stable-Version und dem aktuellen Entwicklungsstand.
Die derzeit veröffentlichte Stable-Version ist **v1.41.1**. Funktionen oder Änderungen, die erst im Entwicklungsstand für v1.42 enthalten sind, werden ausdrücklich als **Nightly / v1.42** gekennzeichnet. Fehlt eine solche Kennzeichnung, bezieht sich die Beschreibung auf die Stable-Version. Die derzeit veröffentlichte Stable-Version ist **v1.42.0**. Funktionen oder Änderungen, die erst mit einer bestimmten Version hinzugekommen sind, werden ausdrücklich als **ab v1.42** gekennzeichnet. Funktionen, die es nur im aktuellen Entwicklungsstand gibt, sind als **Nightly** gekennzeichnet. Fehlt eine solche Kennzeichnung, bezieht sich die Beschreibung auf die Stable-Version.
- [Stable, Beta und Nightly herunterladen](https://kst4contest.hamradioonline.de/download/) - [Stable, Beta und Nightly herunterladen](https://kst4contest.hamradioonline.de/download/)
- [Veröffentlichte GitHub Releases](https://github.com/praktimarc/kst4contest/releases) - [Veröffentlichte GitHub Releases](https://github.com/praktimarc/kst4contest/releases)
+1 -1
View File
@@ -472,7 +472,7 @@ Die Eingabe darf ein sichtbares KST-Suffix oder portable Bestandteile enthalten.
Die Änderung der Liste wirkt sofort. Zum dauerhaften Speichern anschließend **Save Settings** verwenden. Die Basisrufzeichen werden in der `preferences.xml` gespeichert und beim nächsten Programmstart wiederhergestellt. Die Änderung der Liste wirkt sofort. Zum dauerhaften Speichern anschließend **Save Settings** verwenden. Die Basisrufzeichen werden in der `preferences.xml` gespeichert und beim nächsten Programmstart wiederhergestellt.
> Die Zusammenführung der KST-Suffixe über das Basisrufzeichen ist im Nightly beziehungsweise ab v1.42 enthalten. > Die Zusammenführung der KST-Suffixe über das Basisrufzeichen ist ab v1.42 enthalten.
Weitere Hintergründe und die Abgrenzung zum Nachrichtenrouting: [QSO-Monitoring](de-Funktionen#qso-monitoring-ab-v131). Weitere Hintergründe und die Abgrenzung zum Nachrichtenrouting: [QSO-Monitoring](de-Funktionen#qso-monitoring-ab-v131).
--- ---
+4 -3
View File
@@ -8,10 +8,9 @@ Published Stable versions and their application packages are available under [Gi
--- ---
## v1.42 Nightly / in development ## v1.42.0 (2026-08-22)
> Status of this section: 14 August 2026. **Shared band context, session-based ON4KST connection and signed macOS packages**
> v1.42 is not a published Stable release yet. Further changes may be added before release.
v1.42 brings several previously separate calculations together. Band information, Worked status, NOT-QRV marks, callsign suffixes and frequencies are now used more consistently by the user list, station map, priority calculation and external interfaces. v1.42 brings several previously separate calculations together. Band information, Worked status, NOT-QRV marks, callsign suffixes and frequencies are now used more consistently by the user list, station map, priority calculation and external interfaces.
@@ -137,6 +136,8 @@ v1.42 brings several previously separate calculations together. Band information
- More detailed configuration of station height, frequency and K factor is being tracked in [Issue #74](https://github.com/praktimarc/kst4contest/issues/74). - More detailed configuration of station height, frequency and K factor is being tracked in [Issue #74](https://github.com/praktimarc/kst4contest/issues/74).
The published version is available as [Release v1.42.0](https://github.com/praktimarc/kst4contest/releases/tag/v1.42.0).
--- ---
## v1.41.1 (2026-07-08) ## v1.41.1 (2026-07-08)
+1 -1
View File
@@ -874,7 +874,7 @@ The entered value may contain a visible KST suffix or portable components. KST4C
Changes to the list take effect immediately. Press **Save Settings** afterwards to retain them. The base callsigns are stored in `preferences.xml` and restored at the next program start. Changes to the list take effect immediately. Press **Save Settings** afterwards to retain them. The base callsigns are stored in `preferences.xml` and restored at the next program start.
> Base-callsign monitoring across KST suffixes is included in Nightly / v1.42. > Base-callsign monitoring across KST suffixes is included from v1.42 onwards.
Further background and the distinction from message routing: [QSO Sniffer](en-Features#qso-sniffer-from-v131). Further background and the distinction from message routing: [QSO Sniffer](en-Features#qso-sniffer-from-v131).
+1 -1
View File
@@ -234,7 +234,7 @@ For selected stations in the user list, there are direct buttons to open the **Q
## Skeds and Sked Reminders ## Skeds and Sked Reminders
> Available from v1.40; band, callsign and Win-Test handling extended in Nightly / v1.42. > Available from v1.40; band, callsign and Win-Test handling extended in v1.42.
A sked is more than a reminder tied to a particular time. During a contest, it must become visible early enough, move the agreed station up the priority list and if required remind the remote station as well. A sked is more than a reminder tied to a particular time. During a contest, it must become visible early enough, move the agreed station up the priority list and if required remind the remote station as well.
+301 -66
View File
@@ -4,21 +4,63 @@
## Connecting to the Chat ## Connecting to the Chat
1. Select a **chat category** in the settings window (e.g. 144 MHz VHF, 432 MHz UHF, …). Before connecting for the first time, configure at least the callsign, password, locator and primary chat category in the settings window. If a second category is required, its login must also be enabled and configured completely.
2. Click the **Connect** button.
3. Wait for the connection to be established.
> Disconnecting and reconnecting is only possible via the settings window. It is therefore recommended to keep the settings window open. The connection can be started in two ways:
- **Connect to …** in the settings window applies the values currently entered there and starts the connection.
- **File → Connect to …** uses the settings already applied in KST4Contest.
Use **Save Settings** if changed values should also be available after the next programme start.
An active connection can be terminated using **File → Disconnect** or **Disconnect** in the settings window. **Exit + disconnect** terminates the connection and then closes the programme.
If an established connection is lost unexpectedly, KST4Contest waits for a limited period and then attempts a controlled reconnect to ON4KST. A failed initial connection attempt no longer blocks the user interface.
The [`LINK` indicator](#status-bar-and-indicators) in the main window shows whether only the TCP connection exists or whether login and synchronisation have actually been completed.
--- ---
## Main Window Overview ## Main Window Overview
The main window consists of several areas: The main window consists of several areas:
### Status Bar and Indicators
The status bar is located at the top of the main window next to the menu.
<!-- TODO: Screenshot connection_status_indicator.png is missing from the repository. Uncomment the image after the file has been added to github_docs/.
![Status bar with ON4KST connection indicator](connection_status_indicator.png)
-->
The permanently visible `LINK` indicator shows the actual state of the ON4KST connection:
| Indicator | Meaning |
|---|---|
| green `LINK` | Login and synchronisation of all configured chat categories have been completed |
| yellow `LINK…` | Connection, login, user-list synchronisation or controlled shutdown is in progress |
| red `LINK!` | No connection exists, or KST4Contest is waiting before an automatic reconnect |
The tooltip contains the internal connection state and a more detailed description of the current step. The indicator is not a button.
KST4Contest reports `ONLINE` only after login has been confirmed and the user lists of all configured categories have been received. The send field and **TX** remain disabled while the connection is still being established or resynchronised.
Additional indicators appear temporarily after certain events:
- `SKED` indicates that a sked reminder is due. The text contains the complete target callsign and the remaining time.
- `BAND+` appears after a log entry if at least one common, locally enabled and unworked band has been detected for the worked station.
Both indicators flash for approximately twelve seconds and then disappear. Their tooltip contains the complete message or derivation. Neither indicator is clickable.
### PM Window (top left) ### PM Window (top left)
Shows all received **private messages** as well as intercepted public messages containing your own callsign. New messages appear in **red** and fade every 30 seconds from yellow to white. The PM window shows private messages addressed to the local chat logins and the corresponding outgoing replies.
If [QSO Monitoring](en-Features#qso-sniffer-from-v131) is enabled, it additionally shows captured messages involving the monitored base callsigns. These entries receive a `Sniffed:` prefix containing the complete visible sender and receiver callsigns.
New messages are initially highlighted and then gradually return to the normal table colour. This highlighting only indicates the age of the message; it does not change its content or routing.
### User List (Chat Members) ### User List (Chat Members)
@@ -40,6 +82,11 @@ The central table of all currently active chat users. Columns (depending on conf
| NOT QRV @ | Bands on which the station has manually been marked not QRV | | NOT QRV @ | Bands on which the station has manually been marked not QRV |
| Category | Chat category of this entry | | Category | Chat category of this entry |
The QRG column shows the frequency most recently detected for a station. Missing trailing zeros are added for display purposes, so `144.21`, for example, is shown as `144.210`. If KST4Contest detects frequencies on several bands in succession, the column shows the latest match. The internal band information may still contain several current bands for that station.
Relative frequency information is first combined with a band context from the same sender which is no more than 30 minutes old. Only if no such context exists does KST4Contest use the global fallback band. Detection rules, examples and limitations: [QRG Detection](en-Features#qrg-detection-qrg-reading).
### Worked, band and grid-square status ### Worked, band and grid-square status
The subcolumns under **worked** use compact codes because several enabled bands leave little room for full descriptions. `X` marks a callsign worked on that band. `a` and `B+` identify an offered band which has not yet been worked. An appended `o` means that the four-character grid square has already been worked on this band. The subcolumns under **worked** use compact codes because several enabled bands leave little room for full descriptions. `X` marks a callsign worked on that band. `a` and `B+` identify an offered band which has not yet been worked. An appended `o` means that the four-character grid square has already been worked on this band.
@@ -52,39 +99,139 @@ Each status cell has a tooltip containing the legend and the state derived for t
**Sorting**: Click column headers. QRB sorting is numerical (corrected in v1.22). **Sorting**: Click column headers. QRB sorting is numerical (corrected in v1.22).
A callsign displayed in green and bold indicates a directional opportunity derived from a directed message. The marker applies to the sender of that message and remains visible for no more than five minutes. Derivation and limitations: [Directional Opportunities from Directed Messages](en-Features#directional-opportunities-from-directed-messages).
### Send Field ### Send Field
Text input for outgoing messages. After clicking a callsign in the user list, the send field automatically receives focus start typing immediately without double-clicking (from v1.22). The send field contains the prepared text for the next outgoing message.
### MYQRG Field When an operator deliberately selects a station in the user list using the mouse or keyboard, KST4Contest prepares a directed message:
To the right of the send button. Shows the current own QRG, can also be entered manually. ```text
/cq CALLSIGN
```
### MYQTF Field *(for v1.3)* The complete visible callsign, including any suffix, and the chat category of the selected station are retained. A target such as `9A0BB-70` is not shortened to `9A0BB`.
Input field for the current antenna direction. Used for the planned `MYQTF` variable. A background refresh, changed sorting order or filter update must not overwrite message text which has already been edited. Only an actual station selection by the operator prepares the `/cq` recipient again.
- **TX** or `Enter` sends the prepared text.
- `Esc` clears the send field.
- The send field and **TX** remain disabled until KST4Contest is fully connected to ON4KST.
Shortcuts, snippets and variables are described under [Macros and Variables](en-Macros-and-Variables).
### MYQRG and SECONDQRG Fields
The two QRG fields contain the local frequencies for the primary and secondary chat categories.
`MYQRG` can be updated by an enabled TRX synchronisation interface or entered manually when no automatic QRG source is active. `SECONDQRG` remains independent and contains the frequency used for the second category.
Selecting a station from the second chat does not change the meaning of these values: `MYQRG` continues to belong to the primary category and `SECONDQRG` to the secondary category.
Further details: [TRX Sync Settings](en-Configuration#trx-sync-settings).
### MYQTF Field
The MYQTF field shows the current antenna direction as a numerical angle in degrees.
If PSTRotator is enabled, the value is received automatically and the field cannot be edited manually. Without active rotator synchronisation, the antenna direction can be entered directly. The changed value is applied when the field loses focus.
The value affects, among other things:
- QTF filtering,
- the antenna-sector display on the station map,
- priority-score calculation,
- the AP timeline, and
- the `MYQTF` variable.
--- ---
## Filters ## Message Tables
The filter bar is located above the chat-member table and groups related controls: KST4Contest deliberately displays message text on a single line. This keeps a larger number of entries visible when chat activity is high. The disadvantage is obvious: if the **Message** column is narrow, not every message fits completely into its cell.
- **Show only QTF** limits the list to a selected antenna direction. If the message text is wider than the visible cell, moving the mouse over that **Message** cell displays the complete content in a tooltip. No additional full-text tooltip is shown if the message already fits into the column.
- **Show only QRB [km] <=** sets a maximum distance.
- **Find** searches for a callsign.
- **wkd** hides callsigns which have already been worked on at least one band.
- The individual band buttons hide a station if it has already been worked on that band or has been marked NOT QRV there. Only bands enabled for the local station are shown.
- **Only new grids** shows only stations in four-character grid squares which have not been worked on any band.
- **Grid color** is not a filter. It marks the QRA cell of an already worked grid square without hiding stations.
- **New bands** shows stations with at least one detected, locally enabled and unworked band opportunity. NOT-QRV marks take precedence.
- **Reachability**, **Tropo >=0dB** and **AS next 5m** limit the list according to the selected path or AirScout criteria.
The filter bar has no fixed width. QTF, Worked and Reachability controls initially use the available space in their respective rows. When the horizontal divider is moved to the right and the chat-member area becomes narrower, controls wrap only when their actual required width no longer fits. Web addresses beginning with `http://`, `https://` or `www.` are displayed as links inside the message text. Clicking a link opens it in the operating systems default browser. Other protocols are not treated as links.
![Truncated message text with full-text tooltip and clickable link](message_tooltip_and_link.png)
This avoids having to move the divider merely to read an individual long message. The divider can, of course, still be adjusted if a permanently wider message area is required.
---
## Filters and Reachability Controls
The filter bar is located above the chat-member table. Filters can be combined; a station remains visible only if it satisfies every active condition.
![Wrapped filter bar in a narrow chat-member view](filter_bar_wrapped.png) ![Wrapped filter bar in a narrow chat-member view](filter_bar_wrapped.png)
In plain terms: the filters determine the table contents, but no longer enforce the minimum width of the entire right-hand side. The bar remains compact in the normal layout and uses additional height only when the view becomes genuinely narrow. Moving the divider back to the left immediately returns the controls to the available rows. ### Station Filters
| Control | Effect |
|---|---|
| **Show only QTF** | Shows only stations inside the selected antenna direction and configured beamwidth |
| **Show only QRB [km] <=** | Limits the list to the entered maximum distance |
| **Find** | Filters by a complete or partial callsign |
| **wkd** | Hides base callsigns already worked on at least one supported band |
| individual band buttons | Hide stations already worked on that band or marked NOT QRV there |
| **Inactive stations** | Hides stations whose latest chat activity was more than 20 minutes ago |
| **Only new grids** | Shows only stations in four-character grid squares not yet worked on any band |
| **New bands** | Shows stations with at least one detected, locally enabled and unworked band opportunity |
| **Tropo >=0dB** | Shows stations with a calculated non-negative SSB margin |
| **AS next 5m** | Shows stations with a current AirScout window or one expected within the next five minutes |
For **New bands**, KST4Contest evaluates current QRGs, band information in the name field and active callsign variants together. Manual NOT-QRV marks take precedence.
The **Tropo >=0dB** filter removes only stations for which a completed calculation returned a negative margin. Stations with pending or failed calculations remain visible. Otherwise, a missing API result would incorrectly be treated as proof that the path is unsuitable.
### Grid Color
**Grid color** is not a filter. It only changes the presentation of the QRA cell and marks four-character grid squares which have already been worked.
The station remains visible regardless of this colour marker. **Reset filters** therefore does not disable **Grid color**.
### Reachability and Calc Selected
The **Reachability** dropdown selects the band used by the Tropo column, the Tropo filter and an explicitly requested path calculation.
- **Auto** derives the band from the stations current QRG, band information in its name field and the supported chat category.
- An explicitly selected band overrides this automatic choice for the Reachability calculation.
Changing the dropdown does not start a calculation for the entire user list. With an online elevation-data source, that would be unnecessarily slow and multiply the number of external API requests.
**Calc selected** calculates only the currently selected station, using either the explicitly selected or automatically derived band. The result is then used by the Tropo column and the associated views.
### Resetting the Filters
**Reset filters** clears:
- the QTF filter,
- the QRB filter,
- the callsign search field,
- all Worked and band filters,
- **Inactive stations**,
- **Only new grids**,
- **New bands**,
- **Tropo >=0dB**, and
- **AS next 5m**.
The internal filter predicates are explicitly cleared as well. Resetting only the visible toggle buttons would not be sufficient.
The following settings are retained:
- **Grid color**, because it is a display option, and
- the **Reachability** selection, because it selects the calculation band rather than directly filtering the table.
### Behaviour in a Narrow View
The filter bar has no fixed width. QTF, Worked and Reachability controls initially use the available space in their respective rows.
When the middle divider is moved to the right and the chat-member area becomes narrower, controls wrap only when their actual required width no longer fits. Widening the area causes them to rearrange immediately.
In plain terms: the filters determine the table contents, but no longer enforce the minimum width of the entire right-hand side.
--- ---
@@ -158,74 +305,148 @@ Calculation and limitations: [Priority Score and Priority List](en-Features#prio
## Station Map ## Station Map
The station map is opened or closed through: The station map can be opened in two ways:
**Windows → Show / hide station map** - **Windows → Show / hide station map** opens or closes the map window.
- **Show on map** in the **Further Info** panel opens the map and focuses the selected station.
The window uses the chat members currently visible in the filtered user list. Changing the QRB, QTF, Worked, band or Reachability filters can therefore also change the stations shown on the map. The map uses the stations which remain visible after applying the current user-list filters. Its header shows the number of displayed stations and indicates a filtered view with `filtered view active`.
A station can additionally be opened directly from the **Further Info** panel using **Show on map**. This selects the station on the map and requests the associated path analysis. ![Station map with a selected station and visible path analysis](station_map_path_analysis.png)
Stations with the same normalised base callsign and position are combined into one marker. At lower zoom levels, nearby markers may additionally be displayed as clusters. These are display groups only; the individual chat logins remain separate message targets inside KST4Contest. ### Selecting a Station
Clicking a station marker: A single station marker can be selected directly. KST4Contest then:
1. selects the corresponding chat member, 1. selects the corresponding chat member,
2. scrolls the main user list to that entry, 2. scrolls the main user list to that entry,
3. updates the **Further Info** panel, and 3. updates the **Further Info** panel, and
4. prepares the complete visible callsign as the message target. 4. prepares the complete visible callsign as the `/cq` recipient.
The map details for the selected station include its locator, QRB, QTF, detected bands and available band opportunities. **Trigger cluster spot** sends a spot through the built-in local DX Cluster server so that connected logging software can receive the selected station and QRG. Chat logins with the same normalised base callsign and position may share one marker. They nevertheless remain separate message targets inside KST4Contest.
The path-analysis section shows the terrain profile and the calculated route between both stations. Depending on the available data, it includes: Markers which are too close together at the current zoom level are displayed as a cluster containing the number of stations. Clicking the cluster zooms into that area. A concrete station is selected only after an individual marker becomes visible and is clicked.
For a selected station, the header additionally shows:
- the complete callsign,
- locator,
- QRB and QTF,
- detected active bands,
- any available `B+` band opportunity, and
- the most recently known QRGs.
Long header content is shortened. The complete text remains available in its tooltip.
### Clearing the Selection with Reset View
**Reset view** clears the selected station without changing the map position or zoom level.
It:
- clears the selected station,
- clears the selection in the main user list,
- removes the connection line to the remote station,
- discards a pending analysis for the previous station, and
- removes the right-hand analysis panel.
The map itself remains at the previously selected position and zoom level. This function is therefore not a geographical reset to the local station.
<!-- TODO: Screenshot station_map_reset.png is missing from the repository. Uncomment the image after the file has been added to github_docs/.
![Station map after Reset view without a selected station](station_map_reset.png)
-->
Selecting another individual marker restores the station selection and analysis panel.
### Triggering a DX Cluster Spot
**Trigger cluster spot** is visible only while a station is selected. It sends one spot to logging programmes connected to the built-in local DX Cluster server.
This requires:
- the local DX Cluster server to be enabled,
- at least one connected cluster client, and
- a usable QRG for the selected station.
The spot is not sent to a public Internet cluster.
### Path Analysis
The terrain profile is displayed below the map. The right-hand analysis panel includes, among other things:
- the data source and number of elevation samples,
- the analysis frequency, - the analysis frequency,
- line-of-sight and horizon information, - the Earth-curvature or refraction model,
- radio and terrain horizons,
- Fresnel-zone clearance, - Fresnel-zone clearance,
- detected obstructions, - detected obstructions,
- an estimated link budget, - the link budget,
- received power and SSB margin, and - estimated received power, and
- a short assessment of the path. - a summarised path assessment.
Moving the mouse over the terrain profile highlights the corresponding geographical position on the map. The analysis uses the same centrally derived band as the Reachability functions. A band explicitly selected in the **Reachability** dropdown is taken into account.
The analysis can be hidden using **Hide path analysis** when more space is required for the map. The compact state displays **Path analysis is hidden.** together with the **Show path analysis** button. These values remain technical estimates. Buildings, vegetation, local obstructions, current propagation conditions and unknown station parameters may substantially change the real result.
### Hiding the Path Analysis
**Hide path analysis** hides both the terrain profile and the right-hand analysis panel, leaving more space for the map.
![Station map with hidden path analysis](station_map_compact.png) ![Station map with hidden path analysis](station_map_compact.png)
The selected station and map contents remain available while the analysis panel is hidden. The setting is stored and restored at the next start. The **Path analysis is hidden** message and **Show path analysis** button remain visible, so the function can be restored directly.
Calculation method and limitations: [Station Map and Path Analysis](en-Features#station-map-and-path-analysis-from-v141). If no station is selected when the analysis is shown again, no empty right-hand panel is displayed. It is recreated only after a specific station has been selected.
The setting is stored and restored at the next programme start.
The divider between the map and detail panel can be moved horizontally. Longer values wrap in a narrow detail panel; a vertical scrollbar appears if the available height is insufficient.
Detailed derivation and limitations: [Station Map and Path Analysis](en-Features#station-map-and-path-analysis-from-v141).
--- ---
## Global Message Tabs and Monitor Window ## Global Message Tabs and Monitor Window
Three global message tabs are located below the main user list. Unlike the **Further Info** panel, their contents do not depend on the station currently selected. The lower part of the main window contains three global message tabs. Their contents do not depend on the station currently selected in the user list.
| Tab | Displayed messages | | Tab | Content |
|---|---| |---|---|
| **Public messages** | All public chat messages, including CQ calls and beacons | | **Public messages** | Public chat messages, CQ calls and beacons |
| **DXCluster messages** | DX cluster messages received from the ON4KST server | | **DXCluster messages** | DX cluster messages received through ON4KST |
| **QSO of the other** | Directed messages between chat logins other than the local station | | **QSO of the other** | Directed messages between two other stations |
The **Public messages** tab is selected by default. ![Global message tabs in the main window](global_message_tabs.png)
![Global message tabs below the main user list](global_message_tabs.png) In **QSO of the other**, sender and receiver are displayed separately. **Last QRG TX** and **Last QRG RX** contain the frequencies most recently known for the two stations. They do not necessarily represent the frequency discussed in the displayed conversation.
The **DXCluster messages** table contains the time, reporting and reported stations, locators, QRG, message text and global Worked state where these values are available in the received message. **wkd TX?** and **wkd RX?** show the global Worked state of the two base callsigns. These values are not band-specific.
The **QSO of the other** table contains: The **DXCluster messages** tab shows the reporting and reported stations, their locators, QRG, message text and the global Worked state of the reported station. Which fields are actually available depends on the message received from the ON4KST server.
- the complete sender and receiver callsigns, Message text remains on one line. If a cell is too narrow, its complete content is available in a tooltip. Web addresses in the message text are clickable.
- the latest QRG currently known for each station,
- the global Worked state of each station,
- the message text, and
- the chat category.
The displayed QRG is not necessarily the frequency on which the stations intend to make a contact. It is the latest QRG currently associated with the respective chat member. The Worked state is global and not specific to the displayed QRG or band. ### Separate Monitor Window
KST4Contest additionally opens the **Cluster & QSO of the other** window. It shows DX cluster messages in the upper table and directed messages between other stations in the lower table.
![Separate monitor window for DX cluster traffic and directed messages between other stations](cluster_qso_monitor.png)
The vertical divider position and window size are stored together with the other UI settings. Use **Save Settings** after changing them.
The window can be hidden and restored through:
```text
Windows → Hide cluster / stranger QSOs
Windows → Show cluster / stranger QSOs
```
The main-window tabs and separate monitor window use the same underlying data. Hiding the monitor window therefore neither stops message processing nor removes messages from the tabs.
Derivation and limitations: [Global Message Views](en-Features#global-message-views).
---
A directed chat message in this table does not prove that a radio QSO has taken place. The table also contains sked requests, frequency exchanges and other directed messages between third-party chat logins.
### Separate monitor window ### Separate monitor window
@@ -243,14 +464,29 @@ If a message is too long for its table cell, moving the mouse over the cell disp
## Menu ## Menu
### File
- **Connect to …** starts the connection using the settings already applied in KST4Contest.
- **Disconnect** terminates the current ON4KST connection without closing KST4Contest.
- **Exit + disconnect** terminates the connection and then closes the programme.
The Connect and Disconnect entries are enabled or disabled according to the current connection state.
### Options
- **Set QRG as name in Chat (main category)** sends `/SETNAME` containing the current `MYQRG` to the primary chat category.
- **Show me as away in chat** sends `/AWAY`.
- **Show me as active in chat** sends `/BACK`.
- **Show options** shows or hides the settings window.
Functions which communicate with the server are available only after the ON4KST connection has been established completely.
### Windows ### Windows
- **Hide cluster / stranger QSOs** hides the separate monitor window for DX cluster messages and directed messages between other stations. - **Hide cluster / stranger QSOs** and **Show cluster / stranger QSOs** hide or restore the separate cluster and QSO monitor window.
- **Show cluster / stranger QSOs** restores the monitor window. - **hide options** and **show options** hide or restore the settings window.
- **hide options** hides the settings window.
- **show options** restores the settings window.
- **Use dark mode design** activates the dark colour scheme. - **Use dark mode design** activates the dark colour scheme.
- **Use default mode design** restores the default colour scheme. - **Use default mode design** restores the standard light colour scheme.
- **Show / hide station map** opens or closes the separate station-map and path-analysis window. - **Show / hide station map** opens or closes the separate station-map and path-analysis window.
--- ---
@@ -270,8 +506,7 @@ If the layout has become inconvenient, first move the dividers back to usable po
## Operating Tips ## Operating Tips
- **Keep the settings window open**: Quick access to enable/disable the beacon. - **Keep the settings window open**: This provides quick access to the beacon controls.
- **Right-click in the user list**: Opens the snippet menu and other context actions. - **Right-click in the user list**: Opens the snippet menu and additional actions, including QRZ.com profiles and NOT-QRV marks.
- **Mark a station NOT QRV**: Select the station and use the per-band controls in the **Further Info** panel. - **Press Enter while working in the chat**: If the send field contains text, Enter sends it directly even when another control has focus.
- **Enter from anywhere**: When text is in the send field, Enter sends directly even if the focus is elsewhere. - **Stop the beacon while scanning**: Disable the beacon while moving through frequencies to avoid flooding the chat with unnecessary messages.
- **Stop the beacon**: Switch off the beacon while scanning frequencies to avoid flooding the chat with messages.
+3 -3
View File
@@ -1,6 +1,6 @@
pkgbase = kst4contest-bin pkgbase = kst4contest-bin
pkgdesc = ON4KST Chat Client for VHF/UHF contest operation (pre-built) pkgdesc = ON4KST Chat Client for VHF/UHF contest operation (pre-built)
pkgver = 1.41.1 pkgver = 1.42.0
pkgrel = 1 pkgrel = 1
url = https://github.com/praktimarc/kst4contest url = https://github.com/praktimarc/kst4contest
arch = x86_64 arch = x86_64
@@ -10,7 +10,7 @@ pkgbase = kst4contest-bin
provides = kst4contest provides = kst4contest
conflicts = kst4contest conflicts = kst4contest
conflicts = kst4contest-git conflicts = kst4contest-git
source = KST4Contest-v1.41.1-archlinux-x86_64.pkg.tar.zst::https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-archlinux-x86_64.pkg.tar.zst source = KST4Contest-v1.42.0-archlinux-x86_64.pkg.tar.zst::https://github.com/praktimarc/kst4contest/releases/download/v1.42.0/KST4Contest-v1.42.0-archlinux-x86_64.pkg.tar.zst
sha256sums = 8e9a53ff832920c9ef2733635b90c5a4ffcd57a2958aaa251e92bd031142c614 sha256sums = 3d8ac19c9f9d3ab0bdaf0ea621de0aa18c64f442c8776d28bfad607522aaf02b
pkgname = kst4contest-bin pkgname = kst4contest-bin
+2 -2
View File
@@ -1,6 +1,6 @@
# Maintainer: Philipp Wagner <philipp@wagnersnetz.de> # Maintainer: Philipp Wagner <philipp@wagnersnetz.de>
pkgname=kst4contest-bin pkgname=kst4contest-bin
pkgver=1.41.1 pkgver=1.42.0
pkgrel=1 pkgrel=1
pkgdesc="ON4KST Chat Client for VHF/UHF contest operation (pre-built)" pkgdesc="ON4KST Chat Client for VHF/UHF contest operation (pre-built)"
arch=('x86_64') arch=('x86_64')
@@ -10,7 +10,7 @@ depends=('gst-plugins-base' 'gst-plugins-good')
provides=('kst4contest') provides=('kst4contest')
conflicts=('kst4contest' 'kst4contest-git') conflicts=('kst4contest' 'kst4contest-git')
source=("KST4Contest-v${pkgver}-archlinux-${CARCH}.pkg.tar.zst::https://github.com/praktimarc/kst4contest/releases/download/v${pkgver}/KST4Contest-v${pkgver}-archlinux-${CARCH}.pkg.tar.zst") source=("KST4Contest-v${pkgver}-archlinux-${CARCH}.pkg.tar.zst::https://github.com/praktimarc/kst4contest/releases/download/v${pkgver}/KST4Contest-v${pkgver}-archlinux-${CARCH}.pkg.tar.zst")
sha256sums=('8e9a53ff832920c9ef2733635b90c5a4ffcd57a2958aaa251e92bd031142c614') sha256sums=('3d8ac19c9f9d3ab0bdaf0ea621de0aa18c64f442c8776d28bfad607522aaf02b')
package() { package() {
cp -a "${srcdir}/usr" "${pkgdir}/" cp -a "${srcdir}/usr" "${pkgdir}/"
+1 -1
View File
@@ -1,6 +1,6 @@
pkgbase = kst4contest-git pkgbase = kst4contest-git
pkgdesc = ON4KST Chat Client for VHF/UHF contest operation (git) pkgdesc = ON4KST Chat Client for VHF/UHF contest operation (git)
pkgver = 1.42.0.r145.gd885924 pkgver = 1.42.0.r256.g8aadbb9
pkgrel = 1 pkgrel = 1
url = https://github.com/praktimarc/kst4contest url = https://github.com/praktimarc/kst4contest
arch = x86_64 arch = x86_64
+1 -1
View File
@@ -1,6 +1,6 @@
# Maintainer: Philipp Wagner <philipp@wagnersnetz.de> # Maintainer: Philipp Wagner <philipp@wagnersnetz.de>
pkgname=kst4contest-git pkgname=kst4contest-git
pkgver=1.42.0.r145.gd885924 pkgver=1.42.0.r256.g8aadbb9
pkgrel=1 pkgrel=1
pkgdesc="ON4KST Chat Client for VHF/UHF contest operation (git)" pkgdesc="ON4KST Chat Client for VHF/UHF contest operation (git)"
arch=('x86_64') arch=('x86_64')
+4 -4
View File
@@ -1,7 +1,7 @@
pkgbase = kst4contest pkgbase = kst4contest
pkgdesc = ON4KST Chat Client for VHF/UHF contest operation pkgdesc = ON4KST Chat Client for VHF/UHF contest operation
pkgver = 1.41.1 pkgver = 1.42.0
pkgrel = 2 pkgrel = 1
url = https://github.com/praktimarc/kst4contest url = https://github.com/praktimarc/kst4contest
arch = x86_64 arch = x86_64
license = GPL-3.0-only license = GPL-3.0-only
@@ -12,7 +12,7 @@ pkgbase = kst4contest
provides = kst4contest provides = kst4contest
conflicts = kst4contest-bin conflicts = kst4contest-bin
conflicts = kst4contest-git conflicts = kst4contest-git
source = kst4contest-1.41.1.tar.gz::https://github.com/praktimarc/kst4contest/archive/refs/tags/v1.41.1.tar.gz source = kst4contest-1.42.0.tar.gz::https://github.com/praktimarc/kst4contest/archive/refs/tags/v1.42.0.tar.gz
sha256sums = e96207a2d3fee19d35e34717f5312beb28bb087c040164e352337e749ce53b8d sha256sums = bd396387b8de41aac706458d5ebf64140ab3e83b8a7c710b66aa802bd48e804e
pkgname = kst4contest pkgname = kst4contest
+3 -3
View File
@@ -1,7 +1,7 @@
# Maintainer: Philipp Wagner <philipp@wagnersnetz.de> # Maintainer: Philipp Wagner <philipp@wagnersnetz.de>
pkgname=kst4contest pkgname=kst4contest
pkgver=1.41.1 pkgver=1.42.0
pkgrel=2 pkgrel=1
pkgdesc="ON4KST Chat Client for VHF/UHF contest operation" pkgdesc="ON4KST Chat Client for VHF/UHF contest operation"
arch=('x86_64') arch=('x86_64')
url="https://github.com/praktimarc/kst4contest" url="https://github.com/praktimarc/kst4contest"
@@ -11,7 +11,7 @@ makedepends=('java-environment=21' 'maven')
provides=('kst4contest') provides=('kst4contest')
conflicts=('kst4contest-bin' 'kst4contest-git') conflicts=('kst4contest-bin' 'kst4contest-git')
source=("${pkgname}-${pkgver}.tar.gz::https://github.com/praktimarc/kst4contest/archive/refs/tags/v${pkgver}.tar.gz") source=("${pkgname}-${pkgver}.tar.gz::https://github.com/praktimarc/kst4contest/archive/refs/tags/v${pkgver}.tar.gz")
sha256sums=('e96207a2d3fee19d35e34717f5312beb28bb087c040164e352337e749ce53b8d') sha256sums=('bd396387b8de41aac706458d5ebf64140ab3e83b8a7c710b66aa802bd48e804e')
build() { build() {
cd "${srcdir}/kst4contest-${pkgver}" cd "${srcdir}/kst4contest-${pkgver}"
+2 -2
View File
@@ -50,7 +50,7 @@ KST4Contest also updates the AirScout watchlist. Stations which are no longer ac
## How is the AirScout band selected? ## How is the AirScout band selected?
> Automatic station-specific band selection is included in Nightly / v1.42. A fixed configured AirScout band remains available as a manual fallback. > Automatic station-specific band selection is included from v1.42 onwards. A fixed configured AirScout band remains available as a manual fallback.
In **Auto per station** mode, KST4Contest uses the same propagation-frequency resolver as the internal path analysis. The sources are evaluated in the following order: In **Auto per station** mode, KST4Contest uses the same propagation-frequency resolver as the internal path analysis. The sources are evaluated in the following order:
@@ -138,7 +138,7 @@ Each KST4Contest instance should use a distinct client identifier. Incoming AirS
This keeps a reply for one operating position from being assigned to another client merely because both listen on the same UDP network. This keeps a reply for one operating position from being assigned to another client merely because both listen on the same UDP network.
> Strict reply filtering by the configured client/server pair is included in Nightly / v1.42. > Strict reply filtering by the configured client/server pair is included from v1.42 onwards.
## AP variables in messages ## AP variables in messages
+1 -1
View File
@@ -66,7 +66,7 @@ All four entries belong to the same base callsign, but they are four different c
This is particularly important for `9A0BB-2` and `9A0BB-70`: because both use the same category, the category alone cannot distinguish them. This is particularly important for `9A0BB-2` and `9A0BB-70`: because both use the same category, the category alone cannot distinguish them.
> Correct separation of several suffix variants within the same category is included in Nightly / v1.42 and fixes [Issue #73](https://github.com/praktimarc/kst4contest/issues/73). > Correct separation of several suffix variants within the same category is included from v1.42 onwards and fixes [Issue #73](https://github.com/praktimarc/kst4contest/issues/73).
## How are messages routed? ## How are messages routed?
+1 -1
View File
@@ -141,7 +141,7 @@ JN49GL , AP: 1min, 100%; 4min, 75%
AirScout information is optional. A missing AirScout response does not prevent the spot from being sent. AirScout information is optional. A missing AirScout response does not prevent the spot from being sent.
> AP-independent spot creation, corrected sender-locator handling and band-generic frequency conversion are included in Nightly / v1.42. > AP-independent spot creation, corrected sender-locator handling and band-generic frequency conversion are included from v1.42 onwards.
## Connecting a logger ## Connecting a logger
+1 -1
View File
@@ -48,7 +48,7 @@ STATUS packets can also update the local QRG. In multi-operator networks, a stat
Win-Test can additionally receive skeds created in KST4Contest. The handover only takes place when a QRG matching the selected band can be determined. No fixed fallback frequency is inserted merely to make the packet technically valid. Win-Test can additionally receive skeds created in KST4Contest. The handover only takes place when a QRG matching the selected band can be determined. No fixed fallback frequency is inserted merely to make the packet technically valid.
> The band-aware sked handover and explicit `SSB`/`CW` selection are included in Nightly / v1.42. > The band-aware sked handover and explicit `SSB`/`CW` selection are included from v1.42 onwards.
## Stored state and limitations ## Stored state and limitations
+1 -1
View File
@@ -299,7 +299,7 @@ The priority list is calculated from the active station model and is independent
Selecting such a candidate still updates Further Info and prepares the directed message. The active filter remains unchanged. Selecting such a candidate still updates Further Info and prepares the directed message. The active filter remains unchanged.
> Correct band eligibility, base-callsign grouping, separate suffix routing, the final Sked-fail override and selection of filtered candidates are included in Nightly / v1.42. > Correct band eligibility, base-callsign grouping, separate suffix routing, the final Sked-fail override and selection of filtered candidates are included from v1.42 onwards.
## When is the score updated? ## When is the score updated?
+1 -1
View File
@@ -57,7 +57,7 @@ The frequency is not guessed. KST4Contest first looks for a recent QRG of the re
KST-specific suffixes such as `-2`, `-70` or `-144` are removed from the callsign passed to the log. Portable components such as `/P` and `/M` are preserved. KST-specific suffixes such as `-2`, `-70` or `-144` are removed from the callsign passed to the log. Portable components such as `/P` and `/M` are preserved.
> Band-aware QRG validation, explicit `SSB`/`CW` selection and the corrected handling of KST suffixes are included in Nightly / v1.42. > Band-aware QRG validation, explicit `SSB`/`CW` selection and the corrected handling of KST suffixes are included from v1.42 onwards.
![Sked handed over from KST4Contest to Win-Test](/manual/assets/wintest_sked_handover.png) ![Sked handed over from KST4Contest to Win-Test](/manual/assets/wintest_sked_handover.png)
+1 -1
View File
@@ -37,7 +37,7 @@ AP candidates appear in the upper lanes. Up to four selected candidates can be s
Skeds appear as diamonds in the lower lane. Their labels use the complete selected KST callsign so that band-specific or otherwise suffixed logins remain identifiable. Skeds appear as diamonds in the lower lane. Their labels use the complete selected KST callsign so that band-specific or otherwise suffixed logins remain identifiable.
> Complete KST callsigns in sked labels are included in Nightly / v1.42. > Complete KST callsigns in sked labels are included from v1.42 onwards.
## Antenna direction remains visible ## Antenna direction remains visible
@@ -0,0 +1,23 @@
---
title: Version 1.42 released
summary: Shared band context, a session-based ON4KST connection and signed macOS packages
date: 2026-08-22
---
## Version 1.42 is out
v1.42 is available as a Stable release. It brings several previously separate calculations together: band information, Worked status, NOT-QRV marks, callsign suffixes and frequencies are now used consistently by the user list, the station map, the priority calculation and the external interfaces.
### The highlights
- **Shared band context:** One central band-opportunity calculation feeds the user list, *New bands*, the band-upgrade hint, the Priority Score, the station map and the automatic band selection. The band columns now distinguish `X`, `a`, `B+` and `o`, and 50 and 70 MHz are supported everywhere — from the station settings through to the Win-Test listener.
- **A connection you can trust:** The ON4KST link has been rebuilt around session-scoped connection handling with bounded timeouts, heartbeat detection and controlled reconnect backoff. A compact `LINK` indicator in the main window shows what the connection is actually doing, and the user list no longer disappears after login.
- **Signed and notarized macOS packages:** The DMG files for Apple Silicon and Intel are signed with an Apple Developer ID and notarized by Apple. The first launch now works by double-clicking, without the detour through **Open** in the context menu, and it works offline too.
- **More precise frequencies:** QRG recognition uses a station-specific band context, AirScout and the map path analysis derive realistic per-station frequencies, and the obsolete 430 MHz fallback is now 432 MHz.
The complete list of new functions, changes and fixed bugs is in the [changelog](/manual/en/changelog/) and in the [release notes](https://github.com/praktimarc/kst4contest/releases/tag/v1.42.0).
### Getting it
Packages for Windows, Linux and macOS are on the [download page](/download/) and in the [GitHub release](https://github.com/praktimarc/kst4contest/releases/tag/v1.42.0). Arch Linux users get it via the AUR as usual.
The German and English manuals have been checked against the source code, extended and re-screenshotted for this release. 73