Sign in to edit tickets from this page.

← all tickets · home

get_turn supports include_events=true

resolved 274015f0-0107-4ea1-82df-3e052972467b

created_at
2026-04-23
updated_at
2026-04-24
code_context
src/mcp.rs, src/persistence.rs
priority
P2
ticket_type
feature
parent
8894dd80
resolved_at
2026-04-24
resolution
accepted

Body

CONTEXT

Child of 8894dd80 (model adjustments for the web UI). See that parent ticket for motivation, non-gaps, out-of-scope list, and parallelization map. This ticket is narrowly scoped to Gap 2.

================================================================ THE CHANGE

handle_get_turn in src/mcp.rs currently returns:

{ "message": "Turn N at simulation_time T.", "turn_ref": "turn_NNNNNN", "state": }

Add an optional include_events: bool arg. When true, the response gains a new top-level events field containing every audit event whose turn field equals this turn number, in _seq order (ascending — chronological).

When include_events is absent or false, the response is byte-identical to today's. This change is strictly additive for existing callers.

================================================================ WHAT'S IN THE EVENTS ARRAY

All events for turn == N, regardless of attempt_status. This means failed-attempt events are included too — adjudication_rejected events, and the attempt_failed terminator when an attempt did not commit. The view for the turn page wants the full story, including retries.

Do NOT filter by attempt_status. Do NOT apply the include_failed default-false that get_events uses — get_turn(include_events=true) is asking for "everything that happened while the system was trying to produce this turn," which by definition includes the failed attempts before (or leading up to) the committed one.

Order by _seq ascending. Do not re-sort by event_type or attempt_status or anything else — _seq is the canonical ordering.

================================================================ IMPLEMENTATION NOTES

The audit log is at events.jsonl under the world dir; accessible via AuditLog in src/persistence.rs. Whatever read path get_events currently uses is the same one this handler wants. Single pass, filter by turn == N, collect.

Turn number comes from parsing the turn_ref (strip "turn_" prefix, parse as u64) — same trick the existing handler uses.

Edge case: if turn_ref refers to a turn that exists in the turn chain but has no audit events (shouldn't happen for any turn >= 1, but turn 0 is the seed and emits no events), return events: [] rather than erroring.

================================================================ WIRE CONTRACT

Request: { "world_slug": "ant-verify", "turn_ref": "turn_000001", // OR "turn": 1, // existing turn/turn_ref "include_events": true // NEW, optional, default false }

Response when include_events: true: { "message": "Turn 1 at simulation_time ...", "turn_ref": "turn_000001", "state": { ... }, "events": [ { "_seq": 1, "turn": 1, "event_type": "perception_emitted", ... }, { "_seq": 2, "turn": 1, "event_type": "intent_formed", ... }, { "_seq": 3, "turn": 1, "event_type": "intent_adjudicated", ... }, { "_seq": 4, "turn": 1, "event_type": "turn_complete", ... } ] }

Response when include_events is absent or false: unchanged from today.

================================================================ TESTING

Add test: seed a world, run a turn, call get_turn(turn=1) without the flag — assert no events field in response. Call again with include_events: true — assert events is a non-empty array, events are in ascending _seq, every event's turn field equals 1.

If the suite has a test that induces an adjudication retry (even via a mocked router; but per prior guidance tests against the live router are fine), assert that adjudication_rejected events appear in the array for the relevant turn.

================================================================ ACCEPTANCE

================================================================ SCOPE DISCIPLINE

Proposed resolution

Implemented, committed, merged, deployed, and smoke-verified in production.

What changed (src/mcp.rs only):

Unchanged: get_events default behavior; kernel; persistence write path; any other handler.

Receipts:

Deploy + production smoke:

Child of 8894dd80. I am not confirming — over to you.

History (4 events)

Sign in as a human to drive this ticket from the page, or use the MCP tools.