Development and command reference¶
Use GNU Make from the repository root. Rust 1.96.1 and the matching formatter,
Clippy, and WASM targets are pinned in rust-toolchain.toml. make lint also
uses the pinned nightly-2026-07-16 Clippy toolchain to check coverage-only
code paths; install that nightly with its clippy component before running the
full lint command. Documentation uses Python 3.12.10 in CI and hash-locked
MkDocs dependencies.
On hosts without the x86-64 Linux target installed, including ARM hosts, prepare
the target before running make lint-x86-simd:
rustup target add x86_64-unknown-linux-gnu --toolchain 1.96.1
Common commands¶
| Task | Command | Effect |
|---|---|---|
| Help | make help |
Lists contributor commands without running Cargo metadata |
| Build | make build |
Compiles the locked default-feature crate |
| Format / fix | make fmt / make fmt-fix |
Checks / rewrites Rust formatting |
| Contracts | make verify |
Legal, fixture, capability, roadmap, coverage-origin, and release-tool checks |
| Lint | make lint |
Rust formatting plus strict debug/release, coverage-hook, and JPEG benchmark Clippy |
| Tests | make test |
Rustdoc, all-feature tests, strict WASI Clippy, and feature/target lanes |
| Package example | make example |
Executes the self-contained public PNG example |
| Coverage | make coverage |
Measures the full source denominator and enforces alpha floors |
| Selected coverage | make coverage-selected COVERAGE_CASES='decode:webp:<id>' |
Runs exact matrix cases and retains the report, command log, and local execution evidence outside target/ |
| Parity coverage | make coverage-parity |
Runs every active decode/encode parity row and reports planned rows without running unit tests or fault-contract rows |
| Full matrix coverage | make coverage-matrix |
Runs active decode/encode parity and fault-contract rows, reports planned rows, and does not run ordinary unit tests |
| Complete coverage | make coverage-complete |
Requires all four metrics to reach 100% |
| Package inspection | make package-verify |
Builds, extracts, and tests the distributable archive |
| Documentation setup | make docs-setup |
Creates an isolated environment and installs the hashed lock |
| Site build / preview | make docs-build / make docs-serve |
Builds checked HTML / serves localhost:8000 |
| JPEG oracle setup | make bench-setup |
Downloads, verifies, and builds pinned TurboJPEG under target |
| JPEG comparison | make bench |
Runs all 20 configurations for encode and decode, five rounds each |
| Full local CI | make ci |
Runs validation, tests, coverage, and packaging |
Setup and initial toolchain/dependency builds may need network access.
Documentation builds do not execute benchmarks. Stop the local preview with
Ctrl-C. Benchmark output directories must be new or empty; use
BENCH_OUTPUT=target/benchmarks/jpeg/run-2 for a repeat.
Parity inputs and outputs¶
The maintained manifest, complete encoded inputs, and pinned Pillow oracle define observable behavior. Generate references using the documented canonical macOS ARM64 environment. Compare formats, modes, metadata, frames, pixels, palettes, deterministic output bytes, and structured error behavior where the contract requires them.
Do not replace exact comparisons with prefix checks, dimensions, or hashes chosen to match the Rust output. Add the corresponding public input when changing codec behavior. Preserve planned and not-applicable outcomes.
tests/fixtures/coverage_matrix.json also keeps an append-only
mode_decode_cases index, with at least one active Pillow-backed decode row
for each format/header-mode/decoded-mode pair. Add extra representative rows
when distinct source layouts normalize to the same public mode pair, such as
RGB-carrier TIFF layouts. Header and decoded-transfer modes are independent
expectations and may differ when Pillow reports different modes for the source
header and pixel transfer. A case can set frame_index to represent a decoded
animation or multipage frame; without it, the case uses the row's ordinary
decoded image. Exact Pillow-backed sequence frame modes also contribute to the
required pair set. When a decoder adds a new pair or a carrier alias needs an
explicit row, append it to that index. The parity harness checks both
identities independently, that indexed rows remain active, and that every
successful mode pair is listed. Every indexed decode row reruns token-aware
still decode and its max-pixel token-policy path. Both must preserve the exact
Pillow result and ordinary transfer identity, alongside owned and borrowed
encoded-source header inspection. Indexed sequence-frame cases rerun token-aware,
work-budget, and max-pixel token-policy sequence decode, checking every exact
frame's decoded transfer mode and raster identity. GIF frame references can be
rendered RGB while the public sequence retains indexed source samples; the harness checks the retained
indexed identity and compares the separately rendered RGB pixels exactly.
The matrix also keeps an append-only mode_encode_cases index with one active
Pillow-reference-backed encoder row for each format/source-mode/decoded-mode
pair. When an encoder adds a new pair, append a representative row; the parity
harness checks that each listed case retains its byte and pixel references and
that no successful mode pair is omitted. Every indexed encode case also checks
its encoded header and decoded-transfer identity, even when other cases in the
same format share the internal raster mode.
Successful encode rows also exercise append-only sink delivery. The harness
starts with a sentinel prefix and leaves OutputSink::checkpoint() at its
default None; it checks that the prefix remains intact, appended bytes match
both the Pillow byte reference and the in-memory encoder, and the reported
byte count equals the appended length. One-frame TIFF rows use the sequence
sink API; other one-frame rows use the still-image API, and multi-frame rows
use the sequence API.
Some oracle outputs are checked in because clean CI source checkouts consume them. They are reproducible through maintained generators, but regeneration requires the exact source assets and pinned oracle. In particular, AV1's index and five sidecars form one input set. Do not delete them just because they are generated. AVIF provenance describes how to regenerate them.
Coverage and focused work¶
Use Coverage MCP for source observations with the exact selected fixture IDs and source revision. Report all four aggregate totals (lines, branches, functions, and regions). Selected-case reports do not establish full coverage, and missing observations are not automatically regressions.
Successful still-image AVIF decode parity rows also require inspect,
inspect_basic, and inspect_with_policy to agree. They compare source and
color metadata through the public accessors against decode output, including
normalized auxiliary-item relationships. Sequence metadata has separate parity
coverage because its decoded frame source can include sequence-only item data.
For focused exploration, pass one or more exact manifest keys to
make coverage-selected, separated by spaces:
make coverage-selected COVERAGE_CASES='decode:webp:lossy_vp8 encode:png:enc_rgb'
Use make coverage-parity to execute the complete active decode/encode matrix
through the parity harness. Planned rows are retained in the report as not
executed; fault-contract rows and ordinary unit tests are excluded. The command
also retains its LLVM report, log, and local evidence receipt under
.coverage-mcp/local-evidence/selected/, using the same source and fixture
identity checks as focused selected coverage.
Use make coverage-matrix to include all declared fault-contract rows with the
decode/encode parity matrix in one retained coverage report. Planned rows remain
reported as not executed, and ordinary unit tests are not run. Fault-contract
rows exercise deterministic target-only failures and are reported separately
from Pillow parity results within the retained evidence.
Full coverage uses target/cargo-llvm-cov/full; selected coverage uses
target/cargo-llvm-cov/selected. Each is isolated from ordinary and feature-matrix
builds. Full runs use Cargo's host layout and selected runs pass an explicit
--target; sharing their cache lets LLVM-Cov collect old executables from both
layouts and change the reported denominator. Existing cache contents are retained.
Set COVERAGE_TARGET_DIR to relocate their parent, or set
COVERAGE_FULL_TARGET_DIR and COVERAGE_SELECTED_TARGET_DIR individually. Keep
each cache dedicated to its invocation layout. Direct script calls default to
the selected cache and honor an explicit CARGO_TARGET_DIR. Local receipts
record the resolved Cargo output directory.
The runner rejects malformed, duplicate, unknown, and planned-only selections,
then delegates canonical validation and execution to the existing Rust matrix
harness. By default it writes the LLVM report, captured command log, and local
evidence receipt together under a unique
.coverage-mcp/local-evidence/selected/<run-id>/ directory. It prints each
repository-relative path when the run finishes. These artifacts are outside
target/, so target cleanup leaves them in place. They are local, ignored
evidence; keep a separate copy if you need them beyond this checkout's
lifetime.
Set SELECTED_COVERAGE_REPORT to choose another report path. The report, log,
and receipt remain adjacent. The runner accepts paths inside the repository,
rejects paths that resolve outside it, and refuses to overwrite an existing
report, log, or receipt. The receipt records the Git revision and worktree
state, relevant source and fixture hashes, toolchain, target, feature set,
exact command arguments, per-case results, and all four report totals. It is
local evidence, not a registered Coverage MCP source/build receipt.
After a focused run, pass its printed repository-relative report path to
Coverage MCP coverage_gaps and record the returned status and limitations.
The current interface exposes coverage_gaps and coverage_compare; it has no
local CLI bridge or action to register the receipt. MCP may therefore report
source=unverified and tests=unknown. Use coverage_compare with scope
selected_tests to compare two selected reports; this reports observed
coordinates without combining their totals. Use scope incremental only when
the selected report and a resolvable full exploration baseline have compatible
source/build identity, instrumentation, denominator, and known test results.
If the baseline is missing, stale, or incompatible, record that limitation
without claiming aggregate gain or union. Selected reports do not enforce
full-suite floors. This command stays opt-in and is not part of push, release,
or full-coverage CI jobs.
Run make coverage occasionally to refresh a full exploration baseline, not
for every selected increment. Give that report its own directory outside
target/:
mkdir -p .coverage-mcp/local-evidence/full
run_dir="$(mktemp -d .coverage-mcp/local-evidence/full/run.XXXXXX)"
COVERAGE_REPORT="$run_dir/coverage.json" make coverage
This full run still measures the complete source denominator and enforces the configured alpha floors. It is not required for each focused change.
The alpha floors are 59% lines, 46% branches, 52% functions, and 58% regions. No source exclusions are added to reach those floors. Complete coverage retains 100%; every executed test must pass. The evidence guide preserves the distinction between old claim-ledger measurements and the release report.
Optional native coverage exporter¶
The pinned Rust LLVM coverage reader can select a hash-zero unused mapping before a real mapping with the same function name. Historical exports of the same profile and object set depended on object order. The optional native patch recognizes complete unused mappings, prefers real mappings even with zero executions, and retains unmatched unused source regions. It changes mapping selection in LLVM itself; it does not rewrite report counters or omit sources.
The supported setup recipe is native macOS ARM64 with
nightly-2026-07-16 (Rust commit
d0babd8b6b05ef9bb65d42f928cef4129d64cf65, LLVM 22.1.8). Independent source
review and native builds passed on that host. A fresh seven-executable campaign
retained all 110 repository sources and produced identical JSON and LCOV for 18
order labels (17 distinct object orders). All 64 restored positive functions
matched their exact merged-profile tuples; 397 unused-only functions stayed at
zero. A genuine raw-profile subset also preserved real zero-count branch
mappings with two and seven branches. Positive foreign-hash unmatched-unused
retention has source-policy proof only: no natural runtime control occurred.
The descriptor records conditional admission for this pinned native platform.
A separately bound maintained v3 recipe built from the prepared source, passed
real no-op/concurrent reuse, and matched the audited native exports in all 17
distinct object orders. The integrated canonical coverage command also passed
all executed tests and the alpha floors. Construction and command checks are
recorded separately in the evidence guide; the descriptor records
the producer pin and its admission scope. The
first-source-fetch path remains source-reviewed and unexercised. This is an
opt-in contributor tool; another platform and an upstream fixed release have
not been verified.
Install Git, CMake, Ninja and the pinned Rust toolchain with
llvm-tools-preview through the normal contributor setup, then run:
make coverage-exporter-setup
make coverage-with-exporter
make coverage-with-exporter COVERAGE_EXPORTER_TARGET=coverage-complete
The first setup fetches the exact
Rust LLVM source commit,
checks the source and patch hashes, and builds only llvm-cov with two jobs.
LLVM is governed by its upstream license.
Rust runtime dependencies and installed toolchain files remain unchanged.
COVERAGE_EXPORTER_SOURCE=/absolute/path/to/pinned/llvm-project reuses a
prepared clean checkout or the exact reviewed patched checkout without another
download. COVERAGE_EXPORTER_PREFIX=/absolute/path/to/exporter selects an
isolated build directory; its default is under the removable target/ tree.
Setup verifies the descriptor, source, native executable, build configuration
and coupled profile tool on every reuse. Changed or stale bindings fail.
The explicit coverage target uses the documented
LLVM_COV and LLVM_PROFDATA overrides
only for its recursive Make invocation. Conflicting caller overrides, custom
LLVM flags and unsupported toolchain or cross-target settings are rejected.
The setup also rejects custom native build flags or a CMake toolchain file
instead of changing caller settings. The optional alias accepts report names
with spaces or apostrophes. It rejects dollar signs, backticks, double quotes,
backslashes and CR/LF before running a coverage command: the unchanged inner
Make recipes cannot represent those characters literally.
Normal make coverage keeps the normal Cargo command, alpha floors, complete
source denominator and test-failure policy. The strict command still requires
100% for all four metrics. Run setup separately before using the explicit
target; a missing or invalid receipt never triggers a silent download.
Submit a change¶
Run the narrow failing lane first, then the relevant full contract. Explain the first observed divergence and how the pinned oracle behaves. Keep durable implementation nuance beside the relevant source, with public guidance here when it changes contributor procedure. Follow Contributing.
Run make test-feature-matrix to repeat the complete native, WASI, and WASM feature lanes independently.