Repository navigation
Load safeguards before the floor gate - #68
Merged
Merged
Conversation
Refresh the Composer lock: wordpress-configs moves to its trunk at 8d53efd, which finds a plugin's main file by its header, and roave/security-advisories to its latest advisories; the framework's path packages take trunk's references. The npm lock stays as it is, because npm's seven-day release-age cooldown on this host resolved older @php-wasm and @WordPress packages than the lock already holds. No code change was needed. Assisted-by: Claude Code:claude-opus-5-5
consumer-a's entry loads its safeguard after the floor gate, so on a runtime below the plugin's PHP or WordPress floor the export lock never loads, while a failed boot or a dependency below its floor keeps it. A restriction the merchant set should hold whenever the plugin cannot run, so the safeguard loads before the gate. The PHP 8.5 row that raises Requires PHP now expects the safeguard attached and an explicit false relaxation to change nothing. A new Php74 row runs consumer-a on PHP 7.4 with WordPress 6.3 and expects the export capability to map to do_not_allow, the updater to stay hooked and core's requirements message to show; the Php74 lane builds consumer-a for it. Both fail until the entry moves the safeguard. Assisted-by: Claude Code:claude-opus-5-5
The PHP 7.4 harness reads consumer-a's export capability by its literal name, which WPCS reports as unknown because only the safeguard's map_meta_cap callback knows it. The line now waives that sniff with its reason, so the tests profile passes. Assisted-by: Claude Code:claude-opus-5-5
consumer-a loaded includes/safeguards.php after Requirements::check_floors(), so a site below the plugin's PHP or WordPress floor showed what the export lock forbids, while a missing vendor-prefixed/ skipped the gate and loaded the safeguard anyway: two ways the build cannot run, with opposite outcomes. A restriction should hold whenever the plugin cannot boot, so the entry now loads the safeguard first, and the bootstrap check takes the same shape as consumer-b's and the personas'. A safeguard therefore runs on any runtime that parses the plugin. Convention 5 states the rule that follows: it parses on PHP 7.4 and calls only WordPress APIs present at the oldest WordPress the bootstrap package runs on, or guards them. phpstan.bootstrap.neon analyzes consumer-a's safeguard at that PHP and WordPress, which reports a PHP 8 function, a native mixed type or a WordPress 5.9 function there. Limitation 6 no longer lists below-floor runtimes, and limitation 5 drops the safeguard clause it no longer needs. X ruling 89. Assisted-by: Claude Code:claude-opus-5-5
The README's command table said the PHP 7.4 lane builds only the bootstrap persona, and its testing strategy listed only the persona's rows there, while the lane now also builds consumer-a and checks that its safeguard holds below its floors. Both now say so. Assisted-by: Claude Code:claude-opus-5-5
The missing-build-file rows and the PHP 7.4 row hooked no relaxation, so the export capability mapped to do_not_allow from the safeguard's default branch and would still have done so had the safeguard honored an explicit false before boot. Each now hooks one, so a safeguard that relaxes without a booted plugin fails all six rows. Assisted-by: Claude Code:claude-opus-5-5
Convention 5 bounded a safeguard's WordPress APIs by the oldest WordPress the bootstrap package runs on, a version no manifest key holds, while the bootstrap manifest's extra.requires-wp names a newer one for its updater. It now names phpstan.bootstrap.neon, whose WPCompat.requiresAtLeast sets it. Assisted-by: Claude Code:claude-opus-5-5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A plugin's safeguards now load before its floor gate, so a site below the plugin's PHP or WordPress floor keeps the restrictions they enforce, as a failed boot and a missing dependency already did. consumer-a, the reference anatomy, loads
includes/safeguards.phpfirst, and the conventions state what that asks of a safeguard: it parses on PHP 7.4 and calls only WordPress APIs present at the oldest WordPress the bootstrap package runs on, or guards them.Affected packages
wp-framework-bootstrapwp-framework-sharedwp-framework-corewp-framework-settingswp-framework-woocommerceNo package code changes; the change is consumer-a's entry, AGENTS.md and the test lanes.
Checklist
composer quality-checkpasses locally (PHPCS, PHPStan and the tests)README.mdWhat changes
includes/safeguards.phpbefore the bootstrap check, which takes consumer-b's and the personas' shape: a missingload.phpshows the build notice and returns, otherwiseload.php,Updater::register()andRequirements::check_floors()run.falserefused; a newPhp74row runs consumer-a on PHP 7.4 with WordPress 6.3 and expects the export capability mapped todo_not_allow, the updater hooked and core's requirements message; the missing-build-file rows hook afalserelaxation, so a safeguard relaxing without a booted plugin fails them. ThePhp74lane builds consumer-a.phpstan.bootstrap.neonanalyzes consumer-a's safeguard at PHP 7.4 and WordPress 5.2, beside the bootstrap package.Not verified locally
integration-php74job building consumer-a, and the older WordPress branches of the Integration matrix, run only in CI.