docs(迭代周期规则批): 迭代周期三条线定型——中值精确值不取整/5–10 日常规/超 10 须带日期特批/硬下限 5、硬上限 20(特批不放行)

2026-10-21 用户裁定落地四件:
- process-conventions 四查③改「总估时三条线」(<5 不得编/5–10 直接编/超 10 呈报整批/拆批两案等裁、确认后带日期标记/>20 不得编、确认也不放行)
- doc-conventions §12.2 预计周期列改「≈N 个工作日」中值精确值形态(退役 0.5 步进周形态,1 周=5 工作日)
- roadmap 粒度句换代;迭代 31–35 五行按中值精确值改写(31≈7.5/32≈8.75/33≈13.25/34≈11 归特批/35≈15.25 个工作日)
- pipeline_gate:WEEKS_RE→PERIOD_RE;周期判据改三条线(<5 与 >20 判红、10<x≤20 须带日期特批标记、「—」历史行豁免)

变异验证 8 例(worktree 备份→sed 变异→恢复):25 带标记红(硬上限拦)/4 红(硬下限拦)/15 无标记红/15 带标记绿/20 带标记绿(边界放行)/10 无标记绿(边界不触批)/旧周形态红/标记缺日期红;恢复后全绿
This commit is contained in:
DKChan committed 2026-10-21 23:33:27 +08:00
1 parent 7280070f3d
commit c61d00b41a
4 files changed
+29 -21

No files matched your search

+21 -13
View File
@@ -4,7 +4,7 @@ r"""pipeline_gate.py — 工作流程流水线闸(待办清单条目状态机
职责:机检待办清单条目(标题元数据/属性齐备/状态词白名单/条件凭据/状态段累积制在场约束/特批/
零命中)与 roadmap 迭代总表(六列/状态四形态/卡片与报告存在性/编入时间与预计周期的
历史行「—」豁免/周期≤2 周可特批豁免/单元格白名单/零命中);「已编迭代↔已写卡段↔迭代行
历史行「—」豁免/周期三条线(<5 与 >20 判红、超 10 须带日期特批标记)/单元格白名单/零命中);「已编迭代↔已写卡段↔迭代行
卡片列」交叉核只此一处。2026-10-18 卡片冲突修订批补两条卡片机检:C1 关联文档同步面的
文档义务口径(生效 2026-10-17)、C2 设计事实源声明(生效 2026-10-18)——两条都按文件名
日期只追新规生效日之后的卡,旧卡属 git 历史留档不回头改。2026-10-21 验收闭合批补 C3:
@@ -68,7 +68,7 @@ HEADING_RE = re.compile(r"^(#{1,4})\s+")
SEP_ROW_RE = re.compile(r"^\|[\s\-|:]+$")
STATUS_COL_RE = re.compile(
r"^(待开工|进行中|已完成\(\d{4}-\d{2}-\d{2}\)|已终止\(\d{4}-\d{2}-\d{2}\))$")
WEEKS_RE = re.compile(r"^≈(\d+(?:\.\d+)?)\s*周$")
PERIOD_RE = re.compile(r"^≈(\d+(?:\.\d+)?)\s*个工作日$")
ITER_CODE_COL_RE = re.compile(r"^迭代\s*(\d+)")
@@ -304,7 +304,7 @@ def cell_shape(cell, card_col=False):
return "成段叙述(卡片列一格一行一卡,禁叙述文字)"
return None
if "。" in cell or "," in cell or len(cell) > 60:
return "成段叙述(只许路径/日期/状态词/保留字/—/≈N 周/特批标记)"
return "成段叙述(只许路径/日期/状态词/保留字/—/≈N 个工作日/特批标记)"
return None
@@ -325,7 +325,7 @@ def check_iter_table(block, issues, where, root):
if len(cells) != 6:
issues.append((where, ln, "六列数", "本行 %d 列(须恰六列)" % len(cells)))
continue
code, status, cards, date, weeks, report = cells
code, status, cards, date, period, report = cells
for ci, cell in enumerate(cells):
bad = cell_shape(cell, card_col=(ci == 2))
if bad:
@@ -347,16 +347,24 @@ def check_iter_table(block, issues, where, root):
"需求卡片列 %s 相对仓库根不存在" % part))
if date != "—" and not re.fullmatch(r"\d{4}-\d{2}-\d{2}", date):
issues.append((where, ln, "编入时间", "「%s」须为 YYYY-MM-DD(历史迭代不可考填「—」)" % date))
# 预计周期:≈N 周(N≤2);超 2 周须格内带日期特批标记(§12.2/§12.4);历史行「—」跳过
week_marks = APPROVAL_RE.findall(weeks)
week_core = APPROVAL_RE.sub("", weeks).strip()
wm = None if week_core == "—" else WEEKS_RE.match(week_core)
if week_core != "—" and wm is None:
# 预计周期:≈N 个工作日(估时中值精确值);<5/>20 硬判红(特批标记不放行);10<x≤20 须格内带日期特批标记(§12.2/§12.4);历史行「—」跳过
per_marks = APPROVAL_RE.findall(period)
per_core = APPROVAL_RE.sub("", period).strip()
pm = None if per_core == "—" else PERIOD_RE.match(per_core)
if per_core != "—" and pm is None:
issues.append((where, ln, "预计周期",
"「%s」须为「≈N 周」形态(N≤2,允许 0.5 步进;历史迭代不可考填「—」)" % weeks))
elif wm is not None and float(wm.group(1)) > 2 and not any(DATE_RE.search(mk) for mk in week_marks):
issues.append((where, ln, "预计周期",
"「%s」超 2 周且无带日期特批标记〔用户特批 YYYY-MM-DD …〕" % weeks))
"「%s」须为「≈N 个工作日」形态(精确值不取整;历史迭代不可考填「—」)" % period))
elif pm is not None:
wd = float(pm.group(1))
if wd < 5:
issues.append((where, ln, "预计周期",
"「%s」低于 5 个工作日硬下限,不得编入" % period))
elif wd > 20:
issues.append((where, ln, "预计周期",
"「%s」超过 20 个工作日硬上限,特批标记不放行,须拆批" % period))
elif wd > 10 and not any(DATE_RE.search(mk) for mk in per_marks):
issues.append((where, ln, "预计周期",
"「%s」超 10 个工作日且无带日期特批标记〔用户特批 YYYY-MM-DD …〕" % period))
# 实现报告:已完成=存在路径或退役保留字(历史报告已按「证据只留最新」退役),禁「—」
done = status_n.startswith("已完成(")
report_n = norm_parens(report)