Skip to content
This repository was archived by the owner on May 26, 2026. It is now read-only.

feat(KR-P2-BOOT-PANEL): boot status admin UI (gate sequence viewer) against stub endpoint#45

Merged
rafe-walker merged 1 commit into
mainfrom
feat/kora-KR-P2-BOOT-PANEL
May 21, 2026
Merged

feat(KR-P2-BOOT-PANEL): boot status admin UI (gate sequence viewer) against stub endpoint#45
rafe-walker merged 1 commit into
mainfrom
feat/kora-KR-P2-BOOT-PANEL

Conversation

@rafe-walker

Copy link
Copy Markdown
Owner

Summary

Read-only operator-side panel for Kora's boot sequence outcome — the ordered gate run with per-gate pass/fail + a recent boot history table. Pairs with KR-P2-H (BootGateRunner, CC#1 — in flight) and ships ahead of the runtime wire-in.

This is the 4th panel in the proven stub-first pattern. Predecessors: PR #26 (OPS), #31 (SEA), #37 (CONTROL). The OPS-PANEL stub→real flip already landed in PR #35, so the pattern is empirically known to flip cleanly.

Endpoint (kora_cli/web_server.py)

GET /api/boot-status — returns current + history with stub: true:

field semantics
current.outcome booting / ready / failed
current.gates[] ordered gate sequence; each {gate_id, title, gate_class, outcome, elapsed_ms, detail}
history[] recent boots; failed entries carry failed_gate_id + failed_gate_title + detail

No POST/PUT/DELETE — operator intervention on stuck boots is operator-side (flyctl restart, Doppler env-var fix). No "force re-boot" / "skip gate" controls.

Frontend (web/)

  • pages/BootStatusPage.tsx
    • Current boot card — outcome badge with tone, boot metadata strip (boot_id, started_at, completed_at, elapsed), and a GitHub-PR-checks-style horizontal gate-sequence strip:
      • pass ⇒ green checkmark + elapsed badge
      • fail ⇒ red X
      • pending (booting) ⇒ spinning amber loader
      • steps after a failure ⇒ gray (not run)
      • connector lines progressively green; gray at/after the failure index
    • Failed-gate call-out — destructive panel below the strip when there's a fail; surfaces gate id + title + detail + operator playbook hint pointing at the kora.boot.failed chain event payload
    • Recent history — collapsible table; default-expanded if the most recent boot failed (operator sees prior boots immediately for context), collapsed otherwise. Limit 10 rows with "show more (up to 20)" toggle.
  • lib/api.ts — typed GateOutcome / GateClass / BootOutcome enums + GateResult / CurrentBoot / BootHistoryEntry / BootStatusResponse
  • App.tsx/boot-status route + nav entry (PowerSquare icon) between /operational-state and /kora-control

Flip-over plan

When KR-P2-H lands and BootGateRunner.last_result() + BootGateRunner.recent_history(limit=20) exist, swap get_boot_status body to project from those and drop the stub flag. The page itself doesn't change.

Test plan

  • tests/kora_cli/test_web_server_boot_status.py — 10/10 green, covers all 8 §5 scenarios + 2 contract guards (ready ⇒ all-pass; failed history entries carry failure metadata)
  • test_web_server_{kora_control,sea_tickets,cron_profiles,host_header,mcp,gateway_identity}.py — 57/57 still green
  • npx tsc -b on web/ — clean
  • npx vite build on web/ — clean
  • §8 grep checks: STUB banner present, endpoint registered, zero write-side routes leaked
  • Manual smoke: navigate to /boot-status, verify STUB banner renders, verify gate-sequence strip shows all 7 gates checked green, verify history table shows the failed prior boot with red X on gate 5

Pre-existing test debt (NOT caused by this PR)

tests/kora_cli/test_web_server_operational_state.py has 4 failing tests on main HEAD e33e90a — reproduces with this PR's tree stashed:

  • test_stub_shape_matches_spec_exactly
  • test_transition_history_has_required_keys
  • test_valid_next_states_point_at_valid_primary_states
  • test_ready_state_advertises_three_known_next_states

Cause: PR #35 (KR-P2-I-integration ST5) flipped /api/operational-state from stub → real but didn't update the test file that pinned the original stub shape. These tests were valid against the stub and need rewriting for the real endpoint's shape. Out of scope for this PR — flagged so it doesn't get lost.

Dependency notes

  • KR-P2-H (CC#1, in flight) builds BootGateRunner + R4.1 §9.2 gate sequence
  • BootGateRunner.last_result() + .recent_history(limit=20) are the accessors that flip this from stub to real

🤖 Generated with Claude Code

…gainst stub endpoint

Read-only diagnostic panel showing Kora's most recent boot — the
ordered gate sequence with per-gate outcomes — plus recent boot
history. Pairs with CC#1's KR-P2-H (BootGateRunner) but goes in
ahead of the runtime wire-in; v1 returns a hardcoded sample of a
successful current boot + one failed historical boot with
``stub: True`` so the panel renders meaningfully and the operator
can verify the failed-gate path before any real failures occur.

The flip-over swaps the endpoint body to project from
``BootGateRunner.last_result()`` + ``BootGateRunner.recent_history(
limit=20)``; the page itself doesn't change. This is the 4th panel
shipped against the same stub-first pattern (#26 OPS, #31 SEA, #37
CONTROL all proven; KR-P2-I-integration #35 flipped OPS-PANEL's
stub → real two weeks ahead of where the bucket originally planned).

Backend (kora_cli/web_server.py):
  GET /api/boot-status — read-only stub. No POST/PUT/DELETE; operator
  intervention on stuck boots is operator-side (flyctl restart,
  Doppler env-var fix, etc.).

Frontend:
  - BootStatusPage.tsx — 2 sections:
    * Current boot card: outcome badge with appropriate tone, boot
      metadata strip, GitHub-PR-checks-style horizontal gate-sequence
      strip with checkmark for pass / red X for fail / spinning loader
      for pending. Steps after the failure render gray (not run).
      Connector lines turn green progressively and gray at/after a
      failure. When failed, a destructive call-out renders below the
      strip with the failed gate's title + detail + operator playbook
      hint pointing at the ``kora.boot.failed`` chain event payload.
    * Recent history: collapsible table sorted ``started_at desc``;
      default-expanded if the most recent boot failed (operator should
      see prior boots immediately for context), collapsed otherwise.
      Limit 10 rows by default with "show more (up to 20)" toggle.
  - api.ts — typed GateOutcome / GateClass / BootOutcome enums +
    GateResult / CurrentBoot / BootHistoryEntry / BootStatusResponse.
  - App.tsx — /boot-status route + nav entry (PowerSquare icon)
    between /operational-state and /kora-control per spec §3.

Tests: tests/kora_cli/test_web_server_boot_status.py — 10 tests
covering all 8 §5 scenarios + 2 contract guards (ready ⇒ all-pass;
failed history entries carry failure metadata). 10/10 green.

Pre-existing test debt: tests/kora_cli/test_web_server_operational_state.py
has 4 failing tests on main HEAD (reproduces on c2f9f16 base) due to
PR #35's operational-state stub → real flip not updating the test
file. Out of scope for this PR (it's a separate operational-state
clean-up); flagged in the PR body so it isn't lost.

§8 pre-push grep checks: STUB banner present, endpoint registered,
zero write-side routes leaked.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant