diff --git a/AGENTS.md b/AGENTS.md
index adee395..8b59b4a 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -5,7 +5,7 @@ inferred schema and model structure in one compressed `.mlbundle` file.
It owns export, metadata-only inspection and validated loading. It is the
training-side companion to MLSuite, whose runtime accepts `.mlbundle` uploads.
-MLSuite does not train models. The package version is 0.2.0; format 1 is not frozen.
+MLSuite does not train models. The package version is 0.2.1; format 1 is not frozen.
Implementation claims require code and test proof.
## What must remain true
diff --git a/README.md b/README.md
index a16d0a1..7c19263 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@
-
+
@@ -43,11 +43,11 @@ preserve the supported model without conversion.
## Installation
-MLbundle **0.2.0** requires Python **3.14** for export with the schema extra.
+MLbundle **0.2.1** requires Python **3.14** for export with the schema extra.
The installation command for this release is:
```bash
-python -m pip install "mlbundle[sklearn,schema]==0.2.0"
+python -m pip install "mlbundle[sklearn,schema]==0.2.1"
```
To use a local checkout, run `python -m pip install -e ".[sklearn,schema]"`
diff --git a/SECURITY.md b/SECURITY.md
index 5f1ed08..f52044a 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -1,6 +1,6 @@
# Security policy
-MLbundle 0.2.0 has not had an independent security review;
+MLbundle 0.2.1 has not had an independent security review;
do not accept bundles from untrusted parties. Format version 1 is not frozen.
It implements strict manifest validation, secure container reading/writing, metadata-only
`inspect`, export/load, sklearn, XGBoost, CatBoost and ONNX adapters, local schema inference,
diff --git a/docs/publishing.md b/docs/publishing.md
index ef847aa..5c8ad6c 100644
--- a/docs/publishing.md
+++ b/docs/publishing.md
@@ -1,6 +1,6 @@
# Publishing to PyPI
-Version `0.2.0` is prepared by this checkout. Merging a version change into
+Version `0.2.1` is prepared by this checkout. Merging a version change into
`main` automatically starts the PyPI workflow; no one needs to start a release
run manually. Format version 1 is not frozen, so incompatible manifest/schema
shapes require re-export. Valid a2 bundles remain compatible, as documented in
@@ -19,7 +19,7 @@ independent review; do not accept bundles from untrusted parties.
tests on Ubuntu and Windows, and all frontend checks, tests and builds.
4. If every check passes, Actions uploads the exact CI-built wheel and source
archive to [mlbundle on PyPI](https://pypi.org/project/mlbundle/).
- Install with `python -m pip install "mlbundle[sklearn,schema]==0.2.0"` on
+ Install with `python -m pip install "mlbundle[sklearn,schema]==0.2.1"` on
Python 3.14, replacing the example version as needed.
The GitHub `pypi_env` environment contains the project-scoped
diff --git a/docs/src/content/docs/getting-started/installation.md b/docs/src/content/docs/getting-started/installation.md
index 17bd87e..854a464 100644
--- a/docs/src/content/docs/getting-started/installation.md
+++ b/docs/src/content/docs/getting-started/installation.md
@@ -1,15 +1,15 @@
---
title: Installation
-description: Install mlbundle 0.2.0 with the extras for your model library, from PyPI or a local checkout, and check the Python and dependency ranges.
+description: Install mlbundle 0.2.1 with the extras for your model library, from PyPI or a local checkout, and check the Python and dependency ranges.
---
mlbundle requires **Python 3.14 or newer**. Its only core dependency is Pydantic v2; every model
library is an optional extra that is imported lazily, only when a bundle needs it.
-These pages document mlbundle 0.2.0.
+These pages document mlbundle 0.2.1.
```bash
-python -m pip install "mlbundle[sklearn,schema]==0.2.0"
+python -m pip install "mlbundle[sklearn,schema]==0.2.1"
```
Replace `sklearn` with the extra for your model library; the extras are listed
@@ -17,7 +17,7 @@ Replace `sklearn` with the extra for your model library; the extras are listed
## From a local checkout
-To work from source, or before 0.2.0 is available from your package index, install a checkout of
+To work from source, or before 0.2.1 is available from your package index, install a checkout of
the repository:
```bash
@@ -66,7 +66,7 @@ from importlib.metadata import version
import mlbundle
-print(version("mlbundle")) # 0.2.0
+print(version("mlbundle")) # 0.2.1
print(mlbundle.FORMAT_NAME, mlbundle.FORMAT_VERSION) # mlbundle 1
```
diff --git a/docs/src/content/docs/guides/cli.md b/docs/src/content/docs/guides/cli.md
index 14e94c3..89d7bbe 100644
--- a/docs/src/content/docs/guides/cli.md
+++ b/docs/src/content/docs/guides/cli.md
@@ -22,7 +22,7 @@ Metadata and integrity validated; model claims NOT verified.
Format: mlbundle 1
Bundle id: aa6f6b39-574a-499b-a0ff-de4cdd334050
Created: 2026-10-19T11:17:51.949658+00:00
-Writer: "0.2.0"
+Writer: "0.2.1"
Model: sklearn "DecisionTreeClassifier" (classifier)
Counts: features=2, outputs=1, classes=[2]
Features (declared): ["temperature", "humidity"]
@@ -34,7 +34,7 @@ Members:
schema.json: 361 bytes sha256=ea62a6a7502ae8ea30b45b61bb18d8e31bd2ec55f026d9fbf0c05ef42d01ff25
structure.json: 526 bytes sha256=66204da26781a4e2a800a1f3ed246ab1a43e8c97ced73d06a2640f897eeda03c
Training: {"python": "3.14.7", "implementation": "CPython", "os": "Windows", "os_version": "11", "architecture": "AMD64"}
-Packages: {"catboost": "1.2.10", "mlbundle": "0.2.0", "mlschema": "0.3.0", ...}
+Packages: {"catboost": "1.2.10", "mlbundle": "0.2.1", "mlschema": "0.3.0", ...}
ONNX environment: null
Present: schema=yes, structure=yes, samples=no
User metadata: {}
diff --git a/docs/src/content/docs/guides/inspect-and-load.md b/docs/src/content/docs/guides/inspect-and-load.md
index 69ea76c..0d7d53c 100644
--- a/docs/src/content/docs/guides/inspect-and-load.md
+++ b/docs/src/content/docs/guides/inspect-and-load.md
@@ -27,7 +27,7 @@ from mlbundle import inspect
view = inspect("trained.mlbundle")
manifest = view.manifest
-print(manifest.format_version, manifest.writer_version) # 1 0.2.0
+print(manifest.format_version, manifest.writer_version) # 1 0.2.1
print(manifest.model.n_features, manifest.model.n_outputs) # 2 1
print([member.value for member in view.members])
# ['manifest.json', 'model.skops', 'schema.json', 'structure.json']
diff --git a/landing/src/data/example.json b/landing/src/data/example.json
index acc01e0..6c0bc59 100644
--- a/landing/src/data/example.json
+++ b/landing/src/data/example.json
@@ -1,8 +1,8 @@
{
- "version": "0.2.0",
+ "version": "0.2.1",
"code": "import pandas as pd\nfrom sklearn.tree import DecisionTreeClassifier\n\nfrom mlbundle import export, load\n\ntraining = pd.DataFrame(\n [[0.0, 1.0, \"cold\"], [1.0, 0.0, \"warm\"]] * 2,\n columns=[\"temperature\", \"humidity\", \"target\"],\n)\nfeatures = training.drop(columns=\"target\")\nmodel = DecisionTreeClassifier(random_state=7)\nmodel.fit(features, training[\"target\"])\n\nexport(\n model,\n \"trained.mlbundle\",\n training_data=training,\n target_names=[\"target\"],\n)\n\nbundle = load(\"trained.mlbundle\")\nrecord = {\"temperature\": 0.0, \"humidity\": 1.0}\nprediction = bundle.predict_record(record)[0]\nprint(prediction.predicted_label, prediction.probabilities)\n",
"printed": "cold (1.0, 0.0)",
- "bundleBytes": 9227,
+ "bundleBytes": 9233,
"members": [
{
"name": "manifest.json",
@@ -12,7 +12,7 @@
{
"name": "model.skops",
"size": 15011,
- "sha256": "13257b547ae5a12c2bc5cea20afaf68d1a36d6073c8f77f1ae676979c40375d6"
+ "sha256": "b332c1e060939f16a2f300797c6ee1625e99d684f215e45ba8772fd7dfee5da2"
},
{
"name": "schema.json",
@@ -28,9 +28,9 @@
"manifest": {
"format_name": "mlbundle",
"format_version": "1",
- "bundle_id": "a9e717a9-b071-4d23-bbd1-6deedc47e6b5",
- "created_at": "2026-10-19T11:17:33.114088Z",
- "writer_version": "0.2.0",
+ "bundle_id": "869eb397-2dce-44b4-b0d0-b6a85d757b0b",
+ "created_at": "2026-10-19T13:27:32.304933Z",
+ "writer_version": "0.2.1",
"model": {
"estimator_class": "DecisionTreeClassifier",
"kind": "classifier",
@@ -90,7 +90,7 @@
"architecture": "AMD64",
"packages": {
"catboost": "1.2.10",
- "mlbundle": "0.2.0",
+ "mlbundle": "0.2.1",
"mlschema": "0.3.0",
"numpy": "2.5.4",
"onnx": "1.23.0",
@@ -105,7 +105,7 @@
},
"integrity": {
"model.skops": {
- "sha256": "13257b547ae5a12c2bc5cea20afaf68d1a36d6073c8f77f1ae676979c40375d6",
+ "sha256": "b332c1e060939f16a2f300797c6ee1625e99d684f215e45ba8772fd7dfee5da2",
"size": 15011
},
"schema.json": {
@@ -159,7 +159,7 @@
},
"inspect": {
"exit": 0,
- "stdout": "Metadata and integrity validated; model claims NOT verified.\nFormat: mlbundle 1\nBundle id: a9e717a9-b071-4d23-bbd1-6deedc47e6b5\nCreated: 2026-10-19T11:17:33.114088+00:00\nWriter: \"0.2.0\"\nModel: sklearn \"DecisionTreeClassifier\" (classifier)\nCounts: features=2, outputs=1, classes=[2]\nFeatures (model): [\"temperature\", \"humidity\"]\nClass labels (output-major): [[\"cold\", \"warm\"]]\nTarget names (output-major): [\"target\"]\nMembers:\n manifest.json: validated (no self-integrity record)\n model.skops: 15011 bytes sha256=13257b547ae5a12c2bc5cea20afaf68d1a36d6073c8f77f1ae676979c40375d6\n schema.json: 388 bytes sha256=e770ad53af881faf368c686de86b2b00f0a64a1444e241985643349bf7b0bba4\n structure.json: 511 bytes sha256=8cf658be94b826ba4f81f1a78ed2c8e5107fce656d212dc888bd8621a9068baa\nTraining: {\"python\": \"3.14.7\", \"implementation\": \"CPython\", \"os\": \"Windows\", \"os_version\": \"11\", \"architecture\": \"AMD64\"}\nPackages: {\"catboost\": \"1.2.10\", \"mlbundle\": \"0.2.0\", \"mlschema\": \"0.3.0\", \"numpy\": \"2.5.4\", \"onnx\": \"1.23.0\", \"onnxruntime\": \"1.30.0\", \"pandas\": \"3.0.6\", \"scikit-learn\": \"1.9.1\", \"scipy\": \"1.18.1\", \"skops\": \"0.16.0\", \"xgboost\": \"3.4.1\"}\nONNX environment: null\nPresent: schema=yes, structure=yes, samples=no\nUser metadata: {}",
+ "stdout": "Metadata and integrity validated; model claims NOT verified.\nFormat: mlbundle 1\nBundle id: 869eb397-2dce-44b4-b0d0-b6a85d757b0b\nCreated: 2026-10-19T13:27:32.304933+00:00\nWriter: \"0.2.1\"\nModel: sklearn \"DecisionTreeClassifier\" (classifier)\nCounts: features=2, outputs=1, classes=[2]\nFeatures (model): [\"temperature\", \"humidity\"]\nClass labels (output-major): [[\"cold\", \"warm\"]]\nTarget names (output-major): [\"target\"]\nMembers:\n manifest.json: validated (no self-integrity record)\n model.skops: 15011 bytes sha256=b332c1e060939f16a2f300797c6ee1625e99d684f215e45ba8772fd7dfee5da2\n schema.json: 388 bytes sha256=e770ad53af881faf368c686de86b2b00f0a64a1444e241985643349bf7b0bba4\n structure.json: 511 bytes sha256=8cf658be94b826ba4f81f1a78ed2c8e5107fce656d212dc888bd8621a9068baa\nTraining: {\"python\": \"3.14.7\", \"implementation\": \"CPython\", \"os\": \"Windows\", \"os_version\": \"11\", \"architecture\": \"AMD64\"}\nPackages: {\"catboost\": \"1.2.10\", \"mlbundle\": \"0.2.1\", \"mlschema\": \"0.3.0\", \"numpy\": \"2.5.4\", \"onnx\": \"1.23.0\", \"onnxruntime\": \"1.30.0\", \"pandas\": \"3.0.6\", \"scikit-learn\": \"1.9.1\", \"scipy\": \"1.18.1\", \"skops\": \"0.16.0\", \"xgboost\": \"3.4.1\"}\nONNX environment: null\nPresent: schema=yes, structure=yes, samples=no\nUser metadata: {}",
"stderr": ""
},
"verify": {
@@ -169,7 +169,7 @@
},
"editedInspect": {
"exit": 0,
- "stdout": "Metadata and integrity validated; model claims NOT verified.\nFormat: mlbundle 1\nBundle id: a9e717a9-b071-4d23-bbd1-6deedc47e6b5\nCreated: 2026-10-19T11:17:33.114088+00:00\nWriter: \"0.2.0\"\nModel: sklearn \"DecisionTreeClassifier\" (classifier)\nCounts: features=2, outputs=1, classes=[2]\nFeatures (model): [\"temperature\", \"humidity\"]\nClass labels (output-major): [[\"cold\", \"warm\"]]\nTarget names (output-major): [\"target\"]\nMembers:\n manifest.json: validated (no self-integrity record)\n model.skops: 15011 bytes sha256=13257b547ae5a12c2bc5cea20afaf68d1a36d6073c8f77f1ae676979c40375d6\n schema.json: 388 bytes sha256=e770ad53af881faf368c686de86b2b00f0a64a1444e241985643349bf7b0bba4\n structure.json: 511 bytes sha256=8cf658be94b826ba4f81f1a78ed2c8e5107fce656d212dc888bd8621a9068baa\nTraining: {\"python\": \"3.14.7\", \"implementation\": \"CPython\", \"os\": \"Windows\", \"os_version\": \"11\", \"architecture\": \"AMD64\"}\nPackages: {\"catboost\": \"1.2.10\", \"mlbundle\": \"0.2.0\", \"mlschema\": \"0.3.0\", \"numpy\": \"2.5.4\", \"onnx\": \"1.23.0\", \"onnxruntime\": \"1.30.0\", \"pandas\": \"3.0.6\", \"scikit-learn\": \"1.9.1\", \"scipy\": \"1.18.1\", \"skops\": \"0.16.0\", \"xgboost\": \"3.4.1\"}\nONNX environment: null\nPresent: schema=yes, structure=yes, samples=no\nUser metadata: {}",
+ "stdout": "Metadata and integrity validated; model claims NOT verified.\nFormat: mlbundle 1\nBundle id: 869eb397-2dce-44b4-b0d0-b6a85d757b0b\nCreated: 2026-10-19T13:27:32.304933+00:00\nWriter: \"0.2.1\"\nModel: sklearn \"DecisionTreeClassifier\" (classifier)\nCounts: features=2, outputs=1, classes=[2]\nFeatures (model): [\"temperature\", \"humidity\"]\nClass labels (output-major): [[\"cold\", \"warm\"]]\nTarget names (output-major): [\"target\"]\nMembers:\n manifest.json: validated (no self-integrity record)\n model.skops: 15011 bytes sha256=b332c1e060939f16a2f300797c6ee1625e99d684f215e45ba8772fd7dfee5da2\n schema.json: 388 bytes sha256=e770ad53af881faf368c686de86b2b00f0a64a1444e241985643349bf7b0bba4\n structure.json: 511 bytes sha256=8cf658be94b826ba4f81f1a78ed2c8e5107fce656d212dc888bd8621a9068baa\nTraining: {\"python\": \"3.14.7\", \"implementation\": \"CPython\", \"os\": \"Windows\", \"os_version\": \"11\", \"architecture\": \"AMD64\"}\nPackages: {\"catboost\": \"1.2.10\", \"mlbundle\": \"0.2.1\", \"mlschema\": \"0.3.0\", \"numpy\": \"2.5.4\", \"onnx\": \"1.23.0\", \"onnxruntime\": \"1.30.0\", \"pandas\": \"3.0.6\", \"scikit-learn\": \"1.9.1\", \"scipy\": \"1.18.1\", \"skops\": \"0.16.0\", \"xgboost\": \"3.4.1\"}\nONNX environment: null\nPresent: schema=yes, structure=yes, samples=no\nUser metadata: {}",
"stderr": ""
},
"editedVerify": {
diff --git a/playground/README.md b/playground/README.md
index 66acc0f..8d27486 100644
--- a/playground/README.md
+++ b/playground/README.md
@@ -8,7 +8,7 @@ Intended host: . Documentation: None:
import mlbundle
- assert mlbundle.__version__ == "0.2.0"
+ assert mlbundle.__version__ == "0.2.1"
view = mlbundle.inspect(path)
assert view.manifest.model.library == "sklearn"
assert "cannot attest" in _console("--help")
diff --git a/uv.lock b/uv.lock
index 2e6358f..29e8825 100644
--- a/uv.lock
+++ b/uv.lock
@@ -459,7 +459,7 @@ wheels = [
[[package]]
name = "mlbundle"
-version = "0.2.0"
+version = "0.2.1"
source = { editable = "." }
dependencies = [
{ name = "pydantic" },