Development

Canonical verification command

Run the complete local verification verdict:

make verified

make verified is the command to cite when reporting a branch as green. It first brings the native build up to date, then runs the subject-identity-aware runtime suite (verified-test), configuration and generated-file checks (config-check), Ruff lint, mypy, and the Ruff format check. The aggregate is fail-fast: a red verdict identifies the first failing constituent, not every failure that may be present. Ruff deliberately covers pstrain and tests, matching the blocking CI lint job; repository-wide Ruff also includes pre-existing vendored and utility scripts outside that scope.

The aggregate invokes the checks directly instead of running pre-commit. This keeps verification non-mutating and avoids hook-environment setup and unrelated repository-hygiene hooks. The tradeoff is that the Ruff format command and its scope are repeated in the Makefile and CI and must remain aligned.

Individual build and test commands

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_CLI=ON
cmake --build build --parallel
ctest --test-dir build --output-on-failure --no-tests=error
pip install -e ".[dev,test,docs]"
PSTRAIN_REQUIRE_CLIB=1 pytest

Always configure CMake from the repository root. The Makefile provides build-c and test shortcuts for these individual steps. make test is a runtime-suite shortcut, not a complete verification verdict; use make verified for that verdict.

Changing the native interface

Python reaches libpstrainc through the declarations in the CDEF string in pstrain/lib/_cffi/cdef.py. Because cffi resolves symbols lazily, a library built from older sources can load and then fail much later. Two load-time checks in pstrain/lib/_cffi/core.py reject such a stale library instead:

  • Interface fingerprint. make cffi-exports-gen writes a hash of the exact CDEF text into csrc/libs/libpstrain/pstrain_interface_fingerprint.h, alongside the linker export lists. The library returns it from pstrain_interface_fingerprint(), and Python compares it with the hash of the CDEF it loaded. After any edit to CDEF, rerun make cffi-exports-gen and commit the regenerated files; make config-check fails until you do. No version bump is needed for an added, removed, or re-typed function or a changed struct.

  • ABI version. PSTRAIN_ABI_VERSION in csrc/libs/libpstrain/pstrain_align.h must equal the same constant in core.py. Bump both only for a change of meaning behind unchanged declarations, such as a function whose signature stays the same while its return contract, ownership rule, or units change. The fingerprint cannot see that kind of change.

Building documentation

make docs

This runs the existing Sphinx HTML build. Configuration-reference generation is available separately as make docs-gen.

Code Quality

# Linting
ruff check pstrain tests

# Type checking
mypy pstrain

# Formatting
ruff format --check pstrain tests

# All repository hooks
pre-commit run --all-files