Python API

Applications embed InvarLock through invarlock.engine. This module is the stable facade for the paired evaluation engine. Modules that encode or decode individual bundle files remain internal unless explicitly documented.

Reference

Surface: Python facade exported by invarlock.engine

Stability: Stable public API; undocumented invarlock.* imports remain internal

Use this page when: Embedding evaluate, verify, report, request loading, receipt verification, or provider-ABI types in Python

Diagram
The Python facade accepts caller-owned paths, resources, trust anchors, and evaluator exports, preserves the evaluate and verify transaction boundaries, and returns typed evidence, receipt, report, and error results.
The Python facade accepts caller-owned paths, resources, trust anchors, and evaluator exports, preserves the evaluate and verify transaction boundaries, and returns typed evidence, receipt, report, and error results.The Python facade accepts caller-owned paths, resources, trust anchors, and evaluator exports, preserves the evaluate and verify transaction boundaries, and returns typed evidence, receipt, report, and error results.

Stable exports

The facade deliberately groups these stable surfaces:

Data table with columns: Surface, Exports
SurfaceExports
Transactionsevaluate_request_file, verify_evidence, render_evidence, native/captured receipt verification, judge verification and signed judge receipts, acceptance attestations
Requestload_evaluation_request, EvaluationRequest, EvaluationRequestError
Captured authoringCapturedEvaluationRequest, make_run, load_run, write_run, run_digest, physical_file_digest, freeze_case_set, case_set_digest, validate_run_case_set, compare_runs, comparison_policy_digest, normalize_captured_request, captured_request_digest, EvaluationRecordsError, DEFAULT_MAX_BOOTSTRAP_DRAWS
Evaluator scorer inputsCapturedSourceRequest, CapturedJudgeRequest, capture_evaluator_run, evaluator_input_capabilities, prepare_evaluator_judge, import_judge_sources
Trust profilesload_trust_inputs, TrustInputs, CapturedTrustInputs, TrustInputsError
Results and errorsEvaluation, verification, reporting, receipt, and evidence-pack result types
OCI host executionPer-side launch values, host executor, and environment-backed launch resolution
Provider ABIABI constant, provider/session protocols, capabilities, runtime specs/resources/context, resolver protocols, batches, identities, receipts, and observations
Runtime-import authoringStrict JSONL record loading, typed observation and receipt builders, complete side publication/reload, and verifier-derived paired-record publication
Scorer extensionABI constant, descriptor and binding types, replay protocol and request/result types, explicit registry, and binding/result builders
Evaluator qualificationqualify_evaluator_export, EvaluatorQualificationResult, EvaluatorQualificationError, and four format constants
HF identitycheckpoint_tree_sha256, hf_tokenizer_contract_sha256
Captured subject identitydigest, validate_service_identity, evaluated_subject_digest

Imports from other invarlock.* modules are not stable merely because they are importable. Use the facade unless implementing the provider protocol documented in Runtime providers.

The captured evaluation helpers are part of the documented SDK for captured-result comparisons. They expose normalized run construction and loading, multi-metric comparison, evidence publication, independent verification, and scoped receipt handling through the same evaluation transaction surface. Their evidence and recorded-score semantics are described in evaluation records.

Transactions

from pathlib import Path

from invarlock.engine import (
    OciRuntimeExecutor,
    evaluate_request_file,
    launch_from_environment,
    render_evidence,
    verify_evidence,
    verify_signed_verification_receipt,
)

# Load both fingerprints from an independently managed trust registry.
evidence_signer_fingerprint = "sha256:" + "3" * 64
verifier_fingerprint = "sha256:" + "4" * 64
artifact_digests = {
    "baseline": "sha256:" + "5" * 64,
    "subject": "sha256:" + "6" * 64,
}
schedule_digest = "sha256:" + "7" * 64

evaluation = evaluate_request_file(
    Path("request.yaml"),
    signing_key_path=Path("keys/evidence-signer.pem"),
    runtime_executor=OciRuntimeExecutor(launch_from_environment()),
    runtime_image_digests={
        "baseline": "sha256:" + "1" * 64,
        "subject": "sha256:" + "2" * 64,
    },
)

verification = verify_evidence(
    evaluation.evidence_path,
    policy_path=Path("policy/acceptance.json"),
    expected_baseline_artifact=artifact_digests["baseline"],
    expected_subject_artifact=artifact_digests["subject"],
    expected_schedule=schedule_digest,
    expected_baseline_runtime="sha256:" + "1" * 64,
    expected_subject_runtime="sha256:" + "2" * 64,
    expected_signer=evidence_signer_fingerprint,
    receipt_path=Path("verification.receipt.json"),
    verifier_signing_key_path=Path("keys/evidence-verifier.pem"),
    verifier_identity="release-verifier",
)

