Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions docs/STABILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ source identity reject credential material rather than persist it.
|--------|-------|-------|
| `tributo.exporting.service` — `BundleExportService` | `beta` | Primary export orchestration |
| `tributo.exporting.models` — core storage values | `stable` | AliasConfig, artifact/producer/reference/validation values, execution/failure results, BundleResult, BundleRef, ResolvedArtifact, and PublishedBundle |
| `tributo.exporting.models` — export configuration, Hook and plugin values | `beta` | Exporter orchestration and Hook payloads retain independent contracts |
| `tributo.exporting.models` — `PluginLoadDiagnostic` | `stable` | Flavor/plugin discovery diagnostic value fields |
| `tributo.exporting.models` — export configuration and Hook values | `beta` | Exporter orchestration and Hook payloads retain independent contracts |
| `tributo.exporting.protocols` — all protocols | `beta` | Exporter/Validator/SourceProvider contracts |
| `tributo.exporting.manifest` — schema-v1 models and registry | `stable` | Source info, typed signatures, execution records, ExportManifest, and schema reader registration |
| `tributo.exporting.manifest` — `ExportManifestV2` and `compute_bundle_digest` | `beta` | Explainability extension and compatibility digest helper |
Expand All @@ -167,16 +168,17 @@ source identity reject credential material rather than persist it.
| `tributo.exporting.executor` | `beta` | Export executor |
| `tributo.exporting.publisher` | `stable` | Local/file/S3 core publication; the optional Explainability parameter remains Alpha |
| `tributo.exporting.validators` | `beta` | Artifact validator runner |
| `tributo.exporting.registries` | `beta` | Exporter/validator registries |
| `tributo.exporting.registries` — `FlavorRegistry` | `stable` | Flavor registration, lookup, and diagnostics |
| `tributo.exporting.registries` — exporter/source/validator/factory registries | `beta` | Exporter and model-factory orchestration |
| `tributo.exporting.options` | `beta` | Compatibility re-exports; schemas are owned by integration exporters |
| `tributo.exporting.records` | `beta` | Export record types; `PublicationAttempt` is read-only legacy compatibility and receives no new writes |
| `tributo.exporting.gc` | `beta` | Bundle GC |
| `tributo.exporting.events` | `beta` | Immutable publication event contract |
| `tributo.exporting.hooks` | `beta` | Adapter and committed-artifact access contracts |
| `tributo.exporting.dispatch` | `beta` | Inline Hook dispatch policy |
| `tributo.exporting.capabilities` | `beta` | Exporter/Flavor-derived capability declarations |
| `tributo.exporting.capabilities` | `stable` | Capability value structure, discovery projection, and lookup; plugin declarations do not prove execution support |
| `tributo.exporting.repository` | `stable` | Bundle repository/alias ports and their value objects; internal routing remains DeveloperAPI |
| `tributo.exporting.runtime` | `beta` | Bundle model runtime and Flavor protocol |
| `tributo.exporting.runtime` | `stable` | Bundle model protocols, loader/runtime, and support entries; first-party executable guarantee is scoped to onnx-runtime-v1 |
| `tributo.exporting.conftest` | `beta` | Public plugin conformance test kit |

The Stable storage model allowlist is `AliasConfig`, `ArtifactFile`,
Expand All @@ -202,6 +204,21 @@ persistent local publication. Ephemeral paths belong to the staging owner;
BundleExportService guarantees their callback window. Consumers persist
`BundleRef` or `BundleResult.canonical_uri` instead of transient local paths.

The Stable Runtime scope includes `BundleReaderLike`, `BundleModel`,
`BundleModelFlavor`, `FlavorSupportEntry`, `BundleModelLoader`,
`BundleModelRuntime`, and `ONNXRuntimeFlavor`. `FlavorRegistry`,
`ArtifactCapability`, `CapabilityRegistry`, `get_default_capability_registry`,
`PluginLoadDiagnostic`, and `UnsupportedArtifactFormat` complete its public
routing and diagnostic contracts. Exporter/validator/factory registries,
optional dependency internals, other flavors, Ray Data batch orchestration,
and HTTP/gRPC/SSE transports keep their existing levels.

Runtime `close()` releases reader resources exactly once; it does not unload
an in-memory ONNX session. ONNX prediction remains valid after close. Loading
and signature-validation failures close the artifact context before propagating.
The loaded Runtime keeps the validated manifest bytes and role-bound artifact;
custom Flavor execution follows its own declared contract.

### Explainability (tributo.explainability.*)

| Module | Level | Notes |
Expand Down Expand Up @@ -231,7 +248,7 @@ BundleExportService guarantees their callback window. Consumers persist
| `tributo.integrations.exporters.*` | `beta` | Built-in exporter implementations |
| `tributo.integrations.exporters.x_learner` | `alpha` | Fixed X-Learner model and causal-report exporter adapters |
| `tributo.integrations.flavors` | `beta` | Built-in runtime flavor package |
| `tributo.integrations.flavors.onnx_runtime` | `beta` | ONNX Runtime flavor implementation |
| `tributo.integrations.flavors.onnx_runtime` | `stable` | onnx-runtime-v1 named-tensor loading, prediction, and reader-resource lifetime |
| `tributo.integrations.validators` | `beta` | Built-in validator package |
| `tributo.integrations.validators.*` | `beta` | Built-in validator implementations |
| `tributo.integrations.sources` | `beta` | Built-in source provider package |
Expand Down
1 change: 1 addition & 0 deletions docs/reference/support-matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ matrix are generated from the same Registry projection.
| S3 bundle publication | Stable | Core Publisher/repository contracts, manifest-last, leases, idempotency, and alias compare-and-set |
| Bundle manifest/artifact reading and integrity | Stable | BundleReader, schema-v1 fields, exact committed bytes, digest/identity checks, bounded materialization, and context lifetime; extension payload semantics are independent |
| HDFS bundle publication | Not implemented | Storage backend extension |
| ONNX Bundle model loading and prediction | Stable | BundleModelLoader/Runtime and onnx-runtime-v1 only: named tensors, typed signatures, integrity/security gates, and reader-resource lifetime; transport and orchestration levels are separate |
| Ray Data batch inference | Beta | Actor-based model reuse |
| Batch output to local/S3 Parquet | Implemented | Database sinks are separate |
| Batch explainability | Alpha | Optional SHAP adapter over a declared Bundle role; batch-only Ray ingestion and bounded Parquet results |
Expand Down
2 changes: 1 addition & 1 deletion src/tributo/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class AliasConflict(TributoError):
"""Alias CAS update failed — concurrent modification detected."""


@PublicAPI(stability="beta")
@PublicAPI(stability="stable")
class UnsupportedArtifactFormat(TributoError):
"""Consumer does not support this artifact format or flavor.

Expand Down
6 changes: 3 additions & 3 deletions src/tributo/exporting/capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from tributo.util.annotations import PublicAPI


@PublicAPI(stability="beta")
@PublicAPI(stability="stable")
@dataclass(frozen=True)
class ArtifactCapability:
"""Capabilities for one immutable artifact flavor.
Expand All @@ -36,7 +36,7 @@ class ArtifactCapability:
conditional_operations: tuple[str, ...] = ()


@PublicAPI(stability="beta")
@PublicAPI(stability="stable")
class CapabilityRegistry:
"""Immutable registry derived from exporter and flavor descriptors."""

Expand Down Expand Up @@ -254,7 +254,7 @@ def _build_default_capability_registry() -> CapabilityRegistry:
_DEFAULT_CAPABILITY_REGISTRY: CapabilityRegistry | None = None


@PublicAPI(stability="beta")
@PublicAPI(stability="stable")
def get_default_capability_registry() -> CapabilityRegistry:
"""Return the lazily composed first-party capability registry.

Expand Down
2 changes: 1 addition & 1 deletion src/tributo/exporting/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -919,7 +919,7 @@ class ExportSource(BaseModel):
# ── Plugin diagnostics ───────────────────────────────────────────────────────


@PublicAPI(stability="beta")
@PublicAPI(stability="stable")
class PluginLoadDiagnostic(BaseModel):
"""Non-fatal plugin loading issue."""

Expand Down
2 changes: 1 addition & 1 deletion src/tributo/exporting/registries.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ def record_diagnostic(self, diagnostic: PluginLoadDiagnostic) -> None:
# ═══════════════════════════════════════════════════════════════════════════════


@PublicAPI(stability="beta")
@PublicAPI(stability="stable")
class FlavorRegistry:
"""Registry of ``ModelFlavor`` classes keyed by ``flavor_id``.

Expand Down
28 changes: 17 additions & 11 deletions src/tributo/exporting/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

import hashlib
import logging
from contextlib import ExitStack
from contextlib import AbstractContextManager, ExitStack
from dataclasses import dataclass
from typing import Any, ClassVar, Literal, Protocol, runtime_checkable

