All checks were successful
check / check (push) Successful in 22s
Rework against review findings on the branch. Test runtime (B1): the suite's cost was never the 4 MiB fixture, it was filling that fixture from the CSPRNG. sodium.randombytes_buf goes through the wasm wrapper a byte at a time and takes ~20s for 4 MiB, against ~108ms to encrypt the same buffer. Fixture content is not load-bearing anywhere in the file — only length and tag are — so payloads now come from a seeded LCG instead, which also makes them deterministic and reproducible as the README asks. A seeded generator rather than a constant fill, so a downloader that reordered or repeated chunks would still be caught. make test goes from over the 30s cap in script/test (it was failing outright, then rerunning verbose) back to 8.96s, against 10.02s on main. Atomic write coverage (B2): every failure the suite injected originated in streamDecrypt, which runs before anything is written, so no test observed a temp file existing or being cleaned up and the catch block in writeAtomic was dead code. rename is now intercepted in the test file, which adds two cases per entry point: one asserting the staged file exists at rename time and is a sibling of the destination, and one failing the rename itself so the cleanup path runs with a temp file genuinely on disk. Deleting writeAtomic in favour of a plain writeFile now turns the suite red. TAG_FINAL (M1): STREAM_TAG_FINAL was a hardcoded 3 plus a test to detect drift. The premise was right — libsodium attaches its constants inside ready.then(...), so an eager module-level read binds undefined — but a lazy read works, and decryptBlob was doing exactly that before. Replaced with streamTagFinal(), which reads the library's own value at call time. The drift test is repurposed to pin the accessor against the tag observed on a real final chunk, which fails if it is ever made eager again. Partial trailing chunk (M2): a transfer that stopped mid-chunk surfaced as "authentication failed", which reads as corruption and sends the user after the wrong problem. A final chunk that arrived in full always authenticates, so trailing bytes that do not are reported as the truncation they almost always are, with the authentication failure kept as the error's cause. Poly1305 cannot separate a partial chunk from a corrupt one, so the message names both possibilities; a corrupt whole chunk mid-stream is still reported as an authentication failure, and both are now tested. The pre-existing test that wrote its output to the process working directory, i.e. the repo root, now writes into the test's temp directory.