feat(check): 规则检查(报价形式、形式要件、响应表),表格按单元格分行
- check/rules.py(规则集 2026.11-r1,不调模型):大小写金额、分项合计、超最高限价、 多个报价、别的项目名称、没填的地方、落款日期、投标有效期、附加条件、响应表里的未响应; 每条挂投标原文,有依据的挂招标侧出处;缺限价、截止时间、有效期要求时写进覆盖范围 - 文字层的句子带上单元格框,表格按单元格上沿分行 - 按 Fable 审读意见收紧致命级:认不准的降为重要或提示 - 评测:score.py 评规则问题;P07 注入记录改为空白处前后原文,剔除注入到人员表的 D10 - 上传页的检查范围文案同步 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -334,6 +334,8 @@ class Mutator:
|
||||
|
||||
def compliance(self) -> None:
|
||||
for t in self.tables(fixed=True):
|
||||
if not any("响应" in str(h) for h in t.get("header") or []):
|
||||
continue # 只有响应表(表头有「响应情况」栏)才注入;人员表、业绩表不是
|
||||
rows = [r for r in t["rows"] if self.free(r.get("responds") or [])]
|
||||
if not rows:
|
||||
continue
|
||||
@@ -388,7 +390,7 @@ class Mutator:
|
||||
b = self.rng.choice(paras)
|
||||
blank = self.phrase("P07", "blanks")
|
||||
b["text"] = b["text"].replace(bidder, blank, 1)
|
||||
self.rule("P07", "投标人名称空", b["text"][:24])
|
||||
self.rule("P07", "投标人名称空", blank_context(b["text"], blank))
|
||||
|
||||
def p08(self) -> None:
|
||||
signs = [b for b in self.blocks if b.get("type") == "sign"]
|
||||
@@ -423,6 +425,13 @@ class Mutator:
|
||||
self.rule("P12", text, text)
|
||||
|
||||
|
||||
def blank_context(text: str, blank: str) -> str:
|
||||
"""空白处前后的原文(不跨句号),评分时拿它对照问题的投标侧出处。"""
|
||||
i = text.index(blank)
|
||||
start = max(i - 10, max(text.rfind(x, 0, i) for x in "。;") + 1)
|
||||
return text[start : i + len(blank) + 10]
|
||||
|
||||
|
||||
def table_mode(b: dict[str, Any]) -> str:
|
||||
"""表格的响应方式:档案里表单写了 mode 的以它为准(如 S02 评分要的技术规格表是 presence,不是逐条响应的机制)。"""
|
||||
return str(b.get("mode") or ("implicit" if b.get("only_deviations") else "explicit"))
|
||||
@@ -473,7 +482,7 @@ def main() -> None:
|
||||
for f in OUT.glob(f"{tender}-*/manifest.json"):
|
||||
for uid, e in json.loads(f.read_text())["units"].items():
|
||||
if (e.get("review") or {}).get("ok") is False:
|
||||
m.rejected.add(uid) # noqa: S311 评测数据,不用于安全
|
||||
m.rejected.add(uid)
|
||||
if not a.manifest_only:
|
||||
if a.density == "high":
|
||||
m.d01_block()
|
||||
|
||||
Reference in New Issue
Block a user