world_sync/tests/checks/m11b2d_a3a1b_cmd_index_consistency.py

138 lines
6.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- 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())