155 lines
6.1 KiB
Markdown
155 lines
6.1 KiB
Markdown
# 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.rs` exists and is called from
|
|
`discovery.rs:183-188` when the `Hello` handshake fails.
|
|
- `discovery.rs:134` synthesizes `legacy-{addr}` peer IDs when `proto_ver`
|
|
is absent from mDNS TXT records.
|
|
- `discovery.rs:169` treats `proto_ver.is_none()` as handshake-eligible.
|
|
- `update_and_announce_games` (`handlers.rs:605-624`) branches on
|
|
`FEATURE_LIBRARY_DELTA` and falls back to `announce_games_to_peer`
|
|
(sending `Request::AnnounceGames`) for peers that don't advertise the
|
|
feature.
|
|
- `Request::AnnounceGames` is still defined in
|
|
`lanspread-proto/src/lib.rs:75` and handled in
|
|
`services/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 every
|
|
`update_game_db`, `update_local_games_in_db`, and
|
|
`update_game_directory`. It calls `set_all_uninstalled()` and re-runs
|
|
`update_game_installation_state` over every bundled-DB entry,
|
|
re-reading `version.ini`, re-checking `local/`, re-parsing version
|
|
strings.
|
|
- `update_local_games_in_db` (`src-tauri/src/lib.rs:667-704`) just merged
|
|
the peer's authoritative `Game` values into the Tauri-side `GameDB`.
|
|
Immediately after, `refresh_games_list` re-derives the same fields
|
|
from disk and overwrites the merged result.
|
|
- The per-ID rescan optimization in `local_monitor.rs` is 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`:
|
|
|
|
```rust
|
|
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_index` non-atomic** — landed in `fdad162`, atomic
|
|
temp+fsync+rename at `local_games.rs:169-184`.
|
|
- **#11 Split `download.rs`** — landed in `a251233`, split under
|
|
`crates/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.md` only 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.
|