# P15-086 Stage0 Decision Status: `GO`. G04 and G05 authorize B28 partial subextent decoding for LZ4, LZMA, and Deflate. Zstd is not authorized for partial decoding and must use the exact full-decode fallback for ordinary strict subextent reads. Existing partial-reference maps retain their bounded-prefix path. Shifted, interlaced, unknown, and future backends also remain on full fallback unless a new gate authorizes them. The gate is bound to DUT BASE `6bf5724619be70f805bbe7d1ba77dd70cdced69f`, FreeBSD source HEAD `106727738dcfb6c001b46f25363b91cece970085`, erofs-utils generations v1.4, v1.7, and v1.8.6 for LZ4, erofs-utils 1.8.6 for the stream codecs, liblz4 1.10.0, liblzma 5.8.1, zlib 1.3.1, and libzstd 1.5.7. ## Authoritative Run The gate ran once from `/work/erofs-freebsd-pre` as: ```sh timeout -k 10 240 repo-pre-15/tests/pre15/gates/P15-086.sh \ --base 6bf5724619be70f805bbe7d1ba77dd70cdced69f \ --output planning/pre15/evidence/20260815T154915Z-G04-G05-P15-086/gate-output ``` It returned 0 and recorded G04=`GO`, G05=`GO`, and B28=`AUTHORIZED`. Evidence is rooted at `planning/pre15/evidence/20260815T154915Z-G04-G05-P15-086/`. The authoritative script SHA-256 is `591e407f20a6c8ab5d506329b3bd39ff7bd7f78b66ac86b9db2c45a498b31184`, the input SHA-256 is `62f7f505aef846fa85085039b2f47e252e11602e6ef1bf41f56841cdc9089a2a`, and the result SHA-256 is `33ef86b73447cd8c8099dc33901b9c4fff6c8ecedda3837d25cac9463a369d4f`. ## Decision Rule Each codec is decided independently. A codec is partial-capable only when real, twice-reproduced EROFS input decodes every requested range to the exact full slice, reports a consumed-byte boundary before the end of the stream, leaves guard pages unchanged, preserves positive FreeBSD errno, and reduces peak temporary bytes by at least 20 percent without exceeding the fixed hard budget. Failure of the benefit subgate selects exact full fallback for that codec; an incorrect slice, unbounded memory, missing corruption boundary, or missing oracle stops P15-086. ## Reproducible Corpus All images are fixed-time, fixed-UUID, root-owned, and generated twice with identical bytes. Matching fsck reconstructs every legal source. | Codec | Generator | Image SHA-256 | Logical bytes | Physical bytes | Leading zero bytes | Stream bytes | |---|---|---|---:|---:|---:|---:| | LZ4 | v1.4 | `8f940673ed9f7e00efc5c0f06d41b2216748ea84256b740751aabff0d632de2b` | 1,038,906 | 4,096 | 0 | 4,096 | | LZ4 | v1.7 | `93451e563f4eaf95b2690381074b5dfb3da0257691043c51619fd7d4c68dba7e` | 1,038,906 | 4,096 | 0 | 4,096 | | LZ4 | v1.8.6 | `853649c78b159161421a6e833e0c516216382f3e8d135fc80aacd509ddb27b2c` | 1,038,906 | 4,096 | 0 | 4,096 | | Deflate | 1.8.6 | `5f98ff39be30b1396be8164e54a8ae80b144d181d5295a640b2e7814406d7a2d` | 22,878 | 4,096 | 1 | 4,095 | | LZMA | 1.8.6 | `887d4a9baf629533c8d512177a84ca256a20135157d29a201408534f63230889` | 151,552 | 4,096 | 3,556 | 540 | | Zstd | 1.8.6 | `93f6beb46e77187ea8b0fc1ad3a5a1cb565d546d9ce40d51278f26d67187d5fa` | 151,552 | 4,096 | 1,092 | 3,004 | The LZ4 corpus spans all three historical generators required by G04. Stream codec consumption is reported by independent liblzma, zlib, and libzstd decoders after the common EROFS leading-zero padding is removed. LZ4 is checked by an independent raw parser and liblz4 partial/full output. ## Hard Budget and Benefit The fixed input cap is 1 MiB, the decoded-output cap is 12 MiB, and the caller cap is 1 MiB. Codec workspace caps are 0 for LZ4, 512 KiB for Deflate, 9 MiB for LZMA, and 4 MiB for Zstd. These caps cover the frozen format maxima rather than only the selected 4 KiB pclusters. | Codec | Workspace full/partial | Hard cap | Baseline peak | Candidate peak | Reduction | CPU median partial/full | Decision | |---|---:|---:|---:|---:|---:|---:|---| | LZ4 v1.8.6 | 0 / 0 | 14,680,064 | 1,047,098 | 12,288 | 98.826% | 10,688 / 208,150 ns | `GO` | | Deflate | 39,928 / 39,928 | 15,204,352 | 70,998 | 52,216 | 26.454% | 14,207 / 61,627 ns | `GO` | | LZMA | 98,992 / 98,992 | 24,117,248 | 258,736 | 111,280 | 56.991% | 21,384 / 80,329 ns | `GO` | | Zstd | 95,992 / 313,080 | 18,874,368 | 255,736 | 325,368 | -27.228% | 109,253 / 91,015 ns | `FULL_FALLBACK` | All three LZ4 generations have the same 98.826 percent memory reduction; their partial/full CPU ratios are 4.845, 4.632, and 5.135 percent. The gate collected nine samples of 25 decodes per mode and stopped at that fixed sample count. CPU timings are diagnostic because host scheduling produced visible outliers; the authorization is based on deterministic peak temporary bytes. No noisy CPU sample is used to rescue a codec that misses the 20 percent memory threshold. ## Ranges, Corruption, and Errno Prefix, cross-page, middle, and tail requests all match the corresponding full slice. The tail request reaches the extent end and therefore exercises full fallback. Prefix consumption is 1,032 bytes for LZ4, 805 for Deflate, 352 for LZMA, and 1,457 for Zstd. Corruption begins later at stream offsets 4,032, 4,031, 476, and 2,940 respectively. Every partial prefix remains byte-exact; the same full read and every one-byte truncation return positive `EINTEGRITY` (97). Real corrupted EROFS images fail matching fsck. All output guards and codec cleanup checks pass. Partial success is only evidence that the requested slice is correct. It is not reported as verification of bytes after the consumed boundary or of the full extent. ## State and Cleanup Model B28 adds no persistent cache, owner, waiter, pool, or unmount-drain state. A cache hit remains first. A gate-authorized strict subextent miss decodes into a request-local bounded prefix and never publishes a partial cache entry. Full requests, unsupported ordinary strict subextent codecs, shifted/interlaced maps, and arithmetic fallback retain the existing exact full-decode/cache policy. Existing partial-reference maps remain bounded-prefix and cache-ineligible. Failure frees the local output after input release; success publishes no shared partial state. Reclaim, eviction, unmount, and key reuse therefore retain their existing ownership model. The owned temporary tree was removed and the evidence SHA-256 manifest verifies in full. No QEMU process was started. Protected PID 26318, port 9222, and the shared base image were not touched. The full feature suite was not run. ## Consequence B28 may implement bounded-prefix decode only for LZ4, LZMA, and Deflate in the exact planned write set for ordinary strict subextent reads. Zstd and all non-authorized backends must retain exact full fallback there without returning an unsupported error; existing partial-reference behavior remains unchanged. B28 acceptance owns D, the targeted TC176 host case, both KLD configurations, and strict-timeout TC176 QEMU. It must preserve guards, consumed-byte semantics, positive errno, cache eligibility, provider/GEOM ownership, and cleanup ordering. ## B28 Execution Outcome B28 source/test commit `7a0d7e4a4047ac6d6130a3be5cb677cb94979fe7` has the exact 11-path actual write set. LZ4, LZMA, and Deflate ordinary strict subextent reads decode a bounded prefix; Zstd and non-authorized backends use exact full fallback. Existing partial-reference maps remain bounded-prefix and cache-ineligible. Final D, targeted host TC176 subset `20260815T163642Z-host-B28-partial-1356298-0`, and targeted zstdio0/zstdio1 K2 `20260815T163515Z-host-B28-partial-1355895-0` pass. Earlier host and K2 `RUNNER_FAIL` records are retained with their corrected oracle/build findings. The strict-timeout QEMU run `20260815T163824Z-qemu-B28-partial-1356729-0` is `INFRA_BLOCKED` because guest SSH did not become ready before the boot deadline; it did not reach the target marker, so no guest TC176 runtime PASS is claimed. Owned cleanup passes, protected PID 26318 and port 9222 were untouched, and the full feature suite was not run. Complete evidence is under `planning/pre15/evidence/20260815T161336Z-B28/`.