Skip to content

fix(session): reject review event frames whose id disagrees with their publication fields - #781

Open
lilfrogdev wants to merge 1 commit into
modem-dev:mainfrom
lilfrogdev:fix/session-review-event-id-address-mismatch
Open

fix(session): reject review event frames whose id disagrees with their publication fields#781
lilfrogdev wants to merge 1 commit into
modem-dev:mainfrom
lilfrogdev:fix/session-review-event-id-address-mismatch

Conversation

@lilfrogdev

Copy link
Copy Markdown

Fixes #761

Problem

Event frames carry their publication position twice: inside eventId (revent:<type>:<generation>@<revision>) and as the loose generation / stateRevision fields. The four frame parsers validated each part but never checked they agree, so an id naming generation 1 / revision 1 on a frame claiming generation 2 / revision 9 was accepted. The id drives SSE resume and chunk assembly; the fields are what consumers report, so they must name the same position.

Approach

  • One module-private helper, eventIdMatchesFrame(record, fields): parses the id with the existing parseReviewEventId (still the only id grammar) and compares the listed address fields to the frame's own.
  • Each parser swaps its isReviewEventId gate for that helper. Frame and begin compare generation + stateRevision; chunk and end compare generation only (they don't carry a revision).
  • Delete isReviewEventId, which has no remaining callers.

Non-goals: parsers keep returning the validated record via the existing casts (hasExactKeys doesn't narrow; rebuilding each object adds casts without changing behavior). Checking the id's event type against the SSE event: name is out of scope; the parsers never see it.

Belongs in src/session/reviewEventProtocol.ts: both ends of the stream import this one contract; not expressible as an extension.

Tests

New cases in src/session/reviewEventProtocol.test.ts: a well-formed single frame parses; each of the four parsers rejects an id whose generation (and, where carried, revision) disagrees with the frame while every value is individually valid. The rejection test fails against the previous code. Existing round-trip/framing/reassembly tests, browserReviewServer.integration.test.ts, and the review-conformance consumers cover the unchanged accept path.

Ran:

bun test src/session/reviewEventProtocol.test.ts
bun test src/session/broker/browserReviewServer.integration.test.ts
bun test test/review-conformance
bun run typecheck
bun run lint
bun run knip
bun run format

Two pre-existing failures reproduce identically on main at 5ebe975 and are unrelated to this change:

Knip reports nothing for src/session/reviewEventProtocol.ts, including the removed isReviewEventId.

Tested on macOS (Bun 1.3.14). Not run on Linux/Windows; change is platform-neutral validation with no I/O. No UI change.

AI assistance

An AI coding agent helped scope the change, draft the helper/tests, and this description. I wrote and reviewed the final diff, ran every command above, and can speak to each decision here.

@vercel

vercel Bot commented Aug 16, 2026

Copy link
Copy Markdown

@lilfrogdev is attempting to deploy a commit to the Modem Team on Vercel.

A member of the Team first needs to authorize it.

@greptile-apps

greptile-apps Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

PR author is not in the allowed authors list.

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.

Reject review event frames whose ID disagrees with their publication fields

1 participant