Skip to content

🤖 perf: update zod to 4.6.5 - #6078

Merged
ThomasK33 merged 6 commits into
mainfrom
perf/zod-4.6.5-startup
Oct 10, 2026
Merged

ThomasK33 merged 6 commits into
mainfrom
perf/zod-4.6.5-startup

Conversation

@ThomasK33

@ThomasK33 ThomasK33 commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

Refs #6071. Depends on #6080 and #6087 (both merged): this branch is rebased onto them.

Summary

This PR updates zod from 4.4.3 to 4.6.5 and raises the package.json floor to ^4.6.5. zod 4.5 and 4.6 build schemas much faster. Most of the first-load main-*.js task in xum server is the evaluation of the entry module graph, and about half of that is zod schema construction.

The PR has six commits:

  1. perf: update zod to 4.6.5: package.json and bun.lock. The lockfile keeps one root zod copy. The nested 4.6.1 copies under the MCP SDK packages are gone.
  2. fix: keep tuple result types exact in code_execution declarations: one line in src/node/services/ptc/typeGenerator.ts, plus a regression test. Without it, the bump turns the attach_file result value into never[] in the code_execution type declarations.
  3. tests: pin persisted-data parsing across the zod 4.6 changes: two behavioral tests for persisted data that the new parse rules touch.
  4. fix: fail history rows with a strict-object __proto__ key, as zod 4.5 does: one line in src/node/services/historyMessageEvidence.ts. That streaming readability check copies zod's strict-object rules by hand, and it still let an own __proto__ key through. The existing differential test validates actual workflow variants, strict fields, and unbounded JSON values failed on the bump without it.
  5. fix: keep a code-point-safe prefix in streamed history evidence: the same check kept maxLength + 1 UTF-16 units of each string, but zod 4.6 counts string bounds in code points. A description of 1,025 emoji was cut to about 512 code points and looked readable. It now keeps 2 * (maxLength + 1) units, and a differential test compares it with the real parse at 1,024 and 1,025 code points for ASCII, emoji and mixed input (Codex finding, round 1).
  6. fix: keep minute-precision workflow timestamps readable under zod 4.6: IsoDateTimeSchema in orpc/schemas/workflow.ts and attemptDeadlineAt in types/evaluation.ts now use zod's documented union of both precisions (offset: true, with and without precision: -1). Without it, a run.json with a zoned timestamp without seconds became unreadable, and createRunIfAbsent then treated a deterministic child run as half-created and deleted its directory (Codex finding, round 2). Writers still use toISOString().

Performance

Local Lighthouse gate: pass. Head's desktop eval median is 86.5 ms, against 160.05 ms on base: 73.6 ms lower (the gate needs at least 50 ms). Every head run stays under the bounds: desktop at most 88.1 ms observed and 88 ms reported (bound 120 ms), mobile at most 363 ms reported (bound 480 ms). No run was disqualified.

