chore(id-check): 两根护栏转报告制——编号门禁减负第一步

背景(用户裁定 2026-10-28):语义标识已是默认形态,编号体系本身不再产生价值,
而门禁每次都花时间。实测拆账:单次运行只有 1.8 s,但 近 80 笔提交里 61 笔 改了
id_registry.json / id_aliases.json / check_ids.py / docs/编号规范.md;语料共 99 族
(78 族已冻结、8 族快照、21 族未冻结),registry 87.6 KB + 别名表 187 KB。
结论:贵在养语料,不在跑检查。故先摘掉语料审计的强制面。

本笔只做第一步(①②③ 路线见 docs/编号规范.md §8.5):
- 护栏 1(可判定比例基线)与护栏 2(不可判定引用绝对数上限)改为 只打印、不影响退出码;
  输出标签由 [比例] 改 [比例·报告],越线打 [报告] 两行并指向 §8.5。
  --update-baseline 保留(只用来把当前值记成新记录基线)。
- 校验 1~6 不动:台账外新账照旧拦提交,这是本次减负的边界。
- 同步改口径文档:docs/编号规范.md §8 表与 §8.1 护栏行 + 新增 §8.5 退役路线,
  docs/门禁说明/id-check.md §1 表 + §6 限制第 7 条 + 新增 §7.6.1,AGENTS.md 门禁段,
  id_registry.json 两条 note,各加一条 2026-10-28 变更记录行。

自证(实测):
- 把 decidable_ratio_baseline 临时改 99.9、undecidable_total_ceiling 临时改 1 →
  两护栏必然越线,实跑 退出码 0,只出 [报告] 两行;字节级还原 registry 后复跑正常。
- 反向自证牙还在:往一个新文件写一个自造前缀 + 数字(让 git 看见该文件)→
  校验 1 报 1 处错误 + 增量拦截 FAIL,退出码 1。
- 全门禁:check_ids --strict 校验 1~6 无错误(可判定 87.15% / 不可判定 1033,仅报告);
  doc-links --all --sections-strict 通过(210 文档);mojibake / bom-guard /
  coding-standard / git diff --check 全 rc=0。钩子数不变(替换口径,不加不减)。
This commit is contained in:
2026-10-28 12:18:00 +08:00
parent 6daa01aea4
commit bf2a5c21b0
5 changed files with 54 additions and 24 deletions
+15 -12
View File
@@ -16,7 +16,7 @@ check_ids.py — 编号门禁(docs/编号规范.md §8 的 8 项校验)。
5 冻结前缀出现游标之外的新号 错误
6 文档内编号引用未紧邻文档名 错误
7 定义了但全库无引用(孤儿条目) 告警
8 打印「编号引用可判定比例」 每次运行,只许涨不许跌
8 打印「编号引用可判定比例」 每次运行,只报告不拦提交(2026-10-28 起)
「定义」的机械判据:**字面量出现在该族的属主登记处文档里**(不依赖表格行首这类易漂移的
形态)。因此 §5.5 的「销项 = 删行 + 清全库引用」一旦只做一半,校验 3 立刻报——这正是
@@ -27,7 +27,7 @@ check_ids.py — 编号门禁(docs/编号规范.md §8 的 8 项校验)。
构建产物。裸形盲区显式登记在 id_registry.json 的 `unmanaged_bare`,不是「检查通过」。
上线节奏(§8):默认 **warn-only**(退出码 0);`--strict` 才让校验 1~6 拦提交。
第 8 项的比例跌破基线**任何模式都失败**(它就是防回退的那根线)。
第 8 项(两根护栏)自 2026-10-28 起**只报告、不拦提交**(用户裁定);退役路线见 docs/编号规范.md §8.5。
用法(仓库根):
& '.venv\\Scripts\\python.exe' scripts/check_ids.py # warn-only 全库
@@ -35,7 +35,7 @@ check_ids.py — 编号门禁(docs/编号规范.md §8 的 8 项校验)。
& '.venv\\Scripts\\python.exe' scripts/check_ids.py --top 30 --verbose # 多打 + 修法
& '.venv\\Scripts\\python.exe' scripts/check_ids.py --update-baseline # 抬升第 8 项基线
& '.venv\\Scripts\\python.exe' scripts/check_ids.py --only 1,3,5 # 只跑部分校验
退出码:0 = 通过 / 仅告警;1 = 错误(--strict)或比例跌破基线;2 = 环境错误。
退出码:0 = 通过 / 仅告警;1 = 错误(--strict);2 = 环境错误。(比例 / 绝对数越线不再影响退出码)
"""
import argparse
@@ -660,17 +660,17 @@ class Checker(object):
dec = self.stats["decidable"]
ratio = (100.0 * dec / total) if total else 100.0
base = self.reg.get("decidable_ratio_baseline")
print("\n[比例] 校验 8 编号引用可判定 %d/%d = %.2f%%(基线 %s,容差 %.1fpp)"
print("\n[比例·报告] 校验 8 编号引用可判定 %d/%d = %.2f%%(记录基线 %s,容差 %.1fpp;只报告,不拦提交)"
% (dec, total, ratio,
"未建档" if base is None else "%.1f%%" % base, RATIO_TOL))
print(" 可判定 = 字面量落进已登记前缀族**且该族属主登记处已存在**;"
"未登记前缀、形态违规、属主登记处还是 [计划] 的都算不可判定 → 只许涨不许跌")
"未登记前缀、形态违规、属主登记处还是 [计划] 的都算不可判定(指标口径保留;自 2026-10-28 起只报告)")
# 绝对数护栏(2026-10-26 方案 B 同批加):比值会被口径稀释——**删掉一批「本可判定」
# 的引用反而让比例下跌**(清号批次实测 -0.2pp),拿比值当唯一护栏等于惩罚清号。
# 不可判定引用的**绝对数**不受稀释影响:号只许越清越少,不会因分母变小而"变多"。
und_now = total - dec
ceil_now = self.reg.get("undecidable_total_ceiling")
print(" 不可判定引用绝对数 %d 处%s(只许减不许增;比值会骗人,绝对数不会)"
print(" 不可判定引用绝对数 %d 处%s(只报告,不拦提交;比值会骗人,绝对数不会)"
% (und_now, "(未设上限)" if ceil_now is None else ",上限 %d" % ceil_now))
return ratio, errs
@@ -832,19 +832,22 @@ def main():
except OSError as exc:
print("[WARN] 无法运行追溯脚本:%s" % exc, file=sys.stderr)
# 两根护栏自 2026-10-28 起转「报告制」(用户裁定):只打印,不影响退出码。
# 理由:它们逼着每一笔提交维护 99 族语料(近 80 笔提交有 61 笔被编号体系牵连),
# 而真正防回潮的是校验 1~6 的台账外新账。退役路线见 docs/编号规范.md §8.5。
base = reg.get("decidable_ratio_baseline")
if base is not None and ratio + RATIO_TOL < base and not args.update_baseline:
print("\n[FAIL] 校验 8:可判定比例跌破基线 %.2f%% < %.2f%%(只许涨不许跌,容差 %.1fpp)"
print("\n[报告] 校验 8:可判定比例 %.2f%% 低于记录基线 %.2f%%(容差 %.1fpp)"
% (ratio, base, RATIO_TOL))
return 1
# 绝对数护栏:与比值护栏同时生效,任一越线即失败(§8.1)。
print(" 只报告、不拦提交。想把当前值记成新基线跑 --update-baseline;"
"口径见 docs/编号规范.md §8.5")
# 绝对数护栏同样转报告制(2026-10-28):越线只打印,不影响退出码。
und_now = ck.stats["refs_total"] - ck.stats["decidable"]
ceil_now = reg.get("undecidable_total_ceiling")
if ceil_now is not None and und_now > ceil_now and not args.update_baseline:
print("\n[FAIL] 校验 8:不可判定引用绝对数 %d > 上限 %d(只许减不许增,§8.1)\n"
" → 要么把新增的号登记进属主文档 / 别名表,要么别加这个号"
print("\n[报告] 校验 8:不可判定引用绝对数 %d 高于记录上限 %d(只报告、不拦提交)"
% (und_now, ceil_now))
return 1
print(" 清理方向不变:号只该越清越少;口径见 docs/编号规范.md §8.5")
if err_total:
if args.strict:
led = load_backlog()
+2 -2
View File
@@ -2215,7 +2215,7 @@
"U-RPT"
]
},
"baseline_note": "2026-10-26 方案 B 曾把比例基线由 86.6% 下调到 85.9%(转短语消掉的全是「本可判定」引用,比值被稀释而不可判定绝对数未增;理由见 docs/门禁说明/id-check.md §7.6 与 docs/编号规范.md §8.1);同批新增第二根护栏 undecidable_total_ceiling 后,本文档又瘦身了一半,删掉的多是不可判定的历史号引用,两根护栏已按 --update-baseline 重打为比例 86.0% / 绝对数 1166(都只朝好的方向动)。",
"baseline_note": "2026-10-26 方案 B 曾把比例基线由 86.6% 下调到 85.9%(转短语消掉的全是「本可判定」引用,比值被稀释而不可判定绝对数未增;理由见 docs/门禁说明/id-check.md §7.6 与 docs/编号规范.md §8.1);同批新增第二根护栏 undecidable_total_ceiling 后,本文档又瘦身了一半,删掉的多是不可判定的历史号引用,两根护栏已按 --update-baseline 重打为比例 86.0% / 绝对数 1166(都只朝好的方向动)。2026-10-28 起两根护栏只报告、不拦提交(用户裁定,退役路线见 docs/编号规范.md §8.5)。",
"undecidable_total_ceiling": 1166,
"undecidable_ceiling_note": "不可判定引用绝对数上限(refs_total - decidable),只许减不许增;--update-baseline 同步下调且拒绝上调。加它的原因:比值会被清号动作稀释,绝对数不会。"
"undecidable_ceiling_note": "不可判定引用绝对数上限(refs_total - decidable),只许减不许增;--update-baseline 同步下调且拒绝上调。加它的原因:比值会被清号动作稀释,绝对数不会。2026-10-28 起转报告制:越线只打印,不影响退出码(见 docs/编号规范.md §8.5)。"
}