report = render_evidence(
    evaluation.evidence_path,
    html_path=Path("evidence.html"),
    explain=True,
)

receipt_check = verify_signed_verification_receipt(
    verification.receipt_path,
    evaluation.evidence_path,
    policy_path=Path("policy/acceptance.json"),
    expected_artifact_digests=artifact_digests,
    expected_schedule_digest=schedule_digest,
    expected_runtime_digests={
        "baseline": "sha256:" + "1" * 64,
        "subject": "sha256:" + "2" * 64,
    },
    expected_pack_signer_fingerprint=evidence_signer_fingerprint,
    expected_verifier_identity="release-verifier",
    expected_verifier_fingerprint=verifier_fingerprint,
)
assert receipt_check.ok

Replace the illustrative anchors with independently approved values. Before a run, inspect both selected images with Docker or Podman and supply those exact local identities in runtime_image_digests; the executor cannot provide its own trust inputs. This example is for native deterministic evidence.

The result types are:

Data table with columns: Type, Important fields
TypeImportant fields
EvaluationPreflightResultexecution_mode, output, input digests, providers, checks, as_json()
EvaluationTransactionResultevidence_path, comparison_id, pack_manifest_digest, optional policy_verdict, as_json()
EvidenceVerificationevidence_path, payload, receipt_path, summary, as_json()
EvidenceReporttext, html_path, evidence_signer, pack_manifest_digest, observations
EvidenceReportV2text, kind, pack_manifest_digest, requested_outputs, written_outputs, failed_output, errors, as_json()
CapturedEvaluationPreflightResultrequested_authentication, run/policy/request digests, record/scope counts, required/allowed draws, output, checks, as_json()
CapturedEvaluationTransactionResultevidence_path, comparison_id, run/policy/request/manifest digests, authentication, policy_verdict, as_json()
ReceiptVerificationok, signed, statement, verifier_fingerprint, errors
JudgeVerificationResultauthenticated, replayed, verified, accepted, decision, policy/evidence bindings, errors
JudgeReceiptVerificationok, signed, authenticated statement, embedded local result, verifier fingerprint, errors

EvaluationTransactionResult.policy_verdict is optional presentation metadata from publication. It is not added to as_json() and does not establish recipient acceptance. Use independent verification for that decision. EvidenceReport.text is Markdown presentation content; console and HTML layouts are not stable parsing interfaces. Use canonical evidence and verifier payloads for automation.

EvaluationPreflightError, EvaluationTransactionError, EvidenceVerificationError, and EvidenceReportError carry CLI-compatible exit_code values. The first three also expose machine-readable JSON behavior. Applications should treat every exception or verification payload with ok != true as rejection.

EvidenceReceiptError is also exported for failures that prevent safe receipt processing. Ordinary receipt authenticity or anchor mismatches are reported in ReceiptVerification.errors with ok set to false.

For native and captured directory packs, render_evidence checks the closed bundle and authenticates its internal evidence signature when the manifest declares signed authentication. Unsigned captured packs retain their explicit local assurance label. Judge rendering validates envelope structure and replays measurements; it does not authenticate the envelope signature. Rendering does not take independent artifact, schedule, policy, runtime, run, request, or signer anchors. For independent technical verification in Python, call verify_evidence for native deterministic or captured v2 packs and verify_judge_evidence_with_policy for judge evidence. The CLI dispatches both through invarlock verify with the corresponding recipient trust inputs.

External evaluator qualification

The stable SDK accepts a normalized export from any open or proprietary evaluator. The caller owns evaluator execution and native-output parsing; InvarLock owns closed-contract validation, digest binding, schedule matching, and replay of the supported deterministic metric declared by the profile.

from pathlib import Path

from invarlock.engine import qualify_evaluator_export

result = qualify_evaluator_export(
    profile_path=Path("profile.json"),
    schedule_path=Path("schedule.json"),
    export_path=Path("export.json"),
    raw_output_path=Path("upstream-output.json"),
)

if result.authority == "verdict_authority":
    import_records = result.runtime_records()
else:
    assert result.runtime_records() == ()

runtime_records() never exposes records for aggregate-only, externally rated, nondeterministic-judge, or unsupported-replay profiles. See Evaluator qualification for the contracts, private evaluator path, and maintained matrix.

Portable acceptance handoff

write_acceptance_attestation wraps a signed verification receipt and its bound evidence into an in-toto Statement and DSSE envelope while retaining the exact supplied receipt-file bytes. verify_acceptance_attestation authenticates that envelope, the embedded receipt, the exact subject artifact, separate envelope and receipt-verifier trust, and one recipient-supplied current policy. It does not replay the complete evidence pack; use verify_evidence or invarlock verify for that authoritative technical replay.

The result separates historical_technical_verdict from accepted, and also reports envelope authentication, receipt authentication, subject binding, and closed errors. See Acceptance attestations for the TypeURI, canonical serialization, signer relationship, and reference policy.

Function signatures

evaluate_request_file(
    request_path: Path | EvaluationRequest | CapturedEvaluationRequest,
    *,
    signing_key_path: Path | None,
    resource_resolver: RuntimeResourceResolver | None = None,
    runtime_executor: OciRuntimeExecutor | None = None,
    runtime_image_digests: Mapping[str, str] | None = None,
    scorer_registry: ScorerExtensionRegistry | None = None,
    unsigned: bool = False,
    max_bootstrap_draws: int | None = DEFAULT_MAX_BOOTSTRAP_DRAWS,
) -> EvaluationTransactionResult | CapturedEvaluationTransactionResult | JudgeWorkflowResult

preflight_evaluation_request(
    request_path: Path | EvaluationRequest | CapturedEvaluationRequest,
    *,
    signing_key_path: Path | None,
    scorer_registry: ScorerExtensionRegistry | None = None,
    runtime_image_digests: Mapping[str, str] | None = None,
    resource_resolver: RuntimeResourceResolver | None = None,
    unsigned: bool = False,
    max_bootstrap_draws: int | None = DEFAULT_MAX_BOOTSTRAP_DRAWS,
) -> EvaluationPreflightResult | CapturedEvaluationPreflightResult | JudgeWorkflowResult

load_evaluation_request(
    path: str | Path,
    *,
    provider_resolver: ProviderResolver | None = None,
    request_root: Path | None = None,
    baseline_run: Path | None = None,
    subject_run: Path | None = None,
    output: Path | None = None,
) -> EvaluationRequest | CapturedEvaluationRequest

verify_evidence(
    evidence_path: Path,
    *,
    policy_path: Path | None,
    expected_baseline_artifact: str | None,
    expected_subject_artifact: str | None,
    expected_schedule: str | None,
    expected_baseline_runtime: str | None,
    expected_subject_runtime: str | None,
    expected_signer: str | None,
    expected_request_digest: str | None = None,
    receipt_path: Path | None = None,
    verifier_signing_key_path: Path | None = None,
    verifier_identity: str | None = None,
    trust_profile_digest: str | None = None,
    scorer_registry: ScorerExtensionRegistry | None = None,
    policy_bytes: bytes | None = None,
    verifier_signing_key_bytes: bytes | None = None,
) -> EvidenceVerification

render_evidence(
    evidence_path: Path,
    *,
    html_path: Path | None = None,
    explain: bool = False,
    markdown_path: Path | None = None,
    junit_path: Path | None = None,
    case_ids: tuple[str, ...] = (),
) -> EvidenceReport | EvidenceReportV2

Native deterministic requests return native results. Native judge evaluation returns JudgeWorkflowResult, while its preflight returns EvaluationPreflightResult. Captured judge preflight and evaluation both return JudgeWorkflowResult; other captured requests return captured results. A path is dispatched after loading and returns the corresponding union.

For captured calls, omit native runtime/executor/registry/scorer keywords entirely, including explicit None. Frozen-answer v3 requests use the CLI judge workflow; these request-loader annotations do not include v3. render_evidence additionally accepts judge evidence and evidence sets; case_ids selects up to 50 retained judge cases and is rejected for native or captured deterministic packs. Omission and explicit null preserve their distinct native validation semantics; do not forward a bag of unrelated keyword defaults.

Captured verify_evidence uses policy_path, expected_baseline_run, expected_subject_run, expected_request_digest, expected_signer, receipt_path, verifier_signing_key_path, and verifier_identity, plus optional trust_profile_digest, immutable policy_bytes/verifier_signing_key_bytes, and the recipient's max_bootstrap_draws. It does not accept native artifact, schedule, runtime, or scorer anchors. load_trust_inputs returns CapturedTrustInputs for a v2 captured profile and TrustInputs for native v1; the CLI's --trust-profile resolves those inputs through the same facade.

