openstatspec 0.3.0__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. {openstatspec-0.3.0 → openstatspec-0.5.0}/.github/workflows/ci.yml +3 -3
  2. {openstatspec-0.3.0 → openstatspec-0.5.0}/.github/workflows/release.yml +1 -1
  3. openstatspec-0.5.0/CHANGELOG.md +191 -0
  4. {openstatspec-0.3.0 → openstatspec-0.5.0}/PKG-INFO +27 -42
  5. {openstatspec-0.3.0 → openstatspec-0.5.0}/README.md +26 -41
  6. openstatspec-0.5.0/docs/in-place-transformation.md +9 -0
  7. {openstatspec-0.3.0 → openstatspec-0.5.0}/docs/release-readiness.md +51 -4
  8. openstatspec-0.5.0/docs/transformations.md +218 -0
  9. {openstatspec-0.3.0 → openstatspec-0.5.0}/pyproject.toml +5 -2
  10. openstatspec-0.5.0/src/openstatspec/__init__.py +48 -0
  11. {openstatspec-0.3.0 → openstatspec-0.5.0}/src/openstatspec/api.py +130 -19
  12. {openstatspec-0.3.0 → openstatspec-0.5.0}/src/openstatspec/cli.py +44 -4
  13. {openstatspec-0.3.0 → openstatspec-0.5.0}/src/openstatspec/core/__init__.py +14 -0
  14. openstatspec-0.5.0/src/openstatspec/frontends/__init__.py +1 -0
  15. openstatspec-0.5.0/src/openstatspec/frontends/sas/.gitkeep +0 -0
  16. openstatspec-0.5.0/src/openstatspec/frontends/spss/__init__.py +30 -0
  17. openstatspec-0.5.0/src/openstatspec/frontends/spss/binding.py +511 -0
  18. {openstatspec-0.3.0/src/openstatspec/transform → openstatspec-0.5.0/src/openstatspec/frontends/spss}/compiler.py +16 -2
  19. openstatspec-0.5.0/src/openstatspec/frontends/spss/execution.py +50 -0
  20. {openstatspec-0.3.0/src/openstatspec/transform → openstatspec-0.5.0/src/openstatspec/frontends/spss}/syntax.py +309 -6
  21. openstatspec-0.5.0/src/openstatspec/frontends/stata/.gitkeep +0 -0
  22. openstatspec-0.5.0/src/openstatspec/spss/__init__.py +36 -0
  23. openstatspec-0.5.0/src/openstatspec/spss/sav.py +1244 -0
  24. openstatspec-0.5.0/src/openstatspec/sql/__init__.py +66 -0
  25. openstatspec-0.5.0/src/openstatspec/sql/capabilities.py +624 -0
  26. openstatspec-0.5.0/src/openstatspec/sql/catalog_verification.py +283 -0
  27. openstatspec-0.5.0/src/openstatspec/sql/database_urls.py +22 -0
  28. openstatspec-0.5.0/src/openstatspec/sql/dolt_conformance.py +455 -0
  29. openstatspec-0.5.0/src/openstatspec/sql/inplace_transform.py +1104 -0
  30. {openstatspec-0.3.0 → openstatspec-0.5.0}/src/openstatspec/sql/profiles.py +132 -35
  31. openstatspec-0.5.0/src/openstatspec/sql/wide.py +1749 -0
  32. {openstatspec-0.3.0 → openstatspec-0.5.0}/src/openstatspec/sql/workflow.py +3 -2
  33. openstatspec-0.5.0/src/openstatspec/transform/__init__.py +64 -0
  34. openstatspec-0.5.0/src/openstatspec/transform/plan.py +854 -0
  35. openstatspec-0.5.0/src/openstatspec/transform/schema.py +88 -0
  36. openstatspec-0.5.0/src/openstatspec/transform/validation.py +378 -0
  37. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/conformance.py +1 -1
  38. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/test_atomic_import.py +212 -82
  39. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/test_attribute_catalog.py +21 -52
  40. openstatspec-0.5.0/tests/test_catalog_lifecycle.py +208 -0
  41. openstatspec-0.5.0/tests/test_catalog_persistence_review.py +253 -0
  42. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/test_cli.py +72 -5
  43. openstatspec-0.5.0/tests/test_conditional_inplace_transform.py +374 -0
  44. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/test_document_round_trip.py +10 -6
  45. openstatspec-0.5.0/tests/test_dolt_conformance.py +382 -0
  46. openstatspec-0.5.0/tests/test_inplace_transform.py +1088 -0
  47. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/test_loss_reports.py +39 -36
  48. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/test_normative_catalog.py +2 -0
  49. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/test_official_conformance.py +9 -4
  50. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/test_pyspssio_catalog_authority.py +25 -15
  51. openstatspec-0.5.0/tests/test_review_transaction_boundary.py +209 -0
  52. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/test_sav_sqlite.py +237 -22
  53. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/test_spss_catalog_preflight.py +24 -16
  54. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/test_sql_profiles.py +341 -108
  55. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/test_sql_services.py +35 -152
  56. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/test_sql_workflow.py +4 -0
  57. openstatspec-0.5.0/tests/test_strict_catalog_review.py +188 -0
  58. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/test_transform_frontend.py +314 -5
  59. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/test_vls_compatible_names.py +10 -44
  60. openstatspec-0.3.0/CHANGELOG.md +0 -92
  61. openstatspec-0.3.0/docs/in-place-transformation.md +0 -41
  62. openstatspec-0.3.0/src/openstatspec/__init__.py +0 -32
  63. openstatspec-0.3.0/src/openstatspec/spss/__init__.py +0 -22
  64. openstatspec-0.3.0/src/openstatspec/spss/sav.py +0 -575
  65. openstatspec-0.3.0/src/openstatspec/sql/__init__.py +0 -14
  66. openstatspec-0.3.0/src/openstatspec/sql/capabilities.py +0 -452
  67. openstatspec-0.3.0/src/openstatspec/sql/inplace_transform.py +0 -556
  68. openstatspec-0.3.0/src/openstatspec/sql/wide.py +0 -1241
  69. openstatspec-0.3.0/src/openstatspec/transform/__init__.py +0 -33
  70. openstatspec-0.3.0/src/openstatspec/transform/binding.py +0 -298
  71. openstatspec-0.3.0/src/openstatspec/transform/plan.py +0 -416
  72. openstatspec-0.3.0/tests/test_inplace_transform.py +0 -309
  73. {openstatspec-0.3.0 → openstatspec-0.5.0}/.github/verify_release_ref.py +0 -0
  74. {openstatspec-0.3.0 → openstatspec-0.5.0}/.gitignore +0 -0
  75. {openstatspec-0.3.0 → openstatspec-0.5.0}/THIRD_PARTY_NOTICES.md +0 -0
  76. {openstatspec-0.3.0 → openstatspec-0.5.0}/docs/architecture.md +0 -0
  77. {openstatspec-0.3.0 → openstatspec-0.5.0}/docs/pyspssio-spike.md +0 -0
  78. {openstatspec-0.3.0 → openstatspec-0.5.0}/docs/sav-profile.md +0 -0
  79. {openstatspec-0.3.0 → openstatspec-0.5.0}/docs/sql-transformation-workflow.md +0 -0
  80. {openstatspec-0.3.0 → openstatspec-0.5.0}/src/openstatspec/core/results.py +0 -0
  81. {openstatspec-0.3.0 → openstatspec-0.5.0}/src/openstatspec/spss/dictionary.py +0 -0
  82. {openstatspec-0.3.0 → openstatspec-0.5.0}/src/openstatspec/spss/raw_dictionary.py +0 -0
  83. {openstatspec-0.3.0 → openstatspec-0.5.0}/src/openstatspec/sql/catalog_api.py +0 -0
  84. {openstatspec-0.3.0 → openstatspec-0.5.0}/src/openstatspec/sql/normative.py +0 -0
  85. {openstatspec-0.3.0 → openstatspec-0.5.0}/src/openstatspec/transform/errors.py +0 -0
  86. {openstatspec-0.3.0 → openstatspec-0.5.0}/tests/test_release_ref.py +0 -0
