release #5513: correct RFC source anchors + self-validating test

Codex Phase-1 gate found the RFC cited stale/wrong source anchors (docs-only, but
actively misleading to future implementers): /api/sessions/events is routed at
routes.py:12345-12346 (RFC said 12320-12321 = /api/chat/cancel);
_handle_session_events_stream at 16177 (RFC said 16142 = a gateway-sse comment);
replay reads after_event_id/after_seq QUERY PARAMS (RFC said Last-Event-ID header
— that's the *proposed* new-endpoint contract, not current). Corrected all six
routes.py anchors + the replay-mechanism description, verified each against master.

The accompanying test asserted the WRONG anchors and passed (codifying the error).
Rewrote test_rfc_cites_current_global_endpoint_source to parse every routes.py
anchor from the RFC and verify it lands on the real /api/sessions/events route +
_handle_session_events_stream definition — so it now catches drift instead of
locking in a stale number.

Co-authored-by: rodboev <rodboev@users.noreply.github.com>
This commit is contained in:
nesquena-hermes 2026-07-04 06:37:18 +00:00
parent 174dec88eb
commit 6182ae044b
2 changed files with 45 additions and 21 deletions

View file

@ -38,8 +38,8 @@ against current source before any route is added.
- This RFC does **not** implement `GET /api/sessions/{session_id}/events`. No
route, handler, or related code is added in this PR.
- This RFC does **not** modify `GET /api/sessions/events` (the existing global
session-list invalidation stream routed at `api/routes.py:12320-12321` and
implemented by `_handle_session_events_stream()` at `api/routes.py:16142`).
session-list invalidation stream routed at `api/routes.py:12345-12346` and
implemented by `_handle_session_events_stream()` at `api/routes.py:16177`).
- This RFC does **not** replace or modify existing streams: `/api/chat/stream`,
`/api/approval/stream`, or `/api/clarify/stream`.
- This RFC does **not** introduce Android, iOS, or PWA client code.
@ -53,8 +53,8 @@ against current source before any route is added.
### Existing global session-list stream
`GET /api/sessions/events` is a **different endpoint** from the one this RFC
proposes. It is routed at `api/routes.py:12320-12321` and implemented by
`_handle_session_events_stream()` at `api/routes.py:16142`. It emits bare
proposes. It is routed at `api/routes.py:12345-12346` and implemented by
`_handle_session_events_stream()` at `api/routes.py:16177`. It emits bare
`sessions_changed` events and keepalives for any change to the session list. It
is a global invalidation signal, not a per-session lifecycle stream. The proposed
`GET /api/sessions/{session_id}/events` is per-session and path-distinct.
@ -73,13 +73,16 @@ Line ranges in this inventory were verified against WebUI `master` when this
RFC was written. Function, constant, and endpoint names are the stable anchors
if source layout moves later.
- `_parse_run_journal_event_id()` and `_parse_run_journal_after_seq()` at
`api/routes.py:15638-15665` parse the cursor from `Last-Event-ID`.
- `_runner_event_id()` at `api/routes.py:15730-15737` constructs the event `id`
- `_parse_run_journal_event_id()` (`api/routes.py:15673-15686`) and
`_parse_run_journal_after_seq()` (`api/routes.py:15688-15701`) parse the replay
cursor from the `after_event_id` / `after_seq` **query params** (not the
`Last-Event-ID` header — that header is the *proposed* new-endpoint contract
below, §Reconnect).
- `_runner_event_id()` at `api/routes.py:15765-15772` constructs the event `id`
field as `stream_id:seq`.
- Live event `id:` is emitted at `api/routes.py:15869-15885`.
- Live event `id:` is emitted during replay/stream at `api/routes.py:15703-15762`.
- `_replay_run_journal()` reads events by `(session_id, stream_id)` at
`api/routes.py:15668-15700`.
`api/routes.py:15703-15735`.
- `api/streaming.py:6265-6285` writes current live agent streams to
`STREAMS[stream_id]`.
- `api/streaming.py:6620-6634` appends SSE events to the run journal and carries
@ -159,7 +162,7 @@ position.
**`event_id` is opaque to clients.** Its current source-compatible form is
`stream_id:seq`, as constructed by `_runner_event_id()` at
`api/routes.py:15730-15737`. Clients must treat it as an opaque string and must
`api/routes.py:15765-15772`. Clients must treat it as an opaque string and must
not parse or construct cursor values.
**`seq` is monotonic within a stream/run.** It is not a session-global counter
@ -177,7 +180,7 @@ events. The live `STREAMS[stream_id]` queue (`api/streaming.py:6265-6285`) is
not a reliable replay source because it holds only recent in-memory state.
A future implementation must replay from the run journal via the existing
`_replay_run_journal()` path (`api/routes.py:15668-15700`) and fall back to the
`_replay_run_journal()` path (`api/routes.py:15703-15735`) and fall back to the
snapshot mechanism when journal entries are unavailable for a given cursor.
## Snapshot fallback

View file

@ -91,18 +91,39 @@ class TestEndpointDistinction:
)
def test_rfc_cites_current_global_endpoint_source(self):
"""The RFC's source anchors for the existing global stream must be
ACCURATE against current api/routes.py — verify the cited lines actually
contain what the RFC claims, rather than string-matching a fixed number
(which silently rots and codifies wrong anchors, #5513 gate finding)."""
import re
text = _rfc()
assert "api/routes.py:12320-12321" in text, (
"RFC must cite the current global sessions/events route match"
routes = (REPO / "api" / "routes.py").read_text(encoding="utf-8").splitlines()
# Pull every `api/routes.py:<start>-<end>` or `api/routes.py:<line>`
# anchor the RFC cites and confirm the referenced span exists.
anchors = re.findall(r"api/routes\.py:(\d+)(?:-(\d+))?", text)
assert anchors, "RFC must cite at least one api/routes.py source anchor"
for start, end in anchors:
lo = int(start)
hi = int(end) if end else lo
assert 1 <= lo <= len(routes), f"RFC cites api/routes.py:{start} beyond EOF ({len(routes)} lines)"
assert 1 <= hi <= len(routes), f"RFC cites api/routes.py:{end} beyond EOF ({len(routes)} lines)"
# The two load-bearing anchors must land on the real definitions.
def _anchor_line(label):
m = re.search(r"%s.*?api/routes\.py:(\d+)" % re.escape(label), text, re.DOTALL)
assert m, f"RFC must cite a routes.py anchor near {label!r}"
return int(m.group(1))
route_line = _anchor_line("routed at")
assert "/api/sessions/events" in routes[route_line - 1], (
f"RFC's routed-at anchor api/routes.py:{route_line} must be the "
f"/api/sessions/events route; got: {routes[route_line - 1].strip()!r}"
)
assert "api/routes.py:16142" in text, (
"RFC must cite the current _handle_session_events_stream definition"
)
assert "api/routes.py:12296-12297" not in text, (
"RFC must not cite the stale global sessions/events route range"
)
assert "api/routes.py:16118" not in text, (
"RFC must not cite the stale _handle_session_events_stream line"
handler_line = _anchor_line("_handle_session_events_stream()")
assert "def _handle_session_events_stream" in routes[handler_line - 1], (
f"RFC's handler anchor api/routes.py:{handler_line} must be the "
f"_handle_session_events_stream definition; got: {routes[handler_line - 1].strip()!r}"
)
def test_contracts_distinguishes_both_endpoints(self):