声明式覆盖
章节头写了 > 覆盖条目:R-012,正文一个字没写。v1 的覆盖率算 100%,报告全绿。
COV-02 阻断。
投标失败通常不是因为写得不好,而是因为 漏了一条要求、编了一个参数、 承诺了一句不该承诺的话。v2 把这三种事故变成三门可被机器拦住的闸机: 条目化台账、零发明标记、双轨核查。
这三个问题都不是"功能不够",而是"通过得太容易"。看上去都绿了,实际上什么都没查。
章节头写了 > 覆盖条目:R-012,正文一个字没写。v1 的覆盖率算 100%,报告全绿。
COV-02 阻断。
覆盖率用 \bR-\d{3,}\b。中文算 \w,"条目R-001"匹配不到——覆盖率可能恒为 0 或恒为 100。
T01 回归用例锁死这个行为。
没装 python-docx 时返回 [跳过] 字符串,它被当作正文参与扫描。报告"正常",数据全错。
InputError + 退出码 2:宁可失败,不给假绿。
v1 不管你问什么,都跑六阶段。一句话的请求也要走完全流程——慢,且容易在无关步骤上跑偏。v2 先判断你要的是哪一种活。
"这份招标文件讲了什么?红线在哪?"
"帮我写技术标 / 商务标。"
"复核一下这版有没有坑。"
"这句话能不能写?算不算负偏离?"
与 v1 最大的差别不是"多了几步",而是每一步都有失败动作:门禁不过时,正确做法是停下来说明缺什么,而不是继续往下写。
收齐 I1–I8,跑资格符合性自检:只列缺口。
G0 · 无文件即停条目化 + 去重 + 溯源行号,产出三个基准数字。
G1 · 量级不符即补抽修 mandatory / strength,补 owner,整理澄清函。
每条要求有主应答章节;评分点有落点与证据。
G2 · 硬门禁覆盖声明 + 首段逐字回应 + 承诺分级。
脚本管形式,清单管实质;八件套齐备才算交付。
G3 · BLOCKER 清零不是"优化了一下",而是可以复现的 bug:给旧脚本同一个输入,它会给出错误的"通过"。
\bR-\d{3,}\b 匹配条目编号#投标这件事,说不清就等于没做。新增能力全部以"可被第三方复核"为标准设计。
把评分办法拆成"得分点 → 分值 → 证据 → 章节 → 把握度",一张表回答三个问题:哪些分确定拿不到、哪些分还没落点、离满分差多远。
SCORE-01 阻断SCORE-02 阻断比"凭空编造"更危险的编造变体:旧项目名、旧编号、内部用语没删干净。读起来通顺,直到资格性审查被废标。
POLL-01 阻断POLL-02 警告POLL-03 阻断validate.json:每条发现带 id、规则号、定位、证据、整改建议,直接接 CI 与台账。
禁止 / 必须 / 应 / 宜 / 可,替代 Y/N 二分——整改时先改哪条,不再靠感觉。
原文摘录 + 行号 + 版本标记。随机抽三条,30 秒内找不到原文,就是溯源不合格。
固定目录(00-输入 到 50-交付)、命名规则、Issue ID(F-001)、十节核查报告结构;外加 14 类真实异常的处理口径:扫描件、加密文件、超长标书、多版本补遗、联合体、分包、电子标 CA、涉密项目…… 每一类都明确"怎么降级、怎么标注、什么情况下必须停"。
只要 Python 3.8+。读 .docx 才需要可选的 python-docx,不装也能跑 .md / .txt。
# 一条命令把招标文件变成可勾选的台账 python scripts/extract_requirements.py --input 招标文件.md --output requirements.csv --ver v1 # 输出:原始条目 22 / 去重合并 3 / 主条目 19 / 必答 12 / 需澄清 2
# exit 0 = 通过;1 = 有阻断项;2 = 输入有问题 python scripts/validate_bid.py --bid ./20-正文 --req requirements.csv \ --map outline-map.csv --score scoring-matrix.csv \ --project "本项目名称" --project-no "KM-2026-1234" \ --report validate.json
python -m unittest discover -s tests -v ... Ran 23 tests in 1.7s OK