This repository was archived by the owner on May 26, 2026. It is now read-only.
feat(KR-P2-I-integration ST2): chain-event emit on operational-state transitions#36
Merged
Merged
Conversation
…transitions
Adds the listener that writes a chain event for every transition
through the OperationalStateHolder. PM-verified vocabulary against
foundation/0159_kora_r41_operational_state_event_vocabulary.sql on
isokron-prod (2026-05-21):
* ALWAYS emit ``kora.operational_state.transitioned`` — single
generic edge event per substrate-team design. Payload carries
from/to primary_state, new claim_permission, sorted
degradation_reasons, and trigger.
* ADDITIONALLY emit when a per-trigger literal exists:
- (BOOTING → READY, "all §9.2 gates pass") → kora.boot.ready
- (BOOTING → STOPPED, "invariant gate failure …") →
kora.boot.failed
- (any → PAUSED, trigger contains "cost 100%") →
kora.paused.cost_limit
* Operator-pause and substrate-pause: only the generic event.
Per-trigger literals can land in a follow-on substrate vocab
migration if cockpit needs the signal.
Fail-LOUD: preflight failures (missing provider / connection /
workspace_id) and substrate-side raises both surface as
OperationalStateEmitError. The state-machine listener-error
handler logs but doesn't roll back — listeners are observability,
not policy — so a broken emit is loudly logged but the state
machine keeps moving.
agent/operational_state_emit.py exposes:
- GENERIC_TRANSITION_EVENT, BOOT_READY_EVENT, BOOT_FAILED_EVENT,
PAUSED_COST_LIMIT_EVENT — constants matched against
foundation/0159
- emit_state_transition(provider, from, to, trigger) — async
callable, fail-LOUD
- make_emit_listener(provider) — factory returning a
StateTransitionListener; ST3 wires this into the holder at
provider init
Tests (tests/test_operational_state_emit.py): 16 cases covering
payload shape, per-trigger literal selection (incl. lenient
substring match for varied caller wording), the BOOTING → STOPPED
disambiguation (invariant-failure vs STOP-KORA L4/L5), fail-LOUD
preflight (None provider, missing connection, workspace_id raise
or empty), generic-plus-extra dual-emit, substrate-failure
propagation, and the make_emit_listener factory.
Builds on ST1 (#32). ST3 will land the wire-in.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Replaces PR #33 (auto-closed when ST1 base branch was deleted post-merge).
ST2 of KR-P2-I-integration cascade. Adds agent/operational_state_emit.py: always-emit kora.operational_state.transitioned + conditional per-trigger literals (kora.boot.ready / kora.boot.failed / kora.paused.cost_limit) matching substrate-team's foundation/0159 source-of-truth vocab. Fail-LOUD via OperationalStateEmitError. 16 unit tests.
Rebased onto main; #32 squash-merged as 06e27e4.