mirror of
https://github.com/praktimarc/kst4contest.git
synced 2026-11-15 00:52:31 +01:00
Harden beacon sessions and mark automatic messages
This commit is contained in:
1 parent
19bcdb428d
commit
f13fe54fde
63 files changed
+1905
-252
No files matched your search
@@ -0,0 +1,207 @@
|
||||
# Beacon Session Safety Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Make beacon activation session-only, enforce a five-minute minimum, disable the correct category after an external QRG move beyond 5 kHz, and render a reason-aware traffic-colour `MyBeacon` chip.
|
||||
|
||||
**Architecture:** A controller-owned `BeaconSessionState` coordinates the existing observable runtime flags, category references, inactive reasons and send failures. Manual QRG commits and UCXLog/Win-Test reports enter through distinct controller methods; a structured model snapshot crosses the existing thread-status boundary and `app-desktop` localises and styles it.
|
||||
|
||||
**Tech Stack:** Java 21, Kotlin 2.2, Compose Multiplatform 1.8.x, JUnit 5, Mockito, Gradle wrapper
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-11-11-beacon-session-safety-design.md`
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- Work directly on `main`, as explicitly authorised.
|
||||
- Do not stage, commit, push, merge, tag, release or deploy; commit steps are deliberately omitted because Marc authorised none of them.
|
||||
- Keep source comments and Javadoc in English; user-facing DE/EN text follows the project writing style.
|
||||
- Use exactly 5 minutes and 5,000 Hz; exactly 5,000 Hz must not disable a beacon.
|
||||
- Do not add a production dependency or change ON4KST/UCXLog/Win-Test framing.
|
||||
- Keep the shared timer, initial ten-second check, outbound queue and second-chat eligibility unchanged.
|
||||
- Do not execute UI callbacks while holding an internal beacon-state lock.
|
||||
- Preserve unrelated local changes and inspect the diff before and after every task.
|
||||
|
||||
## Review Focus
|
||||
|
||||
- A secondary beacon using `MYQRG` must be refused or disabled when the primary QRG is invalid, even though its own reference remains the secondary QRG; Task 1 pins this cross-template case.
|
||||
- An external report with no reference must establish the reference without disabling; Task 1 pins this first-report case.
|
||||
- Without SO2R a Win-Test/UCXLog report must affect only the main beacon; Task 3 pins both integrations.
|
||||
- An old XML file with enabled flags and a one-minute interval must load as disabled with a five-minute interval and later write `false`; Task 2 pins the migration.
|
||||
- `FAILED` must stay red without an orange flash while ordinary worker chips retain current theme colours; Task 4 pins both sides.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Pure beacon session policy and structured status
|
||||
|
||||
**Files:**
|
||||
- Create: `core/src/main/java/kst4contest/controller/BeaconFrequencyParser.java`
|
||||
- Create: `core/src/main/java/kst4contest/controller/BeaconSessionState.java`
|
||||
- Create: `core/src/main/java/kst4contest/model/BeaconStatusSnapshot.java`
|
||||
- Create: `core/src/test/java/kst4contest/controller/BeaconFrequencyParserTest.java`
|
||||
- Create: `core/src/test/java/kst4contest/controller/BeaconSessionStateTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: `BeaconFrequencyParser.parseHz(String): OptionalLong`.
|
||||
- Produces: `BeaconSessionState.Channel { MAIN, SECOND }` and synchronized policy methods `resetSession(ChatPreferences)`, `setEnabled(Channel, boolean, ChatPreferences)`, `onManualQrgChanged(Channel, String, ChatPreferences)`, `onExternalQrgChanged(Channel, long, ChatPreferences)`, `onTemplateChanged(Channel, ChatPreferences)`, `recordSendFailure(Channel, boolean)` and `snapshot(ChatPreferences): BeaconStatusSnapshot`.
|
||||
- Produces: explicit `BeaconStatusSnapshot` DTO with aggregate state `OFF`, `PARTIAL`, `ON`, `FAILED`, plus main/second category DTOs carrying availability, enablement, failure and `InactiveReason`.
|
||||
|
||||
- [ ] **Step 1: Write parser tests** for `144.300`, `144,300`, `144.300.03`, `1296.123.000`, compact `144300`, compact `10368100`, blanks, malformed text, non-positive values and overflow.
|
||||
- [ ] **Step 2: Run the parser test and verify RED.**
|
||||
|
||||
Run: `.\gradlew.bat :core:test --tests kst4contest.controller.BeaconFrequencyParserTest --console=plain`
|
||||
|
||||
Expected: compilation failure because `BeaconFrequencyParser` does not exist.
|
||||
|
||||
- [ ] **Step 3: Implement `BeaconFrequencyParser`** with integer arithmetic and the QRG forms already used by the client; accept only a complete positive frequency that maps to a supported `Band`.
|
||||
- [ ] **Step 4: Re-run the parser test and verify GREEN.**
|
||||
- [ ] **Step 5: Write session-policy tests** for initial reasons, independent enablement, placeholder requirements in either template, partial aggregate activation, manual reference creation/rebase, invalid manual clearing, cross-template invalidation, first external reference, 5,000/5,001-Hz boundaries, per-category external changes, reason retention and send-failure clearing.
|
||||
- [ ] **Step 6: Run `BeaconSessionStateTest` and verify RED** because the policy and DTO are absent.
|
||||
- [ ] **Step 7: Implement the DTO and policy** so the existing observable preference booleans are projection only and no listener/callback leaves a synchronized method.
|
||||
- [ ] **Step 8: Re-run both focused tests and verify GREEN.**
|
||||
- [ ] **Step 9: Inspect the task diff** for duplicated state, floating-point frequency comparisons or display strings in `core`.
|
||||
|
||||
### Task 2: Session-only persistence and five-minute migration
|
||||
|
||||
**Files:**
|
||||
- Modify: `core/src/main/java/kst4contest/model/ChatPreferences.java`
|
||||
- Modify: `core/src/main/java/kst4contest/controller/ChatController.java`
|
||||
- Modify: `core/src/main/resources/praktiKSTpreferences.xml`
|
||||
- Modify: `core/src/test/java/kst4contest/model/ChatPreferencesBeaconStateTest.java`
|
||||
- Modify: `core/src/test/java/kst4contest/model/ChatPreferencesRoundTripTest.java`
|
||||
- Modify: `app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/BeaconTabStateTest.kt`
|
||||
- Modify: `app-desktop/src/test/kotlin/kst4contest/view/i18n/RemainingTextsFollowTheLanguageTest.kt`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: Task 1 `BeaconSessionState`.
|
||||
- Produces: `ChatController.MIN_BEACON_INTERVAL_MINUTES == 5` and session reset during controller/profile construction without reset on reconnect.
|
||||
|
||||
- [ ] **Step 1: Replace persistence expectations with failing tests** proving defaults are off, stored `true` is ignored, every full write stores both legacy/current enable tags as `false`, layout-only writes do not revive them, and intervals below five normalise in memory.
|
||||
- [ ] **Step 2: Add interval tests** proving four is refused, five accepted, and an old stored one becomes five without changing a larger value.
|
||||
- [ ] **Step 3: Run the focused core and desktop tests and verify RED.**
|
||||
|
||||
Run: `.\gradlew.bat :core:test --tests kst4contest.model.ChatPreferencesBeaconStateTest --tests kst4contest.model.ChatPreferencesRoundTripTest :app-desktop:test --tests kst4contest.view.compose.tabs.BeaconTabStateTest --tests kst4contest.view.i18n.RemainingTextsFollowTheLanguageTest --console=plain`
|
||||
|
||||
- [ ] **Step 4: Make enable flags session-only**: initialise both false, ignore XML enable values, always serialise `false`, retain existing element names, and reset the policy only when a new controller/profile preferences object is installed.
|
||||
- [ ] **Step 5: Set and enforce the five-minute minimum** in controller, XML defaults and preference-load normalisation; retain timer start/restart semantics.
|
||||
- [ ] **Step 6: Re-run the focused tests and inspect their XML summaries.**
|
||||
- [ ] **Step 7: Inspect the task diff** to confirm no reconnect path resets the session and no default was silently raised to ten minutes.
|
||||
|
||||
### Task 3: Explicit manual and external QRG paths
|
||||
|
||||
**Files:**
|
||||
- Modify: `core/src/main/java/kst4contest/controller/ChatController.java`
|
||||
- Modify: `core/src/main/java/kst4contest/controller/ReadUDPbyUCXMessageThread.java`
|
||||
- Modify: `core/src/main/java/kst4contest/controller/ReadUDPByWintestThread.java`
|
||||
- Modify: `app-desktop/src/main/kotlin/kst4contest/view/compose/ChatInputState.kt`
|
||||
- Modify: `app-desktop/src/main/kotlin/kst4contest/view/compose/ChatInputRow.kt`
|
||||
- Modify: `app-desktop/src/main/java/kst4contest/view/ComposeChatInputActions.java`
|
||||
- Modify: `app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/BeaconTabState.kt`
|
||||
- Modify: `app-desktop/src/main/kotlin/kst4contest/view/compose/SettingsTabs.kt`
|
||||
- Modify: focused fake `ChatInputActions` implementations in affected tests
|
||||
- Modify: `core/src/test/java/kst4contest/controller/BeaconControlTest.java`
|
||||
- Modify: `core/src/test/java/kst4contest/controller/ReadUDPbyUCXMessageThreadLoopbackTest.java`
|
||||
- Modify: `core/src/test/java/kst4contest/controller/WinTestStatusSlotTest.java`
|
||||
- Modify: `app-desktop/src/test/kotlin/kst4contest/view/compose/ChatInputStateTest.kt`
|
||||
- Modify: `app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/BeaconTabStateTest.kt`
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: controller methods `applyManualQrg(RadioSlot, String)`, `applyExternalQrg(RadioSlot, String, long)`, `onMainBeaconTemplateApplied()` and `onSecondBeaconTemplateApplied()`.
|
||||
- Produces: a `ChatInputActions`/`ChatInputState` manual-QRG commit method used by `ChatInputRow` instead of writing preferences directly.
|
||||
- Consumes: Task 1 policy and Task 2 session lifecycle.
|
||||
|
||||
- [ ] **Step 1: Add failing controller tests** for individual activation refusal, valid partial chip activation, user disable reason, manual rebase, invalid manual cross-template disabling and template-apply revalidation.
|
||||
- [ ] **Step 2: Add failing chat-input tests** proving both manual fields call the explicit action with the correct `RadioSlot`/category and never write preferences directly.
|
||||
- [ ] **Step 3: Add failing UCXLog tests** for exact Hz conversion, first-reference behaviour, >5-kHz main-only shutdown without SO2R and second-only shutdown for RadioNr 2 with SO2R.
|
||||
- [ ] **Step 4: Add failing Win-Test tests** for main/pass frequency selection, 100-Hz units, non-SO2R main-only and SO2R slot routing.
|
||||
- [ ] **Step 5: Run the four focused test groups and verify RED.**
|
||||
- [ ] **Step 6: Implement the controller entry points** so the preference value and policy update occur together on the existing UI-dispatch boundary and publish a fresh beacon status only after state is consistent.
|
||||
- [ ] **Step 7: Route manual Compose commits through `ComposeChatInputActions`** while preserving focus/commit behaviour and existing displayed `ObservedValue` mirrors.
|
||||
- [ ] **Step 8: Give both template draft properties a shared post-apply effect key** that revalidates active beacons after all writes, without changing their validation-before-stage behaviour.
|
||||
- [ ] **Step 9: Route UCXLog and Win-Test through `applyExternalQrg`** only when their current QRG-sync setting already permits the update; preserve packet parsing and diagnostics.
|
||||
- [ ] **Step 10: Re-run focused tests and inspect XML summaries.**
|
||||
- [ ] **Step 11: Run related integration tests** for SO2R routing, settings apply and chat-input rendering.
|
||||
- [ ] **Step 12: Inspect the task diff** for protocol/framing changes, toolkit calls in `core`, or source inference through listeners.
|
||||
|
||||
### Task 4: Beacon task status, translated tooltips and traffic colours
|
||||
|
||||
**Files:**
|
||||
- Modify: `core/src/main/java/kst4contest/controller/BeaconTask.java`
|
||||
- Modify: `core/src/main/java/kst4contest/controller/BeaconStatus.java`
|
||||
- Modify: `core/src/main/java/kst4contest/model/ThreadStateMessage.java`
|
||||
- Create: `app-desktop/src/main/kotlin/kst4contest/view/compose/BeaconStatusPresentation.kt`
|
||||
- Modify: `app-desktop/src/main/kotlin/kst4contest/view/compose/StatusIndicatorState.kt`
|
||||
- Modify: `app-desktop/src/main/kotlin/kst4contest/view/compose/StatusBar.kt`
|
||||
- Modify: `app-desktop/src/main/i18n/strings_de.properties`
|
||||
- Modify: `app-desktop/src/main/i18n/strings_en.properties`
|
||||
- Modify: `core/src/test/java/kst4contest/controller/BeaconTaskTest.java`
|
||||
- Modify: `core/src/test/java/kst4contest/controller/BeaconControlTest.java`
|
||||
- Create: `app-desktop/src/test/kotlin/kst4contest/view/compose/BeaconStatusPresentationTest.kt`
|
||||
- Modify: `app-desktop/src/test/kotlin/kst4contest/view/compose/StatusIndicatorStateTest.kt`
|
||||
- Modify: `app-desktop/src/test/kotlin/kst4contest/view/compose/StatusBarScreenTest.kt`
|
||||
- Modify: relevant i18n boundary tests
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: Task 1 `BeaconStatusSnapshot` and policy send-failure methods.
|
||||
- Produces: optional structured beacon snapshot on `ThreadStateMessage`; other thread messages remain unchanged.
|
||||
- Produces: `BeaconStatusPresentation` mapping snapshot plus current strings to label, tooltip and visual style.
|
||||
|
||||
- [ ] **Step 1: Add failing core tests** proving a failed active category yields `FAILED`, a later successful run clears only its failure, disabled categories are not failed, and ordinary timer runs preserve inactive reasons.
|
||||
- [ ] **Step 2: Add failing presentation tests** for bilingual per-category tooltips, initial/user/QRG/QRG-invalid reasons, `1/2`, and no concrete frequency in the QRG reason.
|
||||
- [ ] **Step 3: Add failing colour-model tests** for the exact light/dark OFF colours, ON/PARTIAL green, 200-ms orange highlight, FAILED red/white with highlight suppression and unchanged default-worker colours.
|
||||
- [ ] **Step 4: Run focused core and desktop tests and verify RED.**
|
||||
- [ ] **Step 5: Attach the structured snapshot to the existing status message** without adding translated display prose to `core`.
|
||||
- [ ] **Step 6: Make `BeaconTask` record per-category outcomes** while retaining text resolution, category validation and regular TX queue insertion.
|
||||
- [ ] **Step 7: Implement translated presentation and visual style** only for messages carrying a beacon snapshot; keep action/provider ordering and stale-update protection intact.
|
||||
- [ ] **Step 8: Implement the selected colours in `ThreadStatusButtonView`** and suppress the highlight when style is FAILED.
|
||||
- [ ] **Step 9: Add aligned DE/EN i18n keys** and re-run translation-boundary tests.
|
||||
- [ ] **Step 10: Re-run focused tests and inspect XML summaries.**
|
||||
- [ ] **Step 11: Run the affected Compose screen tests** and inspect a rendered light/dark result if the test harness emits one.
|
||||
- [ ] **Step 12: Inspect the task diff** to ensure no non-beacon chip acquired special colours or click behaviour.
|
||||
|
||||
### Task 5: Targeted documentation, context and full verification
|
||||
|
||||
**Files:**
|
||||
- Modify: `github_docs/de-Konfiguration.md`
|
||||
- Modify: `github_docs/en-Configuration.md`
|
||||
- Modify: `github_docs/de-Contest-Workflow.md`
|
||||
- Modify: `github_docs/en-Contest-Workflow.md`
|
||||
- Modify: `github_docs/de-Makros-und-Variablen.md`
|
||||
- Modify: `github_docs/en-Macros-and-Variables.md`
|
||||
- Review/modify: `github_docs/de-Funktionen.md`, `github_docs/en-Features.md`
|
||||
- Review/modify: `github_docs/de-Benutzeroberflaeche.md`, `github_docs/en-User-Interface.md`
|
||||
- Modify: `github_docs/de-Changelog.md`
|
||||
- Modify: `github_docs/en-Changelog.md`
|
||||
- Modify: `website/src/features/macros.md`
|
||||
- Review/modify: `website/src/features/trx-qrg-synchronisation.md`
|
||||
- Modify: `docs/PROJECT_CONTEXT.md`
|
||||
- Modify: `docs/superpowers/specs/2026-11-04-live-beacon-control-design.md`
|
||||
- Review: `github_docs/client_settings_window_beacon.png`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: completed behaviour from Tasks 1-4.
|
||||
- Produces: semantically aligned DE/EN user documentation and current durable project context.
|
||||
|
||||
- [ ] **Step 1: Update the targeted manual sections** with session-only activation, five-minute minimum, activation prerequisites, source-specific reference/QSY rules, per-category tooltip and traffic colours.
|
||||
- [ ] **Step 2: Update both changelogs compactly** without inventing a version or release state.
|
||||
- [ ] **Step 3: Update only website sections that already describe interval or TRX-QRG behaviour**; do not duplicate the manual.
|
||||
- [ ] **Step 4: Reconcile the older live-beacon design and `PROJECT_CONTEXT`** so they no longer claim activation persists or the one-minute minimum remains unchanged.
|
||||
- [ ] **Step 5: Inspect the existing Beacon settings screenshot** and record replacement only if a visible value is now false; do not fabricate an image.
|
||||
- [ ] **Step 6: Run all focused test classes from Tasks 1-4.**
|
||||
- [ ] **Step 7: Run the full build.**
|
||||
|
||||
Run: `.\gradlew.bat build --console=plain`
|
||||
|
||||
Expected: `BUILD SUCCESSFUL` with no failed tests.
|
||||
|
||||
- [ ] **Step 8: Read every generated `*/build/test-results/**/TEST-*.xml` summary** and report test/failure/error/skipped totals rather than relying only on exit code.
|
||||
- [ ] **Step 9: Count PMD and SpotBugs XML findings per module** from `<violation` and `<BugInstance>` and identify findings touching changed production files.
|
||||
- [ ] **Step 10: Run `git diff --check` and inspect `git status --short`.**
|
||||
- [ ] **Step 11: Review the complete diff against the approved spec** for unrelated cleanup, stale documentation, accidental protocol changes and user-authored changes.
|
||||
- [ ] **Step 12: Perform a manual runtime check if safely possible**: initial off state, valid/invalid category activation, manual rebase, external >5-kHz shutdown, `1/2`, OFF tooltip, orange flash and persistent FAILED red.
|
||||
|
||||
## Self-Review Result
|
||||
|
||||
- Every approved behaviour maps to Tasks 1-4; documentation and durable context map to Task 5.
|
||||
- Exact types and controller entry points are defined once in the Interfaces blocks.
|
||||
- Cross-template QRG dependencies, first external reference, non-SO2R routing, XML migration and FAILED colour priority are explicit tests.
|
||||
- Plan size reflects five independently reviewable deliverables; no implementation bodies or unauthorised Git actions are included.
|
||||
@@ -0,0 +1,96 @@
|
||||
# Automatic Chat Suffix Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Append the fixed suffix ` *a*` to every active KST4Contest autoanswer and beacon while leaving manual and protocol traffic unchanged.
|
||||
|
||||
**Architecture:** A package-private `AutomaticChatMessageFormatter` owns the suffix and performs unconditional appending. The active autoanswer and beacon producers call it explicitly; beacon validation keeps a 120-character payload allowance and validates the resulting 124-character maximum.
|
||||
|
||||
**Tech Stack:** Java 21, Kotlin 2.2, Gradle wrapper, JUnit 5, Mockito
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-11-13-automatic-chat-suffix-design.md`
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- The exact suffix is ` *a*`, including its leading space.
|
||||
- `[KST4C Automsg]` remains on autoanswers and remains the loop-prevention marker.
|
||||
- Suffix insertion is unconditional; duplicate `*a*` markers are allowed.
|
||||
- Beacon payloads remain limited to 120 characters; complete suffixed beacons are limited to 124 characters.
|
||||
- Manual messages and internal ON4KST frames must remain byte-for-byte unaffected by this feature.
|
||||
- No new dependency, setting, persistence field, version bump, staging, commit or publication action.
|
||||
|
||||
## Review Focus
|
||||
|
||||
- A 120-character beacon payload must be sent as exactly 124 characters after suffix insertion.
|
||||
- A 121-character beacon payload must still be rejected rather than producing a 125-character frame.
|
||||
- Text already ending in `*a*` must receive a second suffix without deduplication.
|
||||
- Autoanswer validation and cooldown accounting must still reject invalid text before consuming cooldown.
|
||||
- The existing prefix-based ping-pong guard and all manual send paths must remain unchanged.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Shared automatic-message formatter and autoanswers
|
||||
|
||||
**Files:**
|
||||
- Create: `core/src/main/java/kst4contest/controller/AutomaticChatMessageFormatter.java`
|
||||
- Create: `core/src/test/java/kst4contest/controller/AutomaticChatMessageFormatterTest.java`
|
||||
- Modify: `core/src/main/java/kst4contest/controller/MessageBusManagementThread.java`
|
||||
- Modify: `core/src/test/java/kst4contest/controller/MessageBusManagementThreadAutoAnswerDecisionTest.java`
|
||||
- Modify: `core/src/test/java/kst4contest/controller/MessageBusManagementThreadAutoAnswerTest.java`
|
||||
- Modify: `core/src/test/java/kst4contest/controller/MessageBusManagementThreadChatFrameTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: `AutomaticChatMessageFormatter.appendSuffix(String messageText): String`
|
||||
- Consumes: existing `ApplicationConstants.AUTOANSWER_PREFIX` and `On4KstProtocol.messageText(String)`
|
||||
|
||||
- [x] Add failing formatter tests for exact suffix insertion and intentional duplicate suffixes.
|
||||
- [x] Run `\.\gradlew.bat :core:test --tests "kst4contest.controller.AutomaticChatMessageFormatterTest"` and confirm the tests fail because the formatter is absent.
|
||||
- [x] Implement the package-private formatter with `SUFFIX = " *a*"` and unconditional appending.
|
||||
- [x] Update failing autoanswer and version-reply expectations so generic, QRG and `//VER` replies end in ` *a*` while retaining `[KST4C Automsg]`.
|
||||
- [x] Append before final autoanswer protocol validation and in the `//VER` construction path.
|
||||
- [x] Run the formatter and three focused autoanswer test classes and confirm zero failures.
|
||||
|
||||
### Task 2: Beacon suffix and length boundaries
|
||||
|
||||
**Files:**
|
||||
- Modify: `core/src/main/java/kst4contest/controller/ChatController.java`
|
||||
- Modify: `core/src/main/java/kst4contest/controller/BeaconTask.java`
|
||||
- Modify: `core/src/test/java/kst4contest/controller/On4KstProtocolTest.java`
|
||||
- Modify: `core/src/test/java/kst4contest/controller/BeaconTaskTest.java`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: `AutomaticChatMessageFormatter.appendSuffix(String)` from Task 1
|
||||
- Produces: beacon payload validation at 120 characters and final-message validation at 124 characters
|
||||
|
||||
- [x] Add failing tests asserting that each queued beacon ends in ` *a*`, a 120-character payload produces a 124-character message, and a 121-character payload is rejected.
|
||||
- [x] Run `\.\gradlew.bat :core:test --tests "kst4contest.controller.On4KstProtocolTest" --tests "kst4contest.controller.BeaconTaskTest"` and confirm the new assertions fail.
|
||||
- [x] Separate the 120-character payload limit from the 124-character final beacon limit in `ChatController`.
|
||||
- [x] Append the suffix only after macro resolution and payload validation, then validate the final message before queueing.
|
||||
- [x] Run the focused beacon tests and confirm zero failures.
|
||||
|
||||
### Task 3: Targeted documentation and verification
|
||||
|
||||
**Files:**
|
||||
- Modify: `github_docs/de-Konfiguration.md`
|
||||
- Modify: `github_docs/en-Configuration.md`
|
||||
- Modify: `github_docs/de-Makros-und-Variablen.md`
|
||||
- Modify: `github_docs/en-Macros-and-Variables.md`
|
||||
- Modify: `github_docs/de-Funktionen.md`
|
||||
- Modify: `github_docs/en-Features.md`
|
||||
- Modify: `github_docs/de-Changelog.md`
|
||||
- Modify: `github_docs/en-Changelog.md`
|
||||
- Modify: `website/src/features/automatic-replies.md`
|
||||
- Modify: `website/src/features/macros.md`
|
||||
- Modify: `docs/PROJECT_CONTEXT.md`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: implemented suffix and length behaviour from Tasks 1 and 2
|
||||
- Produces: aligned German/English user documentation and durable current-state context
|
||||
|
||||
- [x] Update examples and behavioural text so autoanswers retain `[KST4C Automsg]` and all automated chat messages end in ` *a*`.
|
||||
- [x] Document the 120-character beacon payload and 124-character transmitted-message limits in German and English.
|
||||
- [x] Record the fixed suffix rule in the changelogs and `docs/PROJECT_CONTEXT.md` without changing unrelated documentation.
|
||||
- [x] Run the focused core tests from Tasks 1 and 2, then `\.\gradlew.bat build`.
|
||||
- [x] Read every Gradle test-result XML summary and report failures, errors and skipped tests; inspect PMD and SpotBugs XML counts produced by the build.
|
||||
- [x] Run the website test/build commands defined by the current `website/package.json` if the changed website pages participate in that build.
|
||||
- [x] Run `git diff --check` and review the complete scoped diff for accidental changes; perform no Git publication action.
|
||||
Reference in new issue
Block a user