Contributing

The press accepts contributions that follow its laws (see the architecture guide: facts once, generators over checkers over conventions, artifacts verified as objects, scars become law).

One command to verify

From a clean checkout with pip install -e '.[dev]', run the whole local proof, fast layers first:

scripts/verify.sh          # lint + type + selftest + pytest, then the
                           # coverage and mutation ratchets and the site build
scripts/verify.sh --quick  # stop after the fast lint/type/test layer
scripts/verify.sh --full   # also run CI's container gauntlet locally (Docker)

CI calls these same tools. --full additionally runs the integration gauntlet in the pinned toolchain image (scripts/gauntlet.sh) — build the wheel, scaffold a stranger’s book, run the whole press all, and prove tampering turns the verifier red — so the container tier where rendered-artifact bugs surface is proven before you push, not on the CI round-trip. It runs natively on Apple Silicon since the toolchain image went multi-arch (needs Docker). Only the live second-party proofs (a fork-PR from another account, a private book in another org) stay CI/human-only. Do not run scripts/coverage_ratchet.py --update: it re-measures on your machine and can push the committed baselines above the floor CI enforces.

Iterating on a render

scripts/verify.sh --full runs the whole gauntlet; when you are tuning one thing — a template, a Lua filter, an aesthetic — and want to look at the output, scripts/dev-render.sh builds a single book in the same pinned toolchain image and hands the artifacts back on the host:

scripts/dev-render.sh                          # build Alice's PDF (the default book)
scripts/dev-render.sh pdf --preview            # + JPEG page previews to open
scripts/dev-render.sh all --book ~/code/make-ready
scripts/dev-render.sh --shell                  # a shell inside the toolchain

It mounts your checkout read-only and runs python -m press from src/, so a source edit takes effect on the next run with no reinstall, and it reads the toolchain image straight from build.yml so it can never drift from CI. Artifacts land in build/dev-render/dist, previews in build/dev-render/preview. This is a convenience for the edit–render–look loop, not a substitute for the gauntlet: prove with verify.sh --full before you push.

What a proof has to prove

Coverage measures that a line ran, not that its output was right. A branch can execute under an integration test whose only assertion is “it built” — and ship a wrong result. That is exactly how a title-page generator shipped a dropped and a clipped cover at 11.5% coverage: the lines ran, the artifact was never inspected.

So the bar is the artifact, not the line count:

Filing and proposing

Open issues through the issue forms (defect, proposal, documentation); a defect asks for press doctor, press selftest, the version, and a minimal reproduction. Report security vulnerabilities privately per the security policy, never as a public issue. Pull requests follow the template: a test that fails before and passes after, regenerated projections, and the compatibility impact.

This project has one maintainer; how decisions, releases, and conduct are handled is in the governance doc, and participation is under the Code of Conduct.