Skip to content

feat(tui): consume odek turn_started frame for card reconciliation - #70

Merged
jkyberneees merged 1 commit into
mainfrom
feat/turn-started-frame
Sep 3, 2026
Merged

feat(tui): consume odek turn_started frame for card reconciliation#70
jkyberneees merged 1 commit into
mainfrom
feat/turn-started-frame

Conversation

@jkyberneees

Copy link
Copy Markdown
Contributor

What

Consumes odek's new turn_started wire frame — the implementation of
TEMP_ODEK_TURN_STARTED_TASKS.md (verified against the upstream code:
frame lands after the session frame, every turn, initiated
{system, operator}, server-gated, plus R3 turn_id tagging on
streamed frames).

Behavior

Turn Signal Card
Wake (initiated: system) turn_started → stamped session frame → lazy fallback ⬡ odek · wake
Foreign operator turn (another client on this session) turn_started → lazy fallback plain remote card — now opens earlier (at announcement, not first stream)
bodek's own turn own send path; frame is a no-op existing card

Idempotency (R2): guards (cur() >= 0 \|\| busy) suppress replays and
live-turn arrivals. All three opening paths coexist — a turn must be
missed by all three to drop from the transcript.

R3 turn_id on streamed frames decodes into client.Event.TurnID but
does not yet drive UI state (no mid-turn attribution UI exists).

Tests (RED-first)

5 TUI tests (system → wake card, operator → plain card, replay
idempotency, own-turn no-op, busy suppression) + 2 client decode tests.
RED before the Event fields/handler existed, GREEN after. Full race
suite 7/7; vet/fmt clean. AGENTS.md + README synced.

odek now announces every turn with a dedicated turn_started frame
(turn_id, initiated=system|operator) right after the session frame —
per the TEMP_ODEK_TURN_STARTED_TASKS.md spec implemented upstream.

bodek consumes it as the primary card-opening signal: system turns open
the wake-marked card, foreign operator turns (prompted from another
client on this session) open a plain remote card, replays and live-turn
arrivals are idempotently suppressed. The stamped session frame and the
lazy first-stream fallback stay as belt-and-suspenders — a turn must be
missed by all three paths to drop from the transcript. turn_id on
streamed frames (R3) decodes but does not yet drive UI state.
@jkyberneees

Copy link
Copy Markdown
Contributor Author

Closes #69 — implements the consumption side of the turn_started protocol (supersedes the lazy-open heuristic as primary signal; it remains as belt-and-suspenders fallback).

@jkyberneees
jkyberneees merged commit 063fc04 into main Sep 3, 2026
7 checks passed
@jkyberneees
jkyberneees deleted the feat/turn-started-frame branch September 3, 2026 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant