# 分镜清单绑定：镜头 ID、文件、哈希与顺序

组装前保持 shotId、准确文件名、SHA-256 与剪辑顺序一致。这些检查证明文件身份和顺序，不证明镜头视觉连续或生成画质。

完整包只使用 Node 标准库。不需要安装媒体工具。

在本目录运行，并选择不存在的新输出目录，脚本拒绝覆盖。受内存管理的工作站可在 Node 命令前加本地串行执行包装器。不需要提供商密钥，夹具不会向设备外发请求。

```sh
node run-recipe.mjs --out ./my-run
```

实际记录：8项检查通过，包含6项预期拒绝，Node v24.18.0。未启动 FFmpeg 子进程。

准备

- 准备 Node.js，只使用内置文件与加密模块。三份原创一秒分镜规格为 opening、hinge、hold；不接触媒体提供商。
- 同时查看 shot-manifest.json 和 shots/ 内的 JSON。每份文件除了外部清单绑定，内部还保留自己的 shotId。
- 选择新目录，order 必须为1至3且与行位置一致。basename 必须为本地唯一文件名，不接受父目录或重复文件。

## 01. 让镜头身份独立于文件名

夹具写出三份不同分镜 JSON，以及包含 shotId、order、file、sha256 的清单。剪辑身份为 opening/hinge/hold，文件名为 shot-01.json 至 shot-03.json；改名和改身份因此是两个需要审查的决定。

## 02. 优先核对顺序与唯一性

先核对准确行数、唯一镜头 ID、连续 order 和安全且唯一的文件名。文件能打开也不能放过重复 ID；清单乱序时直接失败，不暗中排序成另一种剪辑顺序。

## 03. 同时验证字节和内部镜头身份

要求文件存在、SHA-256 匹配，内部 shotId 也等于清单。脚本先测试交换文件名但保留旧哈希，再单独测试把哈希也改成错镜头文件的哈希；第二种仍会因身份不匹配失败。

## 04. 保留错误绑定供复核

检查八项断言与六条预期拒绝。缺文件、重复 ID、错顺序、错文件、内部身份不符和重复文件均有具体错误原因；动作和连续性应另行看视频验收。

验收

- 合法三行清单按原顺序通过，没有自动重排行。
- opening、hinge、hold 确为三个唯一镜头身份。
- 重复镜头 ID 与乱序行分别失败。
- 交换文件名会因原 SHA-256 绑定不符而失败。
- 缺失文件与重复文件名均被拒绝。
- 即使重绑错文件的哈希，内部 shotId 不符仍被拒绝；八项检查通过。

排错

文件可读，但分给了错误镜头。更正文件到 shotId 的绑定并核对内部身份，仅重算哈希不能修复剪辑错配。

两行使用同一镜头 ID。把错误记录及其文件内容改为真正的独立 shotId，再只重算该文件哈希。

下载完成后镜头顺序变了。把 manifest order 当作交付约定，拒绝与行位置不一致，不改用文件名字母排序。

公开回执副本仅归一化本地 checkout 路径，publicPathNormalization 保存原始回执 SHA-256；未改动原件保留在非公开资产之外。真实回执位于 executed/。failure-receipt.json 记录预期负向案例，不表示套件断言失败。原创新夹具会重新生成到指定新目录，包内保留实跑输入输出便于复核。临时原始数据和本机 HTTP 服务在 finally 清理。

checksums.json 覆盖自身与 ZIP 以外的全部分发文件，避免循环自引用；ZIP 内包含同份清单。下载后可重算，但比较前提是预期清单可信。execution-receipt.json 记录实际脚本运行前后哈希，ZIP 也会由发布目录的资产清单绑定。

这份清单让三份分镜规格可以成套复核，不检查视频本身、不保证叙事含义，也没有证明任何视频模型运行。

2026-10-14 实际读取的来源

- Node.js filesystem API: local file inspection：https://nodejs.org/api/fs.html
- Node.js crypto API: SHA-256 hashing：https://nodejs.org/api/crypto.html
