The subtree is in place, so everything that used to fetch and patch core at
build time now just copies it.
tools/build.sh copies wordpress/ — no download, no checksum step,
because there is nothing to fetch and nothing to
trust that is not already in the repository
docker/Dockerfile COPY wordpress/ instead of curl + sha256 + patch;
the build args and the `patch` package are gone
docker-compose.yml no WP_VERSION / WP_URL / WP_SHA256 to keep in step
tools/update-wordpress.sh is rewritten around what the subtree makes
possible. It imports the pristine release onto sirius-press/wordpress-upstream
and then `git subtree merge`s that branch, which three-way merges upstream
against the fork's own commit. A patch either applies with fuzz and hopes or
fails and leaves you re-deriving the change by hand; a merge conflict is
resolved once, in the file, and the next release merges against the
resolution.
patches/ survives as documentation rather than mechanism, and is now
generated: tools/refresh-patches.sh diffs the subtree against the pristine
import and rewrites the directory, with --check for CI. It answers the
question anyone auditing a fork asks first — what exactly did you change
inside WordPress? — in a minute, which `git log wordpress/` cannot, because
that log is mostly upstream imports. Generated documentation stays true; a
hand-maintained record of a core diff drifts, and a stale one is worse than
none because people trust it.
One test change worth noting: the syntax sweep no longer walks all of
wordpress/. It lints the fork's own PHP plus every core file patches/ says
the fork touches, which keeps the suite at seven seconds instead of a minute
while still covering the only core file that can break.
5.3 KiB
Testing
Four suites, in rough order of how fast they run and how much they prove.
tests/run.sh # unit + interop, ~1 second, no services
node tests/live.mjs # end to end against a running instance
The fast suites
tests/run.sh
Needs PHP 7.4+ with GMP or BCMath, and Node 18+. About a second, no database and no server.
| Suite | Checks | What it pins |
|---|---|---|
test-crypto.php |
23 | secp256k1 against published vectors, RFC 6979 determinism, low-S, recovery round trips |
test-identity.php |
44 | CashAddress encode/decode/normalise, BIP-39/32 derivation, both signing envelopes, canonical JSON |
test-export.php |
49 | URL-to-path mapping, document-relative rewriting, gateway path rules |
interop.mjs |
22 | the browser wallet against the PHP one, byte for byte |
interop.mjs is the one that matters most. Sirius Press implements the
same cryptography twice — PHP verifies, JavaScript signs — and every vector in
that file came from libauth, the library the Sirius portal wallet and the BNS
gateway both use. If the two implementations disagree by a byte, nobody can
log in, and the error looks like a rejected password rather than a hash
mismatch. This suite makes that a test failure instead of a bad evening.
A throwaway instance
You do not need Docker, MySQL or a VPS to run a real Sirius Press. PHP's built-in server plus the official SQLite drop-in is enough, and it starts in seconds.
# 1. a complete tree (copied out of the vendored wordpress/, plugins added)
tools/build.sh
cp -R dist/sirius-press /tmp/wpsite
# 2. SQLite instead of MySQL
curl -fsSL -o /tmp/sqlite.zip \
https://downloads.wordpress.org/plugin/sqlite-database-integration.zip
unzip -q /tmp/sqlite.zip -d /tmp/wpsite/wp-content/plugins/
cp /tmp/wpsite/wp-content/plugins/sqlite-database-integration/db.copy \
/tmp/wpsite/wp-content/db.php
mkdir -p /tmp/wpsite/wp-content/database
# 3. a config (any salts will do for a throwaway)
cp /tmp/wpsite/wp-config-sample.php /tmp/wpsite/wp-config.php
# edit it: DB_* values are ignored by the SQLite drop-in, but add
# define( 'WP_HOME', 'http://127.0.0.1:8760' );
# define( 'WP_SITEURL', 'http://127.0.0.1:8760' );
# 4. run it
php -S 127.0.0.1:8760 -t /tmp/wpsite
Then open http://127.0.0.1:8760/wp-admin/install.php. The setup screen asks
for a wallet address instead of an email one — that alone confirms the core
patch applied.
PHP needs pdo_sqlite, sqlite3, gd, mbstring and one of GMP or BCMath.
Set pretty permalinks before testing publishing. With plain permalinks
every post's URL is /?p=N, whose path is /, so the whole site maps to
index.html and each page overwrites the last. The Publishing screen refuses
to let this pass quietly, but a script driving the queue directly will not see
the warning.
End to end
WALLET=/tmp/admin-wallet.json BASE=http://127.0.0.1:8760 node tests/live.mjs
WALLET is a JSON file holding an administrator's phrase and address:
{ "phrase": "twelve words …", "address": "bchtest:qq…" }
40 checks covering sign-in, replay refusal, a stranger's signature, a signature over altered text, purpose separation, registration, the recovery page and the REST endpoints — against a real WordPress, with real sessions.
It creates one account per run, so point it at a throwaway.
Running it with the ecosystem loaded
The suite is worth far more with third-party plugins active, because it then also proves the fork's admin screens survive them:
for p in wordpress-seo contact-form-7 woocommerce; do
curl -fsSL -o "/tmp/$p.zip" "https://downloads.wordpress.org/plugin/$p.zip"
unzip -q -o "/tmp/$p.zip" -d /tmp/wpsite/wp-content/plugins/
done
# activate them, then re-run tests/live.mjs
If you hit a 429, the rate limiter is doing its job — it caps signature verification per client. Clear it between runs:
DELETE FROM wp_options WHERE option_name LIKE '%_transient_%sirius_rl_%';
Publishing, without a registered name
The upload path cannot be tested end to end without a BCNR name and the key that owns it. What can be tested is the part that actually breaks — the bytes being signed — against the real verifier:
node tests/mock-gateway.mjs --owner bchtest:qq… --port 8799
This implements PUT /api/site/<name>/<path> with the signature check
transcribed from Argus/src/gateway/public-gateway.mjs: same envelope, same
digest, same recovery, same comparison against the owner. A request it accepts
is one the real gateway accepts.
Point the site at it — Sirius Press → Settings, gateway
http://127.0.0.1:8799 — store the matching phrase, publish a post, and watch
the queue drain. Signing with any other key gets the same 403 the real gateway
returns.
It needs @bitauth/libauth resolvable from the script, which is the point: it
verifies with the same library the gateway does, not with ours.
What is not covered
- A fresh VPS install.
install.shand the Docker stack are written and syntax-checked but have not been run against a clean Ubuntu box. - A real gateway upload. Verified against the transcribed verifier above,
not against
navigate.stwith a registered name. - Browser UI. The signing scripts are exercised through Node, which runs the same code, but nobody has clicked the buttons in a browser.