bb7497c0ff
NEXT_STEPS item 4 needed the streamed-install integrity model to be a conscious decision. Keep the current runtime behavior, but name it as sender archive integrity: the receiver verifies streamed file size and RAR CRC32 from the sender's archive metadata before committing the install transaction. This protects against truncation, transport corruption, and stream provider bugs. It deliberately does not claim malicious-peer protection, because the sender controls both the streamed bytes and the RAR metadata. The docs now say that trusted content requires a future catalog schema with catalog-owned archive or extracted-file SHA-256 hashes. Test Plan: - just fmt - just test - just clippy - python3 crates/lanspread-peer-cli/scripts/run_extended_scenarios.py S41 --build-image - git diff --check - git diff --cached --check Refs: NEXT_STEPS.md item 4
68 lines
2.9 KiB
Markdown
68 lines
2.9 KiB
Markdown
# Streamed Install Next Steps
|
||
|
||
I’d treat the prototype as proof of the hard part: “can we stream
|
||
archive-derived install bytes into `local/` without making the receiver a
|
||
source?” Yes. Next I’d harden the pieces that decide whether this is
|
||
product-ready.
|
||
|
||
1. **Done — Move from CLI-only to real app integration**
|
||
|
||
The GUI now has an explicit “Low disk install” action in the game detail
|
||
modal for remote-only games. The Tauri backend queues that path through
|
||
`stream_install_game`, injects the shared external `unrar` stream provider,
|
||
and hands fetched file details to `StreamInstallGame` instead of the normal
|
||
download command.
|
||
|
||
2. **Done — Replace per-file `unrar p` with a final archive provider**
|
||
|
||
The shared external `unrar` stream provider now runs `unrar lt` once for the
|
||
archive metadata and one sequential `unrar p` pass per archive for payload
|
||
bytes. It frames directories, file starts, file chunks, and file ends from
|
||
the technical listing, so CLI and GUI callers use one purpose-built provider
|
||
instead of a per-file extraction loop.
|
||
|
||
3. **Done — Handle solid archives deliberately**
|
||
|
||
The provider exposes the RAR `solid` flag in `ArchiveBegin` and always uses
|
||
one sequential payload pass per archive, which is the safe path for solid
|
||
archives. S41 now verifies a real solid RAR fixture through the Docker
|
||
peer-cli flow, including local-only final state, absent root archive/sentinel,
|
||
byte count, and extracted payload SHA-256 hashes.
|
||
|
||
4. **Done — Decide the integrity model**
|
||
|
||
Streamed installs intentionally verify against sender archive metadata for
|
||
now: each file must match the RAR-advertised size and CRC32. That catches
|
||
transport corruption, truncation, and provider bugs, but does not claim
|
||
malicious-peer protection. Trusted content remains a separate catalog schema
|
||
step: add catalog-owned archive or extracted-file SHA-256 hashes, then verify
|
||
those at the receiver before commit.
|
||
|
||
5. **Upgrade retry/resume semantics**
|
||
|
||
Right now, failed stream means failed operation and rollback. Next useful
|
||
step:
|
||
|
||
- retry whole stream from another trusted peer
|
||
- later, maybe keep completed files and restart only the interrupted file
|
||
- avoid byte-offset resume until there’s a strong reason
|
||
|
||
6. **Expand scenario coverage**
|
||
|
||
I’d add cases for:
|
||
|
||
- sender disconnect mid-stream
|
||
- receiver cancel mid-stream
|
||
- corrupted/truncated stream fails and leaves no `local/`
|
||
- already-installed game rejects streamed install
|
||
- multi-archive `.eti` roots stream in sorted order
|
||
|
||
7. **Clean product semantics**
|
||
|
||
Decide how the UI labels this state. It is installed but not downloaded, so
|
||
“Local only” is technically correct, but users may need a clear affordance
|
||
like “Installed, not shareable”.
|
||
|
||
My recommended next slice: make the provider abstraction final-ish, then
|
||
implement a real one-pass provider. Everything else builds cleanly on that.
|