Skip to content

feat(deploy): release the Feed only when its inputs change; settle gate for container rollouts - #652

Merged
AsperforMias merged 1 commit into
mainfrom
feat/feed-release-decoupling
Nov 8, 2026
Merged

AsperforMias merged 1 commit into
mainfrom
feat/feed-release-decoupling

Conversation

@AsperforMias

Copy link
Copy Markdown
Collaborator

Why

Production releases failed in 15 of 81 attempts between 2026-10-17 and 2026-11-07. Cloudflare data shows the main cause, 9 of 15:

  • The race: Cloudflare marks a Containers rollout completed at creation, but new placements keep starting the previous image for about 2–3 minutes. On 2026-11-07 the rollout completed at 09:04:26, the off restart at about 09:05 was rejected with container_version_or_contract_mismatch, and the replacement placements only appeared at 09:06:25 and 09:07:18.
  • The coupling: the Feed cutover also runs on every site release, so a Feed problem fails the whole production release.

What

  • Settle gate (ghfind-server feed-production-rollout.mjs): no lifecycle request is sent until 240 s after the rollout was created. Lifecycle requests are still never retried. The rollout step timeout goes from 310 s to 610 s.
  • Plan job: hashes the Feed inputs (feed-release-plan.mjs) and compares them with the last successful cutover (feed/released).
  • Site job: runs when the Feed is unchanged. It deploys the Web in the live gateway mode (web-mode), re-verifies it, runs the smoke test, and rolls back on failure. It never touches the runtime.
  • Deploy job: runs when the Feed changed. It is the existing cutover, and it records feed/released only after a successful smoke.
  • Bot: follows whichever path made its SCORE backend live.
  • D1 migrations: production and apps releases share production-d1-writers, so core migrations are never applied concurrently.
  • Contract: check-cf-release-workflow enforces all of the above, with new negative tests (17/17). The new feed-release-plan tests run in CI.

Requires ghfind-server ≥ v1.0.2. The next composed release will run one Feed cutover (no successful cutover is recorded yet) to bring the paused Feed back.

🤖 Generated with Claude Code

- plan job: hash the Feed inputs and compare with the last successful cutover
  (feed/released); FEED_RELEASE_MODE=always forces a cutover.
- site job (Feed unchanged): core migrations, Web build, deploy in the live
  gateway mode with re-verification, public smoke, rollback to the previous
  Web on failure. Never touches the runtime, containers or consumers.
- deploy job (Feed changed): the existing cutover, with a 610 s rollout gate
  that waits for container placements to settle; records feed/released only
  after a successful smoke.
- bot deploys after whichever path made its SCORE backend live.
- production deploy/site and the apps release share production-d1-writers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@AsperforMias
AsperforMias merged commit 528338e into main Nov 8, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant