SDK docs · record/02

Decision record — SDK packaging

Accepted: the verifier SDK ships as versioned platform packages with the proof engine compiled in at a version fixed at build time — so a substituted or drifted engine cannot arrive through any normal installation path.

Context

Status: Accepted (2026-07-21) · recorded 2026-07-19 · depends on the specification’s paid-verification permission and its trust-boundary rules

The verifier SDK is a Python package whose correctness depends on a specific release of the Rust proof engine and on byte-for-byte agreement with the chain’s state layout, checked by a published vector suite. An integrator must receive all of that as one verifiable unit: a mismatched engine or a stale state-layout assumption is a security defect, not an inconvenience. The distribution form had to be decided before the first external integrator existed.

Three constraints of the specification frame the choice: verification may also be offered as a paid off-chain service, so packaging must make both embedded and service consumption practical; no interface is trusted merely for returning well-formed data, so the cryptographic checks must not be silently substitutable; and proof verification lives in the pinned Rust engine while Python orchestrates — packaging must preserve the pin.

Options considered

Option A — versioned Python package with the engine compiled in (accepted)

Publish mintid-verifier-sdk as platform wheels, with the Rust engine compiled in as a native extension at a version fixed at build time and recorded in package metadata.

  • Pros: one artifact, one version; standard pip install experience; the engine pin is decided at release time and not overridable by dependency resolution; platform wheels make the Rust toolchain invisible to integrators.
  • Cons: we own a per-platform build matrix and release engineering before the first integrator; source builds still need the Rust toolchain as a fallback.

Option B — git dependency at a tag

Zero release infrastructure and always buildable from source — but every integrator needs the Rust toolchain, the engine pin lives in build configuration where an integrator can patch it, and repository access is a bad long-term distribution channel with no artifact-level integrity story. Retained only as the interim channel for design partners until the first tagged release exists.

Option C — vendored source drop (rejected)

Works in locked-down environments, but has the worst upgrade path, makes pin substitution trivial, and duplicates the build burden onto every integrator.

A: wheelsB: git tagC: vendored
Engine pin enforceableyes (built-in)weakno
Integrator toolchain burdennoneRust + oursRust + ours
Upgrade pathsemver via pipre-pin tagmanual
Works for paid-verification service operatorsyesyesawkward

Decision & versioning policy

Accepted: Option A, with B as the interim channel for design-partner integrators until the first tagged release exists. Versioning under Option A:

  • Semver on the SDK package: major for any change to the public surface or to accepted-behavior semantics; minor for additive surface; patch otherwise.
  • Package metadata records the engine release, the state-layout vector version and the specification revision built against. A release is blocked if the state-layout vectors fail against the target chain version.

Consequences

Option A commits us to a wheel-building pipeline and a release checklist — an engine pin bump is a reviewed change, never automatic. In exchange, integrators cannot end up running an unpinned or substituted proof engine through normal installation paths: substituting one becomes a deliberate, visible act outside the supported channel, which is exactly the posture the specification’s trust-boundary rules ask for.