feat(check): 文件要在、扫描件兜底(C10);响应方式存进清单并可改(C12)

- check/presence.py:「提供《授权委托书》」「须提交投标函」这类要求按标题里有没有这个文件名判断,不调模型。
- 扫描件兜底:要附证明材料的要求没找到、投标文件里有扫描件页时,改为提示级「可能在扫描件里,请人工核对」。
- 响应方式解析时识别、带依据句子存进 checklist.response_modes(迁移 0008);清单页显示、可改(写审计,
  重新解析不覆盖人工改过的);查标用存下来的。新接口 PUT /projects/{id}/checklist/response-modes/{category}。
- check_item_result.layer 加 presence(迁移 0007);契约同步默认接受的两种结论。

开发集 17 份:规矩投标文件的致命问题 120 → 51,致命级召回不变(22 / 32)(docs/architecture/check-eval.md §5)。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
YANG JIANKUAN
2026-11-04 15:53:45 +08:00
parent cb0c2fcafe
commit 47c6a1258e
21 changed files with 529 additions and 24 deletions

View File

@@ -1171,6 +1171,34 @@ paths:
description: '`checklist_empty` 或 `project_read_only`'
content: { application/problem+json: { schema: { $ref: '#/components/schemas/Problem' } } }
/projects/{project_id}/checklist/response-modes/{category}:
parameters:
- $ref: '#/components/parameters/ProjectId'
- name: category
in: path
required: true
schema: { type: string, enum: [technical, commercial] }
put:
tags: [checklist]
operationId: setResponseMode
summary: 改招标文件某一类要求的响应方式(C12 的人工确认点)
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [mode]
properties:
mode: { type: string, enum: [explicit, implicit] }
responses:
'200':
description: 返回清单概况
content:
application/json:
schema: { $ref: '#/components/schemas/Checklist' }
'409': { $ref: '#/components/responses/ProjectReadOnly' }
/projects/{project_id}/checklist/versions:
parameters:
- $ref: '#/components/parameters/ProjectId'
@@ -2469,6 +2497,10 @@ components:
type: object
required: [status, version_no, counts, marking_rules]
properties:
response_modes:
type: array
description: 招标文件对技术、商务要求的响应方式(C12)。识别出来的(origin = rule)可以改(origin = human,人工确认点);查标按它判没找到响应算不算问题
items: { $ref: '#/components/schemas/ResponseMode' }
status: { type: string, enum: [draft, confirmed] }
version_no: { type: integer, description: 最近一次确认的版本号;没确认过为 0 }
confirmed_by:
@@ -2863,6 +2895,25 @@ components:
oneOf:
- $ref: '#/components/schemas/Timestamp'
- type: 'null'
ResponseMode:
type: object
required: [category, mode, status, origin, citations]
properties:
category: { type: string, enum: [technical, commercial] }
mode: { type: string, enum: [explicit, implicit], description: 逐条响应 / 默认接受(只列偏离) }
status: { type: string, enum: [found, conflict, unknown], description: 写明了 / 两处写法冲突(按逐条处理)/ 没写明(按逐条处理) }
origin: { type: string, enum: [rule, human] }
citations:
type: array
items: { $ref: '#/components/schemas/Citation' }
set_by:
oneOf:
- $ref: '#/components/schemas/UserRef'
- type: 'null'
set_at:
oneOf:
- $ref: '#/components/schemas/Timestamp'
- type: 'null'
CheckItemResult:
type: object
required: [checklist_item_id, verdict, layer, evidence_status, bid_citations, detail, reused]
@@ -2871,11 +2922,12 @@ components:
title: { type: [string, 'null'] }
verdict:
type: string
enum: [responded, not_found, negative_deviation, suspected_unmet, no_value, undetermined, scanned]
enum: [responded, not_found, negative_deviation, suspected_unmet, no_value, undetermined, scanned, implicit_accepted, implicit_review]
description: |
已响应 / 未找到 / 负偏离未说明 / 疑似不满足 / 未给出具体值 / 未判定(模型漏答或暂时不可用)/ 扫描件请人工核对。
已响应 / 未找到 / 负偏离未说明 / 疑似不满足 / 未给出具体值 / 未判定(模型漏答或暂时不可用)/ 扫描件请人工核对 /
按招标文件默认接受(未列入偏离表的视为接受,不出问题)/ 默认接受的实质性要求、请人工核对(C12)。
没有校验通过的投标侧证据,不会是 responded(架构 §3.6)
layer: { type: string, enum: [deviation_table, rule_compare, model, retrieval], description: 结论来自哪一层(m3-plan §2.1) }
layer: { type: string, enum: [deviation_table, rule_compare, model, retrieval, presence], description: 结论来自哪一层(m3-plan §2.1;presence 是按文件在不在判断) }
evidence_status: { type: string, enum: [verified, unverified, none] }
reason_code: { type: [string, 'null'], description: 证据没通过、漏答、模型错误等的原因码 }
bid_citations: