Skip to content

🤖 fix: start the perf servers with a per-server token instead of --no-auth - #7908

Merged
ThomasK33 merged 7 commits into
mainfrom
fix/dev-server-perf-token
Nov 3, 2026
Merged

ThomasK33 merged 7 commits into
mainfrom
fix/dev-server-perf-token

Conversation

@ThomasK33

@ThomasK33 ThomasK33 commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

Summary

Four perf scripts started xum server --no-auth on a loopback port, which every local account can reach. Each now starts the server with a per-server random token in its environment, the same way make dev-server does since #7904. The skill gets the argv-free browser open, -s on the curl example, and a fix for a sentence that was stale.

Background

make dev-server stopped using --no-auth in #7904, with the perf scripts named there as the same class of issue. scripts/perf/{pageTiming,firstRunViewParity,generatePhoneChrome}.ts and scripts/perf/workspace-scale/run-server-bench.ts still passed --no-auth for their short-lived servers. run-server-bench runs in perf-profiles.yml through make perf-workspace-scale. The bug-bash container and the test harness (src/node/services/sessionLocks/backendKill.testHarness.ts) also start --no-auth servers. They are not in this PR.

Implementation

  • scripts/perf/serverToken.ts has newServerToken() (32 random bytes, hex) and withServerToken(url, token).
  • Each script sets the token in the server's env (serverTokenEnv: XUM_SERVER_AUTH_TOKEN and the legacy MUX_SERVER_AUTH_TOKEN, written by assignXumEnvironmentValue) and drops --no-auth. The token is never in argv.
  • The three browser scripts navigate with ?token=, which the app and the static views already read. pageTiming keeps the URL in its per-run record without the token. firstRunViewParity now matches its route by path, because the URL has a query. run-server-bench sends a bearer header.
  • Skill, .xum/skills/dev-server-sandbox/SKILL.md:

Validation

Red first: scripts/perf/serverToken.test.ts failed because the module did not exist, then passed.

Each script ran with auth on. A /proc probe watched every xum server that a script started: no --no-auth in argv, a 64-character token in the environment only, and an unauthenticated POST /api/config/getConfig returned 401.

  • generatePhoneChrome --check: passes ("phone chrome skeleton matches the live page").
  • pageTiming --base <tree> --head <tree> --pages p1,p2 with one tree for both arms: exit 0. The probe saw 64 servers, all returned 401, and 0 of the 64 per-run records contain a token.
  • run-server-bench on a 50-workspace fixture (--repetitions 1 --launches 1): completed and wrote its results.
  • firstRunViewParity exits 1 on this host with the same shell pixel diffs as the copy of the script on main (for example 390-dark: shell: 490 pixels off by more than 16 at x,y,w,h 13,15,14,14 in both). I did not find the cause. No workflow runs this script.

Browser-open output (round 4 fix): I ran the skill's recipe as written against a sandbox with a token of Xq+9/aZ=_proof&k#z and saved stdout and stderr:

  • Real agent-browser, success: 0 bytes on stdout and stderr, 0 hits for the raw and the URL-encoded token. The page loaded authenticated (the first-run provider dialog, not "Authentication Required") and its URL had no token.
  • A stand-in agent-browser that echoes the opened URL with the token, as the batch can: the old recipe printed it (1 hit for the encoded token). The new recipe printed nothing with exit 0, and with exit 1 it printed http://localhost:<port>/?token=<redacted> (0 hits).
  • On this host the real batch printed the URL after the app had stripped the token, so I could not make the old recipe leak with the real tool in 6 runs. The leak depends on timing.

Argv-free browser open: sandbox token Xq+9/aZ=_proof&k#z, so the raw and URL-encoded forms differ. A /proc scanner and strace -f --seccomp-bpf -e trace=execve covered the chain, including the agent-browser daemon and Chrome with its helper processes.

  • The new form (the skill's snippet), two runs: 0 execve calls and 0 scanner hits with the token in either form. The app loaded authenticated, and the page URL afterwards had no token.
  • The old form (agent-browser open "<url>") as a control: the execve of the agent-browser client carried the encoded token, and the scanner hit on it. Chrome's argv held neither the token nor any URL in either form.
  • The scanner polls about every 30 ms, so strace is the authority for short-lived processes.

make static-check, make lint-eslint, make crap-check and make dry-check pass. scripts/perf/, scripts/devServerAuth.test.ts and scripts/rlm-eval/ give 284 tests: 282 passed on the first run here, and the two desktopColdStart tests hit bun's 5 s default timeout on a cold tsx start in a fresh checkout under load. They pass with a longer timeout and on a warm rerun.

Risks

  • The scripts now need a server that reads a server auth token from its environment. The --tree comparisons can start trees from before the Xum rename (🤖 feat: transition product identity from Mux to Xum #3903), which read only MUX_SERVER_AUTH_TOKEN, so the scripts set both names. A unit test covers the two names. I did not run a real pre-rename build.
  • The token is not a secret from the user who runs the script: it is in the server's environment and in the browser URL. The change keeps out the other local accounts, not the same user.

Generated with xum • Model: anthropic:claude-sonnet-5-5 • Thinking: xhigh

Red: scripts/perf/serverToken.ts does not exist yet.
…-auth

pageTiming, firstRunViewParity, generatePhoneChrome and run-server-bench started xum server with --no-auth on a loopback port that every local account can reach. Each now sets XUM_SERVER_AUTH_TOKEN in the server's env (never argv), navigates with ?token= (kept out of result files), or sends a bearer header.
…in argv

- The skill opens the app with `agent-browser batch`: node builds the `[["open", url]]` JSON with the token and the process pipes it on stdin. Neither node nor agent-browser nor Chrome gets the token as an argument. The old `agent-browser open "<url with token>"` puts it in the client's command line.
- The curl example gets `-s`.
- The Security notes no longer say that the sandbox backend runs with `--no-auth` (stale since the backend takes a token).
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 3, 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-11-03T22:47:49.145825Z 6af6bc2 Manual request
🔒 Security Review ✅ Completed 2026-11-03T22:51:07.692985Z 6af6bc2 Manual request
ℹ️ 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: 602a49edf5

ℹ️ 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 scripts/perf/pageTiming.ts Resolved
…UX_ name

The perf scripts start built trees from before the MUX_ to XUM_ rename for --tree comparisons. Those trees read only MUX_SERVER_AUTH_TOKEN, so the XUM_ token was ignored and the browser's token was refused. serverTokenEnv writes both names through assignXumEnvironmentValue.
@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

🟢 e2e stories (Haiku): 14 passed

22 agent steps · 7 replayed from cache · 15 model calls · 47.1k tokens (23% cached)
Spend: $0.09 of the $1.00 cap (proxy ledger)

All 14 tests in 9 files
Test Agent Time
🟢 chatRestart.e2e.ts · 1 passed 1 step · 1 call 5.8s
🟢 a chat survives a restart of the server 1 step · 1 call 5.8s
🟢 compaction.e2e.ts · 1 passed 1 step · 1 call 4.4s
🟢 /compact replaces the old chat with a summary 1 step · 1 call 4.4s
🟢 pluginTrustRestart.e2e.ts · 1 passed 4 steps · 2 calls 9.5s
🟢 a trusted plugin hook stays trusted after the server restarts 4 steps · 2 calls 9.5s
🟢 settingsRoundTrip.e2e.ts · 1 passed 2 steps · 1 call 8.6s
🟢 a chat survives trips through Settings 2 steps · 1 call 8.6s
🟢 sidebarPerWorkspace.e2e.ts · 1 passed 4 steps · 1 call 4.1s
🟢 a new workspace starts with its right sidebar collapsed while another keeps it open 4 steps · 1 call 4.1s
🟢 smoke.e2e.ts · 1 passed 2 steps · 1 call 3.1s
🟢 the agent opens the playground workspace 2 steps · 1 call 3.1s
🟢 streamErrors.e2e.ts · 1 passed 1 step · 1 call 8.7s
🟢 stream errors show in the chat, and the chat recovers 1 step · 1 call 8.7s
🟢 todoNudge.e2e.ts · 1 passed 1 step · 1 call 3.2s
🟢 the agent finishes open TODO items after the turn-end nudge 1 step · 1 call 3.2s
🟢 touchAlignment.e2e.ts · 6 passed 6 steps · 6 calls 22.3s
🟢 the Settings close button is level with the title on a touch screen 390px wide 1 step · 1 call 4.4s
🟢 the Settings close button is level with the title on a touch screen 768px wide 1 step · 1 call 4.0s
🟢 Backup settings checkboxes are small and level with their labels on a touch phone 1 step · 1 call 4.6s
🟢 the heartbeat checkbox is small and level with its label on a touch phone 1 step · 1 call 3.0s
🟢 a reply's model and time stay on one line on a touch phone 1 step · 1 call 3.5s
🟢 the workspace actions menu stays on the title row on a touch phone 1 step · 1 call 2.7s

e2e 0.20.0 · 1m 13s · web · run artifacts

🟢 e2e Electron stories (Haiku): 3 passed

3 agent steps · 3 model calls · 7.9k tokens (22% cached)
Spend: $0.02 of the $1.00 cap (proxy ledger)

All 3 tests in 3 files
Test Agent Time
🟢 electron/deepLink.e2e.ts · 1 passed 1 step · 1 call 6.0s
🟢 a deep link of a second launch starts a chat in the running app 1 step · 1 call 6.0s
🟢 electron/menuBar.e2e.ts · 1 passed 1 step · 1 call 5.7s
🟢 the workspace menu bar is the desktop title bar 1 step · 1 call 5.7s
🟢 electron/smoke.e2e.ts · 1 passed 1 step · 1 call 4.6s
🟢 Xum Electron opens the playground workspace 1 step · 1 call 4.6s

e2e 0.20.0 · 18.6s · electron · run artifacts

🟢 e2e agent repros (Haiku): no tests selected

Spend: $0.00 of the $1.00 cap (proxy ledger)

e2e 0.20.0 · 5.8s · 2 targets (web, phone) · run artifacts

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

Head: 43d4fa4

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 43d4fa485c

ℹ️ 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".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 43d4fa485c

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

…er skill

agent-browser batch prints the URL it opened, token included. The recipe now keeps that output in a variable and prints nothing on success, and prints it with the token removed on failure. Also fixes the stale --no-auth comment in dev-server-sandbox.ts.
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

Head: 6af6bc2

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: 6af6bc27fd

ℹ️ 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".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 6af6bc27fd

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@ThomasK33
ThomasK33 added this pull request to the merge queue Nov 3, 2026
Merged via the queue into main with commit 3eef95e Nov 3, 2026
33 of 34 checks passed
@ThomasK33
ThomasK33 deleted the fix/dev-server-perf-token branch November 3, 2026 23:13
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