Repository navigation
v3.3.0 — Through the front door
1,028 merged PRs (#10812–#11850), 968 of them the catalog pipeline's own. The highlights — the full record is CHANGELOG.md, and each PR carries its own reasoning.
Added
- 👍 / 👎 directly on the plot — rating an implementation is one tap on the static preview or the interactive surface, stored per library and language; one vote per image per session (#11827).
- A shared-secret origin gate closes the direct
*.run.appdoor, and the apex Worker's source moves into the repository —api/origin_gate.pyrefuses with 403 anything the Cloudflare edge did not stamp, so the bot challenge, WAF and cache can no longer be bypassed one URL away (#11208). - The API image is built and its container smoke-tested before merge, not after — the first build of a changed Dockerfile used to happen in Cloud Build after merge, which is how the deploy trigger sat red from 2026-08-30 with every PR check green (#11205).
- IndexNow: changed pages are pushed to Bing, Yandex, Seznam, Naver and Yep instead of waiting for a crawl — every push touching
plots/submits the affected spec and implementation URLs (#11202). - The bot-serving monitor now raises an alarm instead of only turning a tab red, and derives what it asserts from the repo — a failing run opens an issue; it had sat red for ten consecutive nights unnoticed (#11209).
Changed
anyplot-apiruns as a single instance: min 1, max 1, concurrency 40 — between 2026-08-29 and 09-10 Cloud Run started 464 extra instances, each cold start paid for by a live request; the frontend follows at max 1, concurrency 80 (#11828, #11829).- Search results for a plot now name its languages and its other libraries — hub titles read
{title} in Python, R, Julia and JavaScript, implementation pages{title} in plotnine (Python)(#11844). - The frontend deploys through a candidate revision instead of straight onto live traffic — smoked on its tag URL, then promoted exactly; the API deploy got the same net (#11207, #10821).
- The API image is built in two stages and loses more than half its weight — 1.62 GB to 693 MB; a
.dockerignorethat is actually read and shipped bytecode followed (#10821, #11211). - The site's typeface is MonoLisa 3.000: MonoLisa Code everywhere, MonoLisa Text registered for experiments — the webfont CSS is now generated, so the next font update is a re-run (#11836).
- Every PR now adds a
changelog.d/fragment instead of a bullet inCHANGELOG.md— the shared[Unreleased]spot stops producing sibling-PR conflicts, and a CI gate enforces it (#11215). - The scheduled regen runs once a day instead of ten times — 02:17 UTC, re-enabled after the gap backfill (#11848).
Fixed
- OG cards render MonoLisa's italic swashes in production again — the API image installs
libraqm0; the guard added on the way had blocked every API deploy for two days (#10813, #10821). - Infrastructure failures no longer spend a pair's generation budget — the Claude outage of 2026-09-02 had burned all three attempts of 27 pairs in twenty minutes (#11199).
- Implementation pages no longer share one meta description per spec — 4,254 plot pages had about 334 distinct descriptions (#11203).
- Google had no clean image to show as a result's thumbnail —
primaryImageOfPagenow points at the render itself (#11844). - Google showed no icon for anyplot.ai — the bot HTML declares the icons and a real
favicon.icoships (#11838). - Coverage matrix on the stats page counted against 9 libraries instead of 15 — the denominator now comes from the registry (#11835).
Security
- The site's own origin has a gate now, and it ships switched off —
anyplot-app's nginx refuses what the edge did not stamp, armed by measurement rather than a leap (#11221). script-srcdrops'unsafe-inline'for a per-request nonce — Cloudflare copies the nonce onto its injected detection script, which no hash could ever cover (#11220).- The origin gate loses its last real exemption: the cache flush now carries the edge's header instead of being waved through (#11214).
Full Changelog: v3.2.0...v3.3.0