From 1274180f26655c213eb9747ba4b5713fcb6313f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Thu, 10 Sep 2026 00:21:59 +0300 Subject: [PATCH 1/2] chore: prepare Python 0.8.1 patch release --- CHANGELOG.md | 34 +++++++++++++++++++++++++++-- README.md | 2 +- docs/release-readiness.md | 46 +++++++++++++++++++++++++++++++++++---- pyproject.toml | 2 +- tests/test_cli.py | 2 +- 5 files changed, 77 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb7c919..2918b1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,39 @@ All notable changes to this reference implementation are documented here. -## Unreleased +## 0.8.1 - Unreleased -_No unreleased changes._ +### Fixed + +- Preserve other variables' shared value labels when replacing one variable's + labels. Reject deletion of variables referenced by published derived lineage + before any plan mutation, with `variable_has_dependents`. +- Enable and verify SQLite foreign keys on in-place apply connections. +- Read export values, dictionary metadata, import fidelity events and validation + reflection from one native database snapshot; close it before writing SAV/ZSAV. +- Scope transformation label reads to the target variable's dataset. Unrelated + malformed labels no longer fail the operation; malformed target-linked labels + still fail, and shared/foreign-owned linked label sets remain supported. + +### Performance + +- Remove quadratic suffix/name scans from canonical-plan binding and reuse one + canonical plan encoding/hash per public canonical or SPSS apply. +- Remove redundant full case-row dictionary collections from database reads and + imports. Results remain buffered; this is not a streaming API. +- Avoid the discarded core relation hash during SQLite workflow registration, + retaining physical projection validation and derived-parent integrity checks. + Execution-time hashes remain required; their loop avoids a redundant tuple copy. + +### Documentation and cleanup + +- Document numeric create/replace, RECODE and separately provisioned target + recipes, with bounded local SQLite measurements in the transformations manual. +- Remove an unreachable view-creation branch; workflow output remains + materialized-only. + +The specification pin, engine dependency, database/profile claims, catalog schema, +public call signatures and Dolt-owned versioning policy remain unchanged. ## 0.8.0 - 2026-09-07 diff --git a/README.md b/README.md index 79b089b..fa596a7 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The reference Python implementation of the OpenStatSpec specification. This package implements the specification; it does not define or extend it. The normative model lives in the `OpenStatSpec/specification` repository. -Python 0.8.0 pins released specification `v0.5.0` at +Python 0.8.1 pins released specification `v0.5.0` at `864e84479f554b8ee250ffed44c4dfb963750d4a` and selects SAV/ZSAV 1.0 with `database_io_policy=openstatspec-database-io-v1`. This does not claim implementation of the optional Transformation Workflow 0.3 profile. diff --git a/docs/release-readiness.md b/docs/release-readiness.md index e79ff84..4b81c76 100644 --- a/docs/release-readiness.md +++ b/docs/release-readiness.md @@ -1,8 +1,17 @@ -# 0.8.0 release readiness +# 0.8.1 release readiness This page records the expected release contract, not a publication event. Creating a version tag remains a separate maintainer action. +## Patch scope + +Version 0.8.1 includes the merged metadata-integrity, consistent-read-snapshot, +row-copy, transformation-planning and SQLite workflow fixes described in the +[release notes](../CHANGELOG.md). It introduces no catalog +migration, dependency change, new database support or specification pin update. +The local 0.8.0 evidence below is historical, not verification of this patch. +Re-run the gates below on the exact selected 0.8.1 release commit. + The release selects SAV/ZSAV 1.0 with the optional Database I/O Execution Policy `openstatspec-database-io-v1`. Reads and exports, including failures, write no database audit records; export results omit `operation_id` and return @@ -104,7 +113,7 @@ The gate must prove that: neither HEAD nor branch and never commits or resets; state is rechecked after the dataset lock and success must leave an inspectable working-set diff; other supported SQL connections remain allowed; and -- string comparisons and v0.2 string assignments fail closed until exact +- string comparisons and v0.2 string assignments remain fail-closed. The built wheel must contain the generic openstatspec.transform modules and the implemented openstatspec.frontends.spss package. Stata and SAS remain empty @@ -156,6 +165,23 @@ of exact `864e84479f554b8ee250ffed44c4dfb963750d4a`): Other database services were not configured locally. This is local evidence, not a claim that the updated remote CI or release publication has completed. +## 0.8.1 local preparation verification + +On Python 3.13.2 with SQLAlchemy 2.0.52 and the exact v0.5.0 specification +checkout, without configured database services: + +- `python -m pytest -p no:cacheprovider -m 'not services'`: **414 passed, + 9 skipped, 53 deselected**. The release-ref guard tests also passed (**5**). +- `compileall`, `git diff --check`, wheel/sdist build and `twine check` passed. +- A clean wheel install outside the checkout resolved the required engine + `openstatspec-pyspssio==0.5.1.post2` from PyPI. Installed capabilities reported + 0.8.1, released specification v0.5.0 at the expected commit, and the selected + database I/O policy. Core, SPSS frontend and legacy compiler re-exports loaded + from `site-packages` without a source-path override. + +This is local candidate evidence, not final release-commit service CI or +publication evidence. No v0.8.1 tag or registry upload was made by these checks. + ## Maintainer checks before tagging 1. Publish the pinned `openstatspec-pyspssio==0.5.1.post2` engine distribution @@ -179,14 +205,26 @@ not a claim that the updated remote CI or release publication has completed. 4. Build with `python -m build` and install the generated wheel in a clean environment, resolving `openstatspec-pyspssio==0.5.1.post2` from PyPI. Run the installed CLI outside the source checkout with `PYTHONPATH` unset; - verify adapter version `0.8.0` and the selected database I/O policy. + verify adapter version `0.8.1` and the selected database I/O policy. 5. Confirm `openstatspec capabilities` reflects the intended support boundary. 6. Confirm CI, release fixtures, and capabilities use the published OpenStatSpec specification `v0.5.0` at exact commit `864e84479f554b8ee250ffed44c4dfb963750d4a`, publish `specification_status=released`, and set `specification_release` to `v0.5.0`. Use an exact checkout via `OPENSTATSPEC_SPECIFICATION_DIR` for local tests. -7. Review this document, the README, and CHANGELOG for accurate scope. +7. Review this document, the README, and CHANGELOG for accurate scope. Finalize + the 0.8.1 changelog date before selecting the final release commit. +8. Confirm the exact release commit's CI matrix and package smoke passed, and + verify the protected `pypi` environment and Trusted Publishing setup before + pushing a new annotated/protected `v0.8.1` tag. A `v*` tag push starts the + publishing workflow; it is not a preparation-only check. Do not move an + existing tag. The workflow also rebuilds the unchanged specification companion + package 0.1.0 at its existing pin and uses `skip-existing`; it does not release + the newer specification validator changes. +9. After publication, verify the tag resolves to the intended commit, the + tag-triggered workflow succeeded, and PyPI installs `openstatspec==0.8.1` in a + clean environment. Record the tag, CI and registry evidence before claiming + the release is published. The tag-triggered release workflow repeats the non-service test suite, builds the distributions, and installs the wheel with the exact required SPSS engine diff --git a/pyproject.toml b/pyproject.toml index 862a7dc..8a87876 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "openstatspec" -version = "0.8.0" +version = "0.8.1" description = "Reference adapter for the OpenStatSpec relational contract" readme = "README.md" requires-python = ">=3.11" diff --git a/tests/test_cli.py b/tests/test_cli.py index 3c0fdeb..b86d01b 100755 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -42,7 +42,7 @@ def test_cli_import_inspect_validate_and_export_emit_json(tmp_path, capsys) -> N def test_capability_matrix_is_public_and_cli_matches_engine_boundary(capsys) -> None: matrix = openstatspec.capability_matrix() - assert matrix["adapter_version"] == "0.8.0" + assert matrix["adapter_version"] == "0.8.1" assert matrix["database_io_policy"] == "openstatspec-database-io-v1" assert matrix["specification_status"] == "released" assert matrix["specification_release"] == "v0.5.0" From 7b82097b36a9e882cdded4d35c2e206fd8c0d003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Ormisson?= Date: Thu, 10 Sep 2026 00:32:29 +0300 Subject: [PATCH 2/2] docs: clarify release checklist includes publication --- docs/release-readiness.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release-readiness.md b/docs/release-readiness.md index 4b81c76..a4e186a 100644 --- a/docs/release-readiness.md +++ b/docs/release-readiness.md @@ -182,7 +182,7 @@ checkout, without configured database services: This is local candidate evidence, not final release-commit service CI or publication evidence. No v0.8.1 tag or registry upload was made by these checks. -## Maintainer checks before tagging +## Maintainer release checklist 1. Publish the pinned `openstatspec-pyspssio==0.5.1.post2` engine distribution first and confirm that a clean environment can download it from PyPI. The