fix(dev-infra): serialize lint after invariant staging

This commit is contained in:
Tianyi Cui
2026-07-28 00:36:05 +08:00
parent 6b0cec04d6
commit 5b79a43d4c
5 changed files with 10 additions and 6 deletions
@@ -2,5 +2,5 @@
# 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-replayable-gate-plans.md
2026-07-27-replayable-gate-plans.md: fc4f883d74d765d173a6d1419c2e75f44bd1966f
2026-07-27-replayable-gate-plans.zh.md: d6c6eb9649120c7dfbfb6cd0c935e915c62f40ef
2026-07-27-replayable-gate-plans.md: a45b4e056a57b0d4c55b5f0a5d61c85e10cc0f92
2026-07-27-replayable-gate-plans.zh.md: 0d356825c9727dd404d78249619c15ccf2dfbea2
@@ -20,7 +20,7 @@ Every mode supports deterministic `--list` output and a versioned stable `--list
The scheduler announces each start, buffers a child's stdout and stderr until that gate settles, and then emits one attributable result while unrelated gates continue. Failure blocks include the display command, redacted scheduler-owned environment operations, orthogonal exit and signal outcomes, complete child output, and the replay command; successful child output remains suppressed unless `DSH_GATE_VERBOSE=1`. Child output is not persisted.
The `check:ci:consumers` mode owns the Node 24 consumer job's seven top-level commands and a plan-visible seven-worker default and ceiling. That default preserves the prior process pool even on a host reporting fewer CPUs; `DSH_GATE_CONCURRENCY` may request fewer workers but cannot exceed the plan ceiling. Publint first validates the manifest-declared public artifact view, including the existence of exported files; `verify-built-package-invariants` then depends on publint and validates every compiled invariant plus its declared runtime closure and the restored Loader bundle. Snapshot, NodeNext type checks, and built-bin smokes depend on both stages through `verify-built-package-invariants`, while source lint and source compatibility smokes may overlap them.
The `check:ci:consumers` mode owns the Node 24 consumer job's seven top-level commands and a plan-visible seven-worker default and ceiling. That default preserves the prior process pool even on a host reporting fewer CPUs; `DSH_GATE_CONCURRENCY` may request fewer workers but cannot exceed the plan ceiling. Publint first validates the manifest-declared public artifact view, including the existence of exported files; `verify-built-package-invariants` then depends on publint and validates every compiled invariant plus its declared runtime closure and the restored Loader bundle. Snapshot, NodeNext type checks, and built-bin smokes depend on both stages through `verify-built-package-invariants`. Source compatibility smokes may overlap the validation stages; lint and duplication wait for built-package invariant validation so ESLint cannot traverse its transient staged package views, then may overlap downstream consumers.
## Verification
@@ -42,6 +42,6 @@ The `check:ci:consumers` mode owns the Node 24 consumer job's seven top-level co
The scheduler owns a small CLI and a versioned JSON schema that must evolve deliberately with the gate model. Focused replay is faster to diagnose but is not complete evidence, so the CLI labels it explicitly and always names the owning aggregate.
Later artifact consumers start only after publint and built-package invariant validation, reducing their overlap when either verifier is slow. Independent source checks still overlap both stages; a missing public export or broken compiled-invariant closure fails before it can produce misleading downstream results.
Later artifact consumers and lint start only after publint and built-package invariant validation, so ESLint cannot traverse the verifier's transient staged views and those downstream gates may overlap one another. Source compatibility smokes still overlap both validation stages; a missing public export or broken compiled-invariant closure fails before it can produce misleading downstream results.
Buffered output is coherent and attributable, but no progress from a long-running child appears until that child settles, and the runner retains no second copy after the console is lost. Operators trade live interleaving and durable local output for a smaller scheduler whose diagnostic state is the inspected plan, settlement block, and replay command.
@@ -20,7 +20,7 @@ Status: implemented
调度器会宣告每项门禁开始运行,将子进程的 stdout 和 stderr 缓冲到该门禁结束,再在无关门禁仍继续运行时输出一项归属明确的结果。失败块包含显示命令、经过脱敏且由调度器掌管的环境操作、彼此独立的退出码和信号结果、完整的子进程输出,以及回放命令;成功运行的子进程输出默认仍不显示,只有设置 `DSH_GATE_VERBOSE=1` 时才会输出。子进程输出不会持久化。
`check:ci:consumers` 模式管理 Node 24 消费方作业的 7 条顶层命令,以及计划中可见的 7 个工作进程默认值和上限。即使主机报告的 CPU 数量更少,该默认值仍会保留原有进程池;`DSH_GATE_CONCURRENCY` 可以请求更少的工作进程,但不能超过计划上限。publint 首先验证 manifest(元数据清单)所声明的公开产物视图,包括导出文件是否存在;`verify-built-package-invariants` 随后依赖 publint,验证每个已编译不变式、其声明的运行时闭包以及恢复后的 Loader bundle。快照、NodeNext 类型检查和已构建二进制文件的冒烟测试都通过 `verify-built-package-invariants` 依赖这两个阶段,而源码 lint 和源码兼容性冒烟测试可以与它们并行。
`check:ci:consumers` 模式管理 Node 24 消费方作业的 7 条顶层命令,以及计划中可见的 7 个工作进程默认值和上限。即使主机报告的 CPU 数量更少,该默认值仍会保留原有进程池;`DSH_GATE_CONCURRENCY` 可以请求更少的工作进程,但不能超过计划上限。publint 首先验证 manifest(元数据清单)所声明的公开产物视图,包括导出文件是否存在;`verify-built-package-invariants` 随后依赖 publint,验证每个已编译不变式、其声明的运行时闭包以及恢复后的 Loader bundle。快照、NodeNext 类型检查和已构建二进制文件的冒烟测试都通过 `verify-built-package-invariants` 依赖这两个阶段源码兼容性冒烟测试可以与验证阶段并行;lint 和 duplication 会等待已构建包不变式验证,以免 ESLint 遍历验证过程中临时暂存的包视图,之后可以与下游消费方并行。
## 验证
+1
View File
@@ -364,6 +364,7 @@ describe('Node 24 consumer plan', () => {
])
expect(subject.gates.find(item => item.id === 'publint')?.needs).toBeUndefined()
expect(subject.gates.find(item => item.id === 'built-package-invariants')?.needs).toEqual(['publint'])
expect(subject.gates.find(item => item.id === 'lint-and-duplication')?.needs).toEqual(['built-package-invariants'])
for (const id of ['snapshot', 'node-next-types', 'built-bin-smoke']) {
expect(subject.gates.find(item => item.id === id)?.needs).toEqual(['built-package-invariants'])
}
+4 -1
View File
@@ -414,7 +414,10 @@ function ciConsumerGates(): Gate[] {
const publicArtifacts = ['publint']
const restoredBuild = ['built-package-invariants']
return [
pnpmScript('lint-and-duplication', 'check:ci:lint', { label: 'lint and duplication' }),
pnpmScript('lint-and-duplication', 'check:ci:lint', {
label: 'lint and duplication',
needs: restoredBuild,
}),
pnpmScript('node-compat', 'check:node-compat', { label: 'Node compatibility' }),
snapshotGate(restoredBuild),
pnpmScript('publint', 'publint'),