简体中文
审查反馈
最后一个阶段把发现和验证结果变成评论。这里没有 agent:workflow 合并属于同一个问题的发现,按规则打标签、排序,workflow/report 把它们渲染成 Markdown 和 SARIF。
评论格式
每条评论都遵循 Conventional Comments:
text
<label> [decorations]: <subject>
[discussion]标签由一条发现的三个事实决定,每个事实都用已发表的尺度:
| 事实 | 尺度 | 在 eyeful 里 |
|---|---|---|
| 关于什么 | 功能性或可演化性,Mäntylä 和 Lassenius | note 是可演化性,其余是功能性 |
| 怎样检验 | 验证方法,ISO/IEC/IEEE 29148 | 证据 |
| 有多确定 | kind,SARIF 2.1.0 | 类别 |
Go 取第一条符合的。标签的名字和含义来自 Conventional Comments;哪些事实对应哪个标签,是 eyeful 自己的规则(见参考资料)。
| 标签 | 用于 | Conventional Comments 的定义 |
|---|---|---|
nitpick | 评论背后的发现全是 note | "trivial preference-based requests" |
issue | 类别为 fail 的发现 | "highlight specific problems" |
question | 给出了失败场景、但还没被证实的发现:test 或 analysis | "a potential concern but … not quite sure if it's relevant" |
suggestion | 没有场景、对照标准读出来的发现:inspection | "propose improvements" |
修饰词说明评论是否阻塞、属于哪个方面:security、correctness、design、tests、ux、readability。只有 issue 是 blocking(见一次审查)。主题和讨论是专家自己的原话,取自评论背后最严重的那条发现。
text
issue (blocking, correctness): A session is still valid at exactly expires_at.
is_expired compares with >, so a request at the expiry second is accepted. The reproduction
test below fails on this change and passes with the suggested fix.行内评论
在 pull request 上,eyeful 以事件 COMMENT 提交一条 review,从不使用 REQUEST_CHANGES 或 APPROVE。写明了文件和行、且裁判没有否定的 issue 会发在那一行上;复现通过前四道关卡的 question 也会发在那一行上,作为附上失败测试、交给作者确认的问题。其余 question、suggestion 和 nitpick 不发布,每条以完整的主题各自折叠在总结末尾。总结会数出被测试复现的发现,以及其中能阻塞合并的几条。标题先数已发布的 issue;没有时数已复现的 question,再数还需要你判断的 warning 和 error,再依次说明 CI 失败、什么都没审或审查不完整;只有审查完整、且没有待判断的发现时,才写"No issues found"。已复现但修复没验证的发现,会写明原因。总结超过 GitHub 单条评论的长度时,接着发在下一条评论里。GitHub 只接受落在它的 pull request diff 所显示的行上的行内评论,所以其他行上的 issue 会完整地放进总结。发出的评论里只有一处针对同一文件的修复时,这处修复作为 suggested change 附上。eyeful 提交状态只表示有没有发布审查,不表示改动是否正确(见审查生命周期)。
排序报告
其余内容都进入一份报告。属于同一个问题的发现会合并,评论记录有几个专家报告了它。评论按以下顺序排列:
- 是否站得住:裁判没有异议的,然后是有异议的,最后是 nitpick;
- 类别:
fail、review、open(见类别与严重度); - 报告它的专家数量;
- 标签:
issue、question、suggestion、nitpick; - 计划里的分组,然后是文件和行。
有异议的评论和 nitpick 折叠在末尾的收起区域里。没有任何内容被丢掉。报告的结尾是:
- 被拆分的改动的各个范围,以及它们的文件和发现;
- 分拣时放到一边的文件;
- 不确定性清单:缺席的专家、没能复现的发现、没有运行的命令,以及预算是否用完。
输出位置
| 输出 | 给谁 |
|---|---|
| Markdown | 终端 |
| Findings JSON | 桌面应用,显示在 diff 旁边 |
| SARIF | 其他 agent、脚本、GitHub code scanning、评估 |
| GitHub review | pull request 上的行内评论 |
| GitHub comment | 简短总结:计数、发出的发现,其余折叠 |
eyeful 状态 | 是否发布了审查,并链接到这次运行 |
发到 GitHub 的内容由审查的 job 提交,每条只发一次(见架构)。
终端里的输出
eyeful review 依次打印:
- 按类别统计的发现数量;
- 改动做了什么:规划器的摘要和分组,核心组在前;
- 被改动弄坏的测试(见回归);
- “No blocking issues”,或者按报告顺序排列的发现表:
text
| Severity | File:Line | Issue |
| ------------ | ------------------------- | ----------------------------------------- |
| 🔴 error | `app/session.py:11` | Session still valid at exactly expires_at |
| 🟠 warning | `web/src/Login.svelte:40` | The expiry is shown in UTC |- 每条发现:严重度、方面和类别,一句话摘要,失败场景,推理过程,验证方式,复现测试,以及 diff 形式的修复;
- 有异议的评论、nitpick、被放到一边的文件和不确定性清单。
每次运行都会保存 review.md、findings.json、results.sarif 和 result.json(见本地运行)。
多轮审查
再次审查是对同一对象的一次新审查:在本地,就是 .eyeful/runs 里基准提交相同、且 head 是当前 head 或其祖先的最近一次运行。在 execution 下,专家开始之前,验证器把上一次审查看到失败的每个复现各运行五次,不调用模型:
| 复现现在的情况 | 这条发现 |
|---|---|
| 每次都通过 | 已解决,列在 “Resolved since the last review” 下 |
以 fails 文本失败,且在基准提交上不失败 | 仍未解决;连同测试一起带入本次审查,并告知专家 |
| 在基准提交上以同样方式失败 | 原本就有;会报告,永不阻塞 |
| 不稳定、以别的方式失败或无法运行 | 作为未验证的评论展示,并列入不确定性清单 |
上一次审查没能复现的发现不会带过来:专家重新阅读改动。在 read_only 或 none 下什么都不带。
