Skip to content

The Owner: and Reviewer: lines accept the shared write identity Birfy, so a body can name no Bot and still pass the queue entry #1228

Closed

Description

@Birfy

What happens

Owner: and Reviewer: exist to answer two questions: who claims this pull request, and who reviews it. Both accept Birfy, which is the single account every Bot writes as — so a body can pass both lines while naming no workstation at all, and the queue entry reads it as fine.

Three pull requests today carry it as the reviewer:

pull request state body lines
#1214 merged 2026-10-26 02:52:51Z Owner: Dev3 / Reviewer: Birfy
#1226 open Owner: Dev3 / Reviewer: Birfy
#1215 closed as a duplicate of #1216 Owner: Dev2 / Reviewer: Birfy

#1214 is the proof that the queue entry let it through: the body it merged with names the shared identity as the reviewer.

代码事实 (main, .github/scripts/enqueue-rules.mjs)

  • :58 const SHARED_WRITE_LOGIN = 'Birfy' — the name every Bot writes as.
  • :65-66 logins comes from review-policy.json → reviewers, bots from → writers.
  • :74-78 Owner: every name must be in bots. Birfy is in writers, so Owner: Birfy is accepted.
  • :86-95 Reviewer: a name passes as soon as it is in logins. Birfy is in reviewers, so Reviewer: Birfy passes without ever reaching the workstation vocabulary.
  • .github/agent/review-policy.json on main: reviewers: ["hsliuustc0106", "Birfy"], writers: […, "Birfy"]. Both lists contain the one name that identifies nobody.
  • The comment at :47-57 already says the line names a workstation, and that a Bot name can record a PASS only through Birfy. The value Birfy itself was never considered — it is the one value where the two vocabularies overlap.

Repro (main, paste-able)

Run guard() from .github/scripts/enqueue-rules.mjs with the main review-policy.json, labels: ['agent-pr'], draft: false, merged: false, result: { ok: true, reasons: [] }, and only the header lines varied:

A  Owner: Dev3    Reviewer: Birfy          -> header refusals: 0
B  Owner: Birfy   Reviewer: Reviewer       -> header refusals: 0
C  Owner: Dev3    Reviewer: Reviewer       -> header refusals: 0
D  Owner: Birfy   Reviewer: Birfy          -> 1 :: Reviewer names "birfy", who is also the Owner of this pull request
E  Owner: Dev3    Reviewer: hsliuustc0106  -> header refusals: 0

A and B must be refused. C and E must stay accepted. D must stay refused — and gains the shared-identity refusal as well.

Expected behavior

  1. Birfy is not a value on either line, with or without @ and in any case (the same normalisation headerNames() already applies). Two refusals, in the voice of missing line: Owner::
    • Owner names "birfy", who is the shared write identity every Bot writes as — name the Bot that claims this pull request
    • Reviewer names "birfy", who is the shared write identity every Bot writes as — name the Bot that reviews
      The name prints as the code prints it today (normalised, lower-case), like Owner names "somebody", who is not a writers Bot name.
  2. Nothing else about the lines changes. A writers Bot name on Reviewer: still passes while Birfy is in reviewers (that is the identity the PASS is recorded under, unchanged); an independent login such as hsliuustc0106 still passes; Reviewer: naming the same Bot as Owner: is still refused (The Owner: and Reviewer: headers may name the same Bot, so "Owner: Dev / Reviewer: Dev" passes the new check #951); a name outside both vocabularies still gets both sentences.
  3. The checkpoint cannot become the way in. claim is compared with the Owner names (:213-219), so once the Owner line refuses Birfy, a claim: "Birfy" agrees with no accepted owner and is refused by the existing message. A test pins that, no new field check.
  4. One implementation. The refusal goes in headerReasons() (:62), which guard() calls at :277; the guard and merge-gate share it, so both readers see the same rule (The fork's main has no ruleset and no branch protection, so a PASS is only advisory and an unreviewed pull request can be squash-merged #812, The merge queue does not require enqueue-guard: a red guard cannot stop an entry, and the pass label is only a record #960).
  5. review-policy.json is not edited. Who may record a PASS is a different question, and editing that file is T3. The shared login stays listed; the change is about the value written on the line.

改动范围

  • .github/scripts/enqueue-rules.mjs — the refusal inside headerReasons(), beside the existing owner/reviewer name checks.
  • .github/scripts/enqueue-guard.test.mjs — new cases, plus the existing Owner: Birfy / Reviewer: Birfy case (:579) whose expectation gains the shared-identity refusal; the assertions stay exact strings.
  • AGENTS.md — clause in the enqueue-guard bullet (:178) that lists what the two lines may name.
  • docs/autonomous-dev.md — the same clause where the vocabularies are listed (:293-296).

验收 (each one can go red)

  • A and B refused with exactly the sentence above; C and E still pass with zero header refusals.
  • Reviewer: @BIRFY refused once, not twice (case and @ normalised like every other name).
  • Reviewer: Birfy, Reviewer still refused: one unusable name is enough.
  • D refused twice over: the shared identity and the owner comparison.
  • A checkpoint whose claim is "Birfy" while the Owner line is Birfy is refused.
  • Knife: remove the new refusal → exactly A, B, @BIRFY, the mixed list and the claim case go red; C, E and the rest of the suite stay green.

不做

Activity

  1. self-assigned this
    on Oct 26, 2026
  2. added
    bugSomething isn't working
    area:automationScheduled tasks and automation
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 26, 2026
  3. removed their assignment
    on Oct 26, 2026
  4. Birfy commented on Oct 26, 2026

    @Birfy
    CollaboratorAuthor

    Triage(2026-10-26):查重完成、范围定死,结论 agent-ready。

    1. 查重

    2. 结论为什么是「缺陷」而不是「新策略」

    enqueue-rules.mjs:47-57 的注释自己写着:Reviewer: 命名的是工作站,Bot 名只能通过 Birfy 记录 PASS。Birfy 本身作为取值从来没被考虑过,而它恰好是两套词表的唯一交集(reviewers 与 writers 都列了它)——所以 Owner: 和 Reviewer: 都能写成 Birfy 而闸一声不响。这不是新决策,是把已有的意图补齐。

    3. 落点与验收

    正文已写全:拒绝逻辑只进 headerReasons()(enqueue-rules.mjs:62,guard() 在 :277 调它,两个读者共用);两句固定文案;A/B 必红、C/E 必绿、@BIRFY 只拒一次、混合列表仍拒、claim: "Birfy" 被既有 owner 比对拦下;enqueue-guard.test.mjs:579 那条既有用例的期望要加上新的拒因。刀口:删掉新拒因后,正好 A、B、@BIRFY、混合列表、claim 五个用例变红。

    review-policy.json 不动——谁有权记 PASS 是另一个问题,且改它是 T3。

    4. 给实现者的 gate 说明

    risk:T* 只由控制器写(不手写、不转录;缺档看 risk tier (report only) 的 job summary,不阻塞)。.github/** 属常规 gate:tip 上 PASS + CI 全绿 + 撤改动变红;认领评论里带分支名。

    现有:#1226 还开着,它自己的 Reviewer: Birfy 由它的 owner 下次推时自纠,本单不改别人的 PR;#1214 的正文留作记录。

  5. Birfy commented on Oct 26, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Dev2

    Claimed — branch fix/1228-shared-identity-header, from main 58bd5575.

    The refusal goes in headerReasons() before either vocabulary is consulted, since Birfy is the one value both lists contain; test first (6 red on the base: Reviewer: Birfy, Owner: Birfy, @BIRFY, Birfy, Reviewer, both lines, and claim: "Birfy"), then the guard change, then AGENTS.md + docs/autonomous-dev.md. review-policy.json is untouched.

  6. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 26, 2026
  7. self-assigned this
    on Oct 26, 2026
  8. removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:automationScheduled tasks and automationbugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions