This repository was archived by the owner on May 26, 2026. It is now read-only.
feat(kora): KR-AGENT-ACTIVITY-PANEL — recent agent calls lens (stub)#114
Merged
rafe-walker merged 1 commit intoMay 22, 2026
Merged
Conversation
Operator observability for the /mcp endpoint — surfaces recent
agent-driven MCP tool calls (claude_pm, kora drones, etc.) so the
operator can see which agents are touching Kora and whether their
calls succeeded, were capability-denied, or failed.
Single-PR scope:
* GET /api/agent-activity/recent stub — 5 representative calls
deliberately spanning ok / capability_denied / denied_prod_only
so the first look at the panel surfaces what failure modes
actually look like. stub:true keeps the FE banner visible.
* AgentActivityPanel.tsx — stats strip + status filter pills +
caller dropdown + expandable timeline.
* Dashboard card #8 (Workflow icon — Activity is reserved by
/operational-state). Layout: keeps lg:grid-cols-3 per PM
preference; row 2 becomes 3+3+2 instead of bumping to cols-4.
Headline goes destructive when denied >10 OR any
handler_error/timeout in the visible window.
3-layer security contract (standardizing the pattern from
KR-WEBHOOK-EVENTS #109):
1. result_summary is a SHORT TEXTUAL summary — never raw JSON.
Backend test pins via _JSON_LEAK regex against {/}/[/].
2. caller_actor_kind is a LABEL — never bearer-token or
token-hash shaped. Backend test pins via _HEX_TOKEN_PIN
(≥16 hex) + _BASE64_TOKEN_PIN (≥20 b64) regexes, plus a
walk-the-whole-payload sweep that catches future drift.
3. TS interface declares both fields as plain strings with the
wire contract documented inline — no raw_payload or
auth_token field exists on AgentCall.
CC#3's KR-MCP-RUNTIME-SURFACE ST2 swaps the stub body for the
real per-call ledger maintained by kora_cli/listeners/mcp.py.
Shape is pinned by the new test suite so the FE shipping off this
PR keeps rendering correctly during the cut-over.
Tests:
* tests/kora_cli/test_web_server_agent_activity.py — 10 tests
covering shape, status diversity, both security regex guards
(per-field + whole-payload), by_caller_24h reconciliation,
cron-regression sanity.
* Full admin-panel regression: 202/202 across 19 suites
(heartbeat, mcp_clients, webhook_events, agent_activity,
health_rollup, operational_state, cost_state, boot_status,
dr_state, sea_tickets, kora_control, runbooks, charter,
capabilities, chain_events, diag_bundle, mcp, host_header,
gateway_identity).
* tsc --noEmit + vite build both clean.
Diag bundle note: the existing /api/diag-bundle doesn't include
heartbeat / mcp_clients / webhook_events either — keeping
agent_activity out of it too, separate cleanup bucket for
re-syncing the bundle source list.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 tasks
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
Operator observability for the
/mcpendpoint — a panel surfacingrecent agent-driven MCP tool calls so the operator can see which
agents (claude_pm, kora drones, etc.) are touching Kora and whether
their calls succeeded, were capability-denied, or failed outright.
Pairs with CC#3's KR-MCP-RUNTIME-SURFACE bucket — ST2 will swap the
stub
/api/agent-activity/recentbody for the real per-call ledgermaintained by
kora_cli/listeners/mcp.py. Shape is pinned by thenew test suite so the FE shipping in this PR keeps rendering during
the cut-over.
What's in here
GET /api/agent-activity/recentreturning 5representative calls deliberately spanning
ok/capability_denied/denied_prod_onlyso the operator's firstlook surfaces what failure modes look like.
stub: truekeeps theFE banner visible.
AgentActivityPanel.tsx(new): stats strip (total + per-callerbreakdown) + status filter pills + caller dropdown + expandable
timeline rows with
tool_name(mono) + caller badge + status pill/agent-activityroute + nav entry with theWorkflowicon(placed between
/webhook-eventsand/mcp-clientsper speclayout note).
Activityis reserved by/operational-statesoWorkflowis the semantic next-best — "agent-driven tool callsflowing through Kora".
lg:grid-cols-3per PM preference — row 2 becomes 3+3+2 insteadof bumping to
cols-4. Headline goes destructive whendenied > 10OR anyhandler_error / timeoutappears in thevisible window (mirrors WebhookEvents
dead_letter > 5rule).3-layer security contract
Standardizing the pattern from KR-WEBHOOK-EVENTS #109 (PM-validated
"walk-the-whole-payload guard is exactly the right shape"):
result_summaryis a SHORT TEXTUAL summary — never raw JSONpayloads. Backend test pins via
_JSON_LEAKregex against{/}/[/].caller_actor_kindis a LABEL — never bearer-token ortoken-hash shaped. Backend test pins via
_HEX_TOKEN_PIN(≥16hex chars) +
_BASE64_TOKEN_PIN(≥20 b64 chars) regexes, plus awalk-the-whole-payload sweep that catches future drift if an
`auth_token_hash` field is ever added to a call entry or a
session id gets stuffed into `result_summary`.
AgentCalldeclaresthe fields as plain strings with the wire contract documented
inline; no
raw_payloadorauth_tokenfield exists on the type.Test plan
tests/kora_cli/test_web_server_agent_activity.py— 10 tests:shape, 5-call pin, status diversity, per-entry schema, JSON-leak
guard (per-field), token-shape guards (per-field + whole-payload),
by_caller_24h reconciliation, cron-regression sanity.
pnpm tsc --noEmitclean.pnpm buildclean./agent-activity, exercise filters, expandrows, confirm STUB banner + destructive tone trigger.
Notes
/api/diag-bundledoesn't includeheartbeat / mcp_clients / webhook_events either — keeping
agent_activity out of it too for now, separate cleanup bucket
re-syncs the bundle source list across all newer panels at once.
/admin/agent-activityandpages/admin/— using the establishedflat
/agent-activityroute +web/src/pages/location to matchevery prior panel in this branch.
🤖 Generated with Claude Code