Skip to content

Coverage contract

Captured: 2026-09-05

Coverage is a merge gate, not an inferred property of the test count. Python and Rust use separate measurements because the CPython extension and supervised worker cross process/runtime boundaries that one coverage runtime cannot merge honestly.

Python release surface

The Python gate runs all native binding, runtime, CLI, and MCP/CodeMode tests with line and branch measurement:

uv run pytest \
  tests/test_main.py \
  tests/test_native_binding.py \
  tests/test_native_runtime.py \
  tests/test_pydantic_ai_capability.py \
  tests/test_commit_judge.py \
  tests/test_python_surface.py \
  --cov=src/vsh --cov-branch --cov-report=term-missing --cov-fail-under=100

Current result: 103 tests, 508 statements, 124 branches, 100% line and 100% branch coverage.

pyproject.toml omits only the generated/static version module. Every maintained Python module in the release surface is included in line and branch measurement.

Rust core

CI installs exact cargo-llvm-cov =0.9.0 with --locked and runs every workspace crate, feature, target, and test under stable Rust 1.95 coverage instrumentation:

cargo llvm-cov \
  --workspace --all-features --all-targets --locked --summary-only \
  --ignore-filename-regex '(vsh-python|vsh-worker)' \
  --fail-under-lines 79 \
  --fail-under-functions 70 \
  --fail-under-regions 81

Current stable-toolchain core result:

Metric Measured Merge floor
Lines 81.48% 79%
Functions 74.65% 70%
Regions 83.05% 81%

The measurement executed 166 Rust tests. The ignore expression affects the threshold report, not test execution. vsh-python is loaded and exercised by the Python/PyO3 suite. vsh-worker is exercised through ten real subprocess protocol/isolation tests. Both report zero when measured only by the parent cargo test profile because they execute in a CPython runtime or a child process; counting those zeros as untested Rust core would misstate both boundaries.

Rust 100% is not a merge target. Mutually exclusive Unix/Windows paths, injected I/O failures, child-process code, and the CPython extension cannot all be represented honestly by one stable-toolchain parent-process report. Chasing a headline number by removing defensive branches or counting generated/subprocess code as covered would weaken the signal. Instead, critical invariants have explicit behavioral tests: single-use reservation finalization, every durable commit boundary, stale writes, workspace/runtime relocation, internal symlink replacement, bounded directory growth, checksummed state corruption, worker frame/output limits, GIL release, and Python panic translation. The active-snapshot function tests additionally cover shared pathlib visibility, recursive mutation preflight, bounded discovery, Unicode search offsets, iterative deep glob matching, and typed call-frame sizing. The aggregate floor prevents broad regressions; these tests protect the high-risk contracts even where platform error branches remain unexecuted locally. Hook coverage additionally exercises immutable canonical evidence, read-only scope, pending feedback, approval, hard-deny exclusion and fail-closed Python handler errors. The Pydantic AI tests register a real capability on Agent, execute every filesystem tool, verify JSON-safe result projection, and preserve review feedback without adding a new lifecycle state.

Judge tests use offline Pydantic AI models and exercise direct pending approval, canonical before/after content, main-agent review/reject feedback, invalid evidence references, incomplete or binary content, content-sharing authorization, bounded input/concurrency, timeout, cancellation, provider failure and stale commit rejection. They verify the integration contract, not a real model's judgment accuracy or resistance to prompt injection.

The optimization additions include a 94,501-case policy-matcher differential oracle, compiled-pattern fast-path comparisons, portable path normalization oracle checks, overlay prefix-sibling visibility and existing generated-operation replay checks. Python acceptance also executes fixture-owning SDK/MCP/separate-process CLI recipes, the actual first-run documentation block and multibyte Unicode output truncation. APFS rejects invalid UTF-8 filename fixtures before snapshot capture; that platform condition is explicit rather than mistaken for a runtime failure.

Rust branch coverage is not claimed: cargo-llvm-cov --branch remains nightly-only and unstable. VSH keeps its production and coverage compiler pinned to stable Rust 1.95, and uses stable region coverage plus explicit adversarial behavioral tests instead of silently adding a nightly toolchain. Python branch coverage remains a hard 100% gate.

Coverage floors may only rise or stay fixed. Lowering or expanding an omission requires an evidence-backed plan change and review.