fix(health): canonicalize on /api/health + /api/v1/health alias + drift guard#364
Merged
Merged
Conversation
…uard against drift Root cause: routes/api.php is mounted under the /api prefix (not /api/v1), so the health route is /api/health. Consumers that assumed the v1 prefix hit /api/v1/health -> 404 — most damagingly the installer readiness probe (installer/health.py), which checks for HTTP 200, so first-run 'waiting for Parthenon to come online' could never reach ready and the Done-page Open button never enabled. LegacyAtlasRedirectController also 301-redirected WebAPI fallbacks to the 404. Fixes: - backend: add backward-compatible /api/v1/health alias route (direct, not a redirect — probes need 200) so already-shipped installer binaries + external monitors work; HealthCheckTest now locks BOTH paths to 200 - installer: probe + tests + GUI label -> /api/health - LegacyAtlasRedirectController: redirect fallbacks -> /api/health - runbooks: compliance (DR/IR/remediation) + finngen runbook -> /api/health; finngen jq fixed to .services.darkstar (the .finngen field was specced but never implemented) Permanent + evolving prevention: - scripts/checks/check_health_urls.py: DERIVES the real health routes from api.php and fails if any live consumer (installer/deploy/infra/SPA) references a health path the backend doesn't serve — so a future typo or alias removal is caught automatically. Verified it flags a planted /api/v2/health. - wired into CI (license-guard.yml) and the pre-commit hook - deploy.sh smoke checks now probe both /api/health and /api/v1/health (prod regression catch) Verified: guard pass + self-test, installer pytest (5), HealthCheckTest both paths 200, Pint, PHPStan.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Root cause
routes/api.phpis mounted under the/apiprefix (not/api/v1), so the health route is/api/health. Consumers that assumed thev1prefix hit/api/v1/health→ 404. Most damaging: the installer readiness probe (installer/health.py) checks for HTTP 200, so first-run "waiting for Parthenon to come online" could never reachreadyand the Done-page "Open" button never enabled.LegacyAtlasRedirectControlleralso 301-redirected WebAPI fallbacks to the 404.Fixes (the comprehensive sweep)
/api/v1/healthalias (direct route, not a redirect — probes need a real 200) so already-shipped installer binaries + external monitors work;HealthCheckTestnow locks both paths to 200./api/health./api/health./api/health; FinnGenjqcorrected to.services.darkstar(the.finngenfield was specced but never built).Permanent + evolving prevention (so it can't recur)
scripts/checks/check_health_urls.py— derives the real health routes fromapi.phpand fails if any live consumer (installer/deploy/infra/SPA) references a health path the backend doesn't serve. Self-maintaining: add/rename a route and the allowed set updates; remove the alias and every straggler is flagged; a new typo is caught. Verified it flags a planted/api/v2/health.license-guard.yml) and the pre-commit hook./api/healthand/api/v1/health.Verified
Guard pass + self-test, installer pytest (5),
HealthCheckTestboth paths 200 (24 assertions), Pint, PHPStan.🤖 Generated with claude-flow