Deployment Bundles Guide

Use ONNX bundles as the supported deployment handoff artifact. They keep the strict SCM inference contract together with the metadata needed to validate and reload it.

Install the deployment workflow dependencies with:

python -m pip install "zeroproofml[deployment]"

Export checks required dependencies before creating an output directory. ONNX Runtime remains lazy for export-only workflows and is required only when a runtime session is loaded.

Export writes into a temporary sibling directory, validates the completed schema-v3 bundle and model digest, then publishes it. By default, an existing bundle directory is wholly replaced only after validation succeeds; old and new files are never merged. Pass overwrite=False to fail before export when a target already exists.

Bundle contents

An exported bundle includes at least:

  • model.onnx
  • metadata.json
  • metadata.sha256 (a detached canonical manifest digest written at export)

Validation and regenerated report artifacts typically live beside those files:

  • VALIDATION_REPORT.md
  • VALIDATION_REPORT.summary.json
  • VALIDATION_REPORT.summary.svg

Export and validate

from zeroproofml.inference import (
    StrictDecodePolicy,
    export_bundle,
    load_onnx_runtime_bundle,
    run_bundle_reference_smoke_test,
    validate_bundle,
)

policy = StrictDecodePolicy(
    rejection_threshold=1e-5,
    ambiguity_band=1e-6,
    coordinate_axis=None,  # use -1 for a shared-denominator last-axis tuple
)
export_bundle(
    projective_model,
    (x_example,),
    "bundle_dir",
    decode_policy=policy,
)
validate_bundle("bundle_dir")

runtime = load_onnx_runtime_bundle("bundle_dir", providers=["CPUExecutionProvider"])
result = runtime.run(x_numpy)
payload = result.payload
operational = result.operational

run_bundle_reference_smoke_test("bundle_dir", projective_model, (x_smoke,))

Use run_bundle_reference_smoke_test(...) before shipping so the exported ONNX path is checked against typed decoding of the raw projective Python model on a known sample.

For a custom shared-denominator tuple model, set both projective_coordinate_axis and projective_denominator_contract="shared_denominator_by_construction_v1" only after reviewing that the denominator is constructed from one value for every runtime input. An axis declaration without that capability is refused before ONNX tracing. The graph retains a tensor-native equality check as defense in depth; a runtime disagreement is a typed representation fault and rejection.

What downstream consumers should rely on

  • metadata.json embeds decoder_policy and binds it through semantic_identity.decoder_policy_sha256
  • decoder_policy.coordinate_axis distinguishes elementwise pairs from a shared-denominator tuple and is part of that hash
  • semantic_identity.refinement_profile_id names onnxruntime-cpu, while the hashed execution_runtime freezes CPUExecutionProvider order and options
  • schema-v3 ONNX output order is payload, core_presence, core_status, semantic_domain, execution, observation, operational, representation, compilation, ambiguity, exact_zero_evidence, cause_code
  • schema-v3 metadata requires model_bytes and model_sha256 for integrity binding
  • validate_bundle_descriptor(...) returns a ValidatedBundleDescriptor containing verification status and model hashes
  • compute_bundle_manifest_sha256(...) is stable across JSON whitespace and object-key ordering
  • Python runtime loading reconstructs ResultTensor; status axes remain independent and are not projected into a merged bottom mask
  • schema-v3 runtime overrides must match the recorded provider contract;
  • generated validation reports surface the schema-v3 gauge, decoder policy and coordinate axis, semantic ABI, refinement profile, runtime provider contract, and their binding hashes instead of empty legacy threshold fields; unrecorded session options are refused
  • recorded schema-v1 merged_only_masks and deprecated experimental_provenance_outputs bundles remain valid under their own metadata as unverified legacy bundles

Previously exported bundles are validated under their recorded schema and metadata, including strict_inference_schema_version, strict_inference_exports, and any inference_output_schema or legacy experimental_inference_output_schema sidecar. They are not silently reinterpreted under the new hardened schema.

Schema-v3 typed bundles are the default and carry their complete decoder policy beside the hashed semantic_identity. They must not also carry legacy tau_infer or tau_train fields: duplicated thresholds could contradict the policy identity while appearing to validate under the same artifact hash. Schema-v1 and schema-v2 bundles continue to require and validate their recorded threshold fields.

Passing a legacy SCMInferenceWrapper to schema-v3 export requires an explicit decode_policy. The exporter unwraps the raw projective model only after that policy is supplied; it refuses to reinterpret the wrapper's raw-abs(Q) threshold as a canonical denominator-score threshold.

Schema v2 is an explicit compatibility export selected with bundle_schema_version=2; it requires InferenceConfig and returns the merged six-output contract. For those bundles, fault_mask and semantic_bottom_mask are not disjoint. A sample with both an IEEE-fault payload and a below-threshold denominator sets both split masks. Consumers reading the split masks see the full picture; consumers reading bottom_provenance alone see the same four-state picture through NONE, FAULT, SEMANTIC, and MIXED.

The promoted bundle metadata name is inference_output_schema. Recorded bundles that still use experimental_inference_output_schema validate as a compatibility alias and emit DeprecationWarning. New bundles should not write the old key.

Treat that metadata as part of the deployment interface, not as an optional comment.

Integrity is not publisher authenticity

The model digest in metadata.json detects accidental corruption only when the metadata is itself trusted. Likewise, metadata.sha256 is a convenient detached transport file, not an authenticity mechanism: someone who can replace both the model and local metadata can regenerate both digests.

For a trusted deployment, obtain the canonical manifest digest from an external authenticated channel (for release bundles, the signed release attestation) and pin it before creating a runtime session:

from zeroproofml.inference import load_onnx_runtime_bundle

runtime = load_onnx_runtime_bundle(
    "bundle_dir",
    expected_bundle_digest="<digest from signed release attestation>",
    providers=["CPUExecutionProvider"],
)

Callers with a richer attestation format can instead pass a verifier_callback to load_onnx_runtime_bundle; it receives the validated descriptor before ONNX Runtime is initialized. Neither option verifies a publisher signature by itself—the external channel or callback supplies that trust decision.

C++ consumer policy

The C++ helper at examples/cpp/zeroproofml_bundle.hpp applies the same contained-path, regular-file, schema-v2 byte-size, and SHA-256 checks before it creates an ONNX Runtime session. It exposes verification_status() so callers can record the digest that passed bundle checksum validation and explicitly distinguish legacy bundles. Historical three-output bundles are inspectable as unverified compatibility artifacts, but are not executable through the C++ wrapper; migrate them to a checksum-validated schema-v2 bundle first. The C++ consumer has the same integrity/authenticity boundary as Python: a self-contained model digest is not a publisher signature, so deployments need an externally authenticated manifest digest or attestation.

Regenerate the operator report

From an existing bundle directory:

python -m zeroproofml.report bundle bundle_dir

That refreshes the Markdown validation report and writes the SVG summary figure used for operator handoff.

Shipping checklist

  1. Freeze StrictDecodePolicy with the canonical-score rejection threshold and ambiguity band.
  2. Export the bundle from the raw (P, Q) model.
  3. Run validate_bundle(...).
  4. Run a reference smoke test with saved example inputs.
  5. Regenerate the bundle report and ship the report with the bundle.