D2 Desktop Cold Start: pass. On the current head (rebased onto #6087, no code changes): run 38086092991, base cd6aa8c7c6 (merge-base), head 21fc89cbee, 20 pairs. Mean change -5.17%, one-sided 95% upper bound -4.48% (gate: at most +5%), half-width 0.69%. Median markMs: base 765.2, head 724.0. Earlier heads: run 38083040151 on b876091e48 (mean -4.90%, upper bound -4.17%), run 38080882296 on c8262fd925 (mean -4.79%, upper bound -4.24%) and run 38073922951 on 368e36b5a2 (mean -6.14%, upper bound -4.66%).

Lighthouse auditor branch run (information, not a gate): head 21fc89cbee merged with main 0390895cc2, compared with the auditor's main cd6aa8c7c6 cycle. 0390895cc2 adds only #6082 (bug-bash test tooling, docs and one generated skill-content file). Lighthouse 13.5.0, 3 runs per page and form factor, all 12 head runs host-qualified. The host load average was higher than in earlier runs (13-24 on 32 CPUs, both sides). All 12 head runs are under the bounds. On main, 11 of 12 runs are over (seeded mobile run 1 was 449 ms).

Page and form factor Longest main-*.js task, head (ms) Same, main (ms) TBT, head vs main
First-run, mobile 354, 320, 323 750, 601, 578 270 vs 760 ms
First-run, desktop 82, 81, 90 188, 178, 141 30 vs 130 ms
Seeded, mobile 339, 329, 306 449, 556, 667 550 vs 710 ms
Seeded, desktop 80, 87, 78 160, 140, 140 60 vs 130 ms

LCP is unchanged. Served first-load JS grows by 7,496 bytes (brotli), almost all in the API-*.js chunk (+7,269), the same as on earlier heads. The auditor attributes this to zod 4.6.5 itself. Neither of us verified that.

Lighthouse method and every run

Setup: Lighthouse 13.5.0 against xum server --no-auth --host 127.0.0.1 under env -i, with a fresh XUM_ROOT and HOME and XUM_DISABLE_TELEMETRY=1, on the first-run page. Base and head ran as two servers at the same time, alternating run by run (8 desktop and 4 mobile each). Every build and measurement block ran under the shared host lock. "obsEval" is the main-*.js evaluation task in the trace. "LH main" is the task length Lighthouse reports (mobile is simulated with 4x CPU throttling).

I wrote the host qualification rule before any candidate run. A run is disqualified only by host data: Lighthouse failed, the auditor's Chrome overlapped, CPU pressure (/proc/pressure/cpu some avg10) above 10, or a load average above 16 (32 CPUs). The retry budget was one extra interleaved pair per preset. It was not needed.

A/A on base (two servers, same build): 0 of 24 runs disqualified. Desktop medians 155.8 and 155.15 ms (limit: within 10 ms). Mobile observed medians 154.65 and 157.45 ms (limit: within 40 ms). The host qualified.

side preset runs disqualified obsEval median obsEval max LH main median LH main max
A1 desktop 8 0 155.8 162.4 155.5 162.0
A1 mobile 4 0 154.64999999999998 156.3 619.0 625.0
A2 desktop 8 0 155.15 163.7 155.5 164.0
A2 mobile 4 0 157.45 166.3 630.0 665.0

Candidate, base vs head:

side preset run obsEval ms LH main-*.js ms layout in task TBT ms psi avg10 before/after load before/after qualified
base desktop 1 160.6 161.0 0 115.0 0.0/0.72 2.49/3.69 yes
head desktop 1 85.9 86.0 0 41.0 0.72/0.23 3.69/3.69 yes
base desktop 2 154.2 154.0 0 104.0 0.23/0.05 3.69/4.14 yes
head desktop 2 85.6 86.0 0 41.0 0.05/0.01 4.14/4.97 yes
base desktop 3 162.9 163.0 0 119.0 0.01/0.0 4.97/5.58 yes
head desktop 3 85.1 85.0 0 41.0 0.0/0.08 5.58/6.3 yes
base desktop 4 149.3 149.0 0 105.0 0.08/0.01 6.3/8.03 yes
head desktop 4 87.7 88.0 0 43.0 0.01/0.0 8.03/7.8 yes
base desktop 5 159.5 159.0 0 109.0 0.0/0.0 7.8/7.36 yes
head desktop 5 87.1 87.0 0 37.0 0.0/0.0 7.36/7.07 yes
base desktop 6 385.8 193.0 1 237.0 0.0/3.69 7.07/8.83 yes
head desktop 6 88.1 88.0 0 38.0 3.69/0.91 8.83/7.89 yes
base desktop 7 161.6 162.0 0 117.0 0.91/0.22 7.89/7.42 yes
head desktop 7 87.1 87.0 0 38.0 0.22/0.05 7.42/6.9 yes
base desktop 8 151.1 151.0 0 106.0 0.05/0.06 6.9/6.94 yes
head desktop 8 85.0 85.0 0 41.0 0.06/0.01 6.94/6.16 yes
base mobile 1 158.3 633.0 0 652.0 0.01/0.0 6.16/5.6 yes
head mobile 1 88.3 353.0 0 454.0 0.0/0.0 5.6/4.98 yes
base mobile 2 155.7 623.0 0 642.0 0.0/0.46 4.98/5.87 yes
head mobile 2 90.9 363.0 0 452.0 0.46/0.11 5.87/5.23 yes
base mobile 3 147.9 591.0 0 608.0 0.11/0.02 5.23/4.7 yes
head mobile 3 87.0 348.0 0 428.0 0.02/0.0 4.7/4.9 yes
base mobile 4 155.3 621.0 0 638.0 0.0/0.18 4.9/4.55 yes
head mobile 4 87.0 348.0 0 432.0 0.18/0.04 4.55/4.05 yes
side preset runs disqualified obsEval median obsEval max LH main median LH main max
base desktop 8 0 160.05 385.8 160.0 193.0
base mobile 4 0 155.5 158.3 622.0 633.0
head desktop 8 0 86.5 88.1 86.5 88.0
head mobile 4 0 87.65 90.9 350.5 363.0

Base desktop run 6 had a host stall (observed 385.8 ms, a Layout inside the task, pressure 3.69 after the run). It is under the disqualification limits, so it stays in the record. It changes neither the base median nor any head result.

zod changelog audit (4.4.3 to 4.6.5)

I read the release notes for 4.5.0 through 4.6.5. Each row is a behavior change, Xum's use of the affected API, and the disposition.

Change (zod PR) Xum use Disposition
z.iso.datetime() with a zone requires seconds (#6457) IsoDateTimeSchema in orpc/schemas/workflow.ts (about 24 fields), evaluation.ts attemptDeadlineAt, sessionTape.ts startedAt. Every producer writes toISOString(). Restored for workflow records (commit 6): run.json, journal lines and evaluation deadlines with minute precision stay readable, as on zod 4.4. sessionTape.ts startedAt keeps the new rule: only the recorder writes it, with toISOString(), and a rejected header only skips that tape.
String .min()/.max()/.length() count code points (#6441) 3 tool-definition string bounds (.min(2), .min(5)), refinement.ts sha256 .length(64) (hex). Accept. .max() only loosens. The .min() bounds apply to model text and are tiny.
Record keys and intersections match TypeScript (#6412) 2 intersections (agents.get, agentSkills.get inputs). Regex-keyed records in config. Accept. The intersection inputs now fold into one object in JSON Schema (see the schema table). The refine on the left side still runs.
unrecognized_keys no longer aborts the object (#2200) About 296 .strict() objects, including tool inputs. Accept. A strict input with an extra key and a bad value now reports both issues. Tool error text gets more complete.
__proto__ is always stripped, and .strict() reports an own __proto__ key (#6386, #6221) Strict tool inputs, lenient userPreferences records. evaluation.ts already rejects __proto__. Accept. 10 strict tool inputs now reject an own __proto__ key. Commit 4 makes historyMessageEvidence agree with the real parse. New config-loading test pins that lenient preferences drop the key without adopting a prototype.
Stricter string formats: ipv6, ulid, httpUrl, emoji (#6442, #6095, #6035, #6532) No use of these formats. Not affected.
JSON Schema: closed tuples emit items: false / additionalItems: false (#6194) Tool result schemas, oRPC OpenAPI, code_execution types. Fixed in commit 2. json-schema-to-typescript reads only draft-7 tuples, so result types now use target: "draft-7".
JSON Schema: chained checks fold as a conjunction (#6554) session_history.offset_chars (.int().min(0)). Accept. The advertised minimum changes from -MAX_SAFE_INTEGER to 0, which is what runtime already enforced.
JSON Schema: nullable as a type array (type: [X, "null"]) instead of anyOf 22 .nullish() tool inputs per route. Accept. See "Provider routes".
Error maps run on first read of error (#6519) No z.config or error-map use. Not affected.
Numeric enum .options drop reverse mappings (#6542) No z.enum over a TypeScript enum. Not affected.
base64 and email patterns rewritten (#6534) No use. Not affected.
Metadata members (.minLength and others) become prototype getters (#6554). Methods live on the prototype (4.5). src/cli/proxifyOrpc.ts clones a schema with a spread. Accept. proxifyOrpc tests pass, and the CLI help comparison over 357 commands shows only help-text changes.
catch and prefault fixes (#6192, #6440, #6587) lenient() in userPreferences.ts, .optional().catch(undefined) in message.ts and telemetry.ts. Accept. A differential parse on base and head was unchanged on the tested corpus: 44,596 real chat.jsonl rows, real config files and damaged variants of them.

Provider-facing schema comparison

I dumped every tool definition through the real provider conversion paths (getToolsForModel and AI SDK prepareTools for OpenAI Responses, OpenAI Chat, Anthropic and Google), the oRPC OpenAPI document, and the code_execution type declarations, on base (4.4.3) and head (4.6.5). After I normalize anyOf: [{type: X}, {type: "null"}] to type: [X, "null"], these differences remain:

Surface Difference Count Cause Evidence
Tool inputs, every route nullable anyOf becomes a type array 22 fields zod JSON Schema output live calls below
Tool inputs, every route session_history.offset_chars minimum -9007199254740991 becomes 0 1 field (per route) #6554 runtime already enforced 0
Tool result schemas closed tuples gain minItems, maxItems, additionalItems: false 6 #6194 commit 2 test
oRPC OpenAPI workflow datetime fields become anyOf of two strings: the seconds form (with format: date-time) and a minutes-only pattern 3,072 commit 6 (zod's union for #6457) commit 6 tests
oRPC OpenAPI closed tuples gain items: false 18 #6194 none needed (documentation only)
oRPC OpenAPI workflow descriptor required gains scope 12 z.preprocess now reports required runtime already rejected a missing scope
oRPC OpenAPI agents.get and agentSkills.get allOf fold into one object 2 #6412 the xum api agents get --help output now lists real flags instead of --input [json]
code_execution types attach_file result value: unknown[] becomes the exact tuple union 1 commit 2 ptc-types-diff

Parse changes that touch persisted data

  1. Minute-precision ISO datetimes with a zone (2026-05-29T00:01Z): zod 4.5 rejects them. Commit 6 keeps them readable in workflow records, as zod 4.4 did. The new WorkflowRunStore.test.ts cases check that a minute-precision run.json stays readable through getRun and getRunStatusSnapshot, that createRunIfAbsent keeps the existing run directory and journal, and that minute-precision journal lines stay. A workflow.test.ts case covers attemptDeadlineAt. All of them fail on c8262fd925 (before commit 6) and pass with it. Xum writes every timestamp with toISOString(), and none of the 5,580 workflow files on this host had minute precision.
  2. Strict tool inputs reject an own __proto__ key. This only affects model tool calls, not persisted data.
  3. A strict object with an unknown key and a bad value reports both issues.
  4. String .min() and .length() count code points.

The lenient userPreferences test passes on base and on head. It guards the __proto__ and record changes: the loader keeps dropping only the bad entries, and no __proto__ key becomes a prototype.

Provider routes

Tool input schemas now carry nullable fields as type: [X, "null"] (22 fields per route). I checked every route Xum supports:

Route Adapter behavior Result
Anthropic (direct) pass-through Live-verified. claude-haiku-5-5 accepted the head tool set and returned a valid session_history call with nulls.
OpenAI Responses pass-through Live-verified. gpt-6-luna accepted the head tool set and returned a valid call.
Google Gemini AI SDK sends parametersJsonSchema Live-verified. gemini-3.8-flash (direct API) accepted all 39 functions, including the 22 type arrays, and returned a valid call. Google's structured-output docs accept {"type": ["string","null"]}, and FunctionDeclaration.parametersJsonSchema takes JSON Schema.
xAI @ai-sdk/xai drops additionalProperties: false only Contract-verified, not live-verified. xAI's docs accept a type array for nullable fields.
Ollama (built-in ollama: route) #6080 rewrites every type array to the equivalent anyOf at the model boundary Covered for old servers. Servers before v0.6.6 (ollama/ollama#9434) parse type only as a string. With zod 4.6.5 on this branch, the captured /api/chat body for the real ollama: tool set has 39 tools and 0 type arrays. The custom openai-compatible route (for example an old Ollama /v1 endpoint, which decodes the same Go structs) gets the same rewrite since #6087. With zod 4.6.5 on this branch, a custom openai-compatible provider with the real tool set sends 39 tools and 0 type arrays.
Amazon Bedrock @ai-sdk/amazon-bedrock passes the schema through as toolSpec.inputSchema.json Not verified. Bedrock documents the field as JSON Schema with no subset. Xum does not set strict. I have no Bedrock key, and I did not check how each Bedrock model family (Nova, Llama, Mistral) handles type arrays.
OpenRouter @openrouter/ai-sdk-provider passes the schema through Not verified. OpenRouter does not document how it rewrites schemas for each upstream provider. I have no OpenRouter key.

Xum sets no tool-level strict on any of these routes, so no restricted strict-mode dialect applies. Live probe cost: one request per provider per side, about 34k input and 0.6k output tokens per side in total. I estimate under $0.10. I did not check invoices.

Validation

  • On the current head b876091e48: make static-check and make typecheck pass (React Compiler line stays at 23/24). The workflow (store, runner, schema, evaluation), evidence, PTC, config and providerModelFactory suites pass: 1,301 tests in 36 files.
  • make test on 368e36b5a2 (before the code-point fix and the rebase): 24,793 pass, 3 fail. The 3 failures also fail on base 4a181066f4 on this host: 2 taskGitPatchEngine tests (the global init.templateDir points to a missing directory, so .git/info does not exist) and BackupRepoCache > does not transfer 200 commits… (5 s timeout under load). The one "unhandled error between tests" comes from that timed-out test.
  • Browser bundle: source maps list one zod root (node_modules/zod) on base and on head.
  • Regression proofs:
    • code_execution types: the new typeValidator.test.ts case fails on the bump without commit 2 (Property 'type' does not exist on type 'never') and passes with it. The generated-type comparison base vs head differs only in the attach_file tuple.
    • Workflow timestamps: the WorkflowRunStore.test.ts and workflow.test.ts minute-precision cases fail on c8262fd925 and pass with commit 6. With only the workflow.ts change reverted, the store cases fail. With only the evaluation.ts change reverted, the attemptDeadlineAt case fails.
    • historyMessageEvidence.test.ts: 10 of 10 pass on head with commits 4 and 5. With commit 4 on base (zod 4.4.3), the suite fails, so the fix belongs with the bump. Without commit 5, the new code-point test fails.
  • xum <cmd> --help for 357 CLI commands, base vs head: only help text changes. Nullable flags read "type: string or null", and agents get and agent-skills get list real flags instead of --input [json].

Dogfood

Head build, env -i server on 127.0.0.1 with XUM_MOCK_AI=1 (a fake Anthropic key on a dead loopback port, as the bug-bash seed does, because the composer needs a configured provider):

  1. The onboarding dialog opens at "Xum Gateway (evaluation credits)", step 1 of 7. I stepped through all 7 steps and added a project in step 3.
  2. The runtime picker lists Local, Worktree, SSH, Docker and Dev container. I created a Local workspace and sent a message. The mock reply arrived.
  3. I stopped the server, appended an agent_skill_list card and a workflow_run card to the workspace's chat.jsonl, and restarted. Both cards render. The expanded skill card groups the skills by scope.
  4. Reload: the transcript hydrates. The page and the console show no errors.

Screenshots at 1440 px and 390 px and a video of the whole run are in a comment below.


Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high • Cost: $23.89

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 10, 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-10-10T21:26:32.304146Z 21fc89c Manual request
🔒 Security Review ✅ Completed 2026-10-10T21:29:00.334631Z 21fc89c 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.

@ThomasK33

ThomasK33 commented Oct 10, 2026 •

Copy link
Copy Markdown
Member Author

Dogfood evidence for the head build (368e36b5a2), xum server under env -i with XUM_MOCK_AI=1. Steps are in the PR body under "Dogfood".

  1. The onboarding dialog opens at step 1 of 7.

Onboarding at step 1 of 7, 1440 px

  1. The runtime picker on the new-workspace screen.

Runtime picker, 1440 px

  1. A mock message in a Local workspace.

Mock reply, 1440 px

  1. After a restart and a reload: the seeded agent_skill_list and workflow_run cards render, and the skill card expands.

Seeded cards after reload, 1440 px

  1. The same transcript at 390 px, and the home screen at 390 px.

Transcript at 390 px
Home at 390 px

Video of the whole run (108 s):

dogfood.mp4

Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high • Cost: $23.89

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@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: 368e36b5a2

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.

@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: 368e36b5a2

ℹ️ 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 package.json
Comment thread package.json
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

Please take another look. The branch is rebased onto main with the Ollama prerequisite #6080. Both round-1 findings are fixed (replies on the threads).

@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: c8262fd925

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.

@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: c8262fd925

ℹ️ 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 package.json
Raise the zod floor to ^4.6.5 and dedupe the MCP packages onto the root copy.

Refs #6071
zod >= 4.5 emits closed tuples as prefixItems + items:false, which
json-schema-to-typescript renders as never[]. Emit draft-7 for result types.

Refs #6071
Workflow journals skip a line whose timestamp lacks seconds (zod >= 4.5
rejects minute precision) and keep the run readable. Lenient
userPreferences loading drops __proto__ keys and invalid record entries
without adopting a prototype.

Refs #6071
….5 does

zod >= 4.5 `.strict()` reports an own `__proto__` key as unrecognized
(colinhacks/zod#6221). The streaming readability evidence still skipped
that key in strict contexts, so it called rows readable that the real
parse rejects.

Refs #6071
zod >= 4.5 counts string bounds in code points. The streamed evidence kept
maxLength + 1 UTF-16 units, so a description of 1,025 emoji was cut to
about 512 code points and looked readable. Keep 2 * (maxLength + 1) units,
which always hold one code point past the bound, and test the bound
against the real parse for ASCII, emoji and mixed input.

Refs #6071
zod >= 4.5 rejects a zoned datetime without seconds ("2026-05-29T00:01Z"),
which zod 4.4 accepted. A run.json with one became unreadable, and
createRunIfAbsent then treated the run as half-created and deleted it.
Workflow timestamps and the evaluation attemptDeadlineAt now use zod's
documented union of both precisions. Writers still use toISOString.

Refs #6071
@ThomasK33
ThomasK33 force-pushed the perf/zod-4.6.5-startup branch from b876091 to 21fc89c Compare October 10, 2026 21:02
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

Perf owner: this head is a rebase of the approved b876091 onto main (with #6080 and #6087) and has no code changes. The merge-base-relative diff is byte-identical. The automatic review on this head completed with no findings but left no approval, so I am requesting one explicit review. Review ledger for this PR: Codex runs on 368e36b, c8262fd (automatic plus manual), b876091 and 21fc89c (automatic), so this request is run 6 of the six-round limit. If it finds anything or completes without an approval, the PR stops unmerged and I record the blocker. No further request will follow.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: 21fc89cbee

ℹ️ 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: 21fc89cbee

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 Oct 10, 2026
Merged via the queue into main with commit 40de096 Oct 10, 2026
33 checks passed
@ThomasK33
ThomasK33 deleted the perf/zod-4.6.5-startup branch October 10, 2026 21:43
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