lith: wire CF cache auto-purge into the deploy pipeline
Three fixes for the issue that left the latency-paper cards URL pinned
to a stale SPA-fallback HTML response in Cloudflare's edge cache:
1. Caddyfile — when neither {path} nor {path}.html exists on disk,
serve /index.html as a SPA fallback but tag it Cache-Control:
no-cache, must-revalidate, max-age=0. Without this, a request for a
not-yet-deployed PDF gets the SPA HTML and CF pins that HTML to the
PDF URL for 4h via its default static-asset cache.
2. webhook.sh — replace the purge_everything sledgehammer with a
URL-scoped purge: collect changed system/public/<host>/<rel> paths,
map each to its public URL(s) (papers.aesthetic.computer files also
get purged as papers.prompt.ac), and POST in 30-URL chunks per
Cloudflare's per-request limit. The trigger condition is unchanged
but the env-var gate now logs which URLs would have been purged
when CLOUDFLARE_PURGE_TOKEN / CLOUDFLARE_ZONE_ID aren't set.
3. lith/scripts/cf-purge.fish — workstation-side ad-hoc tool with the
same API. Reads creds from $CLOUDFLARE_PURGE_TOKEN, then the lith
vault env, then falls back to the Global API Key. Used to clear the
currently-poisoned cards URL.
Production still needs CLOUDFLARE_PURGE_TOKEN + CLOUDFLARE_ZONE_ID
added to aesthetic-computer-vault/lith/.env.gpg before the webhook
auto-purge fires; .env.example is updated alongside this commit (in
the vault repo) to document the keys.