Skip to main content
ProofFrame

ProofFrame

PyPI Crates.io docs.rs CI Codecov DeepSource License MSRV

Relational Arrow contracts, exact dataset rules, and verifiable evidence.

ProofFrame is a Rust-native data quality engine for PyArrow, Pandas, Polars, CSV, Parquet, and Arrow streams. It compiles strict contracts against the physical schema, scans record batches without turning rows into Python objects, and produces evidence that can be stored, compared, and signed.

Why ProofFrame

Most data checks answer one question: did the table pass? Production systems usually need three:

  1. What exactly was checked? Versioned BLAKE3 fingerprints identify the ordered dataset.
  2. Why did it fail? Exact violation counts and bounded row-level findings explain the verdict.
  3. What changed? Keyed diffs report added, removed, and changed records without loading both datasets into memory.

ProofFrame keeps these answers deterministic and resource-bounded. Exact uniqueness, diff, and leakage operations have explicit memory, temporary-storage, sample, and output limits. Corrupt temporary data, incompatible schemas, ambiguous contracts, and exceeded limits fail closed.

Current release — 0.5.1

0.5.1 adds strict cross-column and conditional rules, exact dataset-level constraints, deterministic partition validation, and ordered partition manifests. Python and Rust execute the same native plan. V1 contracts and both fingerprint protocols remain frozen.

Install

Python 3.10–3.13:

pip install proofframe==0.5.1

Rust 1.85 or newer:

cargo add proofframe@0.5.1

The 30-second demo

import pyarrow as pa
import proofframe as pf

orders = pa.table({
    "order_id": [101, 102, 103],
    "subtotal": [12.50, 8.00, 10.00],
    "total": [12.50, 7.50, 10.00],
})

contract = {
    "version": "proofframe.contract.v2",
    "columns": {},
    "row_rules": [{
        "name": "total_covers_subtotal",
        "compare": {
            "left": {"column": "total"},
            "op": "gte",
            "right": {"column": "subtotal"},
        },
    }],
    "dataset_rules": {
        "row_count": {"min": 1},
        "distinct_ratio": {"order_id": {"min": 1.0}},
    },
}

report = pf.check(
    orders,
    contract,
    max_memory=64 << 20,
    max_temp=512 << 20,
    max_samples=20,
)

assert report["valid"] is False
assert report["violation_count"] == 1

The contract is compiled before scanning. Unknown fields, missing required columns, invalid bounds, and rules that do not match the Arrow type are rejected before the first row is processed. violation_count remains exact even when the retained findings sample is truncated.

Cross-column and conditional rules

V2 compares Arrow values in their physical type. It does not cast through Python objects or parse an expression language at runtime.

shipments = pa.table({
    "ordered_at": [1, 3],
    "delivered_at": [2, 2],
    "status": ["delivered", "pending"],
    "tracking_id": ["TR-1", None],
})

contract = {
    "version": "proofframe.contract.v2",
    "columns": {},
    "row_rules": [
        {
            "name": "delivery_window",
            "compare": {
                "left": {"column": "ordered_at"},
                "op": "lte",
                "right": {"column": "delivered_at"},
            },
        },
        {
            "name": "delivered_has_tracking",
            "when": {
                "left": {"column": "status"},
                "op": "eq",
                "right": {"literal": "delivered"},
            },
            "assert": {"column": "tracking_id", "not_null": True},
        },
    ],
}

report = pf.check(shipments, contract)

Comparisons support signed and unsigned integers, floats, booleans, UTF-8, dates, timestamps, and decimal128 where the Arrow types are compatible. Null behavior is explicit. Conditional assertions cover nullability, numeric bounds, allowlists, patterns, and NaN policy without building a row mask.

Dataset-level rules and partitions

Dataset rules keep exact state across record-batch and partition boundaries. Distinct and composite keys use canonical values, not hash-only identity. When the memory budget is reached, sorted, checksummed runs spill under the configured temporary-storage limit.

partitions = [
    pa.table({"order_id": [101, 101], "line_id": [1, 2]}),
    pa.table({"order_id": [102], "line_id": [1]}),
]

contract = {
    "version": "proofframe.contract.v2",
    "columns": {},
    "dataset_rules": {
        "row_count": {"min": 3},
        "distinct_ratio": {"order_id": {"min": 0.5}},
        "composite_unique": [{
            "name": "line_key",
            "columns": ["order_id", "line_id"],
        }],
    },
}

report = pf.check_partitions(partitions, contract, threads=2)
assert report["valid"] is True

pf.check_partitions_with_evidence additionally returns an ordered manifest binding every partition's V2 fingerprint, row count, schema, contract, compiled plan, result contribution, global result, and resource settings. Reordering, omission, duplication, or mixed identities fails verification.

One engine, several proof operations

Fingerprint a dataset

legacy = pf.fingerprint(orders, version="v1")
current = pf.fingerprint(orders, version="v2")

Fingerprints bind schema, row and column order, nulls, type tags, and canonical values. They do not depend on Arrow display formatting and remain stable across record-batch boundaries. V1 is frozen for existing proofs; V2 is a separate protocol for new evidence.

Diff by business key

changes = pf.diff(
    before,
    after,
    keys="order_id",
    max_memory=256 << 20,
    max_temp=2 << 30,
    max_samples=100,
    output="changes.jsonl",
    spill="auto",
)

Counts are exact. Samples stay bounded, while full change records can be written atomically as JSON Lines or Arrow IPC. Duplicate keys and schema mismatches fail loudly.

Create verifiable evidence

checked = pf.check_with_evidence(orders, contract, max_samples=20)
report = checked["report"]
evidence = checked["evidence"]

assert report["valid"] is False
assert evidence["schema"] == "proofframe.evidence.v2"

Evidence V2 binds the dataset fingerprint, canonical contract source, compiled plan, Arrow schema, engine version, resource limits, and result. Signed receipts use Ed25519 and separate cryptographic validity from signer trust. Keep signing material in a secret manager and verify against a public key obtained independently from the receipt.

Find PII and train/test leakage

pii = pf.scan_pii(customers)
overlap = pf.detect_leakage(train, test, keys="user_id")

PII findings contain the class, column, row, confidence, and a keyed fingerprint—not the matched value. Leakage reports support business keys or full-row identity and expose only bounded hashed samples.

Arrow-native by design

Pandas / Polars / PyArrow / Arrow C Stream / CSV / Parquet
                           |
                           v
                  Arrow record batches
                           |
          +----------------+----------------+
          |                |                |
       contracts       fingerprints      keyed diff
          |                |                |
          +----------------+----------------+
                           |
                           v
              deterministic JSON evidence

Known DataFrame containers provide exact row and logical-byte hints. Stream-only inputs remain streaming. The Rust scan releases the Python GIL, and the ProofFrame crate itself uses #![forbid(unsafe_code)].

CLI

proofframe check data.parquet --contract contract.json --max-memory 256MiB --max-temp 2GiB
proofframe fingerprint data.csv --fingerprint-version v2
proofframe diff old.parquet new.parquet --key order_id --output changes.jsonl
proofframe evidence data.parquet --contract contract.json --output evidence.json
proofframe verify receipt.json --expected-public-key "$PROOFFRAME_PUBLIC_KEY"
Exit code Meaning
0 Operation succeeded; check or receipt is valid
1 Contract violation or invalid receipt
2 Invalid input, contract, or command configuration
3 Engine, I/O, schema, or corrupt-data failure
4 Resource limit exceeded

JSON is emitted only after a successful operation. File outputs use same-directory temporary files, fsync, and atomic replacement.

Rust core

The default crate has no Python dependency. Rust users get the same compiled contracts, typed Arrow kernels, fingerprints, evidence, receipt verification, resource accounting, and spill engine used by the Python wheels. See the crate guide and API documentation.

Compatibility and performance evidence

The 0.5 line preserves V1 fingerprints and the established compatibility entry points. New work should use check, explicit fingerprint versions, Evidence V2, and Receipt V2.

Performance claims are tied to raw samples, dataset hashes, compiler and package versions, and machine metadata. The committed smoke harness is deterministic; the pinned 7,645,034-row Bitcoin comparison remains a dedicated-runner gate rather than a published benchmark claim. See testing and benchmark methodology.

Release integrity

