工程+文档(判据出处行锚挂钩+存量清偿第一批·test oracle 项): test-conventions §8.3 立「判据出处行锚」(需求点格须带现行文档:行锚——断言预期值从规格句抄出禁反推实现)+退役对账义务+真实入口判定收窄(信号直发=接线验证不充真实入口)+§8.7 审计加判据出处核对问; capability_audit 增链式锚反向覆盖机检(80套件须被能力行承接——13链断套件补挂 9 能力行归零); pipeline_gate 增 C5 行锚格式机检(生效日 2026-11-05 按卡文件名日期分流——红证「判据出处行锚缺失」+旧卡零误伤双验); 清偿第一批=大门两分支/进档链/设置入口真输入化(emit→push_click 经 push_input 管线,open_camp_via_savesel coroutine 化补排版帧——开层同帧 rect 未排真点击落空实证修复,7 调用点 await)+README 能力行 :158 七物件接线验证降级残险登记/:159 大门行真入口换承载; 待办清单登记分期条目(28); 同区并入闸门耗时基线表(README 耗时基线节+无远端旧口径换代,--docs 已验)。验证: capability_audit --strict 绿(链断0)/pipeline_gate PASS/probe_gate --click --full 全段 PASS(ui_click_probe 问题=0)/--docs 验收通过零新增红
This commit is contained in:
1 parent
9011efc3b5
commit
aeff033e9b
11 files changed
+124
-34
No files matched your search
@@ -185,6 +185,7 @@ def capability_rows():
|
||||
def check_capability_rows(cap_tables, suites, funcs, cards):
|
||||
total = 0
|
||||
names = []
|
||||
referenced = set()
|
||||
suite_by_base = {}
|
||||
for rel in suites:
|
||||
suite_by_base.setdefault(Path(rel).name, []).append(rel)
|
||||
@@ -207,13 +208,25 @@ def check_capability_rows(cap_tables, suites, funcs, cards):
|
||||
red(README.relative_to(REPO), no, "能力行结构",
|
||||
"「%s」行格数不足或空列(%s)" % (name[:16], "/".join(empty) or "列数"))
|
||||
continue
|
||||
referenced.update(m.group(1) for m in CASE_RE.finditer(short("代表用例")))
|
||||
if "条件闸" in short("代表用例"):
|
||||
continue
|
||||
check_cases(no, name, short("代表用例"), suite_by_base, funcs, cards)
|
||||
check_entry(no, name, short("真实入口"), funcs, cards)
|
||||
if total == 0:
|
||||
selfcheck.append("能力表零数据行")
|
||||
return names
|
||||
return names, referenced
|
||||
|
||||
|
||||
def check_suite_coverage(suites, referenced):
|
||||
"""链式锚反向覆盖(test-conventions §8.3 退役对账):run_all.gd manifest 的每个套件
|
||||
必须被 ≥1 个能力行「代表用例」引用——断言(尾缀挂卡/挂套件)→套件→能力行→系统文档
|
||||
的链条中,套件未接能力行=卡片退役后验收意图断链(营地图批先例)。"""
|
||||
missing = [rel for rel in suites if Path(rel).name not in referenced]
|
||||
for rel in sorted(missing):
|
||||
red(README.relative_to(REPO), 1, "链式锚",
|
||||
"套件 %s 未被任何能力行「代表用例」引用——断言→套件→能力行→系统文档链条断环" % rel)
|
||||
return missing
|
||||
|
||||
|
||||
def check_cases(no, name, cell, suite_by_base, funcs, cards):
|
||||
@@ -323,7 +336,8 @@ def main():
|
||||
funcs = product_funcs()
|
||||
if not funcs:
|
||||
selfcheck.append("产品码零 `func`")
|
||||
names = check_capability_rows(cap_tables, suites, funcs, cards_corpus())
|
||||
names, referenced = check_capability_rows(cap_tables, suites, funcs, cards_corpus())
|
||||
missing_suites = check_suite_coverage(suites, referenced)
|
||||
check_coverage(cov_tables, names)
|
||||
|
||||
if selfcheck:
|
||||
@@ -331,9 +345,9 @@ def main():
|
||||
for s in selfcheck:
|
||||
print(" ! " + s)
|
||||
|
||||
print("| ── 能力审计:系统文档 %d 篇 · 能力行 %d · 套件 %d · 覆盖域表 %d 行 · 红项 %d"
|
||||
print("| ── 能力审计:系统文档 %d 篇 · 能力行 %d · 套件 %d · 覆盖域表 %d 行 · 链断套件 %d · 红项 %d"
|
||||
% (len(system_docs()), len(names), len(suites),
|
||||
sum(len(r) for _, r in cov_tables), len(reds)))
|
||||
sum(len(r) for _, r in cov_tables), len(missing_suites), len(reds)))
|
||||
for path, line, check, msg in reds:
|
||||
print(" ✗ [%s] %s:%d %s" % (check, path, line, msg))
|
||||
if selfcheck:
|
||||
|
||||
+25
-3
@@ -63,6 +63,9 @@ CAP_README = Path("game/tests/README.md")
|
||||
# C4 验收档申报(2026-11-04 验收强度分级批,生效 2026-11-05;test-conventions §8.3)
|
||||
GRADE_RULE_DATE = (2026, 11, 5)
|
||||
GRADE_RE = re.compile(r"验收档\s*[::]\s*[高中低]")
|
||||
# C5 判据出处行锚(2026-11-05 立;test-conventions §8.3:需求点格须带现行文档判据句锚)
|
||||
ANCHOR_RULE_DATE = (2026, 11, 5)
|
||||
ANCHOR_RE = re.compile(r"([A-Za-z0-9_\-.\\/]+\.(?:md))\s*:\s*(\d+)")
|
||||
# 待办条目正文限长双判据(2026-11-04 立,doc-conventions §12.1:行数抓清单蔓延、字数抓单行堆砌)
|
||||
ENTRY_MAX_LINES = 12
|
||||
ENTRY_MAX_CHARS = 700
|
||||
@@ -498,10 +501,19 @@ def capability_names(root):
|
||||
return names
|
||||
|
||||
|
||||
def check_ledger(text, path, when, issues, root):
|
||||
"""C3 改动—验收对照表结构检查(生效 2026-10-21)。
|
||||
def anchor_valid(root, rel, lineno):
|
||||
"""判据出处行锚有效性:文档存在且行号在行数范围内(相对仓库根解析)。"""
|
||||
p = root / rel.replace("\\", "/")
|
||||
if not p.is_file():
|
||||
return False
|
||||
return 1 <= lineno <= len(p.read_text(encoding="utf-8-sig").splitlines())
|
||||
|
||||
只查:对照表节在不在、表头有没有五个必需列、有没有数据行、必填格空不空。
|
||||
|
||||
def check_ledger(text, path, when, issues, root):
|
||||
"""C3 改动—验收对照表结构检查(生效 2026-10-21);C5 判据出处行锚(生效 2026-11-05)。
|
||||
|
||||
只查:对照表节在不在、表头有没有五个必需列、有没有数据行、必填格空不空;
|
||||
C5=生效日后需求点格须带现行文档行锚且指向存在(test-conventions §8.3)。
|
||||
不判断测试是否真的覆盖改动——那是独立验收审计的职责,机器闸不猜语义。
|
||||
"""
|
||||
lines = text.splitlines()
|
||||
@@ -614,6 +626,16 @@ def check_ledger(text, path, when, issues, root):
|
||||
issues.append((str(path), i + 1, "能力行不可核",
|
||||
"既有能力「%s」不在 game/tests/README.md 能力表"
|
||||
% cap_name[:24]))
|
||||
if when >= ANCHOR_RULE_DATE:
|
||||
point_cell = cells[idx["需求点"]] if idx.get("需求点", 99) < len(cells) else ""
|
||||
anchors = ANCHOR_RE.findall(point_cell)
|
||||
if not anchors:
|
||||
issues.append((str(path), i + 1, "判据出处行锚缺失",
|
||||
"「需求点」格须带判据出处行锚 `<现行文档相对路径>:<行号>`"
|
||||
"(2026-11-05 起,test-conventions §8.3)"))
|
||||
elif not any(anchor_valid(root, rel, int(no)) for rel, no in anchors):
|
||||
issues.append((str(path), i + 1, "判据出处行锚不可核",
|
||||
"锚指向的文档或行号不存在:%s" % point_cell[:40]))
|
||||
if rows == 0:
|
||||
issues.append((str(path), header_line, "验收对照表零行",
|
||||
"表内没有数据行"))
|
||||
|
||||
Reference in new issue
Block a user