This repository was archived by the owner on May 26, 2026. It is now read-only.
feat(kora): KR-FE-DASHBOARD-SNAPSHOT-WIRE — $0-cost dashboard via /api/snapshot#162
Merged
rafe-walker merged 1 commit intoMay 24, 2026
Conversation
…i/snapshot
Per the unified-operator-interface lens + cheap-substrate thesis
(feedback-opus-escalation-must-be-earned): DashboardPage now
tries the $0 daemon snapshot first on page load, projects the
fields the snapshot covers cleanly, and only fans out to live
endpoints for the fields where projection would mislead the
operator. Force-refresh button gives the explicit "I want live"
path. Cost-economy thesis made visible via the freshness badge.
Shifted to snapshot (2 of 4 spec-listed fields)
================================================
* operational — snapshot.operational_state.{primary, paused,
pause_reason} maps cleanly to OperationalStateResponse's
{primary_state, is_degraded, claim_permission} fields the
OperationalCardBody consumes. claim_permission defaults via
paused → "none" / not paused → "normal" (valid enum values
per api.ts:1004 ClaimPermission).
* alerts — snapshot.alerts.{active_count, by_severity,
by_category} populates AlertsResponse's {total_active,
by_severity}; per-alert array projected empty (snapshot
doesn't carry it). AlertsBanner uses total_active for
visibility check + falls through to aggregate-hash for
dismissal — change documented inline in the banner.
KEPT on fan-out (2 of 4 spec-listed fields)
============================================
Per spec §2(b) "If field types don't line up cleanly, prefer to
leave the existing fan-out call for that field rather than
coerce." Coercion would actively mislead operator:
* cost — snapshot.cost_ladder has {current_tier,
monthly_budget_pct_used, model_default} but LACKS
spent_to_date_usd + credit_pool_usd which CostCardBody
renders PROMINENTLY ($ figures). Defaulting to $0 / $0
would scream "no budget used" — actively misleading.
* health — snapshot.service_health is SaaS-dependency health
(vercel/sentry/doppler/supabase/fly), NOT Kora's own
control_plane / worker daemon health. HealthHero renders
overall/control_plane/worker; the semantic mismatch means
a derived "any service unhealthy → overall unhealthy"
projection would conflate dep-health with daemon-health.
Anti-projection tests pin both (test_dashboard_does_not_project_
cost_from_snapshot + test_dashboard_does_not_project_health_from_
snapshot) so a future refactor that tries the coercion gets
caught at the test gate.
Wired (per spec §3 acceptance)
================================
* api.getSnapshot() wrapper with typed
SnapshotResponse | SnapshotUnavailable union (caller
branches on `"error" in resp`)
* loadInitial() tries snapshot first; falls back to full
fan-out on `{error: "no_snapshot"}` OR exception (network /
5xx). Snapshot success: project ops + alerts, then fan out
the remaining 17 fields (cost, health, sea, control, boot,
dr, capabilities, charter, recentEvents, runbooks,
heartbeat, mcpClients, webhookEvents, agentActivity,
slackDM, email, reasoning).
* forceFullLiveRefresh() bypasses snapshot, runs full fan-out.
* Per-card retry buttons unchanged; loadOne tracks live
overrides — when a snapshot-projected field gets refreshed
via per-card button, badge counts it for the "mixed"
sub-mode.
FreshnessBadge component (new)
================================
web/src/components/FreshnessBadge.tsx — 4 visual states:
* snapshot — "Snapshot from N min ago · $0 cost view"
(success-toned border)
* live — "Live (just refreshed) · live fetch"
(neutral border)
* unavailable — "Live fetch · backend snapshot unavailable"
(muted; no shame about the fallback)
* mixed — "Snapshot from N min ago · K field(s) force-
refreshed · mixed cost view" (warning-toned)
Force-refresh button always present. Hover tooltip shows the
underlying ISO timestamp (computed_at for snapshot mode; last
live-fetch time for live mode) — operator can grep forensically.
NOTE: timestampAbsoluteUtc inlined locally (KR-FE-OPS-QUALITY-
PASS #155 — which exports it from panelHelpers — hasn't merged
into this branch's base). Follow-on PR can swap to the shared
helper once #155 lands.
AlertsBanner snapshot-compatibility patch
==========================================
Banner now hides on `data.total_active === 0` instead of
`data.alerts.length === 0` so the snapshot path (empty per-alert
array, but total_active > 0) still surfaces the banner.
Dismissal hash falls through from id-set hash to aggregate-shape
hash (`agg:{total_active}:{critical}:{warning}:{info}`) when the
per-alert array is empty — re-dismissal triggers on aggregate
shape change so operator doesn't get silenced across new alert
additions just because we're on the $0 path.
Tests (tests/kora_cli/test_dashboard_snapshot_wire.py — 17 tests)
=================================================================
Source-pin tests (no FE component-runner per the established
CC#2 pattern):
* api.getSnapshot wrapper signature + URL
* SnapshotResponse + SnapshotUnavailable types declared with
required field set
* FreshnessBadge: component exists, 3-mode union, Force-
refresh button, $0-cost-view literal, mixed mode marker
* DashboardPage projects operational + alerts (positive pin)
* DashboardPage does NOT project cost + health (anti-
projection pin to lock the spec-§2(b) discipline)
* loadInitial calls api.getSnapshot FIRST
* Snapshot unavailable → fanOutAll fallback path
* forceFullLiveRefresh sets mode="live" + bypasses snapshot
* AlertsBanner total_active check + aggregate-hash fall-through
Verification:
* 17/17 source-pin tests pass
* tsc -b clean
* vite build clean
* Screenshot rendered: web/docs/freshness-badge/states.png
(4 visual states + preview HTML for reproducibility)
Refs:
* rafe-walker/kora-docs 17_cc_bucket_prompts/KR-FE-DASHBOARD-SNAPSHOT-WIRE_zero_cost_dashboard.md
* PR #157 — snapshot infrastructure (GET /api/snapshot)
* PR #134 — AlertsPanel + AlertsBanner (the dismissal logic
being patched)
* Council R3 unified-operator-interface lens
* feedback-opus-escalation-must-be-earned (cost-economy
visibility thesis)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
rafe-walker
added a commit
that referenced
this pull request
May 24, 2026
…/errors (schema v4) (#170) snapshot.daemon_health section: overall_status + boot_at + uptime_seconds + per-listener health (14 listeners — actual inventory via grep) + recent_error_count_5min. Schema_version 3→4. 14-listener inventory: heartbeat_probes, snapshot, purelymail_client, probe_wake, mcp, email_inbound_imap, heartbeat, web, cost_telemetry, slack_client, mcp_consumption, webhooks, reasoning_engine, alert_notifier. Accessor reuse: current_coordinator() + DaemonCoordinator.get_status() + _startup_completed_at + read_audit_entries(since=...) all pre-existing. Wall-clock boot_at added (_startup_completed_wall_at + get_boot_at). v1 trade-off: per-listener last_event_at + consecutive_errors deferred — would touch 14 listener files with no consumer today; v1 stubs them 'unknown' so wire shape is forward-compatible (future bucket fills incrementally without breaking). Completes the snapshot v4 expansion. Unblocks CC#2 KR-FE-DASHBOARD-HEALTH-SNAPSHOT-SHIFT (HealthHero shift to snapshot — the second of PR #162's two anti-coercion holdouts). 22 new daemon_health tests + 47 existing snapshot tests + 182 cross-bucket regression + ruff clean.
4 tasks
rafe-walker
added a commit
that referenced
this pull request
May 24, 2026
…n holdouts (#174) 4-of-4 dashboard hero fields snapshot-driven on warm cache. Verified at DashboardPage.tsx:1270-1345 — loadInitial does NOT call api.getOperationalState / getCurrentAlerts / getCostState / getHealthRollup with fresh snapshot. PR #162 anti-projection tests FLIPPED (not deleted): test_dashboard_does_not_project_*_from_snapshot → test_dashboard_projects_*_from_snapshot with null-return + per-field fallback pins. New pins: badge surfaces N-of-M hero count + DASHBOARD_HERO_FIELD_COUNT===4 literal regression guard. K-DG drift caught + fixed: SnapshotResponse TS type was stale — missing cost_ladder.spent_to_date_usd + credit_pool_usd (#169) + the entire daemon_health section (#170). Added; required before projection helpers could compile. Per-card retry buttons + forceFullLiveRefresh still fan out by design (operator-triggered force paths). 19/19 tests pass, tsc + vite build clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Per the unified-operator-interface lens + cheap-substrate thesis (
feedback-opus-escalation-must-be-earned): DashboardPage now tries the $0 daemon snapshot first on page load, projects the fields the snapshot covers cleanly, and only fans out to live endpoints for the fields where projection would mislead the operator. Force-refresh button gives the explicit "I want live" path. Cost-economy thesis made visible via the freshness badge.Field shift table
snapshot.operational_state.{primary, paused, pause_reason}projects cleanly intoOperationalStateResponse.{primary_state, is_degraded, claim_permission}.claim_permissiondefaults viapaused → "none" / not paused → "normal"(valid enum values perapi.ts:1004).snapshot.alerts.{active_count, by_severity, by_category}populatesAlertsResponse.{total_active, by_severity}. Per-alert array projected empty (snapshot doesn't carry it). AlertsBanner patched to usetotal_active+ aggregate-hash dismissal fall-through.snapshot.cost_ladderhas{current_tier, monthly_budget_pct_used, model_default}but lacksspent_to_date_usd+credit_pool_usdwhichCostCardBodyrenders prominently ($ figures). Defaulting to $0/$0 would scream "no budget used" — actively misleading.snapshot.service_healthis SaaS-dependency health (vercel/sentry/doppler/supabase/fly), NOT Kora's owncontrol_plane/workerdaemon health.HealthHerorenders the daemon health; semantic mismatch means coercion would conflate dep-health with daemon-health.Net: 2 of 4 spec-listed fields shifted to snapshot, 2 kept on fan-out per spec §2(b) "prefer to leave the existing fan-out call for that field rather than coerce." Anti-projection tests pin both kept-on-fan-out decisions so a future refactor that tries the coercion gets caught at the test gate.
Freshness badge screenshot
States rendered (top → bottom):
"Snapshot from 2m ago · $0 cost view"with success-toned border"Live (just refreshed) · live fetch"with neutral border"Live fetch · backend snapshot unavailable"with muted tone"Snapshot from 2m ago · 1 field force-refreshed · mixed cost view"with warning toneHTML preview source:
web/docs/freshness-badge/preview.html(open in any browser to reproduce).What's in here
Backend:
/api/snapshotalready shipped in PR #157 — no backend changes in this PR.Frontend:
web/src/lib/api.ts—getSnapshot()wrapper +SnapshotResponse/SnapshotUnavailableTS typesweb/src/components/FreshnessBadge.tsx(new) — 4-state cost-economy indicator with Force-refresh buttonweb/src/components/AlertsBanner.tsx— snapshot-compat patch:total_activevisibility check + aggregate-hash dismissal fall-throughweb/src/pages/DashboardPage.tsx—loadInitial()(snapshot-first) +forceFullLiveRefresh()+ per-card live-override tracking + projection helpers (projectOperationalFromSnapshot,projectAlertsFromSnapshot)Per-card refresh unchanged for the operator: existing retry buttons still call
loadOne(field, fetcher). When that field was snapshot-projected,loadOneadds it to aliveOverridesSet, which drives the badge's "mixed" sub-mode counter.Notes
timestampAbsoluteUtcis inlined locally inFreshnessBadge.tsxbecause KR-FE-OPS-QUALITY-PASS (PR feat(kora): KR-FE-OPS-QUALITY-PASS — empty-state + TZ + show-more #155 — which exports it frompanelHelpers.ts) hasn't merged into this branch's base. Follow-on PR can swap to the shared helper once feat(kora): KR-FE-OPS-QUALITY-PASS — empty-state + TZ + show-more #155 lands.Reloadbutton still works — callsloadAll(true)which now goes throughloadInitial()so the operator gets the $0 experience on every Reload hit, not just initial mount.Test plan
tests/kora_cli/test_dashboard_snapshot_wire.py— 17 source-pin tests: wrapper signature, type declarations, FreshnessBadge component + 3-mode union + Force-refresh button +$0 cost viewliteral + mixed mode marker, positive projection pins (operational + alerts), anti-projection pins (cost + health stay on fan-out),loadInitialcalls snapshot first, fallback tofanOutAllon unavailable,forceFullLiveRefreshsetsmode="live", AlertsBannertotal_activecheck, aggregate-hash dismissal fall-through.pnpm tsc -bcleanpnpm buildcleanRefs
rafe-walker/kora-docs→17_cc_bucket_prompts/KR-FE-DASHBOARD-SNAPSHOT-WIRE_zero_cost_dashboard.mdGET /api/snapshot)feedback-opus-escalation-must-be-earned— cost-economy visibility thesis🤖 Generated with Claude Code