# 全量视频字幕与内容识别流水线

本文为研究档案公开版，保留来源版本的论述与限制。公开时间：2026-09-08；不表示已完成同行评审。 本文属于公开研究资料（历史笔记、研究稿或来源记录）：已完成格式、来源限制与重复项筛查，尚未完成逐篇独立事实复核；原文中的解释、候选判断和未确认内容均按其原有限制阅读。

来源版本日期：2026-07-14

证据边界：本页是进入执行态的T3工作协议。T1锁定事实为：READY-B相对READY-A按relative_path、bytes与mtime UTC比较0 added、0 removed、0 changed，批次状态READY_SEALED；权威清单为21299个文件、529个目录、4419913652206字节和6154个视频路径；12TMAC02根目录已建立；《冰山》DJI_0016.MP4本地双引擎试点成功，最终location为loc-ee88bbc8ebabdb0a518c；镜像19:12 UTC在HF_2021_06_12_18_44_32.mp4的未发布partial上触发源—目标SHA-256不一致并安全恢复；2026-07-14 02:52 UTC又检测到封存后源根增量，监督器立即停止镜像并将新增空目录幸福王国与王亚男 风车 TV/DJI_0298.MP4定位为不在manifest内的下一批材料；根.DS_Store虽mtime改变但源—既有目标SHA仍一致。固定UUID、manifest SHA、无活动flock、progress、owned partial与1.5 TB保留线复核后，02:57 UTC以同一manifest恢复，新增项不并入本批。正式任务账已完成20路径probe canary与1条61.61秒MLX机器稿，连同早期《冰山》试点共2条真实ASR样本。6154是视频路径分母，不是独立资产、可读音轨、已授权转写、含语音资产或可公开字幕数量。本页不授权改写源盘、外部上传、人物自动确认、AI训练、公开发布或删除重复。

# 全量视频字幕与内容识别流水线

> [!summary] 一句话决策
> “全量”不是给 6,154 个视频路径盲目生成 6,154 份 SRT，而是让**每一个视频路径都有可审计的 `resolved_outcome`**；在去重、可读性、音轨、语音与权利检查之后，让**每一个独立、可读取、确有言语内容且获准进行本地 ASR 的资产**得到一套可追溯的机器字幕包。

> [!success] 当前已经进入执行态
> READY-B 已与 READY-A 完成稳定性复核并封存为 `READY_SEALED`；`12TMAC02` 目标根目录已经建立，《冰山》`DJI_0016.MP4` 的本地双引擎试点已成功，全量镜像也已启动。这里的“执行态”只表示批次封存和基础链路开始运行，**不表示镜像已经完成，更不表示 6,154 个视频路径已经全部获得语音字幕**。

> [!important] 批次级本地转写权限已落账
> Owner指令已写入`2026-07-13-ready-sealed-local-asr-authorization.json`，仅对本批开放`LOCAL_ASR_ALLOWED`，同时锁定`restricted / machine_unreviewed / public=no / cloud=false / source_write=false`。它允许内部归档转写，不使公开、AI训练、声纹识别或项目确认获得默认授权。运行器必须校验该文件的批次、manifest SHA-256、许可字段和文件哈希；没有这道门时不得执行全量`run --execute`。

> 上一卷：04-首批项目路由与三十天执行顺序-2026-07-13（馆内参考，未随本文公开）｜返回P4素材盘项目式归档总入口（馆内参考，未随本文公开）｜下一卷：暂无

## 一、封存后的权威分母：先把“有多少”说准确

2026-07-13 09:15 PDT 的 **READY-B** 与 08:45 的 **READY-A**，以 `relative_path + bytes + mtime UTC` 为比较键复核，结果为：

```text
added   = 0
removed = 0
changed = 0
batch_status = READY_SEALED
```

因此，以下数字不再只是 READY 候选 A 的观察值，而是本批次封存清单的权威路径级分母：

| 指标 | READY_SEALED 权威清单 | 相对旧基线 | 证据含义 |
|---|---:|---:|---|
| 文件路径 | **21,299** | **+116** | 尚未等同于独立数字资产 |
| 目录 | **529** | — | 目录结构计数，不进入资产分母 |
| 总字节数 | **4,419,913,652,206 B** | 约 +0.488 TB | 十进制约 **4.420 TB**，以精确字节值为权威 |
| 视频路径 | **6,154** | **+114** | 依据扩展名识别，不代表均可解码、有音轨或有言语 |
| 新增 XML | **2** | **+2** | 来自 `子丑破月`，应作为伴随元数据候选处理 |
| 新增 MP4 | **114** | **+114** | 来自 `子丑破月`，尚待哈希、探测、权利与项目关系确认 |

旧基线为 21,183 个文件、3.932 TB、6,040 个视频路径；本轮新增共 116 个文件，全部位于 `子丑破月`，由 114 个 MP4 与 2 个 XML 构成。这里必须保留三个边界：

1. **本批次已经 `READY_SEALED`**，但封存清单并不等于 21,299 个路径已经全部写入 Archive v2，也不等于镜像已经完成。
2. **6,154 是视频路径数，不是独立视频资产数**；只有 SHA-256 解析后才能知道 `unique_video_assets`。
3. 路径所暗示的项目归属仍是 `candidate/probable`，不能因为字幕内容“看起来像某个项目”就自动升级为确认关系。

因此，本工程同时维护两类分母：

- 路径分母：`discovered_video_paths = 6154`，用于保证没有漏扫任何入口；
- 资产分母：`unique_video_assets`，哈希后生成，用于避免重复转码、重复 ASR 与重复字幕。

## 二、什么叫“完成”：结果不是只有“转写成功”

全量工程的第一目标是**闭合路径责任**。每条视频路径最终必须落入一个明确、可复查的 `resolved_outcome`：

| `resolved_outcome` | 含义 | 是否算路径已解决 | 是否进入 ASR 分母 |
|---|---|---:|---:|
| `transcribed` | 已生成并校验机器字幕包 | 是 | 是 |
| `existing_transcript_reused` | 已有合格字幕版本，完成关系复用 | 是 | 是 |
| `exact_duplicate_reused` | SHA-256 完全相同，复用同一资产与字幕 | 是 | 否 |
| `no_audio_stream` | 容器内无音频流 | 是 | 否 |
| `silence_only` | 有音轨但只有静音或近静音 | 是 | 否 |
| `non_speech_audio` | 只有音乐、环境声等非言语声音 | 是 | 否 |
| `rights_hold` | 权利判断不足，暂缓处理 | 是 | 否 |
| `sealed_no_asr` | 封存材料明确不允许自动转写 | 是 | 否 |
| `unsupported_codec` | 当前本地解码链不支持 | 是，但进修复队列 | 否 |
| `probe_failed` | 探测失败，需重试或人工诊断 | 是，但进修复队列 | 否 |
| `corrupt` | 文件损坏或有效数据不完整 | 是，但进隔离队列 | 否 |
| `withdrawn` | 权利人或档案责任人要求撤回 | 是 | 否 |

`NO_AUDIO`、`NON_SPEECH`、`EXACT_DUPLICATE`、`RIGHTS_HOLD`、`UNSUPPORTED/CORRUPT` 都是合法的完成状态，而不是“失败后留空”。尤其不能用空白 SRT 伪装无音轨材料已经完成。

## 三、状态机：一条视频路径怎样变成可追溯字幕

