Stop another service's outage rolling this repo's deploy back - #392
Conversation
This comment has been minimized.
This comment has been minimized.
5ea8b30 to
d8a8487
Compare
This comment has been minimized.
This comment has been minimized.
d8a8487 to
814e84c
Compare
This comment has been minimized.
This comment has been minimized.
Three probes in production-smoke-tests named towers.retina.fm. Since the origin flip of 2026-09-14 Cloudflare routes that name to tower-finder-service's own edge, so they no longer traversed our nginx at all and asserted nothing about what this repo does. They now point at map.retina.fm, which we do serve. Repointing alone would not have been enough, and the first draft of this change claimed otherwise. The probes reach the same service through our proxy either way, and assert_tower_contract failed on any non-200, so a service outage still failed the smoke — and this job answers a failed smoke by SSHing into production and reverting retina-server. A dependency being down was grounds for rolling back a healthy release. So the two causes are now told apart. A gateway status (502, 503, 504) means our nginx matched the location and forwarded, and the far side did not answer: warned, not failed. Anything else stays fatal, and a broken forward is not a gateway status anyway — with no `location /api/towers` the request falls through `location /` to the app, whose tower stack went with the monolith, so it 404s. That is the regression these probes exist to catch and it is untouched. This follows the precedent already in the same block. /api/elevation has warned on its upstream's refusal since 2026-08-27, when open-meteo's quota rolled production back on a deploy that was fine. The reasoning there was never specific to elevation; it was specific to a fault we do not own. Two consequences carried deliberately. That comment justified elevation's leniency by saying towers and config stay strict, which is no longer true, so it now rests on the 404 case instead. And the direct-run gate in tower-contract.sh keeps treating a config gateway status as fatal: the production smoke is asking "should this deploy be reverted", but that gate is asking "may a vhost be pointed at this instance", and an instance that is not answering is not ready. Staging's suite warns on the same terms. A red staging smoke skips the production deploy, so left strict it would hold releases behind an outage this repo cannot fix. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
814e84c to
c2b2247
Compare
|
Claude finished @Babissimo's task in 2m 27s —— View job Review of PR #392 (updated diff, commit
|
Ticket: https://app.clickup.com/t/123zgec2zeq
Independent of #389 and #391 — branched from
main, mergeable on its own.The problem
production-smoke-testsends in aRollback production on smoke-test failurestep that SSHes into production and reverts retina-server. Two things were wrong with what it gated on.Three probes named
towers.retina.fm. Since the origin flip of 2026-09-14, Cloudflare routes that name to tower-finder-service's own edge, so those probes stopped traversing our nginx at all. They asserted nothing about what this repo does, while still being able to roll it back.And repointing them is not sufficient. An earlier revision of this PR claimed it was; that was wrong. The probes reach the same service through our proxy whichever hostname they use, and
assert_tower_contractfailed on any non-200, so a tower-finder-service outage still failed the smoke and still reverted a healthy retina-server release.The fix
The probes move to
map.retina.fm, which we do serve, and the two causes are told apart.A gateway status (502, 503, 504) means our nginx matched the location and forwarded, and the far side did not answer. That is warned, not failed. Anything else stays fatal.
A broken forward does not look like a gateway status: with no
location /api/towersthe request falls throughlocation /to the app, whose tower stack went with the monolith, so it answers 404. That is the regression these probes exist to catch and it is untouched.This follows a precedent already eight lines below in the same block.
/api/elevationhas warned on its upstream's refusal since 2026-08-27, when open-meteo's quota rolled production back on a deploy that was fine (86cbaxrhp, and again on 2026-09-14 as 123zgec2qqa). The reasoning was never specific to elevation, only to a fault we do not own.Two consequences carried deliberately
/api/towersand/api/configstay strict. No longer true, so it now rests on the 404 case instead. Comment updated rather than left to mislead.tower-contract.shstill treats a config gateway status as fatal. The production smoke asks "should this deploy be reverted"; that gate asks "may a vhost be pointed at this instance", and an instance that is not answering is not ready. Without this thetower-service-contractjob would have started passing against a dead service.Staging's suite warns on the same terms: a red staging smoke skips the production deploy, so left strict it would hold releases behind an outage this repo cannot fix.
Coverage after this change
tower-service-contractjobtest_towers_vhost_coverage.pyVerification
Nothing in CI validates a workflow edit in this repo — no
actionlintstep, no pre-commit hook, and the smoke jobs only run on push tomain. So a green tick here proves little. Checked by hand:assert_tower_contractandassert_config_contractgive rc 2 for 502/503/504 and rc 1 for 404 and 500.actionlintclean;bash -nclean on both scripts;shellcheckreports nothing intower-contract.shand nothing in the lines this touches instaging-smoke-test.sh.pre-commit run --all-filespasses.test_towers_vhost_coverage.pyandtest_nginx_rewrite_ordering.pypass (8 tests).map.retina.fm/200,/api/towers200 onmap,api,dash;/api/elevationand/api/config200 ondashandmap.adminanswers 302 without credentials, which is expected — it is behind Cloudflare Access and the job supplies a service token.The real proof is the first production deploy after merge; worth watching that run.
🤖 Generated with Claude Code