Skip to content

fix(health): canonicalize on /api/health + /api/v1/health alias + drift guard#364

Merged
sudoshi merged 1 commit into
mainfrom
fix/health-endpoint-canonicalization
Jun 10, 2026
Merged

fix(health): canonicalize on /api/health + /api/v1/health alias + drift guard#364
sudoshi merged 1 commit into
mainfrom
fix/health-endpoint-canonicalization

Conversation

@sudoshi

@sudoshi sudoshi commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

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/health404. Most damaging: the installer readiness probe (installer/health.py) 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 (the comprehensive sweep)

  • Backend: add a backward-compatible /api/v1/health alias (direct route, not a redirect — probes need a real 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 corrected to .services.darkstar (the .finngen field was specced but never built).
  • Historical/archived design specs left as-is (they record past state).

Permanent + evolving prevention (so it can't recur)

  • scripts/checks/check_health_urls.pyderives 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. 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.
  • Wired into CI (license-guard.yml) and the pre-commit hook.
  • deploy.sh smoke checks now probe both /api/health and /api/v1/health.

Verified

Guard pass + self-test, installer pytest (5), HealthCheckTest both paths 200 (24 assertions), Pint, PHPStan.

🤖 Generated with claude-flow

…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.
@sudoshi sudoshi merged commit 0307fe5 into main Jun 10, 2026
20 checks passed
@sudoshi sudoshi deleted the fix/health-endpoint-canonicalization branch June 10, 2026 21:01
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