Skip to content

perf(net): lazy-load the WebSocket fallback and drop zod from the static graph - #8719

Merged
moq-bot[bot] merged 6 commits into
mainfrom
quest/m1/js-bundle-audit
Nov 14, 2026
Merged

moq-bot[bot] merged 6 commits into
mainfrom
quest/m1/js-bundle-audit

Conversation

@kixelated

@kixelated kixelated commented Nov 14, 2026 •

Copy link
Copy Markdown
Collaborator

Finishes quest/m1/js-bundle-audit.md.

Problem

Nightly's 30-day size comparison (10%) fails from 2026-11-21 until a post-growth report becomes its anchor on 12-13. moq-dev/moq#8654 accepted the growth as feature growth and asked for an audit of what each consumer bundle carries, landing the non-breaking cuts. From 12-07 (the 11-07 anchor), net (1.119x) and hang (1.105x) still failed.

Approach

Two cuts. Both reach every bundle because every bundle carries @moq/net:

  • @moq/qmux loads on demand. The WebSocket fallback's QMux stack was in every first load, though a session over WebTransport never uses it. connectWebSocket now dynamic-imports it once WebTransport's head start runs out, so a session WebTransport wins never downloads it. With no head start (no WebTransport, or WebSocket won the last race to this server), the import starts at once. transportOf no longer uses instanceof Session. It reads a transport = "websocket" label on the qmux Session, the same way @moq/p2p's transport labels itself "webrtc". This also classifies a qmux session a caller passes in through transport.
  • zod leaves @moq/net's static graph. Its only runtime use was the internal HopSchema, a refined, branded bigint. It is now a branded type plus toHop(), which throws the same message as a RangeError. zod stays a peer for the @moq/net/zod subpath, which only uses its types.

Audit

Static (first-load) chunks, from the bundles.ts metafiles. Marginal brotli means the bundle with only that package left external.

Bundle Top inputs, raw (before) Marginal brotli Verdict
net js/net/dist 446 KB (track 56, lite/subscriber 45, lite/publisher 30, origin 30, resume 26, group 18), js/qmux 44 KB, pako 42 KB, js/pattern 14 KB, zod 9 KB qmux 10.8 KB, pako 11.8 KB, zod 3.3 KB, pattern 3.4 KB qmux made lazy, zod dropped. The rest is the protocol itself.
hang net + zod 37 KB + js/hang 36 KB (container/consumer 11 KB) zod 9.1 KB The larger part of zod is the public catalog schemas (@moq/hang/catalog), which watch parses before playback. Making them lazy would need an async, breaking catalog API to save 9 KB, so no m2 quest.
watch, watch-ui hang + js/watch 123 KB (player chunk 68 KB, ui/element 43 KB, element 12 KB) UI adds about 10.9 KB This is the player and UI the element is for. CMAF is already lazy.
publish hang + js/publish 71 KB (encoder chunk 51 KB, element 11 KB) Encoder and element. mediabunny is already lazy.

pako stays. CompressionStream can't do moq-flate's job: it is async, it can't flush a sync slice per frame, and it can't stop a bomb partway through a chunk. fflate would be 4.2 KB brotli against pako's 11.8 KB. But its streaming Inflate buffers all of a push's output before the size check, which loses the decoder's bound (declaration plus one 4 KB chunk). It also copies the 32 KB window on every push. fflate's Deflate (3.3 KB) next to pako's Inflate (9.2 KB) would be 12.5 KB, more than pako alone (11.8 KB).

Before and after (bun sh/size/bundles.ts, brotli bytes)

Bundle Before (main 97a7267) After Change
net 153,149 140,254 -12,895 (-8.4%)
hang 174,142 163,611 -10,531 (-6.0%)
watch 192,680 181,571 -11,109 (-5.8%)
watch-ui 203,579 192,412 -11,167 (-5.5%)
publish 186,314 175,619 -10,695 (-5.7%)

Raw size falls 45 to 53 KB and gzip 12.7 to 15.6 KB per bundle. The lazy qmux chunk is outside the first load, which is all Nightly measures.

30-day comparison

Replaying the retained nightly-size-history (11-13 artifact) against these bytes:

  • 12-05 to 12-12 now pass (anchors 11-05, 11-06, 11-07; worst ratio 1.073). Before this PR, 12-05 to 12-12 failed.
  • 11-21 to 12-04 stay red by design (anchors 10-22 to 11-03; 1.107x to 1.418x). Clearing 12-03 and 12-04 would take another 4.6 KB off net and cuts in hang, watch, and watch-ui, and no non-breaking cut that size is left. As Nightly artifact sizes says, the comparison is not waived or reset.

Impact

  • @moq/qmux: Session gains readonly transport: "websocket" (additive).
  • @moq/net: no public API change. The WebSocket fallback is now a separate chunk loaded on demand, like the moq-transport stack already is. A bundler has to emit dynamic-import chunks, which it already must for the moq-transport stack. @moq/net needs a @moq/qmux that carries the label; the workspace:^ range pins that at release.
  • Wire: none.

Validation

  • bun sh/size/bundles.ts before and after, as in the tables. The metafile check shows no js/qmux input in any first-load chunk.
  • End to end: bundled a publish-and-subscribe script with esbuild code splitting against the built dist. qmux landed in its own chunk. Ran it in Node (no WebTransport) against a local moq-relay from this tree. Both sessions reported transport: websocket, connected via WebSocket, and a frame round-tripped through the relay.
  • New qmux test: a Session labels its transport websocket. stats.test.ts now marks the fallback mock by that label.
  • After the head-start wording fix in doc/lib/js/net.md, just check passes.
  • just ci passes (biome, just js check including the build and API reports, and the JS tests).

Caused by

None. moq-dev/moq#8654 accepted the growth as feature growth, and this audit follows from it.

Decisions

Each was taken by the agent under /quest-afk, for the maintainer's review:

  • Lazy-load @moq/qmux from connectWebSocket, after WebTransport's head start. Rejected: keeping it static (gives up 10.8 KB in every bundle). Rejected: moving the fallback behind a subpath export (breaking, and every browser consumer still needs the fallback). Rejected: prefetching it during the head start (the review's round 1 finding: every WebTransport session would still download it). The trade-off: a fallback dial waits for the chunk fetch once per page load.
  • Identify a qmux session by a transport = "websocket" label on Session. Rejected: a WeakSet of sessions that connect dialed, which would misclassify a qmux session passed in through transport and change how open.ts orders stream opens. Rejected: instanceof against the lazily loaded class, which fails before the module loads and across duplicate copies.
  • Keep pako. Rejected: CompressionStream, and fflate, alone or split with pako, for the reasons under Audit.
  • No m2 quest for @moq/hang's zod (9.1 KB). The catalog schemas are public, and watch needs them before playback, so a lazy catalog would be a breaking async API for one bundle-sized win. Rejected: filing it anyway.
  • Delete the quest as finished. 11-21 to 12-04 stay red by design (see the 30-day comparison). Rejected: keeping the quest open for those nights, since no non-breaking cut clears them and they clear on their own.

Alternatives

  • Hand-rolled validators to replace zod in @moq/hang: breaking, and it would rebuild what zod/mini already does in about 9 KB.

Follow-ups

None.

Models

Size: M
Implementer: Claude Code, claude-opus-5-5, unknown effort
Implementer: Claude Code, claude-opus-5-5, unknown effort (iterate, XS)

🤖 Generated with Claude Code

(Written by Claude Opus 5.5)

Review

mechanical fix by codex, gpt-6.1-sol, medium effort: Merged base and completed the HopSchema.parse-to-toHop rename in six base-added tests; ran nix develop --command just ci base and git diff --check successfully. (head daf3f69)

Rewritten by quest review after each round.

  • Head: 6e61841

  • Base: origin/main at 99d789e

  • Reviewer: Codex, gpt-6.1-sol, high effort

  • Session: 01a1d8c2-d01a-7083-bd51-3b836913b359, round 3

  • Score: 10/10, The only incremental change accurately qualifies when lazy loading avoids downloading the fallback chunks, with no new issues found.

  • Rounds: 3; findings 1 (medium 1): fixed 1, refuted 0, open 0

  • Findings: none

kixelated and others added 2 commits November 13, 2026 22:13
…tic graph

@moq/qmux now loads on demand when the fallback dials, and transportOf reads
a "websocket" label on the qmux Session instead of instanceof. The internal
HopSchema becomes a plain branded bigint with toHop(). Every consumer bundle
loses 10.5 to 12.9 KB of brotli, which clears Nightly's 30-day size comparison
from 2026-12-05 instead of 12-13. Finishes quest/m1/js-bundle-audit.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title Audit what the JS bundles carry perf(net): lazy-load the WebSocket fallback and drop zod from the static graph Nov 14, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated marked this pull request as ready for review November 14, 2026 06:41
@coderabbitai

coderabbitai Bot commented Nov 14, 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 9 seconds.

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

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f2c59847-8056-4f96-bb87-9d18bf1da952
Commits

Reviewing files that changed from the base of the PR and between 7a41906 and daf3f69.

Files selected for processing: 26

  • doc/lib/js/net.md
  • js/net/bench/broadcasts.ts
  • js/net/src/announced.test.ts
  • js/net/src/connection/connect.ts
  • js/net/src/connection/stats.test.ts
  • js/net/src/connection/transport.ts
  • js/net/src/hop.ts
  • js/net/src/ietf/cluster.test.ts
  • js/net/src/ietf/cluster.ts
  • js/net/src/ietf/peer-violations.test.ts
  • js/net/src/ietf/publisher.test.ts
  • js/net/src/ietf/subscriber.test.ts
  • js/net/src/lite/announce.test.ts
  • js/net/src/lite/announce.ts
  • js/net/src/lite/connection.ts
  • js/net/src/lite/setup.test.ts
  • js/net/src/lite/setup.ts
  • js/net/src/lite/subscriber.test.ts
  • js/net/src/origin.test.ts
  • js/net/src/request-deadline.test.ts
  • js/net/src/resume.model.test.ts
  • js/net/src/session-limits.test.ts
  • js/qmux/api/index.api.md
  • js/qmux/src/session.test.ts
  • js/qmux/src/session.ts
  • quest/m1/js-bundle-audit.md
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ℹ️ No critical issues — two small rough edges worth a look.

Reviewed changes

I reviewed the two bundle cuts in @moq/net, the transport label on qmux's Session, and the mechanical HopSchema → toHop migration. The stats, qmux session, connect, setup, and announce tests pass locally (277 pass).

  • Lazy @moq/qmux: connectWebSocket waits out WebTransport's head start, then races cancel against import("@moq/qmux"). If cancel wins, nothing loads. If the import fails, only the WebSocket contender rejects, and Promise.any still lets WebTransport win.
  • transportOf by label: it reads transport ("websocket" from qmux, "webrtc" from @moq/p2p) instead of instanceof Session. connectInner and open.ts share that one classifier now.
  • zod out of the static graph: HopSchema becomes a branded Hop plus toHop(), which throws RangeError. No decode path can reach the throw, since u62 and the leading-ones varint both stay inside 64 bits.
  • Quest closed: deletes quest/m1/js-bundle-audit.md.

ℹ️ zod is still a required peer of @moq/net, but nothing outside @moq/net/zod uses it

After this PR, @moq/net uses zod only as a type, in src/zod.ts (the ./zod subpath). js/net/package.json still lists it as a required peerDependency, so npm 7+ installs zod for every consumer, including ones that never import the subpath. That doesn't change bundle size, but it makes the "zod stays a peer only for the subpath" story incomplete.

Technical details
# Mark zod as an optional peer of @moq/net

## Affected sites
- js/net/package.json `peerDependencies.zod`: still required, though only `src/zod.ts` uses it (`import type * as z from "zod/mini"`)

## Required outcome
- Consumers that don't import `@moq/net/zod` aren't made to install `zod`.

## Suggested approach
- Add `"peerDependenciesMeta": { "zod": { "optional": true } }`, the same way `js/signals/package.json` marks `react` optional for its subpath.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using claude-opus-5-5 | 𝕏

Comment thread doc/lib/js/net.md Resolved
…'s head start

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pullfrog[bot]
pullfrog Bot previously approved these changes Nov 14, 2026

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

Re-reviewed the one commit since the prior Pullfrog review.

  • Doc wording fixed: doc/lib/js/net.md now says a moq-lite session WebTransport wins within its head start never downloads the fallback chunks, which matches connectWebSocket. This settles the open thread.

The earlier zod optional-peer note is still unapplied. It is informational and doesn't block merge.

Pullfrog  | View workflow run | Using claude-sonnet-5-5 | 𝕏

@kixelated
kixelated added this pull request to the merge queue Nov 14, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Nov 14, 2026
@moq-bot

moq-bot Bot commented Nov 14, 2026

Copy link
Copy Markdown
Contributor

quest land watch: the merge queue removed this pull request at 6e61841 because its merge_group build failed (failed_checks).

The land fixer works on it in the background, and the watcher re-enqueues it at the back of the queue once it is fixed or judged flaky, or hands it back here with what it needs.

Queue / Queue (job) failure at step Check:

…y hop it plays
moq-doc check: (pass) audio stretch corpus > silence > moves the output by exactly the shifts it took
moq-doc check: (pass) audio stretch corpus > stereo-linked > matches the checked-in case [0.14ms]
moq-doc check: (pass) audio stretch corpus > stereo-linked > decides every hop it plays
moq-doc check: (pass) audio stretch corpus > stereo-linked > moves the output by exactly the shifts it took
moq-doc check: (pass) audio stretch corpus > stereo-opposite > matches the checked-in case [0.13ms]
moq-doc check: (pass) audio stretch corpus > stereo-opposite > decides every hop it plays
moq-doc check: (pass) audio stretch corpus > stereo-opposite > moves the output by exactly the shifts it took
moq-doc check: (pass) audio stretch corpus > bridge-44100 > matches the checked-in case [0.10ms]
moq-doc check: (pass) audio stretch corpus > bridge-44100 > decides every hop it plays [0.01ms]
moq-doc check: (pass) audio stretch corpus > bridge-44100 > moves the output by exactly the shifts it took [0.03ms]
moq-doc check: (pass) audio stretch corpus > bridge-48000 > matches the checked-in case [0.10ms]
moq-doc check: (pass) audio stretch corpus > bridge-48000 > decides every hop it plays
moq-doc check: (pass) audio stretch corpus > bridge-48000 > moves the output by exactly the shifts it took
moq-doc check: (pass) audio stretch corpus > speed-up-16000 > matches the checked-in case [0.13ms]
moq-doc check: (pass) audio stretch corpus > speed-up-16000 > decides every hop it plays
moq-doc check: (pass) audio stretch corpus > speed-up-16000 > moves the output by exactly the shifts it took
moq-doc check: 
moq-doc check: ::endgroup::
moq-doc check: 
moq-doc check:  198 pass
moq-doc check:  0 fail
moq-doc check:  24654 expect() calls
moq-doc check: Ran 198 tests across 5 files. [15.16s]
moq-doc check: �[96m../js/net/src/lite/subscriber.test.ts�[0m:�[93m1662�[0m:�[93m51�[0m - �[91merror�[0m�[90m TS2304: �[0mCannot find name 'HopSchema'.
moq-doc check: 
moq-doc check: �[7m1662�[0m  const subscriber = new Subscriber(quic, version, HopSchema.parse(1n));
moq-doc check: �[7m    �[0m �[91m                                                  ~~~~~~~~~�[0m
moq-doc check: 
moq-doc check: �[96m../js/net/src/lite/subscriber.test.ts�[0m:�[93m1724�[0m:�[93m51�[0m - �[91merror�[0m�[90m TS2304: �[0mCannot find name 'HopSchema'.
moq-doc check: 
moq-doc check: �[7m1724�[0m  const subscriber = new Subscriber(quic, version, HopSchema.parse(1n));
moq-doc check: �[7m    �[0m �[91m                                                  ~~~~~~~~~�[0m
moq-doc check: 
moq-doc check: �[96m../js/net/src/lite/subscriber.test.ts�[0m:�[93m1781�[0m:�[93m51�[0m - �[91merror�[0m�[90m TS2304: �[0mCannot find name 'HopSchema'.
moq-doc check: 
moq-doc check: �[7m1781�[0m  const subscriber = new Subscriber(quic, version, HopSchema.parse(1n));
moq-doc check: �[7m    �[0m �[91m                                                  ~~~~~~~~~�[0m
moq-doc check: 
moq-doc check: �[96m../js/net/src/lite/subscriber.test.ts�[0m:�[93m1828�[0m:�[93m51�[0m - �[91merror�[0m�[90m TS2304: �[0mCannot find name 'HopSchema'.
moq-doc check: 
moq-doc check: �[7m1828�[0m  const subscriber = new Subscriber(quic, version, HopSchema.parse(1n));
moq-doc check: �[7m    �[0m �[91m                                                  ~~~~~~~~~�[0m
moq-doc check: 
moq-doc check: �[96m../js/net/src/lite/subscriber.test.ts�[0m:�[93m1905�[0m:�[93m51�[0m - �[91merror�[0m�[90m TS2304: �[0mCannot find name 'HopSchema'.
moq-doc check: 
moq-doc check: �[7m1905�[0m  const subscriber = new Subscriber(quic, version, HopSchema.parse(1n));
moq-doc check: �[7m    �[0m �[91m                                                  ~~~~~~~~~�[0m
moq-doc check: 
moq-doc check: �[96m../js/net/src/lite/subscriber.test.ts�[0m:�[93m1952�[0m:�[93m51�[0m - �[91merror�[0m�[90m TS2304: �[0mCannot find name 'HopSchema'.
moq-doc check: 
moq-doc check: �[7m1952�[0m  const subscriber = new Subscriber(quic, version, HopSchema.parse(1n));
moq-doc check: �[7m    �[0m �[91m                                                  ~~~~~~~~~�[0m
moq-doc check: 
moq-doc check: �[91m[error]�[0m Failed to convert one or more packages, result will not be merged together
moq-doc check: 121 | 		if (app.logger.hasErrors() || app.logger.hasWarnings()) {
moq-doc check: 122 | 			throw new Error(`TypeDoc: ${app.logger.errorCount} errors and ${app.logger.warningCount} warnings`);
moq-doc check: 123 | 		}
moq-doc check: 124 | 	};
moq-doc check: 125 | 	const project = await app.convert();
moq-doc check: 126 | 	if (!project) throw new Error("TypeDoc: conversion failed");
moq-doc check:                                ^
moq-doc check: error: TypeDoc: conversion failed
moq-doc check:       at generate (/var/cache/github-runner-work/moq/moq/doc/.vitepress/api/index.ts:126:26)
moq-doc check: 
moq-doc check: ::error file=doc/.vitepress/api/index.ts,line=126,col=26,title=error: TypeDoc%3A conversion failed::%0A      at generate (/var/cache/github-runner-work/moq/moq/doc/.vitepress/api/index.ts:126:26)
moq-doc check: 
moq-doc check: Bun v1.4.4 (Linux x64)
moq-doc check: �[31mfailed to load config from /var/cache/github-runner-work/moq/moq/doc/.vitepress/config.ts�[39m
moq-doc check: �[31mbuild error:�[39m
moq-doc check: Command failed: bun /var/cache/github-runner-work/moq/moq/doc/.vitepress/api/index.ts
moq-doc check: Error: Command failed: bun /var/cache/github-runner-work/moq/moq/doc/.vitepress/api/index.ts
moq-doc check:     at genericNodeError (node:internal/errors:986:15)
moq-doc check:     at wrappedFn (node:internal/errors:540:14)
moq-doc check:     at checkExecSyncError (node:child_process:942:11)
moq-doc check:     at execFileSync (node:child_process:978:15)
moq-doc check:     at file:///var/cache/github-runner-work/moq/moq/node_modules/.vite-temp/config.ts.timestamp-1794686496503-b870597933cc4.mjs:269:1
moq-doc check:     at ModuleJob.run (node:internal/modules/esm/module_job:561:25)
moq-doc check:     at async node:internal/modules/esm/loader:647:26
moq-doc check:     at async loadConfigFromBundledFile (file:///var/cache/github-runner-work/moq/moq/node_modules/vitepress/node_modules/vite/dist/node/chunks/dep-CkSfqg8D.js:49778:15)
moq-doc check:     at async bundleAndLoadConfigFile (file:///var/cache/github-runner-work/moq/moq/node_modules/vitepress/node_modules/vite/dist/node/chunks/dep-CkSfqg8D.js:49621:22)
moq-doc check:     at async loadConfigFromFile (file:///var/cache/github-runner-work/moq/moq/node_modules/vitepress/node_modules/vite/dist/node/chunks/dep-CkSfqg8D.js:49584:44)
moq-doc check: Exited with code 1
Traceback (most recent call last):
  File "/var/cache/github-runner-work/moq/moq/js/../sh/js/workspace.py", line 263, in <module>
    main()
    ~~~~^^
  File "/var/cache/github-runner-work/moq/moq/js/../sh/js/workspace.py", line 258, in main
    run(action, plan)
    ~~~^^^^^^^^^^^^^^
  File "/var/cache/github-runner-work/moq/moq/js/../sh/js/workspace.py", line 211, in run
    scripts("check")
    ~~~~~~~^^^^^^^^^
  File "/var/cache/github-runner-work/moq/moq/js/../sh/js/workspace.py", line 139, in scripts
    command("bun", "run", *concurrency, *filters, "--elide-lines=0", verb)
    ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/cache/github-runner-work/moq/moq/js/../sh/js/workspace.py", line 131, in command
    subprocess.run(args, cwd=cwd, check=True)
    ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/nix/store/xahxrjs30p3mw0a42bqg9ikgkikskw8m-python3-3.14.8/lib/python3.14/subprocess.py", line 578, in run
    raise CalledProcessError(retcode, process.args,
                             output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '('bun', 'run', '--filter=@moq/audio-quality', '--filter=@moq/bench-browser', '--filter=@moq/crypto', '--filter=@moq/demo', '--filter=@moq/demo-boy', '--filter=@moq/demo-carla', '--filter=@moq/hang', '--filter=@moq/interop-browser', '--filter=@moq/interop-native', '--filter=@moq/json', '--filter=@moq/loc', '--filter=@moq/msf', '--filter=@moq/net', '--filter=@moq/p2p', '--filter=@moq/p2p-test', '--filter=@moq/publish', '--filter=@moq/qmux', '--filter=@moq/qmux-interop', '--filter=@moq/receive-credit-test', '--filter=@moq/room', '--filter=@moq/stats', '--filter=@moq/stream-credit-test', '--filter=@moq/video-test', '--filter=@moq/watch', '--filter=moq-doc', '--elide-lines=0', 'check')' returned non-zero exit status 1.
error: recipe `check-changed` failed on line 36 with exit code 1
##[endgroup]
##[error]ci: check js failed
ci: wall and CPU seconds per module
    29      40  check biome
    89     222  check js (failed)
    12       5  check quest
    35      27  check shell
     1       0  check large_files
     2       0  check text
     1       0  check toml
     5       3  check nix
     0       0  check justfile
   118     300  whole run
error: recipe `ci` failed on line 119 with exit code 1
##[error]Process completed with exit code 1.
##[group]Run actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9
with:
  name: cargo-timings
  path: target/cargo-timings/cargo-timing-*.html
  if-no-files-found: ignore
  retention-days: 14
  compression-level: 6
  overwrite: false
  include-hidden-files: false
  archive: true
env:
  BASE: 7a4190608da40f53c7c6e493122f4bdc30f5218f
  CHECK_FAIL_FAST: 1
  NEXTEST_TEST_THREADS: 24
  MBX_CACHE_LINKS: 1
  MBX_REMOTE_URL: 
##[endgroup]
No files were found with the provided path: target/cargo-timings/cargo-timing-*.html. No artifacts will be uploaded.
Post job cleanup.
##[start-action display=Run jdx/mr-boxington-action@88acf2bb50552c7c508cbac13e5f8c576b95b1de;id=__9a779419-ce88-4d31-abdf-a7242ab9e8eb.mbx]
##[end-action id=__9a779419-ce88-4d31-abdf-a7242ab9e8eb.mbx;outcome=skipped;conclusion=skipped;duration_ms=0]
Post job cleanup.
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git version
git version 2.56.0
Temporarily overriding HOME='/var/cache/github-runner-work/_temp/d5d39e1c-6499-4bc4-940d-5ad3f1814ab6' before making global git config changes
Adding repository directory to the temporary git global config as a safe directory
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --global --add safe.directory /var/cache/github-runner-work/moq/moq
Removing SSH command configuration
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --local --name-only --get-regexp core\.sshCommand
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :"
Removing HTTP extra header
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :"
Removing includeIf entries pointing to credentials config files
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --local --name-only --get-regexp ^includeIf\.gitdir:
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git submodule foreach --recursive git config --local --show-origin --name-only --get-regexp remote.origin.url
A job completed hook has been configured by the self-hosted runner administrator
##[group]Run '/nix/store/3wq9f25mz2ksqrx6zs5nq522386djzw1-ci-cache-gc.sh/bin/ci-cache-gc.sh'
shell: /nix/store/lfm00fnq66xfgbn099vqckabyl5jllz6-bash-interactive-5.3p20/bin/bash --noprofile --norc -e -o pipefail {0}
##[endgroup]
evicted 0 objects and 0 action results (0 B logical); 49.8 GiB logical remain
evicted 0 objects and 0 action results (0 B logical); 49.8 GiB logical remain
Cleaning up orphan processes

(written by quest land watch)

@moq-bot

moq-bot Bot commented Nov 14, 2026

Copy link
Copy Markdown
Contributor

codex, gpt-6.1-sol, medium effort land fixer note:

The queue failed with TS2304 because six subscriber tests added on base still called HopSchema.parse after this PR replaced that constructor with toHop. Merged base and updated those six calls to toHop(1n), preserving their inputs and assertions. The full queue gate passed with nix develop --command just ci base, including lint, type checks, builds, API reports, and affected tests.

(written by codex, gpt-6.1-sol, medium effort)

@moq-bot

moq-bot Bot commented Nov 14, 2026

Copy link
Copy Markdown
Contributor

quest land watch: armed auto-merge on this pull request at daf3f69, so it joins the back of the merge queue once its required checks pass, with the land fixer's fix (codex, gpt-6.1-sol, medium effort): Merged base and completed the HopSchema.parse-to-toHop rename in six base-added tests; ran nix develop --command just ci base and git diff --check successfully..

(written by quest land watch)

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

I re-reviewed the two commits added since the last Pullfrog review.

  • Merged main: brought in six new tests in js/net/src/lite/subscriber.test.ts.
  • Finished the toHop rename: changed HopSchema.parse(1n) to toHop(1n) in those six tests. Nothing under js/ uses HopSchema any more.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

@moq-bot
moq-bot Bot added this pull request to the merge queue Nov 14, 2026
Merged via the queue into main with commit c3c561e Nov 14, 2026
8 checks passed
@moq-bot
moq-bot Bot deleted the quest/m1/js-bundle-audit branch November 14, 2026 22:18
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