@@ -20,7 +20,7 @@ jobs:
20
20
  uses: actions/checkout@v7
21
21
  with: &specification-checkout
22
22
  repository: OpenStatSpec/specification
23
- ref: 79339ec3d8f8aa81789b7e85f6b8afa6f1374e50
23
+ ref: f2fdf687d8cb32b944ca55a3e9e7215ffc603019
24
24
  path: openstatspec-specification
25
25
  - name: Checkout required SPSS engine
26
26
  uses: actions/checkout@v7
@@ -143,7 +143,7 @@ jobs:
143
143
  steps: *sql-test-steps
144
144
 
145
145
  dolt-integration:
146
- name: Dolt ${{ matrix.dolt }} integration
146
+ name: Dolt ${{ matrix.dolt }} read-only / fail-closed integration
147
147
  runs-on: ubuntu-latest
148
148
  strategy:
149
149
  fail-fast: false
@@ -217,7 +217,7 @@ jobs:
217
217
  connection.close()
218
218
  break
219
219
  PY
220
- - run: python -m pytest -m services
220
+ - run: python -m pytest -m "services and not candidate_evidence"
221
221
  - name: Show Dolt logs on failure and stop server
222
222
  if: always()
223
223
  run: |
@@ -47,7 +47,7 @@ jobs:
47
47
  uses: actions/checkout@v7
48
48
  with:
49
49
  repository: OpenStatSpec/specification
50
- ref: 79339ec3d8f8aa81789b7e85f6b8afa6f1374e50
50
+ ref: f2fdf687d8cb32b944ca55a3e9e7215ffc603019
51
51
  path: openstatspec-specification
52
52
  - name: Checkout required SPSS engine
53
53
  uses: actions/checkout@v7
@@ -0,0 +1,191 @@
1
+ # Changelog
2
+
3
+ All notable changes to this reference implementation are documented here.
4
+
5
+ ## Unreleased
6
+
7
+ Planned adapter release: `0.5.0`, after lifecycle integration and final specification conformance.
8
+ ### Fixed
9
+
10
+ - Removed the temporary `*_catalog` compatibility schema and made SAV/ZSAV
11
+ import, validation, export, fidelity reporting, and in-place metadata edits
12
+ use the normative UUID-keyed OpenStatSpec catalog exclusively.
13
+ - Existing databases that contain former compatibility relations must be
14
+ remediated manually before further operations.
15
+ - Imports now reject dataset names that collide with normative UUID identifiers,
16
+ cleanup drops only a physical table actually created by the failing import,
17
+ and non-preserved SPSS compatible variable names are reported as an explicit
18
+ loss requiring export consent.
19
+
20
+
21
+ ### Added
22
+
23
+ - Added bounded typed expressions with variable references, numeric literals,
24
+ parentheses, `=`, `<`, `<=`, `>`, `>=`, `AND`, and `OR`. String comparison
25
+ and v0.2 string assignment fail closed pending exact portable semantics.
26
+ - Added sequential SPSS-like `COMPUTE` and `IF` assignment operations plus
27
+ `FORMATS`, `VARIABLE LEVEL`, and `EXECUTE`.
28
+ - Added atomic numeric target creation on SQLite and PostgreSQL. MySQL,
29
+ MariaDB, and Dolt fail closed on `target_mode=create`; their targets must be
30
+ provisioned physically and in the catalog by a separate versioned stage
31
+ before this executor applies assignment and metadata operations.
32
+ - Added synthetic exact-program, catalog, failure-boundary, and pre-existing
33
+ target regression coverage.
34
+
35
+ ### Changed
36
+
37
+ - Bumped the canonical transformation-plan and SPSS frontend contracts to
38
+ `v0.2`; canonical JSON and hashes include every sequential operation.
39
+ - In-place apply records variable label, value labels, `F` print/write
40
+ format, and measurement level only in the normative catalog.
41
+ - Dolt still requires an exact branch, exact HEAD, and clean working set;
42
+ successful apply leaves an inspectable diff and never calls `DOLT_COMMIT`.
43
+ - Dolt declaration validation is implemented by the Python adapter. The
44
+ specification remains a language-neutral source of JSON contracts and
45
+ fixtures and is not installed as a Python distribution.
46
+
47
+ ### Specification basis
48
+
49
+ - Release validation is pinned to the untagged OpenStatSpec specification
50
+ release candidate at immutable commit
51
+ `f2fdf687d8cb32b944ca55a3e9e7215ffc603019`. Its
52
+ `specification_release` remains null until that commit receives a stable tag.
53
+
54
+ ## 0.4.0 — 2026-07-31
55
+
56
+ ### Added
57
+
58
+ - Added a public canonical transformation-plan in-place API accepting either
59
+ typed plan objects or strictly validated mappings.
60
+ - Added apply-plan and install-in-place-schema CLI workflows alongside the
61
+ compatible apply-spss command.
62
+ - Added explicit audit provenance distinguishing canonical plan documents from
63
+ SPSS syntax sources.
64
+ - Added a transformation manual covering the canonical core, frontend boundary,
65
+ execution invariants, CLI/API workflows, and extension rules.
66
+
67
+ ### Changed
68
+
69
+ - Moved the SPSS parser, binder, compiler, and convenience execution adapter to
70
+ the dedicated openstatspec.frontends.spss package.
71
+ - Kept openstatspec.transform language-neutral with canonical plan, schema, and
72
+ live-schema validation modules while preserving previous SPSS import paths.
73
+ - Reserved empty Stata and SAS frontend directories without exposing parsers,
74
+ capabilities, CLI choices, or support claims.
75
+ - Strengthened pre-mutation target-type checks and target-scoped physical table
76
+ identity guards. The executor continues to modify the same dataset and table
77
+ without creating OpenStatSpec rollback, copy, snapshot, or history layers.
78
+
79
+ ### Specification basis
80
+
81
+ - Conformance and release validation continue to use OpenStatSpec specification
82
+ release v0.2.0 at exact commit
83
+ 79339ec3d8f8aa81789b7e85f6b8afa6f1374e50.
84
+
85
+ ## 0.3.0 — 2026-07-31
86
+
87
+ ### Added
88
+
89
+ - Added a bounded SPSS-like `RECODE`, `VARIABLE LABELS`, and `VALUE LABELS`
90
+ parser with stable diagnostics and conformance fixtures.
91
+ - Added canonical Transformation Plan serialization, RFC 8785 hashes, schema
92
+ binding, deterministic typed operations, and an agent-facing CLI/API.
93
+ - Added product-neutral in-place execution with same dataset/table identity,
94
+ direct data and metadata mutation, and compact operation audit. Dolt adds
95
+ expected branch/HEAD and clean-working-set checks.
96
+
97
+ ### Changed
98
+
99
+ - Version history, diff, rollback, restoration, and commit remain database
100
+ responsibilities; the transformer creates no derived/copy/snapshot/recovery
101
+ layer and performs no `DOLT_COMMIT`.
102
+ - SQL server support now distinguishes conservative family claims from exact
103
+ CI evidence: PostgreSQL 17.x/18.x at 17.10/18.4, MySQL 8.4.x/9.7.x at
104
+ 8.4.11/9.7.2, and MariaDB 11.4.x/11.8.x/12.3.x at
105
+ 11.4.12/11.8.8/12.3.2. Each service job verifies the live normalized version.
106
+ - Dolt remains an independent core profile, now claiming canonical stable
107
+ versions `>=2.2.2,<2.3.0` and running its complete service suite at exact
108
+ versions 2.2.2 and 2.2.3 from immutable container-image pins.
109
+ SQLite retains its core `>=3.24.0,<4.0.0` and optional workflow
110
+ `>=3.35.0,<4.0.0` tiers. MSSQL remains unsupported and roadmap-only.
111
+
112
+ ### Specification basis
113
+
114
+ - CI, release validation, and machine-readable capabilities use OpenStatSpec
115
+ specification release `v0.2.0` at exact commit
116
+ `79339ec3d8f8aa81789b7e85f6b8afa6f1374e50`.
117
+
118
+ ## 0.2.0 — 2026-07-30
119
+
120
+ This release extends the reference adapter while keeping imported source
121
+ datasets immutable and all unsupported paths fail-closed.
122
+
123
+ ### Added
124
+
125
+ - An optional SQLite-only Transformation Workflow for immutable, versioned,
126
+ parameterized SELECT definitions; materialized derived datasets; lineage and
127
+ weights; public catalog APIs; and CLI operations.
128
+ - An independent Dolt core SQL profile for exact product version 2.2.2, with
129
+ service-backed coverage, conservative adapter limits, complete compensating
130
+ cleanup, and pre-DDL rejection of unsupported values. Transformation Workflow
131
+ support on Dolt is not claimed.
132
+
133
+ ### Changed
134
+
135
+ - SAV and ZSAV validation now rewrites legacy compatible names consistently
136
+ across type-2 records and subtype-13/subtype-14 long-name metadata.
137
+ - Transformation publication, interrupted-run reconciliation, retirement, and
138
+ physical-removal recovery now preserve auditable state and fail closed on
139
+ catalog or relation drift.
140
+ - Release automation builds distributions before test-only source checkouts and
141
+ supports idempotent rebuilds of an existing release tag.
142
+
143
+ ### Specification basis
144
+
145
+ - CI and release validation are pinned to OpenStatSpec specification release
146
+ `v1.0.0-rc.1` at exact commit
147
+ `fef0dc6f4b17ff7141dad3f49d0524c63efbfed5`.
148
+
149
+ ## 0.1.0 — 2026-07-29
150
+
151
+ First public reference implementation of the OpenStatSpec strict wide-table
152
+ SPSS profile.
153
+
154
+ ### Included
155
+
156
+ - Import of unencrypted SAV and ZSAV sources into one dedicated wide SQL table
157
+ and its metadata catalog.
158
+ - Export of supported dataset semantics to SAV and ZSAV.
159
+ - SQLite, PostgreSQL, MySQL, and MariaDB profiles, including service-backed
160
+ PostgreSQL 17/18, MySQL 8.4/9.7, and MariaDB 11.4/11.8/12.3 CI coverage.
161
+ - Read-only positive Dolt identity and working-set inspection. Operational
162
+ Dolt writes use adapter-owned declaration validation and remain fail-closed
163
+ because the adapter ships no concrete declaration claim. The specification
164
+ remains language-neutral and is consumed only as JSON contracts and fixtures.
165
+ - Added explicit packaged/directory conformance-source injection and exact
166
+ single-match binding across active Dolt product version, adapter
167
+ implementation and version, and specification commit before mutation.
168
+ - Explicit catalog initialization/migration through `initialize_catalog` and
169
+ `openstatspec init`; data operations never auto-create catalog relations.
170
+ - Read-only Dolt working-set evidence through `dolt_state_snapshot` and
171
+ `openstatspec dolt-state`; core performs no Dolt version-control mutations.
172
+ - Preflight checks for target profile limits, atomic imports, validation, a
173
+ command-line interface, and machine-readable capability and loss reports.
174
+
175
+ ### Important boundaries
176
+
177
+ - This release promises semantic round-trip equivalence only for supported
178
+ features; it never promises byte-identical SAV/ZSAV output.
179
+ - The adapter requires explicit `allow_loss` consent before exporting known
180
+ unsupported or lossy dictionary semantics.
181
+ - Multiple-response sets, variable alignment, variable sets, and custom
182
+ attributes have explicit capability diagnostics; see the SAV profile.
183
+ - Encrypted SPSS files are not supported.
184
+ - Dolt adapter-envelope values are not claims about Dolt server limits. Failure
185
+ recovery is compensating and reports deterministic residual inventory; a
186
+ verified catalog receives a best-effort failed-operation audit when cleanup
187
+ itself fails.
188
+ - Export publication uses a durable, audit-recorded prior-file backup through
189
+ SQL finalization. Post-success backup retention is reported separately and
190
+ does not rewrite a successful export as failed; pre-success failures restore
191
+ the prior destination and close the running operation as failed.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openstatspec
3
- Version: 0.3.0
3
+ Version: 0.5.0
4
4
  Summary: Reference adapter for the OpenStatSpec relational contract
