A saved SUB_IDS array can contain the same GUID more than once. Loading
it verbatim creates repeated subscription rows with identical Compose
and reorderable-list keys, which can crash the subscription screen.
Deduplicate IDs in the shared reader while preserving the first-seen
order and mutable-list contract. This protects every index consumer
without changing subscription records, generating replacement IDs, or
adding writes during reads. Different subscriptions with identical or
blank names remain separate.
Add six regression tests for duplicate rows, stable ordering, read-only
decoding, mutable round trips, repeated names, and existing empty/invalid
input behavior. Three assertions fail on unchanged upstream; all six
pass with the fix. The full 63-test suite and Play Store debug build pass.
On the API 37.1 Pixel 9 Pro emulator, a deliberately duplicated saved
index loaded each subscription once, retained first-occurrence order,
reopened safely, and edited the correct record. The raw index remained
duplicated throughout the check; no app crash was observed.
Logcat used the complete log text as a Compose lazy-list key after 258de2097. Identical timestamped messages and repeated stack frames are valid log output, but collide as keys and crash the main thread while browsing logs.
Give each occurrence its own key in a small ViewModel-owned presentation model. Count oldest-first so prepending newer logs and filtering unrelated lines retain existing occurrence keys. Build the projection off the main thread and keep raw text, duplicates, ordering, copy and share behavior unchanged.
Add six regression tests covering duplicate messages, repeated frames, filtering, refresh, empty input and key-like text. All 63 Play Store unit tests pass; the debug APK was checked on the API 37.1 emulator with duplicate-line scrolling, filtering, refresh, reopening and lossless export. The original failure is documented by the user-provided physical-device crash log.
Switch routing ruleset lookup, save, and delete flows from list index to stable ruleset ID. Routing edit intents now pass `ruleset_id`, editing reloads by ID, and list item edit actions use each rule’s ID. This avoids index mismatch bugs when list order changes and keeps update/delete targeting the correct ruleset.
* docs: refresh agent guidelines
* docs: add agent harness adapters
* Update local-only block markers in AGENTS.md
DO NOT COMMIT phrase was confusing most LLMs and preventing them from committing anything without an additional explicit permission.
Build presentation-ready server row models in the ViewModel and publish each group's raw data and row data as one atomic state.
This removes storage and description work from composition, reduces the server-row API, and keeps reordering consistent across both representations.
Disabling traffic statistics removed the whole policy section from the
generated config, including the levels block (uplinkOnly, downlinkOnly,
connIdle, handshake) from the template or from a user's custom config.
Only the stats-related policy.system block should be stripped; keep
policy.levels intact in both the unified and the custom config paths.
Load asset metadata on Dispatchers.IO and publish the asset list and file details as one lifecycle-aware UI state.
Remove refresh-key workarounds, await reloads before downloads, and keep the content composable stateless.
Clear visible delays immediately, but move the per-profile MMKV reset to the existing I/O coroutine. Finish the reset before starting the test service so newly reported results cannot be erased.
* fix: extend bottom bar background and content to screen edge for edge-to-edge
* Extract NavigationBarsSpacer and navigationBarsBottomPadding to reduce duplicate code
* Rename navigationBarsBottomPadding to NavigationBarsBottomPadding for naming consistency
* Localize runtime-generated UI text
Keep connection-test and status data locale-neutral until the UI formats it, and localize delay units at their Compose presentation boundary.\n\nShow stable localized failures while retaining diagnostic exceptions in Logcat. Clarify routing rule matching and subscription entry/exit proxy behavior at the relevant UI call sites, and remove the now-unused core error resources.
* Fix Compose resource lookup in routing editor
* Adjust string
---------
Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>