# 预注册 · 处方 4 判据「`L1Fingerprint` 不得变」造故障验收

**⛔ 本文件跑前落盘，事后不改假设。** 起草时间 2026-08-26 15:xx CST
承接 [`docs/round2-status.md`](round2-status.md) §19.6 第 1 条（处方 4 未覆盖）。

被验对象：[`proposals/2026-08-24-archive-triage.md`](../proposals/2026-08-24-archive-triage.md) §5 验收表**第 3 行**

> | **L1Fingerprint** 不得变 | **逐字节相同** | ✅ 新增。删的若真是 0 引用流水账，确定性注入层结构上不该动 |

---

## 0. 起手事实（**已实测**，非假设）

### 0.1 指纹的 8 个分量（[`metrics/context-manifest.mjs:635-646`](../metrics/context-manifest.mjs#L635-L646)）

```
cwdIsWorktree · subjectSha · entry[] · hookEvents · hookScripts[]
sessionStartSha · userPromptSubmitSha · sessionStartDelivered
```

⚠️ **`cwdFacts.dirtyCount` 不在指纹里** —— 但 `sessionStartSha` 间接吃它，见 0.2。

### 0.2 `sessionStartSha` 间接吃 dirty 数（**N40 早已登记 hook 三态，但没人把它与本判据对上**）

`.claude/hooks/onboarding-checklist.sh`：
- `:82` `DIRTY_COUNT=$(git status --porcelain | wc -l)`
- `:87` `DIRTY_DESC="起手检测到 **$DIRTY_COUNT** 个未提交改动…"`
- `:92` `WORKTREE_NOTE` 内含该数字，`:98` **`$WORKTREE_NOTE` 就在注入文本末尾**
- `:32-33` `PICKUP_DISPLAY` 从 `docs/STATUS.md` 解析「固定指针」得到，**也进注入文本**

⇒ 采集器头注释 ① 已登记 **N40**「注入文本随 git 探测结果分三态」。
⇒ **缺口不是新事实，是跨文档推论没做**：已知「hook 吃 dirty」+ 已知「指纹吃 sessionStartSha」，
   从未与「删文件后指纹不得变」这条判据放在一起推一遍。

### 0.3 🔴 桶三**已被 DS 真实执行 4/5 项**（§19.6 却把处方 4 整条登记为「未覆盖」）

| 桶三对象 | 处方说 | `4a68e02d` | `c1db57b8` | 判 |
|---|---:|---:|---:|---|
| `docs/_archive/_reports` | 8 | 16 | **8** | ✅ 删 8 |
| `docs/_archive/_plans` | 7 | 9 | **2** | ✅ 删 7 |
| `docs/_archive/_design-kickoffs` | 2 | 2 | **0** | ✅ 删 2 |
| `docs/_archive/_archive` | 1 | 1 | **0** | ✅ 删 1 |
| `docs/internal/STATUS-CHANGELOG.md` | 1 | 1 | **1** | ⛔ **未删** |

删的份数与桶三清单**逐行吻合**。归因：`483e3feb` subject 逐字含「归档桶三」。

### 0.4 ⚠️ 真 pin 对比**不可归因**（§2.12 第 13 条「别把别人的账记上」）

`4a68e02d..c1db57b8` 共 **2** 个 commit，但 `483e3feb` **一个 commit 混了多份处方**
（「解闸链 fail-fast + 补两处判据缺口 + 归档桶三 + D1-D11 提炼」）。
另测：`AGENTS.md` 改 **2** 次 ⇒ `entry` 必变；`docs/STATUS.md` 改 **2** 次 ⇒ 经 pickup 指针带动 `sessionStartSha`。
✅ `onboarding-checklist.sh` / `settings.json` 改 **0** 次 ⇒ `hookScripts` 不变。

⇒ **真 pin 对比只作「判据在真实世界通不过」的旁证，⛔ 不作「删归档导致指纹变」的归因证据。**
⇒ **主证 = 变量隔离的造故障。**

---

## 1. 命题

**这条判据在它被指定用来验的动作（删桶三清单文件）下，能给出与命题相关的读数吗？**

命题（处方自己写的）= 「删的若真是 0 引用流水账，**确定性注入层结构上不该动**」。

## 2. 装置匹配性自查（**AGENTS §2.15，跑前必答**）

> 问：这个装置在故障存在与不存在时会给出不同的读数吗？

被测对象**就是判据本身**，装置 = 采集器 `context-manifest.mjs`。
⇒ 因此必须**先证采集器在同一环境重复采集给出逐字节相同的指纹**（H5），
否则任何「指纹变了」都可能是采集噪声，而非判据的属性。**H5 是其余各格的前置。**