```text
DISCOVERED
→ HASH_PENDING
→ ASSET_RESOLVED
  ├─ EXACT_DUPLICATE_REUSE
  └─ UNIQUE_ASSET
→ PROBE_PENDING
  ├─ PROBE_FAILED
  ├─ UNSUPPORTED_CODEC
  ├─ NO_AUDIO
  └─ AUDIO_PRESENT
→ SPEECH_TRIAGE
  ├─ SILENCE_ONLY
  ├─ NON_SPEECH_AUDIO
  └─ SPEECH_PRESENT
→ RIGHTS_PREFLIGHT
  ├─ RIGHTS_HOLD
  ├─ SEALED_LOCAL_ONLY
  └─ LOCAL_ASR_ALLOWED
→ AUDIO_EXTRACTED_TEMP
→ ASR_RUNNING
→ MACHINE_TRANSCRIPT_COMPLETE
→ TECHNICALLY_VALIDATED
→ HUMAN_REVIEW_QUEUE
  ├─ INTERNAL_MACHINE_ONLY
  ├─ TEXT_REVIEWED
  ├─ SPEAKER_REVIEWED
  └─ PUBLICATION_APPROVED
→ ARCHIVED
→ 可选：PUBLISHED / WITHDRAWN
```

不能把这条状态机压成一个“字幕状态”字段。至少要分别保存：

- `asset_resolution_status`：路径是否解析到独立 P4-A；
- `probe_status`：容器、编解码器与音轨能否读取；
- `speech_status`：有无言语内容；
- `ai_transcription_permission`：是否允许本地机器转写；
- `transcription_status`：ASR 和技术校验进度；
- `review_status`：机器稿、文本校对、说话人确认的层级；
- `publication_status`：是否经过独立公开审批；
- `resolved_outcome`：该路径在本轮最终如何闭合。

这样才能区分“技术上可做但尚无授权”“已有机器稿但未校对”“校对过但不可公开”等完全不同的事实。

## 四、九步流水线

### 1. 批次冻结与 READY 握手

本轮 READY 握手已经完成：READY-B 相对 READY-A 在 `relative_path + bytes + mtime UTC` 上为 0 added、0 removed、0 changed，批次状态为 `READY_SEALED`。批次运行期间不接受源目录继续变化；若创作者继续拷贝，新文件进入下一批，而不是悄悄混入正在运行的清单。每批保留只读 manifest、文件大小、mtime 与源路径；任何转写产物都不得写回 `〔本地资料路径省略〕` 源树。

### 2. 哈希与资产解析

为路径计算 SHA-256，先解析为 Archive v2 的 P4-A：

- 完全相同的 SHA-256 只建立一个 `digital_assets` 记录；
- 多个原始路径写作同一资产的 location/路径证据，不复制字幕；
- 查询 Archive v2 是否已有该资产的主字幕，符合要求则复用，不重新耗算力；
- 项目名、日期、文件名和所在文件夹都不能生成稳定 ID。

### 3. 全量 `ffprobe` 与音轨枚举

对每个独立、可支持的视频资产执行只读探测，记录容器、时长、视频编码、音频流数量、每一条音频流的 stream index、codec、sample rate、channel layout、语言标签、default 标记、时长与音频指纹。不得假设“第 0 条音轨就是应该转写的主混音”。

### 4. 本地语音初筛

在本地进行静音、非言语音频、语音段落和语言候选判断。初筛只决定队列，不确认人物身份、项目归属或公开价值。音乐、掌声、环境声可成为辅助标注，但不是默认 ASR 文本。

### 5. 权利预检

先检查授权状态、可见级别和敏感性，再抽音频。`ai_transcription` 是独立许可，不可由“可以保存”“可以内部观看”或“可以公开放映”自动推导，更不能与 `ai_training`、声音克隆、人物识别和生成式使用混为一谈。

### 6. 确定性音频提取

音频只提取到独立 scratch/derivative 盘：使用固定采样率、声道策略和工具版本，记录命令、源 SHA-256、音轨索引、时间基与处理配置。scratch 是可重建的工作区，不是永久保存副本；不得在空间不足时删除源盘文件换取容量。

### 7. 本地 ASR 与说话人分段

模型、推理、VAD、语言检测和可选 diarization 全部在本地完成，**不上传云端或外部 API**。ASR 的输入键必须包括源资产 SHA-256、音轨/声道、目标语言、模型与版本、配置和流水线版本，以便幂等复跑。

### 8. 产物校验与 Archive v2 导入

校验时间码递增、片段不越界、VTT/SRT 可解析、UTF-8、JSONL schema、产物 SHA-256 与 manifest 一致；随后进行幂等导入。所有失败都有显式错误码和重试次数，不能只留下日志中的一句报错。

### 9. 人工复核与发布分离

机器稿首先是内部工作资产。文本复核、说话人确认、权利复核、隐私处理、发布审批分别签名；公开发布必须经过既有 G5/H4 门槛。机器字幕完成不等于字幕真实、不等于人物已确认，更不等于获准公开。

## 五、Archive v2：源视频、转写文本与字幕文件不是同一个对象

正确的关系是：

```text
源视频 digital_asset：P4-A-...
  ├─ transcript：P4-TX-...
  │    └─ transcript_segments：带时间码的文本片段
  └─ 字幕产物各自成为新的 digital_asset：P4-A-...
       ├─ manifest.json
       ├─ segments.jsonl
       ├─ words.jsonl（可选）
       ├─ transcript.txt
       ├─ captions.vtt
       ├─ captions.srt
       ├─ quality.json
       └─ review.tsv
```

实施规则：

1. `transcripts.asset_id` 指向**源视频资产**，不是 VTT 或 SRT 文件。
2. VTT、SRT、JSONL、TXT 是不同字节序列，分别拥有自己的 P4-A 与 SHA-256；它们不是源视频的多个 location。
3. 字幕产物可通过同一 archive item 的 `item_assets` 以 `subtitle`、`full_text`、`attachment` 等角色连接；更稳妥的未来增量迁移是增加 `transcript_artifacts` 连接表，明确 `transcript_id`、`artifact_asset_id`、`artifact_role` 与 `version`。不另建第三套字幕数据库。
4. 新转写使用 `P4-TX-<16HEX>` 一类数据库生成代码并保留既有 legacy code；不能从项目名、路径或日期拼稳定编号。
5. 已入账版本不原位覆写。换模型、修正正文或人工校对均新增 `version`；同一源资产、语言、类型和版本保持唯一，并明确 primary。
6. 转写所属项目通过源视频、archive item 与 `item_projects` 继承。源关系若是 candidate，字幕关系仍是 candidate；内容推断最多生成 machine candidate，不能自动确认。
7. 每个 P4-TX 必须能落到一个项目关系，或显式进入 `unmapped_hold`，不得项目字段空白。
8. 本机路径只进入受控 location/导入账，不序列化到 transcript 正文或公共数据库字段。

## 六、产物目录与文件格式

未经人工复核的机器稿先进入受限区；只有完成相应用途审核的版本才复制为工作或公开衍生件。项目包只保存 `transcripts.csv` 索引和关系，不复制全量字幕：

```text
07_restricted/machine-transcripts/
  <P4-A-source>/
    <language>/
      <type>/
        <P4-TX>/
          manifest.json
          segments.jsonl
          words.jsonl
          transcript.txt
          captions.vtt
          captions.srt
          quality.json
          review.tsv

03_derivatives/publication-subtitles/
  <仅存已经通过相应用途审核的字幕版本>
```

