41e9a0efc1
Replace the `a9f9845` local-update dedup cache with explicit peer event semantics. Local scans now emit `LocalLibraryChanged` when the library changes, while operation mutations emit `ActiveOperationsChanged` from the mutation path. Tauri keeps joining those facts into the existing `games-list-updated` payload, so the frontend contract stays stable. This removes the cache/invalidation coupling between scan emission and operation state. The remaining forced local snapshot is explicit: accepted game directory changes can refresh the UI for an equivalent new path without sending a peer library delta. Operation guard cleanup and liveness cancellation now publish the same active operation snapshot as normal command-handler transitions. The peer CLI JSONL events follow the same split with `local-library-changed` and `active-operations-changed`. Test Plan: - `just fmt` - `CARGO_BUILD_RUSTC_WRAPPER= just test` - `CARGO_BUILD_RUSTC_WRAPPER= just clippy` - `git diff --check` Refs: CLEAN_CODE_PLAN_1.md
5.5 KiB
5.5 KiB
Peer CLI P2P Scenarios
This matrix tracks the headless peer-to-peer contract exercised through
lanspread-peer-cli. It intentionally avoids the GUI and uses direct connect
for deterministic local runs; mDNS/macvlan remains an environment smoke path.
Scenario Matrix
| ID | Scenario | Setup | Expected result |
|---|---|---|---|
| S1 | Startup scan | Start one peer with fixture-alpha. |
Peer emits local-peer-ready and local-library-changed; catalog fixture games are downloaded=true, installed=false, availability=Ready. |
| S2 | Direct connect handshake | Start alpha and bravo, send alpha connect to bravo's ready address. |
Both peers record one remote peer, no self-peer entry appears, and each peer receives the other's library. |
| S3 | Remote aggregation | Empty client connects to alpha and bravo. | list-games shows remote-only games once; shared ggoo has peer_count=2, unique games have peer_count=1. |
| S4 | Single-source download, no install | Empty client connected to bravo downloads bfbc2 with install=false. |
Client emits got-game-files, download-begin, download-finished, then local bfbc2 is downloaded=true, installed=false; root files exist and local/ does not. |
| S5 | Auto-install download | Empty client connected to bravo downloads cnctw with default install. |
Download finishes, install begins and finishes, and local cnctw is downloaded=true, installed=true with local/fixture-payload.txt. |
| S6 | Manual install and uninstall | After S4, client sends install bfbc2, then uninstall bfbc2. |
Install marks bfbc2 installed and creates local/; uninstall removes local/ while preserving downloaded root files. |
| S7 | Duplicate-source majority download | Empty client connects to alpha and bravo, then downloads shared ggoo. |
Metadata from both peers validates by majority/plurality, download completes once, and installed state matches the install flag. |
| S8 | Ambiguous metadata rejection | Two peers advertise the same game/version with conflicting file sizes. | Download fails with a download-failed event; no committed version.ini is left for the target game. |
| S9 | Missing game | Client asks for a game none of its peers can serve. | CLI reports a deterministic command failure and emits no-peers-have-game; no local files are created. |
| S10 | Shutdown and goodbye cleanup | Alpha and bravo are connected, then bravo shuts down. | Alpha receives peer loss/removal and remote games from bravo disappear. |
| S11 | Same identity reconnect | Bravo restarts with the same state dir but a new port, then alpha connects to the new address. | Alpha has one bravo peer entry with the updated address, not duplicate identities. |
| S12 | Transfer serving gates | A peer has a non-catalog, missing-sentinel, active-operation, or local/ path request. |
The serving peer declines metadata/data; covered by unit tests where timing is too small for a stable CLI race test. |
| S13 | Exact transferred-file equality | Repeat small and large downloads, then compare every transferred regular file against its source with SHA-256 manifests. | Source and receiver manifests match exactly for each transferred file; no extra or missing files appear in the downloaded game root. |
| S14 | Large multi-peer chunked download | fixture-alpha/alienswarm contains a renamed RAR .eti larger than 100 MB. A second peer downloads it, then a third peer downloads alienswarm from both peers. |
The third peer's downloaded files match the source by SHA-256; download-chunk-finished events show the large .eti chunks coming from both peers with byte counts balanced within one chunk. |
Run Log
2026-05-17 - Exact Transfer And Large Multi-Peer Chunking
- Fixture update:
fixture-alpha/alienswarm/alienswarm.etiwas rebuilt withrar a -idq -m0from three random 40 MiB payload files, then renamed to.eti. Final archive size:125,829,913bytes.unrar t -idqpassed. - Gates before manual runs:
just fmt,just test,just peer-cli-build,just clippy, andjust peer-cli-imagepassed. - S13 small exact transfer:
deep-small-clientdownloadedbfbc2fromfixture-bravowithinstall=false. SHA-256 manifests matched exactly:bfbc2/bfbc2.etif7accef0833f29481acdeaac58261bc4fc23ebb58b7197049024d354f60daabc;bfbc2/version.inif3d94f70edcebbbc7d8ce38fdf076412fb95114ce1ecf071b26c9c2f93586372. - S13 large exact transfer:
deep-stage-bdownloadedalienswarmfromfixture-alphawithinstall=false. SHA-256 manifests matched exactly:alienswarm/alienswarm.eti8a4fb1fd458e731affb175134b7b99efc8d8a5eda80e978ba81f721d01aecc43;alienswarm/notes.txt3832bcb7057a4453981e975d2d2d528bfd9a26671423352f4a8527362d5b9810;alienswarm/version.ini8dfdc51d4dbfb06015b41a85a5f5d47f44144139e4a12db2b17eb040773082a3. - S14 multi-peer setup:
deep-stage-cconnected to alpha (10.66.0.3:53514) anddeep-stage-b(10.66.0.2:58491).list-gamesshowedalienswarmwithpeer_count=2before the download. - S14 chunk-source evidence for
alienswarm/alienswarm.eti:deep-stage-creceived chunks fromdeep-stage-bat offsets0and67,108,864(67,108,864bytes total) and from alpha at offsets33,554,432and100,663,296(58,721,049bytes total). The source-byte difference was8,387,815bytes, below one32 MiBchunk. - S14 final exactness:
deep-stage-c'salienswarmSHA-256 manifest matchedfixture-alphaexactly foralienswarm.eti,notes.txt, andversion.ini.