Audit batch 4: I-6 whitespace audit format, I-7 explicit non-sub2api capability gate, I-8 coord gate attribution, I-10 checked gates, I-11 gate-without-finding escalate, I-13 structured-first classification

This commit is contained in:
host committed 2026-11-04 18:02:23 +00:00
1 parent 06e4e16bbb
commit cdac8039b3
5 files changed
+959 -47

No files matched your search

+29
View File
@@ -231,9 +231,16 @@ def evaluate(state, task_id, gate_results, findings=None, fixed=None):
本轮全部门的 {门名: 是否通过},必须含全部已跑过的门;findings
为本轮确定性/主观发现;fixed 为 {finding_id: 已修复证据},调用方
以此证明上一轮 finding 已修复(无证据不得丢标准)。
注意:fixed 仅供测试/未来调用方——生产两条接线(单任务
_audit_loop_wire、协调员 _coord_audit_loop_merge)均不传
fixed,只认重报与门通过;不要顺手给生产接线加 fixed
语义,那是另一项功能。
返回决策 dict:decision 为 pass / pushback / escalate /
needs_review 之一;packet 只在 pushback 时有值;new_state 只在
pass / pushback / escalate 时有值(needs_review 不写状态)。
有失败门但无 finding 时返回 escalate(reason 为
gate_failed_without_finding),不再走到 PushbackPacket 抛
ValueError——调用方拿到的是决策,不是异常。
"""
findings = list(findings or [])
fixed = dict(fixed or {})
@@ -329,6 +336,28 @@ def evaluate(state, task_id, gate_results, findings=None, fixed=None):
# 有 finding 但门全过、finding 为空的矛盾态:门说通过、发现说有
# 问题,以 finding 为准(finding 是审计的直接证据)。
# 审计批 4(I-11):有失败门但无 finding 时,旧代码走到
# 下面 PushbackPacket 抛 ValueError(findings 为空)——
# 调用方拿到的是异常而不是决策。显式升级:门说失败、
# 发现说没问题,无法构成推回包,reason 点名缺 finding;
# 状态正常保存为 escalate(不再像异常路径那样回滚)。
# 生产两条接线实际走不到这支(单任务接线在终局非
# completed 时必有 execution_failed finding,协调员合流
# 为失败子任务必有 finding),它是直接调用方的契约修复。
# 注意 wire 层原来看到的是 evaluate_failed 升级(异常
# 转 escalate),新行为后看到的是 gate_failed_without_
# finding 升级——原因更精确,不是行为倒退。
if failed_now and not all_findings:
new_state = LoopState(
task_id, round=prev_round, passed_gates=sorted(passed_now),
criteria=new_criteria, last_decision="escalate")
return {
"decision": "escalate", "round": prev_round, "packet": None,
"new_state": new_state, "reason": "gate_failed_without_finding",
"regression": [f.to_dict() for f in regression],
"missing_gates": [], "weakened": [],
}
if prev_round >= MAX_PUSHBACKS:
new_state = LoopState(
task_id, round=prev_round, passed_gates=sorted(passed_now),