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

chore(kora): KR-FRONTEND-CLEANUP — tsc drift + stale mcp_clients tests#125

Merged
rafe-walker merged 1 commit into
feature/phase2-upgradesfrom
feat/kora-KR-FRONTEND-CLEANUP
May 22, 2026
Merged

chore(kora): KR-FRONTEND-CLEANUP — tsc drift + stale mcp_clients tests#125
rafe-walker merged 1 commit into
feature/phase2-upgradesfrom
feat/kora-KR-FRONTEND-CLEANUP

Conversation

@rafe-walker

Copy link
Copy Markdown
Owner

Summary

Two-part cleanup bucket addressing pre-existing drift flagged in PRs #117 / #120 / #121.

Part A — tsc enum drift fix (4 errors → 0)

CC#1's KR-FEAT-HEARTBEAT ST2 (#118) added 4 fields to the heartbeat surface; FE consumers in HeartbeatPanel.tsx + DashboardPage.tsx didn't handle the additive shape, leaving tsc -b with 4 errors on bare feature/phase2-upgrades.

Fixes:

  • HeartbeatStatus gained "unknown" (probe pending — cold-start / auth-missing / in-flight). Panel now renders it as a muted-outline pill with "probe pending" label + CircleDashed icon. Distinct from "unhealthy" — pending is not failing.
  • HeartbeatService.last_check_at became nullable. formatTimestamp / formatRelative helper signatures now accept string | null; null path renders "never checked" (matches the MCP-clients health-display convention from feat(kora): KR-MCP-CLIENTS-HEALTH-DISPLAY — render last_check_at + last_error #117 to keep the operator's mental model consistent across panels).
  • HeartbeatService.error: string | null surfaced in the expanded detail view as a destructive-toned <pre> block (mirrors MCP-clients last_error). Plain-text rendering; no dangerouslySetInnerHTML — probe output is untrusted.
  • HeartbeatServicesResponse.cache_warming: boolean. Panel renders "Probes warming up…" Hourglass banner above the services list. Dashboard card mutes the headline tone + appends · warming to suppress false-outage signal during daemon cold-start.

Also: dashboard counts.unknown bucketed separately from healthy/degraded/unhealthy so the operator can distinguish "scheduler not done yet" from "service down".

Part B — investigation only (task NousResearch#269 closed; task NousResearch#265 remains)

Root cause is NOT stale assertions (Part B hypothesis was incorrect). All 13 failures + 5 errors collapse on a single:

ModuleNotFoundError: No module named 'slowapi'

raised when the test imports kora_cli.web_server → which transitively imports kora_cli.listeners.__init__kora_cli.listeners.webhooksslowapi. That import is unconditional at the package __init__ level.

The slowapi package is declared in pyproject.toml's web extra (fastapi==0.133.1, uvicorn[standard]==0.41.0, slowapi>=0.1.9), but the test environment only installs --extra dev — so slowapi is missing in CI/dev test runs.

Confirmed: running uv sync --frozen --extra dev --extra web + pytest passes 19/19 of the mcp_clients tests. No assertion shape is stale.

This is the existing task NousResearch#265 (slowapi). Per the bucket spec's "Genuine bug → STOP" rule (§1 Part B) and §3 non-scope ("Investigating tasks NousResearch#265 (slowapi) — separate"), NOT applying the fix here. Possible fixes for NousResearch#265:

  • (a) Add slowapi>=0.1.9 to the dev extra in pyproject.toml (1-line; tests then run from a single extra).
  • (b) Add the web extra to CI test runs alongside dev.
  • (c) Make slowapi imports lazy in kora_cli/listeners/webhooks.py so listeners/__init__.py doesn't fail at import time when only test/dev deps are installed.

(a) is simplest; recommend that path for the NousResearch#265 PR.

Test plan

  • tests/kora_cli/test_heartbeat_panel_drift_fixes.py — 11 new source-pin tests: source files exist, "unknown" arm in STATUS_TONE / STATUS_LABEL / StatusIcon switch, dashboard counts include "unknown", formatTimestamp + formatRelative accept string | null with "never checked" null path, service.error rendered as JSX child (no dangerouslySetInnerHTML), cache_warming banner + dashboard headline tone suppression.
  • Full admin-panel regression: 260/260 across 22 suites (including the previously-failing mcp_clients suite, which passes once --extra web is installed).
  • pnpm tsc -b clean (was 4 errors → now 0).
  • pnpm build clean.
  • Manual smoke: load /heartbeat with an "unknown" status seeded, confirm "probe pending" pill + warming banner + error block.

Refs

🤖 Generated with Claude Code

Part A — tsc enum drift fix (4 errors → 0)
============================================

CC#1's KR-FEAT-HEARTBEAT ST2 (PR #118) added 4 fields to the
heartbeat surface; FE consumers in HeartbeatPanel.tsx +
DashboardPage.tsx didn't handle the additive shape, leaving
`tsc -b` with 4 errors on bare feature/phase2-upgrades.

Fixes:
  * HeartbeatStatus enum gained "unknown" (probe pending —
    cold-start / auth-missing / in-flight). Panel now renders
    it as a muted-outline pill with "probe pending" label +
    a CircleDashed icon. Distinct from "unhealthy" — pending
    is not failing.
  * HeartbeatService.last_check_at became nullable. Helper
    signatures formatTimestamp / formatRelative now accept
    `string | null`; null path renders "never checked"
    (matches the MCP-clients health-display convention from
    PR #117 to keep the operator's mental model consistent).
  * HeartbeatService.error: string | null surfaced in the
    expanded detail view as a destructive-toned <pre> block
    (mirrors MCP-clients last_error). Plain-text rendering;
    no dangerouslySetInnerHTML — probe output is untrusted.
  * HeartbeatServicesResponse.cache_warming: boolean. Panel
    renders "Probes warming up…" Hourglass banner above the
    services list. Dashboard card mutes the headline tone +
    appends "· warming" to suppress false-outage signal
    during daemon cold-start.

Also: dashboard counts.unknown bucketed separately from
healthy/degraded/unhealthy so the operator can distinguish
"scheduler not done yet" from "service down".

Part B — test_web_server_mcp_clients.py: investigation only
============================================================

Root cause is NOT stale assertions (Part B hypothesis was
incorrect). All 13 failures + 5 errors collapse on a single
`ModuleNotFoundError: No module named 'slowapi'` raised when
the test imports `kora_cli.web_server` → which transitively
imports `kora_cli.listeners.__init__` → `kora_cli.listeners.
webhooks` → `slowapi`. That import is unconditional at the
package __init__ level.

The `slowapi` package is declared in pyproject.toml's `web`
extra (`fastapi==0.133.1`, `uvicorn[standard]==0.41.0`,
`slowapi>=0.1.9`), but the test environment only installs
`--extra dev` — so slowapi is missing in CI/dev test runs.

Confirmed: running `uv sync --frozen --extra dev --extra web`
+ pytest passes 19/19 of the mcp_clients tests. No assertion
shape is stale.

This is the existing task NousResearch#265 (slowapi). Per the bucket
spec's "Genuine bug → STOP" rule, and §3 non-scope
("Investigating tasks NousResearch#265 (slowapi) — separate"), NOT
applying the fix here. Possible fixes for NousResearch#265:

  (a) Add `slowapi>=0.1.9` to the `dev` extra in pyproject.toml
      (1-line; tests then run from a single extra).
  (b) Add the `web` extra to CI test runs alongside `dev`.
  (c) Make slowapi imports lazy in kora_cli/listeners/webhooks.py
      so listeners/__init__.py doesn't fail at import time
      when only test/dev deps are installed.

(a) is simplest; recommend that path for the NousResearch#265 PR.

Tests
=====

  * tests/kora_cli/test_heartbeat_panel_drift_fixes.py — 11
    new source-pin tests: source files exist, "unknown" arm
    in STATUS_TONE / STATUS_LABEL / StatusIcon switch,
    dashboard counts include "unknown", formatTimestamp +
    formatRelative accept string|null with "never checked"
    null path, service.error rendered as JSX child (no
    dangerouslySetInnerHTML), cache_warming banner + dashboard
    headline tone suppression.
  * Full admin-panel regression: 260/260 across 22 suites
    (including the previously-failing mcp_clients suite,
    which passes once --extra web is installed).
  * `pnpm tsc -b` clean (was 4 errors → now 0).
  * `pnpm build` clean.

Refs: PRs #108 (KR-MCP-CLIENTS-FLIP) + #113 (KR-MCP-CONSUMPTION
ST2) + #118 (KR-FEAT-HEARTBEAT ST2); task NousResearch#269 (closed by
Part B investigation: dependency issue, not stale assertions);
task NousResearch#265 (slowapi dependency — open, recommended fix above).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rafe-walker rafe-walker merged commit 6adaea6 into feature/phase2-upgrades May 22, 2026
@rafe-walker rafe-walker deleted the feat/kora-KR-FRONTEND-CLEANUP branch May 22, 2026 23:46
rafe-walker added a commit that referenced this pull request May 23, 2026
Closes BOTH task NousResearch#265 (slowapi placement) AND task NousResearch#269 (mcp_clients test failures — confirmed downstream of same import-chain issue per CC#2 investigation in PR #125).

- pyproject.toml: slowapi==0.1.9 moves from [web] optional-deps to runtime deps (next to aiosmtplib pin that set the precedent in PR #124).
- uv.lock regenerated.
- Exact-equals pin per the security policy in the dependencies-block header (2026-05-12 Mini Shai-Hulud response).

Base-install verification (uv sync --frozen --extra dev, NO --extra web): mcp_clients 19/19 pass (was 13 fail + 5 err); full admin-panel regression 271/271 across 23 suites.
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