Skip to content

fix(otel): emit extraction_tier + genre + world on TurnComplete event#409

Merged
slabgorb merged 1 commit intodevelopfrom
fix/playtest-2026-04-11-otel-tier-field
Apr 11, 2026
Merged

fix(otel): emit extraction_tier + genre + world on TurnComplete event#409
slabgorb merged 1 commit intodevelopfrom
fix/playtest-2026-04-11-otel-tier-field

Conversation

@slabgorb
Copy link
Copy Markdown
Owner

Summary

Playtest 2026-04-11 hotfix for two adjacent OTEL dashboard bugs that share the same root cause: the dashboard's TimelineTab reads from the TurnComplete event, but several required fields were missing.

Bug 1 (low) — "Tier: ?": `extraction_tier` was emitted on `AgentSpanClose` (dispatch/mod.rs:1127) instead of `TurnComplete`. Wrong event. Net result: every Turn Details panel showed `Tier: ?`.

Bug 2 (medium) — Turn # collision: Two sessions in the same world both showed `#1` rows in the timeline. `turn_id` resets per session but the event didn't carry enough metadata to distinguish them.

Fix

Add three fields to the TurnComplete WatcherEventBuilder in `telemetry.rs::record_turn_telemetry`:

  • `extraction_tier` (closes Bug 1)
  • `genre` (enables session grouping)
  • `world` (enables session grouping)

`(player_id, genre, world)` is now a stable session identifier the dashboard can use to draw session dividers. Companion UI fix in slabgorb/sidequest-ui will consume these fields to detect session boundaries by watching for backward turn_id resets within a (player_id, genre, world) bucket.

Test plan

  • 3 source-inspection tests in `turn_complete_telemetry_playtest_2026_04_11.rs`:
    1. extraction_tier present + sourced from result.prompt_tier
    2. genre and world present + sourced from ctx
    3. All existing fields still present (regression guard)
  • `cargo build -p sidequest-server` clean
  • `cargo test -p sidequest-server --test turn_complete_telemetry_playtest_2026_04_11` — 3/3 pass
  • OQ-1 verifies after merging both this PR and the companion UI PR: Open `#/dashboard` → play any turn → expect `Tier: full` or `Tier: delta` (not `Tier: ?`). Play 2 sessions in the same world → expect a visual session divider in the timeline between them.

Needs restart

Yes — API restart required.

🤖 Generated with Claude Code

Playtest 2026-04-11 reported two adjacent OTEL dashboard bugs that share
the same root cause: the dashboard's TimelineTab reads its data from the
TurnComplete event in telemetry.rs::record_turn_telemetry, but several
fields it depends on were missing from that event.

Bug 1 — "Tier: ?" in Turn Details panel:
  The extraction_tier value (full / delta per ADR-066) was being emitted
  on the AgentSpanClose event in dispatch/mod.rs:1127, but the dashboard
  reads it from the TurnComplete fields. Wrong event. Net result: every
  Turn Details panel showed `Tier: ?` because the field simply didn't
  exist on the event the UI was reading. This made it impossible to tell
  during a playtest whether a turn was running on Full or Delta tier —
  critical for diagnosing prompt-cost regressions.

Bug 2 — Turn # collides across sessions:
  Two different sessions in the same genre/world both showed `#1 narrator`
  rows in the Timeline, mingled together with no way to tell them apart.
  turn_id resets per session, but the TurnComplete event didn't carry
  enough metadata for the client to group rows by session. (player_id
  alone is insufficient — same player can play the same world twice.)

Fix: add three fields to the TurnComplete WatcherEventBuilder:
- extraction_tier — sourced from result.prompt_tier (closes Bug 1)
- genre — sourced from ctx.genre_slug (enables session grouping)
- world — sourced from ctx.world_slug (enables session grouping)

Together (player_id, genre, world) form a stable session identifier the
dashboard can use to draw session dividers. The companion UI fix in
sidequest-ui will consume these fields to detect session boundaries when
turn_id resets backwards in the timeline.

Regression tests (turn_complete_telemetry_playtest_2026_04_11.rs):
1. extraction_tier field present and sourced from result.prompt_tier
2. genre and world fields present and sourced from ctx
3. All existing dashboard-required fields still present (regression
   guard so a future refactor can't silently drop one)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@slabgorb slabgorb merged commit 82bff65 into develop Apr 11, 2026
@slabgorb slabgorb deleted the fix/playtest-2026-04-11-otel-tier-field branch April 11, 2026 12:50
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