plesty check runs a sequential gate pipeline. The first failure terminates the check — fix it and re-run. This design makes the output actionable: you always have exactly one thing to fix.
How it works
Pre-push hook
plesty init installs a pre-push hook that runs plesty check automatically before every git push. The standard it enforces comes from [tool.plesty] standard in pyproject.toml when that key is set:
cat .git/hooks/pre-push
# #!/bin/sh
# unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE … (git's own hook variables)
# uv run plesty check
The hook clears git's own variables first, so the checks that call git themselves see the project and not the push in progress.
This means you cannot push code that fails the compliance check without explicitly bypassing the hook (which is strongly discouraged).
The standard ramps with your version
Set no [tool.plesty] standard and the standard is derived from the release
version you declare, so a prototype is not held to release rules on day one
and a released module cannot quietly stay on prototype rules:
| Declared version | Standard |
|---|---|
< 0.1.0 — or no release tag yet |
pixel |
< 1.0.0 |
nebula |
>= 1.0.0 |
quantum |
A fresh plesty init scaffold therefore starts at pixel, and the tier rises
on its own as you release. plesty check prints which rule it applied
(derived from version 0.2.1, or from [tool.plesty] standard), so the
answer is never a guess.
Two things override the ramp: an explicit [tool.plesty] standard always
wins, and a project declaring no version at all falls back to quantum — the
conservative default. A dynamic version (versioningit) is read from the latest
git tag.
The --standard flag on plesty init sets only the tier written into the
generated .gitlab-ci.yml; bump that input alongside your releases.
Gate summary
| # | Gate | Tier | Standard |
|---|---|---|---|
| 1 | Metadata & Namespace | [SDK+CI] |
pixel |
| 2 | Code Hygiene | [SDK+CI] |
pixel |
| 3 | API Interface Matching | [SDK+CI] |
nebula |
| 4 | Data Layer Compliance | [SDK+CI] |
nebula |
| 5 | Documentation Completeness | [SDK+CI] |
nebula |
| 6 | Dependency Coexistence | [SDK+CI] |
nebula |
| 7 | Automated Test Coverage | [SDK+CI] |
quantum |
| 8 | Semantic Versioning | [SDK+CI] |
quantum |
| 9 | Licensing Compliance | [SDK+CI] |
quantum |
| 10 | Vulnerability Audit | [SDK+CI] |
quantum |
| 11 | Docs Build | [SDK] |
quantum |
| d1 | Device API Pipeline | [Device] |
quantum |
| d2 | Device Status Contract | [Device] |
quantum |
| d3 | Device Docs | [Device] |
quantum |
| a1 | Analyzer Contract | [Analyzer] |
quantum |
| e1 | Experiment Contract | [Experiment] |
quantum |
| e2 | Experiment Persistence | [Experiment] |
quantum |
| e3 | Experiment Manifest | [Experiment] |
quantum |
| f1 | Field Test Findings | [SDK] |
quantum |
| 12 | Docs Deploy | [CI] |
quantum |
| 13 | Secret Detection | [CI] |
quantum |
| 14 | Build & Release | [CI] |
quantum |
Seven of the lettered gates are activated by module_type in [tool.plesty] and
report N/A otherwise — so a module is only ever held to its own type's rules:
module_type = "device"
- d1 — Device API Pipeline: a test calls
DevicePipeline.run_mock_pipeline()and passes without hardware — one call runs all eight mock gates.plesty init mock-testwrites that test. See Testing devices. - d2 — Device Status Contract: the device reports its state the way every consumer expects, so a client can ask what is wrong without knowing the instrument.
- d3 — Device Docs: the package imports, exposes a hardware-free
DocDevice/Devicefactory, and produces a populateddoc_model()— soplesty docscan generate the Parameters / Functions / Standard Methods pages with no hand-written content.
module_type = "analyzer"
- a1 — Analyzer Contract: the analyzer implements the interface an experiment drives it through.
module_type = "experiment"
- e1 — Experiment Contract: the five
ExperimentPipelinechecks — a single publicExperimentsubclass, deterministicbuild_plan(), resolvable step operations, JSON-serializable plans, async lifecycle hooks. See Testing experiments. - e2 — Experiment Persistence: no ad-hoc persistence in the package — no
np.save,pickle.dump,h5py.Fileoropen(…, "w"). Results are saved through plesty-lib (save_result,ResultDocument), so every run's data has the same readable shape. - e3 — Experiment Manifest:
python -m <module> --manifestprints the run contract, every configuration setting carries a type and a description (and a unit where it is bounded), and the schema and the module'sconfig/*.yamldeclare the same keys — which is what lets PLESTY Bench lay the settings out as a form.
Any module type
- f1 — Field Test Findings: no published
reports/<instrument>/field-test.jsonholds anerrorfinding — a parameter the instrument refuses or will not answer, which the module nonetheless declares. Modules with no report published skip it.plesty init field-testis what writes the test the report comes from.
Sections
- Pixel & Nebula gates (1–6) — fast local checks
- Quantum gates (7–11 + the lettered gates) — full verification
- CI-only gates (12–14) — run in GitLab CI only