所有文本采用 UTF-8 无 BOM、LF 换行；内部时间统一为整数毫秒；每个文件都写 SHA-256。各格式的责任不能混淆：

| 文件 | 责任 |
|---|---|
| `manifest.json` | 全局来源、权利、模型、配置、音轨、时间基、版本与哈希入口 |
| `segments.jsonl` | 无损的规范片段层，保存时间码、重叠、说话人候选、置信度与审核状态 |
| `words.jsonl` | 可选词级时间码，用于精细校准，不要求所有模型都生成 |
| `captions.vtt` | 首选显示与网页交换格式 |
| `captions.srt` | 面向剪辑软件和旧播放器的兼容衍生格式 |
| `transcript.txt` | 搜索和快速阅读，不作为时间码证据 |
| `quality.json` | 技术校验、低置信区间、时间漂移与错误统计 |
| `review.tsv` | 保留不可变机器候选列，另设人工修订、身份依据、审核者与时间列 |

`manifest.json` 至少记录：`source_asset_code`、源 SHA-256、`transcript_code`、语言、类型、版本、音轨索引、声道范围、源/代理关系、模型及版本、配置摘要、pipeline 版本、开始/结束时间、转写许可、可见级别、产物哈希和 `resolved_outcome`。

`segments.jsonl` 至少记录：`sequence`、`start_ms`、`end_ms`、`speaker_label`、`text`、`language_code`、`confidence`、`speaker_attribution_source`、`review_status` 与可选 `metadata`。语言使用 BCP 47：如 `zh-Hans`、`zh-Hant`、`en`、`und`、`mul`；源音轨语言与字幕文本语言分别保存，翻译必须另建 `transcript_type: translation`。

置信度只保留模型原生含义：不同 provider 的数值不可直接横比，无数据时为 null；人工确认写入审核字段，不能把 confidence 粗暴改成 1。

## 七、说话人：先匿名分段，后证据确认

- 机器 diarization 只生成 `SPK_00`、`SPK_01` 等局部标签，不生成 PER 编号。
- `speaker_person_id` 只允许在 `manual` 或 `self_identified` 证据下写入；机器或导入候选保留为 label。
- 片段重叠在 JSONL 规范层保留。VTT/SRT 为显示需要可以展平，但不得反过来抹掉规范层的重叠事实。
- 笑声、音乐、掌声、噪声等写作 captions/metadata 候选，而不是伪装成人物发言。
- 空白和静音可成为 quality/machine annotation，不创建空 transcript。

## 八、特殊格式与棘手材料的明确处置

### BRAW

BRAW 单独成批，使用可验证的本地解码链，并完整保留 sidecar。若 ASR 实际来自代理文件，必须记录代理资产、原始 BRAW、timebase/offset 变换和至少三个锚点校验；不能把 BRAW 直接丢进通用 MP4 队列后假定时间码一致。

### AVC 与 BDM

AVC、BDM 先探测再判断：它们可能是裸码流、设备元数据、无音轨文件或当前工具不支持的容器。`no_audio_stream` 与 `unsupported_codec` 都是有效结果，不得靠改扩展名强行运行。

### 多音轨与多声道

完整枚举 stream index、codec、sample rate、channel layout、language、default、duration 和 fingerprint。默认只转写经确认的主混音，同时保存其他轨的机器检测信息。现有 transcript 唯一约束尚不足以安全表达“同一源资产、同一语言、同一类型但不同音轨”的并存版本；批量逐轨导入前应增补 `audio_stream_index`、`channel_scope` 并调整唯一性。迁移完成前，每个源资产只导入一个经确认的主混音 transcript；其他逐轨结果仅作受控 artifact，不冒充主字幕。

### 重复、近重复与不同剪辑

- SHA-256 完全相同：同一 P4-A、同一 transcript，多路径复用。
- 视频编码不同但音频指纹、时长和 timebase 对齐：必须完成音频对齐和三个锚点验证，才可生成资产特定字幕版本并记录来源变换。
- 只有固定 offset：保存变换参数并抽查开头、中段、结尾。
- 剪辑点、音轨或时长不同：重新 ASR，不能机械复制时间码。
- 既有 SRT/VTT：作为独立 P4-A 导入，attribution 标记 `imported`；它是一个历史版本，不自动成为 ground truth。
- 画面烧录字幕：OCR 是另一条 machine candidate 流水线，与声音 ASR 分开保存和比对。

### 无音轨、音乐、损坏

无音轨不生成 transcript row 或空 SRT。纯音乐/非言语音频写 `non_speech_audio`；如未来需要无障碍字幕，可人工审核后制作 `[音乐]`、`[掌声]` 等 captions 版本。损坏和探测失败进入隔离、重试与人工诊断队列，源文件保持原样。

## 九、权利、隐私与本地计算边界

新材料的保守默认值应为：

```yaml
visibility: private
authorization_status: unknown
workflow_status: draft
ai_transcription_permission: pending
ai_training_permission: no
```

机器转写会把原本难以检索的声音变成可全文搜索的文本，因此字幕产物的权限不得低于源材料，原则上应与源相同或更严格。以下内容默认进入 `sensitive`、`sealed_local_only` 或 `rights_hold`：聊天室、监控画面、私人访谈、未成年人、身份证件、联系方式、健康和亲密信息，以及权利不明的第三方电影、音乐和歌词。

本流水线只授权**本地转写**：不上传云端，不调用外部识别服务，不进行人脸或声纹身份识别，不用于 AI 训练、声音克隆或生成式再利用。公开文本必须另做隐私、版权、署名和撤回机制审查；机器稿永远不能默认公开。

## 十、批次、幂等与算力排兵

批次操作标签采用：

```text
p4-YYYYMMDD-transcript-<project-or-scope>-NN
```

按项目候选、权利等级、编码类型和语言分组，而不是把 6,154 个路径一次性投入同一个进程。建议：

- 试点批次：最多 20 个独立资产或 10 小时音频；
- 稳定批次：最多 100 个独立资产或 50 小时音频；
- BRAW、超大文件、多音轨和敏感材料各自独立批次；
- 每批都要能暂停、恢复、回滚导入，并进行至少一次产物恢复测试。

幂等键应由下列字段计算：

```text
source_sha256
+ audio_stream_index
+ channel_scope
+ target_language
+ model_provider/model_version
+ config_hash
+ pipeline_version
```

同一键重复运行只返回既有 job/产物，不重复创造字幕记录。最终不可变导入账可沿用已批准的 `P4-DIALOGUE-*` 批次账口径；日常 processing job 与最终归档账应区分。

## 十一、首轮试点：单件链路已经跑通，仍需完成分层试点

当前已有一项可核查的执行成果：《冰山》`DJI_0016.MP4` 已完成**本地双引擎试点**，最终资产 location 为 `loc-ee88bbc8ebabdb0a518c`。这证明“本地读取 → 双引擎识别 → 结果汇合 → location 落账”的最小链路可以运行；但一个成功样本不能代表 20 资产试点已经验收，也不能代表 BRAW、多音轨、重复、无音轨、敏感材料和既有字幕等分支已经覆盖。