The release workflow packages the exact wheel, sdist, and crate subjects before publication. It emits deterministic SHA-256 checksums, SPDX JSON SBOMs, GitHub build-provenance attestations, and SBOM attestations. PyPI uses trusted publishing; crates.io publication is gated by the same tagged commit and CI evidence. These controls support provenance verification, but they are not a claim of formal SLSA certification.

Development

cargo test --locked --all-targets --all-features
cargo clippy --locked --all-targets --all-features -- -D warnings
maturin develop --release --locked
python -m pytest -q

CI covers Rust 1.85, Python 3.10–3.13 on Linux, macOS, and Windows, portable wheels, release-mode allocation contracts, Miri-compatible state machines, fuzz targets, source-package hygiene, coverage, DeepSource, and SonarCloud.

License and security

ProofFrame is licensed under Apache-2.0. Report vulnerabilities through the process in SECURITY.md. Sponsorship is available through GitHub Sponsors.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

proofframe-0.5.1.tar.gz (138.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

proofframe-0.5.1-cp310-abi3-win_amd64.whl (1.9 MB view details)

Uploaded CPython 3.10+Windows x86-64

proofframe-0.5.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.9 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

proofframe-0.5.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.8 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

proofframe-0.5.1-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (3.5 MB view details)

Uploaded CPython 3.10+macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file proofframe-0.5.1.tar.gz.

File metadata

  • Download URL: proofframe-0.5.1.tar.gz
  • Upload date:
  • Size: 138.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for proofframe-0.5.1.tar.gz
Algorithm Hash digest
SHA256 a700a0018caaefbb163c833cbc51ab7a9fde11351438235b2f4ba598680d1487
MD5 c32cd50dea7ce2eac676cebb3471f889
BLAKE2b-256 06f213ae1ae57ad8f85db6c2bb0d5ac454d77cb5a74187ad8a5359b616ec294c

See more details on using hashes here.

Provenance

The following attestation bundles were made for proofframe-0.5.1.tar.gz:

Publisher: publish.yml on emirhuseynrmx/proofframe

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file proofframe-0.5.1-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: proofframe-0.5.1-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.9 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for proofframe-0.5.1-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 105de314d6c06f79be9a3f999b199e91b85bea908523405c01877ac611e6aca1
MD5 d47a902097d616dbde30739b2057dda0
BLAKE2b-256 d41b76e5b8b9e13b12fc80e9003b96b51a8c2a5c5bec93e91556d492e518243b

See more details on using hashes here.

Provenance

The following attestation bundles were made for proofframe-0.5.1-cp310-abi3-win_amd64.whl:

Publisher: publish.yml on emirhuseynrmx/proofframe

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file proofframe-0.5.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for proofframe-0.5.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 546602ecc446a4303b2a41fda96834c5e224b6edc808d78b732cf5ffe5a110f5
MD5 a2b2ba1276e3226ee583fdd20b930093
BLAKE2b-256 7a56f37d6e81d48d543a4c62b026a8d166cc40c227b405ae810ce3cf1666c642

See more details on using hashes here.

Provenance

The following attestation bundles were made for proofframe-0.5.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on emirhuseynrmx/proofframe

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file proofframe-0.5.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for proofframe-0.5.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 c356bf61560c08e954bfd7ac26e814f135cbbe9054b785244a06d01d3e27bb3c
MD5 9372a83e7de16e7868092080a38704da
BLAKE2b-256 ebf4842904b9c7ca8b58c8b565dc7ff3a3ca842d82d0b3ed9f82e911c6663511

See more details on using hashes here.

Provenance

The following attestation bundles were made for proofframe-0.5.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on emirhuseynrmx/proofframe

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file proofframe-0.5.1-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for proofframe-0.5.1-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 09c5e4eac41771a9fcbbf82535a5cffb34159b90b396d04571118734bc5b90f5
MD5 4b1a89dd77010585763de041a1cfad28
BLAKE2b-256 d0b8493917016f079f1f394953c58c5b1cc81358be59dad15e1d417522b22229

See more details on using hashes here.

Provenance

The following attestation bundles were made for proofframe-0.5.1-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:

Publisher: publish.yml on emirhuseynrmx/proofframe

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.5.1 This release

5 files

0.5.0

5 files

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