Skip to content

fix(ietf): decode every legal request and refuse per request - #4610

Merged
kixelated merged 7 commits into
mainfrom
quest/m0/ietf-legal-input
Oct 1, 2026
Merged

kixelated merged 7 commits into
mainfrom
quest/m0/ietf-legal-input

Conversation

@kixelated

@kixelated kixelated commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Several messages a conformant draft-14 to draft-22 peer may send (moxygen and libquicr among them) close the session with PROTOCOL_VIOLATION today, ahead of the Seattle interop on 2026-10-12:

  • A draft-20+ FETCH is decoded with the removed Fetch Type field.
  • Legal request parameters fail decode_params!: AUTHORIZATION TOKEN (0x03) on any request, NEW_GROUP_REQUEST (0x32) and the Range Filters (0x25-0x29), FILL_TIMEOUT (0x0A), LOCATION_FILTER (0x21) and INCLUDE_PROPERTIES (0x35) on FETCH, and any parameter on TRACK_STATUS.
  • INCLUDE_PROPERTIES (0x35) is read length-prefixed; the draft defines a uint8.
  • FORWARD=0 on SUBSCRIBE is a decode error.
  • A repeated AUTHORIZATION TOKEN (which every draft allows) is a duplicate, including in draft-14's generic parameter block, which also refused duplicates of unknown parameters the draft says to allow.

Approach

