fix: guard against agents-api dual-load version skew on bootstrap#2485
Merged
Conversation
The agents-api substrate guards its entire class-loading block with a single coarse AGENTS_API_LOADED constant. When two different versions of the substrate coexist on one network (data-machine's bundled copy plus a separately activated standalone agents-api plugin) and the OLDER copy wins the load race, the newer bundled copy early-returns before requiring its newer classes. Any path touching a newer-only class (e.g. WP_Agent_Package_Artifact_Hasher during agent export) then fatals with a bare "Class ... not found". Add a bootstrap guardrail that detects the skew (constant defined but canary class absent), self-heals by topping up the missing class files from data-machine's OWN bundled copy where safe (drift-free: it parses the bundled bootstrap's require list rather than hardcoding it), and otherwise surfaces a clear admin notice + WP-CLI error instead of degrading into a cryptic fatal. The durable fix (idempotent per-class loading) belongs upstream in Automattic/agents-api and is tracked separately; this is the data-machine guardrail only. Fixes #2477
Contributor
Homeboy Results —
|
- Add the repo's standard narrow phpcs:ignore for the local-file file_get_contents read in the bootstrap parser (matches the existing convention used across the Bundle classes). - Align assignment whitespace in the self-heal helper. - Reword an inline comment to end in a full stop. - In the smoke test, rename the loop collection off the WPCS global-override name list and route the src/-prefix check through the assertion helper instead of an interpolated echo, removing the output-escaping and global-override violations.
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.
Fixes #2477
What this is — and isn't
This is the data-machine consumer-side guardrail for the agents-api dual-load version-skew fatal. It is not the durable substrate fix. The root cause lives in
automattic/agents-api's all-or-nothingAGENTS_API_LOADEDguard; the durable fix (idempotent per-class loading) is tracked upstream in Automattic/agents-api#291 and is intentionally out of scope here.Problem (from #2477)
The agents-api substrate guards its entire class-loading block with one coarse constant:
When two different versions of the substrate coexist on a network — data-machine's bundled (vendored) copy and a separately activated standalone
agents-apiplugin — and the older copy wins the load race, the newer bundled copy early-returns before requiring its newer classes.agent export(and any newer-only class path) then fatals with a bareClass "WP_Agent_Package_Artifact_Hasher" not found. All export profiles (share,backup,fork) were dead.The guardrail
After the agents-api require block in
data-machine.php, run a guardrail that:defined('AGENTS_API_LOADED') && ! class_exists('WP_Agent_Package_Artifact_Hasher')(the hasher is the canary).require_once AGENTS_API_PATH . 'src/...'list rather than hardcoding it, and every include isrequire_onceso already-loaded files are skipped and only missing classes are topped up. This makes export work even when an older standalone copy won the race.admin_noticeserror and (under WP-CLI) callsWP_CLI::error()with a clear message naming the cause and the fix (deactivate/remove the older standalone agents-api plugin, or update it to >= the bundled version). Never degrades into a bare "class not found" fatal.It does not refactor the bootstrap and does not touch the vendored agents-api files (composer artifact).
Files changed
inc/agents-api-guardrail.php(new) — detection + self-heal + clear-error helpers.data-machine.php— require + invoke the guardrail right after the agents-api require block.tests/agents-api-dualload-guardrail-smoke.php(new) — simulates the collision and asserts detection → self-heal → idempotency.Test results
The new smoke simulates the exact collision (define
AGENTS_API_LOADEDwith the canary class absent), then asserts the guardrail detects it, self-heals the canary from the bundled copy, and is idempotent on a second run. (On the live VPS the standalone duplicate has already been removed, so the smoke is the durable way to exercise the guardrail.)Durable fix tracked upstream
The real fix — idempotent per-class loading independent of the
AGENTS_API_LOADEDbootstrap constant — is filed at Automattic/agents-api#291. This PR is the guardrail so data-machine fails safely (and self-heals) until the substrate ships that fix.