随后已建立正式任务账`p4-20260713-video-asr-01`，并以`p4_local_asr_pipeline.py 2026-07-13.2`完成一个**20路径技术canary**。这20条按manifest顺序取样，不能冒充跨项目分层样本：单worker `ffprobe`在约30秒内完成，18条识别为单音轨可转写媒体，2条因`moov atom not found`进入`PROBE_FAILED`；在批次权限文件未应用前，18条全部保持`RIGHTS_HOLD`，证明权限门不会把“技术可转写”直接写成“已获准”。

Owner的本批`LOCAL_ASR_ALLOWED`决定经batch、snapshot、manifest SHA-256、源根、输出分级与文件哈希校验后，MLX正式队列又完成1条61.61秒素材：`loc-212caca9544144ca1e5b`，结果`TRANSCRIBED`。本次从源SHA-256、音频提取到冷启动推理的总耗时79.885秒，RTF 1.2966；5项规范字幕产物和`done.json`哈希一致，JSON／JSONL严格可解析，scratch清零，权限为`0600`，状态仍是`restricted / machine_unreviewed / public=no`。它与早期《冰山》试点合计构成2条真实ASR样本，但仍不足以外推全库准确率或总工期。当前canary任务账还保留17条`READY_FOR_ASR`与2条`PROBE_FAILED`，在全量镜像完成前不继续制造I/O竞争。

下一步仍须把首批扩展到 20 个独立资产，覆盖以下十种情况：

1. 《冰山》当前目录中的 6 个视频样本，但必须先查询 Archive v2，避免重做既有字幕；
2. 一个完全重复路径组；
3. 一个视频编码不同、音频及时基相同的近重复组；
4. 一个无音轨视频；
5. 一个音乐或环境声为主的视频；
6. 一个多人抢话和重叠明显的视频；
7. 一个多音轨视频；
8. 一个聊天室、监控或私密材料，只做封存/权利决策，不输出公开稿；
9. 一个 BRAW 或其代理链样本；
10. 一个已有 SRT/VTT 的视频，用于测试版本与来源关系。

从中抽取 60 至 90 分钟制作人工参考稿，用 CER、专名错误率、时间漂移、重叠语音、远场语音和处理成本比较本地模型。试点不发布。通过后按既有归档优先级推进：《冰山》→ 实像 →《致幻》→《影子对位法》，再进入《茧房》等后续项目；优先级可因权利状态调整，但必须留变更理由。

完整试点验收的最低条件：

- 100% 入选路径完成 SHA-256、probe 和 `resolved_outcome`；
- 100% 产物有 SHA-256，并通过格式校验；
- 源盘修改数为 0，外部上传数为 0；
- 完成一次从备份恢复字幕包的演练；
- 未经人工审批的公开字幕数为 0。

## 十二、KPI：不拿“生成了多少 SRT”冒充完成度

### 分母

```text
discovered_video_paths = 6154
unique_video_assets = 哈希后确定
audio_bearing_assets = probe 后确定
speech_bearing_assets = 本地语音初筛后确定
local_asr_allowed_assets = 权利预检后确定
```

### 覆盖率

- 路径闭合率 = 有 `resolved_outcome` 的视频路径 / 6,154；
- 独立资产解析率 = 已绑定 P4-A 的独立资产 / `unique_video_assets`；
- probe 覆盖率 = 已探测独立资产 / `unique_video_assets`；
- 精确重复复用率与避免重复计算时长；
- ASR 资产覆盖率 = 已完成合格机器字幕的资产 / `local_asr_allowed_assets`；
- ASR 音频小时覆盖率；
- 字幕包技术校验通过率；
- 项目已连接率与 `unmapped_hold` 数量；
- 文本复核率、说话人复核率、发布审批率；
- probe/ASR 失败率、重试成功率与积压时长。

### 质量

- 分层抽样 CER；
- 人名、地名、项目名等专名错误率；
- 时间戳漂移 P95；
- 低置信分钟数及其人工抽查通过率；
- JSONL、VTT、SRT 片段一致性；
- 有 SHA-256 的产物比例；
- 随机恢复测试成功率。

### 必须长期保持为零的指标

- 源材料被流水线改写：**0**；
- 原始声音或视频上传外部服务：**0**；
- 完全重复资产造成的重复 ASR：**0**；
- 未复核机器稿公开发布：**0**。

`no_audio_stream`、`silence_only`、`non_speech_audio`、精确重复和权利暂缓都计入路径闭合率，但不进入 ASR 应完成分母。这样，“全量”才是一套对每条材料负责的档案制度，而不是一场以字幕数量为指标的算力表演。

## 十三、执行看板：四个硬门槛的当前完成度

| 硬门槛 | 当前状态 | 已验证事实 | 下一动作 |
|---|---|---|---|
| 封存可验证 manifest | **已完成** | READY-B 相对 READY-A 为 0 added、0 removed、0 changed；批次 `READY_SEALED`；权威清单为 21,299 文件、529 目录、4,419,913,652,206 B、6,154 视频路径 | 保持源盘只读；任何新增材料进入新批次 |
| 20路径技术canary | **已完成** | 20条完成单worker probe：18条单音轨、2条`moov atom not found`；权限文件应用后1条正式MLX机器稿成功，产物严格解析与哈希通过，scratch为0 | 保留技术证据；不把顺序样本写成分层质量样本 |
| 20资产分层试点 | **执行中** | 现有2条真实ASR样本：《冰山》双引擎试点与正式队列1条MLX样本 | 镜像完成后补齐跨项目、重复、无音轨、非语音、多音轨、BRAW、敏感和既有字幕分支 |
| 多音轨 schema | **部分完成** | probe任务账已记录`audio_stream_count/index`并把多音轨阻断，不会盲选；Archive v2尚未导入 | 增加人工主音轨选择、`channel_scope`、多字幕关系与唯一性迁移 |
| 独立实体镜像 | **已恢复推进、未完成** | 既有10,245个final复核完成后，新复制阶段累计298件／256,734,203,383 B且零SHA冲突；09:16与09:31两次无进度后09:45安全封停。09:47只读诊断发现两个非本批全树宽扫造成明确I/O争用；只终止对应进程组并静置后，09:50完整重验恢复门并启动PID 30509／会话`20260714T095042Z-2286a6abafee`，已越过此前4.56 GB项并持续产生SHA一致事件 | 继续观察恢复吞吐；禁止同机箱额外媒体／全树扫描。仍须完成21,299件与terminal receipt，且不把宽扫写成唯一根因或硬件无故障证明 |

镜像未完成之前，不能宣称 12TMAC02 已经形成完整保护副本；单件 ASR 成功也不能把未处理路径标成 `transcribed`。当前规模化执行的正确顺序是：先让镜像和校验闭合，再按批次推进哈希、probe、语音判断、权利预检与本地 ASR，最终保证**全部 6,154 个视频路径都有 `resolved_outcome`**。其中无音轨、纯音乐、精确重复、权利暂缓、损坏或不支持的路径可以得到合法的非字幕结论；全路径闭合从来不等于每条路径都必须产生语音字幕。

当四个门槛全部闭合后，字幕工程才从已启动的执行链路升级为 P4 的长期档案基础设施：每一份机器文本知道自己从哪一段声音来、使用了什么模型、能被谁看到、属于哪个版本、与哪个项目有何种证据关系，并且在错误、争议与撤回发生时，可以沿着关系账精确纠正，而不伤害原件。

## 十四、自动接力器：镜像完成后先全量probe，不盲跑全量ASR

`com.p4.archive.postmirrorprobe.ready01`最初加载的v2026-07-14.2已经在2026-07-14约05:00 UTC由一次受控`bootout/bootstrap`替换；固定工具为`p4_post_mirror_probe_runner.py 2026-07-14.4`，SHA-256为`58be4336b6766e676275fd1e1bdd11495793a66997740f6be8c855f7560b067f`。现有plist传入`--poll-seconds 300`，部署effective config SHA-256为`b22d3d8261191e1af1f8df9041d533d7509df27c182901affd515610c95cbda9`。它在09:45 UTC故障保持时曾为避免误接力而unload；09:54Z镜像恢复稳定产生SHA一致事件后重新bootstrap为PID 34666，当前仍为`waiting / wait_for_mirror`、`last_error=null`。只有镜像取得成功终态并同时满足以下条件才可接力：

1. 最新镜像session以`complete=true`结束，launchd进程停止且镜像flock释放；
2. 同一session的JSON／CSV receipt与21,299行、4,419,913,652,206 B和源—目标SHA全部一致；
3. 两块卷UUID、manifest SHA、工具SHA、精确漂移许可与源树“probe前两遍＋report后一遍”元数据门都未漂移；
4. 目标盘仍保有1.5 TB以上可用空间。

过门后它依次生成final fixity五件套、把现有20条队列幂等扩展到6,154条、用4个worker做全量`ffprobe`、导出状态与CSV。运行器对ASR子命令的白名单只有`init / probe / status / export-queue`，代码和参数层均拒绝`run`及`--execute`；因此它能自动把“这些文件究竟能不能读、有几条音轨”闭合，不会跳过重复复用、语音判断、20资产质量试点和人工抽审直接制造数千份低质量字幕。

对现有ASR脚本的二次审查确认：它已具备逐件恢复、单GPU工作、权限门和原子产物写入，但尚未实现精确SHA字幕复用、内嵌字幕复用和多音轨主轨选择；此外，断电恰好发生在稳定产物已写入而`done.json`未提交的窗口时，下次执行会以`OUTPUT_CONFLICT`停队。因此目前**有意不挂载无人值守的全量`run --execute`**：先用全量probe得到时长、音轨和异常分布，再生成确定性去重／例外计划，修复中断恢复窗口，完成20资产分层质量门后才分批运行。这不是缩小“全量”目标，而是避免把重复文件、空字幕、错音轨和不可恢复中断写成假的完成数。

为降低同一ACASIS外置机箱中源—目标双盘的Spotlight随机读竞争，`12TMAC02`索引仍为disabled，`12TMAC01`为enabled。09:45 UTC进入故障保持时，独立标签`com.p4.archive.spotlightrestore.ready01`曾先于post-mirror runner卸载；09:54Z已重新bootstrap为PID 34668，但只等待镜像成功终态，当前不会提前改变索引状态。这一临时状态不改写`〔本地资料路径省略〕`的任何文件，也不是硬盘健康判断。

2026-07-14另建立Codex心跳监督`P4 素材归档监督`（automation id `p4-2`），每15分钟复核launchd状态、卷UUID、progress/receipt/status/log与1.5 TB保留线。第一次持续无进度后曾在全部恢复门通过时使用既有`--resume`；第二次同型无进度复发后，09:45策略升级为incident hold。该hold仅在09:47发现并移除两个非本批宽扫、磁盘静置两分钟这一明确外部状态变化后解除，且09:50重新通过UUID、manifest、源边界、flock、partial归属与容量门。监督不得改写源盘、不得增加同机箱媒体扫描，也不得绕过去重、音轨、质量与中断恢复门盲跑bulk ASR。若再次异常停止，仍须fail-closed重新判断，不自动循环resume。

## 十五、19:12 UTC SHA-256冲突与安全暂停

2026-07-13 19:12:55 UTC，镜像脚本在`3P/小视频/HF_2021_06_12_18_44_32.mp4`的同名`.p4mirror.partial`发布前重读中发现源—目标SHA-256不一致。该件为742,315,576 B；脚本以`safety_or_integrity_error`和exit 2结束，未将partial原子改名为final，也未覆写既有final。当时session在冲突前报告481件／191,710,070,339 B新复制完成，全局append-only账中已有502件／196,799,232,165 B的`copied`事件。

因submitted launchd带`keepalive`，该job在19:12:57 UTC自动重启并从头重验已有final。监督器识别出校验冲突后于19:25 UTC移除`com.p4.archive.mirror.ready01`，防止在未诊断前循环截断partial和重读约200 GB既有镜像。被移除进程在内核`U`型I/O等待返回后已退出，mirror flock可非阻塞获取；两卷UUID、manifest SHA与1.5 TB保留线均再验通过。IORegistry报告源—目标物理盘的read/write error与retry计数均0；这只说明底层未报错，不能消解本次字节级不一致。

定向诊断对源文件和错误partial各做两遍哈希：源两遍均为`95c5a7e8736a26358bf111853db9db7f2deaa0e5b2223f3b97288037969312d1`，partial两遍均为`46ad3300d244ef7b01403621e667be1ce1d96859aba9586dc28c102855ac66d5`，两者fingerprint均稳定。字节比较将差异锁定在第73个1 MiB块，绝对偏移76,554,724至77,594,623，该块有1,035,486个不同字节；其余91 MiB块全部一致。随后执行一次受控诊断重拷贝，复制过程源哈希与目标连续两遍重读哈希均等于上述源哈希，表明错误可由安全重拷贝避免，但原因仍只能记为“一次局部传输／写入异常，底层未报错”而不是已确认硬件故障。

错误partial已从payload原子移到`99_system/integrity-diagnostics/20260713T191255Z-HF_2021_06_12_18_44_32/mismatched-original.p4mirror.partial`，诊断重拷贝、`incident.json`和`diagnostic-result.json`同目录保存。镜像已改为`KeepAlive=false`的持久LaunchAgent，于19:41:01 UTC以session `20260713T194101Z-5dd835e4d1c4`恢复，已开始重验既有final；若再发生任何integrity error，job会停留供诊断，不再自动循环。post-mirror probe和Spotlight恢复器也已重启为waiting；Spotlight恢复脚本同时加入了`mdutil -s`双卷结果复验，不再将“命令返回0但输出报错”记成completed。

19:41 UTC恢复会话完成了502件既有final的逐件SHA-256重验。21:13:07 UTC它重新复制原冲突文件，21:13:20 UTC以源—目标同为`95c5a7e8736a26358bf111853db9db7f2deaa0e5b2223f3b97288037969312d1`的`copied`事件原子发布final，随后已继续越过该路径复制新文件。21:21 UTC全局进度为554件／226,907,299,817 B，本恢复会话在重验502件后新复制52件，`run_stopping=0`。因此可将“本次冲突的安全恢复”标记为已验证，但全批镜像和终态fixity仍未完成。

## 十六、02:52 UTC封存后增量与固定manifest恢复

2026-07-14 02:52:40 UTC，心跳监督发现`〔本地资料路径省略〕`根目录fingerprint从封存时的`dev=16777254 / inode=135488 / mtime=ctime=1783957313`变为`mtime=ctime=1783997082`。这构成源树封存边界漂移。监督器没有把“镜像仍能读”当成安全证明，而是立即向PID 5492发送`SIGTERM`；进程约2秒后退出，flock释放，既有final未被覆盖，正在复制的`HF_2020_12_19_12_54_41.mp4`只留下由既有`copy_started`事件证明归属的260,046,848 B partial。