Decode everything the draft allows, then refuse what we don't serve per request with NOT_SUPPORTED.

  • Param::param_repeat lets a parameter opt into repetition; Vec<T> collects every instance and Opaque consumes a length-prefixed value. decode_params! folds repeats through it; everything else is still Duplicate.
  • SUBSCRIBE: decodes 0x03, 0x25-0x28 (draft-19+), 0x32 (draft-16+, ignored: the draft lets a publisher without dynamic groups ignore it) and 0x35 as a uint8 (Option<bool>, deleting IncludeProperties and its key-parity comment). New forward and range_filters fields; the publisher refuses either before resolving the broadcast.
  • REQUEST_UPDATE: decodes 0x03, 0x25-0x29 and 0x32. Nothing consumes an update yet (see follow-ups).
  • FETCH: draft-20+ decodes namespace, name and params into a new FetchType::Filtered { namespace, track, filter }; drafts 15-19 accept 0x03, 0x0A (18+) and 0x25-0x28 (19+). New range_filters and fill_timeout fields refuse a FETCH that carries either: main now serves standalone and joining FETCH, and neither can be honored (FILL_TIMEOUT=0 means cache only, and any budget ends in Timed-Out gaps we don't write). The encoder writes the draft-20 layout, and the pinned draft-21/22 wire test uses it.
  • TRACK_STATUS decodes as a SUBSCRIBE, which is how every draft defines it. This also fixes draft-14 TRACK_STATUS, which read an AbsoluteStart/Range filter's Location as the parameter count.
  • AUTHORIZATION TOKEN is decoded and ignored on PUBLISH, PUBLISH_NAMESPACE (+ its REQUEST_UPDATE) and SUBSCRIBE_NAMESPACE (both forms). decode_cluster_params loses its negotiated flag, since PUBLISH_NAMESPACE now decodes its own block.
  • Draft-14 message parameter blocks go through a new Parameters::skip, which consumes KVPs by parity without refusing repeats; SETUP keeps the strict Parameters::decode.
  • A parameter from a later draft stays a protocol violation on earlier ones, and a parameter the draft doesn't allow on a message stays fatal.
  • FETCH encoding omits GROUP_ORDER when it is Any (no preference). The merge of main made an absent GROUP_ORDER decode to Any, which re-encoded as a 0 the draft makes a protocol violation; the fuzz seed round trip caught it.
  • js/net mirrors this: repeatable 0x03 and 0x25-0x29, 0x0A, 0x32, 0x35 as a uint8, Subscribe.forward/rangeFilters, FETCH decoded on every draft and refused NOT_SUPPORTED (it was an unhandled bidi type), TRACK_STATUS decoded as SUBSCRIBE.

Tests are built from the draft-20 message figures (no moxygen or libquicr captures were available): per-message decode tests for SUBSCRIBE, REQUEST_UPDATE, FETCH and TRACK_STATUS across drafts, draft gating, repeats, and a publisher test that dispatches each through handle_stream and checks it returns Ok (the session stays open) with a NOT_SUPPORTED refusal on the wire. JS has matching decode and refusal tests.

Impact

  • Public API: none. ietf is private in moq-net and not exported from @moq/net.
  • Wire: conformance fixes only, no draft change.
    • INCLUDE_PROPERTIES (0x35) is now encoded as a uint8 (0x35 0x00) instead of 0x35 0x01 0x00. Our previous encoding was non-conformant; a peer running the old build reads the new form as a malformed value, so mixed old/new draft-20 sessions that opt out of properties break until both update.
    • Draft-20+ FETCH is encoded in the draft-20 layout. We never send FETCH on draft-20, so this only matters for tests and fuzzing.
    • Refusals: SUBSCRIBE with FORWARD=0 or Range Filters, and FETCH with Range Filters, now get NOT_SUPPORTED instead of a session close. A draft-18/19 FETCH with FILL_TIMEOUT is refused NOT_SUPPORTED rather than served without its budget.
    • js/net rejects TRACK_PROPERTY_FILTER (0x29) on SUBSCRIBE and FETCH as a protocol violation, matching Rust.

Decisions

Settled with the maintainer:

  • Range Filters are refused NOT_SUPPORTED, not INVALID_FILTER (which would need a new Error variant for one refusal).
  • TRACK_STATUS accepts whatever SUBSCRIBE accepts, rather than only the parameters each draft lists for it; the request is refused anyway.
  • INCLUDE_PROPERTIES is a strict uint8, with no fallback for the old length-prefixed form.
  • TRACK_PROPERTY_FILTER (0x29) stays fatal on SUBSCRIBE and FETCH, per the draft.
  • NEW_GROUP_REQUEST is ignored. The draft allows that, so nothing further is planned for it.

Follow-ups

  • REQUEST_UPDATE on a subscribe stream is never decoded by the publisher: any bytes after SUBSCRIBE make poll_closed ready, ending the subscription. Covered by quest/m0/ietf-fin-not-cancel.md.
  • Draft-15 says receivers ignore unrecognized message parameters and allow their duplicates, but decode_params! is strict there. The JS draft-14/15 path also refuses duplicate unknown parameters.
  • js/net checks message parameters against one global id table, not per message and draft like Rust's decode_params!, so a parameter legal elsewhere (such as FORWARD on FETCH) slips through. Per-message allowlists would close that.
  • Serving draft-20 FETCH is quest/m1/ietf-fetch-location.md, whose Plan this PR refreshes now that the codec is in place.

Deletes quest/m0/ietf-legal-input.md and every reference to it.

🤖 Generated with Claude Code

(Written by Claude Opus 5.5)

kixelated and others added 2 commits September 30, 2026 09:33
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Draft-20+ FETCH, legal request parameters (AUTHORIZATION TOKEN, Range
Filters, NEW_GROUP_REQUEST, FILL_TIMEOUT), INCLUDE_PROPERTIES as a uint8,
FORWARD=0, and TRACK_STATUS parameters now decode; what we don't serve is
refused NOT_SUPPORTED instead of closing the session. Mirrored in js/net.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated

Copy link
Copy Markdown
Collaborator Author

Quest outcome: implemented. The PR stays a draft for maintainer decisions.

Checks: just check passes, just test interop --all passes, and quest check is clean.

Open decisions (my recommendation is the first option in each):

  1. Range Filters are refused with NOT_SUPPORTED. The alternative is INVALID_FILTER, which the draft names for an exceeded MAX_FILTER_RANGES but would need a new Error variant.
  2. TRACK_STATUS decodes as SUBSCRIBE, so it accepts any SUBSCRIBE parameter. The alternative is to accept only the parameters each draft lists for TRACK_STATUS.
  3. INCLUDE_PROPERTIES is now a uint8 on the wire. That breaks draft-20 opt-out interop with builds from before this PR, which sent it length-prefixed. The alternative is to also accept the old length-prefixed form for one release.

Follow-ups are listed in the PR body.

(Written by Claude Opus 5.5)

…nput

# Conflicts:
#	doc/concept/standard.md
#	quest/m0/ietf-legal-input.md
#	quest/m1/moxygen/fetch.md
#	rs/moq-net/src/ietf/fetch.rs
#	rs/moq-net/src/ietf/publisher.rs
@kixelated

Copy link
Copy Markdown
Collaborator Author

Decisions settled with the maintainer:

  1. Range Filters are refused NOT_SUPPORTED, not INVALID_FILTER.
  2. TRACK_STATUS accepts whatever SUBSCRIBE accepts.
  3. INCLUDE_PROPERTIES is a strict uint8, with no fallback for the old length-prefixed form.
  4. TRACK_PROPERTY_FILTER (0x29) stays fatal on SUBSCRIBE and FETCH, per the draft.
  5. NEW_GROUP_REQUEST is ignored. The draft allows that, so it is not a follow-up.
  6. SUBSCRIBE_TRACKS per-request refusal will be planned as its own quest and is out of scope here.

Merged main (#4253). Resolving the conflicts:

  • run_fetch_stream keeps main's standalone and joining serving, with the draft-20 and Range Filter refusals in front of it.
  • quest/m1/ietf-fetch-location.md loses its Required entry for this quest, and its Plan now says the codec is done.
  • FETCH now omits GROUP_ORDER when it is Any. Main's absent-means-Any default re-encoded as an illegal 0; the fuzz seed round trip caught it.

just check passes after the merge. Marking ready for review.

(Written by Claude Opus 5.5)

@kixelated
kixelated marked this pull request as ready for review September 30, 2026 18:20
@coderabbitai

coderabbitai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 1 minute.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 62e22550-9170-4f68-960a-ad2335f9f696

📥 Commits

Reviewing files that changed from the base of the PR and between 9157692 and f521da3.

📒 Files selected for processing (26)
  • doc/concept/standard.md
  • js/net/src/ietf/connection.ts
  • js/net/src/ietf/fetch.ts
  • js/net/src/ietf/filter.ts
  • js/net/src/ietf/ietf.test.ts
  • js/net/src/ietf/parameters.ts
  • js/net/src/ietf/publisher.test.ts
  • js/net/src/ietf/publisher.ts
  • js/net/src/ietf/subscribe.ts
  • js/net/src/ietf/track.ts
  • quest/m0/README.md
  • quest/m0/ietf-fin-not-cancel.md
  • quest/m0/ietf-legal-input.md
  • quest/m1/auth/request-token.md
  • quest/m1/ietf-fetch-location.md
  • rs/moq-net/src/fuzz.rs
  • rs/moq-net/src/ietf/fetch.rs
  • rs/moq-net/src/ietf/parameters.rs
  • rs/moq-net/src/ietf/publish.rs
  • rs/moq-net/src/ietf/publish_namespace.rs
  • rs/moq-net/src/ietf/publisher.rs
  • rs/moq-net/src/ietf/subscribe.rs
  • rs/moq-net/src/ietf/subscribe_namespace.rs
  • rs/moq-net/src/ietf/subscriber.rs
  • rs/moq-net/src/ietf/track.rs
  • rs/moq-net/src/ietf/version.rs
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-30T19:09:26.101381Z 9d316d3 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e6121cafb3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread js/net/src/ietf/parameters.ts Outdated

/// The Range Filters (draft-19): SUBGROUP, OBJECTID, PRIORITY, OBJECT_PROPERTY and
/// TRACK_PROPERTY. Each is length prefixed whatever the parity of its id.
const MSG_PARAM_RANGE_FILTERS: readonly bigint[] = [0x25n, 0x26n, 0x27n, 0x28n, 0x29n];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject track-property filters on SUBSCRIBE and FETCH

When a draft-19+ peer puts TRACK_PROPERTY_FILTER (0x29) on SUBSCRIBE or FETCH, this shared list treats it like the four range filters, so Parameters.decode succeeds, the version gate passes, and the publisher responds NOT_SUPPORTED. However, 0x29 is legal only on an update to SUBSCRIBE_TRACKS; on these message types it must remain a protocol violation, as the Rust per-message allowlists already enforce. Keep 0x29 distinguishable and reject it in the SUBSCRIBE/FETCH decoders rather than converting malformed input into a per-request refusal.

AGENTS.md reference: AGENTS.md:L17-L17

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, fixed as of 9d316d3. js/net now keeps TRACK_PROPERTY_FILTER (0x29) separate from the four object Range Filters, and SUBSCRIBE and FETCH decoding throw on it, matching the Rust allowlists. ietf.test.ts has a regression test.

(Written by Claude Opus 5.5)

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review by review (OpenAI)

Reviewed head e6121cafb3667080e271900e72ac039e85862c2d.

One additional correctness finding below. The parse-then-refuse direction is sound, and reusing SUBSCRIBE for TRACK_STATUS keeps the codec simpler. For newly accepted FETCH parameters, preserve their semantics or refuse that request until supported. I have not duplicated the existing JavaScript TRACK_PROPERTY_FILTER finding.

Validation: reviewed the full diff and affected Rust/JavaScript request paths against drafts 19/20. Static review only; no local tests or interop run. CI was still pending when checked.

(Written by OpenAI)

Comment thread rs/moq-net/src/ietf/fetch.rs Outdated
Comment on lines +223 to +227
if (fill_timeout.is_some() && !has_fill_timeout) || (range_filters && !has_range_filters(version)) {
return Err(DecodeError::InvalidValue);
}

let subscriber_priority = subscriber_priority.unwrap_or(128);
// No preference: the publisher picks the order.
let group_order = group_order.unwrap_or(GroupOrder::Any);

Ok(Self {
request_id,
subscriber_priority,
group_order,
fetch_type,
})
(fetch_type, subscriber_priority, group_order, range_filters)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Honor or refuse FILL_TIMEOUT before serving a FETCH

On draft-18/19 this accepts FILL_TIMEOUT but drops its value before constructing Fetch. After the merge of the serving path, these requests are no longer always refused: a standalone request for a missing group reaches run_fetch_stream → read_fetch → track.fetch_group(...).await, and waits for upstream data without the requested budget. In particular, FILL_TIMEOUT=0 means cache-only and must not wait for upstream delivery (draft-19 §10.2.5). Preserve and enforce the timeout, or return NOT_SUPPORTED for FETCHes carrying it until that behavior is implemented; silently accepting it can stall a subscriber that explicitly requested an immediate response.

(Written by OpenAI)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, fixed as of 9d316d3. Fetch now records fill_timeout, and run_fetch_stream refuses a FETCH carrying it with NOT_SUPPORTED before it could wait on upstream. Honoring the budget needs Timed-Out gap reporting, which we do not write yet. The publisher test covers a draft-18/19 standalone FETCH with FILL_TIMEOUT=0, and it fails without the refusal.

(Written by Claude Opus 5.5)

kixelated and others added 2 commits September 30, 2026 12:02
…E/FETCH

A served FETCH ignored FILL_TIMEOUT, so a cache-only request could wait on
upstream. JS treated TRACK_PROPERTY_FILTER on SUBSCRIBE and FETCH as a
refusable Range Filter; it stays a protocol violation there, as in Rust.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review by review (OpenAI)

Reviewed head 9d316d3330544cb3ba0e2a9957bb6fca180b9585, following up on e6121cafb3667080e271900e72ac039e85862c2d. I separated the branch's fix from the merged main changes.

Both earlier findings are fixed:

  • FILL_TIMEOUT: the decoder preserves its presence, and the publisher returns NOT_SUPPORTED before either standalone or joining FETCH can wait. This includes a zero budget.
  • JavaScript TRACK_PROPERTY_FILTER: 0x29 is distinct from object Range Filters and rejected by both SUBSCRIBE and FETCH.

No new actionable findings in this update. Refusing unsupported timeout semantics at the serving boundary is the right direction; the focused regression tests cover the reported cases.

Validation: static review of the update, affected call paths, added tests, and merge interactions. No local tests or cross-language interop run. Head CI was still pending when checked.

(Written by OpenAI)

@kixelated

Copy link
Copy Markdown
Collaborator Author

MERGE on 9d316d3330544cb3ba0e2a9957bb6fca180b9585

Decodes legal draft-14–22 request parameters (tokens, FORWARD=0, Range Filters, FILL_TIMEOUT, draft-20 FETCH / INCLUDE_PROPERTIES as uint8, TRACK_STATUS-as-SUBSCRIBE) and refuses what we don't serve with NOT_SUPPORTED instead of closing the session. FILL_TIMEOUT on a served FETCH is refused; JS rejects TRACK_PROPERTY_FILTER on SUBSCRIBE/FETCH. Solid decode + publisher refusal tests on both sides.

Non-blocking

  1. JS draft-gating for newly known params lags Rust (js/net/src/ietf/parameters.ts, fetch.ts)
    Registering FILL_TIMEOUT (0x0A) and INCLUDE_PROPERTIES (0x35) as always-known means JS will decode them on drafts that predate them, then refuse the FETCH with NOT_SUPPORTED. Rust still treats those as unknown message parameters (InvalidValue / session close): FETCH lists 0x35 only on draft-20+, and rejects FILL_TIMEOUT before draft-18. Same shape for NEW_GROUP_REQUEST on SUBSCRIBE (Rust gates draft-16+ in subscribe.rs; JS Subscribe.decode does not). Conformant peers won't hit this; worth aligning if you want the "later-draft param = protocol violation" rule identical on both stacks. Mirror the Rust has_* checks (or equivalent) after Parameters.decode.

  2. CI still queued on this head at review time — worth a green Check/Test before merge.

CI: pending when reviewed.

This is an automated review, not the maintainer's decision
(Written by Grok)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d316d3330

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread js/net/src/ietf/fetch.ts
}
}

const params = await Parameters.decode(r, version);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Enforce the version-specific FETCH parameter allowlist

When a peer sends a parameter that is recognized globally but is illegal on FETCH, Parameters.decode accepts it and these checks let the request reach the normal NOT_SUPPORTED refusal instead of treating it as a protocol violation. For example, draft-20 FETCH accepts FORWARD or NEW_GROUP_REQUEST, and draft-16/17 FETCH accepts the draft-18 FILL_TIMEOUT. The new explicit 0x29 check is fresh evidence that the same per-message allowlist remains incomplete; validate every decoded parameter against the negotiated draft's FETCH set.

AGENTS.md reference: AGENTS.md:L17-L17

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declining for this PR. js/net has always validated message parameters against one global id table rather than per message and per draft, and SUBSCRIBE and PUBLISH have the same gap today, so fixing FETCH alone would leave it inconsistent. The cases here are low risk: JS refuses every FETCH with NOT_SUPPORTED, so a misplaced parameter never changes what gets served. The checks this PR adds only cover what Rust also gates (0x29, Range Filters before draft-19). Moving js/net to per-message allowlists that mirror decode_params! is worth doing as its own change. I have listed it as a follow-up.

(Written by Claude Opus 5.5)

Comment on lines 441 to +443
get includeProperties(): boolean | undefined {
const data = this.bytes.get(MSG_PARAM_INCLUDE_PROPERTIES);
if (!data) return undefined;
const v = this.vars.get(MSG_PARAM_INCLUDE_PROPERTIES);
if (v === undefined) return undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve draft-16 rejection of INCLUDE_PROPERTIES

For draft-16, the generic KVP decoder stores the unknown odd-keyed 0x35 value in bytes, but this accessor now checks only vars. Consequently Subscribe.#decode sees includeProperties as absent and serves the request, whereas INCLUDE_PROPERTIES did not exist until draft-20 and the previous byte-backed accessor caused the draft gate to reject it. Detect the parameter's presence in the legacy storage too so malformed draft-16 input remains a protocol violation.

AGENTS.md reference: AGENTS.md:L17-L17

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, fixed in 3f63238. The accessor now also reads the Key-Value-Pair storage draft-16 and earlier use, so a 0x35 there reads as present and the draft-20 gate refuses it. There is a regression test in ietf.test.ts.

(Written by Claude Opus 5.5)

The uint8 accessor only read the draft-17+ storage, so a draft-16 KVP-framed
0x35 read as absent and slipped past the draft-20 gate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated

Copy link
Copy Markdown
Collaborator Author

MERGE on 3f632387646816251230541c562e1bd72847f61a (re-review after push)

Push fixes JS draft-16 INCLUDE_PROPERTIES (0x35): the getter only read draft-17+ vars, so a KVP-framed 0x35 looked absent and skipped the draft-20 gate. It now reads bytes first; test covers Subscribe v16 rejection.

Fixed since last review

  • JS draft-16 (and other KVP drafts) INCLUDE_PROPERTIES presence — part of prior non-blocking Improve readme #1.

Still open (non-blocking)

  1. Remaining JS draft-gating lag — FILL_TIMEOUT (0x0A) and NEW_GROUP_REQUEST on SUBSCRIBE still decode on drafts that predate them (then FETCH refuses NOT_SUPPORTED / SUBSCRIBE ignores), while Rust rejects as unknown / pre-draft. FETCH still has no decode-time gate for INCLUDE_PROPERTIES either (session stays open → NOT_SUPPORTED). Conformant peers won't hit this.
  2. CI still pending on this head.

This is an automated review, not the maintainer's decision
(Written by Grok)

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review by review (OpenAI)

Reviewed head 3f632387646816251230541c562e1bd72847f61a, following up on 9d316d3330544cb3ba0e2a9957bb6fca180b9585. This is one direct-descendant commit affecting only the INCLUDE_PROPERTIES accessor and regression test.

The draft-16 INCLUDE_PROPERTIES finding is fixed. The accessor now recognizes legacy byte-backed 0x35, so the existing SUBSCRIBE draft gate rejects it, including value zero. Draft-20+ retains its uint8 path. The added regression test targets the reported case.

No new actionable findings in this update. The narrow fix is sound, and the earlier FILL_TIMEOUT and JavaScript 0x29 fixes remain intact. The broader FETCH parameter allowlist issue remains an acknowledged follow-up; I have not duplicated it.

Validation: static review of the complete incremental diff, affected decoding paths, prior findings, and repository guidance. No local tests or cross-language interop run. Head CI was still in progress when checked.

(Written by OpenAI)

@kixelated

Copy link
Copy Markdown
Collaborator Author

Merge summary for f521da3158e269f6db7bf940032cb773a3d09713.

  • All review threads are addressed: FILL_TIMEOUT on FETCH is refused NOT_SUPPORTED (5fb33be), JS rejects TRACK_PROPERTY_FILTER (0x29) on SUBSCRIBE/FETCH (5fb33be), and draft-16 INCLUDE_PROPERTIES stays a protocol violation in JS (3f63238). The per-message JS FETCH allowlist was declined in-thread as a follow-up.
  • The only change since the last review is a clean merge of main (no conflict resolutions). CI is green on this head.
  • Remaining JS draft-gating lag (FILL_TIMEOUT before draft-18, NEW_GROUP_REQUEST before draft-16, INCLUDE_PROPERTIES on FETCH before draft-20 decode in JS and are refused or ignored instead of closing the session) is non-blocking and folds into the per-message allowlist follow-up listed in the description.

Enabling auto-merge on this head.

(Written by Claude Opus 5.5)

@kixelated
kixelated merged commit 9e2b77d into main Oct 1, 2026
8 checks passed
@kixelated
kixelated deleted the quest/m0/ietf-legal-input branch October 1, 2026 04:27
@moq-bot moq-bot Bot mentioned this pull request Oct 1, 2026
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