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

feat(KR-P2-OPS-PANEL): operational state admin panel against stub endpoint#26

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

feat(KR-P2-OPS-PANEL): operational state admin panel against stub endpoint#26
rafe-walker merged 1 commit into
mainfrom
feat/kora-KR-P2-OPS-PANEL

Conversation

@rafe-walker

Copy link
Copy Markdown
Owner

Summary

Read-only /operational-state admin panel shipped against a hardcoded stub endpoint. Pairs with CC#1's KR-P2-I-skeleton (R4.1 §9.1 state machine) and goes in ahead of the runtime wire-in so the UI is ready when KR-P2-I-integration lands.

Endpoint (kora_cli/web_server.py)

GET /api/operational-state — returns the v1 stub:

{
  "primary_state": "ready",
  "claim_permission": "normal",
  "degradation_reasons": [],
  "is_degraded": false,
  "transition_history": [{ "timestamp": "...", "from_state": "booting", "to_state": "ready", "trigger": "..." }],
  "valid_next_states": [{ "to_state": "active", "trigger": "..." }, ...],
  "stub": true
}

Enum value strings pinned verbatim to R4.1 §9.1:

  • primary_state ∈ {booting, ready, active, paused, stopped}
  • claim_permission ∈ {none, critical_only, normal}
  • degradation_reason ∈ {cost, auth, dispatch, substrate, migration, operator, token_expiring, retry_ceiling}

No write-side endpoints — state mutations belong to kora_control (KR-P2-J), not this panel.

Frontend (web/)

  • pages/OperationalStatePage.tsx — primary-state badge with tone per state, claim-permission pill, degradation chips with hover blurbs (rendered only when present), transition-history table, valid-next-states list. STUB banner renders only when stub: true so a real outage never gets masked as "stub data".
  • lib/api.ts — typed enums + OperationalStateResponse so a future Python-side enum drift surfaces as a TS error.
  • App.tsx/operational-state route + nav entry (Activity icon) inserted between /sessions and /analytics per spec §3.

Flip-over plan

When KR-P2-I-integration lands, swap the get_operational_state body to project from the real OperationalState singleton and drop the stub: True field. Frontend continues to work unchanged; the stub banner disappears the moment the flag goes away.

Test plan

  • tests/kora_cli/test_web_server_operational_state.py — 8/8 green, covers all five §5 scenarios + READY-exits guard + enum-subset guard
  • test_web_server_{cron_profiles,host_header,mcp,gateway_identity}.py — 39/39 still green (regression sanity, 47 total in suite)
  • 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 /operational-state, verify STUB banner renders, verify READY badge + transition row + three valid next-states list render

Dependency notes

  • R4.1 §9.1 is the contract this stub is built against.
  • KR-P2-I-skeleton (CC#1) lands the Python dataclass + enum + transition table. This PR's TypeScript enum value strings match §9.1 verbatim; if CC#1 deviates, we update here.
  • KR-P2-I-integration (post-substrate-round Bucket C) flips the stub → real read.

🤖 Generated with Claude Code

…point

Skeleton for the operator-facing /operational-state admin page. Pairs
with CC#1's KR-P2-I-skeleton (R4.1 §9.1 state machine) but goes in
ahead of the runtime wire-in: the data source is a hardcoded
``GET /api/operational-state`` stub that always reports READY/normal/
no-degradation with ``stub: true`` so the frontend can render a banner
making it obvious to operators that the values are not live runtime
state. When KR-P2-I-integration lands, the endpoint flips to read from
the real OperationalState singleton and the ``stub`` flag goes away —
the page itself doesn't change.

Backend (kora_cli/web_server.py):
  GET /api/operational-state — read-only stub. Enum value strings pinned
  verbatim to R4.1 §9.1: primary_state ∈ {booting,ready,active,paused,
  stopped}, claim_permission ∈ {none,critical_only,normal}, eight
  degradation_reason values. No POST/PUT/DELETE — state mutations belong
  to kora_control (KR-P2-J), not this panel.

Frontend:
  - OperationalStatePage.tsx — primary-state badge with tone per state,
    claim-permission pill, degradation chips with hover blurbs (rendered
    only when present), transition-history table, valid-next-states list
    with trigger phrases. STUB banner renders only when stub: true.
  - api.ts — typed shape (PrimaryState, ClaimPermission, DegradationReason
    enums + OperationalStateResponse) so a future enum drift in the
    Python side surfaces as a TS error rather than a silent runtime
    miscompare.
  - App.tsx — /operational-state route + nav entry (Activity icon)
    inserted between /sessions and /analytics per spec §3.

Tests: tests/kora_cli/test_web_server_operational_state.py covers all
five §5 scenarios plus an extra READY→{active,paused,stopped} guard
(catches stub drift) and an enum-subset guard (catches typos). 8 tests
green; all 47 web_server-suite tests green; tsc -b + vite build clean.

§8 pre-push grep checks: STUB DATA 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