For captured receipt authentication, verify_signed_verification_receipt takes expected_run_digests={"baseline": ..., "subject": ...} and expected_request_digest instead of native artifact/schedule/runtime digests. It still requires independent policy, evidence-signer fingerprint, verifier identity/fingerprint, and the expected profile digest when used. Its ok means the receipt authenticates, not that the embedded technical verdict passes. Native-only acceptance and deployment APIs reject captured scope.

compare_runs takes baseline, subject, policy and a local work budget; it does not publish or gate. EvaluationRecordsError is the canonical record validation, adapter, capacity, and safe-I/O exception. normalize_captured_request, captured_request_digest, run_digest, and comparison_policy_digest derive portable pins without signing keys, scoring, or publication. A local SDK budget of None explicitly removes the work allowance, not byte/record limits. The CLI accepts only integer allowances and never infers an unlimited value from evidence.

The optional annotations on verify_evidence support a uniform Python signature; the public evidence-pack v1 transaction requires every artifact, schedule, policy, runtime, signer, receipt, verifier-key, and verifier-identity input. Missing values raise EvidenceVerificationError rather than reducing assurance.

evaluate_request_file always completes the same request, input, schedule, policy, runtime, key, and output preflight before it calls a run-mode executor. Every programmatic run must supply both independently inspected runtime_image_digests; neither an executor nor a resource resolver can self-assert those trust inputs. preflight_evaluation_request exposes that gate separately when an application wants to inspect the result without executing a runtime or mutating the output tree. Embedders must independently confirm that run-mode images are local before supplying their digests; the CLI performs that inspection through Docker or Podman without starting a container. For a scorer-bound request, preflight also loads the explicitly authorized scorer's deterministic descriptor and schema and validates the exact binding and task/input/output compatibility without calling scorer replay.

EvaluationPreflightResult serializes as invarlock/evaluation-preflight-v2. When policy sample qualification is enabled, sample_qualification.record_count contains the minimum, observed count, and status: pass; sample_qualification.interval_width contains the maximum, unit, and status: pending_execution. Applications must not convert that pending state into a successful precision claim.

Applications evaluating a run request that selects a runtime input hook must pass a side-aware RuntimeResourceResolver to the public transaction. The hook authenticates schedule-bound external resources without loading the model. Successful resolution of both sides against their inspected image digests is recorded as runtime_resources in EvaluationPreflightResult.checks. The OCI executor implements both execution and resource resolution so its frozen per-side image, device, root, and support bindings cannot drift between baseline and subject validation.

When a request selects comparison.scorer_extension, the embedding must pass an explicit ScorerExtensionRegistry to both evaluate_request_file and verify_evidence. The registry may contain caller-injected authorized scorers or may explicitly enable installed invarlock.scorers entry-point discovery. Neither an installed package nor a binding inside the submitted evidence authorizes scorer code by itself. Strict verification resolves the policy- pinned scorer through this registry and replays it deterministically.

The registry includes five built-in deterministic scorers: invarlock.normalized_match, invarlock.numeric_tolerance, invarlock.json_fields, invarlock.json_exact and invarlock.token_f1. Pass ScorerExtensionRegistry(allow_installed=False) to use these through the SDK without enabling third-party discovery. The core CLI supplies this registry automatically. Bindings still pin the scorer's version and configuration schema.

Request loading

from invarlock.engine import load_evaluation_request

request = load_evaluation_request(Path("request.yaml"))

The loader returns an immutable native EvaluationRequest or CapturedEvaluationRequest whose paths are resolved beneath the request root. Its default provider resolver exposes only the built-in Hugging Face provider. evaluate_request_file uses the core registry, which also discovers installed first-party add-ins.

Loading validates structure and path confinement; the evaluation transaction repeats no-follow reads at the point of use to detect later filesystem changes.

Host-coordinated OCI evaluations

The stable facade exports OciEvaluationLaunch, OciSideLaunch, OciRuntimeExecutor, and launch_from_environment. The public CLI constructs this executor for every run-mode request. The host prepares the schedule, launches one independently pinned worker per side, validates both closed side results, and keeps the evidence-signing key outside the workers.

An embedding can build the same launch explicitly:

from invarlock.engine import (
    OciEvaluationLaunch,
    OciRuntimeExecutor,
    OciSideLaunch,
    OciWorkerLimits,
)

baseline_digest = "sha256:" + "1" * 64
subject_digest = "sha256:" + "2" * 64
executor = OciRuntimeExecutor(
    OciEvaluationLaunch(
        engine="docker",
        worker_limits=OciWorkerLimits(
            cpus="8",
            memory_mib=16384,
            user="12001:12001",
        ),
        baseline=OciSideLaunch(
            image_ref=f"registry.example/invarlock-runtime@{baseline_digest}",
            image_digest=baseline_digest,
            device="cpu",
            entrypoint="auto",
        ),
        subject=OciSideLaunch(
            image_ref=f"registry.example/invarlock-runtime@{subject_digest}",
            image_digest=subject_digest,
            device="cpu",
            entrypoint="auto",
        ),
    )
)

Each worker receives read-only job, schedule, artifact, and support mounts plus one isolated writable output mount. OciWorkerLimits applies validated CPU, memory, and numeric non-root user controls independently to each worker; its defaults are 4, 65536 MiB, and 65532:65532. The launcher may run two CPU workers or two different explicit CUDA indexes concurrently. Generic CUDA selection, a shared index, and CPU/CUDA pairs run sequentially. CUDA selection exposes a device but does not make a CPU-only image CUDA-capable; use the x86_64 image built from runtime/Dockerfile.cuda for canonical CUDA Hugging Face execution.

launch_from_environment resolves the common and per-side image, digest, device, entrypoint, and common worker-limit variables documented in Environment variables. Explicit function arguments take precedence over environment values.

Direct executed evaluations and caller resources

evaluate_request_file accepts an optional resource_resolver implementing the runtime resource resolver protocol. This is a lower-level programmatic hook for execution that is already inside an authenticated strict runtime context. It supplies caller-owned artifact roots, support files, device selection, and the selected side-image digest. It is not the host OCI launcher. Passing both a resource_resolver and runtime_executor is rejected.

RuntimeResourceResolver is exported from invarlock.engine as a structural protocol. Its exact method is:

def resolve(
    self,
    *,
    request_root: Path,
    role: Literal["baseline", "subject"],
    side: ComparisonSideRequest,
    provider: RuntimeProvider,
) -> RuntimeArtifactResources: ...

ComparisonSideRequest is intentionally not a stable construction surface; the loader supplies it to the resolver. A custom resolver reads only the already validated side and returns caller-authorized resources. The following HF-only resolver is complete for a transaction already running inside its strict side context because HF needs no executable support files:

from pathlib import Path
from typing import Any, Literal

from invarlock.engine import (
    RuntimeArtifactResources,
    RuntimeProvider,
)


class AuthorizedHFResources:
    def __init__(self, *, image_digest: str, device: str = "cpu") -> None:
        self.image_digest = image_digest
        self.device = device

    def resolve(
        self,
        *,
        request_root: Path,
        role: Literal["baseline", "subject"],
        side: Any,
        provider: RuntimeProvider,
    ) -> RuntimeArtifactResources:
        if provider.name != "hf_transformers":
            raise ValueError(f"unsupported authorized provider: {provider.name}")
        artifact = side.artifact.path
        if artifact is None:
            raise ValueError(f"{role} has no run-mode artifact")
        relative = artifact.relative_to(request_root).as_posix()
        return RuntimeArtifactResources(
            root=request_root,
            primary_artifact=relative,
            support_resources={},
            device_kind=self.device,
            container_image_digest=self.image_digest,
        )

ProviderResolver is the callable type Callable[[str], RuntimeProvider]. It is for controlled request loading; it must reject unknown provider names rather than fall back to a default.

Provider ABI types

The facade exports runtime-provider ABI version 1 as INVARLOCK_RUNTIME_PROVIDER_ABI, together with these value and protocol types:

  • RuntimeProvider, RuntimeProviderCapabilities, and RuntimeSession;
  • ModelRuntimeSpec, ModelArtifactIdentity, and RuntimeArtifactResources;
  • RuntimeExecutionContext;
  • EvaluationBatch and EvaluationRecord;
  • RuntimeProviderReceipt, RuntimeScoringRecord, and ScoringObservation;
  • RuntimeBehavioralSchedule and the three artifact-identity variants; and
  • plugin, backend, execution-settings, and device provenance values.

The two resolver annotations used by the public function signatures are also exported: ProviderResolver and RuntimeResourceResolver.

Core value constructors

The most commonly embedded ABI values have these stable constructor fields:

Data table with columns: Type, Required constructor fields, Defaults and constraints
TypeRequired constructor fieldsDefaults and constraints
ModelRuntimeSpecprovider_name, model_idsettings={}; values must be finite JSON scalars and keys canonical names
RuntimeArtifactResourcesabsolute root, relative primary_artifact, support_resources, device_kind, container_image_digestRoot and every resource are checked without following links; device is cpu or cuda; digest is required
RuntimeExecutionContextstrict, allow_network, container_image_digest, device_kindartifact_identity_sha256, opaque provider_state, scorer, and close callback default to None
EvaluationInputPartkind, canonical role, bare sha256Text parts carry text; content parts carry content_id, media_type, and byte_length
EvaluationRecordrecord_id, first input_text, bare input_sha256expected_output=None; input_parts=() retains the provider-construction compatibility path
EvaluationBatchbare schedule_sha256, nonempty tuple of recordsmetric="exact_match"; task="text_causal"; record IDs must be unique
RuntimeProviderCapabilitiesprovider, artifacts, tasks, metrics, modes, required extra/imageFormat and ABI fields are fixed by the type
ScoringObservationprovider, artifact digest, schedule digest, nonempty records, aggregate-source digestRecord IDs must be unique; format is fixed

Scroll horizontally to see every column.

Mappings are copied into immutable views during construction. Passing a mutable dictionary does not make the resulting ABI object mutable. Digest fields in the ABI are generally bare 64-character lowercase SHA-256 values; OCI image fields use sha256:<64 hex>. The constructor validation distinguishes them.

Hugging Face identity helpers

The stable facade exposes the exact helpers used by the canonical built-in provider:

from invarlock.engine import (
    checkpoint_tree_sha256,
    hf_tokenizer_contract_sha256,
)

checkpoint_tree_sha256(path) returns a sha256: digest after a no-follow, change-detecting tree scan. hf_tokenizer_contract_sha256(tokenizer) returns a bare digest of the live tokenizer behavior contract and does not import or load Transformers itself. The caller must load the local tokenizer with network and remote code disabled. Importing invarlock.engine remains backend-lazy.

Provider implementations may also use the complete torch-free ABI module, invarlock.core.runtime_provider, for canonical schedule construction and observation-verification helpers that are outside the embedding facade. Backend imports must remain lazy so provider discovery does not import a heavyweight or hardware-specific runtime.

Author complete runtime-import evidence

The stable facade includes a typed authoring path for evaluation records emitted outside the native provider transaction. It is deliberately narrower than a generic results importer:

  • load_external_scoring_records_jsonl accepts one backend observation per line and rejects unknown or aggregate-summary fields;
  • build_runtime_import_observation binds those records to the exact schedule and artifact identity;
  • build_runtime_import_receipt binds provider, backend, execution, device, image, artifact, and canonical observation bytes;
  • write_runtime_import_side atomically writes all six files needed for one import side, then reloads them through strict runtime-manifest verification;
  • load_runtime_import_side independently reloads an existing side; and
  • write_runtime_import_paired_records derives canonical pairs from two verified sides. It never accepts caller-supplied scores.

The high-level signatures are:

load_external_scoring_records_jsonl(
    path: str | Path,
    *,
    schedule: RuntimeBehavioralSchedule,
) -> tuple[RuntimeScoringRecord, ...]

write_runtime_import_side(
    directory: str | Path,
    *,
    role: Literal["baseline", "subject"],
    schedule: RuntimeBehavioralSchedule,
    policy_digest: str,
    artifact_identity: ModelArtifactIdentity,
    records: tuple[RuntimeScoringRecord, ...],
    plugin: RuntimeProviderPluginIdentity,
    backend: RuntimeBackendIdentity,
    capabilities: RuntimeProviderCapabilities,
    execution_settings: RuntimeExecutionSettings,
    device: RuntimeDeviceFacts,
    runtime_image_ref: str,
    runtime_image_digest: str,
    generated_at_utc: str,
) -> RuntimeImportSideEvidence

write_runtime_import_paired_records(
    path: str | Path,
    *,
    schedule: RuntimeBehavioralSchedule,
    metric: str,
    baseline: RuntimeImportSideEvidence,
    subject: RuntimeImportSideEvidence,
    scorer_binding: ScorerExtensionBinding | None = None,
    scorer_registry: ScorerExtensionRegistry | None = None,
) -> RuntimeImportPairedRecords

The timestamp is explicit so identical inputs produce identical files. The writer records strict container execution, offline operation, disabled remote code, and disabled third-party discovery. Those fields describe facts the caller is responsible for measuring; serialization does not independently establish their accuracy or attest execution. Independent verification must still pin the artifact, schedule, policy, runtime-image, and signer identities.

RuntimeImportAuthoringError is raised before publication when record pairing, output digests, provider identities, provenance, side files, or manifest replay do not agree. An import request also needs the matching authorized provider package so the transaction can reproduce the artifact identity from request settings.

See Runtime providers for lifecycle and conformance obligations.

Verify a signed receipt

load_trust_inputs loads a closed invarlock/trust-inputs-v1 profile for applications that want the same verifier-owned input grouping as the CLI. It returns TrustInputs, including the policy and verifier-key bytes captured through descriptor-relative reads, their display paths, normalized anchors, scorer authorization, and the formatting-independent profile digest. Unsafe paths, symlinks, duplicate JSON members, unknown fields, and missing files raise TrustInputsError before verification.

Pass the captured policy_bytes and verifier_signing_key_bytes to verify_evidence; do not reopen the display paths after loading the profile. This keeps verification and receipt signing bound to the exact bytes that were accepted during the profile read:

trust = load_trust_inputs(Path("trust/trust-inputs.json"))
verification = verify_evidence(
    evidence_path,
    policy_path=trust.policy_path,
    policy_bytes=trust.policy_bytes,
    expected_baseline_artifact=trust.expected_artifact_digests["baseline"],
    expected_subject_artifact=trust.expected_artifact_digests["subject"],
    expected_schedule=trust.expected_schedule_digest,
    expected_baseline_runtime=trust.expected_runtime_digests["baseline"],
    expected_subject_runtime=trust.expected_runtime_digests["subject"],
    expected_signer=trust.expected_signer_fingerprint,
    expected_request_digest=trust.expected_request_digest,
    receipt_path=Path("verification.receipt.json"),
    verifier_signing_key_path=trust.verifier_signing_key_path,
    verifier_signing_key_bytes=trust.verifier_signing_key_bytes,
    verifier_identity=trust.verifier_identity,
    trust_profile_digest=trust.profile_digest,
    scorer_registry=ScorerExtensionRegistry(
        allow_installed=trust.allow_installed_scorers
    ),
)

verify_signed_verification_receipt is the stable downstream receipt reader. It accepts the receipt and pack paths plus independently supplied policy, baseline and subject artifact-identity digests, canonical schedule digest, baseline and subject runtime digests, expected evidence signer, expected verifier identity, expected verifier fingerprint, and the optional normalized- request digest. The request digest is required for GGUF evidence. It verifies the receipt signature and embedded public-key fingerprint, then compares every statement binding with those caller-owned values and the supplied pack manifest.

The function returns ReceiptVerification; check ok before using statement. signed reports whether a signed envelope was present, while errors contains closed failure details. require_signed defaults to true and should remain true for evidence-pack v1 acceptance.

verify_signed_verification_receipt(
    receipt_path: Path,
    pack_dir: Path,
    *,
    policy_path: Path,
    expected_artifact_digests: dict[str, str],
    expected_schedule_digest: str,
    expected_runtime_digests: dict[str, str],
    expected_pack_signer_fingerprint: str,
    expected_verifier_identity: str,
    expected_verifier_fingerprint: str,
    expected_trust_profile_digest: str | None = None,
    expected_request_digest: str | None = None,
    require_signed: bool = True,
) -> ReceiptVerification

There is no separate receipt-verification CLI command. Applications and automation use this Python facade when consuming a receipt issued by another verifier.

Judge verification results and receipts

Native evaluate_request_file also accepts metric: judge in a run/import request. It retains the normal native resource and signing-key requirements and returns JudgeWorkflowResult, whose JSON has kind: judge, the evidence path, analysis decision and collection stop state. Native preflight retains EvaluationPreflightResult and adds judge model, unit, trial and budget metadata. The installed optional collector reads credentials from its process environment; callers do not pass keys in the request or plan. Recipient replay requires only the core package. Native judge evidence includes a bound runtime capture, whereas ordinary frozen-answer import makes no runtime-provenance claim.

Captured v2 requests also select metric: judge; both preflight and evaluation return JudgeWorkflowResult. CapturedJudgeRequest supplies the private workspace, signer identity and optional retained measurements path. prepare_evaluator_judge(recipe, baseline, subject) freezes a plan and analysis policy without calls. import_judge_sources(sources, plan=plan, baseline_run=baseline, subject_run=subject) accepts a mapping of source IDs to unchanged canonical retained-call JSON bytes, validates all trial bindings and returns the measurements object. Import does not invoke a provider or Inspect.

verify_judge_evidence and verify_judge_evidence_with_policy replay bounded judge evidence under an external judge recipient policy and return an unsigned JudgeVerificationResult. write_signed_judge_verification_receipt signs that complete validated result, its recipient-policy digest, the verifier identity and verifier key fingerprint under the judge receipt domain. The destination and signing key must remain outside the submitted evidence.

verify_signed_judge_verification_receipt authenticates a received receipt against caller-owned verifier identity, fingerprint and recipient-policy digest. It does not reopen evidence. replay_signed_judge_verification_receipt adds exact fresh evidence replay under the external recipient policy. Use verify_stored_judge_result for the same fresh comparison when the stored object is an unsigned local result rather than a signed receipt.

from pathlib import Path
from invarlock.engine import (
    replay_signed_judge_verification_receipt,
    verify_judge_evidence_with_policy,
    verify_signed_judge_verification_receipt,
    write_signed_judge_verification_receipt,
)

policy = Path("recipient/judge-policy.json")
evidence = Path("judge-evidence")
receipt = Path("recipient/judge.receipt.json")
local = verify_judge_evidence_with_policy(evidence, policy)
fingerprint = write_signed_judge_verification_receipt(
    evidence,
    local,
    receipt,
    recipient_policy_path=policy,
    verifier_identity="release-verifier",
    verifier_signing_key_path=Path("recipient/verifier.pem"),
)
authenticated = verify_signed_judge_verification_receipt(
    receipt,
    expected_verifier_identity="release-verifier",
    expected_verifier_fingerprint=fingerprint,
    expected_recipient_policy_sha256=local.recipient_policy_sha256,
)
assert authenticated.ok
assert replay_signed_judge_verification_receipt(
    receipt,
    evidence_path=evidence,
    recipient_policy_path=policy,
    expected_verifier_identity="release-verifier",
    expected_verifier_fingerprint=fingerprint,
).accepted

These APIs preserve bounded-judge-fixed-benchmark-v1. Receipt authentication does not establish that the benchmark represents deployment traffic or that the judge is correct outside the retained rubric and cases.

Evidence pack result types

EvidencePackResult, EvidencePackStatus, and EvidenceObservation are exported for applications that inspect verifier results or attach typed observation-only JSON during evidence publication. EvidenceObservation contains an ID, baseline/subject/comparison scope, kind, and canonical JSON payload bytes. Publication adds the comparison, schedule, policy, and artifact bindings. The high-level verify_evidence transaction is preferred because evidence-pack v1 requires a separately signed receipt.

The package contains additional lower-level publication and format readers for its own transactions and tests. They are not re-exported by the stable engine facade. Do not depend on their import paths when the evaluate, verify, report, and signed-receipt functions cover the required workflow.

EvidencePackStatus exposes these lower-level values:

Data table with columns: Member, Value, Category
MemberValueCategory
OK0Complete success
USAGE2Missing or invalid caller input
MISSING3Required pack material absent
FORMAT4Contract, canonical-byte, or structural format rejection
SIGNATURE5Signature-specific rejection
INTEGRITY6Digest, inventory, or semantic binding rejection
REPORTS7Report replay or policy-result rejection
INTEGRITY_ONLY8Internal category for an integrity-only result

Scroll horizontally to see every column.

The high-level transaction may normalize precondition failures and does not promise that every enum member is emitted by every public command. Accept only OK, never a selected nonzero category.

Exception handling

Data table with columns: Exception, When raised, Machine-readable behavior
ExceptionWhen raisedMachine-readable behavior
EvaluationRequestErrorRequest parsing, schema, path, provider, or capability failureMessage only at request-loader boundary
EvaluationPreflightErrorExecution-free request, input, runtime-availability, key, or output qualification failsas_json() uses invarlock/evaluation-preflight-v2
EvaluationTransactionErrorExecute/import/publication cannot produce evidenceexit_code; as_json() uses invarlock/evaluation-result-v1
EvidenceVerificationErrorTrust input, pack replay, receipt write, or acceptance failureexit_code, payload, and as_json()
EvidenceReportErrorSignature-authenticated report cannot be rendered safelyexit_code
EvidenceReceiptErrorReceipt parsing or processing cannot complete safelyException; ordinary authenticity mismatches remain in ReceiptVerification.errors
TrustInputsErrorTrust profile parsing, schema, path, or referenced-file validation failsMessage only; no verification is attempted

Scroll horizontally to see every column.

Do not catch ValueError broadly and continue with partial output. Catch the documented transaction exception, log its closed message or payload, and reject the transaction. A rejected verification can still have a signed receipt when replay completed; inspect the exception payload for signed_receipt.