PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Canceled after 13s
PR Checks / Build Pipeline (no push) (pull_request) Canceled after 0s
PR Checks / AI Code Review (Claude) (pull_request) Canceled after 0s
Staging serves the same image as production off stx., with robots.txt saying Allow: / and no noindex — a fully crawlable duplicate of the site. Nothing appears indexed today, most likely because the pages canonicalise across to production, but that is a side effect rather than a control. X-Robots-Tag, not a robots.txt Disallow. Disallow blocks crawling, which is not the same as blocking indexing: a disallowed URL can still be indexed from external links, and blocking the crawl means Google never fetches the page and so never sees a noindex at all. Staging stays crawlable and answers noindex. Matched on the staging host explicitly rather than 'any host that is not production'. The inverted form would cover future environments automatically, but its failure mode is deindexing production if the Host header ever arrives rewritten by a proxy — which cannot be verified from here. This form's failure mode is a new environment being indexable until someone adds it, which is recoverable. Any new non-production hostname must be added. The journeys only ever run against staging (deploy.yml passes STAGING_BASE_URL; promote.yml smoke-polls production without Playwright), so asserting the header there is safe. The two assertions live in one test because the halves only work together. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj