fix: verdict 结构化标记 + 解析失败降级'需人工核对' - #19
Merged
Merged
Conversation
表头严重度分布之前靠正则猜报告正文, 格式稍变即误读 (把表头/枚举句数字
当计数, 真实案例正文 P0=0 却渲染 P0×2) 或读不到 (fallback 解析失败)。
mcp-server 侧:
- prompt 要求报告以严格单行 'VERDICT: P0=n P1=n P2=n MERGE=yes|no' 收尾
- _append_verdict_marker(): 自尾向头找该行, 转写成文末 HTML 注释标记
zob-verdict (GitHub 评论不渲染); 模型没按格式输出则原样返回不编造
review-gate 侧:
- parse_severity_counts 优先读 zob-verdict 标记 (全文搜索), 无标记退正文
正则兜底
- verdict_from_counts: 解析失败 → unresolved ('❓ 需人工核对') 而非误标
concerns — 假红灯曾致下游指挥 agent 停工等人工
- 评论表头三态渲染; README/模块注释同步
测试: review-gate +4 例 (标记优先/残缺回退/仅标记/unresolved 渲染) +
mcp-server +6 例 (转写/大小写/自尾向头/幂等/空安全/无行不编造)
tizerluo
added a commit
that referenced
this pull request
Aug 15, 2026
PR #18 用 zcode_pr_review 自审发现的跟进修复: - P1-1 实例互斥: checkout 发生在 bridge 侧文件锁之外, 双实例共享同一 state/clone_root 时, 第二实例 (守护进程跑长审查期间手工 --once 调试) 会在 mimosa 扫描中途换掉工作区 (TOCTOU) → 静默扫错代码。 修法: 启动时对 <state_file>.lock 非阻塞 flock, 拿不到锁 exit 2; 正常退出释放, 崩溃时 OS 自动回收。 - P2-1 checkout --force 只丢弃 tracked 改动, untracked 残留跨轮存活 (mimosa 扫工作区文件) → checkout 前补 git clean --force -d -x, clone 为 gate 专有目录, 清到严格基线。 P2-2 (README 三态 verdict) 是跨分支审查视角产物, #19 合入后自然消解。 测试: fake git 补 clean 处理; +2 例 (clean 先于 checkout / 实例锁退出码 2 且不跑审查, 释放后可续跑); 77 全绿。
PR #19 用 zcode_pr_review 自审, 报告自身即复现了 P1-1 (正文引用 zob-verdict 字样 → 幂等短路 → 真标记未追加), 据此修复: - P1-1 标记伪造链 (被审 PR 预埋标记骗表头): ① mcp-server 幂等检查改为「文末完整匹配 <!-- zob-verdict:{...} -->」, 裸串/正文引用不再抑制追加 ② 转写前对正文完整注释形态标记消毒 ([已消毒的 zob-verdict 引用]), 唯一可信来源 = 文末追加的真标记 ③ review-gate 解析只认完整注释形态 + 取最后一个匹配 (真标记恒在文末) - P2-1 标记 merge=no 时全 0 计数不给 pass (表头'可以合并'与报告结论 矛盾是 issue #16 误导残余) — verdict_from_counts 增 merge_from_marker - P2-2 超长截断日志提示尾部 VERDICT 行可能被切; README 记录评论截断 不含标记的限制 测试: review-gate +3 例 (末匹配胜出/裸串不认/merge 覆盖), mcp-server +2 例 (裸串不抑制/伪造注释被消毒); 全绿。
二轮自审发现: _RE_ZOB_MARK_ANY.sub 只在命中 VERDICT 行的分支里执行, 模型未按格式输出结论行时 (格式漂移真实存在, issue #16 起因即是) 兜底 return 原样透传 — 被审 PR 预埋的完整注释形态伪造标记直达 review-gate, '取最后一个匹配' 全信 → 伪造 pass。 - 消毒提到函数入口无条件执行 (review 已验证正则语言覆盖关系: gate 的 匹配串全部落在消毒模式内), 到达下游的完整形态标记必然出自文末追加 - 幂等改认「VERDICT 行 + 标记行」两行完整追加形态 (_ends_with_appended_marker), 正文孤立标记 (含文末裸标记) 不再抑制追加/透传 测试 +1 例 (文末裸标记无 VERDICT 行 → 消毒且不追加), 全绿。
Owner
Author
狗食审查(zcode_pr_review 自审,两轮)第一轮(8745bda):P0 × 0 / P1 × 1 / P2 × 2,报告自身即复现了 P1-1(正文引用 zob-verdict 字样 → 幂等短路 → 真标记未追加):
第二轮(7dee8a8):P0 × 0 / P1 × 1 / P2 × 4,活体验证通过(报告尾部成功带出
标记链路的两轮攻防验证了 issue #16 修复的完整性。 |
二轮自审的 4 条纵深加固建议全部落地:
- P2-2 位置契约: 结论行只认全文最后一个非空行 (prompt 规定结论收尾),
其余位置的 VERDICT 形态行一律按引用消毒 — 防'真结论之后的尾置引用
行'劫持自尾向头搜索, 也防引用行喂下游 prose 正则
- P2-1 幂等一致性: 尾置「VERDICT 行+标记行」形状对但数值不一致 →
丢弃伪造标记, 以结论行为准重写 (不再是纯形状短路)
- P2-3 正则限界: _RE_ZOB_MARK_ANY 的无界惰性量词 [^>]*? 改
[^>]{0,200}, 消除最坏 O(n²) 扫描 (MB 级构造文本可停摆单线程审查)
- P2-4 位数钳制: 全链路 (mcp 结论行/标记行 + gate 标记/prose) 统一
\d{1,9} — ≥4301 位整数串会让 Python ≥3.11 的 int() 抛 ValueError,
整次审查作废并烧满 gate 侧 5 次重审
测试: mcp 重写 1 例 (位置契约) + 新增 4 例 (尾置引用块/不一致重写/
超长数字×2), gate 新增 2 例 (超长数字标记/prose); 71+81 全绿。
Owner
Author
狗食审查第三轮(加固后终验,c24dc3d + b281052)结论:P0 × 0 / P1 × 0,可以合并。 "核心安全不变量(防伪造、防 DoS、fail-safe 方向)经推演均成立,未发现可实际利用的新引入 P0/P1。" 活体验证全链路通过:
剩余 4 条 P2 均为提示性质,不需要代码变更:① 幂等早退路径的纵深不对称(last-match 规则下正文残留对 gate 惰性)② gate 防伪造前提依赖配套 mcp-server 版本(同仓同 commit 部署即满足)③ verdict 第三态 unresolved 的下游契约说明(issue #16 的目的本身,README 已记)④ 存量 markdown 注入面(#18 P2-3 同款,已知限制)。 三轮攻防轨迹:P1 伪造链 → P1 兜底透传 → 全 P2 提示——攻击面收敛,标记链路闭环。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #16
问题
表头「严重度分布」靠正则猜审查报告正文的 P0/P1/P2 计数,报告格式稍变即误读(真实案例:正文明确「P0 × 0,✅ 可以合并」,表头却渲染「P0 × 2」——疑似把汇总表格行/枚举句的数字当成了计数)或读不到(fallback「解析失败」)。且解析失败一律按 concerns 假红灯,曾致下游指挥 agent 看到表头停工等人工。
修复
mcp-server 侧(标记的生产端):
zcode_pr_reviewprompt 要求报告以严格单行VERDICT: P0=n P1=n P2=n MERGE=yes|no收尾_append_verdict_marker():自尾向头找该行,转写成文末 HTML 注释<!-- zob-verdict:{...} -->(GitHub 评论里不渲染);模型没按格式输出则原样返回,不编造review-gate 侧(消费端):
parse_severity_counts优先全文搜索 zob-verdict 标记,无标记退回原有正文正则兜底verdict_from_counts:解析失败 →unresolved(❓ 需人工核对),不再误标 concerns测试
自证彩蛋
本 PR 合入后,review-gate 审查带 VERDICT 行的报告将直读结构化标记——修 review 工具的 PR 由 review 工具验证。