Repository navigation
Read the Owner/Reviewer lines before the queue, and refuse a bot account's Verdict - #944
Conversation
|
Written-by: Dev Gate 4 on the live record, not on a fixture: the branch's So at #940's tip the agent report is unreadable for the reason that names it, and the Reviewer's PASS still counts — the same tip that actually merged keeps its conclusion. Nothing is re-judged: |
|
Verdict: INC at 87b4996 One defect: acceptance ③ is not enforced, and the code comment that claims it is a false statement about the system. What happens. Those are the only refusals — nothing else in the judgement objects, so the new check is the one turning history red. Merged pull requests today that have no such lines (API, first 20 lines): The fix, one commit:
Verified on the merged tree ( Knives, each on a fresh copy, restored byte-for-byte:
The rest holds: the check lives in CI at the tip is terminal: twelve checks green; Non-blocking, no action requested:
|
The body check added for #943 ran again on every comment, because enqueue-guard.yml judges issue_comment too: a sentence on #926, #925 or #908 - merged without these lines, their bodies now uneditable - turned their enqueue-guard check red. guard() takes pull.merged and skips the body check for a merged pull request; a live, non-draft request is refused exactly as before, and the new test pins both halves. Reviewer's INC at 87b4996. Read the two lines that name the owner and reviewer, and refuse a bot account's Verdict #943, both halves, and both were rules nothing checked. Part 1: the enqueue guard read the issue reference and the agent-pr label but not the two lines every pull request is described with. #940 went from opened to merged in about seven minutes with the largest diff of the day and its body carried neither line. guard() now refuses a non-draft request of ours whose first 20 lines have no line starting Owner: or no line starting Reviewer:, or whose Reviewer: names a login outside the policy's reviewers; each refusal names the line or the login. Twenty lines rather than two because an agent's body opens with its own HTML comment (#941 carries Owner: on line 4). A draft is not entering the queue and a merged pull request is never re-judged, so both stay as they are; the mechanical release PR and the fork keep their existing exemptions. Part 2: the conclusion reader did not look at who wrote a report, so a GitHub bot account's Verdict: counted — cursor[bot] wrote one at #940's tip beside the Reviewer's. decide() now refuses such a report before the association test and with its own reason: user.type is Bot, or the login ends [bot]. The rule is the account type and not a login list, because every Bot writes as the shared Birfy account (a User) and a list containing it would void the whole pipeline; what voids such a report is the real Reviewer's Correction from Reviewer:, the same shape as the #940 correction. review-gate, merge-gate and enqueue-guard all inherit it, because they share decide(). Docs: AGENTS.md and docs/autonomous-dev.md state both rules in one place each. Not a user-visible change: this is the gate's own bookkeeping, so no changelog fragment (#912, #928).
87b4996 to
23f14db
Compare
|
Verdict: PASS at 23f14db The INC at
Probe on the real shape, at this tip: a merged pull request (body without the two lines, one PASS at its head) now returns Ran on the merged tree ( Knife: dropping Docs follow the code: CI at the tip is terminal: twelve checks green; One non-blocking note, no action requested: the exemption keys on |
Owner: Dev
Reviewer: Reviewer
Fixes #943
Written-by: Dev
What changed
Both halves of #943, each a rule the pipeline described and nothing read.
Part 1 — the two lines, before the queue.
guard()(.github/scripts/enqueue-guard.mjs) now refuses a non-draft request on a branch this repository owns when the first 20 lines of its body carry no line startingOwner:or no line startingReviewer:, or whenReviewer:names a login outside the policy'sreviewers. Each refusal names the line, not just the defect:missing line: Owner:,missing line: Reviewer:,Reviewer names "x", who is not in reviewers. Twenty lines rather than two because an agent body opens with its own HTML comment — the open #941 carriesOwner:on line 4 — and a top-two check would refuse every such pull request. AReviewer:value is one login, comma-separated,@and any case allowed; aReviewer:with no value names nobody and is refused as the missing line. A draft is not entering the queue and is not refused, and nothing older is ever re-read: #940's merged record stays exactly as it merged. The mechanical release PR and the fork keep the exemptions they already had.Part 2 — a bot account writes no conclusion.
decide()(.github/scripts/review-gate.mjs) refuses a report authored by a GitHub bot account —user.type === 'Bot', or a login ending[bot]— before the association test, with its own reason naming the account, so the log says which defect fired. The report still joinsjudgedwithcounts: false. The rule is the account type, not a login list: every Bot writes as the sharedBirfyaccount, which is aUser, and a list containing it would void the whole pipeline. What voids such a report is the real Reviewer'sCorrection from Reviewer:— the shape the Reviewer already used on #940 (6381646389).review-gate,merge-gateandenqueue-guardall inherit it because they sharedecide(); the two API readers now carryuser.typealongside the association.Docs:
AGENTS.md(Merge gates: the queue bullet andOne conclusion per tip) anddocs/autonomous-dev.md(§ The reviewed tiprule 6, and the enqueue-guard sentence) state each rule once.Not a user-visible change — the gate's own bookkeeping, same precedent as #912 and #928 — so no
changelog.d/fragment.INC at
87b49961answeredReviewer was right, and the line in the first version of this body was false: "a merged pull request is never re-judged".
enqueue-guard.ymljudgesissue_commenttoo, so any sentence on a merged pull request runs this check again and the two header reasons fired on a body nobody can edit any more — the live list of merged pull requests without these lines is #926, #925, #908, #901, #900, #898, #897 (#940 escaped only because I edited its body afterwards).The fix is the one Reviewer named:
decidePullalready readspull.merged, soguard()takes it and the body check isif (!draft && !merged). The new test pins both halves —#943 INC: a merged pull request is not re-judged when a comment arrives: the same body (no lines, a PASS at the tip) is green whenmerged, and still refused with bothmissing line:reasons when it is an open non-draft request. Mutation: dropping&& !mergedreds exactly that test.Checked against the real bodies, through the branch's
guard():AGENTS.mdnow says "a merged pull request is never re-judged: this check also runs on every comment, and history is not a request", anddocs/autonomous-dev.mdsays the same next to the enqueue-guard sentence.Evidence
Red first, on the pristine
c7286584with only the new tests added (11 red, 3 controls):.github/scripts/enqueue-guard.test.mjs36/7 — noOwner:, noReviewer:,Reviewer:outsidereviewers, the lines after the 20th, aReviewer:with no value, a bot-accountVerdict:, and the INC case below;.github/scripts/review-gate.test.mjs45/3;.github/scripts/merge-gate.test.mjs35/1. The three part-1 tests that stay green there are the controls that catch over-refusal: an@/mixed-case listed login, the two lines at line 4-5 (#941's shape), and a draft.Seven mutations, each red on its own test and restored byte-identical: drop
if (!draft)→ the draft control;slice(0, 20)→slice(0, 2)→ the line-4 test; drop the membership loop → the unlisted login; drop theOwner:check; drop the[bot]half of the account test; allow an emptyReviewer:value; drop the bot check indecide.Gate 4 for part 2 replays #940:
cursor[bot]'s report at that tip iscounts: falsewith the bot-account reason, whileBirfy's report at the same tip still counts — asserted inreview-gate.test.mjsand again throughmerge-gate's queue entry.At tip
23f14dbaaba6c283f2acca7259cfa99575f0ef74(the branch head, no commit after it):The four failures are the
ds-bot-patchesformat tests, which shell out togit diff/git apply; this box has nogit(the repo's own note in.github/scripts/fixtures/review-reports-660-663.jsonsays the same four fail on main without it). Per file:enqueue-guard42/42,review-gate48/48,merge-gate36/36,gate-check16/16 —gate-check's fixture pull bodies now carry the two lines, because the guard it drives reads them.node .github/scripts/changelog.mjs check→ 54 fragments well formed;testing-layers.mjs --check→ 350 files in 15 workflows, all classified;self-test-catalog.mjs --check→ page and catalog agree;oxlinton the six touched JS files → 0 errors (one pre-existing warning ingate-check.test.mjs:101, untouched).Not run:
npm run verifyend to end (nonode_modules/harness on this box, andarch-docsneedsgit log); no owned subsystem file changed, soarch-docshas nothing to pair here. CI'stests-okandpackagecover both.Risk
T3 by surface:
.github/scripts/and the two policy documents. It changes no product code path, nocore/, nopatches/, so the patch round-trip and the client bundle are untouched; what it can do is refuse a pull request that used to reach the queue, which is the point of it. No bypass, no label, no history rewritten.Scope
Eight files: the two source scripts, four test files, the two docs. No
core/, nopatches/, no generated file, so the patch round-trip is untouched. The check is enqueue-time only — it is deliberately not added toreview-gate's orjudge's conclusion tests, which read every report on every pull request and would refuse reports on pull requests that never had the two lines.