Skip to main content

emlint

emlint logo

PyPI version Python versions CI Codecov Documentation License Downloads

stim simulates. sinter samples. emlint verifies.

emlint is a static linter for Stim Detector Error Models (DEMs). It finds structural problems before simulation.

Why emlint?

  • Catch DEM bugs before the expensive simulation. A silent DEM bug can inflate logical error rates and may not surface until 10⁶ simulation shots (≈45 min). emlint finds structural problems in milliseconds.
  • Counter-examples. A failing check identifies the offending mechanism, detector, or observable, so you know where to look.
  • Severity that respects the stakes. error findings are unconditional DEM bugs; warning findings are heuristic or intentional-pattern candidates you review before acting.
  • Agent- and CI-friendly. Exit codes distinguish clean, error, warning, and unlintable input; JSON and SARIF output feed scripts and code-scanning tools.

See it in action

A d=5 surface-code DEM with a missing detector connection (examples/buggy.dem):

$ emlint check examples/buggy.dem
Detectors: 24  Observables: 1  Error mechanisms: 31

  ✓ detectability: All error mechanisms that flip observables also trigger detectors.
  ✗ [warning] sensitivity: 1 detector(s) are never triggered by any error mechanism.
        Counter-example: Detector(s) not triggered by any error mechanism: D17@(1,0,2)
        Hint: Hypothesis: a detector no mechanism ever triggers is either miswired or
        redundant. Expected shape: at least one mechanism per stabilizer check per
        round; look for a missing noise instruction on the gates feeding this detector,
        or a DETECTOR declared on a comparison that never receives a fault.
  ✓ observable_coverage: All declared observables are flipped by at least one error mechanism.
  ✓ probability_bounds: All error mechanism probabilities are in (0, 0.5].
  ✓ duplicates: No duplicate mechanism signatures found.
  ✓ correctability: Every syndrome maps to at most one distinct set of logical observables.
  ✓ null_mechanism: No mechanism has empty detector and observable support.

After reconnecting D17 to its neighbours (examples/fixed.dem), every check passes. The counter-example names the exact detector (D17@(1,0,2)) so the fix is localized. More generated examples live in examples/.

v0.2 is preliminary. The user-facing behavior is usable, but internal APIs and implementation details may change before v1.0.

Quick start

Install emlint:

pip install emlint

Lint a DEM file or raw DEM text:

emlint check circuit.dem
emlint check 'error(0.01) D0 L0
detector D0'

A failing result includes a counter-example identifying the relevant mechanism, detector, or observable. Select checks with --only/--ignore, or emit SARIF for code-scanning tools:

emlint check circuit.dem --only detectability,sensitivity
emlint check circuit.dem --format sarif > emlint.sarif

Project defaults can be placed in pyproject.toml under [tool.emlint]. For all command options, configuration examples, and exit codes, see the CLI reference.

Python

import emlint
import stim

circuit = stim.Circuit.generated(
    "surface_code:rotated_memory_z",
    distance=3,
    rounds=3,
    after_clifford_depolarization=0.001,
)
report = emlint.check(circuit.detector_error_model())
print(emlint.format_text(report))

emlint.check() also accepts a raw DEM string or an explicit pathlib.Path.

Documentation

Guide Use it for
CLI reference Commands, options, output, and exit codes
Agent integration guide Running emlint in a coding-agent fix-loop: exit-code handling, JSON contract, context declaration
Check catalog What the seven checks detect and how to interpret findings, plus the machine-readable output contract
Debugging guide Check-specific causes and investigation steps
Formal grounding DEM vocabulary and formal properties
v0.2 limitations Scope, warnings, repeat blocks, and provisional behavior
Changelog Version history and user-visible changes

Note: on DEMs produced with decompose_errors=True, the duplicates check (warning) may report mechanisms that share a detector signature after graphlike decomposition as "duplicates". This is expected decomposition output, not a concatenation bug. Use the graphlike-decoder profile context when a graphlike matcher is the intended decoder.

Exit codes

Code Meaning
0 All checks passed
1 At least one error-severity finding
2 Warnings only
3 Unlintable input (unreadable or unparseable)

Treat exit code 3 as an input failure, not as findings: an agent loop that parses the report on exit 3 would reason about a DEM that emlint never saw.

Epistemic boundary: emlint analyzes DEMs only. Its findings establish structural properties of the DEM itself; they do not establish that the underlying circuit is semantically correct, nor that a decoder succeeds. Circuit-level verification (e.g. with stim) remains necessary.

CI

For a minimal GitHub Actions setup, install emlint and run it on changed DEM files:

- name: Install emlint
  run: pip install emlint
- name: Lint DEM files
  run: find . -name "*.dem" -print0 | xargs -0 -r -n1 emlint check

For local commits, the repository includes a pre-commit hook configuration:

pip install pre-commit
pre-commit install

The hook runs emlint check --severity error on staged .dem files. Warning-only findings remain non-blocking; input failures still return exit code 3.

Contributing

See CONTRIBUTING.md for development setup, how to add a check, test requirements, and quality gates.

Acknowledgments

emlint is developed with AI assistance for scaffolding, test generation, red-teaming, and documentation. All design decisions, technical content, and final code are reviewed and owned by the maintainers.

Funding

This project is funded by a Mozilla Foundation fellowship and supported by the Unitary Foundation.

License

Apache 2.0

Metadata

Release files for emlint 0.2.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for emlint 0.2.3
File Size Uploaded Provenance Actions
emlint-0.2.3.tar.gz 102.0 kB With provenance Details for emlint-0.2.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for emlint 0.2.3
File Interpreter ABI Platform Actions
emlint-0.2.3-py3-none-any.whl Python 3 none any Details for emlint-0.2.3-py3-none-any.whl

Total release size: 143.8 kB

Release files / emlint-0.2.3.tar.gz

Download URL emlint-0.2.3.tar.gz
Size 102.0 kB
Tags Source
SHA-256 checksum
How to use checksums
0019a470c83e2ce83947b9a984faf9c0852f2e8d2e5933ee8deb41e8960f0547
BLAKE2b-256 checksum
How to use checksums
8e585b40e168e56cdce064d937844556acca41acb1a3a8790d1ebe21a3ccfd62
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / emlint-0.2.3-py3-none-any.whl

Download URL emlint-0.2.3-py3-none-any.whl
Size 41.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e1369a826e59fd13a641f08f644b0ce91c895e7045f9ff0dfb7c13ca9b58133b
BLAKE2b-256 checksum
How to use checksums
5119d9820a31fda60b23f6aeb3a2fe8ea0f22a571163f80bc0920bd81ef2276b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Security for emlint 0.2.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for emlint-0.2.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page