← Documentation indexdocs/superpowers/plans/2026-10-14-v3-issue-255.md

V3 Issue #255: Shared typed runtime events

Issue: #255 — Unify typed runtime events across execution and interfaces Requirements: R153–R160 Branch: Evan/v3-255-runtime-events, based on Evan/v3-236-execution-receipts Dependency: #236, PR #281 (open, unmerged; implementation is present on this branch) Delivery: one signed PR targeting the #236 branch; do not merge either PR.

Goal and boundaries

Establish one immutable runtime-owned event envelope and publisher, then adapt existing event callbacks and CLI/TUI/Web/SSE wire shapes at the interface edges. Preserve durable ownership of task, interaction, usage, and receipt state. Observers remain failure-isolated and cannot authorize work. Keep AgentEngine migration, database redesign, and provider continuation payloads out of scope.

The current compatibility path has a dictionary callback in openkyrozen/learning/failures.py, a ContextVar callback in openkyrozen/app/state.py, text events emitted throughout agent modules, and separate filtering/rendering logic in CLI/TUI/Web. Provider stream events already originate as typed provider records. The change will bridge these existing paths through the canonical publisher instead of adding another event store.

Indexed implementation plan

Task 1 — RuntimeEvent contract and publisher

Files: - Add openkyrozen/agent/events.py for immutable RuntimeEvent validation, identity generation, serialization, and the runtime event publisher. - Modify openkyrozen/agent/runtime.py, openkyrozen/app/state.py, openkyrozen/learning/failures.py, and agent exports. - Test new behavior in tests/test_runtime_events.py.

Contract: versioned immutable records contain event ID, kind, timestamp, sequence, user/workspace/session identity, optional turn/model-request/call/task IDs, and a validated defensive JSON payload. A publisher owns monotonic sequence numbers per turn, isolates observer exceptions, and produces the existing dictionary shape only through a named compatibility adapter. Runtime callbacks receive on_runtime_event; on_event remains compatible.

Task 2 — Correlate turn, model, tool, approval, usage, and task events

Files: - Modify openkyrozen/agent/loop.py, openkyrozen/agent/initial_response.py, openkyrozen/agent/action_rounds.py, openkyrozen/agent/executor.py, openkyrozen/agent/protocol.py, and openkyrozen/agent/modes.py. - Modify the shared provider boundary in openkyrozen/providers/calls.py and openkyrozen/providers/retry.py only where correlation must cross bounded workers. - Modify approval emit/resolve paths in openkyrozen/security/ and durable plan/task event adapters in openkyrozen/tasks/. - Test in tests/test_runtime_events.py, tests/test_execution_receipts.py, tests/test_provider_stream_events.py, and task/approval suites.

Task 3 — Native text pass-through and isolated legacy protocol adapter

Files: - Modify openkyrozen/agent/types.py, openkyrozen/agent/response_recovery.py, and openkyrozen/agent/initial_response.py to route text protocol handling through an explicit legacy adapter. - Modify affected compatibility callers and provider/runtime tests.

Task 4 — CLI, TUI, Web, SSE adapters and final acceptance

Files: - Modify CLI event rendering under openkyrozen/interfaces/cli/. - Modify openkyrozen/interfaces/tui/turns.py and its protocol tests. - Modify openkyrozen/interfaces/web/chat.py, relevant Web chat modules, and SSE tests. - Update runtime event docs and exported API surfaces; do not change persistence schema.

Validation record

Result Evidence
PASS Python 3.12: full make test (798 tests; browser tests enabled, no skips); focused runtime/provider/SSE/TUI suite (53 tests). Python 3.13: focused runtime/provider/SSE/TUI suite (37 tests). Final diff passed make check, make lint, make docs-check, make agent-acceptance, make subagent-acceptance, and make tui-acceptance. Independent review findings fixed and covered by regressions.
FAIL None after fixes.
BLOCKED GitHub PR checks and signature verification remain pending publication.

Compatibility and risks

Existing on_event consumers retain dictionaries through a compatibility adapter. CLI/TUI/Web/SSE wire fields remain compatible while sourcing them from canonical events. Text protocol filtering remains available only at the legacy boundary; native response text is not inspected for control syntax. Event payloads are JSON-safe, bounded/redacted projections. Durable stores and usage ledgers remain the sources of truth. Cancellation and observer failures must not alter execution outcomes.