Files
lanspread/NEXT_STEPS.md
T
ddidderr 0e970dcec7 test(peer-cli): cover solid streamed installs
NEXT_STEPS item 3 needed solid archive handling to be a deliberate
contract instead of an incidental RAR header attribute. Add a tiny real
solid RAR fixture and S41 to the extended peer-cli scenarios so the
Docker harness proves this path end to end.

The scenario verifies the source archive with container-bundled
`unrar lt`, streams the install with the injected provider, and then
asserts the receiver is installed local-only without a root archive or
root `version.ini`. It also compares local payload SHA-256 hashes against
`unrar p` output and checks the streamed byte count matches the extracted
entries. This keeps the existing one metadata pass plus one sequential
payload pass contract covered for solid archives.

Test Plan:
- just fmt
- just test
- python3 -m py_compile crates/lanspread-peer-cli/scripts/run_extended_scenarios.py
- python3 crates/lanspread-peer-cli/scripts/run_extended_scenarios.py S41 --build-image
- python3 crates/lanspread-peer-cli/scripts/run_extended_scenarios.py S41
- git diff --check
- git diff --cached --check

Refs: NEXT_STEPS.md item 3
2026-06-07 22:00:21 +02:00

2.8 KiB
Raw Blame History

Streamed Install Next Steps

Id 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 Id 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. Decide the integrity model

    Current prototype verifies streamed bytes against RAR CRC32 from the senders archive headers. That catches corruption and provider bugs. It does not protect against a malicious peer lying. If you care about that, the next step is catalog-side trusted hashes for archive or extracted files.

  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 theres a strong reason
  6. Expand scenario coverage

    Id 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.