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

feat(KR-P2-SEA-PANEL): Sea_Tickets-assigned-to-Kora viewer panel against stub endpoint#31

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

feat(KR-P2-SEA-PANEL): Sea_Tickets-assigned-to-Kora viewer panel against stub endpoint#31
rafe-walker merged 1 commit into
mainfrom
feat/kora-KR-P2-SEA-PANEL

Conversation

@rafe-walker

Copy link
Copy Markdown
Owner

Summary

Read-only operator-side diagnostic panel for Sea_Tickets assigned to the Kora actor. Pairs with KR-P2-E (consumer loop, CC#1 — in flight) and goes in ahead of the wire-in so the UI is ready when E lands.

Endpoint (kora_cli/web_server.py)

GET /api/sea-tickets/kora-assigned — returns 4 status-grouped lists with stub: true:

section semantics
in_progress currently claimed and being worked (typically 0–1 for single-actor)
queued assigned, waiting for claim; next_eligible_at set ⇒ deferred
recently_resolved last N resolved (completed / released / failed_* / blocked_needs_operator / deferred_cost_limit)
failed_or_blocked currently in failed_terminal or blocked_needs_operator — operator intervention happens cockpit-side

No write-side endpoints — operator interventions on blocked tickets live in the cockpit's blocked_needs_operator action set (unblock / reassign / force_retry / cancel), not here.

Internal claim_fence_token idempotency token is intentionally never in the API shape (test guards against future drift).

Frontend (web/)

  • pages/SeaTicketsPage.tsx
    • In progress: prominent cards, pulsing live indicator, claim counters, claimed-at relative time
    • Queued: sorted criticality desc + assigned_at asc (matches G-8 priority); table with deferred-until call-out when next_eligible_at is in the future
    • Recently resolved: collapsible (default-collapsed); resolution badge + model-tier badge (opus/sonnet/haiku)
    • Failed or blocked: always visible; quiet styling when empty; failure-reason chips with counts; static note "Operator interventions happen in the cockpit, not here"
    • STUB banner renders only when stub: true — non-negotiable so a real outage never gets masked as sample data
  • lib/api.ts — typed Criticality / ModelTier / Resolution enums + 4 section interfaces + KoraAssignedSeaTicketsResponse
  • App.tsx/sea-tickets route + nav entry (Waves icon) between /operational-state and /analytics

Flip-over plan

When KR-P2-E lands and IsoKronMemoryProvider grows a get_assigned_sea_tickets(actor_id) -> AssignedSeaTickets helper, swap get_kora_assigned_sea_tickets body to project from that read and drop the stub flag. The page itself doesn't change — the stub banner disappears the moment stub is gone.

Test plan

  • tests/kora_cli/test_web_server_sea_tickets.py — 10/10 green, covers all six §5 scenarios + non-scope guard (claim_fence_token never in payload)
  • test_web_server_{operational_state,cron_profiles,host_header,mcp,gateway_identity}.py — 47/47 still green (regression sanity, 57 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 /sea-tickets, verify STUB banner renders, verify all 4 sections render with sample data, verify resolved section collapsible

Dependency notes

  • KR-P2-E (CC#1, in flight) wires Kora as a real Sea_Tickets consumer
  • IsoKronMemoryProvider.get_assigned_sea_tickets(actor_id) is the small helper PR that flips this from stub to real (after E)

🤖 Generated with Claude Code

…nst stub endpoint

Read-only diagnostic panel for what Kora's consumer loop is currently
working on: in-progress, queued (priority-ordered), recently resolved
(collapsed by default), and failed/blocked. Pairs with CC#1's KR-P2-E
(consumer loop) but goes in ahead of the runtime wire-in — the data
source is a hardcoded stub returning sample tickets for each section
with ``stub: true`` so the frontend renders a banner making it obvious
to operators that values are not real assignments. When KR-P2-E lands
and IsoKronMemoryProvider grows a ``get_assigned_sea_tickets(actor_id)``
helper, the endpoint body flips to a projection of that read; the page
itself doesn't change.

Backend (kora_cli/web_server.py):
  GET /api/sea-tickets/kora-assigned — read-only stub returning 4
  status-grouped lists. No POST/PUT/DELETE: operator interventions on
  blocked tickets happen via cockpit's blocked_needs_operator action
  set (unblock / reassign / force_retry / cancel), not here. The
  internal ``claim_fence_token`` idempotency token is intentionally
  never exposed in the API shape (test guards against future drift).

Frontend:
  - SeaTicketsPage.tsx — 4 sections by operational priority:
    * In progress: prominent cards with pulsing live indicator, claim
      counters, claimed-at relative time.
    * Queued: sorted criticality desc + assigned_at asc (matches G-8
      priority). Table view with deferred-until call-out when
      next_eligible_at is set.
    * Recently resolved: collapsible (default-collapsed). Resolution
      badge + model-tier badge (opus/sonnet/haiku).
    * Failed or blocked: always visible with quiet styling when empty.
      Failure-reason chips with counts. Static text reminding operator
      that interventions happen cockpit-side.
  - api.ts — typed Criticality / ModelTier / Resolution enums + 4
    section interfaces + KoraAssignedSeaTicketsResponse so a future
    Python-side enum drift surfaces at compile time.
  - App.tsx — /sea-tickets route + nav entry (Waves icon) between
    /operational-state and /analytics per spec §3.
  - Manual reload only; no auto-refresh (matches OPS-PANEL pattern).

Tests: tests/kora_cli/test_web_server_sea_tickets.py — 10 tests
covering all six §5 scenarios plus a non-scope guard
(claim_fence_token never in payload). 57/57 across full web_server
test suite pass. tsc -b + vite build clean.

§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