diff --git a/refactor/baselines/chromecast-real-sdk-validation.json b/refactor/baselines/chromecast-real-sdk-validation.json
new file mode 100644
index 000000000..dc7c0cd12
--- /dev/null
+++ b/refactor/baselines/chromecast-real-sdk-validation.json
@@ -0,0 +1,163 @@
+{
+ "schemaVersion": 1,
+ "task": "PKG-CAST-05",
+ "status": "real-sdk-observed-no-receiver",
+ "capturedAt": "2026-09-16T02:47:08.346Z",
+ "sourceCommit": "681eccfa76eb36da87bb85e32a5dbb93037d8c13",
+ "method": "Connected Chrome through CUA; actual UI clicks, DOM snapshots, Runtime read-only SDK state and Network response bodies. No mocked Cast API or receiver.",
+ "environment": {
+ "browser": "Google Chrome",
+ "version": "152.0.7977.84",
+ "os": "Windows",
+ "origin": "http://localhost:8082",
+ "secureContext": true,
+ "proxyObservation": "System network path in the existing Chrome profile; no network configuration changed."
+ },
+ "page": "http://localhost:8082/?libs=./compiled/artplayer-plugin-chromecast.js&example=chromecast",
+ "localArtifacts": [
+ {
+ "name": "artplayer",
+ "url": "http://localhost:8082/compiled/artplayer.js",
+ "sha256": "8a4caaa50a069875b3898a83765457b3c502700f4731d0c38988d6c463c3d20a",
+ "characters": 208943,
+ "file": "docs/compiled/artplayer.js",
+ "candidate": {
+ "kind": "npm-tarball",
+ "path": "refactor/.cache/packages/run-kK0VCe/artplayer.tgz",
+ "version": "6.0.0",
+ "sourceCommit": "8aa99ef03f2ce6b240da7f4086602a91dd8e721b",
+ "inputFingerprint": "693ac1e1b107501f7202f19e8ab58ab15240e28f6ba6db0e0917eb2bebb447cd",
+ "integrity": "sha512-3HMgVqBMQzTDNJtey+EPO8UlU9+b22SbFgwCFmwXHg/1gAg7iMREaeGi0BtZrYzTAc9B7uZRtP75jBjlDa6OfA=="
+ },
+ "observation": "Actual Chrome Network.getResponseBody UTF-8 SHA256 matched current docs output and registered tarball member."
+ },
+ {
+ "name": "artplayer-plugin-chromecast",
+ "url": "http://localhost:8082/compiled/artplayer-plugin-chromecast.js",
+ "sha256": "af07fc1d768a90c444e9510bd60faf1878f63d30dec9ed6a8f91344afae6dc85",
+ "characters": 6096,
+ "file": "docs/compiled/artplayer-plugin-chromecast.js",
+ "candidate": {
+ "kind": "npm-tarball",
+ "path": "refactor/.cache/packages/run-kK0VCe/artplayer-plugin-chromecast.tgz",
+ "version": "2.0.0",
+ "sourceCommit": "8aa99ef03f2ce6b240da7f4086602a91dd8e721b",
+ "inputFingerprint": "e05496198b0cd7e99fd335de0125d36187c2ffa59d0699e46ef295d8d279ee37",
+ "integrity": "sha512-84Dm7cSe8tpz/L78W5CHMEODjOHy9sAMkO8yZrEsfKkHScZWD+q3XdhFPsKxPYpKlOYeNP+YQVwGYxSpmqb0gg=="
+ },
+ "observation": "Actual Chrome Network.getResponseBody UTF-8 SHA256 matched current docs output and registered tarball member."
+ }
+ ],
+ "remoteScripts": [
+ {
+ "url": "https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1",
+ "status": 200,
+ "sha256": "ee147e859ad0f09aa50367974e38ab53e7c7054c4a51d400a7f45b0eb251454f",
+ "characters": 4272
+ },
+ {
+ "url": "http://www.gstatic.com/eureka/clank/152/cast_sender.js",
+ "status": 200,
+ "sha256": "b99daad4bcc22cce872711e33cdc32636826346e715553645395f8a16ee79d55",
+ "characters": 47163
+ },
+ {
+ "url": "http://www.gstatic.com/cast/sdk/libs/sender/1.0/cast_framework.js",
+ "status": 200,
+ "sha256": "a2bdd8cb01353d4ed2a9ab4c7d7c263225f6908aa875614d015a2f39956d9d73",
+ "characters": 35946
+ }
+ ],
+ "observations": [
+ {
+ "phase": "workspace-demo",
+ "core": "5.4.1",
+ "scope": "Existing uncompiled workspace build, not frozen npm 5.4.0 or minimum-supported core proof",
+ "framework": true,
+ "castState": "NO_DEVICES_AVAILABLE",
+ "session": false,
+ "pluginState": null,
+ "isCasting": false,
+ "remoteStatuses": [
+ 200,
+ 200,
+ 200
+ ]
+ },
+ {
+ "phase": "candidate-first-click",
+ "core": "6.0.0",
+ "framework": false,
+ "session": false,
+ "pluginState": null,
+ "isCasting": false,
+ "remoteStatuses": [
+ 200,
+ 200,
+ 502
+ ],
+ "failedUrl": "http://www.gstatic.com/cast/sdk/libs/sender/1.0/cast_framework.js",
+ "bootstrapScriptsAfterFailure": 0,
+ "scope": "Observed remote framework HTTP 502 retained; no claim that candidate initialization succeeded on this attempt."
+ },
+ {
+ "phase": "candidate-retry-click",
+ "core": "6.0.0",
+ "framework": true,
+ "castState": "NO_DEVICES_AVAILABLE",
+ "session": false,
+ "pluginState": null,
+ "isCasting": false,
+ "frameworkHttpStatus": 200,
+ "bootstrapScripts": 1
+ },
+ {
+ "phase": "run-code-recreate",
+ "core": "6.0.0",
+ "instances": 1,
+ "castControls": 1,
+ "framework": false,
+ "session": false,
+ "bootstrapScripts": 0,
+ "scope": "Observed editor rerun state; not attributed solely to plugin destroy."
+ },
+ {
+ "phase": "recreated-player-click",
+ "core": "6.0.0",
+ "instances": 1,
+ "castControls": 1,
+ "framework": true,
+ "castState": "NO_DEVICES_AVAILABLE",
+ "session": false,
+ "pluginState": null,
+ "isCasting": false,
+ "bootstrapScripts": 1,
+ "remoteStatuses": [
+ 200,
+ 200,
+ 200
+ ],
+ "scriptHashesMatchFirstSuccessfulLoad": true
+ }
+ ],
+ "cleanup": {
+ "restoredProdCheckbox": false,
+ "closedAgentTestTab": true
+ },
+ "limitations": [
+ "No Cast receiver was available. No session creation, receiver playback, media source update or disconnect was verified.",
+ "No claim of requestSession rejection/cancellation, timeout behavior or physical playback from NO_DEVICES_AVAILABLE alone.",
+ "Public callback support and older npm core combinations still rely on separately recorded controlled tests until a receiver is available.",
+ "The SDK bootstrap and framework URLs are mutable; response hashes describe this observation, not a pinned supported SDK version.",
+ "Localhost was a secure context; the SDK itself selected HTTP child script URLs. Production HTTPS behavior was not tested.",
+ "This manual observation does not replace committed deterministic browser tests, all-package release acceptance, or user-directed formal reviews."
+ ],
+ "publicationAuthorized": false,
+ "releaseInputCheck": {
+ "report": "refactor/.cache/release-ledger-KSwaI3/report.json",
+ "sha256": "7fca6b694b1263f03d2a97ae9b35a1bfd3221136549ce72fd37412c915f9b25d",
+ "validLibraryBuilds": 21,
+ "staleLibraryBuilds": 0,
+ "scope": "Documentation and observation only; no candidate build invalidated or browser acceptance rebound."
+ }
+}
diff --git a/refactor/changes/2026-09-16-PKG-CAST-05-real-sdk.md b/refactor/changes/2026-09-16-PKG-CAST-05-real-sdk.md
new file mode 100644
index 000000000..067a150fd
--- /dev/null
+++ b/refactor/changes/2026-09-16-PKG-CAST-05-real-sdk.md
@@ -0,0 +1,56 @@
+# PKG-CAST-05 真实 Chrome / Google Cast SDK 检查点
+
+起点 `681eccfa76eb36da87bb85e32a5dbb93037d8c13`。Chrome 扩展连接恢复,本批使用
+实际本地编辑器和 Google 远端 SDK,没有替换 Cast API 或模拟接收设备。
+结果见[机器记录](../baselines/chromecast-real-sdk-validation.json)。05 从 todo
+进入 doing,实际接收端验收尚未完成。没有生产代码、依赖、测试输入或产物修改。
+
+## 实测过程
+
+环境为 Windows / Google Chrome **152.0.7977.84**,通过连接的 Chrome 操作,
+不是 Playwright Chromium 或内置浏览器。`http://localhost:8082` 的
+`isSecureContext` 为 true。打开原 `example=chromecast`,依赖为实际编译的插件。
+
+1. 现有未编译工作区核心报告版本 5.4.1。点击 Cast 后,bootstrap、Chrome sender
+ 和 Framework 三个远端脚本均 HTTP 200。Framework 创建成功,实际 CastContext
+ 返回 `NO_DEVICES_AVAILABLE`,无当前 session;插件原始状态为 null,isCasting=false。
+ 这不是 npm 5.4.0 或最早支持核心的验证,不将工作区版本当作发布基线。
+2. 通过原 Prod 开关切到重构核心 6.0.0。首次点击时 bootstrap/sender 返回 200,
+ Framework 子脚本返回 HTTP 502。保留失败;观察时 Framework 未就绪、session
+ 不存在、bootstrap script 数量为零。未记录到具体 onError/Promise 结算,不能
+ 用这个快照推断错误通知、超时或用户取消已验证。
+3. 再次正常点击后,Framework 返回 200,SDK 就绪,状态仍为无设备,插件未显示
+ 正在投屏,页面有一个 bootstrap script。
+4. 点击原 Run Code,页面保留一个播放器和一个 Cast 控件,观测时 Framework
+ 未就绪、bootstrap script 为零。这是整个编辑器重跑流程的结果,不单独归因于
+ 插件 destroy。新实例再次点击后,三个真实脚本均 200,进入无设备状态,
+ 仍只有一个播放器、一个控件和一个 bootstrap script。
+
+Chrome 的 checkbox 自动化曾在模式切换重载时报告未勾选;随后新 DOM 明确显示
+Prod 已勾选且核心版本为 6.0.0,因此没有盲目重复点击。结束时通过 UI 将 Prod
+恢复为原先 false,并关闭本次创建的测试页;未修改浏览器权限、代理或用户其他页。
+
+## 来源和证据边界
+
+用 Chrome Network.getResponseBody 读取实际响应,在页面中计算 UTF-8 SHA256。
+本地核心与插件两项响应分别匹配当前 docs/compiled 和已登记候选包的对应成员;
+不存在只看本地文件、却声称浏览器实际使用该内容的替代验证。
+
+三个远端成功响应也记录了 URL、状态、内容摘要和字符数,首次成功与重跑成功
+内容一致。SDK 自己根据当前页面加载了 HTTP sender/Framework 子脚本,本批没有
+重写 URL。这些可变远端 URL 的一次哈希不等于锁定 SDK 版本,也不能证明生产
+HTTPS 页面的加载行为。502 原始观察保留,不因后来成功而删除。
+
+没有可用 Cast 接收设备,所以未验证 session 建立、接收端播放、源更新、会话
+断开或声音输出;无设备状态本身也不证明 requestSession 的拒绝/取消语义。
+原确定性 SDK/生命周期测试继续提供受控边界证据,本批真实观察不能替代它们。
+下一步按 [Cast 验收说明](../chromecast-validation.md) 在实际接收设备上继续。
+
+## 状态与回退
+
+225 done /24 doing /36 todo。05/06 的设备和完整分发门槛仍在;本批只提交来源、
+观察、重跑步骤和状态,没有声称任务完成或发布就绪。计划检查与本地响应/候选
+文件摘要核对通过。没有重跑未变的生产测试,也没有修改其通过标准。
+发布台账检查确认21库build指纹仍有效,零项因本批文档观察而失效。
+撤销本检查点只撤销文档/证据/任务状态;不影响生产 API。
+正式复盘仍由用户指导,没有推送、部署、远程工作流或 npm 发布。
diff --git a/refactor/chromecast-validation.md b/refactor/chromecast-validation.md
new file mode 100644
index 000000000..c046f641d
--- /dev/null
+++ b/refactor/chromecast-validation.md
@@ -0,0 +1,39 @@
+# Chromecast 真实环境验收
+
+实现和受控回归入口见
+[包内维护说明](../packages/artplayer-plugin-chromecast/ARCHITECTURE.md)。
+本文件补充真实远端 SDK 与接收设备验证,不能以 stub 测试替代物理投屏。
+
+## 当前已有证据
+
+[2026-09-16 Chrome 记录](changes/2026-09-16-PKG-CAST-05-real-sdk.md)使用实际
+Chrome 152.0.7977.84 和本地编辑器。现有工作区核心5.4.1与重构核心6.0.0均
+实际加载 Google Cast Framework,当前返回 NO_DEVICES_AVAILABLE。记录包含
+一次远端502、再次点击成功及重复Run后的SDK重新初始化;它们不是接收端播放。
+源码/类型/受控DOM组合和安装证据保留在任务01—04与CI记录中,不重新包装为真机通过。
+
+## 复现加载观察
+
+1. 使用固定 Node/Yarn,并确认本地站点提供的核心/插件来自当前构建。
+2. 打开 `http://localhost:8082/?libs=./compiled/artplayer-plugin-chromecast.js&example=chromecast`。
+ 记录Prod设置、实际核心版本、插件响应哈希与浏览器完整版本。
+3. 点击Cast,记录bootstrap及其子脚本状态和实际SDK状态;仅网络200不代表已就绪。
+ 远端失败保留首次证据,再验证用户重新点击的恢复,不将连续重试当成原本通过。
+4. 重复Run后检查一个播放器/控件,再点击确认能重新初始化。不要仅凭图标判断
+ 会话建立或接收端播放;记录getCurrentSession和接收设备上的实际结果。
+5. 恢复测试前的编辑器设置,关闭测试页。不要保存无关页面请求、cookie或账户信息。
+
+## 仍需真实设备的检查
+
+- 在支持的Chrome安全上下文中连接可用Cast设备,分别验证原支持范围核心和
+ 重构核心。先明确加载的npm/候选版本和文件,不能把5.4.1工作区观察当作完整旧版矩阵。
+- 选用接收端可以访问的绝对媒体URL。当前示例的本地 `/assets/sample/video.mp4`
+ 适合验证页面/SDK加载,不能证明接收设备能访问这台电脑的localhost或相对路径。
+ 插件不负责改写消费者URL;接收端可达性必须独立确认。
+- 用户选择设备后,验证requestSession之后获取真实currentSession,接收端实际
+ 播放正确视频;验证媒体URL更新、重新载入、取消选择、会话断开及错误通知。
+- 多播放器各自更新控件并独立销毁;销毁一个播放器不应擅自结束页面共享会话。
+- 保留Chrome/系统/设备型号、媒体来源、SDK响应及对应候选摘要。没有设备的观察
+ 和能力限制单独标注,不能将isCasting或一个会话对象当作实际播放证据。
+
+这些步骤属于PKG-CAST-05/06和发布前设备验收。正式REVIEW-01/02/03仍等待用户指导。
diff --git a/refactor/plan.md b/refactor/plan.md
index 581190f64..f9fa2aea7 100644
--- a/refactor/plan.md
+++ b/refactor/plan.md
@@ -4,7 +4,7 @@
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 285 项,范围 22 个包及工作区/示例。
-状态:todo 37 / doing 23 / blocked 0 / done 225 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
+状态:todo 36 / doing 24 / blocked 0 / done 225 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -322,7 +322,7 @@
| PKG-CAST-02 | artplayer-plugin-chromecast
建立特有行为与错误测试 | PKG-CAST-01, ENG-03, ENG-05 | SDK 脚本加载失败/重入、无设备/拒绝、重复实例与销毁 | 旧版本行为可重跑,成功/失败/切源/销毁有必要断言 | H | done |
| PKG-CAST-03 | artplayer-plugin-chromecast
整理内部职责与资源 | PKG-CAST-02, CORE-11, CORE-13 | SDK singleton/实例订阅/会话与控件职责分离 | 结构变化和缺陷修复分开记录;原 API/事件/资源生命周期通过 | H | done |
| PKG-CAST-04 | artplayer-plugin-chromecast
迁移自有源码和公开类型 | PKG-CAST-03, ENG-04, ENG-06, CORE-07 | Cast 能力 adapter、全局对象和元数据类型 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容 | H | done |
-| PKG-CAST-05 | artplayer-plugin-chromecast
验证新旧核心和组合 | PKG-CAST-04, CORE-22 | stub 测试之外记录实际 Cast 设备会话、源更新和断开 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | todo |
+| PKG-CAST-05 | artplayer-plugin-chromecast
验证新旧核心和组合 | PKG-CAST-04, CORE-22 | stub 测试之外记录实际 Cast 设备会话、源更新和断开 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | doing |
| PKG-CAST-06 | artplayer-plugin-chromecast
验证分发并同步文档 | PKG-CAST-05, ENG-07 | chromecast.js、SDK URL/权限能力及待支持环境说明 | tarball 入口/资源、类型、8082 demo 和 README 一致,有回退记录 | H | todo |
## 5 包迁移:artplayer-plugin-document-pip
@@ -641,6 +641,7 @@
- PKG-CAST-02: [记录](changes/2026-09-13-PKG-CAST-02-failures.md) [记录](baselines/chromecast-failures-validation.json)
- PKG-CAST-03: [记录](changes/2026-09-13-PKG-CAST-03-runtime.md) [记录](baselines/chromecast-runtime-validation.json)
- PKG-CAST-04: [记录](changes/2026-09-13-PKG-CAST-04-types.md) [记录](baselines/chromecast-types-validation.json)
+- PKG-CAST-05: [记录](changes/2026-09-16-PKG-CAST-05-real-sdk.md) [记录](baselines/chromecast-real-sdk-validation.json) [记录](chromecast-validation.md)
- PKG-DPIP-01: [记录](changes/2026-09-12-PKG-DPIP-01-contract.md) [记录](baselines/dpip-release.json) [记录](baselines/dpip-contract.md) [记录](baselines/dpip-contract-validation.json) [记录](dpip-validation.md)
- PKG-DPIP-02: [记录](changes/2026-09-12-PKG-DPIP-02-tests.md) [记录](baselines/dpip-behavior-validation.json) [记录](dpip-validation.md)
- PKG-DPIP-03: [记录](changes/2026-09-12-PKG-DPIP-03-lifecycle.md) [记录](baselines/dpip-lifecycle-validation.json) [记录](dpip-validation.md)
diff --git a/refactor/progress.md b/refactor/progress.md
index 367cf287a..1c41067bc 100644
--- a/refactor/progress.md
+++ b/refactor/progress.md
@@ -1,5 +1,15 @@
# 进度与证据
+## PKG-CAST-05 实际 Chrome / 远端 SDK 检查点
+
+Chrome连接恢复,使用152.0.7977.84实际打开8082示例。工作区5.4.1和重构6.0.0
+均实际初始化Google Cast Framework,当前没有接收设备。保留Framework首次502、
+重试200、重复Run后一个播放器/控件且重新加载SDK的记录;本地响应哈希与登记候选
+成员一致,见[记录](changes/2026-09-16-PKG-CAST-05-real-sdk.md)。Prod已恢复、测试页
+已关闭。没有真实接收端播放/换源/断开证据,05进入doing而未完成,225/24/36。
+生产源码、测试输入和分发不变;设备步骤见[维护说明](chromecast-validation.md)。
+不进入用户保留的正式复盘,不推送/发布。
+
## REL-02 站点与组合测试之后刷新候选
从干净提交8aa99ef03重建、打包和隔离安装21库,1925输入前后一致,1043快照输入
diff --git a/refactor/tasks.json b/refactor/tasks.json
index 4b6ea3e7c..6c5e8f075 100644
--- a/refactor/tasks.json
+++ b/refactor/tasks.json
@@ -3337,11 +3337,15 @@
"PKG-CAST-04",
"CORE-22"
],
- "status": "todo",
+ "status": "doing",
"risk": "H",
"deliverable": "stub 测试之外记录实际 Cast 设备会话、源更新和断开",
"acceptance": "最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成",
- "evidence": []
+ "evidence": [
+ "changes/2026-09-16-PKG-CAST-05-real-sdk.md",
+ "baselines/chromecast-real-sdk-validation.json",
+ "chromecast-validation.md"
+ ]
},
{
"id": "PKG-CAST-06",