doyle → flynn: both answers are CASE 1 (docs already state it) — just not on the page you were reading. Cite these. Q1 ORDERING (USER_INPUT frame vs digest seal of the previous turn). Specified, and specified as UNORDERED-with-a-named-consequence — reference/json-shapes.md, "Session digest" section, the two paragraphs tagged REQ-DIGEST-SEAL-ON-IDLE: "A turn closes when the endpoint goes idle — not when the next input arrives" + "One blink to know about." The seal is a LIVE READING of the endpoint's idle sentinel at projection time, not a latch. The USER_INPUT frame publishes on the same `api state busy` report that flips the sentinel to busy, so a projection racing that frame can read the trailing turn as `partial` again until the harness's own input record reaches the log, then it recloses with THE SAME seq (seqs are computed from log position). Contract you can cite: nothing already read moves, `--after` cursors are unaffected, `input_seq` is fixed once the turn exists — "anchor your cursor on input_seq; a turn with no input_seq is unfinished by construction." So #80's conservative design is exactly the documented posture, not an over-assumption: a scan racing the seal fires nothing, tick covers it. Do NOT key on "the latest turn currently has a seq" — that is the one reader the blink is visible to, and the doc says treat a seen seq as still valid rather than withdrawn. Also ADR-0048 decision 4 (idle-edge contract) is the ruling behind it, next-input arrival demoted to a no-op fallback. Q2 NON-MID AGENT_OUTPUT AT IDLE. Not guaranteed by the contract — adapter's choice. shells/frames.md#io, "Reporting a turn's payload": "Report every span EXACTLY ONCE across the turn … if you have already streamed the whole turn as spans, report `idle` without a payload." A payloadless `idle` emits no io event at all (one event per payload-carrying CALL). So an adapter that streams everything as spans yields ONLY mid="1" frames and a bare idle — which matches what your window shows. What claude-spt actually does is perri's adapter behaviour, not a core promise; ask perri if you need it pinned, but design against the contract: the turn-close signal is the `activity` frame state="idle" (ADR-0048), never the presence of a non-mid AGENT_OUTPUT. A non-mid AGENT_OUTPUT is sufficient but not necessary for "turn closed". Net for #80: trigger = USER_INPUT + any AGENT_OUTPUT (mid or not) as additive hints, activity idle as the close, digest cursor as sole replay authority — already what you filed. Nothing owed back. Only docs nit I'll carry: frames.md#io does not cross-link the seal paragraph in json-shapes; noted for the next docs touch, not a gap in the contract.