Expand Down Expand Up @@ -75,7 +75,7 @@


@runtime_checkable
@PublicAPI(stability="beta")
@PublicAPI(stability="stable")
class BundleReaderLike(Protocol):
"""Structural reader contract — satisfied by ``BundleReader``.

Expand All @@ -100,17 +100,18 @@ def open_artifact(
storage_profile: str | None = None,
manifest: ExportManifest | None = None,
manifest_bytes: bytes | None = None,
) -> Any: ...
) -> AbstractContextManager[ResolvedArtifact]: ...


@runtime_checkable
@PublicAPI(stability="beta")
@PublicAPI(stability="stable")
class BundleModel(Protocol):
"""A loaded, in-memory model ready for prediction.

After loading, the model must not depend on the bundle's temporary
files — the runtime closes the artifact context as soon as loading
completes, so ``predict`` must work purely in memory.
The runtime retains its artifact context until explicit ``close``; it
does not close it as soon as loading completes. In-memory models, including
the Stable ONNX flavor, must remain usable after those reader resources
close. Other flavors keep their declared loading and execution contracts.
"""

@property
Expand Down Expand Up @@ -150,7 +151,7 @@ def predict(self, inputs: dict[str, np.ndarray]) -> dict[str, np.ndarray]:


@runtime_checkable
@PublicAPI(stability="beta")
@PublicAPI(stability="stable")
class BundleModelFlavor(Protocol):
"""Loads a ``BundleModel`` from a verified bundle artifact.

Expand Down Expand Up @@ -200,7 +201,7 @@ def load(
# ── Serveable flavor support matrix ───────────────────────────────────────────


@PublicAPI(stability="beta")
@PublicAPI(stability="stable")
@dataclass(frozen=True)
class FlavorSupportEntry:
"""One row of the model-artifact capability support matrix.
Expand Down Expand Up @@ -324,10 +325,15 @@ class FlavorSupportEntry:
# ── Loader ────────────────────────────────────────────────────────────────────


@PublicAPI(stability="beta")
@PublicAPI(stability="stable")
class BundleModelLoader:
"""Opens a published bundle as a serveable model runtime.

The Stable first-party execution scope is ``onnx-runtime-v1`` with named
tensors, integrity/security gates, typed signatures, and reader lifetime.
Registry routing and rejection contracts are stable; registering a plugin
does not promote that plugin's execution or model semantics.

Args:
bundle_reader: Reader for manifest + artifacts; defaults to a
fresh ``BundleReader``.
Expand Down Expand Up @@ -519,7 +525,7 @@ def open(
# ── Runtime ───────────────────────────────────────────────────────────────────


@PublicAPI(stability="beta")
@PublicAPI(stability="stable")
class BundleModelRuntime:
"""A loaded model plus the reader resources it was loaded from.

Expand Down
2 changes: 1 addition & 1 deletion src/tributo/integrations/flavors/onnx_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
__all__ = ["ONNXRuntimeFlavor"]


@PublicAPI(stability="beta")
@PublicAPI(stability="stable")
class ONNXRuntimeFlavor:
"""Loads ``onnx-runtime-v1`` artifacts into an ONNX Runtime session."""

Expand Down
11 changes: 11 additions & 0 deletions tests/fixtures/bundle-runtime-classifier.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"format": "onnx",
"ir_version": 10,
"opset": 18,
"operators": [
"Softmax",
"ArgMax"
],
"sha256": "f8d52e8e1589c80771fd4876e501dd7db8cb628fa9821c92fe3d2e02c76fa22e",
"model_base64": "CAoSDXRyaWJ1dG8tdGVzdHM68gEKMgoLZmxvYXRfaW5wdXQSDXByb2JhYmlsaXRpZXMiB1NvZnRtYXgqCwoEYXhpcxgBoAECCjwKDXByb2JhYmlsaXRpZXMSBWxhYmVsIgZBcmdNYXgqCwoEYXhpcxgBoAECKg8KCGtlZXBkaW1zGACgAQISGnRyaWJ1dG8tcnVudGltZS1jbGFzc2lmaWVyWiIKC2Zsb2F0X2lucHV0EhMKEQgBEg0KBxIFYmF0Y2gKAggCYhgKBWxhYmVsEg8KDQgHEgkKBxIFYmF0Y2hiJAoNcHJvYmFiaWxpdGllcxITChEIARINCgcSBWJhdGNoCgIIAkIECgAQEg=="
}
Loading
Loading