feat(peer): journal download file ownership
Track the exact regular files owned by each completed and in-flight peer download instead of sweeping every non-reserved path after cancellation. Bind the record to the canonical games directory, publish pending ownership before payload mutation, and use the final version.ini rename as the recovery commit point. Make replacement, cancellation, and startup recovery preserve unknown files and install state while removing stale or partial downloader-owned bytes. Add a new-format baseline so legacy discarded sentinels cannot make partially modified payloads ready, sync payload and journal state in transaction order, and serialize startup recovery against operation admission. Document ambiguous legacy target adoption, portable alias transitions, and the other ownership tradeoffs in the refactor decision log. Test Plan: - `just clippy` -- passed - `just test` -- passed (182 peer-core tests plus the full workspace) - `just fmt` -- Rust, TOML, and Prettier formatting completed; the command then stopped on 40 pre-existing rumdl findings in unrelated Markdown content - `git diff --cached --check` -- passed
This commit is contained in:
@@ -171,12 +171,16 @@ Downloaded and installed are independent predicates:
|
||||
Reserved per-game paths:
|
||||
|
||||
- `.version.ini.tmp` and `.version.ini.discarded` are download transaction
|
||||
scratch files and are swept during startup recovery.
|
||||
scratch files. Startup recovery interprets them together with the durable
|
||||
ownership journal rather than sweeping them independently.
|
||||
- `.local.installing/` is extraction staging.
|
||||
- `.local.backup/` holds the previous install while an update or uninstall is in
|
||||
flight.
|
||||
- `games/<game_id>/install_intent.json` in the configured state directory is the
|
||||
atomic per-game intent log.
|
||||
- `games/<game_id>/download_ownership.json` in that state directory records the
|
||||
last committed and any pending downloader-owned regular-file set. The record
|
||||
is bound to one canonical configured games directory.
|
||||
- `.lanspread_owned` inside `.local.*` directories proves Lanspread ownership
|
||||
when the current intent is `None`.
|
||||
|
||||
@@ -210,9 +214,10 @@ Most scans become O(number of game dirs), with full recursion only when needed.
|
||||
active for that ID, and the root-level `version.ini` sentinel exists.
|
||||
- `local/` paths are never served, even if a stale or malicious manifest request
|
||||
asks for them.
|
||||
- Cancelling a download discards the peer-owned root download payload and
|
||||
scratch sentinel files. `local/` and install transaction metadata are
|
||||
preserved, so a cancelled update of an installed game settles as local-only.
|
||||
- Cancelling or recovering a download removes only paths named by its durable
|
||||
ownership journal and its validated pending manifest. Unknown user files,
|
||||
`local/`, and install transaction metadata are preserved, so a cancelled
|
||||
update of an installed game settles as local-only.
|
||||
|
||||
### Streamed install integrity
|
||||
|
||||
|
||||
Reference in New Issue
Block a user