---

## 3. 预注册假设（⛔ **事后不改**）

| # | 假设 | 预注册 |
|---|---|---|
| **H5** | **阴性对照/确定性**：同一环境连采 2 次 ⇒ 指纹逐字节相同 | **HIT** |
| **H4** | **阳性对照（证判定面非空 + 分量可分辨）**：改 `AGENTS.md` ⇒ 指纹变，且变的是 `entry` 分量 | **HIT** |
| **H1** | 删桶三剩余项（**不 commit**）⇒ `sessionStartSha` 变 ⇒ 指纹变 | **HIT** |
| **H2** | 🔴 **机制隔离（决定性）**：删 N 个桶三文件 vs 新建 N 个与归档**完全无关**的文件，若 `DIRTY_COUNT` 相同 ⇒ 注入文本逐字节相同 ⇒ **两者指纹完全相同** | **HIT** |
| **H3** | 删桶三并 **commit** ⇒ `subjectSha` 变 ⇒ 指纹变 | **HIT** |
| **H6** | **分量守恒（建设性）**：H1 态下除 `sessionStartSha` 外其余 **7** 分量全同 | **HIT** |

## 4. ⛔ 若 H1 MISS 怎么办（**先疑自己，AGENTS §2.12 推论七**）

不得直接宣布「判据其实没问题」。先查三项：
① `sessionStart.sha256` 取的是不是我以为的那串；
② hook 在 worktree 里是否走了第三态（`CLAUDE_PROJECT_DIR` 未设 / `.git` 是 file 不是 dir —— **`:81` 判的是 `-d "$CLAUDE_PROJECT_DIR/.git"`，而 worktree 的 `.git` 是 file** ⚠️ 这一条很可能触发);
③ 采集器是否真的重跑了 hook 而非用了缓存。

⚠️ **②已预见**：worktree/pin 的 `.git` 是 **file**（实测 `gitEntryKind = file`）⇒ `[ -d .git ]` **为假**
⇒ `DIRTY_COUNT` 留空 ⇒ 走**「探测失败」态**（`:85`）⇒ `WORKTREE_NOTE` **恒定非空且不含 dirty 数**。
⇒ **若如此，H1/H2 的机制换成另一条**：判据在 pin/worktree 上对 dirty **不敏感**，
但对 `subjectSha`（H3）仍必然敏感。**两种机制都要如实登记，⛔ 不许事后挑一个说「我早就想到了」。**

## 5. 结论矩阵（**跑前定死判法**）

| 读数 | 结论 |
|---|---|
| H1 ∧ H2 HIT | 判据在「删了不 commit」口径下**恒假**，且失败理由与命题无关（**分不清删归档与建无关文件**） |
| H3 HIT | 判据在「删了并 commit」口径下**恒假** —— 而处方的安全网逐字是「git 可逆」⇒ **删除必然 commit** ⇒ 这是**现实口径** |
| H6 HIT | **命题对、量具错**：确定性注入层结构确实没动，错的是判据把 `subjectSha` 焊进了比对载体 |
| H1 MISS 且 §4② 成立 | 机制改为「pin 上 dirty 不敏感」，H3 仍成立 ⇒ 结论不变但**机制叙述必须换** |

⛔ **无论哪一支，lab 只报「判据测不出它想测的东西」+ 给出可选修法方向，⛔ 不替 DS 选修法**（§19.3 第 2 条同纪律）。

## 6. 环境与不变式

- 环境名 **`wt-l1fp`** = 一次性 `git worktree` detached @ `c1db57b8`，用完 `worktree remove`
- ⛔ **不碰四个 pin**：采集器只读（`--out` 除外），对 pin 只做读取；起止各查一次 `dirty=0`
- ⛔ **不 build、不跑闸链** ⇒ `lab:E48` 的 `dist/` 维本轮不适用；但须实测采集器在**无 `node_modules`** 的新 worktree 上能跑
- 每格闭环：**先证判定面非空** → 造故障 → **⛔ 不带管道单跑取 EXIT**（`lab:N47`） → 判据 → 还原 → **证还原干净**
- 取数脚本 **fail-closed 起手**（§3.1）：⛔ 不写 `?? true` / `?? {}` 兜底（`lab:N48` 第 8 例）
- 交叉验证**换实现范式**（§2.12 推论八）：指纹比对走**采集器实跑**，⛔ 不用第二个静态解析器互相印证