为避免再次扫描整套媒体，只对根层、发生mtime变化的父目录与manifest做浅层集合比较。结果定位出两个封存后对象：

- 根层新增空目录`幸福王国`；
- `王亚男 风车 TV/`新增`DJI_0298.MP4`，85,274,805 B。

两者均不在21,299行权威manifest内；根层与`王亚男 风车 TV/`在对应浅层比较中均无manifest成员消失。根`.DS_Store`的mtime／ctime发生变化，但当前源文件、镜像中既有final与早先progress记录的SHA-256仍同为`de593351c97a4ac9ee7404bc82e5ac338419974f7d7b82787de87886aec91a04`，因此这是已核实的元数据时间变化，不是内容变化。上述新增对象不得暗中进入当前批次，必须在以后重新执行READY握手时进入新批次。

监督器随后复核两卷UUID、manifest SHA、JSONL零损坏、无活动flock、partial所有权与4.78 TB左右可用空间，确认均满足既有`--resume`前置条件。事故账保存于`〔本地资料路径省略〕`，SHA-256为`8bc1e873dab2880979257a961712abaa9e7ad1b171fbe49c321f7b5e01fa6552`。02:57 UTC以LaunchAgent启动新会话`20260714T025724Z-fa8e148346ba`；首两项`.DS_Store`与`3P/.DS_Store`已获得源—目标SHA一致的`resume_verified`事件，说明固定manifest恢复链路已经重新工作。

本次处置只证明“两个新增对象被排除、已有`.DS_Store`内容未变、恢复前置条件通过”；它不把当前源根重新宣称为原始READY-B状态。新会话将继续逐件复验已有final，并在复制未完成manifest成员时做源—目标SHA-256校验。镜像后的source metadata gate还必须显式识别这份已登记的out-of-batch增量，不能静默忽略，也不能把它误并入当前6,154条视频路径分母。

镜像停止窗口内，post-mirror runner在02:56 UTC按设计把“launchd镜像未运行且progress未完成”记为`blocked`并退出；这不是新的媒体校验冲突。镜像恢复后已重新启动该runner，03:00 UTC进入`verify_manifest`且`last_error=null`，随后只会回到等待镜像终态的状态，不会触发bulk ASR。

## 十七、封存后漂移精确闸门：受控部署成功、等待镜像终态

02:52 UTC事故不能靠“忽略manifest以外对象”草率收口。当前批次新增了一份单独、SHA钉死且无通配符的许可账：

```text
wiki/meta/ledgers/p4-12tmac01-snapshots/20260713T0915-0700-ready-b/
source-drift-allowance-20260714T025240Z.json
SHA-256 = c3f88b54576f2383b39eb6863243ffeb0de2ef1146669f05dbc8cd68cf588ebc
incident SHA-256 = 8bc1e873dab2880979257a961712abaa9e7ad1b171fbe49c321f7b5e01fa6552
```

它接受的不是“这个目录以后都可以变”，而是三个封闭事实：

1. 当前精确的**非许可目录路径集**有528条，路径集摘要为`daa7a167ae076dffaa326851d4ffe521410099e8725bfac5b3485c45d1b080ae`；再加唯一获准且必须保持为空的`幸福王国`，当前总数仍为529。
2. 唯一获准的非manifest文件是`王亚男 风车 TV/DJI_0298.MP4`，只按当次记录的路径、类型、字节、inode、mode、mtime、ctime与birth time逐项比对；本许可不打开、不哈希它，也不把它加入21,299文件或6,154视频分母。
3. 根`.DS_Store`是唯一manifest元数据例外，只允许那一次mtime差异；每次过门仍须重算源文件与既有目标final，且两者都必须等于`de593351c97a4ac9ee7404bc82e5ac338419974f7d7b82787de87886aec91a04`以及terminal receipt中的同一路径SHA。

这里必须保留一条不能补造的证据边界：READY-B只保存了“含根共529个目录”的计数，没有保存当时529条目录路径身份。事故后可接受状态是“528条非许可目录＋1条已登记空目录＝529”，但现有证据**不能证明READY-B时缺席空目录的名字和身份**；“发生过移动或改名”只能作为一种可能推断，不能写成事实。以后任何新增、消失、路径集摘要变化、许可对象fingerprint变化或`.DS_Store`再次变化，都必须重新立事故账与新许可账，不能沿用本次例外。

### v4实现的闭合范围

`p4_post_mirror_probe_runner.py 2026-07-14.4`的已部署SHA-256为`58be4336b6766e676275fd1e1bdd11495793a66997740f6be8c855f7560b067f`，状态文件改为`post-mirror-probe-runner-status-v4.json`。它在真正写入fixity或队列前后增加了以下fail-closed闭包：

- **镜像终态权威**：先以最新成功`run_finished`、launchd退出与镜像flock释放作为观察，再取得镜像自己的排他flock；receipt读取前后必须是完全相同的progress设备、inode、mtime、ctime、字节前缀SHA、行数、session和终态。该flock持续持有到successor全部结束，防止新镜像会话在检查和使用之间插入。
- **receipt与final fixity同一作用域**：terminal JSON／CSV receipt须完整覆盖21,299行与4,419,913,652,206 B，逐路径源—目标SHA相等，并按manifest顺序计算全量scope摘要；final fixity五件套再以同一session和scope复验。summary、path fixity与exact-SHA duplicate导出均按固定schema、字段类型、manifest元数据和完整记录比对，完整canonical证据冲突时不得自动改名或覆盖。
- **源树精确漂移门**：使用descriptor-relative DFS，祖先目录fd保持到子树结束，拒绝symlink、特殊文件与嵌套挂载；probe前做两遍元数据扫描，report后再做一遍且摘要必须相同。manifest成员仍按路径、字节、inode、mtime与birth time比对；两个许可对象只能按精确fingerprint出现；目录按上述528路径摘要闭合。除根`.DS_Store`例外外，runner不打开源媒体正文。
- **6,154路径精确队列**：队列导出逐行绑定batch、snapshot、卷UUID、source root、location key、相对／绝对路径、字节、inode、mtime与video分类，拒绝同数替换、伪造key、路径别名、未知probe状态和`run_status=running`。probe前后`run_attempts`全作用域摘要必须不变。
- **禁止盲跑bulk ASR**：`p4_local_asr_pipeline.py 2026-07-14.1`的SHA-256为`c20a641f6ae91609f961fd476ef589201eecc2220c332181253cc31873364df5`。所有`run --execute`现在先取得`postmirror-successor.freeze.lock`再取`queue.lock`；v4在扩队、probe和最终发布全程持有同一successor freeze。runner自身的子命令白名单仍只有`init / probe / status / export-queue`，任何`run`或`--execute`都会在创建子进程前被拒绝。
- **终端证据封口**：final status与queue必须来自同一queue lock下的新鲜导出；已存在文件须与新鲜导出完全相符，新建文件在原子发布后须逐字节回读一致。最终completed前再次绑定progress、receipt、fixity五件套、status、queue、manifest、许可账、incident、两卷UUID、目标余量与runner自身SHA。

regular file在被`stat`之后发生同inode原位写入，仍存在没有FSEvents journal seal便无法彻底消除的窄观察窗；READY manifest也没有源内容SHA可供本门逐件重算。v4因此把这一点明写进状态证据，不把元数据稳定冒充内容不可变。真正的内容权威仍来自镜像逐件源—目标SHA与terminal receipt。

