Releases: block/model-ledger
Release list
v0.7.12
Fix: backslash escaping in SQL literals (#35) — _esc now doubles backslashes before doubling quotes; previously any JSON payload with an embedded double quote or backslash was mangled by Snowflake's escape processing inside single-quoted constants, failing PARSE_JSON on the fallback INSERT and poisoning the write buffer (every subsequent flush-before-read 500s). Found by independent post-merge review of #33/#34; verified against live Snowflake.
Also: privilege denials short-circuit the pandas path quietly (no per-flush warning/DROP), unexpected failures log with traceback, failure-path cleanup DROP removed, row construction inside try, regression tests for quote/backslash round-trip and the snapshots fallback.
Strongly recommended over 0.7.10/0.7.11 for any write-enabled deployment.
v0.7.11
Fix: pandas bulk path falls back to SQL on any failure (#34)
On sessions whose backing protocol cannot run PUT file transfers, write_pandas fails with KeyError('command') — not a privilege error — so the v0.7.10 fallback never engaged and the unclearable buffer turned every subsequent flush-before-read into a 500. The pandas path now falls back to the DDL-free SQL flush (idempotent, all columns) on any failure, with a warning logged.
Recommended for all write-enabled deployments on non-native-transport sessions; upgrade path 0.7.10 → 0.7.11 is drop-in.
v0.7.10
Fix: SQL fallback snapshot flush drops PAYLOAD and TAGS (#33)
_flush_snapshots_sql — the DDL-free path taken whenever the role cannot CREATE TEMPORARY TABLE (least-privilege deployments with row-level grants only) — inserted only the 7 scalar columns, silently persisting every snapshot with NULL PAYLOAD and TAGS. The fallback now carries both via PARSE_JSON in the INSERT...SELECT, matching the pandas path. Regression tests included.
If you run a write-enabled deployment on a role without temp-table privileges, upgrade before enabling writes: 0.7.4–0.7.9 lose snapshot payloads on this path.
v0.7.9
MCP Registry release: adds server.json (io.github.block/model-ledger) and the PyPI ownership marker the registry validates. Launch via MCP clients: uvx --from "model-ledger[mcp,cli]==0.7.9" model-ledger mcp.
Full details in CHANGELOG.md.
v0.7.8
What's new
Reliability on the first-touch paths (#29)
- Bare installs (
pip install model-ledgerwithout extras) get a one-line install hint frommodel-ledger --helpinstead of a traceback - Inventory CLI commands detect a Ledger event-log database and exit with guidance instead of a raw sqlite error
model-ledger validatewith an unknown profile exits listing the available profiles
Docs and README accuracy (#29)
- README: CI/downloads badges, production-scale benchmark callout (28.8k models / 212k events, sub-second inventory reconstruction), architecture diagram, SECURITY.md
- The SR 11-7/SR 26-2, EU AI Act Annex IV, and NIST AI RMF validation profiles are correctly documented as shipping in the OSS core (
model_ledger.validate) - Quickstart and all Ledger examples persist to
./ledger.db;history()ordering (newest first) is now shown correctly and asserted in CI
Breaking (#29)
- Removed the
scannermodule (Scanner,InventoryScanner,ModelCandidate,ScanReport), deprecated since v0.4.0 — useSourceConnector+DataNode+Ledger.add()/connect()
Packaging (#29)
- PyPI Development Status: Beta; new keywords:
mcp,model-context-protocol,ai-governance,eu-ai-act,nist-ai-rmf,sr-26-2
Full details in CHANGELOG.md.
v0.7.7 — session self-heal + investigate perf
Changes
- #24 — self-heal on auth-token expiry.
SnowflakeLedgerBackendaccepts an optionalconnection_factory; on Snowflake errno 390114 it swaps in a fresh connection and retries the same statement once. Backstop for long-idle expiry that keep-alive heartbeats can't fully prevent. Backward compatible. - #25 — batched edge resolution in the investigate/graph hot path.
v0.7.6 — least-privilege writes
Fixes
- #26 — least-privilege write path.
SnowflakeLedgerBackendno longer requires schema-ownership DDL to write. Write-mode init skipsCREATE SCHEMA/CREATE TABLE/ALTERwhen the schema + tables already exist (probed viaSELECT-onlyINFORMATION_SCHEMA), and the bulk write path falls back to a DDL-free SQLMERGE/INSERTwhen the role can't create the temp staging table. Net: the entire write path needs onlyINSERT/UPDATE/SELECT. Fresh deployments still auto-provision; introspection failure falls back to theCREATEpath. - #23 — status propagation. Connector-discovered
statuspropagates to the model row onLedger.add()(metadata['status']contract,ModelStatusenum validation, dedup-skip self-correction).
(v0.7.5 was skipped — a stray tag at a pre-v0.7.4 commit, never released.)
v0.7.4 — fast composite_summary
v0.7.4
Performance: SnowflakeLedgerBackend.composite_summary is now a single self-contained SQL statement (#21) — composite inventory queries drop from ~90s / 568 round trips to sub-second / 1 round trip on warehouse-backed ledgers. Semantics are parity-tested against the SDK fallback (replay-true member counts, observation set-difference, last-validated).
Also removes the backend's undeclared dependency on a deployment-specific view.
🤖 Generated with Claude Code
v0.7.3
Changes
- feat:
ModelRefgains ametadata: dict[str, Any]field (default empty). Thread throughregister()andregister_group(). - feat:
register_group(metadata=...)now stores metadata on the composite ModelRef itself. Previously broadcast to everylink_dependencycall (unintended). - feat:
composite_summary(model_types=...)— optional filter for callers treatingml_model/heuristic(or other types) as composites. Default behavior preserved (model_type="composite"). - fix: narrow
ALTER TABLE ADD COLUMN METADATA VARIANTexception suppression to "already exists" only. Previously swallowed all DDL errors. - schema: SQLite + Snowflake backends carry a
METADATAcolumn. Existing deployments auto-migrate via idempotentALTER TABLE.
Backward compatibility
Fully backward compatible. Existing serialized ModelRef data without a metadata field loads with metadata={}.
Upgrade
pip install -U model-ledger==0.7.3Or for git-pinned consumers:
model-ledger = { git = "https://github.com/block/model-ledger.git", tag = "v0.7.3" }v0.7.2
- Push
limit,offset,textfilters to SQL in Snowflake backend — avoids S3 result downloads for paginated queries - Add
count_models()for efficient total counts - In-memory backend also supports text/limit/offset for parity
- Fixes 403 errors when querying through corporate proxies that break S3 presigned URLs