Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,24 @@ jobs:
test -z "$(docker ps -aq --filter 'label=com.docker.compose.project')"
test -z "$(docker volume ls -q --filter 'label=com.docker.compose.project')"

release-artifact:
name: Release artifact verification
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
# actions/checkout v7.0.1
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- uses: ./.github/actions/setup-php-composer
with:
php-version: "8.4"
- name: Verify the exact committed artifact
env:
ARTIFACT_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
run: composer release:verify -- --target=1.0.0-rc.1 --sha="$ARTIFACT_SHA"

exploratory:
name: Exploratory MySQL Innovation (not required)
if: github.event_name == 'workflow_dispatch' && inputs.exploratory
Expand All @@ -246,7 +264,7 @@ jobs:
ci-gate:
name: CI gate
if: always()
needs: [workflow-lint, static, compat, integration, examples-smoke, consumer-verification]
needs: [workflow-lint, static, compat, integration, examples-smoke, consumer-verification, release-artifact]
runs-on: ubuntu-24.04
timeout-minutes: 5
steps:
Expand Down
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

All notable changes to this project are documented in this file.

The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versioning will follow [Semantic Versioning](https://semver.org/) once a version is published. **Nothing in this file has been published, tagged, or released.** See [README.md](README.md) and [SECURITY.md](SECURITY.md) for the current Development/Unpublished status.
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and [Semantic Versioning](https://semver.org/).

## [Unreleased]
## [1.0.0-rc.1]

First release candidate target. Publication state recorded during preparation: **Unpublished**.

### Added

Expand All @@ -13,6 +15,8 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Ver
- Pagination capability: `PdoPaginator`, returning a validated `PageResultDTO`, with whitelist-sorted, bounded, parameterized pagination and a documented non-single-snapshot caveat for its count queries.
- Ordering capability: `ScopedOrderingManager` and `ScopedOrderingConfig`, with global/scoped/nullable-scoped integer ordering, a plain next-position read, a locking next-position read, and a locked, clamped, savepoint-protected move.
- `PHP_PERSISTENCE_PACKAGE_REFERENCE.md` as the canonical Public Runtime API, behavior, and exception reference; `docs/guides/USAGE_GUIDE.md`; runnable, Public-API-only `examples/`; and `llms.txt`.
- External Composer consumer verification and legacy coexistence checks on real MySQL, including snapshot, savepoint, and deadlock replay evidence.
- Release Artifact Verification for the exact Git and Composer archives of this target.
- Composer manifest, PHPStan at level `max`, PER-CS 3.1 code-style verification, and a real MySQL/MariaDB Integration test infrastructure (`scripts/integration.php`, `compose.integration.yaml`, `docker/integration-matrix.json`).

No database version range is declared as supported; see [PHP_PERSISTENCE_PACKAGE_REFERENCE.md §8](PHP_PERSISTENCE_PACKAGE_REFERENCE.md#8-database-engine-support). Durable decisions governing the changes above are indexed in [docs/decisions/DECISIONS_INDEX.md](docs/decisions/DECISIONS_INDEX.md).
3 changes: 2 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ composer test:regression # no Docker needed
composer test:integration # needs Docker; starts a disposable MySQL/MariaDB service
composer examples:smoke # needs Docker; smoke-executes examples/ against a real engine
composer test:consumer # needs Docker; two fresh external Composer verification runs
composer release:verify -- --target=1.0.0-rc.1 --sha="$(git rev-parse HEAD)"
actionlint .github/workflows/*.yml
```

Expand All @@ -57,7 +58,7 @@ This package does not commit `composer.lock`. CI resolves both `latest` and `low

- Keep a pull request to one coherent change; include its own tests and any directly affected documentation in the same change rather than splitting them across separate pull requests.
- Describe the change, its rationale, and which local commands above you ran.
- All applicable CI gates (workflow lint, static checks, compatibility matrix, Integration, example smoke, and consumer verification) must pass before a merge is considered; CI gating and Git/merge permissions follow [AGENTS.md](AGENTS.md) and the pinned `AI_COLLABORATION_WORKFLOW_AR.md`/`GITHUB_PHASE_STACK_WORKFLOW_AR.md` — in particular, merges require explicit Owner authorization.
- All applicable CI gates (workflow lint, static checks, compatibility matrix, Integration, example smoke, consumer verification, and release artifact verification) must pass before a merge is considered; CI gating and Git/merge permissions follow [AGENTS.md](AGENTS.md) and the pinned `AI_COLLABORATION_WORKFLOW_AR.md`/`GITHUB_PHASE_STACK_WORKFLOW_AR.md` — in particular, merges require explicit Owner authorization.

## Reporting a security issue

Expand Down
6 changes: 3 additions & 3 deletions PHP_PERSISTENCE_PACKAGE_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

`maatify/php-persistence` — canonical stable public/runtime/behavioral contract.

Status: **Development / Unpublished.** Nothing described here is published, installable from Packagist, or tagged. This document is the single canonical Package Reference required by the pinned [Package Building Standard](docs/php-engineering-standards/standards/packages/PACKAGE_BUILDING_STANDARD.md) §3. It owns the stable public Runtime API inventory, behavior and exception guarantees, and package boundaries. It supersedes [docs/architecture/CONTRACT_MATRIX.md](docs/architecture/CONTRACT_MATRIX.md) and [docs/architecture/BEHAVIOR_CONTRACT.md](docs/architecture/BEHAVIOR_CONTRACT.md) as the *current* public-contract surface; those documents remain as dated design/evidence records (legacy mapping and the test evidence recorded per behavior) and are not a second competing contract.
Artifact target: **Release Candidate `1.0.0-rc.1`**. Publication state recorded during preparation: **Unpublished**. This document is the single canonical Package Reference required by the pinned [Package Building Standard](docs/php-engineering-standards/standards/packages/PACKAGE_BUILDING_STANDARD.md) §3. It owns the stable public Runtime API inventory, behavior and exception guarantees, and package boundaries. It supersedes [docs/architecture/CONTRACT_MATRIX.md](docs/architecture/CONTRACT_MATRIX.md) and [docs/architecture/BEHAVIOR_CONTRACT.md](docs/architecture/BEHAVIOR_CONTRACT.md) as the *current* public-contract surface; those documents remain as dated design/evidence records (legacy mapping and the test evidence recorded per behavior) and are not a second competing contract.

Composer package identity, PHP/extension requirements, dependencies, autoloading, configuration and distribution are owned exclusively by [`composer.json`](composer.json) under the pinned [Composer Package Standard](docs/php-engineering-standards/standards/packages/COMPOSER_PACKAGE_STANDARD.md). This document explains runtime implications of that manifest; it does not restate or override it.

Expand Down Expand Up @@ -43,9 +43,9 @@ This package is a separate Composer package from the published `maatify/persiste
- Published legacy `v1.4.0` and the unpublished legacy `main` used as source provenance are distinct baselines ([DEC-007](docs/decisions/DEC-007-legacy-source-baseline-and-deprecated-retirement.md)). This package has its own namespace and public API.
- Consumer migration from `maatify/persistence` to this package is explicitly **not** addressed by this document and needs its own separate authorization ([DEC-006](docs/decisions/DEC-006-successor-intent-and-standards-ownership-boundary.md)).

### 1.4 Development / Unpublished state
### 1.4 Release Candidate target

No version of this package is published, resolvable, or installable through Packagist or any other Composer distribution channel, and no Git tag exists. `composer.json` governs the declared package identity, PHP/extension requirements (`php ^8.4`, `ext-pdo`, `ext-pdo_mysql`), and dependency (`maatify/exceptions ^1.0`); see that file for the authoritative, current declaration.
The [README](README.md#installation) records the exact installation target and the condition for external Composer resolution. `composer.json` governs the declared package identity, PHP/extension requirements (`php ^8.4`, `ext-pdo`, `ext-pdo_mysql`), and dependency (`maatify/exceptions ^1.0`); see that file for the authoritative, current declaration.

---

Expand Down
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

![Maatify.dev](https://www.maatify.dev/assets/img/img/maatify_logo_white.svg)

[![Status](https://img.shields.io/badge/Status-Development-blue)](README.md)
[![Status at preparation](https://img.shields.io/badge/Status%20at%20preparation-Development-blue)](README.md#overview)
[![PHP](https://img.shields.io/badge/PHP-%5E8.4-8892BF)](composer.json)
[![License](https://img.shields.io/badge/License-Proprietary-green)](LICENSE)
[![PHPStan](https://img.shields.io/badge/PHPStan-Level%20Max-brightgreen)](phpstan.neon)
[![PHPStan](https://img.shields.io/badge/PHPStan-Level%20Max-brightgreen)](README.md#quality-status)

[![Maatify Ecosystem](https://img.shields.io/badge/Maatify-Ecosystem-blueviolet)](https://github.com/Maatify)

Expand All @@ -28,7 +28,7 @@ Direct-PDO Transaction, Pagination, and Ordering utilities for MySQL and MariaDB

`maatify/php-persistence` is a small, direct-PDO toolkit with three independent capabilities over a **caller-supplied** `PDO` connection: running callbacks inside a transaction or a caller's savepoint (with optional bounded deadlock replay), parameterized whitelist-sorted bounded pagination, and locking next-position/move operations for integer display-order columns. It is developed as a separate package from the earlier, published `maatify/persistence` ([coexistence rules](docs/decisions/DEC-005-coexistence-with-legacy-package.md)), not a drop-in replacement.

This repository is in **Development**. Nothing described here is published, tagged, or installable through Packagist or any other Composer distribution channel.
This tree prepares the **Release Candidate artifact `1.0.0-rc.1`**. The live project is in **Development** while the target is unpublished. The publication state recorded for this preparation is **Unpublished**.

## Key Features

Expand All @@ -49,7 +49,13 @@ These are declared runtime requirements, not a statement that any specific datab

## Installation

This package is **not published**. It has no Packagist listing, no Git tag, and no installable version; `composer require maatify/php-persistence` does not resolve anything today. The intended Composer identity is `maatify/php-persistence` once a release exists; see [CHANGELOG.md](CHANGELOG.md) for the current `[Unreleased]` state.
The exact Composer installation target for this artifact is:

```bash
composer require maatify/php-persistence:1.0.0-rc.1
```

This command resolves through the approved Composer distribution source only after that exact version is published. See the [target changelog](CHANGELOG.md#100-rc1) and [security policy](SECURITY.md) for lifecycle and support details.

## Usage

Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

## Supported Versions

This package is in **Development** and has never published a Stable release or a SemVer Release Candidate. There is currently no supported Stable release line.
This artifact represents Release Candidate `1.0.0-rc.1`. At preparation, the target was **Unpublished** and the package had no supported Stable release line. This release candidate establishes no Stable support commitment.

## Reporting a Vulnerability

Expand Down
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "maatify/php-persistence",
"description": "PDO persistence utilities for MySQL and MariaDB, in development.",
"description": "Direct-PDO transaction, pagination, and ordering utilities for MySQL and MariaDB.",
"keywords": [
"persistence",
"pdo",
Expand Down Expand Up @@ -62,7 +62,8 @@
"test:regression": "phpunit --testsuite regression",
"test:integration": "@php scripts/integration.php",
"examples:smoke": "@php scripts/examples-smoke.php",
"test:consumer": "@php scripts/consumer-verification.php"
"test:consumer": "@php scripts/consumer-verification.php",
"release:verify": "@php scripts/release-artifact.php"
},
"config": {
"optimize-autoloader": true,
Expand Down
4 changes: 3 additions & 1 deletion docs/architecture/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

`maatify/php-persistence` — direct-PDO transaction, pagination and ordering utilities, designed for MySQL and MariaDB.

Status: **Development**. This document describes the intended architecture decided in WU-3. Since WU-4 the repository contains a Composer manifest and quality tooling; its CI (WU-5) runs the quality gates and real-database infrastructure tests. WU-6 implemented the Transaction capability (`PdoTransactionRunner`, `PdoSavepointTransactionRunner`, their exceptions, and the `@internal` executor and savepoint helper). WU-7 implemented the Pagination capability (`PdoPaginator`, `PageRequest`, `PaginationConfig`, `PdoPaginationQueryDescriptor`, `PageResultDTO`, `SortWhitelist`, `SortDirectionEnum`, and their exceptions). WU-8 implemented the Ordering capability (`ScopedOrderingConfig`, `ScopedOrderingManager`, and their exceptions), reusing the Transaction capability's Gen2 `PdoTransactionRunner` and `@internal` `SavepointScope` rather than a second savepoint helper, per [DEC-011](../decisions/DEC-011-responsibility-placement-and-savepoint-helper.md). WU-9 delivered the canonical [Package Reference](../../PHP_PERSISTENCE_PACKAGE_REFERENCE.md), the consumer-facing README, a Usage Guide, runnable examples, `llms.txt`, and the remaining release-facing files, verified against the current source and tests rather than against this design record. Nothing here is released or installable. Statements about database engine support are design targets, not claims ([DATABASE_SUPPORT_AND_TEST_POLICY.md](./DATABASE_SUPPORT_AND_TEST_POLICY.md)): the Transaction capability's own tests, including real deadlocks, the Pagination capability's own tests, including a deterministic concurrent-writer snapshot test (B-08a), and the Ordering capability's own tests, including real stale-snapshot, lock-wait and deadlock cases, pass on named MySQL and MariaDB versions, which is evidence for those versions, not a declared supported range.
This document records the architecture decided in WU-3. WU-4 and WU-5 established Composer packaging, quality tooling, and real-database CI. WU-6 through WU-8 implemented Transaction, Pagination, and Ordering. Ordering reuses the Transaction capability's Gen2 runner and its `@internal` savepoint helper under [DEC-011](../decisions/DEC-011-responsibility-placement-and-savepoint-helper.md). WU-9 delivered the canonical [Package Reference](../../PHP_PERSISTENCE_PACKAGE_REFERENCE.md), usage guidance, and runnable examples.

WU-10 added [consumer verification and coexistence](../guides/CONSUMER_VERIFICATION.md). WU-11 prepares the `1.0.0-rc.1` artifact and its [archive verification](../guides/RELEASE_ARTIFACT_VERIFICATION.md). See the [README](../../README.md#installation) for installation and the publication state recorded for this artifact. The [database policy](DATABASE_SUPPORT_AND_TEST_POLICY.md) records test evidence for named MySQL and MariaDB versions, including deadlocks, pagination snapshots, and ordering concurrency. That evidence is limited to the tested versions.

## 1. Document map

Expand Down
3 changes: 2 additions & 1 deletion docs/architecture/CI_AND_INTEGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ Every CI gate runs a repository-owned command that a developer can run locally w
| Integration suite (real database) | `composer test:integration` | Integration |
| Standalone examples (real database) | `composer examples:smoke` | Examples smoke |
| Consumer verification and coexistence | `composer test:consumer` | Consumer verification and coexistence |
| Exact-target release archives | [`composer release:verify`](../guides/RELEASE_ARTIFACT_VERIFICATION.md) | Release artifact verification |
| Workflow lint | `actionlint` over `.github/workflows` | Workflow lint |

Unit and Regression need no Docker. `composer test` runs Unit, Regression, and Integration locally. The required `CI gate` aggregates Workflow lint, Static checks, Compat, Integration, Examples smoke, and Consumer verification and coexistence. The exploratory cell is optional.
Unit and Regression need no Docker. `composer test` runs Unit, Regression, and Integration locally. The required `CI gate` aggregates Workflow lint, Static checks, Compat, Integration, Examples smoke, Consumer verification and coexistence, and Release artifact verification. The exploratory cell is optional.

## 2. Integration lifecycle

Expand Down
2 changes: 1 addition & 1 deletion docs/guides/CONSUMER_VERIFICATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ The [behavior contract](../architecture/BEHAVIOR_CONTRACT.md) labels published l

The orchestrator is checked by the package's PHPStan configuration. The independent consumer fixture is syntax-checked and validated through execution in the two production Composer roots, where its legacy imports resolve.

The harness is additional to Unit, Regression, Integration and Examples Smoke. This evidence concerns an unpublished candidate, with no production host migration or support-range claim. DEC-009 remains deferred, and DEC-013 records test versions.
The harness is additional to Unit, Regression, Integration and Examples Smoke. This evidence concerns a candidate tree before publication. It provides neither production host migration evidence nor a support-range claim. DEC-009 remains deferred, and DEC-013 records test versions.
15 changes: 15 additions & 0 deletions docs/guides/RELEASE_ARTIFACT_VERIFICATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Release Artifact Verification

The preparation target for this tree is `maatify/php-persistence:1.0.0-rc.1`. Its publication state during preparation is Unpublished.

Run the same archive checks as CI from a checkout containing the exact committed candidate. The command needs Git, tar, PHP and Composer.

```sh
composer release:verify -- --target=1.0.0-rc.1 --sha="$(git rev-parse HEAD)"
```

The verifier creates an isolated checkout of the selected commit. It generates a VCS archive with `git archive` and a Composer archive with `composer archive`, independently of each other. The verification checks the actual entries and bytes, including required consumer files, the full runtime source, manifest identity and production PSR-4 mapping, and repository-only or sensitive paths. The log records the target, commit, tree, and a file inventory and SHA-256 for each generated archive. The temporary workspace is removed when verification ends. The sensitive-path and private-key checks are structural. The Lead reviews release claims, changelog allocation and the contents for sensitive data in context.

In pull-request CI the archive job checks out and verifies the exact PR HEAD. On a push it verifies the exact pushed commit. Qualification requires Full Applicable CI and Release Artifact Verification on the same actual, Owner-authorized `main` commit and exact target. The [Consumer Verification Harness](CONSUMER_VERIFICATION.md) separately exercises runtime consumption.

After separately authorized publication, the approved Composer channel provides the version and distribution evidence for Published Artifact Verification. Its archive and install mode must be observed there. This preparation step makes no assumption about a source-only distribution mode.
2 changes: 1 addition & 1 deletion docs/guides/USAGE_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Consumer-facing integration guidance for `maatify/php-persistence`. This guide explains how to use the three capabilities; it does not define a technical contract of its own — every normative rule here is a presentation of what [PHP_PERSISTENCE_PACKAGE_REFERENCE.md](../../PHP_PERSISTENCE_PACKAGE_REFERENCE.md) already defines. Where the two disagree, the Package Reference governs.

**Status:** this package is unpublished (Development). Nothing in this guide implies a published, installable version.
**Artifact target:** Release Candidate `1.0.0-rc.1`. See the [README](../../README.md#installation) for the exact installation target and when it resolves.

## Before you start

Expand Down
Loading