Plesty Documentation

Quality Gates

Overview of the plesty check gate system — 14 numbered gates plus eight lettered gates that follow the module type.

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

1
Gate runs → PASS → next gate
2
Gate runs → FAIL → print error, stop

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-test writes 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/Device factory, and produces a populated doc_model() — so plesty docs can 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 ExperimentPipeline checks — a single public Experiment subclass, deterministic build_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.File or open(…, "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> --manifest prints 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's config/*.yaml declare 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.json holds an error finding — a parameter the instrument refuses or will not answer, which the module nonetheless declares. Modules with no report published skip it. plesty init field-test is what writes the test the report comes from.

Sections