工程(复核纪律批·机检面): pipeline_gate 新增卡片复核判据——生效日 REVIEW_RULE_DATE=(2026,11,6) 按文件名日期挡旧卡;三条子判据=有「复核记录」节/节内每条发现记录带四类去向之一(自判·补写·待裁·退回上游)且表格行处置格非空/节末申报 reports/复核-*.md 且文件在盘可核;分流语义不判。头注与 check_cards 文档串随动(卡片口径列 C1–C6)·cross_check 注释编排五查随动。四态自证(临时卡 reports/需求卡片-闸件自检临时-2026-11-07.md 验毕已删):缺节→判据「复核记录缺失」exit 1;记录行无去向→「复核去向未标」+「复核记录空节」+「复核报告未申报」exit 1;合规节→复核类红项 0(该临时卡剩 3 红均为造件自身的 能力行/行锚/审计声明 缺项,属预期);处置空格+假报告路径→「复核处置未填」+「复核报告不可核」exit 1。存量三张卡(最新 2026-11-05)不受影响 exit=0
This commit is contained in:
1 parent
b86e0b803a
commit
121aca4073
1 file changed
+70
-2
+70
-2
@@ -5,7 +5,8 @@ r"""pipeline_gate.py — 工作流程流水线闸(待办清单条目状态机
|
||||
职责:机检待办清单条目(标题元数据与可选优先级档名/四属性齐备与旧属性名防回潮/状态词白名单/
|
||||
改动面四档白名单/条件凭据/无设计线段条目的证据指认/状态段累积制/特批/正文限长双判据/零命中)
|
||||
与 roadmap 迭代总表(六列/状态五形态/卡片与报告存在性/编入时间与预计周期的
|
||||
分档放行)/需求卡片口径(C1 文档义务/C2 设计事实源/C3 改动—验收对照表/C4 验收档申报)+一次交叉核。
|
||||
分档放行)/需求卡片口径(C1 文档义务/C2 设计事实源/C3 改动—验收对照表/C4 验收档申报/
|
||||
C5 判据出处行锚/C6 复核记录)+一次交叉核。
|
||||
约束:每红项一行「文件:行号 判据名 一句白话说明」,exit 0=全绿 / 1=有红 / 2=输入件缺失;
|
||||
卡片与报告存在性相对 --repo-root 解析(缺省=本文件上两级);待办清单与 roadmap 均已为新格式
|
||||
(2026-10-18 数据整改批),本闸已注册进 tools/run_all_gates.sh 文档域(流水线闸)。
|
||||
@@ -66,6 +67,12 @@ 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+)")
|
||||
# C6 复核记录(2026-11-05 立,生效 2026-11-06;req-card 必备结构第 17 节+纪律「复核发现四类分流」)
|
||||
REVIEW_RULE_DATE = (2026, 11, 6)
|
||||
REVIEW_HEADING_RE = re.compile(r"^#{2,4}\s*\d*\.?\s*复核记录")
|
||||
REVIEW_TARGET_WORDS = ("自判", "补写", "待裁", "退回上游")
|
||||
REVIEW_HEADER_WORDS = ("轮次", "去向")
|
||||
REVIEW_REPORT_RE = re.compile(r"reports/复核-[^\s()(),,、|]+\.md")
|
||||
# 待办条目正文限长双判据(2026-11-04 立,doc-conventions §12.1:行数抓清单蔓延、字数抓单行堆砌)
|
||||
ENTRY_MAX_LINES = 12
|
||||
ENTRY_MAX_CHARS = 700
|
||||
@@ -455,7 +462,7 @@ def cross_check(links, index, issues, where):
|
||||
|
||||
一条目可有多张已写卡分编多个迭代(状态段累积「已编迭代 40+已编迭代 41」):
|
||||
对每个已编迭代号核两件——总表该行存在;该行卡片列含本条目至少一张已写卡路径。
|
||||
哪张卡编哪个迭代的卡级映射由编排四查与人工核验,闸不猜卡级映射。
|
||||
哪张卡编哪个迭代的卡级映射由编排五查与人工核验,闸不猜卡级映射。
|
||||
"""
|
||||
for line, no, cards in links:
|
||||
row = index.get(no)
|
||||
@@ -641,6 +648,55 @@ def check_ledger(text, path, when, issues, root):
|
||||
"表内没有数据行"))
|
||||
|
||||
|
||||
def check_review(lines, start, path, issues, root):
|
||||
"""C6 复核记录的单节校验(req-card 必备结构第 17 节,生效 2026-11-06)。
|
||||
|
||||
只查结构与可核性:节内每条记录行都要带四类去向之一(自判/补写/待裁/退回上游),
|
||||
表格行的处置结果格(末格)非空;节内须申报 reports/复核-*.md 路径且该文件在盘上存在。
|
||||
分流分得对不对属语义判断,本闸不判。返回节末行下标(不含)。
|
||||
"""
|
||||
end = len(lines)
|
||||
for i in range(start + 1, len(lines)):
|
||||
if lines[i].strip().startswith("#"):
|
||||
end = i
|
||||
break
|
||||
records = 0
|
||||
for i in range(start + 1, end):
|
||||
s = lines[i].strip()
|
||||
if not s or s.startswith("|") and SEP_ROW_RE.match(s):
|
||||
continue
|
||||
is_row = s.startswith("|")
|
||||
is_bullet = bool(re.match(r"^[-*]\s+", s))
|
||||
if not (is_row or is_bullet):
|
||||
continue
|
||||
if any(mark in s for mark in REVIEW_HEADER_WORDS):
|
||||
continue
|
||||
if not any(word in s for word in REVIEW_TARGET_WORDS):
|
||||
issues.append((str(path), i + 1, "复核去向未标",
|
||||
"该条复核记录缺四类去向之一(自判/补写/待裁/退回上游)——"
|
||||
"先按 req-card「复核发现四类分流」判归属,前两类禁转成问句呈报用户"))
|
||||
continue
|
||||
if is_row:
|
||||
cells = row_cells(s)
|
||||
if not cells or not cells[-1].strip():
|
||||
issues.append((str(path), i + 1, "复核处置未填",
|
||||
"处置结果格为空——须写改了卡内哪一节、退给了哪一段、或用户裁决的结论"))
|
||||
records += 1
|
||||
if records == 0:
|
||||
issues.append((str(path), start + 1, "复核记录空节",
|
||||
"「复核记录」节内没有一条发现记录——卡片必经对抗复核并逐轮登记"))
|
||||
sec = "\n".join(lines[start:end])
|
||||
reports = REVIEW_REPORT_RE.findall(sec)
|
||||
if not reports:
|
||||
issues.append((str(path), start + 1, "复核报告未申报",
|
||||
"「复核记录」节末须申报复核报告落盘路径 reports/复核-<批名>-<日期>.md"))
|
||||
for rel in reports:
|
||||
if not (root / rel).is_file():
|
||||
issues.append((str(path), start + 1, "复核报告不可核",
|
||||
"申报的复核报告不在盘上:%s" % rel))
|
||||
return end
|
||||
|
||||
|
||||
def check_cards(root, issues):
|
||||
"""C1 文档义务口径(生效 2026-10-17)+C2 设计事实源声明(生效 2026-10-18)
|
||||
+C3 改动—验收对照表结构(生效 2026-10-21)。
|
||||
@@ -654,6 +710,8 @@ def check_cards(root, issues):
|
||||
能力行列(2026-10-29 起)既有与新增的名称都须在 game/tests/README.md 能力表在场
|
||||
(新增=写卡同批入表,test-conventions §8.3);至少一行;必填格非空;全文含「验收审计」声明。
|
||||
语义覆盖不在此判。
|
||||
C6 判据(生效 2026-11-06):有「复核记录」节;节内每条发现记录带四类去向之一
|
||||
(自判/补写/待裁/退回上游)且表格行处置格非空;节内申报 reports/复核-*.md 且文件在盘。
|
||||
"""
|
||||
dirn = root / CARD_DIR
|
||||
if not dirn.is_dir():
|
||||
@@ -680,6 +738,16 @@ def check_cards(root, issues):
|
||||
issues.append((str(path), 1, "验收档未申报",
|
||||
"须在卡片头部信息区申报「验收档:高/中/低」(2026-11-05 起,"
|
||||
"test-conventions §8.3)"))
|
||||
if when >= REVIEW_RULE_DATE:
|
||||
lines = text.splitlines()
|
||||
head = next((i for i, raw in enumerate(lines)
|
||||
if REVIEW_HEADING_RE.match(raw.strip())), None)
|
||||
if head is None:
|
||||
issues.append((str(path), 1, "复核记录缺失",
|
||||
"缺「复核记录」节——卡片必经对抗复核,逐轮发现与处置须登记在案"
|
||||
"(req-card 必备结构第 17 节,2026-11-06 起生效)"))
|
||||
else:
|
||||
check_review(lines, head, path, issues, root)
|
||||
if when < SYNC_RULE_DATE:
|
||||
continue
|
||||
in_sec = False
|
||||
|
||||
Reference in new issue
Block a user