A role-files-layout exemption frees a tree from files/<lang>/ because
its import paths are fixed from outside. The mirrored-test lint derived
its scope from that same directory, so every layout exemption silently
became a test exemption nobody ever argued for.
The language now comes from the file suffix. Test code is excluded by
scope rather than exempted: a test-* role and a files/playwright/ or
files/test/ tree are the tests, so demanding a test of them is circular.
The eleven files this newly reaches are framework-instantiated and carry
a stated reason each.
Both plugins ended their candidate chain with a hardcoded
/etc/ssl/certs/ca-certificates.crt. Its own docstring named the condition
that would make it useful — the OS bundle carries the Infinito CA only
once update-ca-certificates has run inside the container — and that
condition never occurs alone: with-ca-trust.sh installs the anchor and
exports CURL_CA_BUNDLE/CA_TRUST_CERT/SSL_CERT_FILE together, and
compose_ca.py sets the same three on every service it covers.
Where the CA override does not apply at all, which is the shipped default
since TLS_MODE is letsencrypt, the OS store holds no internal CA either,
so the fallback could not rescue an internal endpoint. For Joomla the
outcome is byte-identical: with no CURLOPT_CAINFO set, Debian libcurl
compiles in that very path. In swarm the inject runs --no-wrapper, so
update-ca-certificates never runs and the removed line pointed at a file
that provably lacks the CA.
WordPress now verifies against its own bundled Mozilla roots instead of
the image OS store when no variable is set; nothing in the repository
writes into that store for these two images.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The earlier mu-plugin pointed http_request_args['sslcertificates'] at the OS bundle (/etc/ssl/certs/ca-certificates.crt), which does NOT carry the internal root CA unless update-ca-certificates ran in the container — so the OIDC token exchange to the self-signed internal Keycloak still failed with 'cURL error 60: SSL certificate problem' in CI run 28044348006. Read the env-provided bundle first (CURL_CA_BUNDLE / CA_TRUST_CERT / SSL_CERT_FILE), which sys-svc-compose-ca injects into every container pointing at the bind-mounted /tmp/infinito/ca/root-ca.crt (compose_ca.py), falling back to the OS bundle.
Verified chain: daggerhart-openid-connect-generic issues its token/userinfo requests via wp_remote_post/wp_remote_get (the WP HTTP API), so the http_request_args filter applies and WP's curl uses CURLOPT_CAINFO = the internal root CA, which verifies the Keycloak cert.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The OIDC login redirected to Keycloak and back with a valid code, but the server-side token exchange (daggerhart-openid-connect-generic wp_remote_post to the self-signed internal Keycloak) failed with 'cURL error 60: SSL certificate problem: unable to get local issuer certificate' (60x in CI run 28018750880), so the user was never logged in and never redirected to /wp-admin. WordPress's HTTP API (WpOrg\Requests) pins CURLOPT_CAINFO to its own bundled wp-includes/certificates/ca-bundle.crt and ignores the OS trust store and the CURL_CA_BUNDLE/SSL_CERT_FILE env vars, so the earlier ca-certificates Dockerfile change had no effect.
Add a mu-plugin that filters http_request_args to set sslcertificates to the OS CA bundle (/etc/ssl/certs/ca-certificates.crt), which the compose CA-injection populates with the internal root CA, so wp_remote_* TLS verifies the internal cert. Not a green-wash: no assertion weakened, no_sslverify left false (verification stays ON), the test still requires a real OIDC round-trip to /wp-admin.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>