6.1 KiB
Backlog
Smells and small inconsistencies found during post-PLAN.md review. None of these block merging — they are tracked here so they aren't forgotten and so they don't reopen as "new findings" the next time someone reads the code.
Rule of engagement: items in this file get touched only when (a) someone hits the symptom in practice, or (b) work in a nearby area makes fixing the smell incidental. No batch refactor passes. No "while we're here" cleanups that grow beyond the in-scope change.
Legacy peer protocol fallback contradicts the wire policy
CLAUDE.md / AGENTS.md: "There is only one wire version — the current one. No legacy peers, no compatibility shims, no fallback paths for older builds."
Live legacy paths:
crates/lanspread-peer/src/services/legacy.rsexists and is called fromdiscovery.rs:183-188when theHellohandshake fails.discovery.rs:134synthesizeslegacy-{addr}peer IDs whenproto_veris absent from mDNS TXT records.discovery.rs:169treatsproto_ver.is_none()as handshake-eligible.update_and_announce_games(handlers.rs:605-624) branches onFEATURE_LIBRARY_DELTAand falls back toannounce_games_to_peer(sendingRequest::AnnounceGames) for peers that don't advertise the feature.Request::AnnounceGamesis still defined inlanspread-proto/src/lib.rs:75and handled inservices/stream.rs:116.
Functionally inert today — current-build peers don't drop Hello — but
code and stated policy disagree. Either delete the paths or revert the
policy.
Tauri keeps a parallel filesystem-derived scan
The peer now owns the install state machine (per PLAN.md:11), but Tauri still re-derives local install/download state from disk on every event:
refresh_games_list(src-tauri/src/lib.rs:489) fires after everyupdate_game_db,update_local_games_in_db, andupdate_game_directory. It callsset_all_uninstalled()and re-runsupdate_game_installation_stateover every bundled-DB entry, re-readingversion.ini, re-checkinglocal/, re-parsing version strings.update_local_games_in_db(src-tauri/src/lib.rs:667-704) just merged the peer's authoritativeGamevalues into the Tauri-sideGameDB. Immediately after,refresh_games_listre-derives the same fields from disk and overwrites the merged result.- The per-ID rescan optimization in
local_monitor.rsis completely undone on the Tauri side: every peer event triggers a whole-library disk walk.
Today both paths reach the same conclusion. The risk is forward-looking:
the moment one of the two derivation rules changes (a new availability
rule, a new sentinel, a new ignore name), the two scanners can disagree
silently with no rule for which wins.
Fix when convenient: refresh_games_list accepts the peer's Game
slice and trusts it for local fields. Tauri's bundled DB stays as the
source of truth for static metadata (name, description, max_players,
thumbnail mapping), but downloaded/installed/local_version/
availability come from the peer. update_game_installation_state and
set_all_uninstalled go away. The dead log branch at
src-tauri/src/lib.rs:397-402 is obviated naturally by this.
Availability::Downloading is wire-defined but unreachable
crates/lanspread-db/src/db.rs:36-41. The variant exists and serializes
but build_game_summary only emits Ready or LocalOnly.
Operation-table gating handles the in-progress case instead.
peer_db::get_all_games has a code path that lets a remote-advertised
Downloading summary contribute eti_version to aggregation. If a
future maintainer re-enables emitting Downloading from
build_game_summary, aggregation will treat such peers as
not-downloadable but still pull their version info.
Decide-and-document task: either remove the variant (matches the "current wire only" policy) or add a comment in the proto enum naming the contract.
update_game_installation_state dead log branch
src-tauri/src/lib.rs:397-402:
if eti_package_exists(&game_path, &game.id) && !downloaded {
log::debug!("Game ... has archives but no version.ini sentinel; treating as not downloaded");
}
Side-effect-only log line. Either delete or wire to a UI affordance ("partial download — retry?"). Obviated naturally if/when the Tauri parallel scan goes away.
Untested edge: Tauri reconciliation with dropped lifecycle events
The Rust reconcile_active_operations test
(src-tauri/src/lib.rs:1117-1153) covers map replacement but not the
realistic case of an event sequence with a missing begin or finish.
The TS side merges in App.tsx. Real failure mode: a missing finish
followed by a LocalGamesUpdated snapshot should clear the spinner,
and today's code does — but it's not pinned by a test.
Add a test if the spinner ever gets stuck in practice.
Documentation drift
FOLLOW_UP_2.md still lists two items as "Still open" that have
landed:
- #10
save_library_indexnon-atomic — landed infdad162, atomic temp+fsync+rename atlocal_games.rs:169-184. - #11 Split
download.rs— landed ina251233, split undercrates/lanspread-peer/src/download/.
Either mark the doc complete or delete it. Anyone reading it as status will be misled.
The collection of plan/follow-up/review docs in the repo root
(PLAN.md, PLAN_AVAILABILITY.md, PLAN_ATOMIC_INDEX.md,
PLAN_DOWNLOAD_SPLIT.md, FOLLOW_UP_PLAN.md, FOLLOW_UP_2.md,
REVIEW_STEP_1..4.md, IMPL_DECISIONS.md) is also getting noisy. A
single retrospective archive folder for completed plans would help; a
future PLAN.md should be self-terminating with explicit acceptance
criteria so it doesn't spawn this many trailing docs.
How items leave this file
- Closed by fix → delete the entry, mention it in the commit.
- Closed by decision ("we're not doing this") → delete the entry, no commit message ceremony needed.
- Promoted to active work → move back to
FINDINGS.mdonly when there's a concrete plan to fix it now.
This file does not grow unboundedly. If it does, that's a signal to either close items or stop adding to it.