5
5
  Author: OpenStatSpec
6
6
  License: Apache-2.0
@@ -30,10 +30,10 @@ For each supported import, one source dataset becomes one dedicated wide SQL
30
30
  table. Cases are rows and source variables are physical SQL columns. The
31
31
  singular UUID-keyed tables from the specification (`dataset`, `variable`,
32
32
  `operation`, `fidelity_event`, and related metadata tables) are the public
33
- catalog contract. Historical `*_catalog` tables are an internal compatibility
34
- layer for the current exporter and are not the standard database interface.
35
- The adapter does not reshape data, create EAV
36
- or long-form tables, or harmonize studies or waves.
33
+ catalog contract and the only catalog representation created or read by the
34
+ adapter. Databases created with the former `*_catalog` compatibility schema
35
+ must be remediated to the normative schema before use. The adapter does not
36
+ reshape data, create EAV or long-form tables, or harmonize studies or waves.
37
37
 
38
38
  Unsupported source features, SQL targets, or export paths fail explicitly.
39
39
  There is no silent truncation, type conversion, metadata loss, or partial
@@ -45,6 +45,10 @@ import.
45
45
  capabilities, and loss reports.
46
46
  - `openstatspec.sql`: database connection and wide-table/catalog operations.
47
47
  - `openstatspec.spss`: SAV/ZSAV adapter boundary.
