ci: drop recovered-runner fallback from retarget

This commit is contained in:
Tianyi Cui
2026-07-27 15:55:21 +08:00
parent 77a85f9b1a
commit 98877ca326
13 changed files with 64 additions and 140 deletions
@@ -1,6 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-21-serial-cross-platform-ci-reference.md
2026-07-21-serial-cross-platform-ci-reference.md: 220c4b2a092ec1907482edc60a12f981fdf986a4
2026-07-21-serial-cross-platform-ci-reference.zh.md: 70e4c40f0f64fef4b1de05a7603ece25aaf5bea2
# pnpm run verify-translation-pairing --write
2026-07-21-serial-cross-platform-ci-reference.md: 5433d2c51831ce61d06a16ee0b0ed982911f9218
2026-07-21-serial-cross-platform-ci-reference.zh.md: 041d53d13e14354c995e4b65defce94a97646b0a
@@ -14,7 +14,7 @@ Reviewers also need a direct answer to a simpler question: what happens when the
## Decision
[CI](../../../../.github/workflows/ci.yml) gives pull-request and master-push events complementary responsibilities. Pull requests run three primary Linux jobs, one complete Windows job, and the Node compatibility and Python contracts on standard GitHub-hosted capacity. A push to `master` skips those jobs and runs three explicit references named `serial / linux`, `serial / macos`, and `serial / windows`. They intentionally duplicate their short checkout, runtime setup, and immutable install sequences instead of hiding the operating systems behind a matrix or reusable workflow. `workflow_dispatch` is reserved for runner benchmarks.
[CI](../../../../.github/workflows/ci.yml) gives pull-request and master-push events complementary responsibilities. Pull requests run consolidated Linux and Windows jobs plus the Node compatibility and Python contracts on standard GitHub-hosted capacity. A push to `master` skips those jobs and runs three explicit references named `serial / linux`, `serial / macos`, and `serial / windows`. They intentionally duplicate their short checkout, runtime setup, and immutable install sequences instead of hiding the operating systems behind a matrix or reusable workflow. `workflow_dispatch` is reserved for runner benchmarks.
Each reference job runs `pnpm run check:ci` without any shard selector. `DSH_GATE_CONCURRENCY=1` makes the top-level aggregate execute one ready gate at a time; coverage, snapshot replay, built-bin smoke, and publication validation also receive worker counts of one. The three operating-system jobs may run beside one another, but each host's repository gates are serial and complete. Linux installs bubblewrap before replaying snapshots, and Windows enables Developer Mode before installing the symlinked workspace.
@@ -24,7 +24,7 @@ The macOS reference runs the ordinary Vitest project in forked processes. Node 2
Master reference jobs are diagnostic and do not participate in the pull request's required `all checks passed` result. A pull request runs only its required jobs; a master push runs only the three serial references. Performance is evaluated from completed hosted-job timestamps and reported as a measurement; it is not encoded as a `timeout-minutes` value.
The portable reference uses GitHub's standard `ubuntu-latest`, `macos-latest`, and `windows-2025` labels. Substantive required pull-request jobs use the same portable Linux and Windows capacity under the [required-CI decision](2026-07-23-portable-required-pull-request-ci.md). Higher-core hosted runners remain manual benchmarks because a correctness path must remain runnable without repository-external runner configuration.
The portable reference uses GitHub's standard `ubuntu-latest`, `macos-latest`, and `windows-2025` labels. Required pull-request jobs use the same portable Linux and Windows capacity under the [required-CI decision](2026-07-23-portable-required-pull-request-ci.md). Higher-core hosted runners remain manual benchmarks because a correctness path must remain runnable without repository-external runner configuration.
## Alternatives considered
@@ -32,7 +32,7 @@ The portable reference uses GitHub's standard `ubuntu-latest`, `macos-latest`, a
- **Trust only the concurrent primary inventory** - rejected because scheduling and validation share implementation assumptions; a serial aggregate is an independent completeness check.
- **Run the serial references on every pull request** - rejected because they duplicate complete cross-platform aggregates and add macOS work to every change; the required jobs already execute the blocking Linux and Windows contracts.
- **Use one operating-system matrix** - rejected because three named jobs make the reference surface visible without another selection mechanism.
- **Run the serial reference on larger runners** - rejected because substantive required CI and its independent reference must remain runnable when organization-owned pools cannot allocate jobs.
- **Run the serial reference on larger runners** - rejected because both required CI and its independent reference must remain runnable when organization-owned pools cannot allocate jobs.
## Consequences
@@ -14,7 +14,7 @@ Status: implemented
## 决策
[CI](../../../../.github/workflows/ci.yml) 为拉取请求事件与 master 推送事件赋予互补的职责。拉取请求在 GitHub 标准托管容量上运行 3 项 Linux 主作业、1 项完整的 Windows 作业,以及 Node 兼容性与 Python 契约。向 `master` 推送时会跳过这些作业,改为运行三个显式参考作业,名称分别为 `serial / linux``serial / macos``serial / windows`。这些作业有意分别重复简短的代码检出、运行时设置和依赖锁定的安装步骤,不用矩阵或可复用工作流把操作系统差异隐藏起来。`workflow_dispatch` 仅用于运行器基准测试。
[CI](../../../../.github/workflows/ci.yml) 为拉取请求事件与 master 推送事件赋予互补的职责。拉取请求在 GitHub 标准托管容量上运行合并后的 Linux Windows 作业,以及 Node 兼容性与 Python 契约。向 `master` 推送时会跳过这些作业,改为运行三个显式参考作业,名称分别为 `serial / linux``serial / macos``serial / windows`。这些作业有意分别重复简短的代码检出、运行时设置和依赖锁定的安装步骤,不用矩阵或可复用工作流把操作系统差异隐藏起来。`workflow_dispatch` 仅用于运行器基准测试。
每个参考作业均在不设置任何分片选择器的情况下运行 `pnpm run check:ci``DSH_GATE_CONCURRENCY=1` 使顶层聚合每次只执行一个已经就绪的门禁;覆盖率、快照回放、built-bin 冒烟测试和发布验证的并发数也设为 1。三种操作系统的作业可以彼此并行,但每台主机上的仓库门禁都串行运行且完整执行。Linux 在回放快照前安装 bubblewrap,Windows 则在安装采用符号链接的工作区前启用开发人员模式。
@@ -24,7 +24,7 @@ macOS 参考流程使用 fork 进程运行常规 Vitest 项目。macOS arm64 上
master 分支的参考作业仅用于诊断,不参与拉取请求所要求的 `all checks passed` 结果。拉取请求只运行其必需作业;向 master 推送时只运行三个串行参考作业。系统根据已完成托管作业的时间戳评估性能,并将其报告为测量结果,而不是写成 `timeout-minutes` 值。
可移植的参考流程使用 GitHub 标准的 `ubuntu-latest``macos-latest``windows-2025` 标签。依据[必需 CI 决策](2026-07-23-portable-required-pull-request-ci.md),拉取请求中的实质性必需作业使用相同的可移植 Linux 和 Windows 容量。更高核心数的托管运行器仍仅用于手动基准测试,因为正确性路径必须无需仓库外部的运行器配置即可运行。
可移植的参考流程使用 GitHub 标准的 `ubuntu-latest``macos-latest``windows-2025` 标签。依据[必需 CI 决策](2026-07-23-portable-required-pull-request-ci.md),拉取请求必需作业使用相同的可移植 Linux 和 Windows 容量。更高核心数的托管运行器仍仅用于手动基准测试,因为正确性路径必须无需仓库外部的运行器配置即可运行。
## 曾考虑的替代方案
@@ -32,7 +32,7 @@ master 分支的参考作业仅用于诊断,不参与拉取请求所要求的
- **仅信任并发执行的主门禁清单**:不予采纳,因为调度逻辑与校验逻辑共享实现假设;串行聚合流程是一项独立的完整性检查。
- **在每个拉取请求上运行串行参考作业**:不予采纳,因为这些作业会重复完整的跨平台聚合流程,并为每项改动增加 macOS 工作;必需作业已经执行阻塞性的 Linux 和 Windows 契约。
- **使用一个操作系统矩阵**:不予采纳,因为三个具名作业无需另一套选择机制,就能让参考流程的构成清晰可见。
- **在大型运行器上运行串行参考流程**:不予采纳,因为当组织自有运行器池无法分配作业时,承担实质性检查的必需 CI 及其独立参考流程都必须仍可运行。
- **在大型运行器上运行串行参考流程**:不予采纳,因为当组织自有运行器池无法分配作业时,必需 CI 及其独立参考流程都必须仍可运行。
## 后果
@@ -1,6 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-22-evidence-based-larger-hosted-runners.md
2026-07-22-evidence-based-larger-hosted-runners.md: 8a3ca991accd5bbe71b6f92cffff4c9a420b1f25
2026-07-22-evidence-based-larger-hosted-runners.zh.md: 870c4301eed4793d3ac6801c310288abf1d46c3b
# pnpm run verify-translation-pairing --write
2026-07-22-evidence-based-larger-hosted-runners.md: fe11e6929545923d27fbf41f5a39f7dd2b9c3fbf
2026-07-22-evidence-based-larger-hosted-runners.zh.md: 47879284532a537cbe7e78aa2c495c4ef0be26c4
@@ -12,19 +12,19 @@ Larger runners make it possible to pay setup once and parallelize inside the rep
## Decision
The enterprise keeps repo-restricted x64 larger-runner pools for Ubuntu and Windows as measurement infrastructure. Public IPs are disabled, and benchmark concurrency remains bounded because an autoscaling ceiling neither allocates idle machines nor makes repository work scale without limit.
The enterprise keeps repo-restricted x64 larger-runner pools for Ubuntu and Windows. Ordinary pull requests name three 32-core pools directly: Ubuntu 24.04 for exhaustive coverage, Ubuntu latest for the remaining primary Node 24 inventory, and Windows 2025 for blocking Windows contracts. Public IPs are disabled, and workflow concurrency remains bounded because an autoscaling ceiling neither allocates idle machines nor makes repository work scale without limit.
Ordinary pull requests use the standard-hosted primary path owned by the [portable recovery boundary](2026-07-23-portable-required-pull-request-ci.md). `suite=larger-runner-benchmark` compares isolated critical lanes across provisioned sizes, and `suite=consolidated-runner-benchmark` compares whole aggregates. Each benchmark reports its observed processor and memory capacity before running repository work. The [serial reference](2026-07-21-serial-cross-platform-ci-reference.md) keeps an independent complete standard-runner oracle on `master`.
The required primary path depends on those enterprise pools. Standard GitHub-hosted jobs retain the Node 22.19, Node 26, and Python SDK compatibility contracts, while the [portable recovery boundary](2026-07-23-portable-required-pull-request-ci.md) and [serial reference](2026-07-21-serial-cross-platform-ci-reference.md) keep complete standard-runner evidence available on `master`. `suite=larger-runner-benchmark` compares isolated critical lanes across provisioned sizes, and `suite=consolidated-runner-benchmark` compares whole aggregates. Each benchmark reports its observed processor and memory capacity before running repository work.
The former gate-level and coarse primary shard jobs are absent from the workflow. Their static, lint, coverage, snapshot, and scenario shard selectors are also absent from the repository, so an unused diagnostic path cannot preserve a second CI architecture.
Linux primary work uses three independent standard-hosted jobs with single-worker inner bounds. Coverage runs alone, and the static scheduler runs alone so its result has no post-build consumer tail. After static gates finish, that job publishes its emitted `apps/*/lib`, `packages/*/*/lib`, and `vendor/*/lib` tree as a run-scoped artifact. The third job restores that exact tree, then starts lint, Node 24 runtime compatibility, build-backed snapshots, and all artifact consumers without repeating the build. Generated NodeNext consumer directories are excluded from ESLint discovery because the artifact check removes them while these processes overlap. The pnpm store and ESLint cache are restored without putting cache uploads on the pull-request critical path. Performance reports use each job's `startedAt` to `completedAt` interval; runner queue delay is capacity evidence, not repository execution time.
Linux primary work uses three independent 32-core jobs. Coverage runs alone with its own worker bound, and the static scheduler runs alone so its result has no post-build consumer tail. After static gates finish, that job publishes its emitted `apps/*/lib`, `packages/*/*/lib`, and `vendor/*/lib` tree as a run-scoped artifact. The third job restores that exact tree, then starts lint, Node 24 runtime compatibility, build-backed snapshots, and all artifact consumers without repeating the build. Generated NodeNext consumer directories are excluded from ESLint discovery because the artifact check removes them while these processes overlap. The pnpm store and ESLint cache are restored without putting cache uploads on the pull-request critical path. Performance reports use each job's `startedAt` to `completedAt` interval; runner queue delay is capacity evidence, not repository execution time.
The gate dependencies remain explicit. Coverage consumes source and does not wait for build. Documentation typechecking builds its complete project-reference graph once. Snapshot replay and publication consumers wait for emitted output, while Node-version compatibility jobs exercise runtime-sensitive source loading without repeating the primary source-graph typecheck. PTY and subprocess suites keep their bounded inner concurrency rather than inheriting the runner's core count.
The artifact boundary remains explicit. `scripts/publint-all.ts` calls publint's supported API against an in-memory publication view formed from each manifest's declared files plus npm's mandatory metadata, avoiding one package-manager pack process per package. `scripts/verify-built-package-invariants.mjs` stages the declared `lib/` files below the real package and imports its compiled self-reference through plain Node and Cordis Loader normalization; a runtime chunk omitted from the publication contract still fails.
Windows shares one standard-hosted setup across the blocking build and production site plus observational built-artifact contracts, with single-worker bounds. Linux owns the duplicate lint, coverage, and snapshot inventories because running those observational copies on Windows extends the critical path without adding a blocking platform claim.
Windows shares one 32-core setup across the blocking build and production site plus observational built-artifact contracts. Linux owns the duplicate lint, coverage, and snapshot inventories because running those observational copies on Windows extends the paid critical path without adding a blocking platform claim.
An [exact-head all-size benchmark](https://github.com/deepseek-harness/deepseek-harness/actions/runs/29908491351) ran the complete unsharded primary Node aggregate on every Linux pool before the eager-build correction:
@@ -50,11 +50,11 @@ Inner and outer worker limits are separate controls. An [exact-head 32-worker ES
The process-bound coverage project contains exactly five suite files. Thirty-two forks crashed Node 24's CJS lexer twice, and a later 16-fork run reproduced the worker loss and invalid coverage result. The single Vitest invocation therefore uses threads for the broad inventory and reserves forks for suites that exercise process-global state, `process` APIs, or timing-sensitive process I/O. That narrow fork inventory includes the local bash process-plumbing suite and the pi-ai adapter suite because aggregate contention changed timing observations in both. These failures make deterministic coverage, not advertised cores, the upper bound on worker selection.
Complete serial Linux, macOS, and Windows references run only when `master` moves. Pull requests use the standard-hosted required path, while larger-runner sizes run only by manual dispatch.
Complete serial Linux, macOS, and Windows references run only when `master` moves. Pull requests use the enterprise required path plus standard-hosted compatibility jobs, while other larger-runner sizes run only by manual dispatch.
## Alternatives considered
**Restore the former core, CPU, and production-site lanes.** Those jobs met the latency targets, but they paid three setup waves and left primary Node work sharded after larger runners were available. The all-size trace showed that one unnecessary dependency, not a lack of host capacity, kept the single-box aggregate above one minute.
**Keep the three coarse primary Linux lanes.** The core, CPU, and production-site jobs met the latency targets, but they paid three setup waves and left primary Node work sharded after larger runners were available. The all-size trace showed that one unnecessary dependency, not a lack of host capacity, kept the single-box aggregate above one minute.
**Keep the former gate-level shard topology as a manual reference.** A dormant second topology kept hundreds of workflow lines, selector modules, and scenario-partition behavior alive. The all-size and serial suites provide timing and completeness controls without preserving production code that no required job exercises.
@@ -68,7 +68,7 @@ Complete serial Linux, macOS, and Windows references run only when `master` move
**Keep static gates and post-build consumers on one runner.** Reusing one workspace avoids a setup wave and artifact transfer, but build-duration variance delays every consumer and leaves their lint and snapshot tails after the static result. A run-scoped built tree preserves one exact build while independent jobs keep both complete paths within the observed target.
**Use larger-runner pools as the required default.** This offers lower measured latency when allocation works, but a missing entitlement or delayed enterprise transfer leaves required jobs queued without repository diagnostics. The portable path accepts longer runtime, and manual suites preserve the performance experiment.
**Keep the complete required path on standard GitHub-hosted capacity.** This avoids repository-external runner configuration, but exact-head standard-runner runs remain materially slower and can spend longer queued behind shared capacity. Standard-hosted compatibility and serial references preserve portable evidence without making that slower topology the ordinary primary path.
**Keep required and observational Windows checks in separate jobs.** The split preserves status semantics at the workflow level but pays setup twice. `run-gates` preserves the same required versus non-blocking distinction inside one process.
@@ -76,10 +76,10 @@ Complete serial Linux, macOS, and Windows references run only when `master` move
## Consequences
The required topology pays one setup wave per standard-hosted lane and retains no shard selectors. The substantive CI inventory consumes enterprise larger-runner minutes only when a benchmark is dispatched; the lightweight aggregate's separate runner choice is outside this decision.
The required topology pays one setup wave per 32-core lane and retains no shard selectors. Every ordinary pull request consumes paid enterprise Linux and Windows minutes; manual benchmarks add other sizes only when remeasurement is useful.
Splitting Linux repeats setup twice and transfers one built tree, but isolates coverage, static gates, and post-build consumers from each other's critical paths without repeating the build. Consolidating Windows avoids repeating its slower setup. The trade-off is longer elapsed time than the measured larger-runner topology.
GitHub rounds each larger-runner execution up to a whole minute, so complete-job measurement exposes both billed time and workflow complexity. Splitting Linux repeats setup twice and transfers one built tree, but isolates coverage, static gates, and post-build consumers from each other's critical paths without repeating the build; consolidating Windows avoids repeating its slower setup.
Performance targets are observations, not cancellation deadlines or correctness requirements. Manual all-size and serial suites remain available when image, dependency, scheduler, or pricing changes need remeasurement.
Missing or renamed enterprise labels leave manual benchmarks unavailable without queueing a substantive primary job. The retained pools can compare sizes after allocation recovers without making runner assignment an operational dependency of repository gate execution.
Missing or renamed enterprise labels leave required primary jobs queued. Standard-hosted compatibility jobs and `master` references still report useful evidence, but they do not substitute for the required aggregate; runner assignment is therefore an operational dependency that repository CI cannot repair.
@@ -12,19 +12,19 @@ Status: implemented
## 决策
企业保留仅限本仓库使用的 Ubuntu 和 Windows x64 大型运行器池,作为测量基础设施。公网 IP 已禁用;基准测试并发仍设有边界,因为自动扩缩容上限既不会分配闲置机器,也不意味着仓库工作可以无限扩展。
企业保留仅限本仓库使用的 Ubuntu 和 Windows x64 大型运行器池。普通拉取请求直接指定 3 个 32 核运行器池:Ubuntu 24.04 用于完整覆盖率,Ubuntu latest 用于其余主 Node 24 清单,Windows 2025 用于阻塞性 Windows 契约。公网 IP 已禁用;工作流并发仍设有边界,因为自动扩缩容上限既不会分配闲置机器,也不意味着仓库工作可以无限扩展。
普通拉取请求使用由[可移植恢复边界](2026-07-23-portable-required-pull-request-ci.md)规定的标准托管主路径`suite=larger-runner-benchmark` 比较已预配规格上相互独立的关键通道,`suite=consolidated-runner-benchmark` 则比较完整聚合流程。每项基准测试都会先报告实测的处理器和内存容量,再运行仓库工作。[串行参考流程](2026-07-21-serial-cross-platform-ci-reference.md)在 `master` 上保留一套独立、完整的标准运行器判定基准。
必需主路径依赖这些企业级运行器池。GitHub 标准托管作业保留 Node 22.19、Node 26 和 Python SDK 兼容性契约,而[可移植恢复边界](2026-07-23-portable-required-pull-request-ci.md)与[串行参考流程](2026-07-21-serial-cross-platform-ci-reference.md)则在 `master` 上持续提供完整的标准运行器证据`suite=larger-runner-benchmark` 比较已预配规格上相互独立的关键通道,`suite=consolidated-runner-benchmark` 则比较完整聚合流程。每项基准测试都会先报告实测的处理器和内存容量,再运行仓库工作。
原有的门禁级和粗粒度主流程分片作业已从工作流中移除。相应的静态、lint、覆盖率、快照和场景分片选择器也已从仓库中移除,因此未使用的诊断路径无法继续维系第二套 CI 架构。
Linux 主流程使用 3 相互独立的标准托管作业,内部均采用单工作线程上限。覆盖率单独运行;静态调度器也单独运行,因此构建后的消费方不会拖延其结果。静态门禁完成后,该作业将其生成的 `apps/*/lib``packages/*/*/lib``vendor/*/lib` 目录树作为仅供本次运行使用的产物发布。第三个作业恢复完全相同的目录树,再让 lint、Node 24 运行时兼容性、依赖构建产物的快照和所有产物消费方基于构建完成后的工作树启动,而不重复构建。生成的 NodeNext 消费方目录不会纳入 ESLint 的文件发现范围,因为这些进程重叠执行时,产物检查会删除这些目录。pnpm store 和 ESLint 缓存会得到恢复,但缓存上传不会进入拉取请求关键路径。性能报告采用每个作业从 `startedAt``completedAt` 的区间;运行器排队延迟是容量证据,而非仓库执行时间。
Linux 主流程使用 3 相互独立的 32 核作业。覆盖率单独运行,并设有自己的工作线程上限;静态调度器也单独运行,因此构建后的消费方不会拖延其结果。静态门禁完成后,该作业将其生成的 `apps/*/lib``packages/*/*/lib``vendor/*/lib` 目录树作为仅供本次运行使用的产物发布。第三个作业恢复完全相同的目录树,再让 lint、Node 24 运行时兼容性、依赖构建产物的快照和所有产物消费方基于构建完成后的工作树启动,而不重复构建。生成的 NodeNext 消费方目录不会纳入 ESLint 的文件发现范围,因为这些进程重叠执行时,产物检查会删除这些目录。pnpm store 和 ESLint 缓存会得到恢复,但缓存上传不会进入拉取请求关键路径。性能报告采用每个作业从 `startedAt``completedAt` 的区间;运行器排队延迟是容量证据,而非仓库执行时间。
门禁依赖关系保持显式。覆盖率消费源码,不等待构建。文档类型检查只构建一次完整的 project-reference 图。快照回放和发布消费方等待生成的输出,而 Node 版本兼容性作业会验证对运行时敏感的源码加载,且不重复主源码项目图的类型检查。PTY 和子进程套件继续使用自身有界的内部并发,不继承运行器的核心数。
产物边界保持显式。`scripts/publint-all.ts` 对内存中的发布视图调用 publint 支持的 API;该视图由每个 manifest(元数据清单)声明的文件和 npm 强制要求的元数据组成,从而避免为每个包启动一次包管理器 pack 进程。`scripts/verify-built-package-invariants.mjs` 将已声明的 `lib/` 文件暂存到真实包下,并通过普通 Node 和 Cordis Loader 规范化导入其已编译的自身引用;发布契约只要遗漏一个运行时分片,检查仍会失败。
Windows 以一次标准托管环境设置同时承载阻塞性构建、生产网站和观测性的构建产物契约,并采用单工作线程上限。重复的 lint、覆盖率和快照清单由 Linux 承担,因为在 Windows 上运行这些观测性副本会延长关键路径,却不会新增任何阻塞性平台契约。
Windows 以一次 32 核环境设置同时承载阻塞性构建、生产网站和观测性的构建产物契约。重复的 lint、覆盖率和快照清单由 Linux 承担,因为在 Windows 上运行这些观测性副本会延长付费关键路径,却不会新增任何阻塞性平台契约。
一次[分支头精确的全规格基准测试](https://github.com/deepseek-harness/deepseek-harness/actions/runs/29908491351)在修正构建尽早启动逻辑前,对每种 Linux 池都运行了完整且未分片的主 Node 聚合流程:
@@ -50,11 +50,11 @@ Windows 仓库工作在超过 16 核后收益很小,但 32 核池可以让完
进程约束的覆盖率项目恰好包含 5 个套件文件。32 个 fork 曾两次导致 Node 24 的 CJS 词法分析器崩溃,后来一次使用 16 个 fork 的运行又复现了工作进程丢失和无效的覆盖率结果。因此,单次 Vitest 调用会对大范围测试清单使用线程,只为涉及进程全局状态、`process` API 或对时间敏感的进程 I/O 的套件保留 fork。这份有限的 fork 清单包括本地 bash 进程通路套件和 pi-ai 适配器套件,因为聚合争用改变了二者的时序观测结果。这些故障表明,选择工作线程数量时,上限取决于能否得到确定的覆盖率结果,而非标称核心数。
只有在 `master` 移动时,才运行完整的 Linux、macOS 和 Windows 串行参考。拉取请求使用标准托管的必需路径,大型运行器规格仅通过手动触发运行。
只有在 `master` 移动时,才运行完整的 Linux、macOS 和 Windows 串行参考。拉取请求使用企业级运行器必需路径和标准托管兼容性作业,其他大型运行器规格仅通过手动触发运行。
## 曾考虑的替代方案
**恢复原有的核心、CPU 和生产网站通道。** 这些作业均达到延迟目标,但它们需要 3 轮设置,而且在大型运行器已经可用后仍对主 Node 工作进行分片。全规格运行轨迹表明,让单机聚合流程超过 1 分钟的是一项不必要的依赖,而非主机容量不足。
**保留 3 个粗粒度 Linux 主流程通道。** 核心、CPU 和生产网站作业均达到延迟目标,但它们需要 3 轮设置,而且在大型运行器已经可用后仍对主 Node 工作进行分片。全规格运行轨迹表明,让单机聚合流程超过 1 分钟的是一项不必要的依赖,而非主机容量不足。
**将原有的门禁级分片拓扑保留为手动参考。** 一套闲置的第二拓扑会让数百行工作流、选择器模块和场景分区行为继续存活。全规格和串行套件无需保留任何必需作业都不执行的生产代码,也能提供计时与完整性对照。
@@ -68,7 +68,7 @@ Windows 仓库工作在超过 16 核后收益很小,但 32 核池可以让完
**将静态门禁和构建后消费方保留在同一台运行器上。** 复用同一个工作区可以省去一轮设置和一次产物传输,但构建耗时的波动会延迟每个消费方,并使消费方的 lint 和快照尾段延续到静态结果之后。仅供本次运行使用的已构建目录树可以保留同一份构建结果,而相互独立的作业能让两条完整路径都保持在实测目标内。
**将大型运行器池作为必需作业的默认运行环境。** 当运行器能够分配时,此方案可提供实测更低的延迟;但若未获得相应使用权限或企业转移延迟,必需作业会持续排队,且不会发出仓库诊断。可移植路径接受更长的运行时间,手动套件则保留性能实验
**将完整必需路径保留在 GitHub 标准托管容量上。** 此方案可以避免依赖仓库外部的运行器配置,但标准运行器上的分支头精确运行仍明显更慢,也可能因共享容量而排队更久。标准托管兼容性作业和串行参考流程保留可移植证据,无需让这套较慢的拓扑成为普通主路径
**将必需的 Windows 检查和观测性 Windows 检查保留在不同作业中。** 这种拆分在工作流层保留状态语义,却需要支付两次设置开销。`run-gates` 在一个进程内保留了相同的必需与非阻塞区别。
@@ -76,10 +76,10 @@ Windows 仓库工作在超过 16 核后收益很小,但 32 核池可以让完
## 后果
必需拓扑中的每个标准托管通道只承担 1 轮设置开销,且不保留分片选择器。只有在触发基准测试时,实质性 CI 清单才会消耗企业级大型运行器分钟数;轻量级聚合流程单独选择运行器,不属于本决策范围
必需拓扑中的每个 32 核通道只承担 1 轮设置开销,且不保留分片选择器。每个普通拉取请求都会消耗付费的企业级 Linux 和 Windows 运行器分钟数;只有在重新测量有价值时,手动基准测试才会加入其他规格
拆分 Linux 会重复两轮设置并传输一份已构建目录树,但能使覆盖率、静态门禁与构建后消费方不再相互进入关键路径,且无需重复构建合并 Windows 避免重复其耗时更长的设置。代价是总耗时长于经测量的大型运行器拓扑。
GitHub 会把每次大型运行器执行向上取整到整分钟计费,因此完整作业测量能同时呈现计费时长与工作流复杂度。拆分 Linux 会重复两轮设置并传输一份已构建目录树,但能使覆盖率、静态门禁与构建后消费方不再相互进入关键路径,且无需重复构建合并 Windows 避免重复其耗时更长的设置。
性能目标是观测结果,而非取消截止时间或正确性要求。当映像、依赖、调度器或定价发生变化而需要重新测量时,仍可使用手动全规格和串行套件。
企业级运行器标签缺失或改名时,手动基准测试会不可用,但不会让实质性主作业排队。运行器分配能力恢复后,保留的运行器池仍可比较不同规格,同时不会让运行器分配成为仓库门禁执行的运维依赖。
企业级运行器标签缺失或改名时,必需主作业会持续排队。标准托管兼容性作业与 `master` 参考流程仍会报告有用证据,但不能替代必需聚合流程;因此,运行器分配是一项仓库 CI 无法修复的运维依赖。
@@ -1,6 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-23-portable-required-pull-request-ci.md
2026-07-23-portable-required-pull-request-ci.md: 4fd915a00300922d7318c78d16e1e8078b5170ed
2026-07-23-portable-required-pull-request-ci.zh.md: 9d489970a46279de8033cb82af64489d86b20d2c
# pnpm run verify-translation-pairing --write
2026-07-23-portable-required-pull-request-ci.md: d1002c7d9db7cd8bbed3bdfda8a773a4b124bf16
2026-07-23-portable-required-pull-request-ci.zh.md: fedfc6b9c982ace5ece430c52db23c22ec5119d4
@@ -12,24 +12,24 @@ Billing health, a runner definition's `Ready` state, and a large autoscaling cei
## Decision
[CI](../../../../.github/workflows/ci.yml) runs the three required primary Node 24 jobs on standard `ubuntu-latest` and the complete required Windows job on standard `windows-2025`. Static gates publish their exact built tree for the snapshot and artifact job, while coverage remains independent. Top-level gates, coverage, ESLint, publint, and snapshot replay use single-worker bounds on these smaller hosts. Node 22.19, Node 26, and Python SDK compatibility also use standard capacity. The lightweight `all checks passed` aggregate remains a separate scheduling decision because it performs no checkout or repository gate.
[CI](../../../../.github/workflows/ci.yml) runs the required primary Node 24 jobs, plus the stable `all checks passed` aggregate, on repo-restricted enterprise 32-core pools. The aggregate performs no checkout or repository gate, but sharing the enterprise pool prevents the required verdict from introducing a separate standard-hosted billing dependency after its substantive jobs have already succeeded. The required Windows job runs on standard `windows-2025` with single-worker bounds, keeping the complete Windows contract independent of enterprise Windows allocation. Standard `ubuntu-latest` jobs retain Node 22.19, Node 26, and Python SDK compatibility, and `master` runs complete serial Linux, macOS, and Windows references. Those standard-hosted jobs keep the portable execution boundary observable without duplicating the primary inventory on every pull request.
The three Linux primary jobs, Node compatibility, Python SDK, and `windows node 24 / complete` remain dependencies of `all checks passed`; no gate is removed or made observational to recover availability. Branch protection continues to require `e2e` and `all checks passed`.
The two Linux primary jobs, Node compatibility, Python SDK, and `windows node 24 / complete` remain dependencies of `all checks passed`; branch protection continues to require `e2e` and `all checks passed`. There is no automatic fallback when a remaining enterprise Linux label cannot allocate: the standard jobs continue to report their own contracts, but they cannot manufacture the missing required result.
The [larger-runner decision](2026-07-22-evidence-based-larger-hosted-runners.md) owns the retained performance measurements and manual suites. The [serial cross-platform reference](2026-07-21-serial-cross-platform-ci-reference.md) remains the independent standard-hosted completeness check.
The [larger-runner decision](2026-07-22-evidence-based-larger-hosted-runners.md) owns the current primary topology and its measurements. The [serial cross-platform reference](2026-07-21-serial-cross-platform-ci-reference.md) remains the independent standard-hosted completeness check, and the manual larger-runner suites retain size comparisons without expanding the ordinary required matrix.
## Alternatives considered
**Wait for enterprise allocation to recover.** A queue with no assigned runner emits no repository diagnostic and can block every pull request indefinitely, so external recovery is not a correctness path.
**Keep the Linux primary jobs and aggregate on standard capacity.** This removes the remaining enterprise allocation dependency, but complete standard-runner jobs give materially slower feedback and still experience shared-capacity queues. The current split retains portable compatibility and serial evidence while spending enterprise capacity on the Linux primary critical path.
**Use only the smallest enterprise pools.** Every named pool crosses the same enterprise allocation boundary; reducing core count does not remove the dependency that caused the queue.
**Select enterprise size from advertised core count.** Benchmarks show non-monotonic scaling and setup variance, so exact complete-job measurements choose the required pools instead.
**Skip or demote checks while capacity is unavailable.** This would make the status green by dropping evidence rather than by running the repository's required contracts.
**Keep larger-runner worker limits on standard runners.** Concurrent repository gates and their inner worker pools can oversubscribe the smaller memory and CPU allocation, turning an availability repair into contention failures.
**Use one worker policy on every host.** Outer gate concurrency and inner tool workers contend differently on Linux, Windows, and standard runners; measured host-specific bounds avoid turning additional cores into slower execution.
## Consequences
Ordinary pull requests can acquire every substantive runner without enterprise-specific configuration. A live exact-head run proves the same commands that branch protection consumes, at the cost of longer elapsed time on smaller hosts.
Ordinary pull requests spend enterprise capacity on the Linux critical path while standard Windows trades longer runtime for independent allocation. A live exact-head run proves the same commands that branch protection consumes; queue delay is reported separately from each job's `startedAt` to `completedAt` execution interval.
Manual larger-runner benchmarks can remain queued without blocking pull requests. Restoring larger runners to the required path needs a separate evidence-based decision after exact-head jobs receive nonzero runner IDs and complete reliably; changing a pool definition's status alone is insufficient.
Standard compatibility and required Windows jobs remain useful when enterprise allocation is degraded, but they do not make a blocked required Linux job or aggregate green. Recovering Linux availability may require restoring the complete standard-hosted topology; changing a pool definition's status alone is insufficient evidence that it can receive work.
@@ -12,24 +12,24 @@ Status: implemented
## 决策
[CI](../../../../.github/workflows/ci.yml) 在标准 `ubuntu-latest` 上运行 3 项必需的主 Node 24 作业,并在标准 `windows-2025` 上运行完整的必需 Windows 作业。静态门禁发布其完全一致的已构建目录树,供快照与产物作业使用;覆盖率作业则保持独立。这些较小主机上的顶层门禁、覆盖率、ESLint、publint 和快照回放均采用单工作线程上限。Node 22.19、Node 26 和 Python SDK 兼容性也使用标准容量。轻量级 `all checks passed` 聚合流程仍由单独的调度决策管理,因为它不执行代码检出或仓库门禁
[CI](../../../../.github/workflows/ci.yml) 在仅限本仓库使用的企业级 32 核运行器池上运行必需的主 Node 24 作业,以及稳定的 `all checks passed` 聚合流程。该聚合流程不执行代码检出或仓库门禁;但让它与所依赖的实质性作业共用企业级运行器池,可以避免这些作业已经成功后,必需判定结果又引入一项单独的标准托管计费依赖。必需的 Windows 作业在标准 `windows-2025` 上运行,并采用单工作线程上限,使完整的 Windows 契约不依赖企业级 Windows 运行器分配。标准 `ubuntu-latest` 作业保留 Node 22.19、Node 26 和 Python SDK 兼容性,`master` 则运行完整的 Linux、macOS 和 Windows 串行参考流程。这些标准托管作业让可移植执行边界保持可观测,而不必在每个拉取请求中重复主清单
3 项 Linux 主作业、Node 兼容性、Python SDK 和 `windows node 24 / complete` 继续作为 `all checks passed` 的依赖项;为恢复可用性,没有移除任何门禁,也没有将任何门禁改为仅供观测。分支保护继续要求 `e2e``all checks passed`
项 Linux 主作业、Node 兼容性、Python SDK 和 `windows node 24 / complete` 继续作为 `all checks passed` 的依赖项;分支保护继续要求 `e2e``all checks passed`剩余的企业级 Linux 运行器标签无法分配运行器时没有自动后备机制:标准作业会继续报告各自的契约,但无法产出缺失的必需结果。
保留的性能测量结果与手动套件由[大型运行器决策](2026-07-22-evidence-based-larger-hosted-runners.md)记录。[跨平台串行参考流程](2026-07-21-serial-cross-platform-ci-reference.md)继续作为独立的标准托管完整性检查。
当前主拓扑及其测量结果由[大型运行器决策](2026-07-22-evidence-based-larger-hosted-runners.md)记录。[跨平台串行参考流程](2026-07-21-serial-cross-platform-ci-reference.md)继续作为独立的标准托管完整性检查,手动大型运行器套件则保留规格比较,同时不扩大普通必需矩阵
## 曾考虑的替代方案
**等待企业级运行器分配恢复。** 未分配运行器的队列不会发出任何仓库诊断,并且可能无限期阻塞所有拉取请求,因此外部恢复不能作为正确性路径。
**将 Linux 主作业和聚合流程保留在标准容量上。** 此方案消除了剩余的企业级运行器分配依赖,但标准运行器上的完整作业反馈明显更慢,仍会遇到共享容量排队。当前拆分既保留可移植兼容性和串行证据,又将企业级运行器容量用于 Linux 主关键路径。
**仅使用最小的企业级运行器池。** 无论指定哪个运行器池,都要经过同一个企业级分配边界;减少核心数并不能消除导致排队的依赖
**根据标称核心数选择企业规格。** 基准测试表明扩展效果不呈单调变化,设置耗时也存在波动,因此必需运行器池改由完整作业的精确测量结果选定
**在容量不可用时跳过检查或降低其级别。** 这种方式通过丢弃证据而非执行仓库的必需契约来使状态变绿。
**在标准运行器上沿用大型运行器的工作线程上限** 并发运行的仓库门禁及其内部工作线程池,可能让并发需求超过较小的内存和 CPU 配额,使可用性修复反而引发资源争用故障
**在每台主机上使用同一工作线程策略** 外层门禁并发与内层工具工作线程在 Linux、Windows 和标准运行器上的争用方式不同;按主机实测的上限可以避免新增核心反而拖慢执行
## 后果
普通拉取请求无需企业专用配置,即可为每项实质性作业获得运行器。一次实际的分支头精确运行能够证明分支保护使用的同一组命令,代价是在较小主机上耗时更长
普通拉取请求会将企业级运行器容量用于 Linux 关键路径,而标准托管 Windows 作业则以更长的运行时间换取不依赖企业池的运行器分配。一次实际的分支头精确运行能够证明分支保护使用的同一组命令;排队延迟与每个作业从 `startedAt``completedAt` 的执行区间分开报告
手动大型运行器基准测试即使持续排队,也不会阻塞拉取请求。只有在分支头精确作业获得非零运行器 ID 并稳定完成后,才能另行作出基于证据的决策,将大型运行器恢复到必需路径;仅改变运行器池定义的状态仍然不够
企业级运行器分配能力下降时,标准兼容性作业和必需的 Windows 作业仍能提供有用证据,但无法让受阻的必需 Linux 作业或聚合流程变绿。恢复 Linux 可用性时,可能需要恢复完整的标准托管拓扑;仅改变运行器池定义的状态,不足以证明它可以接收作业
@@ -1,6 +0,0 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-07-27-portable-required-status-aggregation.md
2026-07-27-portable-required-status-aggregation.md: 081d841cfb939c97f189c46fc0985f9ff2d1987d
2026-07-27-portable-required-status-aggregation.zh.md: 896e9500d2ad6e2e0ef6c6cc7a37373c6d28b303
@@ -1,35 +0,0 @@
# Agent Note: Portable required-status aggregation
Status: implemented
English | [中文](2026-07-27-portable-required-status-aggregation.zh.md)
## Problem
Branch protection consumes one stable `all checks passed` job instead of tracking the changing names of matrix legs and execution lanes. This job performs no repository work: after its blocking dependencies finish, it only reduces their results into the required verdict.
Assigning that bookkeeping job to a custom runner pool adds an external allocation dependency without using the pool's additional CPU or memory. A provisioning failure can therefore leave the final required status queued even after every substantive check has produced its evidence.
## Decision
The `all-checks-passed` job in [CI](../../../../.github/workflows/ci.yml) runs on standard GitHub-hosted `ubuntu-latest`. It keeps every blocking job in `needs`, retains its load-bearing `if: always()` condition, fails when any dependency is failed, cancelled, or skipped, and succeeds only when every dependency succeeds. It performs no checkout, toolchain setup, dependency installation, or repository gate.
The aggregate depends only on production standard-hosted capacity; it does not use organization-defined, enterprise-defined, or self-hosted labels. Substantive jobs choose their own runner topology independently. Moving this verdict does not change their commands, weaken their evidence, or make an unresolved dependency pass: the aggregate waits for unfinished dependencies and fails on non-success terminal results.
This decision supersedes only the aggregate-placement clause in the [portable pull-request CI recovery boundary](2026-07-23-portable-required-pull-request-ci.md), which continues to own the substantive jobs' recovery topology. The final bookkeeping status remains separately owned so runner-topology changes and branch-protection aggregation can evolve independently.
## Alternatives considered
**Run the aggregate beside substantive jobs on a custom enterprise pool.** This avoids one short standard-hosted allocation, but gives the bookkeeping job a provisioning failure mode without using the larger machine's capacity.
**Use a standby self-hosted runner.** This replaces one external readiness dependency with another and makes a required verdict depend on a separately operated machine. Managed standard-hosted capacity is the production path for this bookkeeping work.
**Require every substantive job directly in branch protection.** This removes the aggregate allocation, but couples repository settings to matrix and lane names that change as the CI topology evolves.
**Treat missing or non-success dependencies as success.** This would produce a green status by discarding required evidence rather than by completing it.
## Consequences
Each pull request allocates one short standard-hosted job after its substantive dependencies settle. Because the job performs no checkout or setup, it adds little active runtime, but its scheduling and billing remain separate from custom pools.
A custom-pool outage can still keep a substantive dependency queued, and the aggregate correctly waits in that case. Once the dependencies reach terminal results, the final required verdict no longer needs custom-pool or self-hosted allocation. Future changes can move substantive jobs between standard and larger runners without reintroducing that dependency into the branch-protection status.
@@ -1,35 +0,0 @@
# Agent Note: 必需状态的可移植聚合
Status: implemented
[English](2026-07-27-portable-required-status-aggregation.md) | 中文
## 问题
分支保护只使用一项稳定的 `all checks passed` 作业,无需跟踪持续变化的矩阵分支名和执行通道名。该作业不执行任何仓库工作:会阻塞判定的依赖项结束后,它只将这些依赖项的结果归并为必需判定。
将这项结果汇总作业分配给自定义运行器池,会在不使用该池额外 CPU 或内存的情况下增加一项外部运行器分配依赖。因此,即使所有实质性检查都已产出证据,预配失败仍可能让最终的必需状态持续排队。
## 决策
[CI](../../../../.github/workflows/ci.yml) 中的 `all-checks-passed` 作业在 GitHub 标准托管的 `ubuntu-latest` 上运行。它在 `needs` 中保留所有会阻塞判定的作业,保留承重的 `if: always()` 条件;任何依赖项失败、被取消或被跳过时,该作业都会失败,只有所有依赖项都成功时才会成功。它不执行代码检出、工具链设置、依赖安装或仓库门禁。
聚合作业只依赖生产环境的标准托管容量;它不使用组织定义的、企业定义的或自托管的运行器标签。实质性作业各自独立选择运行器拓扑。调整这项判定作业的运行位置,不会改变实质性作业的命令、削弱其证据或使未完成的依赖项通过:聚合作业会等待尚未结束的依赖项,并在依赖项产生非成功的终态结果时失败。
本决策仅取代[拉取请求 CI 的可移植恢复边界](2026-07-23-portable-required-pull-request-ci.md)中关于聚合作业运行位置的条款;该记录继续规定实质性作业的恢复拓扑。最终的结果汇总状态仍由本决策单独规定,使运行器拓扑变更与分支保护聚合可以独立演进。
## 曾考虑的替代方案
**让聚合作业与实质性作业一同在自定义企业级运行器池上运行。** 此方案可以避免一次短暂的标准托管运行器分配,但会在未使用大型机器容量的情况下,为结果汇总作业引入预配失败的故障模式。
**使用备用自托管运行器。** 此方案只是用另一项外就绪状态依赖替换原有依赖,并使必需判定依赖一台单独运维的机器。由平台管理的标准托管容量是这项结果汇总工作的生产路径。
**在分支保护中直接要求每项实质性作业。** 此方案不再需要为聚合作业分配运行器,但会将仓库设置与随 CI 拓扑演进而变化的矩阵分支名和通道名耦合。
**将缺失或非成功的依赖项视为成功。** 这种做法不是通过完成相应检查来产出必需证据,而是丢弃这些证据以产出绿色状态。
## 后果
每个拉取请求都会在实质性依赖项的结果确定后分配一项短时运行的标准托管作业。由于该作业不执行代码检出或设置,它只增加少量活跃运行时间,但其调度和计费仍独立于自定义运行器池。
自定义运行器池不可用仍可能让实质性依赖项持续排队,聚合作业在这种情况下会按设计等待。依赖项产生终态结果后,最终的必需判定不再需要自定义运行器池或自托管运行器分配。未来可以在标准运行器与大型运行器之间迁移实质性作业,而不会将这项依赖重新引入分支保护状态。
+13 -13
View File
@@ -27,15 +27,15 @@ env:
jobs:
# Three standard Linux jobs isolate coverage, static analysis, and the
# Three enterprise jobs isolate coverage, static analysis, and the
# build-backed consumer tail. The static job publishes its exact build so
# consumers do not repeat the longest part of their critical path.
node-24:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
runs-on: dsh-enterprise-ubuntu-latest-32core-test
name: node 24 / static
env:
DSH_GATE_CONCURRENCY: '1'
DSH_GATE_CONCURRENCY: '8'
steps:
# Fetch complete history so the archive gate can read the trusted PR base from a reused shallow checkout.
- uses: actions/checkout@v6
@@ -81,11 +81,11 @@ jobs:
node-24-coverage:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
runs-on: dsh-enterprise-ubuntu-24-04-32core-test
name: node 24 / coverage
env:
DSH_COVERAGE_MAX_WORKERS: '1'
DSH_GATE_CONCURRENCY: '1'
DSH_COVERAGE_MAX_WORKERS: '24'
DSH_GATE_CONCURRENCY: '8'
steps:
- uses: actions/checkout@v6
with:
@@ -122,15 +122,15 @@ jobs:
node-24-consumers:
needs: node-24
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
runs-on: dsh-enterprise-ubuntu-latest-32core-test
name: node 24 / snapshots and artifacts
env:
DSH_ESLINT_CACHE: '1'
DSH_ESLINT_CONCURRENCY: '1'
DSH_GATE_CONCURRENCY: '1'
DSH_ESLINT_CONCURRENCY: '8'
DSH_GATE_CONCURRENCY: '8'
DSH_NODE_COMPAT_SKIP_TYPECHECK: '1'
DSH_PUBLINT_CONCURRENCY: '1'
DSH_SNAPSHOT_MAX_CONCURRENCY: '1'
DSH_PUBLINT_CONCURRENCY: '8'
DSH_SNAPSHOT_MAX_CONCURRENCY: '32'
steps:
- uses: actions/checkout@v6
with:
@@ -693,8 +693,8 @@ jobs:
# 'cancelled' and 'skipped'.
all-checks-passed:
name: all checks passed
# This bookkeeping-only verdict must not depend on custom-pool provisioning.
runs-on: ubuntu-latest
# The required verdict must not add a separate standard-hosted billing dependency.
runs-on: dsh-enterprise-ubuntu-latest-32core-test
needs: [node-24, node-24-coverage, node-24-consumers, node-compat, python-sdk, windows]
if: always() && github.event_name == 'pull_request'
steps: