test(release): [REL-04] checkpoint renamed rollback and mainline conflict recovery

This commit is contained in:
Harvey Zhao committed 2026-09-15 00:28:33 +08:00
1 parent aa29dc9212
commit d0c33f6258
14 files changed
+1718 -8

No files matched your search

+1
View File
@@ -30,6 +30,7 @@
| [多轮复盘与 npm 准入](release-reviews.md) | Chrome 验证分工、三轮全局复盘、问题闭环和候选发布门槛 |
| [逐包发布准入台账](release-ledger.md) | 22包候选/证据绑定、源码和产物指纹、任务风险/许可阻断及严格预检 |
| [回退演练与维护](rollback-rehearsal.md) | 独立核心/插件回退、冻结安装文件检查、真实播放及剩余发布门槛 |
| [逐包恢复清单](rollback-inventory.md) | 全包精确旧版本、依赖及完整回退产物的缺口 |
| [工具链与发布](toolchain-release.md) | TypeScript、Bun、构建、版本管理和发布回退 |
| [已实现的开发环境](toolchain-setup.md) | Node/Yarn 固定版本、锁文件、安装命令和实际验证范围 |
| [全包大版本策略](version-policy.md) | 每包分别升级一个 major 的目标清单、兼容要求和版本落地步骤 |
+647
View File
@@ -0,0 +1,647 @@
{
"task": "REL-04",
"source": "refactor/release-ledger.json and frozen historical archives",
"registryAvailabilityRefreshed": false,
"mutableTagPolicy": "Use exact versions and saved lock/artifact hashes. No latest/next/rollback tag is assumed or changed.",
"packages": [
{
"name": "artplayer",
"targetVersion": "6.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/releases.json",
"selector": "releases.0",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {
"option-validator": "^2.0.6"
},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer",
"version": "5.4.0",
"tarball": "https://registry.npmjs.org/artplayer/-/artplayer-5.4.0.tgz",
"integrity": "sha512-2B+plbx8N2yNsjK4nJU3+EOG8TULm1LRZk/QPkWRAMEX2Ee/MSnZG/WJYz8kcoZxZuLKcQ3uXifqLuPxZOH29A==",
"sha256": "42b269a66b9658d53f9a92572bb36d656ea9af56254a387b3a69c7ddea43979e",
"memberCount": 41,
"dependencies": {
"option-validator": "^2.0.6"
},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer": "5.4.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-plugin-ads",
"targetVersion": "3.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/ads-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-ads",
"version": "1.0.6",
"tarball": "https://registry.npmjs.org/artplayer-plugin-ads/-/artplayer-plugin-ads-1.0.6.tgz",
"integrity": "sha512-KMGGf7lhgj6DQXHPOg28jWYkVmDfOZJ4Gr4iF28Wy2GXNPh2ZJtlsFQ2IuWqXCElRPvSLzYK5HugF0OUnVszaw==",
"sha256": "ff132ff8a7108d8b26421621e4aac1d7edf8c99099a5ab4fd2190bd79b8636cd",
"memberCount": 6,
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-ads": "1.0.6"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-plugin-ambilight",
"targetVersion": "2.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/ambilight-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-ambilight",
"version": "1.1.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-ambilight/-/artplayer-plugin-ambilight-1.1.0.tgz",
"integrity": "sha512-FkMI7bn9HovJMfEdgkKbo7/vPt6vrzcpELTaC/vM7B99FPSMWzAf6GAE0xnNxU3KibYcBV5gXnBgvHgpG2xq2A==",
"sha256": "e95bd60fd7bce52142cf0041bad811452305029cbe1129c7d89246eb260c5c86",
"memberCount": 6,
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-ambilight": "1.1.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-plugin-asr",
"targetVersion": "3.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/asr-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-asr",
"version": "2.1.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-asr/-/artplayer-plugin-asr-2.1.0.tgz",
"integrity": "sha512-15gXff458PAx9LeJxKzZEvmpFhfwKUfSLgb1Mfr7Xb/ZGsnE+6EA7ezTnO5S55W5mFExjv/e95iOIXP4ijuruQ==",
"sha256": "8bc3cd93f78ce99e5c09cc546c770a63e8aea5729d3d584134ce04d826b7708b",
"memberCount": 6,
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-asr": "2.1.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-plugin-audio-track",
"targetVersion": "2.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/audio-track-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-audio-track",
"version": "1.1.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-audio-track/-/artplayer-plugin-audio-track-1.1.0.tgz",
"integrity": "sha512-pvvHvTSqC2+sBelwYyjAv2CVmaQgG9KpX+i96t/e8oyZRX/JuepC9iSVIp7GzB3AtliFzhVamksT+8lXvD3RCg==",
"sha256": "7e84f6a2f4bfada428a77ef04b749bf3db53e0149fa1afe7bf5749d925e801ff",
"memberCount": 6,
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-audio-track": "1.1.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-plugin-auto-thumbnail",
"targetVersion": "2.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/auto-thumbnail-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-auto-thumbnail",
"version": "1.1.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-auto-thumbnail/-/artplayer-plugin-auto-thumbnail-1.1.0.tgz",
"integrity": "sha512-ALrcLv+qEDime+R8p4628RZTfMGlrpX6d7PLIQaYWsQEN3lPzVjcVcARCFpqnFI8gvRdqt21w72sJphf50xtVw==",
"sha256": "5ea83d4e45d42fdaf42d3e37b6c666857872adaa276ab329c74edcdaa3c1a978",
"memberCount": 6,
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-auto-thumbnail": "1.1.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-plugin-chapter",
"targetVersion": "2.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/releases.json",
"selector": "releases.1",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-chapter",
"version": "1.1.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-chapter/-/artplayer-plugin-chapter-1.1.0.tgz",
"integrity": "sha512-ji66Lr2K2S+OjFMuMby3yq+pefWlOC51Sbpop/DIr2N6w3F0smrF+YZbshN1Dy8/Tx1TYpT7N6WkkZWy5Jix1w==",
"sha256": "4c3173661854ff96f643a479c0f1c2db7ce9e54681523bd059a7dd9bd77eeada",
"memberCount": 6,
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-chapter": "1.1.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-plugin-chromecast",
"targetVersion": "2.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/chromecast-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-chromecast",
"version": "1.1.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-chromecast/-/artplayer-plugin-chromecast-1.1.0.tgz",
"integrity": "sha512-3xrHj1CHe0Tt8gNMUB9A1epuW4OrbPsa1T9MNFy4AfQsjhYAhWAmef6hYu1GdHdADDybXBtVHP50gQ+EW+ddcw==",
"sha256": "1941d41055ee02deaa343cbf9eaf714495cb9f04883f57966f5b27f128117c30",
"memberCount": 6,
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-chromecast": "1.1.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-plugin-danmuku",
"targetVersion": "6.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/danmuku-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-danmuku",
"version": "5.3.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-danmuku/-/artplayer-plugin-danmuku-5.3.0.tgz",
"integrity": "sha512-a76bU1cWEZr53hD1X8IHfOzS4QawGHn8dQ3fIYyJ5TsyhTSnznhi2WzkS8M7LL3H02ekXRZTUFan9+9EERk12g==",
"sha256": "1abb76460790d85a26590b8b911eb1301fd720885f96c73432060416a38dcb0e",
"memberCount": 6,
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-danmuku": "5.3.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-plugin-danmuku-mask",
"targetVersion": "2.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/danmuku-mask-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {
"@mediapipe/selfie_segmentation": "^0.1.1675465747",
"@tensorflow-models/body-segmentation": "^1.0.2",
"@tensorflow/tfjs-backend-cpu": "^4.21.0",
"@tensorflow/tfjs-backend-webgl": "^4.21.0",
"@tensorflow/tfjs-converter": "^4.21.0",
"@tensorflow/tfjs-core": "^4.21.0"
},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-danmuku-mask",
"version": "1.1.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-danmuku-mask/-/artplayer-plugin-danmuku-mask-1.1.0.tgz",
"integrity": "sha512-VBmmwtNLj0TKYz9lWbyQ7A8osQHdyDiPMazP9g1UZbLyw/rMJ3qRclMgszRpZHN9hod0dQl2iYSJDoaqu3hGOQ==",
"sha256": "96682e46cb140a84b164818dd118480d7be42b24afaab390027a25e52e8ae31c",
"memberCount": 6,
"dependencies": {
"@mediapipe/selfie_segmentation": "^0.1.1675465747",
"@tensorflow-models/body-segmentation": "^1.0.2",
"@tensorflow/tfjs-backend-cpu": "^4.21.0",
"@tensorflow/tfjs-backend-webgl": "^4.21.0",
"@tensorflow/tfjs-converter": "^4.21.0",
"@tensorflow/tfjs-core": "^4.21.0"
},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-danmuku-mask": "1.1.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-plugin-dash-control",
"targetVersion": "2.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/dash-control-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-dash-control",
"version": "1.1.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-dash-control/-/artplayer-plugin-dash-control-1.1.0.tgz",
"integrity": "sha512-EssRkzYXWcln3a6nAzi4ESacBhzMih8s0bzdjXuvBBCh2UFmvK99ITD5E+0cuU8i5ZzIQGQSdce1/gANTrX0BQ==",
"sha256": "f4047a569d99b6a7de57b3719b7ad40109f2a1d360566a840f50ab32aacefcd9",
"memberCount": 6,
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-dash-control": "1.1.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-plugin-document-pip",
"targetVersion": "2.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/dpip-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-document-pip",
"version": "1.1.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-document-pip/-/artplayer-plugin-document-pip-1.1.0.tgz",
"integrity": "sha512-+HCrlO+bQwBrig1bI/IIxgGvbcG7i+aNHAnR5vLqB+RdyIY+FKCHyEe0o9yZREnbYOe0XJVqjv2buEVrouzdoQ==",
"sha256": "b864befea9aff84b3352782a9670ebe72ff073606fec7cdc31d31e92a5ad6d8a",
"memberCount": 6,
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-document-pip": "1.1.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-plugin-hls-control",
"targetVersion": "2.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/hls-control-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-hls-control",
"version": "1.1.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-hls-control/-/artplayer-plugin-hls-control-1.1.0.tgz",
"integrity": "sha512-lWN5oUOWDorWFHdzKcmy9Z8eHcf5f5EcUGDrxBsZBX7aEL5dGRlHPQ5+wqQEizr38D9PYPfTI/nCyun2yFopEw==",
"sha256": "598c354d78d3cb77965136fa61dfc0f94cdea6906a91a30781c1acef2b0c3e8b",
"memberCount": 6,
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-hls-control": "1.1.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-plugin-jassub",
"targetVersion": "2.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/jassub-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-jassub",
"version": "1.1.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-jassub/-/artplayer-plugin-jassub-1.1.0.tgz",
"integrity": "sha512-vQwEtZMmkwr5utbxfUAeE/gRccl2nfcz+SYP2Subn/L8cVIFdMXWMgicm7ZkPVtAoBbCav7p0yP4pwXkCKMzAg==",
"sha256": "00713b4eee4b90e7dc13d1f2c88bc785f9b62f3903b00be6f7bec738fbb78c57",
"memberCount": 6,
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-jassub": "1.1.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-plugin-multiple-subtitles",
"targetVersion": "2.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/multiple-subtitles-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-multiple-subtitles",
"version": "1.2.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-multiple-subtitles/-/artplayer-plugin-multiple-subtitles-1.2.0.tgz",
"integrity": "sha512-3mzoHkgKx3KVdxKQBwLkjetPF6WjJtro5uQNdse8FqUeiV0afbywLnP6H8lcDN/Fwgp2VlBknrs2+COiyFdV8g==",
"sha256": "a013fbe0772bf560d177449fc80e848c41f16ae2f72ace86f8fb0d5b1000a54e",
"memberCount": 6,
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-multiple-subtitles": "1.2.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-plugin-vast",
"targetVersion": "2.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/vast-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {
"@alugha/ima": "2.1.0",
"@glomex/vast-ima-player": "^1.21.2"
},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-vast",
"version": "1.0.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-vast/-/artplayer-plugin-vast-1.0.0.tgz",
"integrity": "sha512-6ia0BYlZMBUAbvfqPq6RD3kvCP/Vpnqjs4zgzcio0CUh3a/iJkp+caKFOFjROfilbL+B0lXUiA7U1kS9KqEwTg==",
"sha256": "35681d60fa3fa09b92f0f30887e39c73cf55e7b14d51a1c38fccbc6c1f253bab",
"memberCount": 6,
"dependencies": {
"@glomex/vast-ima-player": "^1.21.0"
},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-vast": "1.0.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-plugin-vtt-thumbnail",
"targetVersion": "2.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/vtt-thumbnail-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-vtt-thumbnail",
"version": "1.1.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-vtt-thumbnail/-/artplayer-plugin-vtt-thumbnail-1.1.0.tgz",
"integrity": "sha512-p5HIiaxBEN0CV4FWOWXCfy6hcQL59JuFIGUbQtVg9AcunPg2gJ1cJ8P0HEQ/ngH6tl1/puxrJIKydoAdX5L2dw==",
"sha256": "e2df36283538bbffc2c37fe28a8af0fe6fc0fa68a5f6cf93042929ee64d55765",
"memberCount": 6,
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-vtt-thumbnail": "1.1.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-proxy-canvas",
"targetVersion": "2.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/canvas-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-proxy-canvas",
"version": "1.1.0",
"tarball": "https://registry.npmjs.org/artplayer-proxy-canvas/-/artplayer-proxy-canvas-1.1.0.tgz",
"integrity": "sha512-lOq22z+xX2DcpokDSMQrDTk4VGDwUaQm9SovQ0GlhgmvMBdxRBDlvv6QrVxFUFsiGUjXEdx9TmtzdiW38dlxiQ==",
"sha256": "348c1d6671f79d0e0dbf2bb15875a1e6d60d00b73cde833c018bec7e4be96c8e",
"memberCount": 6,
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-proxy-canvas": "1.1.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-proxy-mediabunny",
"targetVersion": "2.0.0",
"distribution": "npm",
"history": {
"file": "refactor/baselines/mb-release.json",
"selector": "release",
"rationale": "Frozen npm tarball provenance; not a new registry availability observation."
},
"currentDependencies": {
"mediabunny": "^1.43.1"
},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-proxy-mediabunny",
"version": "1.2.0",
"tarball": "https://registry.npmjs.org/artplayer-proxy-mediabunny/-/artplayer-proxy-mediabunny-1.2.0.tgz",
"integrity": "sha512-uSKkJFvd5Y2XxPPhwtPM5k9qq3xScbWnO/9fOfC8S+Liz8f8nT/iyA2eynU3maVcHZbJgA3PHZm0r6RRmSkefg==",
"sha256": "acb016166059183917a6de2e03a65ad77b09997fc9fb62513d751a24467ca76c",
"memberCount": 6,
"dependencies": {
"mediabunny": "^1.43.1"
},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-proxy-mediabunny": "1.2.0"
},
"restore": "Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-tool-iframe",
"targetVersion": "2.0.0",
"distribution": "renamed-npm",
"history": {
"file": "refactor/baselines/iframe-release.json",
"selector": "release",
"publishedName": "artplayer-plugin-iframe",
"rationale": "Frozen published predecessor and documented rename commit; candidate keeps current workspace name. Registry target availability still requires REL-01."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"previous": {
"name": "artplayer-plugin-iframe",
"version": "1.0.0",
"tarball": "https://registry.npmjs.org/artplayer-plugin-iframe/-/artplayer-plugin-iframe-1.0.0.tgz",
"integrity": "sha512-9eh5NVjZ8/Vxl0ojZxnMY6IlYxCVVfyGH2Rzl7uYDJnGc8NQ4y9vMN/gVh1h8R2m5qaYm7/XDo/45O9a7hDiKg==",
"sha256": "16dc92aa84d93bd99bc0a34815dc49f1609fafc1ff255eb353ea893e70b5f91f",
"memberCount": 8,
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {}
},
"exactDependency": {
"artplayer-plugin-iframe": "1.0.0"
},
"restore": "Restore application import code, old package name and saved lock together; npm alias alone does not restore the old export/helper surface.",
"status": "archive-verified-batch-rehearsal-required"
},
{
"name": "artplayer-tool-thumbnail",
"targetVersion": "5.0.0",
"distribution": "recovered-npm",
"history": {
"file": "refactor/baselines/thumbnail-release.json",
"selector": "recovered",
"rationale": "Recovered CDN/Git bytes only; original registry tarball and complete archive unavailable. Not an intact rollback artifact."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"restore": "No intact historical npm tarball. Preserve a complete pre-upgrade application/artifact snapshot and verify it before any candidate deployment.",
"status": "complete-rollback-artifact-required",
"evidence": "refactor/baselines/thumbnail-release.json"
},
{
"name": "artplayer-vitepress",
"targetVersion": "2.0.0",
"distribution": "site",
"history": {
"file": "refactor/baselines/site-provenance.json",
"rationale": "Existing docs/site build and URL distribution. No npm publication is inferred."
},
"currentDependencies": {},
"currentPeers": {},
"currentOptionalDependencies": {},
"restore": "Previously verified Pages artifact, exact source SHA and URL map; npm rollback does not apply.",
"status": "previous-deployment-artifact-required",
"evidence": "refactor/pages-deployment.md"
}
]
}
@@ -0,0 +1,642 @@
{
"task": "REL-04",
"status": "checkpoint",
"capturedAt": "2026-09-14T16:27:46.622Z",
"source": "aa29dc9212cca5ec61d90ee8145e2b2c173cf23b",
"toolchain": {
"node": "24.21.0",
"yarn": "1.22.22"
},
"iframe": {
"command": "yarn test:rollback:iframe",
"report": "refactor/.cache/iframe-rollback/run-6AFtyo/report.json",
"sha256": "c93fe7a9ffea5653ad3b5769ee70e69082da37bbd883fd0f1641ab848d494811",
"task": "REL-04",
"capturedAt": "2026-09-14T16:26:50.781Z",
"source": "aa29dc9212cca5ec61d90ee8145e2b2c173cf23b",
"node": "24.21.0",
"yarn": "1.22.22",
"passed": true,
"scope": "Old package name and application imports restored together; independent renamed-package installation rehearsal",
"profiles": {
"old": {
"name": "artplayer-plugin-iframe",
"version": "1.0.0",
"archive": "refactor/.cache/releases/artplayer-plugin-iframe-1.0.0.tgz",
"sha256": "16dc92aa84d93bd99bc0a34815dc49f1609fafc1ff255eb353ea893e70b5f91f",
"lockSha256": "a2d4f7ebecc41729792b66392971384eb497cf27c261d87c3f6cfe7c29b03e6a",
"applicationSha256": "9e869c95f4907957ff820828afd1ba6f13457e46aeb790f93c5bb619a725a315",
"files": {
"package/README.md": "52c0a1199b6529d60ce8f4414984f9bd1bc3a8daa5bb6cfec8f0aae0c8338e46",
"package/dist/artplayer-helper-iframe.js": "47730ed608f0637594549b9762c01191686a4a55b3bd467132304a016d227f4a",
"package/dist/artplayer-helper-iframe.legacy.js": "f4c3b11806cad6d984f03a2d9de63deba78cbe538ffe4044a106b0dddc5d4197",
"package/dist/artplayer-plugin-iframe.js": "df469c3e4582b127f35798494d0845f1fc4ca2d19bbaf01b918492e035479745",
"package/dist/artplayer-plugin-iframe.legacy.js": "15299cb5c848cc61614f7573a802443d69b7c6d0a938a1867835c7cbb4884edd",
"package/package.json": "563a6c8407753b92b86319a5e6d9d567525146c32cb010b45b0d88ff481859f6",
"package/src/index.js": "2e0b9efeedef0d6c4f2d2b526db35f634cd02af044e4e28dd1a0b26a5b9a02bf",
"package/types/artplayer-plugin-iframe.d.ts": "d55d99a2488d60892a0ab82882dc96a0f373dab0c3d2a3cee978bc35aa7c2d0c"
}
},
"candidate": {
"name": "artplayer-tool-iframe",
"version": "1.1.0",
"archive": "refactor/.cache/iframe-rollback/run-6AFtyo/candidate.tgz",
"sha256": "0e803ab0c653e82f9e310712d9929a56d4b781d9ccfadc50fe741c28fd2d25f1",
"lockSha256": "657b0a2f29c651b10f6ceb37eb84ac3d27b3ce5de949b74dc59c748b564b2634",
"applicationSha256": "360e8113b39489aef5a4ecafc0ce798db77b75035694653514c82da671d4782e",
"files": {
"package/ARCHITECTURE.md": "dcb0d58fd02730a7a2cc620e4e7e934fae22dbbf85cc9a6eae21ee5ac2cba167",
"package/README.md": "ef5af60bcb831667a78cc3421f6e3c7b5d9a50b3d2e571c5cd02d46fc533e9ce",
"package/dist/artplayer-tool-iframe.js": "7408fceccb000e1b304abe30ac9bc364da7860c3896ad5aaa6af427804c237e6",
"package/dist/artplayer-tool-iframe.legacy.js": "4e8bd39cdc37e98bff9cd19b5e0c9453ebe5231264242fc1c573aa96edb5ea8a",
"package/dist/artplayer-tool-iframe.mjs": "ac4c5efa670c0429fc95bdab7902df60f5b5540f0dad9c7e65c2bd660796dc83",
"package/package.json": "0de9c86eeb3f9a2fb46f9297105b5beddb8d6164163ffaa9874cf5cd68ba7a58",
"package/types/artplayer-tool-iframe.d.cts": "66850135f45c81d4bd7a0de33b6a2f63a655de9000f2698f43660039727919f3",
"package/types/artplayer-tool-iframe.d.mts": "cd394fd68e61fab3c4474daab29852a3f87dd0086b007e7937106871272676fb",
"package/types/artplayer-tool-iframe.d.ts": "e760de22559caf7ffff48d7c5713485bf9f0ddbe876a93080295fb6106535bfa"
}
}
},
"steps": [
{
"action": "install-predecessor",
"profile": "old",
"installed": {
"name": "artplayer-plugin-iframe",
"version": "1.0.0",
"archiveSha256": "16dc92aa84d93bd99bc0a34815dc49f1609fafc1ff255eb353ea893e70b5f91f",
"verifiedMembers": 8
},
"runtime": "old import and helper restored",
"types": {
"compiler": "5.9.3",
"mode": "node10-commonjs",
"diagnostics": []
},
"otherPackageRemoved": true,
"applicationRestored": true
},
{
"action": "upgrade-renamed-package",
"profile": "candidate",
"installed": {
"name": "artplayer-tool-iframe",
"version": "1.1.0",
"archiveSha256": "0e803ab0c653e82f9e310712d9929a56d4b781d9ccfadc50fe741c28fd2d25f1",
"verifiedMembers": 9
},
"runtime": "candidate import and legacy verified",
"types": {
"compiler": "5.9.3",
"mode": "node10-commonjs",
"diagnostics": []
},
"otherPackageRemoved": true,
"applicationRestored": true
},
{
"action": "restore-predecessor",
"profile": "old",
"installed": {
"name": "artplayer-plugin-iframe",
"version": "1.0.0",
"archiveSha256": "16dc92aa84d93bd99bc0a34815dc49f1609fafc1ff255eb353ea893e70b5f91f",
"verifiedMembers": 8
},
"runtime": "old import and helper restored",
"types": {
"compiler": "5.9.3",
"mode": "node10-commonjs",
"diagnostics": []
},
"otherPackageRemoved": true,
"applicationRestored": true
}
],
"aliasNegative": {
"passed": true,
"result": "old tarball under new dependency key does not preserve candidate constructor/legacy",
"scope": "Local file dependency key alias, not npm registry alias resolution"
}
},
"mainline": {
"command": "yarn test:rollback:mainline",
"report": "refactor/.cache/mainline-rehearsal/run-zTEWy5/report.json",
"sha256": "59ee81a3ead7d04a8c8cbb6f097ba4755643ec49a7bf710ab092e13f4f617fcb",
"patch": {
"path": "refactor/.cache/mainline-rehearsal/run-zTEWy5/resolved.patch",
"sha256": "debee370777d5d3175affe6c9406c4e1897c5b11d60590c12dabc41a533bdfc3"
},
"bundle": {
"path": "refactor/.cache/mainline-rehearsal/run-zTEWy5/rehearsal.bundle",
"sha256": "a5fe84987a8efa44b70693b08c91e0d0d955ea53f194291c156153fe080c72f2"
},
"task": "REL-04",
"capturedAt": "2026-09-14T16:24:22.347Z",
"source": "aa29dc9212cca5ec61d90ee8145e2b2c173cf23b",
"node": "24.21.0",
"passed": true,
"scope": "Synthetic isolated JS-to-TS modify/delete conflict; no production fix or remote mutation",
"steps": [
{
"executable": "git",
"args": [
"init",
"--initial-branch=master"
],
"status": 0,
"stdout": "Initialized empty Git repository in C:/Users/laozh/AppData/Local/Temp/artplayer-consumer-Etvdz1/.git/\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"config",
"user.name",
"ArtPlayer isolated rehearsal"
],
"status": 0,
"stdout": "",
"stderr": ""
},
{
"executable": "git",
"args": [
"config",
"user.email",
"rehearsal@example.invalid"
],
"status": 0,
"stdout": "",
"stderr": ""
},
{
"executable": "git",
"args": [
"config",
"commit.gpgsign",
"false"
],
"status": 0,
"stdout": "",
"stderr": ""
},
{
"executable": "git",
"args": [
"config",
"core.autocrlf",
"false"
],
"status": 0,
"stdout": "",
"stderr": ""
},
{
"executable": "git",
"args": [
"add",
"."
],
"status": 0,
"stdout": "",
"stderr": ""
},
{
"executable": "git",
"args": [
"commit",
"-m",
"fixture: original JavaScript implementation"
],
"status": 0,
"stdout": "[master (root-commit) a10e48e] fixture: original JavaScript implementation\n 3 files changed, 9 insertions(+)\n create mode 100644 consumer.mjs\n create mode 100644 package.json\n create mode 100644 src/retry.js\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"rev-parse",
"HEAD"
],
"status": 0,
"stdout": "a10e48e0c1f7a712fd602d5d8afcacef9a5e68b0\n",
"stderr": ""
},
{
"executable": "node",
"args": [
"consumer.mjs"
],
"status": 1,
"stdout": "",
"stderr": "node:internal/modules/run_main:107\r\n triggerUncaughtException(\r\n ^\r\n\r\nAssertionError [ERR_ASSERTION]: Expected values to be strictly equal:\r\n\r\n-2 !== 0\r\n\r\n at file:///C:/Users/laozh/AppData/Local/Temp/artplayer-consumer-Etvdz1/consumer.mjs:4:8\r\n at ModuleJob.run (node:internal/modules/esm/module_job:561:25)\r\n at async node:internal/modules/esm/loader:647:26\r\n at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5) {\r\n generatedMessage: true,\r\n code: 'ERR_ASSERTION',\r\n actual: -2,\r\n expected: 0,\r\n operator: 'strictEqual',\r\n diff: 'simple'\r\n}\r\n\r\nNode.js v24.21.0\r\n"
},
{
"executable": "git",
"args": [
"switch",
"-c",
"codex/rehearsal"
],
"status": 0,
"stdout": "",
"stderr": "Switched to a new branch 'codex/rehearsal'\n"
},
{
"executable": "git",
"args": [
"add",
"."
],
"status": 0,
"stdout": "",
"stderr": ""
},
{
"executable": "git",
"args": [
"commit",
"-m",
"fixture: split retry policy into TypeScript modules"
],
"status": 0,
"stdout": "[codex/rehearsal 61a9230] fixture: split retry policy into TypeScript modules\n 4 files changed, 4 insertions(+), 4 deletions(-)\n create mode 100644 src/normalize.ts\n delete mode 100644 src/retry.js\n create mode 100644 src/retry.ts\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"rev-parse",
"HEAD"
],
"status": 0,
"stdout": "61a92304ff91bfb87f6c1a08765276187b227cf3\n",
"stderr": ""
},
{
"executable": "node",
"args": [
"consumer.mjs"
],
"status": 1,
"stdout": "",
"stderr": "node:internal/modules/run_main:107\r\n triggerUncaughtException(\r\n ^\r\n\r\nAssertionError [ERR_ASSERTION]: Expected values to be strictly equal:\r\n\r\n-2 !== 0\r\n\r\n at file:///C:/Users/laozh/AppData/Local/Temp/artplayer-consumer-Etvdz1/consumer.mjs:4:8\r\n at ModuleJob.run (node:internal/modules/esm/module_job:561:25)\r\n at async node:internal/modules/esm/loader:647:26\r\n at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5) {\r\n generatedMessage: true,\r\n code: 'ERR_ASSERTION',\r\n actual: -2,\r\n expected: 0,\r\n operator: 'strictEqual',\r\n diff: 'simple'\r\n}\r\n\r\nNode.js v24.21.0\r\n"
},
{
"executable": "git",
"args": [
"switch",
"master"
],
"status": 0,
"stdout": "",
"stderr": "Switched to branch 'master'\n"
},
{
"executable": "git",
"args": [
"add",
"src/retry.js"
],
"status": 0,
"stdout": "",
"stderr": ""
},
{
"executable": "git",
"args": [
"commit",
"-m",
"fixture: clamp negative retry limits"
],
"status": 0,
"stdout": "[master fb62f91] fixture: clamp negative retry limits\n 1 file changed, 1 insertion(+), 1 deletion(-)\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"rev-parse",
"HEAD"
],
"status": 0,
"stdout": "fb62f918310b9cd01ca6deddff6acbb1eecd55c9\n",
"stderr": ""
},
{
"executable": "node",
"args": [
"consumer.mjs"
],
"status": 0,
"stdout": "retry limit regression passed\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"switch",
"codex/rehearsal"
],
"status": 0,
"stdout": "",
"stderr": "Switched to branch 'codex/rehearsal'\n"
},
{
"executable": "git",
"args": [
"status",
"--porcelain"
],
"status": 0,
"stdout": "",
"stderr": ""
},
{
"executable": "git",
"args": [
"rev-parse",
"HEAD^{tree}"
],
"status": 0,
"stdout": "9ed1ebc390513ca0f09c3c4fc20700b38fc2e614\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"cherry-pick",
"-x",
"fb62f918310b9cd01ca6deddff6acbb1eecd55c9"
],
"status": 1,
"stdout": "CONFLICT (modify/delete): src/retry.js deleted in HEAD and modified in fb62f91 (fixture: clamp negative retry limits). Version fb62f91 (fixture: clamp negative retry limits) of src/retry.js left in tree.\n",
"stderr": "error: could not apply fb62f91... fixture: clamp negative retry limits\nhint: After resolving the conflicts, mark them with\nhint: \"git add/rm <pathspec>\", then run\nhint: \"git cherry-pick --continue\".\nhint: You can instead skip this commit with \"git cherry-pick --skip\".\nhint: To abort and get back to the state before \"git cherry-pick\",\nhint: run \"git cherry-pick --abort\".\nhint: Disable this message with \"git config set advice.mergeConflict false\"\n"
},
{
"executable": "git",
"args": [
"ls-files",
"--unmerged"
],
"status": 0,
"stdout": "100644 44a1d3c1960ca191cb02699472e845df31381af2 1\tsrc/retry.js\n100644 826028d2df226a0d8c67fd275fbe689ae86b39c7 3\tsrc/retry.js\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"rev-parse",
"CHERRY_PICK_HEAD"
],
"status": 0,
"stdout": "fb62f918310b9cd01ca6deddff6acbb1eecd55c9\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"cherry-pick",
"--abort"
],
"status": 0,
"stdout": "",
"stderr": ""
},
{
"executable": "git",
"args": [
"rev-parse",
"HEAD"
],
"status": 0,
"stdout": "61a92304ff91bfb87f6c1a08765276187b227cf3\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"rev-parse",
"HEAD^{tree}"
],
"status": 0,
"stdout": "9ed1ebc390513ca0f09c3c4fc20700b38fc2e614\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"status",
"--porcelain"
],
"status": 0,
"stdout": "",
"stderr": ""
},
{
"executable": "git",
"args": [
"cherry-pick",
"-x",
"fb62f918310b9cd01ca6deddff6acbb1eecd55c9"
],
"status": 1,
"stdout": "CONFLICT (modify/delete): src/retry.js deleted in HEAD and modified in fb62f91 (fixture: clamp negative retry limits). Version fb62f91 (fixture: clamp negative retry limits) of src/retry.js left in tree.\n",
"stderr": "error: could not apply fb62f91... fixture: clamp negative retry limits\nhint: After resolving the conflicts, mark them with\nhint: \"git add/rm <pathspec>\", then run\nhint: \"git cherry-pick --continue\".\nhint: You can instead skip this commit with \"git cherry-pick --skip\".\nhint: To abort and get back to the state before \"git cherry-pick\",\nhint: run \"git cherry-pick --abort\".\nhint: Disable this message with \"git config set advice.mergeConflict false\"\n"
},
{
"executable": "git",
"args": [
"rm",
"src/retry.js"
],
"status": 0,
"stdout": "rm 'src/retry.js'\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"add",
"src/normalize.ts"
],
"status": 0,
"stdout": "",
"stderr": ""
},
{
"executable": "node",
"args": [
"consumer.mjs"
],
"status": 0,
"stdout": "retry limit regression passed\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"-c",
"core.editor=true",
"cherry-pick",
"--continue"
],
"status": 0,
"stdout": "[codex/rehearsal db16876] fixture: clamp negative retry limits\n Date: Tue Sep 15 00:24:23 2026 +0800\n 1 file changed, 1 insertion(+), 1 deletion(-)\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"rev-parse",
"HEAD"
],
"status": 0,
"stdout": "db16876b0622d8dd6337a2bebcf7bca9e743fa31\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"log",
"-1",
"--format=%B"
],
"status": 0,
"stdout": "fixture: clamp negative retry limits\n\n(cherry picked from commit fb62f918310b9cd01ca6deddff6acbb1eecd55c9)\n\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"status",
"--porcelain"
],
"status": 0,
"stdout": "",
"stderr": ""
},
{
"executable": "git",
"args": [
"ls-files",
"src/retry.js"
],
"status": 0,
"stdout": "",
"stderr": ""
},
{
"executable": "node",
"args": [
"consumer.mjs"
],
"status": 0,
"stdout": "retry limit regression passed\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"show",
"--format=fuller",
"--binary",
"db16876b0622d8dd6337a2bebcf7bca9e743fa31"
],
"status": 0,
"stdout": "commit db16876b0622d8dd6337a2bebcf7bca9e743fa31\nAuthor: ArtPlayer isolated rehearsal <rehearsal@example.invalid>\nAuthorDate: Tue Sep 15 00:24:23 2026 +0800\nCommit: ArtPlayer isolated rehearsal <rehearsal@example.invalid>\nCommitDate: Tue Sep 15 00:24:24 2026 +0800\n\n fixture: clamp negative retry limits\n \n (cherry picked from commit fb62f918310b9cd01ca6deddff6acbb1eecd55c9)\n\ndiff --git a/src/normalize.ts b/src/normalize.ts\nindex 74a0d7c..2251bcd 100644\n--- a/src/normalize.ts\n+++ b/src/normalize.ts\n@@ -1 +1 @@\n-export const normalizeLimit = (value: number): number => Math.trunc(value);\n+export const normalizeLimit = (value: number): number => Math.max(0, Math.trunc(value));\n",
"stderr": ""
},
{
"executable": "git",
"args": [
"bundle",
"create",
"D:\\github\\ArtPlayer\\refactor\\.cache\\mainline-rehearsal\\run-zTEWy5\\rehearsal.bundle",
"--all"
],
"status": 0,
"stdout": "",
"stderr": ""
},
{
"executable": "git",
"args": [
"bundle",
"verify",
"D:\\github\\ArtPlayer\\refactor\\.cache\\mainline-rehearsal\\run-zTEWy5\\rehearsal.bundle"
],
"status": 0,
"stdout": "The bundle contains these 3 refs:\ndb16876b0622d8dd6337a2bebcf7bca9e743fa31 refs/heads/codex/rehearsal\nfb62f918310b9cd01ca6deddff6acbb1eecd55c9 refs/heads/master\ndb16876b0622d8dd6337a2bebcf7bca9e743fa31 HEAD\nThe bundle records a complete history.\nThe bundle uses this hash algorithm: sha1\n",
"stderr": "D:/github/ArtPlayer/refactor/.cache/mainline-rehearsal/run-zTEWy5/rehearsal.bundle is okay\n"
}
],
"commits": {
"base": "a10e48e0c1f7a712fd602d5d8afcacef9a5e68b0",
"migrated": "61a92304ff91bfb87f6c1a08765276187b227cf3",
"fix": "fb62f918310b9cd01ca6deddff6acbb1eecd55c9",
"resolved": "db16876b0622d8dd6337a2bebcf7bca9e743fa31"
},
"abort": {
"restoredCommit": "61a92304ff91bfb87f6c1a08765276187b227cf3",
"restoredTree": "9ed1ebc390513ca0f09c3c4fc20700b38fc2e614",
"clean": true
},
"resolution": {
"source": "src/retry.js",
"destination": "src/normalize.ts",
"obsoleteFileAbsent": true,
"regressionPassed": true,
"attributed": true
}
},
"inventory": {
"command": "yarn check:rollback-inventory",
"packages": 22,
"verifiedArchives": 20,
"file": "refactor/baselines/rollback-inventory.json",
"sha256": "33d083badfc54f4be5be42518b03fb499062ab724bc4f4ebb3c1dec32b9bfb8a",
"deferredArtifacts": [
{
"name": "artplayer-tool-thumbnail",
"status": "complete-rollback-artifact-required"
},
{
"name": "artplayer-vitepress",
"status": "previous-deployment-artifact-required"
}
]
},
"realRepository": {
"command": "git fetch origin master",
"log": "refactor/.cache/rel04-mainline-fetch-final.log",
"exitCode": 0,
"master": "40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f",
"ahead": 257,
"behind": 0,
"incomingFixes": [],
"cherryPicksApplied": []
},
"engineering": {
"status": "passed",
"log": "refactor/.cache/rel04-workflows-engineering.log",
"exitCode": 0,
"commands": [
"scoped ESLint for three workflow modules",
"node --test test/rollback-files.test.js test/package-runtime.test.js refactor/scripts/ci-workflow.test.mjs",
"yarn check:rollback-inventory",
"yarn check:toolchain --strict",
"node refactor/scripts/plan.mjs --check",
"git diff --check"
]
},
"limitations": [
"REL-04 remains doing: complete Thumbnail fallback and Pages recovery evidence remain.",
"Iframe browser/device acceptance remains in PKG-IFRAME-05; these are real installation/import/type checks.",
"Conflict exercise is synthetic and does not claim a production retry bug or repair.",
"Registry mutable tags and current availability were not queried or changed.",
"All final publication batches must bind actual next-major candidates and repeat relevant rollback checks.",
"No dependencies, production source, root lock, distribution outputs, remote CI runs, push, tag or deployment changes."
]
}
@@ -0,0 +1,30 @@
# REL-04 更名回退、全包清单和主线同步检查点
本次不修改生产运行时代码。新增三个有明确边界的工程入口,无新依赖:
- `test:rollback:iframe`:正常隔离构建 tool 包,旧 plugin→新 tool→恢复旧 plugin 的实际冻结安装、成员检查、应用导入恢复、旧包清理、strict TS 消费者及本地依赖键映射负例。
- `test:rollback:mainline`:独立临时 Git 仓库内实际执行 JS→TS modify/delete 冲突、abort 恢复、手动转移修复和带来源的 continue;保留命令输出、patch 与 bundle。
- `check:rollback-inventory`:验证 22 包生成清单,20 份完整历史 tarball 的 SHA-512/SHA-256、旧/新 manifest 依赖与目标版本。加入 `ci:check` 防止清单漂移。
实际命令均通过,具体记录/哈希见
[机器证据](../baselines/rollback-workflows-validation.json)。scoped lint、生成清单
检查、严格工具链和相关 Node 工程回归通过;没有将本地 CI 配置描述成远端运行通过。
## 兼容边界
旧 iframe 的 require 返回对象、新版返回构造函数;旧 helper 独立。负例确认只把
旧 tarball 映射到新依赖键不能透明回退。已测试方案同时恢复旧应用导入、manifest
和 lock;没有改生产 API,也没有引入未经授权的新包名兼容策略。
主线负数修复是合成 fixture,不是 ArtPlayer 生产缺陷。先验证旧/迁移实现的准确
断言失败,再验证主线和迁移后修复通过;不能用任意 Node 报错代替缺陷复现。
真实仓库 fetch 后无新增 master 修复,未修改其历史/分支/远端。
## 交接
维护职责和完整执行步骤在[回退维护](../rollback-rehearsal.md);包内架构说明已
补更名导出差异和演练入口。恢复表从发布台账生成,不额外维护第二份版本来源。
REL-04 继续 doing:Thumbnail 原完整包缺失,完整替代回退产物和站点恢复证据仍
需处理。全部正式批次需重新绑定最终候选,不把早期核心/Chapter/iframe 演练推广
为其他包或物理设备的完成证据。撤销本工程检查点不会改变生产行为或远端设置。
+1 -1
View File
@@ -658,7 +658,7 @@
- MOD-DEV-01: [记录](changes/2026-09-14-MOD-DEV-01-dev-server.md) [记录](baselines/dev-server-validation.json)
- MOD-03: [记录](changes/2026-09-14-MOD-03-slider-updates.md) [记录](baselines/slider-updates-validation.json) [记录](changes/2026-09-14-MOD-03-performance-acceptance.md) [记录](baselines/core-performance-validation.json)
- REL-08: [记录](changes/2026-09-14-REL-08-release-ledger.md) [记录](baselines/release-ledger-validation.json) [记录](release-ledger.md) [记录](release-ledger.json)
- REL-04: [记录](changes/2026-09-15-REL-04-consumer-checkpoint.md) [记录](rollback-rehearsal.md) [记录](baselines/rollback-consumer-validation.json)
- REL-04: [记录](changes/2026-09-15-REL-04-consumer-checkpoint.md) [记录](rollback-rehearsal.md) [记录](baselines/rollback-consumer-validation.json) [记录](changes/2026-09-15-REL-04-workflows-checkpoint.md) [记录](rollback-inventory.md) [记录](baselines/rollback-workflows-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) [记录](type-compatibility-policy.md) [记录](baselines/factory-compatibility-validation.json) [记录](changes/2026-09-13-PKG-FACTORY-01-compatible-types.md)
- CORE-25: [记录](changes/2026-09-13-CORE-25-defaults-ssr.md) [记录](baselines/defaults-ssr-validation.json)
- ENG-12: [记录](changes/2026-09-13-ENG-12-library-public.md) [记录](baselines/library-public-validation.json)
+9
View File
@@ -1,5 +1,14 @@
# 进度与证据
## REL-04 更名回退与主线工作流检查点
完成旧 iframe 包→新 tool 包→恢复旧包的实际冻结安装、应用导入/类型/成员核验,
并复现仅映射包名无法保持新构造/legacy 用法。独立 Git 仓库内 JS→TS 冲突的
中止恢复与修复同步均通过;真实 master 无新增待同步提交。22 包恢复清单生成,
20 份完整旧 archive 的双哈希验证通过,新增清单 CI 检查。详见
[记录](changes/2026-09-15-REL-04-workflows-checkpoint.md)。Thumbnail 完整替代
回退产物和站点恢复证据尚缺,REL-04 继续 doing,任务完成数不变。
## REL-04 核心/Chapter 回退演练检查点
新增实际隔离安装回退脚本,七步安装/升级/分别回退/整体恢复通过,237 项运行时
+40
View File
@@ -0,0 +1,40 @@
# 逐包回退清单
由 `node refactor/scripts/rollback-inventory.mjs --write` 生成;`--check` 校验同步并复核冻结 tarball 完整性。
本表核对 20 份完整历史 archive 的 SHA-512/SHA-256 和 manifest。它不表示当前 registry 可用,
也不表示全部包的实际回退已验收。机器清单同时保存旧/新 dependencies、peerDependencies 与精确 integrity。
| 当前包 | 目标版本 | 恢复版本/对象 | 旧包运行依赖 | 恢复状态 |
| --- | --- | --- | --- | --- |
| artplayer | 6.0.0 | artplayer@5.4.0 | option-validator@^2.0.6 | archive-verified-batch-rehearsal-required |
| artplayer-plugin-ads | 3.0.0 | artplayer-plugin-ads@1.0.6 | 无声明 | archive-verified-batch-rehearsal-required |
| artplayer-plugin-ambilight | 2.0.0 | artplayer-plugin-ambilight@1.1.0 | 无声明 | archive-verified-batch-rehearsal-required |
| artplayer-plugin-asr | 3.0.0 | artplayer-plugin-asr@2.1.0 | 无声明 | archive-verified-batch-rehearsal-required |
| artplayer-plugin-audio-track | 2.0.0 | artplayer-plugin-audio-track@1.1.0 | 无声明 | archive-verified-batch-rehearsal-required |
| artplayer-plugin-auto-thumbnail | 2.0.0 | artplayer-plugin-auto-thumbnail@1.1.0 | 无声明 | archive-verified-batch-rehearsal-required |
| artplayer-plugin-chapter | 2.0.0 | artplayer-plugin-chapter@1.1.0 | 无声明 | archive-verified-batch-rehearsal-required |
| artplayer-plugin-chromecast | 2.0.0 | artplayer-plugin-chromecast@1.1.0 | 无声明 | archive-verified-batch-rehearsal-required |
| artplayer-plugin-danmuku | 6.0.0 | artplayer-plugin-danmuku@5.3.0 | 无声明 | archive-verified-batch-rehearsal-required |
| artplayer-plugin-danmuku-mask | 2.0.0 | artplayer-plugin-danmuku-mask@1.1.0 | @mediapipe/selfie_segmentation@^0.1.1675465747, @tensorflow-models/body-segmentation@^1.0.2, @tensorflow/tfjs-backend-cpu@^4.21.0, @tensorflow/tfjs-backend-webgl@^4.21.0, @tensorflow/tfjs-converter@^4.21.0, @tensorflow/tfjs-core@^4.21.0 | archive-verified-batch-rehearsal-required |
| artplayer-plugin-dash-control | 2.0.0 | artplayer-plugin-dash-control@1.1.0 | 无声明 | archive-verified-batch-rehearsal-required |
| artplayer-plugin-document-pip | 2.0.0 | artplayer-plugin-document-pip@1.1.0 | 无声明 | archive-verified-batch-rehearsal-required |
| artplayer-plugin-hls-control | 2.0.0 | artplayer-plugin-hls-control@1.1.0 | 无声明 | archive-verified-batch-rehearsal-required |
| artplayer-plugin-jassub | 2.0.0 | artplayer-plugin-jassub@1.1.0 | 无声明 | archive-verified-batch-rehearsal-required |
| artplayer-plugin-multiple-subtitles | 2.0.0 | artplayer-plugin-multiple-subtitles@1.2.0 | 无声明 | archive-verified-batch-rehearsal-required |
| artplayer-plugin-vast | 2.0.0 | artplayer-plugin-vast@1.0.0 | @glomex/vast-ima-player@^1.21.0 | archive-verified-batch-rehearsal-required |
| artplayer-plugin-vtt-thumbnail | 2.0.0 | artplayer-plugin-vtt-thumbnail@1.1.0 | 无声明 | archive-verified-batch-rehearsal-required |
| artplayer-proxy-canvas | 2.0.0 | artplayer-proxy-canvas@1.1.0 | 无声明 | archive-verified-batch-rehearsal-required |
| artplayer-proxy-mediabunny | 2.0.0 | artplayer-proxy-mediabunny@1.2.0 | mediabunny@^1.43.1 | archive-verified-batch-rehearsal-required |
| artplayer-tool-iframe | 2.0.0 | artplayer-plugin-iframe@1.0.0 | 无声明 | archive-verified-batch-rehearsal-required |
| artplayer-tool-thumbnail | 5.0.0 | 完整旧产物尚缺 | 见原有门槛 | complete-rollback-artifact-required |
| artplayer-vitepress | 2.0.0 | 已验证 Pages 产物 | 见原有门槛 | previous-deployment-artifact-required |
每包优先恢复升级前已验证的应用代码、package.json 和 yarn.lock,再执行 `yarn install --frozen-lockfile`;
离线恢复还需保存所需 tarball/依赖缓存。单独把版本改回去并重新解析依赖,不能替代已测试锁文件。
外部播放器 SDK、worker/WASM、远端媒体和平台能力也要恢复对应配置,npm 依赖表不覆盖它们。
iframe 必须同步恢复旧包名、CommonJS `.default`、helper 路径和应用代码;不将 npm alias 当作兼容门面。
Thumbnail 完整原包缺失以及站点部署恢复仍是发布门槛。正式每批重新绑定候选和回退内容,不能直接复用早期演练结果。
来源:[机器清单](baselines/rollback-inventory.json)、[维护入口](rollback-rehearsal.md)、[发布台账](release-ledger.md)。
+49 -4
View File
@@ -61,10 +61,55 @@ ENG-07 而被拒绝;保留该门槛,回退使用独立验证入口。
详见 [机器证据](baselines/rollback-consumer-validation.json) 和
[检查点](changes/2026-09-15-REL-04-consumer-checkpoint.md)。
尚需:22 包逐包旧版本/tag/依赖恢复表、iframe 更名前后消费者回退、主线修改与
JS→TS 冲突同步/中止演练。已执行 `git fetch origin master`,当时 master 没有
新增待同步提交;这不等于验证过冲突解决。
后续检查点已补齐[22 包恢复清单](rollback-inventory.md)、iframe 更名安装回退以及
JS→TS 冲突同步/中止演练。`yarn check:rollback-inventory` 校验生成表并重新检查
20 份完整冻结 archive;CI 的 `ci:check` 同样运行该检查。缺失 tarball 时只按
冻结 registry URL/完整性恢复缓存,不查询或跟随 latest。
## iframe 更名回退
运行 `yarn test:rollback:iframe`。`scripts/iframe-rollback.mjs` 在隔离构建快照内
用正常构建器打包当前 tool 包,并从冻结来源验证旧 plugin 包。先准备两套应用
manifest、lock 和导入代码,再在同一仓库外消费者中依次安装旧包、升级新包、恢复
旧包。检查完整成员、冻结锁、应用代码哈希和被替换包目录确实消失;各步另有实际
require/helper/legacy 及 TS 5.9.3 strict 消费者验证。
实际旧包 `artplayer-plugin-iframe@1.0.0` 的根 require 返回对象,构造类位于
`.default`,并有独立 helper 文件;新 tool 包根 require 直接返回类。负例已实际
把旧 tarball 安装在新的依赖键下,确认构造和 `/legacy` 均无法沿用新版写法。
这是本地 file 依赖键映射验证,没有声称执行过 registry 的 npm alias 协议。
回退要恢复应用导入代码和包名/锁,不能只换版本或别名。
输出为 `refactor/.cache/iframe-rollback/run-*`,包括两套锁、应用代码、构建及
安装日志和报告。该演练覆盖安装/导出/类型恢复,iframe 真机和跨窗媒体测试仍由
PKG-IFRAME-05 承担,不借此关闭其门槛。
## 主线修复同步与中止
运行 `yarn test:rollback:mainline`。`scripts/mainline-rehearsal.mjs` 在仓库外创建
独立 Git 仓库,合成 JS 计算模块迁移至两个 TS 模块后,主线修复旧文件的情形。
它实际复现负数计算的断言失败、cherry-pick 的 modify/delete 冲突;先中止并验证
HEAD/tree/工作区完全恢复,再次应用并把修复移入 TS 计算模块。最终回归通过、旧 JS
文件不存在、提交中保留 `cherry-pick -x` 来源。原仓库没有被切换分支或 cherry-pick。
Git fixture 只使用目录内身份配置,禁用全局配置;所有命令/退出码、断言、冲突内容、
最终 patch 和可验证 Git bundle 保存到 `refactor/.cache/mainline-rehearsal/run-*`。
失败也写报告,并清理已验证的临时消费者目录。该合成演练验证工作流,不代表发现或
修复了真实 ArtPlayer 重试逻辑问题。
实际同步时先 `git fetch origin master`,记录 `git rev-list --left-right --count
HEAD...origin/master` 及修复 SHA,再审查每个上游 diff。找出迁移后的责任模块,
为原缺陷补可重跑回归,在隔离工作树应用 `git cherry-pick -x <已核实修复SHA>`。
发生冲突时审查 `git status`、`git ls-files --unmerged` 和上游完整 diff,不能为
结束冲突而直接恢复已淘汰 JS 文件。修复迁移后的对应模块、暂存明确文件、运行相关
单元/类型/浏览器检查,再 `git cherry-pick --continue`。无法正确落地则
`git cherry-pick --abort`,核对原 HEAD/tree 和工作区状态后登记待同步项。
每个实际修复仍建立任务、保留上游归属、独立提交并通过提交审计。
本次再次 fetch 后 master 仍无新增提交;真实仓库没有需要应用的修复。冻结起点和
当前差分记录在[后续检查点证据](baselines/rollback-workflows-validation.json)。
Thumbnail 的完整旧 npm tarball 缺失、文档站的真实部署恢复继续受原有发布门槛
约束。正式每批需要重新绑定实际 next-major 候选及旧包产物并重跑对应验证。
约束,REL-04 保持 doing,继续准备完整回退替代产物/站点恢复证据。正式每批需要
重新绑定实际 next-major 候选及旧包产物并重跑对应验证。
不执行 npm tag 修改、unpublish、推送或部署,不把本演练当作这些动作的授权。
+75
View File
@@ -0,0 +1,75 @@
import assert from 'node:assert/strict'
import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { fileURLToPath } from 'node:url'
import { ensureArchive, readMember } from './releases.mjs'
const root = fileURLToPath(new URL('../../', import.meta.url))
assert(['--write', '--check'].includes(process.argv[2]) && process.argv.length === 3, 'Use --write or --check')
const read = file => JSON.parse(fs.readFileSync(path.join(root, file), 'utf8'))
const ledger = read('refactor/release-ledger.json')
const rows = []
for (const pkg of ledger.packages) {
const baseline = read(pkg.history.file)
const release = pkg.history.selector?.split('.').reduce((value, key) => value?.[key], baseline)
const current = read(`packages/${pkg.name}/package.json`)
const row = { name: pkg.name, targetVersion: pkg.targetVersion, distribution: pkg.distribution, history: pkg.history, currentDependencies: current.dependencies || {}, currentPeers: current.peerDependencies || {}, currentOptionalDependencies: current.optionalDependencies || {} }
if (pkg.distribution === 'site') {
rows.push({ ...row, restore: 'Previously verified Pages artifact, exact source SHA and URL map; npm rollback does not apply.', status: 'previous-deployment-artifact-required', evidence: 'refactor/pages-deployment.md' })
continue
}
if (pkg.distribution === 'recovered-npm') {
assert(release, 'Missing recovered history')
rows.push({ ...row, restore: 'No intact historical npm tarball. Preserve a complete pre-upgrade application/artifact snapshot and verify it before any candidate deployment.', status: 'complete-rollback-artifact-required', evidence: pkg.history.file })
continue
}
assert(release?.integrity && release.sha256 && release.files, `Missing frozen rollback archive: ${pkg.name}`)
const archive = await ensureArchive(release)
const manifest = JSON.parse(readMember(archive, 'package/package.json'))
assert.equal(manifest.name, release.name)
assert.equal(manifest.version, release.version)
rows.push({
...row,
previous: { name: release.name, version: release.version, tarball: release.tarball, integrity: release.integrity, sha256: release.sha256, memberCount: Object.keys(release.files).length, dependencies: manifest.dependencies || {}, peerDependencies: manifest.peerDependencies || {}, optionalDependencies: manifest.optionalDependencies || {} },
exactDependency: { [release.name]: release.version },
restore: pkg.distribution === 'renamed-npm'
? 'Restore application import code, old package name and saved lock together; npm alias alone does not restore the old export/helper surface.'
: 'Restore the saved application manifest/lock and matching artifacts, then frozen-install the previous exact version with its tested core/plugin combination.',
status: 'archive-verified-batch-rehearsal-required',
})
}
assert.equal(rows.length, 22)
const result = { task: 'REL-04', source: 'refactor/release-ledger.json and frozen historical archives', registryAvailabilityRefreshed: false, mutableTagPolicy: 'Use exact versions and saved lock/artifact hashes. No latest/next/rollback tag is assumed or changed.', packages: rows }
const json = `${JSON.stringify(result, null, 2)}\n`
const dependencies = value => Object.entries(value).map(([name, version]) => `${name}@${version}`).join(', ') || '无声明'
const lines = [
'# 逐包回退清单',
'',
'由 `node refactor/scripts/rollback-inventory.mjs --write` 生成;`--check` 校验同步并复核冻结 tarball 完整性。',
'',
'本表核对 20 份完整历史 archive 的 SHA-512/SHA-256 和 manifest。它不表示当前 registry 可用,',
'也不表示全部包的实际回退已验收。机器清单同时保存旧/新 dependencies、peerDependencies 与精确 integrity。',
'',
'| 当前包 | 目标版本 | 恢复版本/对象 | 旧包运行依赖 | 恢复状态 |',
'| --- | --- | --- | --- | --- |',
...rows.map(row => `| ${row.name} | ${row.targetVersion} | ${row.previous ? `${row.previous.name}@${row.previous.version}` : row.distribution === 'site' ? '已验证 Pages 产物' : '完整旧产物尚缺'} | ${row.previous ? dependencies(row.previous.dependencies) : '见原有门槛'} | ${row.status} |`),
'',
'每包优先恢复升级前已验证的应用代码、package.json 和 yarn.lock,再执行 `yarn install --frozen-lockfile`;',
'离线恢复还需保存所需 tarball/依赖缓存。单独把版本改回去并重新解析依赖,不能替代已测试锁文件。',
'外部播放器 SDK、worker/WASM、远端媒体和平台能力也要恢复对应配置,npm 依赖表不覆盖它们。',
'',
'iframe 必须同步恢复旧包名、CommonJS `.default`、helper 路径和应用代码;不将 npm alias 当作兼容门面。',
'Thumbnail 完整原包缺失以及站点部署恢复仍是发布门槛。正式每批重新绑定候选和回退内容,不能直接复用早期演练结果。',
'',
'来源:[机器清单](baselines/rollback-inventory.json)、[维护入口](rollback-rehearsal.md)、[发布台账](release-ledger.md)。',
'',
]
const markdown = lines.join('\n')
for (const [file, contents] of [['refactor/baselines/rollback-inventory.json', json], ['refactor/rollback-inventory.md', markdown]]) {
if (process.argv[2] === '--write')
fs.writeFileSync(path.join(root, file), contents)
else
assert.equal(fs.readFileSync(path.join(root, file), 'utf8').replaceAll('\r\n', '\n'), contents, `Stale rollback inventory: ${file}`)
}
console.log(`Rollback inventory: ${rows.length} packages, ${rows.filter(row => row.previous).length} verified historical archives, remaining batch gates retained`)
+4 -1
View File
@@ -4805,7 +4805,10 @@
"evidence": [
"changes/2026-09-15-REL-04-consumer-checkpoint.md",
"rollback-rehearsal.md",
"baselines/rollback-consumer-validation.json"
"baselines/rollback-consumer-validation.json",
"changes/2026-09-15-REL-04-workflows-checkpoint.md",
"rollback-inventory.md",
"baselines/rollback-workflows-validation.json"
]
},
{