### 离线验证结果与证据边界

本轮只运行了临时目录测试与manifest／许可账解析，没有再次扫描`〔本地资料路径省略〕`媒体树，也没有启动probe、fixity exporter、ASR或launchd重启：

```bash
PYTHONDONTWRITEBYTECODE=1 python3 -m unittest -v \
  inspool-wiki-zh/scripts/tests/test_p4_post_mirror_probe_runner.py

Ran 17 tests ... OK
```

17项回归全部使用`TemporaryDirectory`，覆盖未知文件／目录、许可空目录非空、许可文件fingerprint变化、`.DS_Store`同尺寸错内容、等数目录替换、同数伪造queue、ASR执行命令守卫、共享freeze、receipt session与full scope、resume fixity空`event_target_bytes`、duplicate完整元数据、完整fixity不自动quarantine、summary伪造、reporting发布后替换和receipt前后progress替换。另做AST解析以及只读manifest／许可账smoke：21,299行、4,419,913,652,206 B、6,154视频、528＋1目录和上述SHA均通过；红队复核收口为`P0=0 / P1=0`。**这些测试只证明离线逻辑，不证明真实源树此刻已经通过v4门。**真实三遍source gate只会在镜像成功终态后由已部署runner执行。

### 05:00 UTC受控部署结果

2026-07-14约05:00 UTC完成了最小范围的受控部署。操作只对`com.p4.archive.postmirrorprobe.ready01`执行一次`bootout/bootstrap`；没有停止、重启或重载镜像与Spotlight恢复作业，也没有因此读取媒体正文或启动任何后继处理。部署凭据如下：

1. 旧post-mirror进程PID 96920已经退出；`post-mirror-probe-runner.lock`的inode为1778704，在重新bootstrap前确认可取得排他锁。新进程PID为89239。
2. 镜像仍为PID 92483，Spotlight恢复器仍为PID 5886；这两个PID在部署前后均未改变，说明替换范围没有越过post-mirror单一job。
3. runner版本为`2026-07-14.4`，SHA-256为`58be4336b6766e676275fd1e1bdd11495793a66997740f6be8c855f7560b067f`；被钉住的ASR pipeline SHA-256为`c20a641f6ae91609f961fd476ef589201eecc2220c332181253cc31873364df5`；漂移许可账SHA-256为`c3f88b54576f2383b39eb6863243ffeb0de2ef1146669f05dbc8cd68cf588ebc`。
4. 必须区分两种配置指纹：代码内**默认配置**使用`poll_seconds=60`，其SHA-256为`04664044f0f4b8b3e8a4967c6a11d4d0cff134667c81e5cfd3f23442dec4d53b`；现有plist实际传入`--poll-seconds 300`，所以本次部署的**effective config** SHA-256是`b22d3d8261191e1af1f8df9041d533d7509df27c182901affd515610c95cbda9`。二者不同是受允许的operator timing override，不是配置漂移。
5. 新v4 status于`2026-07-14T05:00:01Z`开始，当时为`state=waiting / phase=wait_for_mirror`、`last_error=null`；manifest、许可账和工具链的初始校验均已完成。它未取得镜像终态，因此没有提前运行final fixity、扩展6,154路径、执行全量`ffprobe`或触发bulk ASR；09:45曾因incident hold卸载，09:54Z已重新bootstrap为PID 34666并恢复`waiting / last_error=null`，后续状态见第二十节。

部署成功在当时的准确含义只是：**正确版本、正确工具链和实际effective config已经在正确的单一launchd job中等待镜像成功终态。**这份部署证据仍然有效，但job现已因故障保持而unloaded。部署不表示真实源树已经通过三遍source gate，不表示6,154条视频已经probe，更不表示READY-B时刻的位级原貌已被证明。READY manifest的逐行SHA字段原本为空；当前内容权威仍须由镜像逐件源—目标SHA、terminal receipt和后继闸门共同建立。

镜像成功结束后，应让v4自行取得terminal mirror lease，依序完成final fixity、6,154路径扩队、全量probe、报告与terminal seal；不要手工并行启动`init`、`probe`或任何`run --execute`。任一UUID、容量、progress、receipt、fixity、源树、queue或工具校验失败时保持fail-closed，保留status、日志和证据文件供复核，不得以删除canonical证据、放宽许可或绕过freeze来换取“完成”。

## 十八、08:14 UTC既有final复核完成并转入剩余对象复制

2026-07-14约08:14 UTC，恢复会话`20260714T025724Z-fa8e148346ba`完成了02:52 UTC停机前已有的10,245个final的逐件复核。每一件都重新计算当前源文件与目标final的SHA-256并取得一致结果，本轮复核为零冲突；append-only `progress.jsonl`的解析检查仍为`malformed=0`。这标志着会话从“重验既有final”转换到“复制尚未完成的manifest对象”，不是21,299件全批完成，也不是镜像terminal receipt已经生成。

停机时登记的owned partial为`天台上的嚎叫者/3P 天台山的嚎叫者/HF_2020_12_19_12_54_41.mp4.p4mirror.partial`，中断时有260,046,848 B。恢复会话在走到该路径时按既定断点安全语义写入`partial_restart`，没有把旧partial当作已验证前缀续接，而是从零重新复制；源流SHA与目标partial重读SHA一致后，脚本将其原子发布为592,220,006 B final，同名`.p4mirror.partial`随发布消失。随后镜像越过该路径继续复制未完成对象。

阶段转换后的短时观察显示：约08:14 UTC恢复会话已有至少15个新`copied`事件，稍后的同一轮观察增至18个；这些新发布件的源／目标SHA均一致。`15`与`18`只记录当时恢复会话进入新复制阶段后的动态截面，不应写成长期总数或完成率。容量门同样按时点解释：这些progress事件记录的目标可用空间约4.77 TB，`df`只读观测也约4.77 TB，均高于1.5 TB硬保留线；随着后续复制继续，余量会变化，真正约束始终是“不得跌破1.5 TB”，而不是维持某个小数。

证据措辞继续限定为**固定manifest下的 current-source verified mirror**：READY-B manifest的逐行SHA字段原本为空，所以本轮10,245件复核与随后新复制证明的是“复核／复制时当前源字节与目标字节一致”，不能倒推出每一件仍等于READY-B时刻的位级原貌。post-mirror v4 runner在这一阶段仍保持`waiting / wait_for_mirror`；尚未运行final fixity、扩展6,154路径、全量probe或bulk ASR，也不得因既有final复核完成而提前启动这些后继步骤。

## 十九、09:16—09:31 UTC持续无进度与受控恢复

2026-07-14 09:16:31Z之后，镜像会话`20260714T025724Z-fa8e148346ba`的append-only progress停在一个`copy_started`事件，至09:30:57Z约14分钟没有新增进度。对应目标partial为`天台上的嚎叫者/嚎叫者/2020 12.26/DJI_0045.MP4.p4mirror.partial`，当时大小2,065,296,234 B，同名final不存在。只读进程观察显示PID 92483处于`U`态、CPU约0.1%；`lsof`只显示它以`5r`打开该目标partial，连续12秒两次`stat`所见大小和时间均未变化。两卷仍然挂载，现有日志未发现明确的磁盘I/O错误。因此本次只登记为**持续无进度／疑似阻塞**，不把进程状态或短时静止外推为硬盘故障。

依据连续无进度停止线，09:30:57Z向旧镜像进程发送SIGTERM；进程在2秒内退出，没有强杀、拔盘或改写源树。恢复前逐项重新确认：

1. 源卷与目标卷仍以既定UUID挂载；
2. 权威manifest SHA-256仍为`2342c8514dd298da4a4302d4c188789c08ec7e0bcdee4f1006729ef6482592cd`；
3. 已登记的源树边界未再漂移；
4. 旧进程已退出且无活动mirror flock；
5. 2,065,296,234 B partial可由既有`progress.jsonl`的`copy_started`事件证明归属，具备`--resume`恢复条件，同名final仍缺失；
6. 目标卷可用空间约4.53 TB，高于1.5 TB硬保留线。

全部前置条件通过后，09:31:49Z使用既有launchd配置和同一批次`--resume`机制恢复，没有另造目标树。新镜像PID为93130，新会话为`20260714T093151Z-cb8561fc6e46`。恢复会话先对两个`.DS_Store` final完成当前源／目标SHA一致的事件，随后进入第三个约4.56 GB对象复核。这个当时截面只证明恢复会话已经启动且出现两个成功事件，**不足以声称持续吞吐已经完全恢复**；其后的无进度复发与封停见第二十节。

镜像短暂消失时，post-mirror runner按设计fail-closed退出；镜像恢复后仅对该runner做受控重启，新PID为93199。v4 status保持`waiting / wait_for_mirror`、`last_error=null`。Spotlight恢复器PID 5886在全过程未被停止或重载，目标卷Spotlight索引仍为disabled。本事件没有启动final fixity、6,154路径扩队、全量probe或bulk ASR，证据边界继续限定为固定manifest下的`current-source verified mirror`，READY-B逐行内容SHA缺失这一限制也没有改变。

## 二十、09:31—09:45 UTC持续无进度复发与故障保持

第一次受控恢复并没有形成可持续吞吐。launchd在09:31:49Z启动恢复动作后，新会话`20260714T093151Z-cb8561fc6e46`于09:31:52Z写入会话起点；它只完成了根`.DS_Store`与`3P/.DS_Store`两个既有final的当前源／目标SHA一致复核。09:31:53Z开始校验manifest第三项`3P/20200919_145015.mp4`，该文件为4,562,092,032 B。直到09:44:34Z，append-only progress再无任何新增事件；PID 93130持续处于`U`态、CPU约0，进程当时已运行约12分45秒。

这与前一轮“持续无进度／疑似阻塞”同型，因而记为**复发的持续无进度**，但仍不外推为硬盘故障：本次证据只表明同一恢复链在第三个manifest对象校验期间没有产生可观察进展，不能仅凭`U`态、零CPU或progress静止确定故障层级。09:45:06Z向PID 93130发送SIGTERM，进程约3秒后退出；没有强杀、拔盘、改写源树、删除partial或重写append-only进度账。

第二次事件后的处置不再是自动恢复，而是**incident hold／故障保持**。为避免镜像进程消失后自动触发Spotlight恢复，或让post-mirror runner误把停机窗口当作可接力终态，先卸载`com.p4.archive.spotlightrestore.ready01`，再卸载`com.p4.archive.postmirrorprobe.ready01`。最终状态为：

1. `com.p4.archive.mirror.ready01`的job定义仍loaded，但没有运行中的mirror进程；
2. `com.p4.archive.postmirrorprobe.ready01`与`com.p4.archive.spotlightrestore.ready01`均unloaded；
3. 源卷Spotlight索引为enabled，目标卷仍为disabled；
4. v4没有取得成功镜像终态，也没有运行final fixity、扩展6,154路径、全量probe或bulk ASR。

故障保持没有抹除已完成证据。前一复制阶段在会话`20260714T025724Z-fa8e148346ba`中累计发布298个新对象／256,734,203,383 B，全部记录为源／目标SHA一致，零SHA冲突；这些事件继续封存在既有`progress.jsonl`。目标卷当时约有4.53 TB可用空间，高于1.5 TB硬保留线。`天台上的嚎叫者/嚎叫者/2020 12.26/DJI_0045.MP4.p4mirror.partial`仍为2,065,296,234 B，具有先前`copy_started`事件所证明的owned partial身份，同名final缺失，因而在未来满足全部恢复门时仍可按既有语义处理；当前保持不动。

09:45Z当时的下一动作不是再次`kickstart`或`--resume`，而是等待外部状态变化或完成人工诊断；只有随后重新验证两卷UUID、manifest SHA-256、源树登记边界、无活动flock、partial可恢复性与同名final关系，以及目标空间高于1.5 TB保留线，才可重新评估同一批次恢复。该历史hold后来因09:47发现并移除非本批宽扫、磁盘静置这一明确外部状态变化而进入一次新的恢复评估；这不把复发省略为普通断点，也不授权在镜像终态之前启动全量probe或任何bulk ASR。

### 20.1 09:47—09:54 UTC：外部宽扫争用移除、重验恢复门与观察性恢复

09:47Z的只读`lsof/ps`检查发现，同一ChatGPT/Codex父进程PID 36967之下有两个不属于本批次的宽范围扫描已经运行约27—28分钟：PGID 77545的`find`从`/tmp`、`〔本地资料路径省略〕`和`〔本地资料路径省略〕`全树寻找海报；PGID 78468的`rg`扫描`〔本地资料路径省略〕`与`〔本地资料路径省略〕`寻找YouTube链接。同期`disk9`约为164—174 tps、2.3—2.4 MB/s随机读。现有证据不能证明这两个宽扫是两次停滞的唯一根因，但它们明确违反“避免对同一ACASIS机箱增加额外媒体扫描”的执行边界，并形成可观测的I/O争用。

09:47:44Z只终止上述两个进程组，没有触碰、移动、改名或删除任何数据，也没有操作镜像数据结构。随后`disk8/disk9`连续样本均为0 MB/s；QuickLook进程仍持有静态文件描述符，但观察窗口未见对应磁盘吞吐。两分钟静置构成相对于09:45 hold的明确外部状态变化，但这只说明争用条件被移除，不能由此证明硬件无故障或把全部停滞归因于宽扫。

09:50:39Z再次严格核对两卷UUID、manifest SHA-256、无活动flock、owned partial及同名final关系、目标约4.53 TB可用空间高于1.5 TB保留线、已登记源边界未再漂移，并确认没有残留宽扫。全部门通过后，09:50:40Z沿既有launchd与`--resume`语义恢复；当前镜像PID为30509，会话为`20260714T095042Z-2286a6abafee`。该会话很快越过此前停在的第三项4,562,092,032 B对象，并至少继续复核到7,218,953,892 B文件；观察期间持续写入源／目标SHA一致事件且CPU活跃。因此可记录为“在外部争用移除后恢复了可观察吞吐”，但仍须继续监督，不宣称故障根因已经唯一确定。

09:54Z重新bootstrap post-mirror v4 runner为PID 34666、Spotlight waiter为PID 34668。v4当前为`waiting / wait_for_mirror`、`last_error=null`；源卷索引仍为enabled、目标卷仍为disabled。两项后继任务只等待镜像成功终态，没有运行final fixity、扩展6,154路径、全量probe或bulk ASR。若镜像再次连续无进度、出现I/O错误、校验冲突、卷掉线、容量跌破保留线或源树再漂移，必须再次fail-closed停止破坏性动作并保留证据，不得将本次恢复变成自动重试循环。