- Split `validate` into `validate-python` and `validate-frontend`; publish
needs both. Runner capacity is >= 2 (publish and migrate already overlap).
- deploy/ci-python-venv.sh: venv kept under /root/.cache keyed by Python
version, ISO week, pins and requirements; persistent pip cache. A fresh
venv per run spent ~3 min re-downloading the same wheels.
- npm ci gets a persistent download cache and --prefer-offline (every one
of 1,010 packages was a cache miss).
- publish builds and pushes the API and web images concurrently; the web
Dockerfile mounts BuildKit caches for npm and .next/cache.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8