The runtime-analysis tier complements the ordinary test, coverage, and mutation tiers. It does not need to repeat every behavioral assertion under every interpreter. Each check should retain the cases that can expose failures unique to that check:
- Miri executes code that owns
unsafeinvariants or supplies a distinct input path into such code. cargo carefulruns the native suite against a standard library built with additional runtime checks.- Loom exhaustively explores the small concurrency models selected by the
dedicated
required-features = ["loom"]targets. - Bolero exercises operation sequences that hand-written tests do not cover.
Use [package.metadata.anvil.miri] exclude = true when a package contains no
runtime unsafe code, does not provide a unique path into an unsafe dependency,
and interpreting its suite would mostly repeat functional coverage. The package
continues to compile when selected packages depend on it, and its complete test
suite continues to run natively and under cargo careful.
Package-level exclusions enforce the absence of unsafe code with
#![forbid(unsafe_code)]. cachet applies the prohibition to non-test builds
because its test-only tracing initializer expands through ctor, which carries
an internal allow(unsafe_code) attribute. Its shipped library remains unable
to introduce unsafe code.
Prefer a test-level #[cfg_attr(miri, ignore = "...")] when only one
integration scenario lacks Miri-specific value. The reason must name the
coverage retained elsewhere. Use cfg(miri) to reduce a stress-test cardinality
instead of ignoring the test when a smaller case reaches the same unsafe or
concurrency path. Native test cardinalities must remain unchanged.
Miri-specific reductions should preserve the transition or boundary that makes the test valuable rather than preserving an arbitrary native workload size:
- depth and length guards run just beyond their enforced bound;
- oversized-allocation tests use a lower configurable threshold when the physical chunk boundary itself is not the subject of the test;
- statistical and differential tests retain representative samples while their full populations continue to run natively;
- synchronization tests retain every participating role and at least one complete state transition;
- recorder tests use the minimum supported event-ring capacity unless ring sizing or wraparound is the behavior under test.
Pure runtime limits, stack-safety stress, formatting breadth, code generation,
and safe integration scenarios may be excluded from Miri when direct tests
continue to exercise the unsafe implementation or dependency path they cover.
The native and cargo careful suites remain authoritative for the excluded
stress breadth.
Safe default-constructor, preallocation, formatting, allocation-count, and hash-table rollback tests do not gain additional value merely by running under Miri. Prefer a reasoned test-level ignore for those cases while retaining a smaller test that reaches the package's actual unsafe storage or lifecycle path. Platform-emulation matrices similarly retain representative Miri cases for each unsafe callback/lifecycle transition while leaving exhaustive option and validation combinations to native tests.
The following package-level exclusions are intentional:
- Code-generation and benchmark orchestration packages are covered through generated code in consuming crates or by native process-level tests.
cachetandohnocontain no runtimeunsafecode. Their behavioral suites run natively and undercargo careful; their dependencies retain their own Miri coverage.seismograph_cliandseismograph_runtimeare safe integration layers overseismograph. The unsafe recorder and snapshot implementations remain in the Miri-selectedseismographpackage.rest_over_grpckeeps its runtime transcoding tests under Miri, but omits build-time descriptor and code-generation unit tests. The build half is safe Rust and remains covered by native tests andcargo careful.rallocatorkeeps its library and allocator integration suites under Miri, but omitstests/telemetry.rsandtests/performables_telemetry.rs. Those binaries repeatedly capture and decode process-wide snapshots or validate a safe dependency graph; direct Miri tests in the library,performables, andseismographcover the unsafe internals, while native tests andcargo carefulretain the end-to-end assertions.templated_uriremains selected because it is a consumer-facing integration surface, but deterministic pseudo-fuzz breadth is reduced under Miri.internitykeeps unchecked storage and resolution paths under Miri. Native tests retain default-constructor, preallocation, and hash-table rollback breadth, while a bounded long-string case forces storage growth before resolving every handle under Miri.http_extensionsremains selected as an integration surface, but its native allocation-count test is not interpreted by Miri.performablesretains direct ownership and synchronization coverage. Its channel telemetry integration uses the minimum supported event-ring capacity only under Miri; ring-capacity behavior remains covered inseismograph.seismographretains direct recorder and snapshot coverage. Under Miri its object-sampling population, repeated snapshot count, and default test event ring capacity are reduced while still exercising selection, capture, and buffer lifecycle transitions.fetch_winhttp_implretains callback, raw-context, handle, operation-buffer, and foreign-thread lifecycle coverage. Native tests keep exhaustive TLS, protocol, and port-option matrices; Miri executes representative cases.routeramaremains selected so its unsafe scanned-path and query-scanning helpers execute under Miri. Native-only depth keeps the full stack-safety stress, while Miri uses smaller paths that still cross resolver bounds and exercise iterative teardown.multituderetains direct Miri coverage across its unsafe allocation, ownership, destructor, and chunk-lifecycle paths. Tests use smaller configurable oversized thresholds or bulk initialization when per-element repetition does not add another unsafe state transition.compressorscannot run all backends under Miri; its manifest records the backend-specific rationale.
Do not infer that a safe package is automatically dispensable.
rest_over_grpc, for example, remains selected because its runtime tests
provide the workspace's Miri coverage for the transcoding buffer path over
bytes and hyper.
The current cargo-anvil catalog supports only package-level Miri exclusion:
[package.metadata.anvil.miri]
exclude = trueIt does not expose supported package metadata for excluding individual test
targets. Consequently, --all-features --tests may compile and replay empty
Loom or Bolero executables whose source is disabled by cfg(loom) or
cfg(not(miri)). Do not hand-edit generated justfiles/anvil/** to remove
them. Target-level omission requires a cargo-anvil catalog enhancement.
The Bolero recipe likewise has no supported manifest target-exclusion metadata;
on Linux it discovers every bolero::check! target and gives each a 60-second
libFuzzer smoke campaign. Repository code must not silently shorten or remove
attacker-facing and unsafe-lifecycle campaigns to work around this limitation.
Use the generated recipe with impact analysis disabled when evaluating the complete validation boundary:
$env:ANVIL_IMPACT = 'off'
just anvil-pr-runtime-analysisCompare warm runs on the same host and toolchain. Report compilation separately when a clean build is relevant; otherwise, runtime comparisons should not claim compiler-cache changes as test improvements.