fix: neutralize host PHPRC contamination (LocalWP cURL-77 bug)#20
Merged
Conversation
LocalWP-launched shells export PHPRC pointing at a per-site php.ini that pins openssl.cafile / curl.cainfo to a wp-includes ca-bundle.crt scoped to one WP install. When buddy ran in that environment, PHP picked up the host php.ini at interpreter startup and every HTTPS request died with "cURL error 77: error setting certificate verify locations". bin/buddy is now a thin sh wrapper that 'unset PHPRC' before execing PHP on the real entry script (bin/buddy.php). buddy-cli has no reason to honor a host-app php.ini, and the failure mode (silent TLS death before any request leaves the process) is worse than ignoring it. - bin/buddy: new sh launcher - bin/buddy.php: renamed from old bin/buddy (PHP bootstrap unchanged) - tests: invoke php bin/buddy.php directly (the wrapper isn't php) - AGENTS.md: document the two-file layout Repro: PHPRC="/path/to/localwp/conf/php" buddy executions:list ... # before: cURL error 77 # after: works
- .beads/metadata.json: switch from server mode to embedded mode - .beads/metadata.json: rename database from "beads_buddy-cli" to "beads_buddy_cli"
Code review caught that `dirname "$0"` returns the symlink's directory, not the package's bin/. `buddy self:install` symlinks bin/buddy into ~/.local/bin/ and `composer global require` symlinks into ~/.composer/vendor/bin/ — both paths break with the naive wrapper because there's no buddy.php next to the symlink. Walk the symlink chain manually (POSIX; macOS readlink lacks -f) to find the real launcher, then dirname that. Tested with direct, single symlink, and chained symlink invocations.
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.
Problem
When buddy ran from a shell that had
PHPRCset to a LocalWP site's per-site PHP config — the default for any terminal launched from LocalWP — every HTTPS request died with:LocalWP's
php.inipinsopenssl.cafile/curl.cainfoto a wp-includes CA bundle scoped to one WP site. From any other working directory that path doesn't exist, OpenSSL/cURL refuses to initialize TLS, and Guzzle aborts before any request leaves the process.bin/buddywas a PHP shebang script, so the contaminatedPHPRCwas consumed by PHP at interpreter startup — before any application code ran. A PHP-level fix is impossible (ini_seton these directives is a no-op at runtime; the openssl/curl modules are already initialized by the time we'd see them).Fix
bin/buddyis now a thin POSIXshlauncher thatunset PHPRCand thenexecs PHP on the real entry script. The original PHP bootstrap moved verbatim tobin/buddy.php.The wrapper walks the symlink chain manually (POSIX — macOS
readlinklacks-f) before computingdirname, so both install paths resolvebuddy.phpcorrectly:buddy self:install→ symlinksbin/buddyinto~/.local/bin/.composer global requireand consumer projects → Composer'sBinaryInstallerdetects the non-PHP shebang and generates a sh proxy (not thephpvfscomposer://PHP proxy used for PHP bins), which thenexecs our sh wrapper.Verification
Tested under a contaminated LocalWP shell (
PHPRC=/Users/JT/Library/Application Support/Local/run/V-dp05VsH/conf/php):php -r '...HTTPS...'(sanity)buddyvia~/.local/binsymlinkvendor/bin/buddy(Composer sh proxy → wrapper → buddy.php)php vendor/.../buddy.phpdirect (bypass wrappers, contrast)./bin/buddy executions:list ...aftercomposer updateonto this branchFull phpunit suite still passes (270 tests / 657 assertions).
Compatibility
composer update. Anyone invokingbin/buddydirectly asphp bin/buddy …(no longer valid; that was always undocumented) should switch tobin/buddy …orphp bin/buddy.php ….php bin/buddy …were updated tophp bin/buddy.php ….Commits
61a51fa— convert bin/buddy to sh wrapper, move PHP bootstrap to bin/buddy.php, update tests + AGENTS.md214537c— walk symlink chain in the wrapper so install-via-symlink works (caught by a code-review pass)Bd issue (filed retroactively for audit trail):
beads_buddy_cli-s77.