Skip to content

gate: review-gate's report rows drop a review's state, id and an empty body #2870

Open

Description

@HugoXK

Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.

Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: 9b6bdf22f96041bb8c08334b5d1f7310
Branch: dev/5-review-gate-rows
Base: 2eb9661
At: 2026-11-11T11:01:43Z

Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment.

Written-by: FlyBot Lead
Bot: FlyBot Product
Risk tier: T3 (three gate files: .github/scripts/enqueue-rules.mjs, .github/scripts/review-gate.mjs, .github/scripts/review-gate.test.mjs — all in policy/gates.json, so the pull request also needs a Policy-sign: line)

现象(三份 reports 行构造,第三份漂了)

同一段 reports 行构造在仓库里有三份:

  • .github/scripts/enqueue-guard.mjs:67
  • .github/scripts/merge-gate.mjs:224
  • .github/scripts/review-gate.mjs:610

#2092(把 review comment 那一面加进去)和 #2120(把 state 与空 body 的 review 保留)都只改了前两份,文件清单里没有 review-gate.mjs。于是第三份:

  1. 缺 id、多一个 url:review-gate.mjs:611 是 { kind: 'comment', login: c.user?.login, … association: c.author_association, url: c.html_url };另两份是 { id: c.id, kind: 'comment', … }。
  2. 丢掉空 body 的 review:review-gate.mjs:612-614 有 .filter((v) => (v.body ?? '').trim());另两份 #2119 已改成保留,注释原文:「an empty body must not drop the row — "Request changes" is the one refusal a person writes without typing」。
  3. 行里没有 state 字段:enqueue-rules.mjs:297 的 stopRequestAt() 读 String(r?.state ?? '').toUpperCase() 判 CHANGES_REQUESTED;review-gate.mjs:610-614 三行一个 state 都没有。

后果(已按实际降级,不要写大):review-gate 是 report-only(review-gate.yml 的 step continue-on-error: true,注释「the check never turns red」),所以这不是能合进去的洞,而是同一个决定、两个读者给出相反结论的报告:decide() → stopRequestAt() 在 review-gate 那一侧会答 PASS,而队列侧会 hold。

本单范围(A:只修第三份)

  • review-gate.mjs 的 reports 行补齐 id 与 state,空 body 的 review 不再被过滤掉(照 #2119 的措辞与口径);
  • 行内评论这一面要读,但只当请求、不当结论:构造 pulls/${pr}/comments 的 kind: 'review-comment' 行(与 enqueue-guard.mjs:77-79 同款),判据照 enqueue-rules.mjs:22 的 isConclusionSource = r.kind !== 'review-comment'——stopRequestAt() 因此能看见行内 stop 请求,而 PASS/CHANGES_REQUESTED 的结论仍然不来自行内评论。

红先(Chief 指定,必须这样红)

喂一条 空 body + CHANGES_REQUESTED 的 review:

  • 今天:stopRequestAt() 读不到 state(因为它没有这个字段),review-gate 侧答 PASS ⇒ 新断言红;
  • 修好后:stopRequestAt() 读到 state: 'CHANGES_REQUESTED' 并给出 stop;
  • 再加一条正向:空 body + APPROVED 的行仍在 reports 里(不丢行),且不改变结论。

两遍红、复原两遍绿。

不做(B 另开一张,等 A 合入)

三份收成一处、以及「同一 fixture 三个读者输出逐字节相同」的等价测试,都在 B 里做;#812 的注释口径(「第二份拷贝是 kill condition」)带进 B 并改准。不要在这张单里顺手收拢:合在一起会把漂移掩掉,分不出「修好了」还是「两份被删了」。

查重

  • open .github/scripts + review-gate:本轮无同题 open;
  • #2092(merged 299862867e)、#2120(merged c776ffc7b5)只覆盖另两份,文件清单不含 review-gate.mjs;
  • 首见于 fca35af6(11-02,#2085),tip a30d7625 上逐行复核仍是三份。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions