Raxx · internal docs

internal · gated ↑ index

Console Completeness Audit — 2026-05-06 UTC

Status: Static QA pass (Phase 1+3 of the test plan) Scope: console.raxx.app and raxx-console-staging.herokuapp.com — code-side analysis only Why static: Live UI/UX click-through is blocked by absence of a CF Access service token allowlisted on console.raxx.app's CF Access app (#680). UI verification deferred until that lands.


Executive summary

The "console completeness" pain has a measurable shape. Three findings:

  1. Code internally consistent. All 94 url_for(...) references in templates resolve to actual routes. No broken nav links. No phantom endpoints.
  2. The visible nav today is much smaller than the shipped surface. 11 nav entries are wired in base.html, but 9 of them are gated behind flags that default to OFF, plus role checks. With current prod flag state (console_flag_promotions=OFF per memory), the operator's actual top nav is likely Dashboard / Issues / Sign out — plus Secrets if their role is superadmin. The other 8 nav entries exist in code but are hidden until each flag is individually promoted to on in prod.
  3. Five pages have no nav entry even when every flag is on. These are the "shipped but invisible" surfaces — features whose only entry point is the URL itself or a click-through from another deep page.

The "completeness" gap is 80% flag-state (correctly-built feature gated off in prod) and 20% nav-debt (truly orphaned URLs).


Numbers

Metric Count
GET routes registered in console 56
User-facing HTML pages (excluding API + HTMX fragments) ~22
url_for() references in templates that resolve to real routes 94 / 94
Top-nav entries wired in base.html 11
Top-nav entries visible to a fresh operator (current prod flag state) 3 (Dashboard / Issues / Sign out)
Pages with zero url_for() references in any template 31 — but most are API/HTMX, not pages
Pages with no nav entry even when all flags ON 5

The 11 nav entries and their gates

Reading console/app/templates/base.html lines 1051–1149, the nav block has these entries (when the operator is authed):

# Nav entry Endpoint Visibility gate
1 Dashboard dashboard.index Any authed admin
2 Security security.index flag_console_nav_v2 AND role ops/superadmin
3 Status status_page.index flag_console_nav_v2
4 Issues (external → FreeScout) console_tickets_url Any authed admin
5 Secrets secrets.secrets_index role superadmin
6 Feature Flags flags.flags_index flag_console_flag_promotions AND role ops/superadmin
7 Promotions flags.promotions_queue flag_console_flag_promotions AND role ops/superadmin
8 Customers customers.invite_get flag_console_customer_admin AND role superadmin
9 Billing billing.billing_index flag_billing_summary_api AND RBAC admin_has_billing_read
10 Ops (dropdown) → Ops dispatch panel ops.ops_index flag_console_claude_menu AND role superadmin
11 Ops (dropdown) → Versions console_versions_ui.console_versions_index flag_console_claude_menu AND flag_console_version_manager AND role superadmin

Default state of those flags (from backend_v2/api/feature_flags.yaml)

Flag Default Notes
console_nav_v2 (not in YAML) Likely on by env var; verify via heroku config:get
console_flag_promotions false "default OFF; flip after migration 0010 applies"
console_customer_admin false "default OFF; customer invite + bootstrap token mint UI"
billing_summary_api false "default OFF; billing summary API gated by console-billing-read"
console_claude_menu false "default OFF; flip to enable ops dispatch panel"
console_version_manager false "default OFF; console staging-to-prod promotion endpoint"

Per memory project_console_flag_toggle.md (operator-locked), console_flag_promotions is currently OFF in both staging and prod. If the other defaults haven't been individually promoted, the live nav is Dashboard + Issues + Sign out, possibly plus Secrets and Status.

This is not a bug in any single feature. This is the cumulative effect of every feature being built behind a flag and most of those flags never being promoted to on in prod after their soak.


The 5 truly orphaned pages

These have no nav entry and no url_for() reference from any other template. They exist in code as routes, render real HTML, but there's no path to reach them other than typing the URL.

# Path Endpoint Likely intended home Severity
1 /console/deploy-freeze deploy_freeze.deploy_freeze_page Top nav OR ops dropdown Operator already aware — needs nav entry
2 /console/admins/online admins_online.admins_online Security panel sub-nav OR Ops dropdown Medium
3 /console/customers/<id>/tickets customers.customer_tickets Tab on customer detail page Medium
4 /billing/alert-config billing.billing_alert_config Sub-link on /billing page Low (sub-page of /billing)
5 /totp/enroll auth.totp_enroll Account/security menu Acceptable — likely accessed during auth flow

Verdict: #1, #2, #3 are real UX bugs. #4 and #5 are arguably acceptable depending on the auth/billing flows.


Other observations

Code-quality positives

Self-referential bootstrap trap (already-known, worth restating)

Possible RBAC observation (not verified — needs UI access)

Possible redundancy in the Promotions vs Flags nav


What this audit could NOT cover

UI verification is deferred until #680 lands. I could not check:

When #680 lands and a CF Access service token is allowlisted on console.raxx.app, those checks become a single Playwright sweep.


Recommendations

In priority order, ranked by user-visible impact:

  1. Audit prod flag state. Run heroku config -a raxx-console-prod | grep FLAG_ (operator action; I'm not authorized) and decide which flags should be ON for everyday operator use. Most-likely candidates to turn on now: FLAG_CONSOLE_NAV_V2, FLAG_CONSOLE_FLAG_PROMOTIONS, FLAG_CONSOLE_CLAUDE_MENU. The first one alone unlocks Security + Status nav entries.

  2. File card: nav entry for /console/deploy-freeze. Single-line addition to base.html. Operator already noted this gap in chat today. Likely belongs under the Ops dropdown.

  3. File card: nav-tab for /console/customers/<id>/tickets. Should be a tab on the customer detail page (next to Audit, Danger Zone). Discoverable when looking at a specific customer.

  4. File card: /console/admins/online placement. Either Security sub-nav or Ops dropdown. Pick one.

  5. Provision CF Access service token for console.raxx.app (#680). Without this, every future agent QA pass is gated on you running Playwright manually. 5 min in CF dashboard.

  6. (Optional) Audit the bootstrap trap. Document explicitly that console_flag_promotions and console_nav_v2 are bootstrap-only flips via heroku config:set. Update the runbook for whoever onboards next.


Test plan when UI access lands

When #680 closes and a CF Access service token is allowlisted on console.raxx.app:

Phase 1 — reachability (~30 min): - Playwright loads each of the 22 user-facing pages - Captures HTTP status, full-page screenshot - Pass = HTTP 200 + page renders without console errors

Phase 2 — function spot-check (~1-2 hr): - Dashboard tile hover popover (after PR #1263 landed) - Build-strip animation states (if PR #1264 implementation lands) - Deploy modal open/close (no actual dispatch) - Flag promotion mark + approve flow (no actual promote) - Secret rotate modal v2 open (no actual rotate) - Customer detail tab navigation - Mobile breakpoint at 375px

Phase 3 — staging vs prod diff: - Run Phase 1+2 on both, diff screenshots - Identifies drift between the two envs

Phase 4 — gap remediation: - Each "missing from UI" → file as a card with the exact gap - Quick wins (single-line nav adds) ship as small PRs


Appendix: full route inventory

Source-of-truth: console/app/blueprints/*.py. All 56 GET routes:

Module Path Function Linked from
admins_online /console/admins/online admins_online — (orphan)
alerts /_alerts/drawer alerts_drawer_fragment — (HTMX)
alerts /api/_internal/alerts/unread-count unread_count — (JS poll)
api_billing /alert-config get_billing_alert_config — (API)
api_billing /summary billing_summary — (API)
api_status /builds get_builds — (API)
api_status /secrets get_secrets — (API)
api_status /sites get_sites — (API)
api_status /sites/<site_id> get_site — (API)
auth /bootstrap bootstrap — (entry-only)
auth /login login base.html, dashboard
auth /totp/enroll totp_enroll — (probable orphan)
auth /totp/verify totp_verify_page — (server-redirect target)
billing /billing billing_index base.html nav
billing /billing/alert-config billing_alert_config — (orphan, sub-page of /billing)
console_versions_ui /admin/console-versions console_versions_index base.html nav (Ops dropdown)
customers /console/customers/ customer_list 7 references
customers /console/customers/<id> customer_detail 3 references
customers /console/customers/<id>/audit customer_audit_log 5 references
customers /console/customers/<id>/danger-zone danger_zone_get 1 reference
customers /console/customers/<id>/tickets customer_tickets — (orphan)
customers /console/customers/invite invite_get base.html nav
dashboard /dashboard index 6 references
dashboard /dashboard/_activity activity_partial (HTMX from dashboard)
dashboard /dashboard/_status_grid status_grid_partial (HTMX from dashboard)
dashboard /dashboard/api/sites/<id>/latency-history latency_history_api — (API/JS)
dashboard /dashboard/sites/<site_id> site_detail 2 references
deploy_freeze /api/internal/deploy-freeze/state deploy_freeze_state_api — (CI workflow gate)
deploy_freeze /console/deploy-freeze deploy_freeze_page ORPHAN
deploys /api/internal/deploys list_deploys — (API)
deploys /api/internal/deploys/<id> get_deploy — (API)
deploys /api/internal/deploys/<id>/xenv get_deploy_xenv — (API)
flags /console/flags flags_index base.html nav
flags /console/flags/promotions promotions_queue base.html nav
flags /console/flags/promotions/fragment promotions_fragment (HTMX)
health /health health (CI smoke check)
internal /active-sessions active_sessions — (API)
internal /flag-drift/pending flag_drift_pending — (API for #1266)
internal /poller-status poller_status — (API)
internal /promotions/badge-fragment promotions_badge_fragment — (HTMX)
internal /promotions/pending-count promotions_pending_count — (API)
internal /surfaces/<id>/p5 surface_p5 — (HTMX)
ops /ops ops_index base.html nav (Ops dropdown)
ops /ops/status/<job_id> ops_status (JS redirect from /ops)
root / index base.html (logo link)
secrets /secrets secrets_index base.html nav (superadmin)
secrets /secrets/_list secrets_list_partial (HTMX)
secrets /secrets/history rotation_history base.html (superadmin)
secrets /secrets/<name>/rotate-modal rotate_modal (HTMX modal trigger)
secrets /secrets/<name>/rotate-modal-v2 rotate_modal_v2 (HTMX modal trigger)
secrets /secrets/<name>/rotate/<job_id>/cell get_rotation_action_cell (HTMX)
secrets /secrets/<name>/rotate/<job_id>/progress get_rotation_job_progress (HTMX poll)
secrets /secrets/<name>/sop secret_sop (HTMX modal — likely OK)
secrets /api/secrets/<name>/rotate/<job_id> get_rotation_job — (API)
security /security index base.html nav
status_page /status index base.html nav

Audit run by: Claude Code session, 2026-05-06 UTC Phase 2 (UI click-through): deferred until #680 (CF Access service token for console)