Skip to content

[docs] Make v5 the default documentation version - #4498

Merged
VaguelySerious merged 15 commits into
mainfrom
peter/docs-v5-default
Sep 30, 2026
Merged

VaguelySerious merged 15 commits into
mainfrom
peter/docs-v5-default

Conversation

@VaguelySerious

Copy link
Copy Markdown
Member

Replaces #3714, which GitHub auto-closed on 2026-09-21 when #4267 merged and deleted the vitest-v5-follow-ups branch it had been retargeted onto. Same branch, same content, now based on main; #3714 cannot be reopened because its base branch is gone.

Makes v5 the default documentation version for the 5.0.0 GA, and catches the v5 content up with everything that landed on main since the v5 docs were last refreshed. Companion to #3090 (exit changeset pre mode) and #3091 (pin 4.x publishes to previous). #4267 has since merged, so its @workflow/vitest@beta install guidance is taken back to latest here rather than in a stack.

Version flip and routing

content/docs/v5 and content/worlds/v5 now serve unprefixed — /docs, /worlds, /cookbook — and v4 moves under a /v4 prefix. The versioned source config drives both route trees (the root tree always renders versionedSources.current), so this is a routePrefix move plus source re-binding, not a restructure. The only file moves are app/[lang]/v5/** → app/[lang]/v4/**.

  • Version switcher: labels are v5 (Latest) / v4 (Maintenance); current: 'v5'.
  • Banner: pre-release-banner.tsx → maintenance-banner.tsx. v4 pages carry an amber notice (with dark-mode styling) whose "Go to Workflow 5 (Latest)" link deep-links to the same page on the current version; v4-only pages land on the nearest section index via the fallback redirects. v4 pages keep robots: noindex, follow.
  • Redirects (docs/next.config.ts): /v5/* → unprefixed equivalent (permanent; bare /v5 gets its own rule because :path* expands to an empty Location otherwise). The world-docs and api-reference restructure rules are mirrored onto /v4/docs/*, and every page that exists in only one tree has a version-switcher fallback (verified by diffing the two content trees).
  • Worlds routes: both the unprefixed and /v4 worlds routes pass an explicit version into the shared page components, whose semantics flipped with the switch — smoke checks (assertWorldVersionMarkers, assertServesDirectly('/worlds/turso')) now guard the pairing so the canonical /worlds/* pages can't silently serve the maintenance version or self-redirect-loop again.
  • Link lint (docs/scripts/lint.ts): the two-space model swaps with the URL space; redirect destinations resolve against the real HTTP space since redirects are matched before render-time href rewriting.
  • Intentional oddity: rewriteHrefForVersion pulls unprefixed hrefs on v4 pages into the /v4 view, so a /v5/... href is the only way for v4 content to point at a current page. Three such links are kept deliberately; the lint models this.

What moves with the flip

  • whats-new enters the v5 sidebar, first in the tree. [docs] v5 GA content: What's new, World upgrade guide, migration skills #3100 adds the page but leaves it out of content/docs/v5/meta.json, so until this lands it is reachable only by URL.
  • upgrading-to-v5 moves from app/[lang]/v5/worlds/ to app/[lang]/worlds/, following the rest of the v5 worlds routes.
  • Two cross-version links become expressible and are restored. While v4 is the unprefixed version, a v5 page cannot link to a v4 page at all: an unprefixed href on a v5 page is rewritten into the /v5 view. [docs] v5 GA content: What's new, World upgrade guide, migration skills #3100 therefore phrases both as pointers to the version picker. Here they go back to being links — the v4 docs entry point in the What's new callout, and the v4 version of the code-transform page.
  • editPath on the unprefixed docs route points at docs/content/docs/v5/{path}.

Catch-up with main

Swept the 53 commits that landed since the last content refresh, and added what the docs were missing. Most changesets in that window are fixes, internal, or already documented by their own PR; three things were not.

Spec 7, the sealed log (#3634, not merged, default for v5). Positions are handed out ahead of the commit instead of being claimed by the write that fills them, so concurrent writers never contend and a wide fan-out stops serializing. The cost is a position whose writer dies, which the backend closes with a noop event that replay steps over without delivering it and without advancing the deterministic clock.

  • upgrading-to-v5 › Spec versions is rewritten around mintedSpecVersion(). The accepted range widens back to two versions, because a deployment with WORKFLOW_SEALED_LOG=0 stamps the one below, and that makes both SPEC_VERSION_CURRENT and SPEC_VERSION_SUPPORTS_SLOT_IDENTITY literals by another name for declaring it — neither follows the setting. This replaces what [docs] v5 GA content: What's new, World upgrade guide, migration skills #3100 said for spec 6, which was that exactly one version is accepted.
  • A new "Sealed logs and noop events" subsection says what this costs an implementer, which for most is nothing: a World allocating each position at the commit cannot leave a hole, so it never seals and never emits a noop. The obligation belongs to a World that pre-assigns positions; the half that binds everyone is the reader's.
  • WORKFLOW_SEALED_LOG is documented in runtime-tuning, taken verbatim from Add support for 'noop' event type - spec version 7 #3634 so whichever lands second is a no-op merge. The deep reference sections that PR writes — in event-sourcing and the World allocation contract — are left to it, so this does not duplicate them.
  • The migration skill (v0.2.0) gets the same treatment, phrased as findings to report rather than edits to make.

events.createBatch (#3025). An optional World method appending an ordered list of events in one durable write with per-event outcomes. It was documented only as a changelog page and an env var, so the World reference had no mention of a method a World author has to decide about. Added to the interface snippet, to the Key Implementation Details as a contract note (atomicity per attempt, what a World must reject, the one legal same-entity pair), to the upgrade guide's optional surface, and to the skill.

runs.waitForTerminalStatus (#3570). Also missing from the upgrade guide and the skill. It is what makes await run.returnValue a long poll rather than an interval, which is user-facing, so What's new gets that as an entry.

What's new also gains the batched suspension write and the positions change under faster-and-cheaper runs, where they belong: neither has any API surface.

Not addressed. workflow.step.execute.duration, the OpenTelemetry histogram from #3526, has nowhere to go — the docs carry no metrics reference at all, and inventing one for a single metric is a bigger call than this sweep. Flagging rather than guessing.

Second catch-up: the WebSocket default and spec 7

Merged main again (13 commits). Four conflicts, all against #3704's writing-standards pass over the whole corpus, which rewrote the same paragraphs this branch had edited. Took main's normalized text wherever the difference was purely style, kept this branch's meaning where the two disagreed (the spec-7 paragraph main still had at spec 6, the /v4/... link the flip makes expressible, the batch-write contract note), and restyled this branch's own additions so no prose em dashes come back with it.

The WebSocket events transport is the default now. #3702 flipped it and updated worlds.mdx, vercel.mdx and runtime-tuning.mdx, but What's new still said "an opt-in WebSocket transport ... HTTP remains the default", which was the most wrong sentence left in the v5 docs. It now says what happens, that only the exact value http opts out so a typo fails toward the socket, and that tracing is unchanged because the client span is synthesized around the frame.

Spec 7 is settled. #3634 landed, then #3735 made the sealed log opt-in, then #3737 re-enabled it. The end state matches what this branch already documented, and the WORKFLOW_SEALED_LOG section I had taken verbatim merged as the no-op it was meant to be, modulo #3704's restyling. mintedSpecVersion(), the two-version accepted range, and the "if you allocate at the commit you are already compliant" framing all still hold.

Three World-developer notes, all from #3728. These are the ones a custom World cannot discover from its type errors:

  • Process-wide state has to live on globalThis. A module's top-level const/let is one instance per module instance, and a bundler compiles one copy per layer. The runtime caches the World object process-wide while module state it closes over stays layer-local, so anything a World reaches at request time has to be process-wide too. New contract note in the upgrade guide, plus a step of its own in the World skill (v0.3.0) with an intake item, a globalSingleton() example including what the shape version is for, an output-shape section, and a failure-checklist line. Documented by its casualty: the WS transport registered its channel in the route layer's registry and the write path read the instrumentation layer's empty one, so every event fell back to HTTP for the life of the process, with nothing logged and no test failing.
  • One World per process. The entrypoint's queue handler is built from getWorld() instead of getWorldHandlers(), so a stateful World stops getting duplicate connection pools and queue workers. The build-integration row that still pointed custom hosts at getWorldHandlers() is corrected: that export is the build-time view, not how a request-time handler is assembled.
  • A World's transport is its own business, except for the tracing. How a World ships events is unconstrained. What is constrained is that a non-HTTP transport still owes the per-event client span an HTTP write would emit, or the per-event view of a run silently disappears. Points at the Vercel World's span shape as the worked example.

Nothing needed for the remaining commits in the window: globalSingleton's own changeset and the sideEffects: false declaration are internal, the wait-continuation re-arm and the atomic step_created commit are fixes to behavior already documented, and the decrypt-control and trace-name changes are dashboard-side.

Third catch-up: main again, and the Vitest install tag

Merged main once more (21 commits) and stacked this PR on #4267 (vitest-v5-follow-ups), which already carries main's tip, so the merge is both at once. One conflict, in api-reference/workflow-runtime/world/storage.mdx: #4206 rewrote the runs.list params.status cell on main while this branch carried its own. Main's wording is the one kept.

Why the stack. #4267 documents npm i -D @workflow/vitest@beta. That is right while 5.x exists only on the beta tag, and wrong the moment this PR's premise holds — 5.0.0 on latest (#3090), the 4.x line on previous (#3091). So the install guidance goes back to a plain npm i -D @workflow/vitest in the testing guide, the @workflow/vitest API reference and the workflow skill, which is what every other install command in the v5 tree looks like. What survives from #4267's callout is the reason it was written: the plugin carries its own @workflow/core, has to stay on the app's major, and now checks that at the start of each run.

The runtime hint in packages/vitest/src/version-check.ts still points a v5 app at @beta, deliberately. It is correct until 5.0.0 is published, and flipping it (latest for v5, previous for 4.x) edits #4267's own code and its tests, so it belongs with the release rather than with a docs PR stacked on top.

Version-switcher fallbacks refreshed. Re-diffed the two content trees. Seven v5-only pages had no /v4 rule: api-reference/workflow-api/register-lifecycle-hooks and observability/lifecycle-hooks (#3678, landed after the last sweep), the batched-event-writes, lazy-hook-resume and resilient-resume changelog entries, errors/run-expired, and observability/retention. Five of the seven predate the previous sweep, so the list was already out of date when it was written.

The comment above the block overstated what it was for, and now says what it is actually load-bearing for. The switcher dropdown does resolve a missing page client-side, against the paths getVersionSwitchPaths() hands it; what has no such check is the maintenance banner's "Go to Workflow 5" link (a straight prefix swap) and any hand-edited or inbound /v4/... URL. Those are what these rules catch.

Nothing else in the window needed prose. The feature work that landed brought its own v5 pages with it — lifecycle hooks (#3678), the optional World invoke (#4168), the Nest hardening (#3695), the attribute size limit (#4082), the deploy-time system env vars (#4166) — and the rest is tests, fixes, and the dashboard-side cancellation details (#4250). Note that #3090 was reverted on main (#4195) and will re-land with the GA cut; this PR's premise is unchanged, and its merge order is unchanged with it.

Fourth catch-up: back onto main

Merged main (56 commits) after #4267 landed. Five conflicts:

  • api-reference/vitest/index.mdx, testing/index.mdx (x2), skills/workflow/SKILL.md (x2): main's @workflow/vitest@beta install lines against this branch's plain npm i -D @workflow/vitest. Kept this branch's, which is the premise of the PR. The "same major, checked at the start of each run" reason survives in both.
  • foundations/errors-and-retries.mdx: both sides edited the error-code table. Main had already added its own DEPLOYMENT_MISMATCH row, so this branch's duplicate is dropped and main's row keeps its re-routing detail with this branch's link to /docs/errors/deployment-mismatch folded in. STREAM_ERROR takes main's phrasing plus this branch's "retry and report with the runId".
  • worlds/v5/upgrading-to-v5.mdx: union. Main's resolveData: 'skip-step-inputs' contract note and its wider capabilities list (hookForceClaim, dynamicWorkflowCode) are kept alongside this branch's process-state guidance and its events.createBatch / runs.waitForTerminalStatus rows.

Also dropped .changeset/vitest-refs-and-version-guard.md: #4267's Version Packages run already moved it into .changeset/pre/ on main, so the pending copy this branch carried would have bumped the packages a second time for a change that already shipped. The workflow skill goes to 1.18 for the install-wording change.

Merge order is still the open question. main is on 5.0.0-beta.58 with pre.json back in pre mode, so v5 is not GA yet and this PR should not land before #4362 (re-apply #3090) does. Everything here assumes 5.0.0 on latest and the 4.x line on previous.

Verification

Link lint passes with 0 errors. pnpm build compiles, with /en/docs/whats-new prerendered under the unprefixed route, /[lang]/v4/docs/[[...slug]] serving the maintenance tree, and ƒ /[lang]/worlds/upgrading-to-v5. Both were re-run after the merge with #4267 and the fallback refresh, and biome check is clean on the touched files.

Docs Preview

Base: https://workflow-docs-git-peter-docs-v5-default.vercel.sh (requires Vercel team access). Every page below is a current-version page, so the unprefixed URL is itself part of what there is to check; the maintenance tree is the same content under /v4/docs/....

Page Preview
docs/content/docs/v5/testing/index.mdx Installation, Upgrade @workflow/vitest with the SDK
docs/content/docs/v5/api-reference/vitest/index.mdx Installation
docs/content/docs/v5/api-reference/workflow-runtime/world/storage.mdx runs.list()
docs/content/docs/v5/whats-new.mdx What's new
docs/content/docs/v5/foundations/errors-and-retries.mdx Errors and retries
docs/content/docs/v5/how-it-works/code-transform.mdx Code transform
docs/content/worlds/v5/building-a-world.mdx Building a World
docs/content/worlds/v5/upgrading-to-v5.mdx Upgrading to v5

🤖 Generated with Claude Code

VaguelySerious and others added 15 commits August 21, 2026 12:50
Serves `content/docs/v5` and `content/worlds/v5` unprefixed at /docs,
/worlds and /cookbook, moves v4 under /v4, and puts What's new first in
the v5 sidebar.

The versioned source config drives both route trees (the root tree always
renders `versionedSources.current`), so this is a `routePrefix` move plus
source re-binding rather than a restructure. The only file moves are
`app/[lang]/v5/**` → `app/[lang]/v4/**`.

- Version switcher: `v5 (Latest)` / `v4 (Maintenance)`, `current: 'v5'`.
- `pre-release-banner.tsx` becomes `maintenance-banner.tsx`. v4 pages
  carry an amber notice whose "Go to Workflow 5 (Latest)" link deep-links
  to the same page on the current version, falling back to the nearest
  section index for v4-only pages, and keep `robots: noindex, follow`.
- Redirects: `/v5/*` to the unprefixed equivalent (bare `/v5` needs its
  own rule, since `:path*` expands to an empty Location). The world-docs
  and api-reference restructure rules are mirrored onto `/v4/docs/*`, and
  every page existing in only one tree gets a version-switcher fallback.
- Both worlds route trees pass an explicit version into the shared page
  components, whose semantics flipped with the switch, so the smoke checks
  now assert the pairing: a " · v4" title marker and noindex on the
  maintenance routes, neither on the canonical ones, and a community world
  serving directly rather than self-redirecting.
- The link lint's two URL spaces swap with the prefixes. Redirect
  destinations resolve against the real HTTP space, since redirects are
  matched before render-time href rewriting.
- The two `/v4/...` links this makes expressible are restored: a v5 page
  cannot link to a v4 page while v4 is the unprefixed version.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sweep of everything that landed on main since the last content refresh,
plus the spec-7 sealed log from #3634, which is not merged but is the
default for v5.

Spec 7 changes what a World declares, so the upgrade guide's Spec
versions section is rewritten around `mintedSpecVersion()`. The accepted
range widens back to two versions, because a deployment with
`WORKFLOW_SEALED_LOG=0` stamps the one below, and both `SPEC_VERSION_CURRENT`
and `SPEC_VERSION_SUPPORTS_SLOT_IDENTITY` become literals by another name
for the purpose of declaring it: neither follows the setting. The new
section says what a sealed log costs an implementer, which for most is
nothing — a World allocating each position at the commit cannot leave a
hole, so it never seals and never writes a `noop`. The obligation belongs
to a World that pre-assigns positions, and the half that binds everyone
is the reader's.

`WORKFLOW_SEALED_LOG` is documented in runtime-tuning, taken verbatim
from #3634 so whichever lands second is a no-op merge. The deep
reference sections that PR writes, in event-sourcing and the World
allocation contract, are left to it.

Two optional World members shipped after the guide was written and were
missing everywhere:

- `events.createBatch` — in the World reference (interface and contract
  note), the upgrade guide's optional surface, and the skill. Implementing
  it is the declaration, so the note leads with atomicity per attempt and
  what a World must reject.
- `runs.waitForTerminalStatus` — same three places. It is also what makes
  `await run.returnValue` a long poll rather than an interval, which is
  user-facing, so What's new gets it too.

What's new also gains the batched suspension write and the pre-assigned
positions behind it, both under faster-and-cheaper runs where they belong:
neither has any API surface.

Not addressed: `workflow.step.execute.duration`, the OpenTelemetry
histogram added in #3526, has nowhere to go. The docs have no metrics
reference at all, and inventing one for a single metric is a bigger call
than this sweep.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Resolves four conflicts, all against #3704's writing-standards pass over
the whole corpus, which rewrote the same paragraphs this branch had
edited. Took main's normalized text everywhere it was purely style, kept
this branch's meaning where the two disagreed: the spec-7 paragraph main
still had at spec 6, the `/v4/...` link the flip makes expressible, and
the batch-write contract note. Restyled this branch's own additions to
the standard main just adopted, so no prose em dashes come back with it.

Content this landed on top:

- **The WebSocket events transport is the default now**, not opt-in. The
  What's new entry said the opposite, which was the most wrong sentence
  in the v5 docs after #3702.
- **Process-wide state has to live on `globalThis`.** New contract note in
  the World upgrade guide, and a step of its own in the World skill, since
  it type-checks, passes tests in isolation, and fails only in a host that
  bundles the World. Named after its casualty: the WS transport registered
  its channel in one bundler layer and looked it up in another layer's
  empty copy, so every event fell back to HTTP silently.
- **One World per process.** The entrypoint's queue handler is built from
  `getWorld()` rather than `getWorldHandlers()`, so a stateful World stops
  getting duplicate pools and queue workers. The build-integration row
  that still sent custom hosts to `getWorldHandlers()` is corrected.
- **A World's transport is its own business, except for the tracing.** A
  non-HTTP transport still owes the per-event client span, or the
  per-event view of a run disappears.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
#3779 fixed the app migration skill, whose description ended with
`mode: 'client'`. The colon-space made the plain scalar parse as a nested
mapping, and the skills CLI dropped the file: `Found 5 skills`, and
`--skill migrating-workflow-v4-to-v5` answered `No matching skills
found`, which is the command whats-new.mdx tells readers to run.

The World skill's description has no colon-space today, so it parses.
It is also 590 characters of backticked identifiers, and any future
edit naming a field with its value reintroduces the break. Fold it the
same way now, while the value is known good. Verified with the yaml
package that the folded scalar is byte-identical, and with
`skills add . --skill migrating-world-v4-to-v5` that the CLI still
finds all six.

Signed-off-by: Peter Wielander <peter.wielander@vercel.com>
…ics deltas

Docs and migration skills pass over main since the last update:

- errors-and-retries: STREAM_ERROR and DEPLOYMENT_MISMATCH rows, completing
  the RUN_ERROR_CODES table.
- world/storage: runs.list status array form, TERMINAL_WORKFLOW_RUN_STATUSES,
  empty-array semantics and the per-World split.
- building-a-world: terminal-run start fence, runContext on
  WorkflowInvokePayload, analytics.events.getMany plus page limits,
  streams.createWriteSession.
- migrating-world-v4-to-v5: the same contract additions, plus checklist items.
- migrating-workflow-v4-to-v5: analytics.events.listByCorrelationId is
  deprecated; the storage method of the same name is not.
…ow refs

Four follow-ups to the Workflow 5 Vitest path:

- Document that a v5 app has to install `@workflow/vitest@beta`, since
  `@workflow/vitest@latest` is still the 4.x line.
- Fail the test build up front when `@workflow/vitest` and the app resolve
  incompatible `@workflow/core` majors, with the install command that fixes
  it. Same-major differences warn. `WORKFLOW_VITEST_VERSION_CHECK=off` skips
  the check.
- Write the builder's `manifest.json` next to the test bundles and add
  `getWorkflowRef()` / `listWorkflowRefs()`, so a test can name a workflow
  instead of hand-writing the generated `workflow//...` id.
- Rewrite the mocking docs to match what `vi.mock()` actually reaches, and
  pin each case in the workbench.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Co-Authored-By: Peter Wielander <29887157+VaguelySerious@users.noreply.github.com>
#4206 landed a longer cell for `params.status` on main while this branch carried its own. Adopt main's, so the merge that follows is a fast, conflict-free catch-up.

Co-Authored-By: Peter Wielander <29887157+VaguelySerious@users.noreply.github.com>
… pages

Stacked on #4267, which documents `npm i -D @workflow/vitest@beta`.
That is right while 5.x only exists on the `beta` tag, and wrong the
moment this PR's premise holds: `latest` becomes 5.x (#3090) and the
4.x line moves to `previous` (#3091). So the install guidance goes
back to a plain `npm i -D @workflow/vitest` in the testing guide, the
@workflow/vitest API reference, and the workflow skill. What survives
from #4267's callout is the reason it was written: the plugin carries
its own @workflow/core and has to stay on the app's major, which the
plugin now checks at the start of each run.

The runtime hint in packages/vitest/src/version-check.ts still points
a v5 app at `@beta`. It is correct until 5.0.0 is published and should
flip with the release, not here.

Also refreshes the version-switcher fallbacks against the current
content trees. Seven v5-only pages had no /v4 landing spot: the
lifecycle-hooks pair that just landed on main, three changelog
entries, the run-expired error, and observability/retention.

Co-Authored-By: Peter Wielander <29887157+VaguelySerious@users.noreply.github.com>
The switcher dropdown resolves a missing page against getVersionSwitchPaths(); the maintenance banner's prefix swap and inbound /v4 URLs do not. Those are what the block catches.

Co-Authored-By: Peter Wielander <29887157+VaguelySerious@users.noreply.github.com>
Union-resolve the v5 docs conflicts: keep main's newer capability list,
resolveData contract note and DEPLOYMENT_MISMATCH wording, keep this
branch's world process-state guidance and the two added optional-surface
rows, and keep the GA install lines (no `@beta`) that are this branch's
whole point.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#4267 merged to main and its Version Packages run moved this file into
.changeset/pre/. Keeping the pending copy here would bump the packages a
second time for a change that already shipped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ding

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Sep 29, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 482fcad

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
example-nextjs-workflow-turbopack Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
example-nextjs-workflow-webpack Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
example-workflow Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
workbench-astro-workflow Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
workbench-express-workflow Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
workbench-fastify-workflow Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
workbench-hono-workflow Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
workbench-nestjs-workflow Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
workbench-nitro-workflow Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
workbench-nuxt-workflow Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
workbench-python-workflow Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
workbench-sveltekit-workflow Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
workbench-tanstack-start-workflow Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
workbench-vite-workflow Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
workflow-docs Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
workflow-swc-playground Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
workflow-tarballs Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC
workflow-web Ready Ready Preview, v0 Sep 29, 2026 10:56pm UTC

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

🧪 E2E Test Results

✅ All tests passed

🛠 Infra Events (absorbed by the harness)

Platform anomalies the e2e harness detected and worked around (e.g. a run the queue never picked up, replaced by a fresh run). Clustered timestamps indicate a backend blip; a steady drip indicates a platform issue worth escalating.

  • run-pickup-stall · runs app-generated source against a registered step (tanstack-start) · at 22:56:18Z · abandoned wrun_01M3QP3PZM5CGH2TR6J4XGBXYS
  • cold-start-warmup · suite warmup (tanstack-start) · at 22:56:25Z · abandoned wrun_01M3QP3Q0V4YKDKXKSSBBJBK03
  • run-pickup-stall · AllInOneService.processNumber - static workflow method using sibling static step methods (nitro) · at 22:58:20Z · abandoned wrun_01M3QP7EWZW2Y1314E354184XJ
  • run-pickup-stall · hookCleanupTestWorkflow - hook token reuse after workflow completion (nextjs-webpack) · at 23:01:31Z · abandoned wrun_01M3QPD909NTHVREM3CYVW1YPW
  • run-pickup-stall · hookGetConflictWorkflow - awaiting hook.getConflict() registers hook without payload (nextjs-webpack) · at 23:01:40Z · abandoned wrun_01M3QPDHTK09ZM5VY9G376XWWW
  • run-pickup-stall · 'hookGetConflictWithPriorStepWorkflow' - hook.getConflict() does not block step execution (nextjs-webpack) · at 23:01:41Z · abandoned wrun_01M3QPDJTNW3CQKFGSCE9FTWCY
  • run-pickup-stall · customSerializationWorkflow - custom class serialization with WORKFLOW_SERIALIZE/WORKFLOW_DESERIALIZE (nextjs-webpack) · at 23:02:57Z · abandoned wrun_01M3QPFX57CQA0XZBGX4AV4RNR

E2E Test Summary

Summary
Passed Failed Skipped Total
✅ ▲ Vercel Production 3904 0 875 4779
✅ 💻 Local Development 4406 0 550 4956
✅ 📦 Local Production 4406 0 550 4956
✅ 🐘 Local Postgres 4406 0 550 4956
✅ 🪟 Windows 342 0 12 354
✅ 🌐 Cross-language Conformance 68 0 84 152
✅ dynamic-runs 0 0 0 0
✅ vercel-http-transport 879 0 183 1062
✅ vercel-multi-region 27 0 0 27
✅ vercel-ws-transport 595 0 113 708
Total 19033 0 2917 21950
Details by Category

✅ ▲ Vercel Production

App Passed Failed Skipped
✅ astro-node 142 0 35
✅ astro-quickjs 142 0 35
✅ example-node 142 0 35
✅ example-quickjs 142 0 35
✅ express-node 142 0 35
✅ express-quickjs 142 0 35
✅ fastify-node 142 0 35
✅ fastify-quickjs 142 0 35
✅ hono-node 142 0 35
✅ hono-quickjs 142 0 35
✅ nest-node 142 0 35
✅ nest-quickjs 142 0 35
✅ nextjs-turbopack-node 169 0 8
✅ nextjs-turbopack-quickjs 169 0 8
✅ nextjs-webpack-node 169 0 8
✅ nextjs-webpack-quickjs 169 0 8
✅ nitro-node 142 0 35
✅ nitro-quickjs 142 0 35
✅ nuxt-node 142 0 35
✅ nuxt-quickjs 142 0 35
✅ python-node 66 0 111
✅ sveltekit-node 161 0 16
✅ sveltekit-quickjs 161 0 16
✅ tanstack-start-node 142 0 35
✅ tanstack-start-quickjs 142 0 35
✅ vite-node 142 0 35
✅ vite-quickjs 142 0 35

✅ 💻 Local Development

App Passed Failed Skipped
✅ astro-stable-node 148 0 29
✅ astro-stable-quickjs 148 0 29
✅ express-stable-node 148 0 29
✅ express-stable-quickjs 148 0 29
✅ fastify-stable-node 148 0 29
✅ fastify-stable-quickjs 148 0 29
✅ hono-stable-node 148 0 29
✅ hono-stable-quickjs 148 0 29
✅ nest-stable-node 148 0 29
✅ nest-stable-quickjs 148 0 29
✅ nextjs-turbopack-canary-node 176 0 1
✅ nextjs-turbopack-canary-quickjs 176 0 1
✅ nextjs-turbopack-stable-node 176 0 1
✅ nextjs-turbopack-stable-quickjs 176 0 1
✅ nextjs-webpack-canary-node 176 0 1
✅ nextjs-webpack-canary-quickjs 176 0 1
✅ nextjs-webpack-stable-node 176 0 1
✅ nextjs-webpack-stable-quickjs 176 0 1
✅ nitro-stable-node 148 0 29
✅ nitro-stable-quickjs 148 0 29
✅ nuxt-stable-node 148 0 29
✅ nuxt-stable-quickjs 148 0 29
✅ sveltekit-stable-node 167 0 10
✅ sveltekit-stable-quickjs 167 0 10
✅ tanstack-start-node 148 0 29
✅ tanstack-start-quickjs 148 0 29
✅ vite-stable-node 148 0 29
✅ vite-stable-quickjs 148 0 29

✅ 📦 Local Production

App Passed Failed Skipped
✅ astro-stable-node 148 0 29
✅ astro-stable-quickjs 148 0 29
✅ express-stable-node 148 0 29
✅ express-stable-quickjs 148 0 29
✅ fastify-stable-node 148 0 29
✅ fastify-stable-quickjs 148 0 29
✅ hono-stable-node 148 0 29
✅ hono-stable-quickjs 148 0 29
✅ nest-stable-node 148 0 29
✅ nest-stable-quickjs 148 0 29
✅ nextjs-turbopack-canary-node 176 0 1
✅ nextjs-turbopack-canary-quickjs 176 0 1
✅ nextjs-turbopack-stable-node 176 0 1
✅ nextjs-turbopack-stable-quickjs 176 0 1
✅ nextjs-webpack-canary-node 176 0 1
✅ nextjs-webpack-canary-quickjs 176 0 1
✅ nextjs-webpack-stable-node 176 0 1
✅ nextjs-webpack-stable-quickjs 176 0 1
✅ nitro-stable-node 148 0 29
✅ nitro-stable-quickjs 148 0 29
✅ nuxt-stable-node 148 0 29
✅ nuxt-stable-quickjs 148 0 29
✅ sveltekit-stable-node 167 0 10
✅ sveltekit-stable-quickjs 167 0 10
✅ tanstack-start-node 148 0 29
✅ tanstack-start-quickjs 148 0 29
✅ vite-stable-node 148 0 29
✅ vite-stable-quickjs 148 0 29

✅ 🐘 Local Postgres

App Passed Failed Skipped
✅ astro-stable-node 148 0 29
✅ astro-stable-quickjs 148 0 29
✅ express-stable-node 148 0 29
✅ express-stable-quickjs 148 0 29
✅ fastify-stable-node 148 0 29
✅ fastify-stable-quickjs 148 0 29
✅ hono-stable-node 148 0 29
✅ hono-stable-quickjs 148 0 29
✅ nest-stable-node 148 0 29
✅ nest-stable-quickjs 148 0 29
✅ nextjs-turbopack-canary-node 176 0 1
✅ nextjs-turbopack-canary-quickjs 176 0 1
✅ nextjs-turbopack-stable-node 176 0 1
✅ nextjs-turbopack-stable-quickjs 176 0 1
✅ nextjs-webpack-canary-node 176 0 1
✅ nextjs-webpack-canary-quickjs 176 0 1
✅ nextjs-webpack-stable-node 176 0 1
✅ nextjs-webpack-stable-quickjs 176 0 1
✅ nitro-stable-node 148 0 29
✅ nitro-stable-quickjs 148 0 29
✅ nuxt-stable-node 148 0 29
✅ nuxt-stable-quickjs 148 0 29
✅ sveltekit-stable-node 167 0 10
✅ sveltekit-stable-quickjs 167 0 10
✅ tanstack-start-node 148 0 29
✅ tanstack-start-quickjs 148 0 29
✅ vite-stable-node 148 0 29
✅ vite-stable-quickjs 148 0 29

✅ 🪟 Windows

App Passed Failed Skipped
✅ nextjs-turbopack-node 171 0 6
✅ nextjs-turbopack-quickjs 171 0 6

✅ 🌐 Cross-language Conformance

App Passed Failed Skipped
✅ python 68 0 84

✅ dynamic-runs

App Passed Failed Skipped
✅ astro-vercel 0 0 0
✅ example-vercel 0 0 0
✅ express-vercel 0 0 0
✅ fastify-vercel 0 0 0
✅ hono-vercel 0 0 0
✅ nest-vercel 0 0 0
✅ nextjs-turbopack-vercel 0 0 0
✅ nextjs-webpack-vercel 0 0 0
✅ nitro-vercel 0 0 0
✅ nuxt-vercel 0 0 0
✅ sveltekit-vercel 0 0 0
✅ tanstack-start-vercel 0 0 0
✅ vite-vercel 0 0 0

✅ vercel-http-transport

App Passed Failed Skipped
✅ example 142 0 35
✅ express 142 0 35
✅ hono 142 0 35
✅ nextjs-turbopack 169 0 8
✅ nitro 142 0 35
✅ vite 142 0 35

✅ vercel-multi-region

App Passed Failed Skipped
✅ nextjs-turbopack 27 0 0

✅ vercel-ws-transport

App Passed Failed Skipped
✅ example 142 0 35
✅ express 142 0 35
✅ nextjs-turbopack 169 0 8
✅ vite 142 0 35

📋 View full workflow run

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

📊 Workflow Benchmarks

commit 482fcad · Tue, 29 Sep 2026 23:18:38 GMT · run logs

Backend: vercel · app: nextjs-turbopack

Metric Scenario Best (ms) P75 (ms) P90 (ms) P99 (ms) Samples
TTFS step 415 (-36%) 💚 2434 🔴 (-2.8%) 2484 🔴 (-2.6%) 2523 🔴 (-6.2%) 30
TTFS stream 360 (-81%) 💚 2456 🔴 (+23%) 🔻 2862 🔴 (+42%) 🔻 2943 🔴 (+43%) 🔻 30
TTFS hook + stream 789 (+3.0%) 3283 🔴 (+40%) 🔻 3306 🔴 (+37%) 🔻 3372 🔴 (+21%) 🔻 30
Fan-out TTFS Promise.all(100 steps) 587 (+9.5%) 844 (-2.5%) 1211 (+27%) 🔻 3352 (+11%) 10
Fan-out TTLS Promise.all(100 steps) 1510 (-4.4%) 3972 (+21%) 🔻 5610 (+60%) 🔻 10527 (+73%) 🔻 10
STSO 1020 steps (inline) 160 (-3.0%) 209 (-8.3%) 237 (-6.7%) 340 (-9.1%) 1019
WO 1020 steps 205968 (-9.4%) 205968 (-9.4%) 205968 (-9.4%) 205968 (-9.4%) 1
CRTT first chunk (pooled) 79 (+6.8%) 122 (-20%) 💚 162 (-35%) 💚 235 (-16%) 💚 28

Streams

Scenario CRTT 1st p75 p90 p99 CDV max iters
paced control (100/s, 60B) 89 (-21%) 160 (-9%) 203 (-24%) 326 (-14%) 139 (+3%) 10
size sweep (100/s, 160B-12KB) 104 (-13%) 166 (-10%) 233 (-11%) 379 (-10%) 161 (-24%) 10
replay gateway-gpt-5.4-nano-2000t (1x) 102 (-33%) 151 (-13%) 191 (-11%) 766 (+90%) 520 (+74%) 3
replay eve-gpt-5.6-sol-2000t (1x) 144 (-7%) 159 (-9%) 195 (-14%) 423 (-89%) 432 (-78%) 2
replay eve-gpt-5.6-sol-2000t (2x) 106 (-30%) 203 (-15%) 258 (-21%) 544 (±0%) 309 (+3%) 3
📈 STSO distribution vs main (inline / queue-hop histograms)

1020 steps (inline)

Cumulative STSO time: main 226997ms → this run 205629ms (Δ -21368ms, -9%)

  150-200 ms  ███████████░░░░░░░░░░░░┃  main 301  this 643  +342
  200-250 ms  ██████████┃███████████    main 592  this 303  -289
  250-300 ms  █┃██                      main  95  this  51   -44
  300-350 ms  ┃                         main  19  this  13    -6
  350-400 ms  ┃                         main   5  this   5    +0
  400-450 ms  ┃                         main   2  this   4    +2
  450-500 ms  ┃                         main   2  this   0    -2
  700-750 ms  ┃                         main   1  this   0    -1
1500-1550 ms  ┃                         main   1  this   0    -1
3650-3700 ms  ┃                         main   1  this   0    -1
📈 CRTT drill-down vs main (RTT distributions & profiles)
variant  RTT 1ms→5s+             avg         p50         p90         p99     n
control  ······▃█▁····  132.8 (-11%)   125 (-9%)  203 (-24%)  326 (-14%)  3000
sweep    ······▂█▂····  141.2 (-10%)   130 (-8%)  233 (-11%)  379 (-10%)  3000
gw 1x    ·····▁▃█▁▁···     138 (-5%)  123 (-10%)  191 (-11%)  766 (+90%)  5295
eve 1x   ·····▁▃█▁▁···    135 (-31%)  119 (-13%)  195 (-14%)  423 (-89%)  5186
eve 2x   ······▂█▃▁···   168.4 (-9%)   152 (-5%)  258 (-21%)   544 (±0%)  7779

RTT over stream progress (avg per tenth of stream, bars scaled min→max):

control  ▆█▄▅▃▁▄▂▄▃  117–153ms
sweep    ▅█▆▇▃▄▆▅▄▁  124–157ms
gw 1x    █▂▁▄▃▁▂▂▃▁  120–201ms
eve 1x   ▂▁▃▂▁▇█▅█▇  122–149ms
eve 2x   ▂▁▂▂▁▃▆██▄  139–214ms

RTT by chunk size (avg per log size bin, ~160B → ~12KB serialized, bars scaled min→max):

sweep  ▆█▃▇█▂▁  140–142ms

Delivery jitter over stream progress (avg positive CDV per tenth of stream, bars scaled min→max):

control  ▃▅▇▄▁▃▅▄█▄  38–51ms
sweep    ▃▁▃▅▄▅▆▅█▃  49–71ms
gw 1x    █▄▂▁▃▃▄▄▂▁  37–54ms
eve 1x   ▄▅▆▁▃█▇▄▇▆  22–32ms
eve 2x   █▇▄▆▇▃▅▁▇█  19–31ms
ℹ️ Metric definitions & methodology

Streams: first-chunk RTT (the stream-open path, before any buffering/backpressure), CRTT percentiles, and worst delivery stall (CDV max). Cells are medians across iterations; per-run values in the artifacts. No 🔴/🟢 marks until targets attach.

The collapsed STSO distribution section above buckets every step gap, split inline (same warm process — pure framework overhead) vs queue-hop (fresh process — dispatch, reinit, replay). █ = main, ┃ = this run, ░ = fill.

The collapsed CRTT drill-down: per-variant RTT histograms (fixed log bins, · = empty) and mean RTT/positive-CDV profile lines over stream progress and chunk size. Histograms, avgs, and profiles merge exactly across runs; p50–p99 are percentile-of-percentiles. Per-index rows live in the artifacts.

Best/P75/P90/P99 deltas compare against the most recent benchmark run on main at the time of this run. 🔻 flags a delta worse than +15%, 💚 one better than −15%.

Metrics — TTFS: time to first step body (in-deployment start() → first step body) · Fan-out TTFS: fan-out time to first step (in-deployment start() → first of the parallel step bodies to complete) · Fan-out TTLS: fan-out time to last step (in-deployment start() → last of the parallel step bodies to complete, i.e. when the Promise.all resolves) · STSO: step-to-step overhead (gap between consecutive step bodies) · WO: workflow overhead (whole-run time outside step bodies, in-deployment anchored) · CRTT: chunk round-trip time (per-chunk write → read latency, one clock domain: deployment → stream backend → same deployment) · CDV: chunk delay variation / delivery jitter (inter-arrival gap minus inter-write gap per seq-adjacent pair; skew-free; the row is each run's MAX positive value, so one stall moves it)

Scenarios — step: one trivial no-op step, no stream; no hooks, so the run stays in turbo mode (in-process fast path) · stream: one streaming step; no hooks, so the run stays in turbo mode (in-process fast path) · hook + stream: registers a hook before one step, which exits turbo mode (dispatch path) · 1020 steps: 1020 trivial sequential steps; STSO is measured between consecutive steps in the given step ranges, and WO is the whole-run overhead outside step bodies · Promise.all(100 steps): 100 trivial no-op steps started together in a single Promise.all; Fan-out TTFS is the first of them to complete and Fan-out TTLS the last, both from the in-deployment clientStart, so their gap is the spread the runtime adds across the fan-out · paced control (100/s, 60B): the control: 300 tiny (~60B) deltas metronome-paced at 100/s — zero workload structure, so it reads the transport floor and flush cadence, and disambiguates transport-wide vs workload-specific when a replay row moves · size sweep (100/s, 160B-12KB): same pacing as the control with deltas padded in rotation across seven log-spaced sizes (~160B–12KB) — rotation decouples size from stream position, so it isolates whether chunk size causes latency · replay gateway-gpt-5.4-nano-2000t (1x): raw provider SSE cadence captured at the AI gateway boundary (gpt-5.4-nano, the most popular gateway model; per-token deltas p50 208B = the modal production chunk size), replayed exactly as measured — the typical customer's workload; its CDV is the typical customer's real delivery jitter · replay eve-gpt-5.6-sol-2000t (1x): a captured eve turn (gpt-5.6-sol, the most-used demanding eve model; ~2000 output tokens = production p50 turn length) replayed exactly as measured — eve's envelope protocol re-ships the cumulative message so sizes ramp 142B→13KB; the demanding outlier tenant's reality · replay eve-gpt-5.6-sol-2000t (2x): the same eve capture at 2x — the headroom/stress row; real fast-tier models emit the same chunk sizes at proportionally higher rate, so time compression is a faithful speed model · first chunk (pooled): every run's seq-0 RTT pooled across all stream scenarios — the first chunk precedes any workload differentiation, so pooling samples one shared stream-open path with exact percentiles

Replay cadences (semantic sha256) — eve-gpt-5.6-sol-2000t eaf22f5946e7c61f3c65c7006d550df180cfabd4e706254a09f22aec0cfb420d · gateway-gpt-5.4-nano-2000t 6f24ac518b6b83ff1d0e85a5fe78230db192716d66a7fc6b2fe022752001d041

🔴 marks a percentile over its target (within target is left unmarked). Targets (p75/p90/p99, ms) — TTFS 200/300/600

All timestamps are deployment-side; runs are triggered in-deployment, so the CI runner and api.vercel.com sit outside every measured window. TTFS = start() → first step body (includes dispatch + any cold start); Fan-out TTFS/TTLS = first/last step completion of one Promise.all from the same anchor (the gap is the runtime’s fan-out spread); STSO/WO between step bodies; CRTT inside the workflow (excludes the api.vercel.com read path).

Cold starts stay in the numbers (real bursty-workload latency, inflates P75+); Best is the warm floor.

@github-actions

Copy link
Copy Markdown
Contributor

Sim World

Simulated world deterministic testing for races. Traces

🟠 world-sim scenario book — 1 fail of 42 total

fence=per-spec

scenario outcome events virt replay violations
✅ smoke-no-steps completed 3 0ms ok 0
✅ smoke-one-step completed 6 0ms ok 0
✅ hook-at-step-started completed 12 0ms ok 0
✅ hook-at-step-completed completed 12 0ms ok 0
✅ hook-at-hook-created completed 12 0ms ok 0
✅ deadline-hook-wins completed 7 1.0h ok 0
✅ deadline-expires completed 7 1.0h ok 0
✅ step-vs-timer-early-settlement completed 8 1.0h ok 0
✅ long-sleep completed 11 30.0d ok 0
✅ hook-never-arrives stalled 3 0ms skipped 0
✅ step-retries-twice completed 10 2.0s ok 0
✅ parallel-steps completed 9 0ms ok 0
✅ hook-on-execution-state completed 12 0ms ok 0
✅ peek-hook-before-branch completed 12 0ms ok 0
✅ peek-hook-after-branch completed 12 0ms ok 0
✅ peek-hook-at-registration completed 12 0ms ok 0
✅ race-hook-before-probe completed 12 0ms ok 0
✅ race-hook-after-probe completed 12 0ms ok 0
✅ race-duplicate-delivery completed 13 0ms ok 0
✅ attr-hook-before-step completed 11 0ms ok 0
✅ attr-hook-after-step completed 11 0ms ok 0
✅ attr-from-step-body completed 13 0ms ok 0
✅ fork-hook-after-timeout completed 14 1.0m ok 0
✅ fork-hook-before-timeout completed 14 1.0m ok 0
✅ count-hook-after-timeout completed 17 1.0m ok 0
✅ count-hook-before-timeout completed 20 1.0m ok 0
✅ stale-read-step-count-fork completed 20 1.0m ok 0
✅ stale-read-equal-step-counts completed 14 1.0m ok 0
✅ step-vs-step-fork completed 12 0ms ok 0
✅ step-vs-step-fork-fenced completed 12 0ms ok 0
✅ fence-catches-benign-direction completed 12 5ms ok 0
✅ in-flight-before-decision completed 17 1.0m ok 0
❌ in-flight-before-decision-counted completed 17 1.0m ok 0
✅ in-flight-after-decision completed 19 2.0m ok 0
✅ stale-read-step-count-fork-fenced completed 20 1.0m ok 0
✅ fork-hook-wins completed 13 1.0m ok 0
✅ fork-timeout-wins completed 13 1.0m ok 0
✅ unclaimed-payload-under-fork completed 17 1.0m ok 0
✅ claimed-payload-under-fork completed 17 1.0m ok 0
✅ writers-independent-step-bodies completed 12 0ms ok 0
✅ writers-scripted-tempo completed 12 0ms ok 0
✅ cancel-mid-step cancelled 7 0ms skipped 0

Full trace: world-sim.txt

@github-actions

Copy link
Copy Markdown
Contributor
Framework Flow route Step reg. Framework output
hono 265.9 KiB (±0) 97.2 KiB (±0) 1.98 MiB (±0)
nextjs-turbopack 273.3 KiB (±0) 426 B (±0) 979.1 KiB (±0)
About these numbers

Sizes are gzip; parentheses show the change against main.
Flow route and Step reg. gate this job, on raw bytes rather than the gzip shown, at max(2%, 50.0 KiB). Framework output is informational.

482fcad · run

@VaguelySerious
VaguelySerious marked this pull request as ready for review September 30, 2026 16:16
@VaguelySerious
VaguelySerious requested a review from a team as a code owner September 30, 2026 16:16
@VaguelySerious
VaguelySerious merged commit 492b0c2 into main Sep 30, 2026
322 of 327 checks passed
@VaguelySerious
VaguelySerious deleted the peter/docs-v5-default branch September 30, 2026 17:43
@github-actions

Copy link
Copy Markdown
Contributor

No backport to stable for 492b0c2 (AI decision).

This is a docs-site version flip for the 5.0.0 GA: it makes v5 the default documentation version, moves v4 under a /v4 prefix, and rewrites routing, redirects, banners, and link lint accordingly. Nearly all of it lives in the docs app outside docs/content/ and in skills/, neither of which is maintained on stable, and the remaining docs/content/docs/v5 and docs/content/worlds/v5 edits document v5-only behavior (sealed logs, events.createBatch, runs.waitForTerminalStatus, the WebSocket transport default) that does not exist on the 4.x line. Nothing here fixes a defect in content or behavior that stable ships.

To override, re-run the Backport to stable workflow manually via workflow_dispatch and paste this commit SHA into the ref input:

492b0c25dae7df773d9e211349c806b20fd62c66

This branch was successfully deployed

1 active deployment
Preview – workflow-docs — 482fcade Deployed Sep 29, 2026 by vercel[bot]
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.

2 participants