48
+ - `openstatspec.transform`: canonical plans, frontend-neutral schema concepts,
49
+ and plan validation.
50
+ - `openstatspec.frontends.spss`: the SPSS-like syntax frontend and convenience
51
+ execution adapter.
48
52
 
49
53
  ## Intended workflow
50
54
 
@@ -82,43 +86,24 @@ implemented capability boundary.
82
86
 
83
87
  ## SPSS-like transformation frontend
84
88
 
85
- The transformation frontend accepts `RECODE`, `VARIABLE LABELS`, and
86
- `VALUE LABELS`, lowers them to a canonical OpenStatSpec Transformation Plan,
87
- and mutates the same logical dataset and physical wide table. SQLite,
88
- PostgreSQL, MySQL, MariaDB, and Dolt connections are allowed. It creates no
89
- derived dataset, copied table, snapshot, or OpenStatSpec rollback/version layer.
90
-
91
- Install the compact operation-audit relation separately, then apply syntax:
92
-
93
- ```python
94
- from openstatspec import (
95
- apply_spss_in_place,
96
- install_in_place_transformation_schema,
97
- )
98
-
99
- database_url = "postgresql+psycopg://user:password@host/database"
100
- install_in_place_transformation_schema(database_url=database_url)
101
- result = apply_spss_in_place(
102
- database_url=database_url,
103
- dataset_id="...",
104
- actor="agent@example.org",
105
- source_text="""
106
- RECODE age (18 THRU 34 = 1) (35 THRU 64 = 2) INTO age_group.
107
- VARIABLE LABELS age_group 'Age group'.
108
- VALUE LABELS age_group 1 '18-34' 2 '35-64'.
109
- """,
110
- )
111
- ```
112
-
113
- Existing-target recodes and metadata mutations use direct DML. SQLite and
114
- PostgreSQL may also add a target column in the same native transaction. MySQL,
115
- MariaDB, and Dolt reject such schema-changing plans before mutation because
116
- their implicit-commit DDL could otherwise leave a partial apply. On Dolt, the
117
- caller additionally supplies expected branch and HEAD identities, and the
118
- working set must be clean. The transformer never calls `DOLT_COMMIT`.
119
-
120
- See [in-place transformations](docs/in-place-transformation.md) for the full
121
- execution boundary and CLI form.
89
+ The bounded SPSS-like frontend lowers `RECODE`, sequential `COMPUTE` and `IF`,
90
+ `VARIABLE LABELS`, `VALUE LABELS`, numeric `FORMATS`, `VARIABLE LEVEL`, and
91
+ `EXECUTE` into a language-neutral typed canonical plan. Conditions support
92
+ parentheses, variable and numeric literal operands, comparisons, `AND`, and
93
+ `OR`. String comparison and v0.2 string assignment currently fail closed.
94
+ The in-place path applies the plan to the same logical dataset, physical wide
95
+ table, and normative/compatibility metadata without a derived dataset, copied
96
+ table, snapshot, or hidden history layer. Numeric targets may be created
97
+ atomically on SQLite and PostgreSQL. MySQL, MariaDB, and Dolt fail closed on
98
+ `target_mode=create` and require a separately provisioned physical and catalog
99
+ target before assignment. Dolt requires the caller's exact clean branch/HEAD,
100
+ leaves success as an inspectable working-set diff, and never calls
101
+ `DOLT_COMMIT`.
102
+
103
+ See the [dataset transformations manual](docs/transformations.md) for schema
104
+ installation, Python and CLI surfaces, database invariants, audit provenance,
105
+ package layout, and extension guidance. Stata and SAS are unimplemented
106
+ placeholders.
122
107
 
