diff --git a/CHANGELOG.md b/CHANGELOG.md index ab1c4d3..26fbdcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ # Changelog -## Unreleased +## [Unreleased] + +## [0.8.0] - 2026-09-10 + +This release consolidates the never-tagged, never-published 0.7.2 preparation +with official opt-in SPSS Frontend 0.3 support. The previous public release is +0.7.1; there was no 0.7.2 release. ### Added @@ -10,12 +16,15 @@ aliases, finite open RECODE ranges, and ordered typed ADD VALUE LABELS. - Check all 90 effective official cases against the unchanged specification pin, inherited Plan 0.1/0.2 objects and hashes, and native SQLite in-place provenance - and identity. Service CI is pending; no new network runtime claim is made. -- Document the parent precedence decision: comparisons, NOT, AND, OR; - parentheses override. No STRING/DELETE or schema extension, version, codec, - dependency, publication or prepared 0.7.2 scope change. - -## [0.7.2] - Unreleased + and identity. All 20 implementation CI jobs passed at + `22e261842e538188aea281896c578c5f3d1e38b7`, including the service matrix + ([run](https://github.com/OpenStatSpec/php/actions/runs/34483918942)). Declare + Frontend 0.3 officially conformant while retaining its opt-in capability field. + The final 0.8.0 release commit still requires full CI before tagging. +- Use precedence comparisons, NOT, AND, OR; parentheses override. Compilation + is pure over request metadata: callers supply the current ordered dictionary + and typed value labels; the compiler does not read the database. No + STRING/DELETE, schema extension, Plan 0.3 or In-Place 0.3 support is added. ### Fixed @@ -39,7 +48,7 @@ Existing import/export call forms, dependencies, specification pin, database support claims and catalog schema remain unchanged. Catalog preparation and -ownership checks are retained; this patch requires no new migration. +ownership checks are retained; this release requires no new migration. ## [0.7.1] - 2026-09-07 @@ -170,7 +179,8 @@ ownership checks are retained; this patch requires no new migration. - Pinned active conformance fixtures and capabilities to released OpenStatSpec specification v0.1.0 at commit `d287c2cde9ade71f04e27dd012caec876901aed5`. -[0.7.2]: https://github.com/OpenStatSpec/php/compare/v0.7.1...HEAD +[Unreleased]: https://github.com/OpenStatSpec/php/compare/v0.8.0...HEAD +[0.8.0]: https://github.com/OpenStatSpec/php/compare/v0.7.1...v0.8.0 [0.7.1]: https://github.com/OpenStatSpec/php/compare/v0.7.0...v0.7.1 [0.7.0]: https://github.com/OpenStatSpec/php/compare/v0.6.0...v0.7.0 [0.6.0]: https://github.com/OpenStatSpec/php/compare/v0.5.0...v0.6.0 diff --git a/README.md b/README.md index 6892399..c21ca68 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ It imports an unencrypted SPSS `.sav` or `.zsav` dataset into a relational datab ## Status -PHP v0.7.2 targets released OpenStatSpec specification `v0.5.0` at immutable +PHP v0.8.0 targets released OpenStatSpec specification `v0.5.0` at immutable commit `864e84479f554b8ee250ffed44c4dfb963750d4a` (`specification_status: released`). Composer derives the package version from its Git tag; it is independent of the specification version. @@ -139,13 +139,18 @@ Pass only loss codes consciously accepted for that conversion. `operation_catalo ## Transformation API The adapter claims official Transformation Plan 0.1/0.2, SPSS Syntax Frontend -0.2, and In-Place Transformation 0.1/0.2 conformance. Compile an alias-based +0.2/0.3, and In-Place Transformation 0.1/0.2 conformance. Compile an alias-based frontend request, then bind that alias to the existing dataset at apply time. -Unreleased opt-in SPSS Syntax Frontend 0.3 is implemented: explicitly set the +PHP v0.8.0 includes official opt-in SPSS Syntax Frontend 0.3: explicitly set the request `contract` to `openstatspec-spss-syntax-frontend-v0.3` (or use `SpssFrontendRequest::CONTRACT_V03`). It emits only Plan 0.1/0.2; default 0.2 -syntax and APIs remain unchanged. All 90 effective fixtures and native SQLite -apply are tested locally; service CI is pending, not a new runtime claim. +syntax and APIs remain unchanged. Compilation is pure over request metadata; +callers supply the current ordered dictionary and typed value labels, without +compiler database reads. All 90 effective official fixtures and native SQLite +apply are tested locally; all 20 implementation CI jobs passed at +`22e261842e538188aea281896c578c5f3d1e38b7`, including the service matrix +([evidence and final release gates](docs/release-readiness.md#frontend-03-implementation-ci-evidence)). +The final 0.8.0 release commit still requires its own full CI before tagging. Transformation Plan and In-Place Transformation 0.3 remain unimplemented. ```php diff --git a/docs/architecture.md b/docs/architecture.md index fecafd9..84df4a7 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -92,7 +92,10 @@ Encrypted files, Portable (`.por`) files and arbitrary external-engine formats a strict codec, validation, and deterministic plan identity. `src/Frontend/Spss` is the separate SPSS Frontend 0.2 boundary, with opt-in Frontend 0.3 using the same strict request validator, parser, binder and compiler. -Frontend 0.3 emits only Plan 0.1/0.2; its service CI claim is pending. +Frontend 0.3 emits only Plan 0.1/0.2 and is declared officially conformant based +on the passed [implementation CI matrix](release-readiness.md#frontend-03-implementation-ci-evidence). +Frontend 0.2 remains the default; full CI on the final 0.8.0 release commit is +still required before tagging. `src/Transformation/Execution` binds an alias-based plan to one existing dataset and applies it through the active PDO profile; it never invokes the frontend. The Stata and SAS directories are placeholders only. diff --git a/docs/release-readiness.md b/docs/release-readiness.md index cf9cc62..681ad4a 100644 --- a/docs/release-readiness.md +++ b/docs/release-readiness.md @@ -1,20 +1,23 @@ # PHP adapter release readiness -This page records the release contract for PHP adapter v0.7.2. It does not mean +This page records the release contract for PHP adapter v0.8.0 (2026-09-10). It does not mean that a package tag or Packagist publication has happened. Composer derives the package version from the Git tag; `composer.json` has no `version` key. -## Patch scope +## Release scope -Version 0.7.2 includes the merged import precision/error/transaction fixes, -bounded server INSERT batching and grouped export metadata reads described in +Version 0.8.0 consolidates the never-tagged, never-published 0.7.2 preparation +with official opt-in SPSS Frontend 0.3 support. The last public release is 0.7.1; +there was no 0.7.2 release. It includes the merged import precision/error/transaction +fixes, bounded server INSERT batching and grouped export metadata reads described in [the release notes](../CHANGELOG.md). Dependencies, specification pin, SQL support and catalog schema are unchanged. Export still requires a ready, owned catalog; initialize or upgrade it with `SpssAdapter::migrateCatalog()` on a write-capable -deployment connection before export when needed. This patch adds no migration -or setup for an already prepared current catalog. -Run the gates below on the exact selected patch release commit, not an earlier -0.7.1 commit. +deployment connection before export when needed. This release adds no migration +or setup for an already prepared current catalog. The locked SPSS engine remains +`openstatspec/spss-sav` 3.1.1; `composer.json` and `composer.lock` are unchanged. +Run the gates below on the exact selected 0.8.0 release commit, not an earlier +preparation commit. ## Specification pin and claims @@ -23,7 +26,7 @@ released OpenStatSpec specification `v0.5.0` at exact commit `864e84479f554b8ee250ffed44c4dfb963750d4a`, with `specification_status: released`. -Release v0.7.2 selects `database_io_policy: openstatspec-database-io-v1`. +Release v0.8.0 selects `database_io_policy: openstatspec-database-io-v1`. SAV/ZSAV export is database-read-only, including failures, and no longer returns `SpssExportResult::operationId` or writes operation/fidelity audit records. Initialize or upgrade the catalogue with `SpssAdapter::migrateCatalog()` using a @@ -36,33 +39,64 @@ Default Dolt writes support exactly 2.2.2 and 2.2.3 without external declaration files. Unknown patches, including 2.2.4, fail before mutation. Read-only export still verifies server identity but does not require a write-version claim. -Transformation claims remain Transformation Plan 0.1/0.2, SPSS Syntax Frontend -0.2, and In-Place Transformation 0.1/0.2 for the prepared patch. -Separate Unreleased work implements opt-in SPSS Syntax Frontend 0.3 against -this unchanged pin: 90 effective fixtures and native SQLite apply are locally -covered; exact-commit service CI remains pending. Transformation Plan 0.3 and +Transformation claims are Transformation Plan 0.1/0.2, SPSS Syntax Frontend +0.2/0.3, and In-Place Transformation 0.1/0.2. Version 0.8.0 includes official +opt-in SPSS Syntax Frontend 0.3 against this unchanged pin: exactly 90 effective +fixtures and native SQLite apply are locally covered, and implementation service +CI passed as recorded below. Frontend 0.3 is in `official_frontend_contracts`; +the retained `opt_in_frontend_contracts` field reports `official_conformant`. +Frontend 0.2 remains the default; Frontend 0.3 +emits only Plan 0.1/0.2. Compilation is pure over request metadata: callers supply +the current ordered dictionary and typed value labels, without compiler database +reads. Transformation Plan 0.3 and In-Place Transformation 0.3 remain unimplemented. Existing target pre-provisioning and caller-owned Dolt commit rules remain unchanged; see the [transformation migration notes](transformations.md#v060-migration). -## 0.7.2 local preparation verification +## Frontend 0.3 implementation CI evidence + +[GitHub Actions run 34483918942](https://github.com/OpenStatSpec/php/actions/runs/34483918942) +completed successfully at exact implementation commit +`22e261842e538188aea281896c578c5f3d1e38b7`. All 20 jobs passed: two PHP +8.4/8.5 suite jobs and 18 service jobs covering PostgreSQL 17.10/18.4, +MySQL 8.4.11/9.7.2, MariaDB 11.4.12/11.8.8/12.3.2 and Dolt 2.2.2/2.2.3 +on both PHP versions. This establishes implementation conformance and service +support; it does not expand the existing database version policies. + +This is not CI evidence for the final 0.8.0 release commit. That exact commit +still requires the full matrix before tagging; no tag-context CI or publication +is claimed here. + +## 0.8.0 local preparation verification On PHP 8.5.9, PHPUnit 11.5.56 and the exact v0.5.0 specification checkout, without configured database services: -- `composer check` passed strict validation, lint, style, PHPStan and PHPUnit: - **615 tests, 10,468 assertions, 112 skipped**. +- Fresh `composer install --no-interaction --prefer-dist` installed from the + unchanged lock. `OPENSTATSPEC_SPECIFICATION_DIR=/tmp/openstatspec-alignment-spec + composer check` passed strict validation, lint, style, PHPStan and PHPUnit: + **759 tests, 11,032 assertions, 112 skipped**. Initial style checks rejected + CRLF checkout files from global `core.autocrlf=true`; `composer fix` restored + LF with no tracked source diff, matching the staged hook's LF normalization. +- The exact Frontend 0.3 gate passed **91 tests / 456 assertions** (90 cases plus + manifest inventory); default/request-boundary checks passed **52 / 80**, and + native SQLite Frontend 0.3 apply passed **1 / 27**, all with `--fail-on-skipped`. + Plan and Frontend conformance suites passed **44 / 69** and **135 / 663**. + In-Place 0.1 passed **9 / 48, 6 skipped**; 0.2 passed **14 / 97, 11 skipped**. + Service skips are not network-service evidence. - `composer install --dry-run --no-dev` and a disposable ZIP archive inspection passed. Required source, lockfile and release notes were present; `.git` and `vendor` were absent. - A clean extraction installed production dependencies from the unchanged lock (including codec 3.1.1), and the adapter/batch classes autoloaded successfully. + The production-only install compiled explicit Frontend 0.3 and default 0.2 + requests to the same inherited plan without a database connection. This checks the archive, not future Packagist version resolution. This is local candidate evidence, not final release-commit service CI or -publication evidence. No v0.7.2 tag or registry publication was made. +publication evidence. No tag or registry publication was made by this preparation. -## Before tagging v0.7.2 +## Before tagging v0.8.0 1. Verify `git rev-parse HEAD` in the specification checkout equals `864e84479f554b8ee250ffed44c4dfb963750d4a`, and the published `v0.5.0` tag @@ -78,6 +112,16 @@ publication evidence. No v0.7.2 tag or registry publication was made. ``` Confirm all 4 Plan 0.1, 26 Plan 0.2, 44 Frontend 0.2, 6 In-Place 0.1, and 11 In-Place 0.2 manifest cases run for their configured profiles. + Require exactly 90 effective official Frontend 0.3 cases (35 declared plus + inherited cases minus two comment supersessions), including exact inherited + Plan 0.1/0.2 objects and hashes, diagnostics and metadata preservation: + ```bash + vendor/bin/phpunit tests/Frontend/Spss/Conformance/SpssFrontend02Test.php --filter 'testOfficialFrontend03Case|testOfficial03ManifestCoverage' --fail-on-skipped + vendor/bin/phpunit tests/Frontend/Spss/SpssFrontend03Test.php --fail-on-skipped + vendor/bin/phpunit tests/Integration/OfficialInPlaceTransformation01Test.php --filter testOptInFrontend03 --fail-on-skipped + ``` + Retain the default 0.2 and pure request-metadata boundary checks and the + native SQLite provenance/identity regression. 3. Confirm successful applies preserve dataset/table identity and counts and create no copied, output, staging, snapshot, rollback, or version state. 4. Confirm SQLite/PostgreSQL atomic numeric-target creation and preflight @@ -91,24 +135,25 @@ publication evidence. No v0.7.2 tag or registry publication was made. `OPENSTATSPEC_DOLT_READ_ONLY_ADMIN_PASSWORD=root`. It creates and removes only its own isolated database/user and proves SELECT-only SAV/ZSAV export, failure safety, and unchanged working/staged roots and history. -6. Confirm GitHub Actions passes the full PHP 8.4/8.5 jobs plus every +6. On the exact final 0.8.0 release commit (not just the proven implementation + commit above), confirm GitHub Actions passes the full PHP 8.4/8.5 jobs plus every PostgreSQL, MySQL, MariaDB, and Dolt matrix entry. Each service filter must include both official in-place test classes; the Dolt filter must also include `DoltReadOnlyExportTest`. -7. Confirm README, changelog, and release notes agree on this patch's fixes, - unchanged specification pin, initialization requirement and Dolt defaults. - Finalize the 0.7.2 changelog date and comparison link before selecting the - final release commit. Run `composer install --dry-run --no-dev` and - `composer archive --format=zip --dir="$(mktemp -d /tmp/openstatspec-php-v072-package.XXXXXX)"`; +7. Confirm README, changelog, and release notes agree on the consolidated + 0.8.0 fixes and Frontend 0.3 scope, unchanged specification pin, + initialization requirement and Dolt defaults. Verify the 2026-09-10 date + and comparison from v0.7.1 to v0.8.0 before selecting the final release commit. Run `composer install --dry-run --no-dev` and + `composer archive --format=zip --dir="$(mktemp -d /tmp/openstatspec-php-v080-package.XXXXXX)"`; inspect the archive without publishing it. No separate build is required. 8. Confirm the selected commit's full CI matrix, protected-tag controls and Packagist update access. ## Publication (separate maintainer action) -1. Create and verify annotated tag `v0.7.2` on the reviewed `main` commit that +1. Create and verify annotated tag `v0.8.0` on the reviewed `main` commit that passed the gates above. Do not move an existing tag. 2. Wait for tag-context CI before publishing the GitHub release. 3. Confirm Packagist lists the new version and a clean - `composer require openstatspec/php:0.7.2` resolves it to the intended commit. + `composer require openstatspec/php:0.8.0` resolves it to the intended commit. Do not infer publication from this checklist. diff --git a/docs/transformations.md b/docs/transformations.md index 0d15db6..6824997 100644 --- a/docs/transformations.md +++ b/docs/transformations.md @@ -6,15 +6,16 @@ The PHP adapter conforms to these pinned OpenStatSpec contracts: - `openstatspec-transformation-plan-v0.1` and `openstatspec-transformation-plan-v0.2`; -- `openstatspec-spss-syntax-frontend-v0.2`; and +- `openstatspec-spss-syntax-frontend-v0.2` and opt-in + `openstatspec-spss-syntax-frontend-v0.3`; and - `openstatspec-in-place-transformation-v0.1` and `openstatspec-in-place-transformation-v0.2`. -Unreleased opt-in `openstatspec-spss-syntax-frontend-v0.3` is also implemented, -with local fixture/SQLite evidence and service CI pending. It is separately -listed as `implemented_service_ci_pending` in the capability declaration, not -added to its existing conformant contract lists. Plan 0.3 and In-Place 0.3 are -not implemented. +PHP v0.8.0 includes official opt-in `openstatspec-spss-syntax-frontend-v0.3`, +with local fixture/SQLite evidence and a passed implementation service CI matrix. +It is included in `official_frontend_contracts`; the retained +`opt_in_frontend_contracts` field reports `official_conformant` for 0.3. +Frontend 0.2 remains the default. Plan 0.3 and In-Place 0.3 are not implemented. Plans are source-neutral, alias-based, and deterministic. The canonical plan contains only its contract, input alias, and ordered operations. Dataset UUIDs, @@ -104,7 +105,8 @@ comment-only programs fail. Hashing retains original comments and normalizes only CRLF/CR to LF. ADD updates existing typed codes in place and appends new codes, including after preceding VALUE LABELS replacements. Its initial label state comes from the supplied input schema; callers must supply the current -dictionary when compiling. +ordered dictionary and typed value labels when compiling. Compilation is pure +over request metadata: the compiler does not query or mutate the database. **Parent decision:** use conventional SPSS precedence: comparisons, then NOT, then AND, then OR. Thus `NOT a = 1 AND b = 2 OR c = 3` means @@ -188,7 +190,9 @@ and declared metadata preservation. Use alignment checkout at unchanged commit `864e84479f554b8ee250ffed44c4dfb963750d4a`. The public Frontend 0.3 → native SQLite apply regression checks UNKNOWN, metadata, provenance and unchanged dataset/table identity without extra data -artifacts or history. This change has no local network-service evidence; its -service CI gate remains pending. SQLite runs locally. PostgreSQL, MySQL, -MariaDB, and Dolt cases run when their `OPENSTATSPEC_*` service configuration -is supplied; CI configures every service family. +artifacts or history. All 20 jobs in the +[implementation CI run](release-readiness.md#frontend-03-implementation-ci-evidence) +passed, including PostgreSQL, MySQL, MariaDB and Dolt service coverage. +Full CI on the final 0.8.0 release commit remains required before tagging. +SQLite runs locally; network-service cases run when their `OPENSTATSPEC_*` +configuration is supplied. Local skips are not additional service evidence. diff --git a/src/Core/CapabilityDeclaration.php b/src/Core/CapabilityDeclaration.php index 7860720..f0e8fd8 100644 --- a/src/Core/CapabilityDeclaration.php +++ b/src/Core/CapabilityDeclaration.php @@ -64,9 +64,10 @@ public function toArray(): array ], 'official_frontend_contracts' => [ 'openstatspec-spss-syntax-frontend-v0.2', + 'openstatspec-spss-syntax-frontend-v0.3', ], 'opt_in_frontend_contracts' => [ - 'openstatspec-spss-syntax-frontend-v0.3' => 'implemented_service_ci_pending', + 'openstatspec-spss-syntax-frontend-v0.3' => 'official_conformant', ], 'official_binding_contracts' => [ 'openstatspec-in-place-transformation-v0.1', diff --git a/tests/Core/CapabilityDeclarationTest.php b/tests/Core/CapabilityDeclarationTest.php index 0da3aae..20fb7b8 100644 --- a/tests/Core/CapabilityDeclarationTest.php +++ b/tests/Core/CapabilityDeclarationTest.php @@ -54,7 +54,7 @@ public function testDeclarationIsMachineReadableAndIncludesEveryProfileLimit(): $contracts['official_plan_contracts'], ); self::assertSame( - ['openstatspec-spss-syntax-frontend-v0.2'], + ['openstatspec-spss-syntax-frontend-v0.2', 'openstatspec-spss-syntax-frontend-v0.3'], $contracts['official_frontend_contracts'], ); self::assertSame( @@ -62,7 +62,7 @@ public function testDeclarationIsMachineReadableAndIncludesEveryProfileLimit(): $contracts['official_binding_contracts'], ); self::assertSame([ - 'openstatspec-spss-syntax-frontend-v0.3' => 'implemented_service_ci_pending', + 'openstatspec-spss-syntax-frontend-v0.3' => 'official_conformant', ], $contracts['opt_in_frontend_contracts']); self::assertArrayNotHasKey('legacy_plan_contracts', $contracts); self::assertFalse(class_exists(\OpenStatSpec\Transformation\Model\TransformationPlan::class));