fix(settings): rename UDP toggle label for cross-platform audit alignment (#5549)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
James Rich
2026-05-20 14:51:29 -07:00
committed by GitHub
parent 676be26460
commit 4c588b73f8
10 changed files with 471 additions and 3 deletions

View File

@@ -1 +1 @@
{"feature_directory":"specs/20260520-153428-remove-admin-channel-toggle"}
{"feature_directory":"specs/20260520-153504-udp-label-rename"}

View File

@@ -49,5 +49,5 @@ You are an expert Android/KMP engineer. Maintain architectural boundaries, use M
<!-- SPECKIT START -->
For additional context about technologies to be used, project structure,
shell commands, and other important information, read the current plan
at `specs/20260520-153428-remove-admin-channel-toggle/plan.md`
at `specs/20260520-153504-udp-label-rename/plan.md`
<!-- SPECKIT END -->

View File

@@ -1301,7 +1301,7 @@
<string name="tx_power_dbm">Transmit Power</string>
<string name="type">Type</string>
<string name="type_a_message">Type a message</string>
<string name="udp_enabled">Enabled</string>
<string name="udp_enabled">UDP broadcasting</string>
<!-- UNKNOWN -->
<string name="unknown">Unknown</string>
<string name="unknown_age">Unknown Age</string>

View File

@@ -0,0 +1,35 @@
# Specification Quality Checklist: UDP Label Rename
**Purpose**: Validate specification completeness and quality before proceeding to planning
**Created**: 2025-05-20
**Feature**: [spec.md](../spec.md)
## Content Quality
- [x] No implementation details (languages, frameworks, APIs)
- [x] Focused on user value and business needs
- [x] Written for non-technical stakeholders
- [x] All mandatory sections completed
## Requirement Completeness
- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Success criteria are technology-agnostic (no implementation details)
- [x] All acceptance scenarios are defined
- [x] Edge cases are identified
- [x] Scope is clearly bounded
- [x] Dependencies and assumptions identified
## Feature Readiness
- [x] All functional requirements have clear acceptance criteria
- [x] User scenarios cover primary flows
- [x] Feature meets measurable outcomes defined in Success Criteria
- [x] No implementation details leak into specification
## Notes
- All items pass. Spec is ready for `/speckit.clarify` or `/speckit.plan`.
- This is a minimal-scope label change with no ambiguity; no clarification markers needed.

View File

@@ -0,0 +1,28 @@
# Data Model: UDP Label Rename
**Feature**: UDP Label Rename
**Date**: 2025-05-20
## Overview
This feature modifies no data models, entities, or state transitions. The only artifact is a string resource value change.
## String Resource
| Key | Current Value | New Value | File |
|-----|---------------|-----------|------|
| `udp_enabled` | `Enabled` | `UDP broadcasting` | `core/resources/src/commonMain/composeResources/values/strings.xml` |
## Entity Impact
None. No database entities, protobuf messages, or domain models are affected.
## State Transitions
None. The toggle's functional behavior (enabling/disabling UDP broadcasting via `Config.NetworkConfig.ProtocolFlags.UDP_BROADCAST`) is unchanged.
## Validation Rules
- The string value MUST NOT be empty
- The string key `udp_enabled` MUST remain unchanged (preserves Crowdin translation mappings)
- The new value "UDP broadcasting" MUST be ≤40 characters to avoid truncation on standard device widths (it is 16 characters — well within limits)

View File

@@ -0,0 +1,68 @@
# Implementation Plan: UDP Label Rename
**Branch**: `jamesarich/issue-5546-alignment-add-missing-network-config-fi-fbde6f` | **Date**: 2025-05-20 | **Spec**: `specs/20260520-153504-udp-label-rename/spec.md`
**Input**: Feature specification from `specs/20260520-153504-udp-label-rename/spec.md`
## Summary
Rename the `udp_enabled` string resource value from "Enabled" to "UDP broadcasting" in the shared string resources file (`core/resources/src/commonMain/composeResources/values/strings.xml`, line 1304). This is a single-line value change with no code logic modifications. After the edit, run `python3 scripts/sort-strings.py` to maintain alphabetical ordering and regenerate the strings index, then verify with a full build.
## Technical Context
**Language/Version**: Kotlin 2.3+ / JDK 21
**Primary Dependencies**: Compose Multiplatform (string resources via `Res.string.*`)
**Storage**: N/A
**Testing**: `./gradlew assembleDebug test allTests` (full build verification)
**Target Platform**: Android + Compose Desktop (KMP)
**Project Type**: Mobile app (Kotlin Multiplatform)
**Performance Goals**: N/A (label-only change)
**Constraints**: N/A
**Scale/Scope**: 1 line changed in 1 file
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
- **I. Kotlin Multiplatform Core**: ✅ PASS — Only `commonMain` is touched (`core/resources/src/commonMain/composeResources/values/strings.xml`). No platform-specific source sets modified.
- **II. Zero Lint Tolerance**: ✅ PASS — Will run `./gradlew spotlessApply spotlessCheck detekt` after the change. String XML changes are covered by Spotless XML formatting rules.
- **III. Compose Multiplatform UI**: ✅ PASS — No UI code changes. The existing composable (`NetworkConfigItemList.kt`) already references `Res.string.udp_enabled`; only the resolved value changes. No float formatting involved.
- **IV. Privacy First**: ✅ PASS — No PII, location data, or cryptographic material involved. `core/proto` submodule is not touched.
- **V. Design Standards Compliance**: ✅ PASS — The label "UDP broadcasting" aligns with the naming pattern of sibling toggles ("WiFi enabled", "Ethernet enabled"). This is a platform-specific UI label correction; cross-platform spec marked N/A in the feature spec with justification.
- **VI. Documentation Freshness**: ✅ PASS — No documentation pages affected by a string resource value change. No `skip-docs-check` label needed.
- **VII. Verify Before Push**: Will run:
```bash
python3 scripts/sort-strings.py
./gradlew spotlessApply spotlessCheck detekt assembleDebug test allTests
```
Post-push: `gh pr checks <PR>` or `gh run list --branch jamesarich/issue-5546-alignment-add-missing-network-config-fi-fbde6f --limit 5`
All gates pass. No exceptions required.
## Project Structure
### Documentation (this feature)
```text
specs/20260520-153504-udp-label-rename/
├── plan.md # This file
├── research.md # Phase 0 output (trivial — no unknowns)
├── data-model.md # Phase 1 output (minimal — string resource only)
├── quickstart.md # Phase 1 output (implementation steps)
└── tasks.md # Phase 2 output (/speckit.tasks command)
```
### Source Code (repository root)
```text
core/resources/src/commonMain/composeResources/values/
└── strings.xml # Line 1304: udp_enabled value change
scripts/
└── sort-strings.py # Post-edit sort script (existing)
```
**Structure Decision**: This change touches a single string value in the shared KMP resources module. No new files, modules, or directories are created.
## Complexity Tracking
> No violations. All constitution principles satisfied without exception.

View File

@@ -0,0 +1,60 @@
# Quickstart: UDP Label Rename
**Feature**: UDP Label Rename
**Date**: 2025-05-20
## Prerequisites
- JDK 21 installed
- `ANDROID_HOME` set
- Proto submodule initialized (`git submodule update --init`)
- Python 3 available (for sort-strings script)
## Implementation Steps
### Step 1: Edit the string resource
**File**: `core/resources/src/commonMain/composeResources/values/strings.xml`
**Line**: 1304
Change:
```xml
<string name="udp_enabled">Enabled</string>
```
To:
```xml
<string name="udp_enabled">UDP broadcasting</string>
```
### Step 2: Run the string sort script
```bash
python3 scripts/sort-strings.py
```
This re-sorts all string entries alphabetically and regenerates `strings-index.txt`.
### Step 3: Verify the build
```bash
./gradlew spotlessApply spotlessCheck detekt assembleDebug test allTests
```
### Step 4: Confirm CI (after push)
```bash
gh pr checks <PR_NUMBER>
# or
gh run list --branch jamesarich/issue-5546-alignment-add-missing-network-config-fi-fbde6f --limit 5
```
## Verification Checklist
- [ ] `udp_enabled` value reads "UDP broadcasting" in strings.xml
- [ ] `strings-index.txt` is regenerated (check git diff)
- [ ] `spotlessCheck` passes
- [ ] `detekt` passes
- [ ] `assembleDebug` succeeds
- [ ] `test` and `allTests` pass
- [ ] No unintended changes in git diff (only strings.xml and strings-index.txt modified)

View File

@@ -0,0 +1,33 @@
# Research: UDP Label Rename
**Feature**: UDP Label Rename
**Date**: 2025-05-20
**Status**: Complete — no unknowns to resolve
## Summary
This feature has no technical unknowns. The change is a single string resource value modification in an existing XML file. No new dependencies, patterns, or architectural decisions are required.
## Research Items
### R-001: String Resource Location (Resolved)
- **Decision**: Modify `core/resources/src/commonMain/composeResources/values/strings.xml`, line 1304
- **Rationale**: This is the canonical location for all shared string resources in the KMP project. The `udp_enabled` key already exists with value "Enabled"; only the value changes to "UDP broadcasting"
- **Alternatives considered**: None — the string key is already established and referenced by `NetworkConfigItemList.kt`
### R-002: Post-Edit Script Requirement (Resolved)
- **Decision**: Run `python3 scripts/sort-strings.py` after the edit
- **Rationale**: Constitution (Development Workflow section) mandates running the sort script after any string resource modification to maintain alphabetical ordering and regenerate `strings-index.txt`
- **Alternatives considered**: None — this is a mandatory workflow step
### R-003: Build Verification (Resolved)
- **Decision**: Full build verification with `./gradlew spotlessApply spotlessCheck detekt assembleDebug test allTests`
- **Rationale**: Constitution principle VII (Verify Before Push) requires local verification of all touched modules. Since strings.xml is consumed by all UI modules, a full build is appropriate
- **Alternatives considered**: Module-scoped `:core:resources:allTests` — rejected because the string is consumed transitively by multiple feature modules
## Conclusion
All technical context is fully resolved. No NEEDS CLARIFICATION items remain. Proceed directly to Phase 1 design.

View File

@@ -0,0 +1,121 @@
# Feature Specification: UDP Label Rename
**Feature Branch**: `jamesarich/issue-5546-alignment-add-missing-network-config-fi-fbde6f`
**Created**: 2025-05-20
**Status**: Draft
**Input**: User description: "Rename the `udp_enabled` string resource label from 'Enabled' to 'UDP broadcasting' to align with the naming pattern of other network config toggles and make the field identifiable during cross-platform audits."
**Cross-Platform Spec**: N/A — platform-specific UI label correction only; no cross-platform behavior change
## Summary
The Network Config screen contains a toggle for UDP broadcasting that is labeled generically as "Enabled." This makes it indistinguishable from other toggles during cross-platform settings audits and confuses users who see sibling toggles labeled descriptively (e.g., "WiFi enabled," "Ethernet enabled"). This feature renames the label to "UDP broadcasting" so the toggle is self-describing and passes cross-platform validation checks.
## Goals
1. Make the UDP broadcasting toggle immediately identifiable by its label without requiring surrounding context
2. Align the naming convention with sibling network config toggles ("WiFi enabled," "Ethernet enabled")
3. Resolve the settings-validation-matrix discrepancy that marked UDP broadcasting as "Not present" on Android
4. Ensure the label change appears across all supported locales (English base; translators handle other locales via Crowdin)
## Non-Goals
- Changing the underlying functionality of the UDP broadcasting toggle
- Adding new network configuration fields or toggles
- Modifying the `enabled_protocols` bitmask logic or protobuf definitions
- Updating the Apple or other platform clients
- Adding tooltip or help text to the toggle (out of scope for this label fix)
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Identifiable UDP Toggle (Priority: P1)
As a user configuring network settings, I want the UDP broadcasting toggle to have a clear, descriptive label so I can understand what it controls without relying on its position in the list.
**Why this priority**: This is the core deliverable — without a descriptive label, the toggle fails cross-platform audits and confuses users.
**Independent Test**: Can be fully tested by opening the Network Config screen and verifying the toggle label reads "UDP broadcasting."
**Acceptance Scenarios**:
1. **Given** a user navigates to the Network Config screen, **When** the screen renders, **Then** the UDP broadcasting toggle displays the label "UDP broadcasting"
2. **Given** a user has previously seen the toggle labeled "Enabled," **When** they update the app and open Network Config, **Then** the toggle now reads "UDP broadcasting" with no change in toggle state or behavior
---
### User Story 2 - Cross-Platform Audit Alignment (Priority: P2)
As a Meshtastic maintainer running the settings-validation-matrix audit, I want the Android UDP field to be identifiable by name so the audit correctly marks it as "Present."
**Why this priority**: Resolving the audit discrepancy prevents duplicate work and incorrect issue reports.
**Independent Test**: Can be tested by running the settings-validation-matrix audit tool against the updated Android client and confirming the UDP broadcasting field is marked as present.
**Acceptance Scenarios**:
1. **Given** the settings-validation-matrix audit inspects the Android Network Config screen, **When** it searches for a UDP broadcasting field, **Then** it finds the toggle by its label "UDP broadcasting" and marks it as present
---
### Edge Cases
- What happens when the user's locale has no translation for the updated string? The English default "UDP broadcasting" is displayed as a fallback.
- What happens if other toggles in the list also use generic labels? This spec addresses only the `udp_enabled` string; other label improvements are separate issues.
## Architecture
### Key Components
| Component | Module / File | Purpose |
|-----------|---------------|---------|
| NetworkConfigItemList | `feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/component/NetworkConfigItemList.kt` | Renders the UDP broadcasting toggle using the string resource |
| strings.xml | `core/resources/src/commonMain/composeResources/values/strings.xml` | Defines the `udp_enabled` string resource label |
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: The string resource `udp_enabled` MUST display the text "UDP broadcasting" in the English locale
- **FR-002**: The toggle behavior (enable/disable UDP broadcasting via `enabled_protocols` bitmask) MUST remain unchanged
- **FR-003**: The label MUST be visible and readable on all supported screen sizes without truncation on standard device widths
### Non-Functional Requirements
- **NFR-001**: The label change MUST NOT introduce any new accessibility regressions; TalkBack MUST announce the updated label correctly
- **NFR-002**: No new strings beyond modifying the existing `udp_enabled` value; no string key rename required
## Source-Set Impact
| Source Set | Impact | Justification |
|-----------|--------|---------------|
| `commonMain` | Modified: `strings.xml` (1 line change) | String resources live in commonMain |
| `androidMain` | None | No platform-specific changes |
| `jvmMain` | None | No platform-specific changes |
## Design Standards Compliance
- [x] New screens reviewed against design standards — N/A, no new screens
- [x] M3 component selection verified — existing `SwitchPreference` component unchanged
- [x] Accessibility: TalkBack will announce updated label; no touch target changes
- [x] Typography: No typography changes; existing text style preserved
## Privacy Assessment
- [x] No PII, location data, or cryptographic keys logged or exposed
- [x] No new network calls that transmit user data
- [x] Proto submodule (`core/proto`) not modified (read-only upstream)
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: 100% of users see "UDP broadcasting" as the toggle label on the Network Config screen after the update
- **SC-002**: The settings-validation-matrix audit marks the Android UDP broadcasting field as "Present" (previously "Not present")
- **SC-003**: Zero user-reported confusion or support requests about the renamed toggle within 30 days of release
## Assumptions
- All business logic and UI composables reside in `commonMain` source set
- String resources are defined in `core/resources/src/commonMain/composeResources/values/strings.xml`
- The existing `udp_enabled` string key is retained (only the value changes) to avoid breaking existing translations in Crowdin
- Crowdin will pick up the value change and notify translators for localization
- The toggle's functional behavior tied to `Config.NetworkConfig.ProtocolFlags.UDP_BROADCAST` is correct and not part of this change

View File

@@ -0,0 +1,123 @@
# Tasks: UDP Label Rename
**Input**: Design documents from `/specs/20260520-153504-udp-label-rename/`
**Prerequisites**: plan.md ✅, spec.md ✅, research.md ✅, data-model.md ✅, quickstart.md ✅
**Tests**: No new automated tests requested. Verification via full build.
**Verification**: Constitution-required validation included (spotlessApply, detekt, assembleDebug, test, allTests).
## Format: `[ID] [P?] [Story] Description`
- **[P]**: Can run in parallel (different files, no dependencies)
- **[Story]**: Which user story this task belongs to (e.g., US1, US2)
- Exact file paths included in descriptions
---
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: No setup required — existing project, no new files or dependencies.
*(No tasks — project is already initialized and configured.)*
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: No foundational work needed — this is a single string value change in an existing file.
*(No tasks — no blocking prerequisites.)*
---
## Phase 3: User Story 1 - Identifiable UDP Toggle (Priority: P1) 🎯 MVP
**Goal**: Rename the `udp_enabled` string resource value from "Enabled" to "UDP broadcasting" so the toggle is self-describing on the Network Config screen.
**Independent Test**: Open the Network Config screen and verify the toggle label reads "UDP broadcasting."
### Implementation for User Story 1
- [X] T001 [US1] Change `udp_enabled` string value from "Enabled" to "UDP broadcasting" in `core/resources/src/commonMain/composeResources/values/strings.xml` (line 1304)
- [X] T002 [US1] Run `python3 scripts/sort-strings.py` to maintain alphabetical ordering and regenerate the strings index
**Checkpoint**: At this point, the label change is complete and the string resource file is properly sorted.
---
## Phase 4: User Story 2 - Cross-Platform Audit Alignment (Priority: P2)
**Goal**: Ensure the settings-validation-matrix audit correctly identifies the Android UDP broadcasting field as "Present."
**Independent Test**: The audit tool finds the toggle by its label "UDP broadcasting" and marks it as present.
*(No additional implementation tasks — US2 is satisfied by the same string change in US1. The descriptive label is what the audit tool searches for.)*
**Checkpoint**: Both user stories are satisfied by the single string value change.
---
## Phase 5: Polish & Cross-Cutting Concerns
**Purpose**: Constitution-required verification and formatting
- [X] T003 Run `./gradlew spotlessApply` to apply formatting rules in `core/resources/src/commonMain/composeResources/values/strings.xml`
- [X] T004 Run `./gradlew detekt` to verify no static analysis violations
- [X] T005 Run `./gradlew assembleDebug test allTests` to verify full build and test suite passes
- [X] T006 Confirm no logs, telemetry, or config changes expose PII, location data, secrets, or modify `core/proto`
---
## Dependencies & Execution Order
### Phase Dependencies
- **Setup (Phase 1)**: Skipped — no setup needed
- **Foundational (Phase 2)**: Skipped — no blocking prerequisites
- **User Story 1 (Phase 3)**: Can start immediately
- T001 → T002 (sort must run after the string change)
- **Polish (Phase 5)**: Depends on Phase 3 completion
- T003 → T004 → T005 (sequential: format → lint → build)
- T006 can run in parallel with T003T005
### User Story Dependencies
- **User Story 1 (P1)**: No dependencies — can start immediately
- **User Story 2 (P2)**: Fully satisfied by US1 implementation — no additional tasks
### Parallel Opportunities
- T003T005 are sequential (each depends on prior passing)
- T006 is independent and can be verified at any time
- Overall this is a strictly sequential 6-task workflow due to the minimal scope
---
## Implementation Strategy
### MVP First (User Story 1 Only)
1. Execute T001: Change the string value
2. Execute T002: Run sort script
3. **STOP and VALIDATE**: Verify string file is correct
4. Execute T003T005: Full verification pipeline
5. Execute T006: Privacy confirmation
6. Ready for PR
### Execution Summary
| Phase | Tasks | Estimated Effort |
|-------|-------|-----------------|
| Phase 3 (US1) | T001, T002 | < 1 minute |
| Phase 5 (Polish) | T003T006 | ~5 minutes (build time) |
| **Total** | **6 tasks** | **~6 minutes** |
---
## Notes
- This is a single-line value change — no code logic, no new files, no architectural changes
- The string key `udp_enabled` is retained (only the value changes) to avoid breaking Crowdin translations
- All verification is via existing Gradle tasks — no custom test code needed
- Commit after T002 (the functional change) and after T005 (verification passes)