123
108
  ## Current support status
124
109
 
@@ -11,10 +11,10 @@ For each supported import, one source dataset becomes one dedicated wide SQL
11
11
  table. Cases are rows and source variables are physical SQL columns. The
12
12
  singular UUID-keyed tables from the specification (`dataset`, `variable`,
13
13
  `operation`, `fidelity_event`, and related metadata tables) are the public
14
- catalog contract. Historical `*_catalog` tables are an internal compatibility
15
- layer for the current exporter and are not the standard database interface.
16
- The adapter does not reshape data, create EAV
17
- or long-form tables, or harmonize studies or waves.
14
+ catalog contract and the only catalog representation created or read by the
15
+ adapter. Databases created with the former `*_catalog` compatibility schema
16
+ must be remediated to the normative schema before use. The adapter does not
17
+ reshape data, create EAV or long-form tables, or harmonize studies or waves.
18
18
 
19
19
  Unsupported source features, SQL targets, or export paths fail explicitly.
20
20
  There is no silent truncation, type conversion, metadata loss, or partial
@@ -26,6 +26,10 @@ import.
26
26
  capabilities, and loss reports.
27
27
  - `openstatspec.sql`: database connection and wide-table/catalog operations.
28
28
  - `openstatspec.spss`: SAV/ZSAV adapter boundary.
29
+ - `openstatspec.transform`: canonical plans, frontend-neutral schema concepts,
30
+ and plan validation.
31
+ - `openstatspec.frontends.spss`: the SPSS-like syntax frontend and convenience
32
+ execution adapter.
29
33
 
30
34
  ## Intended workflow
31
35
 
@@ -63,43 +67,24 @@ implemented capability boundary.
63
67
 
64
68
  ## SPSS-like transformation frontend
65
69
 
66
- The transformation frontend accepts `RECODE`, `VARIABLE LABELS`, and
67
- `VALUE LABELS`, lowers them to a canonical OpenStatSpec Transformation Plan,
68
- and mutates the same logical dataset and physical wide table. SQLite,
69
- PostgreSQL, MySQL, MariaDB, and Dolt connections are allowed. It creates no
70
- derived dataset, copied table, snapshot, or OpenStatSpec rollback/version layer.
71
-
72
- Install the compact operation-audit relation separately, then apply syntax:
73
-
74
- ```python
75
- from openstatspec import (
76
- apply_spss_in_place,
77
- install_in_place_transformation_schema,
78
- )
79
-
80
- database_url = "postgresql+psycopg://user:password@host/database"
81
- install_in_place_transformation_schema(database_url=database_url)
82
- result = apply_spss_in_place(
83
- database_url=database_url,
84
- dataset_id="...",
85
- actor="agent@example.org",
86
- source_text="""
87
- RECODE age (18 THRU 34 = 1) (35 THRU 64 = 2) INTO age_group.
88
- VARIABLE LABELS age_group 'Age group'.
89
- VALUE LABELS age_group 1 '18-34' 2 '35-64'.
90
- """,
91
- )
92
- ```
93
-
94
- Existing-target recodes and metadata mutations use direct DML. SQLite and
95
- PostgreSQL may also add a target column in the same native transaction. MySQL,
96
- MariaDB, and Dolt reject such schema-changing plans before mutation because
97
- their implicit-commit DDL could otherwise leave a partial apply. On Dolt, the
98
- caller additionally supplies expected branch and HEAD identities, and the
99
- working set must be clean. The transformer never calls `DOLT_COMMIT`.
100
-
101
- See [in-place transformations](docs/in-place-transformation.md) for the full
102
- execution boundary and CLI form.
70
+ The bounded SPSS-like frontend lowers `RECODE`, sequential `COMPUTE` and `IF`,
71
+ `VARIABLE LABELS`, `VALUE LABELS`, numeric `FORMATS`, `VARIABLE LEVEL`, and
72
+ `EXECUTE` into a language-neutral typed canonical plan. Conditions support
73
+ parentheses, variable and numeric literal operands, comparisons, `AND`, and
74
+ `OR`. String comparison and v0.2 string assignment currently fail closed.
75
+ The in-place path applies the plan to the same logical dataset, physical wide
76
+ table, and normative/compatibility metadata without a derived dataset, copied
77
+ table, snapshot, or hidden history layer. Numeric targets may be created
78
+ atomically on SQLite and PostgreSQL. MySQL, MariaDB, and Dolt fail closed on
79
+ `target_mode=create` and require a separately provisioned physical and catalog
80
+ target before assignment. Dolt requires the caller's exact clean branch/HEAD,
81
+ leaves success as an inspectable working-set diff, and never calls
82
+ `DOLT_COMMIT`.
83
+
84
+ See the [dataset transformations manual](docs/transformations.md) for schema
85
+ installation, Python and CLI surfaces, database invariants, audit provenance,
86
+ package layout, and extension guidance. Stata and SAS are unimplemented
87
+ placeholders.
103
88
 
104
89
  ## Current support status
105
90
 
@@ -0,0 +1,9 @@
1
+ # In-place transformations
2
+
3
+ This page has moved to the comprehensive
4
+ [dataset transformations manual](transformations.md).
5
+
6
+ The manual covers the canonical plan, SPSS-like frontend, executor, audit
7
+ schema, Python and CLI surfaces, database and Dolt invariants, provenance,
8
+ package layout, and future frontend boundary. Stata and SAS remain
9
+ unimplemented placeholders.
@@ -1,4 +1,4 @@
1
- # 0.3.0 release readiness
1
+ # 0.5.0 release readiness
2
2
 
3
3
  This page records the expected release contract, not a publication event.
4
4
  Creating a version tag remains a separate maintainer action.
@@ -56,6 +56,50 @@ otherwise the strict export policy reports and blocks the loss. A caller
56
56
  that supplies consent for an available loss code receives the
57
57
  machine-readable loss report with the export result.
58
58
 
59
+ ## Transformation release gates
60
+
61
+ The canonical transformation core and SPSS syntax frontend are separate public
62
+ surfaces. A release must run the specification-owned canonical-plan and SPSS
63
+ frontend conformance fixtures, then exercise both the generic plan apply API
64
+ and the SPSS compatibility apply path.
65
+
66
+ The gate must prove that:
67
+
68
+ - a TransformationPlan object and its strict JSON mapping produce the same
69
+ plan hash and in-place result;
70
+ - the exact bounded `COMPUTE`/`IF` program compiles to all seven ordered
71
+ operations without dropping `FORMATS`, `VARIABLE LEVEL`, or `EXECUTE`;
72
+ - boolean data results match the equivalent expression and the target's label,
73
+ 0/1 value labels, `F1.0` print/write format, and nominal level exist in the
74
+ normative catalog;
75
+ - injected schema, data, catalog, and audit failures leave no partial apply;
76
+ - compensation tracks only newly created targets and never drops or rewrites a
77
+ pre-existing target;
78
+ - MySQL, MariaDB, and Dolt reject create-target plans before mutation; their
79
+ service evidence covers assignment to a separately provisioned physical and
80
+ catalog target without schema DDL;
81
+ - top-level SPSS compiler imports and legacy openstatspec.transform re-exports
82
+ still load from an installed wheel;
83
+ - install-in-place-schema, apply-plan, and apply-spss execute their documented
84
+ CLI workflows;
85
+ - invalid or unsupported plans fail before the first data or metadata mutation;
86
+ - successful applies retain the same dataset ID, physical schema/table
87
+ identity, dataset count, and persistent physical data-table count;
88
+ - audit rows distinguish canonical plans from SPSS syntax, preserve correct
89
+ source/plan hashes and frontend contract, and contain no copied data;
90
+ - no OpenStatSpec rollback, snapshot, staging, copy, derived-dataset, or
91
+ parallel history artifacts are created; and
92
+ - Dolt checks expected branch, HEAD, and a clean working set; success changes
93
+ neither HEAD nor branch and never commits or resets; state is rechecked after
94
+ the dataset lock and success must leave an inspectable working-set diff;
95
+ other supported SQL connections remain allowed; and
96
+ - string comparisons and v0.2 string assignments fail closed until exact
97
+
98
+ The built wheel must contain the generic openstatspec.transform modules and the
99
+ implemented openstatspec.frontends.spss package. Stata and SAS remain empty
100
+ source-tree placeholders and must expose no compiler, apply API, CLI choice,
101
+ capability claim, or implied support.
102
+
59
103
  ## Maintainer checks before tagging
60
104
 
61
105
  1. Publish the pinned `openstatspec-pyspssio==0.5.1.post2` engine distribution
@@ -68,9 +112,12 @@ machine-readable loss report with the export result.
68
112
  4. Build with `python -m build` and install the generated wheel in a clean
69
113
  environment.
70
114
  5. Confirm `openstatspec capabilities` reflects the intended support boundary.
71
- 6. Confirm the release tag matches the package version and that CI, release
72
- fixtures, and capabilities use OpenStatSpec specification release `v0.2.0`
73
- at exact commit `79339ec3d8f8aa81789b7e85f6b8afa6f1374e50`.
115
+ 6. Confirm CI, release fixtures, and capabilities use the untagged OpenStatSpec
116
+ specification release candidate at exact commit
117
+ `f2fdf687d8cb32b944ca55a3e9e7215ffc603019`, publish
118
+ `specification_status=release_candidate`, and leave
119
+ `specification_release` null. If that exact commit receives a stable tag
120
+ before this package is tagged, update the identity and re-run every gate.
74
121
  7. Review this document, the README, and CHANGELOG for accurate scope.
75
122
 
76
123
  The tag-triggered release workflow repeats the non-service test suite, builds