Repository source: docs/plans/openpgp_production_incident_recovery_checklist_v1.md
OpenPGP Production Incident Recovery Checklist
Scope and confirmed behavior
This checklist addresses a production failure in which the browser OpenPGP loader selects a bundle but cannot fetch it:
secure origins select
/assets/openpgp.min.js(v6);public HTTP origins select
/assets/openpgp.v5.11.3.min.js(v5);the loader is itself emitted with a fingerprinted URL;
the bundle URLs are currently raw, runtime JavaScript dependencies.
The HTTP v5 selection is correct. A failure mentioning
/assets/openpgp.v5.11.3.min.js is an asset-delivery failure, not a fallback
selection failure.
Target environment
Public HTTP origin:
http://zenmemes.com/Public HTTPS origin:
https://zenmemes.com/Required HTTP bundle:
http://zenmemes.com/assets/openpgp.v5.11.3.min.jsRequired HTTPS bundle:
https://zenmemes.com/assets/openpgp.min.jsHosting constraint: only the application files and
public/.htaccessare controllable; do not require Apache virtual-host access for recovery.
Observed production state
The public HTTP origin does not serve raw assets, not merely the v5 bundle.
Fingerprinted requests can be served by the PHP FrontController, but raw
requests fall through to a 404. The immediate recovery is the safe raw public
asset fallback in the code-fix inventory; restoring a file alone cannot fix
this host behavior.
./v3 build-static alone is not a recovery action for this incident: its
current output does not contain the raw v5 filename requested by the loader.
Do not clear browser storage, regenerate user keys, force HTTPS, or enable HSTS as incident workarounds. Those actions can strand existing browser-held identities and do not restore the missing bundle.
1. Contain and identify the live asset origin
- [ ] Pause any deployment that publishes a static artifact directory as the
public asset origin until it has passed the checks below.
- [ ] Record the effective production `DocumentRoot`, CDN/origin mapping, and
the location from which `/assets/*` is served.
- [ ] Confirm that the deployed application checkout includes both tracked
source files:
```text
public/assets/openpgp.min.js
public/assets/openpgp.v5.11.3.min.js
```
- [x] The deployed checkout contains `openpgp.v5.11.3.min.js` with the
expected SHA-256:
`89ae4b15e830e08096a125003218bdc7b5c39a4075437dc8d6d4a4e3bdc9a550`.
- [ ] Confirm the web server can read both files.
- [ ] Confirm client-visible behavior only: the checked-in `public/.htaccess`
permits existing `/assets/*` files to bypass PHP. If a requested asset still
reaches PHP, the application must supply a safe public-asset fallback rather
than relying on unavailable host configuration access.
- [ ] From an external machine, capture status, headers, and final URL for
each request. Use `GET`, rather than relying only on `HEAD`:
```bash
curl -sS -D - -o /dev/null http://zenmemes.com/assets/openpgp.v5.11.3.min.js
curl -sS -D - -o /dev/null https://zenmemes.com/assets/openpgp.min.js
```
- [ ] Treat any redirect, HTML/PHP error page, 404, 403, 405, or non-JavaScript
content type as a failed asset check.
- [x] The required HTTP v5 asset check failed with `404`; the required HTTPS
v6 asset check returned JavaScript.
- [ ] Compare the response body checksum with the deployed source file. A
`200` response containing an error document is not a successful recovery.
- [ ] Inspect CDN/reverse-proxy rules for an asset allowlist, deployment-copy
exclusion, or a static-release origin that omits the raw bundle files.