# -*- coding: utf-8 -*- """A3a-1b 重做轮(响应 QC #6/#7 硬门禁):§8 证据索引「跑的是什么」列逐字一致性核对。 三类行的处理方式: (1) 单命令证据件:列内首反引号段以 `# CMD: ` 开头 → 与该证据文件首行去前缀后逐字比对; (2) 转录件(非单命令输出,如 a1c_damage_forensics):列内以 `# FILE: ` 声明首行原文 → 与文件首行原文逐字比对; (3) 本核对件自身(自指行):**不再无条件 SKIP-SELF**(QC #7:唯一真实漂移恰好落在自指行上, SKIP 会造成假绿)。自指行核对两件事: a. §8 自指行「跑的是什么」列引用的 CMD 是否指向本脚本当前实际路径(tests/checks/ 长期工具,脚本自身路径已知); b. 本证据件(--evidence 指定)首行 `# CMD:` 去前缀后是否等于 §8 自指行引用 —— 即「生成后二次读取 自身文件首行」的闭环比对。两项任一不符即计入「不一致」,不接受 SKIP 作为一致。 用法: 取证第一跑(证据件尚未生成): ./.venv/bin/python tests/checks/m11b2d_a3a1b_cmd_index_consistency.py \ --evidence tests/evidence/m11b2d_a3a1b_cmd_index_consistency.txt 闭环第二跑(证据件已生成,同一命令,自指闭环比对生效):同上。 退出码:无不一致行 → 0;否则 1。 """ import argparse import io import os import sys ROOT = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..")) DOC = os.path.join(ROOT, "docs/work-log-2026-09-22-m11b2d-fixture-contract.md") SELF_EVID_DEFAULT = "tests/evidence/m11b2d_a3a1b_cmd_index_consistency.txt" SELF_SCRIPT_REL = "tests/checks/m11b2d_a3a1b_cmd_index_consistency.py" SELF_CMD_BASE = "cd modules/world_sync && ./.venv/bin/python " + SELF_SCRIPT_REL def read_first(path): with io.open(path, encoding="utf-8") as f: return f.read().split("\n")[0] def check_self_row(seg, self_evidence, self_evidence_abs): """返回 (verdict, detail)。自指行不 SKIP,按 QC #7 做闭环比对。""" notes = [] bad = False if seg is None: return "不一致", ["自指行列内无 CMD 原文可核"] if not seg.startswith("# CMD: "): return "不一致", ["自指行列内首段非 # CMD(转录件写法):%r" % seg[:40]] doc_cmd = seg[len("# CMD: "):] # a. §8 自指行 CMD 必须指向本脚本当前实际路径(允许追加 --evidence 参数) ok_path = (doc_cmd == SELF_CMD_BASE or doc_cmd.startswith(SELF_CMD_BASE + " --evidence ") or doc_cmd.startswith(SELF_CMD_BASE + " ")) if not ok_path: bad = True notes.append("§8 自指行 CMD 未指向脚本实际路径 DOC=%r EXPECTED_BASE=%r" % (doc_cmd, SELF_CMD_BASE)) else: notes.append("§8 自指行 CMD 指向脚本实际路径 %s" % SELF_SCRIPT_REL) # b. 闭环比对:本核对件首行 == §8 自指行引用 if os.path.exists(self_evidence_abs): first = read_first(self_evidence_abs) if not first.startswith("# CMD: "): bad = True notes.append("本核对件首行非 `# CMD:` 原文") elif first[len("# CMD: "):] != doc_cmd: bad = True notes.append("自指闭环失败:本核对件首行 CMD 与 §8 自指行引用不一致 FILE=%r DOC=%r" % (first[len("# CMD: "):], doc_cmd)) else: notes.append("自指闭环通过:本核对件首行 `# CMD:` 去前缀后与 §8 自指行引用逐字相同") else: notes.append("本核对件尚未生成(磁盘无 %s),自指闭环比对留待生成后以同一命令第二跑完成" % self_evidence) return ("不一致 " if bad else "一致 ") + ";".join(notes), notes def main(): ap = argparse.ArgumentParser() ap.add_argument("--evidence", default=SELF_EVID_DEFAULT, help="本核对件(证据文件)路径,用于自指闭环比对") args = ap.parse_args() self_evidence = args.evidence.strip() or SELF_EVID_DEFAULT self_evidence_abs = os.path.join(ROOT, self_evidence) lines = io.open(DOC, encoding="utf-8").read().split("\n") rows = [] for ln, text in enumerate(lines, 1): t = text.strip() if not (t.startswith("| `tests/evidence/") and t.endswith("|")): continue cells = [c.strip() for c in t.strip("|").split("`")] fpath = t.strip("|").split("|")[0].strip().strip("`") if fpath == self_evidence: seg = None for c in cells[1:]: if c.strip().startswith("# CMD: ") or c.strip().startswith("# FILE: "): seg = c.strip() break verdict, _ = check_self_row(seg, self_evidence, self_evidence_abs) rows.append((ln, fpath, "自指行(本核对件自身,按 QC #7 闭环比对)", verdict)) continue seg = None for c in cells[1:]: if c.strip().startswith("# CMD: ") or c.strip().startswith("# FILE: "): seg = c.strip() break if seg is None: rows.append((ln, fpath, "列内无 CMD/FILE 原文可核", "SKIP")) continue full = os.path.join(ROOT, fpath) if not os.path.exists(full): rows.append((ln, fpath, "证据文件不存在", "FAIL")) continue first = read_first(full) if seg.startswith("# CMD: "): doc_cmd = seg[len("# CMD: "):] file_cmd = first[len("# CMD: "):] if first.startswith("# CMD: ") else "(文件首行非 # CMD:)" verdict = "一致" if doc_cmd == file_cmd else "不一致 DOC=%r FILE=%r" % (doc_cmd, file_cmd) else: # 转录件:核首行原文 verdict = "一致" if first == seg else "不一致 DOC=%r FILE=%r" % (seg, first) rows.append((ln, fpath, seg[:60] + "…", verdict)) fails = [r for r in rows if r[3].startswith("不一致") or r[3] == "FAIL"] print("SELF-SCRIPT: " + SELF_SCRIPT_REL) print("SELF-EVIDENCE: %s (exists=%s)" % (self_evidence, "yes" if os.path.exists(self_evidence_abs) else "no")) print("SELF-CMD-BASE: " + SELF_CMD_BASE) for ln, fpath, seg, verdict in rows: print(" L%-4d %-62s %s" % (ln, fpath, verdict)) print("统计:核对行 %d,一致 %d,跳过(列内无原文可核) %d,不一致 %d" % (len(rows), sum(1 for r in rows if r[3].startswith("一致")), sum(1 for r in rows if r[3] == "SKIP"), len(fails))) print("RESULT: " + ("ALL_ROWS_CONSISTENT" if not fails else "HAS_INCONSISTENT_ROWS")) return 0 if not fails else 1 if __name__ == "__main__": sys.exit(main())