From 2f6c3e413038a475d2f80791d2d29fc6a5e021c7 Mon Sep 17 00:00:00 2001 From: Renn F Date: Thu, 1 Oct 2026 22:29:34 +0200 Subject: [PATCH] release(1.3.0): floor guard-core-php ^4.3.0 and psr15-guard ^1.3.0, the safety-corpus train - the release gate and lock fixes plus the process scaffold and the 100% line coverage gate ride along --- .github/workflows/ci.yml | 12 +++++----- .github/workflows/release.yml | 8 +++---- .github/workflows/scheduled-lint.yml | 2 +- .github/workflows/static-analysis.yml | 4 ++-- .github/workflows/upstream-drift.yml | 4 ++-- CHANGELOG.md | 19 +++++++++++++++ composer.json | 4 ++-- composer.lock | 34 +++++++++++++++------------ 8 files changed, 55 insertions(+), 32 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7cc46bd..0c6452c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,7 +73,7 @@ jobs: engine = "../guard-core-php/composer.json" with open(engine) as f: d = json.load(f) - d["version"] = "4.2.99" + d["version"] = "4.3.99" with open(engine, "w") as f: json.dump(d, f, indent=4) f.write("\n") @@ -85,7 +85,7 @@ jobs: psr15 = "../psr15-guard/composer.json" with open(psr15) as f: d = json.load(f) - d["version"] = "1.2.99" + d["version"] = "1.3.99" with open(psr15, "w") as f: json.dump(d, f, indent=4) f.write("\n") @@ -165,7 +165,7 @@ jobs: engine = "../guard-core-php/composer.json" with open(engine) as f: d = json.load(f) - d["version"] = "4.2.99" + d["version"] = "4.3.99" with open(engine, "w") as f: json.dump(d, f, indent=4) f.write("\n") @@ -177,7 +177,7 @@ jobs: psr15 = "../psr15-guard/composer.json" with open(psr15) as f: d = json.load(f) - d["version"] = "1.2.99" + d["version"] = "1.3.99" with open(psr15, "w") as f: json.dump(d, f, indent=4) f.write("\n") @@ -251,7 +251,7 @@ jobs: engine = "../guard-core-php/composer.json" with open(engine) as f: d = json.load(f) - d["version"] = "4.2.99" + d["version"] = "4.3.99" with open(engine, "w") as f: json.dump(d, f, indent=4) f.write("\n") @@ -259,7 +259,7 @@ jobs: psr15 = "../psr15-guard/composer.json" with open(psr15) as f: d = json.load(f) - d["version"] = "1.2.99" + d["version"] = "1.3.99" with open(psr15, "w") as f: json.dump(d, f, indent=4) f.write("\n") diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 43d5020..d342c5f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -63,7 +63,7 @@ jobs: engine = "../guard-core-php/composer.json" with open(engine) as f: d = json.load(f) - d["version"] = "4.2.99" + d["version"] = "4.3.99" with open(engine, "w") as f: json.dump(d, f, indent=4) f.write("\n") @@ -71,7 +71,7 @@ jobs: psr15 = "../psr15-guard/composer.json" with open(psr15) as f: d = json.load(f) - d["version"] = "1.2.99" + d["version"] = "1.3.99" with open(psr15, "w") as f: json.dump(d, f, indent=4) f.write("\n") @@ -151,7 +151,7 @@ jobs: engine = "../guard-core-php/composer.json" with open(engine) as f: d = json.load(f) - d["version"] = "4.2.99" + d["version"] = "4.3.99" with open(engine, "w") as f: json.dump(d, f, indent=4) f.write("\n") @@ -159,7 +159,7 @@ jobs: psr15 = "../psr15-guard/composer.json" with open(psr15) as f: d = json.load(f) - d["version"] = "1.2.99" + d["version"] = "1.3.99" with open(psr15, "w") as f: json.dump(d, f, indent=4) f.write("\n") diff --git a/.github/workflows/scheduled-lint.yml b/.github/workflows/scheduled-lint.yml index cd8d74b..a7b65a2 100644 --- a/.github/workflows/scheduled-lint.yml +++ b/.github/workflows/scheduled-lint.yml @@ -38,7 +38,7 @@ jobs: engine = "../guard-core-php/composer.json" with open(engine) as f: d = json.load(f) - d["version"] = "4.2.99" + d["version"] = "4.3.99" with open(engine, "w") as f: json.dump(d, f, indent=4) f.write("\n") diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 943d551..ed88641 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -64,7 +64,7 @@ jobs: engine = "../guard-core-php/composer.json" with open(engine) as f: d = json.load(f) - d["version"] = "4.2.99" + d["version"] = "4.3.99" with open(engine, "w") as f: json.dump(d, f, indent=4) f.write("\n") @@ -72,7 +72,7 @@ jobs: psr15 = "../psr15-guard/composer.json" with open(psr15) as f: d = json.load(f) - d["version"] = "1.2.99" + d["version"] = "1.3.99" with open(psr15, "w") as f: json.dump(d, f, indent=4) f.write("\n") diff --git a/.github/workflows/upstream-drift.yml b/.github/workflows/upstream-drift.yml index 44aa782..b4dae19 100644 --- a/.github/workflows/upstream-drift.yml +++ b/.github/workflows/upstream-drift.yml @@ -51,7 +51,7 @@ jobs: engine = "core-upstream/composer.json" with open(engine) as f: d = json.load(f) - d["version"] = "4.2.99" + d["version"] = "4.3.99" with open(engine, "w") as f: json.dump(d, f, indent=4) f.write("\n") @@ -84,7 +84,7 @@ jobs: -e REDIS_HOST=127.0.0.1 \ composer:2 sh -c ' set -e - composer require --no-update --no-interaction "rennf93/guard-core-php:4.2.99" + composer require --no-update --no-interaction "rennf93/guard-core-php:4.3.99" composer update --no-interaction --no-progress "rennf93/guard-core-php" composer lint php bin/test_slim.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 26918f5..2a3f16f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,25 @@ Release Notes ___ +v1.3.0 (2026-10-01) +------------------- + +### Changed + +- **Both floors rise: `rennf93/guard-core-php` ^4.3.0 and `rennf93/psr15-guard` ^1.3.0.** 1.3.0 tracks the safety-corpus train: the engine ships the spec 12 event bus with dynamic rules and Redis-backed metrics persistence, the spec 10 geo download and refresh lifecycle, the spec 04 ReDoS safety gates over PCRE plus the performance monitor, and the pattern_safety / events / redis_interop conformance runners, while the composed psr15-guard 1.3.0 floors that engine and carries the process scaffold and the coverage gate. Nothing in the Slim surface changes: SlimGuard composes the psr15-guard middleware, so the new engine surfaces ride config through the unchanged factory wiring. The CI sibling version stamps move with the floors (engine 4.2.99 -> 4.3.99, psr15-guard 1.2.99 -> 1.3.99 in ci.yml, release.yml, static-analysis.yml, upstream-drift.yml, scheduled-lint.yml) so the floors resolve against the master siblings while the published constraints stay ^4.3.0/^1.3.0, and `composer.lock` resolves both packages at their released v4.3.0 / v1.3.0. + +### Added + +- **Release Gate and lock fixes (PRs #18, #19).** The v1.2.0 tag's Release Gate failed at Install dependencies with `Source path ../psr15-guard is not found` (the 1.2.0 release added the psr15-guard ^1.2.0 dependency and the ../psr15-guard path repository, and learned ci.yml the sibling checkout and the 1.2.99 stamp, but release.yml never got them): both release jobs (test matrix and composer-audit) now mirror the ci.yml pattern - check out psr15-guard@master into the sibling location, version-stamp it next to the engine, keep the two path repositories while dropping only the eager VCS entries, and composer update both path packages on install. The weekly Scheduled Lint was unbroken separately (PR #19): the committed composer.lock pinned the dev-stamp versions `guard-core-php 4.2.99` / `psr15-guard 1.2.99`, which exist in no registry, so `composer install` could not resolve psr15-guard from Packagist; the lock regenerated against the released versions and the scheduled-lint workflow itself was already correct (the engine path sibling resolves the stamped dev version via the existing composer update step). +- **Process scaffold (PR #20).** `SECURITY.md` (supported versions, advisory reporting), `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `.github/FUNDING.yml`, the PR template and the issue templates, modeled on the Go family and the fastapi-guard baseline. `.github/workflows/static-analysis.yml`: phpstan via the docker pattern these repos already use (composer:2 install with the same ci-only path-repository patch as ci.yml, then `ghcr.io/phpstan/phpstan:latest analyse src --level=5`), on push/pr to master plus the weekly Monday cron; level 5 is the highest level with zero findings on master (level 6 reports one generic return type). `.github/workflows/live-smoke.yml` gains the `live-smoke-advanced` job (the existing simple_app job untouched): a dockerized run of `examples/advanced_app` on host port 8081 asserting `GET /` and `GET /health` 200 plus one blocked-request check (`GET /admin/check?ip=203.0.113.9` without `X-Admin-Token` returns the admin gate's 400 "Missing required header: X-Admin-Token"). CodeQL was drafted and dropped after the first run proved GitHub CodeQL no longer supports PHP (`Did not recognize the following languages: php`); `.github/workflows/semgrep.yml` is the substitute, running the pinned semgrep/semgrep:1.177.0 container with the p/security-audit and p/secrets rulesets over src/ (path-filtered push/PR triggers plus a weekly Monday cron, metrics off). +- **100% line coverage gate (PR #21, following the psr15-guard pilot).** The bespoke `bin/test_*.php` suites stay as they are; `.github/coverage-runner.php` (phpunit/php-code-coverage ^11 + pcov) executes each suite under coverage in collect mode and a merge pass gates on 100.00% measured lines in src/. Coverage went from 70.59% to 100.00% lines (pcov, php 8.3): `bin/test_slim.php` (81 assertions) plus the new `bin/test_slim_no_psr7.php` (4 assertions) covering the documented no-slim/psr7 fallback in `SlimGuard::resolveStreamFactory()` - composer's autoloader cannot reach that branch (slim/psr7 is a dev dependency, so the soft class_exists reference always resolves in a composer-booted process), so the new suite boots through `tests/scoped_autoloader.php` with no composer autoloader and no slim/psr7 mapping, reproducing the production shape the branch exists for. The coverage job mirrors ci.yml's path-repo/stamp resolution and suite pass/fail stays gated by the existing test job. + +### Verification + +- `make lint` exit 0 and `make test` exit 0 on php 8.5.11 (host Redis on 6379, 81/81 checks green), with `composer.lock` resolving guard-core-php v4.3.0 and psr15-guard v1.3.0. + +___ + v1.2.0 (2026-09-27) ------------------- diff --git a/composer.json b/composer.json index 9f707e1..4c1c815 100644 --- a/composer.json +++ b/composer.json @@ -5,8 +5,8 @@ "license": "MIT", "require": { "php": "^8.2", - "rennf93/guard-core-php": "^4.2.0", - "rennf93/psr15-guard": "^1.2.0", + "rennf93/guard-core-php": "^4.3.0", + "rennf93/psr15-guard": "^1.3.0", "slim/slim": "^4.12", "psr/http-factory": "^1.0" }, diff --git a/composer.lock b/composer.lock index 932fabd..8fcc774 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d3982c299dbf93f4a91e432c3d08a57f", + "content-hash": "193ed680933d15104da80de2b3ba2023", "packages": [ { "name": "nikic/fast-route", @@ -382,16 +382,16 @@ }, { "name": "rennf93/guard-core-php", - "version": "v4.2.0", + "version": "v4.3.0", "source": { "type": "git", "url": "https://github.com/rennf93/guard-core-php.git", - "reference": "388d4d1e134b71062b6a18a86a46ba5bdd789571" + "reference": "fe1b6ba14f091397d5588d335be1a59194b8b971" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rennf93/guard-core-php/zipball/388d4d1e134b71062b6a18a86a46ba5bdd789571", - "reference": "388d4d1e134b71062b6a18a86a46ba5bdd789571", + "url": "https://api.github.com/repos/rennf93/guard-core-php/zipball/fe1b6ba14f091397d5588d335be1a59194b8b971", + "reference": "fe1b6ba14f091397d5588d335be1a59194b8b971", "shasum": "" }, "require": { @@ -400,6 +400,9 @@ "ext-pcre": "*", "php": "^8.2" }, + "require-dev": { + "phpunit/php-code-coverage": "^11.0" + }, "type": "library", "autoload": { "psr-4": { @@ -419,7 +422,7 @@ ], "description": "PHP port of guard-core: behavioral WAF engine (detection engine conformance milestone)", "support": { - "source": "https://github.com/rennf93/guard-core-php/tree/v4.2.0", + "source": "https://github.com/rennf93/guard-core-php/tree/v4.3.0", "issues": "https://github.com/rennf93/guard-core-php/issues" }, "funding": [ @@ -432,20 +435,20 @@ "url": "https://paypal.me/renzof93" } ], - "time": "2026-09-27T18:43:50+00:00" + "time": "2026-10-01T20:08:35+00:00" }, { "name": "rennf93/psr15-guard", - "version": "v1.2.0", + "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/rennf93/psr15-guard.git", - "reference": "675ed284f19913ef1932742b998ee8186dcf9ceb" + "reference": "45a0d3392ac8f6f92b52cd8a1f5c15a545d8ca75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rennf93/psr15-guard/zipball/675ed284f19913ef1932742b998ee8186dcf9ceb", - "reference": "675ed284f19913ef1932742b998ee8186dcf9ceb", + "url": "https://api.github.com/repos/rennf93/psr15-guard/zipball/45a0d3392ac8f6f92b52cd8a1f5c15a545d8ca75", + "reference": "45a0d3392ac8f6f92b52cd8a1f5c15a545d8ca75", "shasum": "" }, "require": { @@ -454,10 +457,11 @@ "psr/http-message": "^1.1|^2.0", "psr/http-server-handler": "^1.0", "psr/http-server-middleware": "^1.0", - "rennf93/guard-core-php": "^4.2.0" + "rennf93/guard-core-php": "^4.3.0" }, "require-dev": { - "nyholm/psr7": "^1.8" + "nyholm/psr7": "^1.8", + "phpunit/php-code-coverage": "^11.0" }, "type": "library", "autoload": { @@ -478,7 +482,7 @@ ], "description": "PSR-15 middleware adapter for guard-core-php: translates PSR-7 server requests to the guard-core engine and block verdicts back to PSR-7 responses", "support": { - "source": "https://github.com/rennf93/psr15-guard/tree/v1.2.0", + "source": "https://github.com/rennf93/psr15-guard/tree/v1.3.0", "issues": "https://github.com/rennf93/psr15-guard/issues" }, "funding": [ @@ -491,7 +495,7 @@ "url": "https://paypal.me/renzof93" } ], - "time": "2026-09-27T18:51:51+00:00" + "time": "2026-10-01T20:27:06+00:00" }, { "name": "slim/slim",