# 落库完整性核对报告 · brand-vi-appreciating-method.md 审计对象:`aesthetics/brand-vi-appreciating-method.md`(952 → 1568 行,+616) 比对基线:`/tmp/vi-agents/method-doc-v12-snapshot.md`(952 行)、`/tmp/vi-agents/DRAFT-V3.md`(678 行) 执行:只读核对,未修改仓库任何文件。 --- ## 1. 一句话结论 **可以判定为「旧内容零丢失 + 新内容完整」。** 旧文档 623 个非空行在现文件中无一缺失(多重集口径差集 = 0),V3 正文 549 行逐行零差异完整落地、13 条五字段三格全齐、无截断无重复、层级零跳级。**无阻断级发现。** 存在 2 处 `说明` 级(`/tmp` 临时路径外泄为正文引用)与 1 处 `可疑` 级(脚本留下的连续 `---` 分隔符),均不涉及内容丢失。 --- ## 2. 四张核对表 ### 表一 · 旧内容零丢失 | 项 | 检查 | 通过 | 异常 | |---|---|---|---| | 非空行多重集差集 | 623 | 623 | **0** | | difflib delete 操作块 | 0 块 | — | 0 | | difflib replace 操作块 | 1 块(16 → 1 行) | 1 | 0(判定为移动,见下) | | 文末 `## 已知限制` / `## 相关链接` | 2 | 2 | 0 | **唯一的 replace 块判定**:difflib 把 `old[594:610]` 的 16 行(`### ⚠️ 本方法自己已经犯过的错` 标题 + 12 行自伤记录表 + 第 8 条要命提示)在现文件里压成了 1 行 `---`。这是 **difflib 对大段移动的典型误判**,不是丢失:该 16 行实际位于现文件 1250–1271 行(C 段原位保留 + 新增第 13/14/15 行),且多重集差集为 0 证明每一行都还在。脚本 `land_v3.py:104` 正是把 C 段 `C = doc_lines[i_self:i_limit]` 原样搬到 V3 段之后的,属预期移动。 **判定依据强度**:不依赖 difflib 的对齐结论,另用 `Counter` 多重集差集独立复核 —— 该口径对行序与位置不敏感,只问「每一行是否还在」,比 difflib 更适合回答「有没有丢」。 ### 表二 · V3 正文落地完整性 | 项 | 检查 | 通过 | 异常 | |---|---|---|---| | 13 条编号存在且顺序 | 13 | 13 | 0(顺序与 A-1…A-4,B-1…B-6,C-1…C-2,D-1 完全一致)| | 标题重复 | 13 个编号 | 13 | 0(`##### A-1` 等无二次出现)| | 五字段(含必填「不适用的情况」)| 65 格 | 65 | 0 | | 末尾三格 | 39 格 | 39 | 0 | | V3 正文逐行比对(下沉一级后)| 549 行 | 549 | **0 差异块** | | §3 自检总表 | 在(1091 行 `#### 3.1 总表`)| 1 | 0 | | §5 未经检验清单 | 在(1216 行 `### 5.`)| 1 | 0 | | 截断检查 | 段尾 5 行 vs V3 body 尾 5 行 | 一致 | 0 | **关于 §6 的说明**:V3 的 `## 6. 引用索引` **未**进入落库正文。这是脚本 `land_v3.py:49` 的显式设计(`v_end = i6[1]`),**不是截断**。落库段收在 §5 末尾那句「凡报零,必须同时报:跑了多少份 · 读进去多少字符 · 可打印率。」,句子完整,与 §5 主题连贯。需父会话确认这是有意的(§6 是引用索引,且其 §6.4 讨论的并发变更已在脚本头部裁决)。 ### 表三 · 目录与自指一致性 | 项 | 检查 | 通过 | 异常 | |---|---|---|---| | 标题层级跳级 | 全部 90 个标题 | 全部 | **0** | | 「骨架占位」字样残留 | 1 次检索 | — | 0 | | 指向 V3 文件名的失效引用 | 2 处 | — | **2(见下)** | ### 表四 · 附录边界 | 项 | 检查 | 通过 | 异常 | |---|---|---|---| | 第 8 条 `🔴 本条判死` | 1471 行 | 1 | 0 | | 第 9 条 `🔴 本条判死` | 1485 行 | 1 | 0 | | 判死理由/降级去处齐全 | 2 | 2 | 0 | | 附录 A 说明段在十二条之前 | 1273 → 1281 | 1 | 0 | | 十二条整段完整(一…十二) | 12 | 12 | 0 | | 文末两节无截断 | 1562 / 1553 | 2 | 0 | --- ## 3. 异常分级 ### 阻断(内容丢失或截断) **无。** ### 可疑(需父会话人工判断) **可疑-1:落库段尾与 C 段之间有连续两个 `---`(行 1246、1248)** ``` 1244: > 不是「没找到」——**「零命中是工具故障」这个形状本项目已踩过三次**… 1245: > **凡报零,必须同时报:跑了多少份 · 读进去多少字符 · 可打印率。** 1246: (空) 1247: --- 1248: (空) 1249: --- 1250: ### ⚠️ 本方法自己已经犯过的错(保留不删,供追溯) ``` 成因:`land_v3.py:104` 拼 `body + "\n\n---\n\n" + C`,而 V3 body 自身末尾已带一个 `---`。渲染后成为两个相邻分隔符。**不影响内容与结构**,属排版瑕疵。 ### 说明(属预期差异) **说明-1:两处 `/tmp` 临时路径出现在面向读者的正文里** - 行 1278:`> 与 V2 的逐条关系见 /tmp/vi-agents/DRAFT-V3.md §1。`(在附录 A 说明段内,`land_v3.py:99` 硬编码) - 行 1289:`> 完整报告 /tmp/vi-agents/REPORT-ACCEPTANCE.md(440 行)。`(在十二条正文内的验收状态提示块) `/tmp` 是临时目录,会被系统清理。这两处对读者是失效链接,但**不是本次落库引入的新问题**(后者属旧文档既有内容)。是否改指仓库内路径由父会话决定。 --- ## 4. 本次核对自身的洞 **洞-1:非空行口径完全看不见空行与位置变化。** 全程用「strip 后非空」比对,代价是两件事查不出:一是**空行数量与位置的重排**(如 V3 段与 C 段之间多出的那个空行);二是**段落被并入另一段**而文字未变的情形。本次靠额外读 1240–1300 行原文才发现可疑-1 的双分隔符 —— 这是人工抽查兜住的,不是脚本查出的。 **洞-2:difflib 在「大段移动」上会给出难以判读的块。** 表一里那个 16 行 → 1 行的 replace 块,若只信 difflib 会误报为「16 行被一行 `---` 替换」= 灾难性丢失。是靠 Counter 多重集差集(位置无关口径)交叉验证才定为移动。**若只做 difflib 单口径核对,本次会得出完全相反的错误结论。** 反过来,多重集口径也有自己的洞:它对「A 行被复制成 10 份」这类重复增内容同样不敏感 —— 本次靠表二的编号重复检查补上。 **洞-3:字段检查只验「字符串出现」,不验「语义完整」。** 五字段/三格用的是子串存在性判定,一条写了一半的「不适用的情况」只要出现字段名就算通过。没有校验表格单元格是否闭合、`**` 加粗标记是否配对。 **洞-4:未验证渲染。** 本次只做文本层核对,没有跑站点构建或检查锚点跳转。行 1278 提到的 `\``DRAFT-V3.md\`` 这类代码标记内含路径,在渲染后是否产生预期链接样式未验。 --- ## 5. 会话期间文件稳定性 | 检查点 | 行数 | |---|---| | 开始 | 1568 | | 四项检查完成后复核 | 1568(md5 `c0867e33…`)| **核对期间文件未发生变化**,四张表基于同一版本。 仓库 `git status` 显示大量并发改动(其他会话所致),与本次核对无关。