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

feat(KR-P2-CLEANUP ST3): CONTROL-PANEL flip-to-real + observed-state helper#60

Merged
rafe-walker merged 1 commit into
mainfrom
feat/kora-KR-P2-CLEANUP-st3-control-panel-flip
May 21, 2026
Merged

feat(KR-P2-CLEANUP ST3): CONTROL-PANEL flip-to-real + observed-state helper#60
rafe-walker merged 1 commit into
mainfrom
feat/kora-KR-P2-CLEANUP-st3-control-panel-flip

Conversation

@rafe-walker

Copy link
Copy Markdown
Owner

Summary

KR-P2-CLEANUP ST3 of 5. Flips /api/kora-control/observed-state from the hardcoded stub to a live read against the substrate's public.kora_control table, with the same uninitialized → stub + error fallback shape established by ST2.

plugins/memory/isokron/observed_kora_control.py (new, 227 LOC)

  • read_observed_kora_control(pool, workspace_id) — SELECTs ALL kora_control rows for the workspace. RLS-scoped via the app.workspace_id GUC (same convention as KoraControlReader.get_active_command). Groups in Python by lifecycle_state:
    • activecreated / visible_to_runtime / acknowledged / enforcing (no cap)
    • recently_enforcedlifecycle_state='enforced' (cap 10)
    • history — terminal states beyond the recent cap; superseded / expired / failed / escalated (cap 30)
  • get_observed_state_via_provider(provider) — resolves the workspace_id from the provider, runs the read on the IsoKron dedicated I/O loop. Returns None on any failure.

plugins/memory/isokron/kora_control_reader.py

  • Thin KoraControlReader.get_all_observed_commands() wrapper around get_observed_state_via_provider. Lives on the class for spec symmetry; the endpoint uses the module-level helper directly so it can avoid fabricating a fake kora_actor_id (the read is workspace-scoped only; actor_id is required only for transition_kora_control calls).

Endpoint flip — kora_cli/web_server.py

  • Live branch: returns real grouped data WITHOUT stub flag.
  • Uninitialized branch: stub-shape with stub: True + error field naming the cause.

Stub block extracted into _kora_control_observed_state_stub(error=...).

Tests — tests/kora_cli/test_web_server_kora_control.py (full rewrite, 205 LOC)

  • Uninitialized branch: stub-shape + stub:True + error field + per-entry shape sanity (kind ∈ {stop, reset}, lifecycle_state ∈ documented union, level ∈ 0..5)
  • Live branch (monkeypatched helper): real data passes through; no stub/error fields
  • Live read returning None: falls back to stub with the "substrate read returned None" error
  • Cron-regression sanity

Dependency note

This PR uses plugins.memory.isokron.active_provider (the singleton accessor) which is shipped by #57 (ST2). CI will fail with an import error until #57 merges; once it does, no rebase is needed (this branch is from main and will pick up the new module automatically).

Sub-task chain (this bucket — all independent off main)

ST PR Status
ST1 #55 open
ST2 #57 open (ships active_provider singleton)
ST3 this PR open (depends on ST2 merging for CI green)
ST4 next also depends on ST2
ST5 next independent test fix

🤖 Generated with Claude Code

…helper

Flips /api/kora-control/observed-state from the hardcoded stub to a
live read against the gateway-level IsoKronMemoryProvider, with the
same uninitialized → stub + error fallback shape as ST2.

plugins/memory/isokron/observed_kora_control.py (new):
  - read_observed_kora_control(pool, workspace_id) — SELECTs ALL
    kora_control rows for the workspace (RLS-scoped via the
    app.workspace_id GUC; same convention as KoraControlReader's
    active-command read). Groups in Python by lifecycle_state:
      * active            — created / visible_to_runtime /
                            acknowledged / enforcing (no cap)
      * recently_enforced — lifecycle='enforced' (cap 10)
      * history           — terminal states beyond the recent
                            cap; superseded / expired / failed /
                            escalated; capped at 30
  - get_observed_state_via_provider(provider) — resolves the
    workspace_id from the provider, runs the read on the IsoKron
    dedicated I/O loop, returns None on any failure.

plugins/memory/isokron/kora_control_reader.py:
  - Thin KoraControlReader.get_all_observed_commands() wrapper
    around get_observed_state_via_provider. Lives on the class for
    spec symmetry; production callers (the panel endpoint) use the
    module-level helper directly so they can avoid fabricating a
    fake kora_actor_id (the read is workspace-scoped only and
    actor_id is required only for transition_kora_control calls).

kora_cli/web_server.py:
  - GET /api/kora-control/observed-state now calls
    get_active_provider() (from ST2's singleton module) + delegates
    to the helper. Live branch returns real data WITHOUT ``stub``;
    uninitialized branch returns stub-shape with stub:True + error
    naming the cause. Stub block extracted into
    _kora_control_observed_state_stub for shape symmetry.

Tests (tests/kora_cli/test_web_server_kora_control.py) — full
rewrite to cover both branches:
  - Uninitialized branch: stub-shape + stub:True + error field +
    per-entry shape sanity (kind in {stop,reset}, lifecycle in the
    documented union, level ∈ 0..5)
  - Live branch: monkeypatch the helper to return canned data;
    assert real data passes through; neither stub nor error
    appears
  - Live read returning None: falls back to stub with the
    "substrate read returned None" error
  - Cron-regression sanity

Depends on ST2 (#57) — uses the ``active_provider`` singleton ST2
ships. PR can open in parallel; CI will go green once #57 merges.

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