Splitting this out of #283 / #282 so the security fix ships without being held up by a policy debate.
What happened
wp-coding-standards/wpcs shipped a security patch (3.4.1, CVE-2026-45293). Because composer.json pins "wp-coding-standards/wpcs": "3.4.0" exactly, two things followed:
- Consumers could not pick up the patch on their own — it needed a Dependabot PR, a CHANGELOG PR, and a signed
7.0.1 tag here first.
- More sharply: Composer 2.10 blocks advisory-affected versions by default (
policy.advisories.block), so the pin made released 7.0.0 fail to resolve at all:
- Root composer.json requires wp-coding-standards/wpcs 3.4.0 … not loaded,
because they are affected by security advisories ("PKSA-mh9b-91zm-m1gy")
A pinned dependency becoming advisory-affected now breaks installation of our package outright, not just its security posture. That failure mode did not really exist when the pinning policy was written.
The tradeoff
The pin is deliberate — 7.0.0's CHANGELOG states "Dependencies stay pinned to exact versions (as before) so the standard lints reproducibly." That goal is real: a PHPCS minor can add sniffs and turn a green build red without any change on our side.
The counter-argument is where reproducibility belongs. This is a library, and we deliberately don't commit composer.lock (CI resolves fresh, see ci.yml). Reproducibility for a library is normally the consumer's lockfile, not the library's constraints — pinning here buys reproducibility for everyone at the cost of making us a mandatory release bottleneck for every upstream patch.
Options
- Keep exact pins. Accept the release bottleneck. Mitigate by treating Dependabot security PRs as same-day releases.
~3.4.1 (patch-only drift). Security and bug patches flow to consumers immediately; minors like 3.5.0 still require a deliberate bump here, so the "new sniffs break the build" risk stays contained. Applies equally to squizlabs/php_codesniffer, slevomat/coding-standard, phpcompatibility/phpcompatibility-wp, sirbrillig/phpcs-variable-analysis.
^3.4.1. Maximum flexibility, but reintroduces exactly the minor-drift breakage the pinning policy was meant to prevent. Probably not worth it.
~3.4.1 looks like the right middle ground, but it is a policy call for the team rather than something to slip into a security release.
Worth deciding either way, since the next upstream advisory will reproduce the same install breakage.
🤖 Generated with Claude Code
Splitting this out of #283 / #282 so the security fix ships without being held up by a policy debate.
What happened
wp-coding-standards/wpcsshipped a security patch (3.4.1, CVE-2026-45293). Becausecomposer.jsonpins"wp-coding-standards/wpcs": "3.4.0"exactly, two things followed:7.0.1tag here first.policy.advisories.block), so the pin made released 7.0.0 fail to resolve at all:A pinned dependency becoming advisory-affected now breaks installation of our package outright, not just its security posture. That failure mode did not really exist when the pinning policy was written.
The tradeoff
The pin is deliberate — 7.0.0's CHANGELOG states "Dependencies stay pinned to exact versions (as before) so the standard lints reproducibly." That goal is real: a PHPCS minor can add sniffs and turn a green build red without any change on our side.
The counter-argument is where reproducibility belongs. This is a library, and we deliberately don't commit
composer.lock(CI resolves fresh, seeci.yml). Reproducibility for a library is normally the consumer's lockfile, not the library's constraints — pinning here buys reproducibility for everyone at the cost of making us a mandatory release bottleneck for every upstream patch.Options
~3.4.1(patch-only drift). Security and bug patches flow to consumers immediately; minors like 3.5.0 still require a deliberate bump here, so the "new sniffs break the build" risk stays contained. Applies equally tosquizlabs/php_codesniffer,slevomat/coding-standard,phpcompatibility/phpcompatibility-wp,sirbrillig/phpcs-variable-analysis.^3.4.1. Maximum flexibility, but reintroduces exactly the minor-drift breakage the pinning policy was meant to prevent. Probably not worth it.~3.4.1looks like the right middle ground, but it is a policy call for the team rather than something to slip into a security release.Worth deciding either way, since the next upstream advisory will reproduce the same install breakage.
🤖 Generated with Claude Code