ci: [CI-01] verify identical tarballs on three Node runtimes

This commit is contained in:
Harvey Zhao committed 2026-09-13 13:21:17 +08:00
1 parent 585e11c53c
commit 38355ae4cf
21 files changed
+839 -27

No files matched your search

@@ -0,0 +1,441 @@
{
"schemaVersion": 1,
"task": "CI-01",
"date": "2026-09-13",
"baseCommit": "585e11c53c03b4b12933b21dcfe8c4a117299b2b",
"candidateScope": "Accompanying CI-01 working tree; production package code unchanged",
"nodeBinaries": [
{
"node": "20.19.0",
"platform": "win-x64",
"sha256": "6e3a39787e667d50487f7335c85636c2823a53e636d73c2c841d45da4e57906c",
"source": "https://nodejs.org/download/release/v20.19.0/SHASUMS256.txt"
},
{
"node": "22.12.0",
"platform": "win-x64",
"sha256": "b3b117a08ee61efee09e6fd523ab33c0c018da1b570bde08e4fd914dc1170ed6",
"source": "https://nodejs.org/download/release/v22.12.0/SHASUMS256.txt"
}
],
"build": {
"node": "24.21.0",
"yarn": "1.22.22",
"legacyTypeModes": 5,
"preciseTypeModes": 8,
"knownTypeBlockers": 0,
"knownRuntimeBlockers": 1
},
"runs": [
{
"node": "20.19.0",
"buildNode": "24.21.0",
"passed": true,
"candidateChecks": [
"DIST.cjs",
"DIST.cjs-legacy",
"DIST.esm",
"DIST.esm-default-only",
"DIST.esm-legacy",
"DIST.runtime-cjs-identity",
"DIST.runtime-esm-identity",
"DIST.runtime-legacy-identity",
"DIST.runtime-shared-statics",
"DIST.runtime-types-only",
"DIST.global-core",
"DIST.amd-core",
"DIST.global-core-legacy",
"DIST.amd-core-legacy",
"DIST.global-chapter",
"DIST.amd-chapter",
"DIST.global-chapter-legacy",
"DIST.amd-chapter-legacy",
"SSR.import-template",
"SSR.constructor-browser-only",
"SSR.custom-ua-umd-legacy",
"SSR.custom-ua-esm",
"DIST.i18n-cjs-esm-global",
"DIST.exports-boundary",
"DIST.direct-esm-file",
"EVENT.lazy-registry",
"EVENT.symbol-number-channels",
"EVENT.context-removal",
"EVENT.once-throw-consumed",
"EVENT.chain-context-arguments",
"EVENT.once-reentry",
"EVENT.dispatch-snapshot",
"EVENT.off-original-once",
"EVENT.throw-propagation",
"SSR.defaults-missing-navigator-known-failure",
"API.defaults-controlled-language"
],
"publishedChecks": [
"DIST.cjs",
"DIST.cjs-legacy",
"DIST.esm",
"DIST.esm-default-only",
"DIST.esm-legacy",
"DIST.global-core",
"DIST.amd-core",
"DIST.global-core-legacy",
"DIST.amd-core-legacy",
"DIST.global-chapter",
"DIST.amd-chapter",
"DIST.global-chapter-legacy",
"DIST.amd-chapter-legacy",
"SSR.import-template",
"SSR.constructor-browser-only",
"SSR.custom-ua-umd-legacy",
"SSR.custom-ua-esm",
"DIST.i18n-cjs-esm-global",
"DIST.exports-boundary",
"DIST.direct-esm-file",
"EVENT.lazy-registry",
"EVENT.symbol-number-channels",
"EVENT.context-removal",
"EVENT.once-throw-consumed",
"EVENT.chain-context-arguments",
"EVENT.once-reentry",
"EVENT.dispatch-snapshot",
"EVENT.off-original-once",
"EVENT.throw-propagation",
"SSR.defaults-missing-navigator-known-failure",
"API.defaults-controlled-language"
],
"unresolved": {
"name": "ReferenceError",
"message": "navigator is not defined",
"historical": false,
"resolved": false
},
"installedPackages": [
{
"name": "artplayer",
"version": "5.4.1",
"sha256": "6298aa247ca273fa5fb80297fc49d4434609e611e24a7f24cb37752c6768c214"
},
{
"name": "artplayer-plugin-chapter",
"version": "1.1.0",
"sha256": "53eb3c1bbcc046a28ae499cfb19731eb66a16453bf44eae73e03693bbb510793"
}
],
"report": {
"file": "refactor/.cache/packages/run-oT7iFE/runtime-node-20.19.0.json",
"sha256": "19f69281782a34a7829b47bdfbebeaa22a2bcbaef9e1b982bdd615247b136286"
},
"installLog": {
"file": "refactor/.cache/packages/run-oT7iFE/runtime-node-20.19.0-install.log",
"sha256": "048cba88c2a0a9c14e1e195ac88af9c4c359b6058672d542c49cdb2c6e4f1e6d"
}
},
{
"node": "22.12.0",
"buildNode": "24.21.0",
"passed": true,
"candidateChecks": [
"DIST.cjs",
"DIST.cjs-legacy",
"DIST.esm",
"DIST.esm-default-only",
"DIST.esm-legacy",
"DIST.runtime-cjs-identity",
"DIST.runtime-esm-identity",
"DIST.runtime-legacy-identity",
"DIST.runtime-shared-statics",
"DIST.runtime-types-only",
"DIST.global-core",
"DIST.amd-core",
"DIST.global-core-legacy",
"DIST.amd-core-legacy",
"DIST.global-chapter",
"DIST.amd-chapter",
"DIST.global-chapter-legacy",
"DIST.amd-chapter-legacy",
"SSR.import-template",
"SSR.constructor-browser-only",
"SSR.custom-ua-umd-legacy",
"SSR.custom-ua-esm",
"DIST.i18n-cjs-esm-global",
"DIST.exports-boundary",
"DIST.direct-esm-file",
"EVENT.lazy-registry",
"EVENT.symbol-number-channels",
"EVENT.context-removal",
"EVENT.once-throw-consumed",
"EVENT.chain-context-arguments",
"EVENT.once-reentry",
"EVENT.dispatch-snapshot",
"EVENT.off-original-once",
"EVENT.throw-propagation",
"SSR.defaults-missing-navigator-known-failure",
"API.defaults-controlled-language"
],
"publishedChecks": [
"DIST.cjs",
"DIST.cjs-legacy",
"DIST.esm",
"DIST.esm-default-only",
"DIST.esm-legacy",
"DIST.global-core",
"DIST.amd-core",
"DIST.global-core-legacy",
"DIST.amd-core-legacy",
"DIST.global-chapter",
"DIST.amd-chapter",
"DIST.global-chapter-legacy",
"DIST.amd-chapter-legacy",
"SSR.import-template",
"SSR.constructor-browser-only",
"SSR.custom-ua-umd-legacy",
"SSR.custom-ua-esm",
"DIST.i18n-cjs-esm-global",
"DIST.exports-boundary",
"DIST.direct-esm-file",
"EVENT.lazy-registry",
"EVENT.symbol-number-channels",
"EVENT.context-removal",
"EVENT.once-throw-consumed",
"EVENT.chain-context-arguments",
"EVENT.once-reentry",
"EVENT.dispatch-snapshot",
"EVENT.off-original-once",
"EVENT.throw-propagation",
"SSR.defaults-missing-navigator-known-failure",
"API.defaults-controlled-language"
],
"unresolved": {
"name": "ReferenceError",
"message": "navigator is not defined",
"historical": false,
"resolved": false
},
"installedPackages": [
{
"name": "artplayer",
"version": "5.4.1",
"sha256": "6298aa247ca273fa5fb80297fc49d4434609e611e24a7f24cb37752c6768c214"
},
{
"name": "artplayer-plugin-chapter",
"version": "1.1.0",
"sha256": "53eb3c1bbcc046a28ae499cfb19731eb66a16453bf44eae73e03693bbb510793"
}
],
"report": {
"file": "refactor/.cache/packages/run-oT7iFE/runtime-node-22.12.0.json",
"sha256": "6014c69d26444d0c1884aa2be5de801351d4b4f120682ecaef1d5d440ff67084"
},
"installLog": {
"file": "refactor/.cache/packages/run-oT7iFE/runtime-node-22.12.0-install.log",
"sha256": "0ad1239965a5caa605c43986d81a6efa3778fdc4d5752534edd8b21f1059fe62"
}
},
{
"node": "24.21.0",
"buildNode": "24.21.0",
"passed": true,
"candidateChecks": [
"DIST.cjs",
"DIST.cjs-legacy",
"DIST.esm",
"DIST.esm-default-only",
"DIST.esm-legacy",
"DIST.runtime-cjs-identity",
"DIST.runtime-esm-identity",
"DIST.runtime-legacy-identity",
"DIST.runtime-shared-statics",
"DIST.runtime-types-only",
"DIST.global-core",
"DIST.amd-core",
"DIST.global-core-legacy",
"DIST.amd-core-legacy",
"DIST.global-chapter",
"DIST.amd-chapter",
"DIST.global-chapter-legacy",
"DIST.amd-chapter-legacy",
"SSR.import-template",
"SSR.constructor-browser-only",
"SSR.custom-ua-umd-legacy",
"SSR.custom-ua-esm",
"DIST.i18n-cjs-esm-global",
"DIST.exports-boundary",
"DIST.direct-esm-file",
"EVENT.lazy-registry",
"EVENT.symbol-number-channels",
"EVENT.context-removal",
"EVENT.once-throw-consumed",
"EVENT.chain-context-arguments",
"EVENT.once-reentry",
"EVENT.dispatch-snapshot",
"EVENT.off-original-once",
"EVENT.throw-propagation",
"SSR.defaults-missing-navigator-known-failure",
"API.defaults-controlled-language"
],
"publishedChecks": [
"DIST.cjs",
"DIST.cjs-legacy",
"DIST.esm",
"DIST.esm-default-only",
"DIST.esm-legacy",
"DIST.global-core",
"DIST.amd-core",
"DIST.global-core-legacy",
"DIST.amd-core-legacy",
"DIST.global-chapter",
"DIST.amd-chapter",
"DIST.global-chapter-legacy",
"DIST.amd-chapter-legacy",
"SSR.import-template",
"SSR.constructor-browser-only",
"SSR.custom-ua-umd-legacy",
"SSR.custom-ua-esm",
"DIST.i18n-cjs-esm-global",
"DIST.exports-boundary",
"DIST.direct-esm-file",
"EVENT.lazy-registry",
"EVENT.symbol-number-channels",
"EVENT.context-removal",
"EVENT.once-throw-consumed",
"EVENT.chain-context-arguments",
"EVENT.once-reentry",
"EVENT.dispatch-snapshot",
"EVENT.off-original-once",
"EVENT.throw-propagation",
"SSR.defaults-missing-navigator-known-failure",
"API.defaults-controlled-language"
],
"unresolved": {
"name": "ReferenceError",
"message": "navigator is not defined",
"historical": false,
"resolved": false
},
"installedPackages": [
{
"name": "artplayer",
"version": "5.4.1",
"sha256": "6298aa247ca273fa5fb80297fc49d4434609e611e24a7f24cb37752c6768c214"
},
{
"name": "artplayer-plugin-chapter",
"version": "1.1.0",
"sha256": "53eb3c1bbcc046a28ae499cfb19731eb66a16453bf44eae73e03693bbb510793"
}
],
"report": {
"file": "refactor/.cache/packages/run-oT7iFE/runtime-node-24.21.0.json",
"sha256": "8ca41aa19f023561500a9956d8c34a873cf438e062214dfe76310218ccf7b3fd"
},
"installLog": {
"file": "refactor/.cache/packages/run-oT7iFE/runtime-node-24.21.0-install.log",
"sha256": "973f6f01784e113ec2a4da62c6df6dcb32c99b548f23549cc3bc0eec5280f462"
}
}
],
"firstFailure": {
"error": "ReferenceError: navigator is not defined",
"result": "reproduced in published and candidate; CORE-25 open",
"log": {
"file": "refactor/.cache/ci01-node20-runtime.log",
"sha256": "2b2074af5e5afaab44530a047656a53d5736b19fb2dfe40dd54af724570ae60f"
}
},
"strictRelease": {
"command": "yarn test:package:release",
"expectedExitCode": 1,
"actualExitCode": 1,
"reason": "Known runtime blockers remain",
"log": {
"file": "refactor/.cache/ci01-node-release-negative.log",
"sha256": "6ff96a023493ea284411b725734b2cedf7eac3e4b0602ba458dcb14f09515319"
}
},
"localCI": {
"state": "passed",
"command": "yarn ci:check",
"total": 2429,
"unit": 2031,
"engineering": 27,
"baseline": 371,
"seconds": 240.99,
"targeted": 44,
"metadata": 9,
"actionlint": "1.7.12 passed",
"explicitLint": "passed"
},
"remoteActions": null,
"releaseReady": false,
"limitations": [
"Only core/chapter actual package fixture",
"Three Windows Node runtimes; hosted OS runs not verified",
"Historical and candidate missing-navigator failure is an explicit unresolved observation",
"Tooling minimum clean installs and older consumer Node scope remain unverified"
],
"logs": [
{
"file": "refactor/.cache/ci01-node-ci.log",
"sha256": "b753192c80948138e6ef3c063cf68e9a293496c0601340d24c4122d009975071"
},
{
"file": "refactor/.cache/ci01-node-test-ci.log",
"sha256": "c0f509f45e12f0fcf71939c520be4770673cb504e7c44622060ce111efd43279"
},
{
"file": "refactor/.cache/ci01-node-metadata.log",
"sha256": "7ed48f9eab2ac84ff388255dc87c7e28bcaec5125a5fee1651b9326946901e15"
},
{
"file": "refactor/.cache/ci01-node-actionlint.log",
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"file": "refactor/.cache/ci01-node-lint-final.log",
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
],
"inputs": [
{
"file": "scripts/package-runtime.mjs",
"sha256": "ecbe917118e67e4c53965002912bf4bded821f6bd6d00db1f3f1a56e62cab732"
},
{
"file": "scripts/package-consumer.mjs",
"sha256": "3ab9a6ea73981f777ff7db8a7cb0e54c61b5be43c1bcbc05013423afd1645a25"
},
{
"file": "scripts/package-check.mjs",
"sha256": "8b4a65f7f65083104cb0dba6325e622f221574c213f59656367c3c71b610571b"
},
{
"file": "test/package/runtime.cjs",
"sha256": "cf70882e29817dacfde9323b54890c3d0ae23eb2536c98ce90d573963de9721f"
},
{
"file": "test/package-runtime.test.js",
"sha256": "633e15b760c2ea8b9a0cb3eee49fde353f77a8dda7655595f9bded13e48dc4cb"
},
{
"file": "test/package-check.test.js",
"sha256": "e4f41015c81331ef085a158ec0330e82786402aa4f7e0308b7e3b1a95f2a6ff5"
},
{
"file": "refactor/scripts/ci-workflow.mjs",
"sha256": "588ad0e032c3e9a16620202a21bd293edfb042954411f58d7352d6fee38a631c"
},
{
"file": "refactor/scripts/ci-workflow.test.mjs",
"sha256": "6cac9f185739e9ea7753f7220ddcfa4b708a9699c029b998e2e257f6a04dcdb0"
},
{
"file": ".github/workflows/nodejs.yml",
"sha256": "f3f8476f4a35a80845350f83beaba15fdb70690273f9b56e4614b5e048d002bd"
},
{
"file": "package.json",
"sha256": "4b68d39f4e8fb3c1634ab11bde8686c48aa277e2bf2775a4bf3472f2d1030aca"
}
],
"inputByteScope": "Local working-tree bytes; Git checkout line endings may differ"
}
@@ -0,0 +1,64 @@
# CI-01 同一 tarball 的 Node 消费者矩阵
基于 585e11c53c03b4b12933b21dcfe8c4a117299b2b,标准构建 Node 为 24.21.0。
新增 Node 20.19.0、22.12.0、24.21.0 的实际安装运行,CI-01 保持 doing。
这些是私有根包 engines 的两个分支边界与标准环境,不是发布包声明的最低 Node;
目前各发布包没有 engines.node,不能据此抬高消费者门槛或宣称更早 Node 不受支持。
## 实现与维护
package-check 仍在标准 Node 完成构建、Yarn pack、隔离安装、五个旧类型模式和八个
精确类型模式。报告增加真实源码 SHA、Yarn 版本/执行路径与发布基线成员指纹,保留
已校验的 published-artifacts。候选输出保持原路径、内容与 browser-artifacts 格式。
scripts/package-runtime.mjs 只依赖 Node 内置模块,接管原 package-consumer 的运行时
夹具装配;原导出继续转发,类型编译器留在 package-consumer。新增入口在选择的精确
Node 中,读取同一 package-check 报告、校验 HEAD 和 tarball 摘要,使用记录的 Yarn
1.22.22 在仓库外临时目录 offline/frozen 安装同一 tarball,核对锁不变、逐文件字节、
非 workspace 链接,再执行 require/ESM、legacy/runtime/global/AMD、SSR、语言和
Emitter 契约。真实 child Node 版本写入结果;不会悄悄回退到构建 Node。
发布基线也在该 Node 执行。默认值和 API 形状在同一环境比较;历史行为与候选分别报告。
每次消费生成 runtime-node-<version>.json、安装日志,失败时记录错误及 stdout/stderr,
finally 删除经过根路径校验的临时目录。配置/来源预检的早期失败由 workflow tee 日志
保存;尚未创建运行报告时不会伪造成功报告。旧输出无新增来源字段需重新 test:package。
三个系统的 browser-smoke 在打包后依次切到固定 Node 20/22、运行消费者,最后恢复
.node-version 并重装消费;浏览器工具继续使用标准 Node。工作流校验保护版本、执行
顺序、无条件步骤和恢复动作。每个 Node 复用同一构建,不重新生成候选。
新入口 yarn test:package:runtime 在标准环境运行;其他版本显式执行
node scripts/package-runtime.mjs --expected-node <exact version>。需要先运行 yarn test:package。
新测试加入 test:node 与 test:ci;现有构建/类型/包消费入口保留。没有新增 npm 依赖或锁变化。
## 实际发现:CORE-25
Node 20.19.0 的首轮在实际发布 5.4.0 的静态 option getter 触发
ReferenceError: navigator is not defined。当前候选默认值中的 navigator?.language
同样不能保护未声明的全局变量。较新 Node 提供 navigator,原来的测试因此漏检。
现在夹具在每个 Node 明确删除 navigator,精确记录旧/候选都抛出这个错误;然后在
相同受控 en-US navigator 下比较默认值,并恢复原全局描述符。这仅是区分两个测试
场景,不是修复生产代码,也不代表真实浏览器语言验收。新增 CORE-DEFAULTS-SSR-01
风险和 CORE-25 修复任务,REVIEW-01 依赖该任务。候选 knownRuntimeBlockers=1,
严格 test:package:release 因该问题失败;常规兼容测试中的历史失败观察不等于发布就绪。
## 验证与后续
具体版本、二进制/产物摘要、三个运行结果、初始失败、严格发布反例和最终本地 CI
见 [证据](../baselines/node-consumer-validation.json)。新自动化反例覆盖文件篡改、
路径穿越、workspace 链接、错误 Node、过期源码、遗漏消费者与错误恢复运行时。
本批没有播放器生产代码或公开类型改动,不需要生成或提交库产物;真实打包在忽略
缓存的独立快照中执行。没有新浏览器播放或远端 Actions 执行。每个系统的实际运行、
更早消费者范围、最低工具链干净安装、全插件安装矩阵及类型/设备全组合仍需补证。
下一步独立修复 CORE-25,并重跑这三个 Node 和浏览器语言默认值;CI-01 不标完成。
回退本批恢复原消费者装配和 workflow,保留 CORE-25 的缺陷记录与待办。
Node 本地二进制仅下载到忽略缓存,执行前按官方发布摘要核验:
[20.19.0](https://nodejs.org/download/release/v20.19.0/SHASUMS256.txt)、
[22.12.0](https://nodejs.org/download/release/v22.12.0/SHASUMS256.txt)。旧版本用于隔离兼容测试,
没有替换标准 Node 或更改包管理器。提交主题包含 [CI-01];没有推送、部署或发布。
最终本地验证:完整 ci:check 2429 项(2031 单元、27 工程、371 基线),
定向 test:ci 44 项、元数据 9 项、actionlint 1.7.12 与定向只读 ESLint 全部通过。
严格发布反例按预期 exit 1;并未清除 CORE-25。
+9 -4
View File
@@ -19,7 +19,8 @@
| `yarn check:contracts --report` | 校验12类契约/22包归属、版本及报告对应;--write更新静态表,详见 [维护说明](contract-coverage.md) |
| `yarn ci:check` | 严格 Node/Yarn/锁检查、计划、只读 lint、类型、Node 和基线测试;允许写忽略缓存,不修改源码 |
| `yarn check:ci` | 只读校验实际工作流的完整系统矩阵、安装、缓存、报告和最终检查;已接入 ci:check |
| `yarn test:ci` | CI 汇总真实退出码、工作流破坏反例与全包影响分析,共 37 项 |
| `yarn test:ci` | CI 汇总退出码、工作流/影响分析反例与隔离运行时校验,共 44 项 |
| `yarn test:package:runtime` | 标准 Node 重装同一已检查 tarball;须先运行 test:package,其他 Node 使用显式 --expected-node |
| `yarn ci:build` | 21 库包、i18n、编辑器声明和文档站构建,以及构建后包导入 smoke;会生成 dist 和 docs 内容 |
| `yarn check:impact --report` | 读取实际依赖/验证关系和Git变更,核对workflow必需命令,写CI影响报告;已接入ci:check,见[影响映射](impact-analysis.md) |
| `yarn build:all` | 保留旧入口,执行 ci:build 后只读 lint |
@@ -38,10 +39,12 @@ Actions 固定完整 SHA,Node 来自 .node-version,Yarn 固定 1.22.22;安
| --- | --- | --- | --- |
| checks | Linux、Windows | ci:check、ci:build;Linux 额外执行 actionlint | 45 分钟 |
| coverage | Linux、Windows | 既有源码映射与生命周期覆盖检查 | 15 分钟 |
| browser-smoke | Linux、Windows、macOS | 实际 core/chapter 安装产物、Chromium/Firefox/WebKit、iframe history、性能 | 60 分钟 |
| browser-smoke | Linux、Windows、macOS | 同一 core/chapter tarball 的 Node 20/22/24 消费,三浏览器、iframe history、性能 | 60 分钟 |
| CI result | Linux | 汇总以上三个作业组,所有结果必须为 success | 5 分钟 |
Node 均使用 .node-version 的 24.21.0。TS 5.9.3、4.3.5 和迁移运行时兼容 5.1.6
构建与浏览器工具使用 .node-version 的 24.21.0。安装运行时消费分别使用固定 20.19.0、
22.12.0 和标准 Node,不重新构建候选。它们是根工具 engines 的边界测试点,发布包没有
声明 Node 下限;更早 Node 和最低工具链干净安装仍需验证。TS 5.9.3、4.3.5 和迁移运行时兼容 5.1.6
继续由既有类型脚本按各自适用范围运行,不代表最低 Node 或所有包/TS 组合已验收。
矩阵不设置 fail-fast,单个系统失败后仍尽量收集其他系统证据;显式 bash 保留 tee
上游命令的失败退出码。影响报告继续扩大核心/共享变更到全生态,当前不缩减必需作业。
@@ -75,7 +78,9 @@ summary.md 和 GitHub Job Summary,不依赖先前下载的 artifact 来判断
必须针对实际故障,不以清缓存代替修复锁或构建问题。
本地验证与指纹见 [CI-01 记录](changes/2026-09-13-CI-01-matrix-summary.md)。
最低 Node 消费/工具环境、全生态安装矩阵和有证据的影响调度仍待 CI-01;CI-04 负责
三个 Node 的 Windows 安装证据及新发现见 [消费者记录](changes/2026-09-13-CI-01-node-consumers.md)。
CORE-25 的无 navigator 默认选项缺陷尚未修复,严格 test:package:release 会因此失败。
更早 Node 消费/最低工具环境、全生态安装矩阵和有证据的影响调度仍待 CI-01;CI-04 负责
各系统远端运行、冷热缓存、失败/取消演练及 required check 设置。没有新增远端通过证据。
## Pages 隔离与启用条件
+6
View File
@@ -52,6 +52,12 @@ ENG-PERF-01/02 的后续核心性能工作归 MOD-03,并在 REVIEW-01 重新
## 仍需全项目完成的范围
CI-01 后续 Node 20 安装消费发现 CORE-25:静态 option 在没有 navigator 时抛出
ReferenceError,发布 5.4.0 和当前候选均复现。较新 Node 的全局 navigator 掩盖了它。
已新增独立修复任务与 REVIEW-01 前置,并使严格 package release 检查阻断。
本核心阶段的历史完成记录不代表这个后续发现已修复,见
[Node 消费者记录](changes/2026-09-13-CI-01-node-consumers.md)。
- 各 PKG-*-01/05/06:完整发布基线、支持范围旧核心/新插件、新核心/旧插件、SDK/组合/分发;
chapter 的本轮四组合不能代替所有包,也不能代替它自己的最终进度/质量/全屏组合任务。
- EX-01/02/03 与 SITE:React/Vue、全部 demo/在线编辑器及远端资源;核心 Monaco 场景不是全站验收。
+7 -5
View File
@@ -2,9 +2,9 @@
> 由 tasks.json 生成。请修改数据后运行 `node refactor/scripts/plan.mjs --write`,不要手改本表。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 223 项,范围 22 个包及工作区/示例。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 224 项,范围 22 个包及工作区/示例。
状态:todo 86 / doing 16 / blocked 0 / done 121 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 87 / doing 16 / blocked 0 / done 121 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -14,7 +14,7 @@
| 包 | 基线版本 | 任务 |
| --- | --- | --- |
| artplayer | 5.4.1 | CORE-01, CORE-02, CORE-03, CORE-04, CORE-05, CORE-06, CORE-07, CORE-08, CORE-09, CORE-10, CORE-11, CORE-12, CORE-13, CORE-14, CORE-15, CORE-16, CORE-17, CORE-18, CORE-19, CORE-20, CORE-21, CORE-23, CORE-22, CORE-24 |
| artplayer | 5.4.1 | CORE-01, CORE-02, CORE-03, CORE-04, CORE-05, CORE-06, CORE-07, CORE-08, CORE-09, CORE-10, CORE-11, CORE-12, CORE-13, CORE-14, CORE-15, CORE-16, CORE-17, CORE-18, CORE-19, CORE-20, CORE-21, CORE-23, CORE-22, CORE-24, CORE-25 |
| artplayer-plugin-ads | 2.1.0 | PKG-ADS-01, PKG-ADS-02, PKG-ADS-03, PKG-ADS-04, PKG-ADS-05, PKG-ADS-06 |
| artplayer-plugin-ambilight | 1.1.0 | PKG-AMBILIGHT-01, PKG-AMBILIGHT-02, PKG-AMBILIGHT-03, PKG-AMBILIGHT-04, PKG-AMBILIGHT-PROXY-01, PKG-AMBILIGHT-05, PKG-AMBILIGHT-06, PKG-FACTORY-01 |
| artplayer-plugin-asr | 2.1.0 | PKG-ASR-01, PKG-ASR-02, PKG-ASR-03, PKG-ASR-04, PKG-ASR-05, PKG-ASR-06 |
@@ -132,6 +132,7 @@
| CORE-23 | artplayer<br>检查并补齐键盘、焦点与可访问名称 | CORE-13, CORE-14, CORE-17, ENG-05, BASE-04 | 主要控件/设置/模式退出的键盘与焦点回归、名称和字幕可用性检查及必要兼容修正 | 保持旧快捷键和 DOM/CSS 钩子;真实浏览器验证,不以静态属性检查代替交互;处理 BASE-DOM-01 的主要控件 Tab 不可达,保留既有名称与快捷键 | H | done |
| CORE-22 | artplayer<br>核心阶段完整验收 | CORE-21, CORE-23, PILOT-01, ENG-08, ENG-10, ENG-11 | 核心与旧插件的可自动化完整回归、资源/性能及明确外部验证缺口 | 核心自动化和公开差异处置通过;真实环境缺口链接包集成/REL 门槛,阶段完成不代表可公开发布 | H | done |
| CORE-24 | artplayer<br>修复连续切源的播放意图继承 | CORE-22, PKG-AUDIO-04 | 连续切源保留原播放意图,同时尊重显式暂停与最新来源,回归旧/新 audio | 真实暂停状态的受控测试、重入/取消/失败/销毁、三引擎和 main/legacy 产物验证通过;不恢复过期来源的公开副作用 | H | done |
| CORE-25 | artplayer<br>修复无 navigator 环境读取默认选项 | CORE-22 | 安全读取默认语言并保留浏览器已有默认值;实际 Node 与发布产物正反例 | 记录旧发布版 ReferenceError;候选在无 navigator 时可读默认选项,浏览器语言和公开类型不回归;不以补全局对象隐藏错误 | M | todo |
## 5 包迁移:artplayer-plugin-chapter
@@ -405,7 +406,7 @@
| ID | 范围 / 步骤 | 前置依赖 | 交付物 | 验收条件 | 风险 | 状态 |
| --- | --- | --- | --- | --- | --- | --- |
| REVIEW-01 | workspace<br>第一轮全项目架构与兼容性复盘 | REL-02, CORE-22, SITE-04, DOC-08, MOD-01, MOD-02, MOD-03 | 22 包结构、类型、旧 API/路径、测试盲区和维护文档的逐包报告 | 本轮阻断项由独立修复任务关闭并复测;环境缺口转交下一轮,不宣称已发布就绪 | H | todo |
| REVIEW-01 | workspace<br>第一轮全项目架构与兼容性复盘 | REL-02, CORE-22, SITE-04, DOC-08, MOD-01, MOD-02, MOD-03, CORE-25 | 22 包结构、类型、旧 API/路径、测试盲区和维护文档的逐包报告 | 本轮阻断项由独立修复任务关闭并复测;环境缺口转交下一轮,不宣称已发布就绪 | H | todo |
| REVIEW-02 | workspace<br>第二轮真实浏览器与生态集成复盘 | REVIEW-01, REL-03 | Chrome 交互、自动浏览器、新旧组合、真机/SDK/性能/资源的全范围报告 | 所需环境证据齐全,前轮修复再次核对;本轮阻断项关闭,无关 mock 不替代真实验收 | H | todo |
| REVIEW-03 | workspace<br>第三轮 npm 候选内容与发布准备复盘 | REVIEW-02, REL-04, CI-04 | 实际候选 integrity、干净安装构建/消费者、入口/许可/版本/tag/回退及前轮证据汇总 | 最终候选完整检查通过,发布阻断项为零;准备可审阅的批次报告,不自动执行 publish;逐包核对 major 目标,不能用大版本豁免旧 API 兼容 | H | todo |
@@ -454,7 +455,7 @@
- ENG-09: [记录](changes/2026-09-12-ENG-09-integration.md) [记录](baselines/engineering-integration.json)
- ENG-10: [记录](changes/2026-09-10-ENG-10-test-reliability.md) [记录](test-reliability.md)
- ENG-11: [记录](build-analysis.md) [记录](baselines/bundle-attribution.json) [记录](changes/2026-09-11-ENG-11-build-analysis.md)
- CI-01: [记录](ci-setup.md) [记录](changes/2026-09-13-CI-01-matrix-summary.md) [记录](baselines/ci-matrix-validation.json)
- CI-01: [记录](ci-setup.md) [记录](changes/2026-09-13-CI-01-matrix-summary.md) [记录](baselines/ci-matrix-validation.json) [记录](changes/2026-09-13-CI-01-node-consumers.md) [记录](baselines/node-consumer-validation.json)
- PILOT-01: [记录](changes/2026-09-10-PILOT-01-chapter.md) [记录](baselines/pilot-validation.json)
- CORE-01: [记录](changes/2026-09-10-CORE-01-typed-utils.md) [记录](baselines/core-utils-validation.json)
- CORE-02: [记录](changes/2026-09-11-CORE-02-typed-emitter.md) [记录](baselines/emitter-validation.json)
@@ -555,3 +556,4 @@
- PKG-TOOL-THUMB-03: [记录](changes/2026-09-13-PKG-TOOL-THUMB-03-input-checkpoint.md) [记录](baselines/thumbnail-input-checkpoint.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-03-lifecycle.md) [记录](baselines/thumbnail-lifecycle-validation.json)
- PKG-TOOL-THUMB-04: [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-runtime-types.md) [记录](baselines/thumbnail-runtime-types-validation.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-public-types.md) [记录](baselines/thumbnail-public-types-validation.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-emitter.md) [记录](baselines/thumbnail-emitter-validation.json)
- PKG-FACTORY-01: [记录](baselines/factory-assignment-gaps.json) [记录](baselines/factory-compatibility-proposals.json) [记录](factory-compatibility-decision.md) [记录](changes/2026-09-12-PKG-FACTORY-01-decision.md)
- CORE-25: [记录](changes/2026-09-13-CI-01-node-consumers.md)
+15
View File
@@ -1,5 +1,20 @@
# 进度与证据
## CI-01 Node 消费者矩阵检查点(doing)
标准 Node 24.21.0 构建同一 core/chapter tarball,20.19.0/22.12.0/24.21.0 实际
offline/frozen 安装逐成员验证,每个运行 36 项候选与 31 项发布观察;五个旧类型和
八个精确类型模式通过。三个系统 workflow 已接入精确运行时切换,浏览器前恢复标准 Node。
首次 Node 20 发现无 navigator 读取静态 option 抛错,旧与候选均复现。新增 CORE-25
与 CORE-DEFAULTS-SSR-01,并加入 REVIEW-01 前置;严格 package:release 已验证因此失败。
兼容检查成功包括明确的未修复缺陷观察,不能作为发布成功;下一步优先独立修复 CORE-25。
完整本地 CI 2429 项通过(2031 单元、27 工程、371 基线),定向 44 项、元数据 9 项,
actionlint/定向 lint 通过。无生产源码/公开类型/依赖/版本改动,无新浏览器或远端运行。
见[变更](changes/2026-09-13-CI-01-node-consumers.md)和[证据](baselines/node-consumer-validation.json)。
224 项:121 done、16 doing、87 todo;201 风险。CI-01 的更早 Node/最低工具环境、
全生态安装/影响调度及 CI-04 远端仍待验收。独立本地检查点,不推送、不发布。
## CI-01 系统矩阵、缓存与结果汇总检查点(doing)
checks 扩为 Linux/Windows,浏览器扩为 Linux/Windows/macOS;coverage 保留双系统。
+1
View File
@@ -204,3 +204,4 @@
| MULTI-SUB-ENTITY-01 | open / 已复现 | Vendored cue entity decoding retains semicolons after lt, gt and amp entities | PKG-MULTI-SUB-05 |
| JASSUB-TYPE-01 | open / 已复现 | JASSUB declared required URLs, Promise methods and resize parameter order differ from actual historical behavior | PKG-JASSUB-04 |
| JASSUB-EXPORT-01 | open / 已复现 | JASSUB historical CommonJS object.default changes to a direct factory in 1.1.0 | PKG-JASSUB-04, PKG-JASSUB-06 |
| CORE-DEFAULTS-SSR-01 | open / 已复现 | Reading static defaults throws when navigator is absent | CORE-25 |
+18
View File
@@ -4496,6 +4496,24 @@
],
"compatibleResolution": "Preserve actual historical JS default/direct forms and validate their declared module views independently.",
"closureCriteria": "Installed CJS/ESM/global/legacy consumers and public types preserve the supported historical forms."
},
{
"id": "CORE-DEFAULTS-SSR-01",
"title": "Reading static defaults throws when navigator is absent",
"confirmation": "reproduced",
"status": "open",
"owners": [
"CORE-25"
],
"evidence": [
"test/package/runtime.cjs",
"packages/artplayer/src/option/defaults.ts",
"refactor/changes/2026-09-13-CI-01-node-consumers.md",
"refactor/baselines/node-consumer-validation.json"
],
"compatibleResolution": "Read navigator through a guarded global lookup while preserving browser language defaults and public declaration shape.",
"closureCriteria": "Published failure remains explicit; source and actual installed candidate defaults work without navigator on selected Node versions and browser language behavior stays unchanged.",
"workspaceState": "Node 20.19.0 actual installed probe fails with ReferenceError: navigator is not defined. Published 5.4.0 and candidate 5.4.1 both reproduce under explicitly absent navigator on every selected runtime. CI-01 records this known failure, then compares default values under the same controlled en-US navigator; this is not a production fix."
}
]
}
+16
View File
@@ -68,6 +68,22 @@ export function validateCIWorkflow(source) {
}
const browser = workflow.jobs['browser-smoke']
assert(browser.steps.some(step => step.run?.startsWith('yarn test:browser:install --with-deps') && !Object.hasOwn(step, 'if')), 'Browser dependencies must install even on cache hits')
let consumerIndex = browser.steps.findIndex(step => step.run?.startsWith('yarn test:package'))
for (const [id, version, command] of [
['consumer-node-20', '20.19.0', 'node scripts/package-runtime.mjs --expected-node 20.19.0 2>&1 | tee refactor/.cache/ci/consumer-node-20.log'],
['consumer-node-22', '22.12.0', 'node scripts/package-runtime.mjs --expected-node 22.12.0 2>&1 | tee refactor/.cache/ci/consumer-node-22.log'],
['restore-canonical-node', null, 'node scripts/package-runtime.mjs --canonical 2>&1 | tee refactor/.cache/ci/consumer-node-canonical.log'],
]) {
const index = browser.steps.findIndex(step => step.id === id)
assert(index > consumerIndex, 'Build once before each ordered consumer runtime switch')
const step = browser.steps[index]
assert(step.uses?.startsWith('actions/setup-node@') && !Object.hasOwn(step, 'if'), 'Consumer Node setup cannot be skipped')
assert.deepEqual(step.with, version ? { 'node-version': version, 'package-manager-cache': false } : { 'node-version-file': '.node-version', 'package-manager-cache': false }, 'Use exact consumer versions and restore the canonical browser runtime')
const probe = browser.steps[index + 1]
assert(probe?.run === command && !Object.hasOwn(probe, 'if'), 'Run the installed consumer on the selected Node')
consumerIndex = index + 1
}
assert(browser.steps.findIndex(step => step.run?.startsWith('yarn test:browser ')) > consumerIndex, 'Browser tools must run after canonical Node restoration')
const pages = workflow.jobs.checks.steps.find(step => step.uses?.startsWith('actions/upload-pages-artifact@'))
assert.equal(pages?.if, 'inputs.pages-artifact && github.ref == \'refs/heads/master\' && matrix.os == \'ubuntu-latest\'', 'Only one trusted matrix leg can prepare Pages')
return { jobs: requiredJobs, systems, summary: summary.name }
+3
View File
@@ -31,6 +31,9 @@ for (const [name, mutate] of [
['conditional frozen install', w => w.jobs.checks.steps.find(s => s.run?.includes('yarn install --frozen-lockfile')).if = 'false'],
['commented frozen install', w => w.jobs.checks.steps.find(s => s.run?.includes('yarn install --frozen-lockfile')).run = '# yarn install --frozen-lockfile --non-interactive'],
['conditional Node setup', w => w.jobs.checks.steps.find(s => s.uses?.startsWith('actions/setup-node@')).if = 'false'],
['wrong consumer Node version', w => w.jobs['browser-smoke'].steps.find(s => s.id === 'consumer-node-20').with['node-version'] = '24'],
['skipped installed consumer', w => w.jobs['browser-smoke'].steps.find(s => s.run?.includes('--expected-node 22.12.0')).if = 'false'],
['browser runtime not restored', w => w.jobs['browser-smoke'].steps.find(s => s.id === 'restore-canonical-node').with = { 'node-version': '22.12.0', 'package-manager-cache': false }],
['Pages uploaded by both matrix legs', w => w.jobs.checks.steps.find(s => s.uses?.startsWith('actions/upload-pages-artifact@')).if = 'inputs.pages-artifact && github.ref == \'refs/heads/master\''],
]) {
test(`CI rejects ${name}`, () => {
+23 -2
View File
@@ -756,7 +756,9 @@
"evidence": [
"ci-setup.md",
"changes/2026-09-13-CI-01-matrix-summary.md",
"baselines/ci-matrix-validation.json"
"baselines/ci-matrix-validation.json",
"changes/2026-09-13-CI-01-node-consumers.md",
"baselines/node-consumer-validation.json"
]
},
{
@@ -4362,7 +4364,8 @@
"DOC-08",
"MOD-01",
"MOD-02",
"MOD-03"
"MOD-03",
"CORE-25"
],
"status": "todo",
"risk": "H",
@@ -4478,6 +4481,24 @@
"factory-compatibility-decision.md",
"changes/2026-09-12-PKG-FACTORY-01-decision.md"
]
},
{
"id": "CORE-25",
"phase": "3-4 核心迁移",
"title": "修复无 navigator 环境读取默认选项",
"scope": [
"artplayer"
],
"dependsOn": [
"CORE-22"
],
"status": "todo",
"risk": "M",
"deliverable": "安全读取默认语言并保留浏览器已有默认值;实际 Node 与发布产物正反例",
"acceptance": "记录旧发布版 ReferenceError;候选在无 navigator 时可读默认选项,浏览器语言和公开类型不回归;不以补全局对象隐藏错误",
"evidence": [
"changes/2026-09-13-CI-01-node-consumers.md"
]
}
]
}
+5 -1
View File
@@ -9,7 +9,11 @@
3. 执行 `yarn check:toolchain --strict`,核对实际 Node/Yarn、20 个固定开发工具和 22 个 workspace 的声明及传递依赖锁条目。普通检查允许满足最低工具要求的 Node,同时打印标准版本。
4. 执行 `yarn test:playback`、`yarn test:dash-control`、`yarn build all` 和 `yarn workspace artplayer-vitepress build`。ENG-02 已拆分只读 lint 与 lint:fix;PR/主线入口和独立 Pages 流程见 ci-setup.md。
私有根包最低 Node 为 ^20.19.0 || >=22.12.0,与原本使用的 Vite 7 一致。本轮验证 Node 24.21.0,其他版本矩阵由 CI-01 接续,不能宣称所有最低环境已经通过。
私有根包最低 Node 为 ^20.19.0 || >=22.12.0,与原本使用的 Vite 7 一致。标准工具链验证
使用 Node 24.21.0;CI-01 已在 Windows 的 20.19.0/22.12.0/24.21.0 上重装消费相同
core/chapter tarball,见 [Node 记录](changes/2026-09-13-CI-01-node-consumers.md)。
这不是在最低 Node 上完成仓库工具链的干净安装/构建测试,也不是发布包的最低 Node 声明。
CORE-25 默认选项缺陷仍在严格发布检查中阻断;完整工具与消费范围由 CI-01 继续验证。
## 锁文件和依赖维护