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 |
…cannot review (ThinkFlowLab#950) Owner: Dev Reviewer: Birfy Fixes ThinkFlowLab#947 Tip SHA: 4c11dc8 Written-by: Dev `Reviewer: Birfy` and not `Reviewer: Reviewer`, for one reason: `enqueue-guard.yml` runs the copy of this check on `main`, and that copy is the defect this pull request fixes — it refuses every Bot name. The reviewing workstation for this pull request is Reviewer; the line moves to `Reviewer: Reviewer` once this lands, and nothing else on the record changes. ## What changed - `.github/scripts/enqueue-guard.mjs` — `headerReasons` accepts a `Reviewer:` value that is either a `reviewers` login or a `writers` Bot name (leading `@` and case ignored, comma-separated as before); a word in neither is refused with two reasons that name the list it missed; and a line whose names are only `writers` Bot names is refused while `Birfy` — the identity every Bot writes as — is not in `reviewers`. One name from either list is enough for the line, and one bad name still refuses it. - `.github/scripts/enqueue-guard.test.mjs` — five new cases, plus the ThinkFlowLab#943 refusal case updated to the new pair of sentences. - `AGENTS.md`, `docs/autonomous-dev.md` — the two sentences that still said the value must be a login. Nothing else moves: the 20-line window, the draft and merged exemptions, `missing line: Owner:` / `missing line: Reviewer:`, the issue reference, the `agent-pr` label, the fork and mechanical-release exemptions and ThinkFlowLab#944's bot-account rule are as they were. ## Evidence Red on `ed60c5a` with only the new cases in the tree — 5 red, 43 green: ``` not ok 36 - ThinkFlowLab#943, reworded by ThinkFlowLab#947: a Reviewer: outside both vocabularies is refused and names the word not ok 38 - ThinkFlowLab#947: a Reviewer: naming a writers Bot name is accepted not ok 39 - ThinkFlowLab#947: either vocabulary is accepted, with an @ and in any case not ok 40 - ThinkFlowLab#947: a name in neither vocabulary is refused, and the refusal says which two lists it missed not ok 41 - ThinkFlowLab#947: a writers Bot name names nobody when the shared account is not a reviewer ``` Real bodies, judged as a live request (the `merged` exemption lifted), this branch left, `main` right: ``` ThinkFlowLab#942 Reviewer: Reviewer2 ok: true no header reason | ok: false Reviewer names "reviewer2", who is not in reviewers ThinkFlowLab#944 Reviewer: Reviewer ok: true no header reason | ok: false Reviewer names "reviewer", who is not in reviewers ThinkFlowLab#941 Reviewer: Birfy ok: true no header reason | ok: true no header reason ``` The boundary Chief asked for, run on the real policy with `Birfy` taken out of `reviewers`: ``` Reviewer: Reviewer2 ok: false Reviewer names "reviewer2", who is a writers Bot name but cannot record a Verdict here: every Bot writes as "Birfy", which is not in reviewers Reviewer: hsliuustc0106 ok: true no header reason ``` Mutations, each restored byte-identical afterwards: | mutation | red | | --- | --- | | drop the `writers` branch | 38, 39, 41, 42 | | `sharedLogin` always true | 41 | | drop the shared-login refusal | 41 | | back to the single old refusal sentence | 36, 40 | ## Ran - `node --test .github/scripts/enqueue-guard.test.mjs` → 48/48 pass - `node --test .github/scripts/review-gate.test.mjs` → 48/48 pass - `node --test .github/scripts/merge-gate.test.mjs` → 36/36 pass - `node --test .github/scripts/gate-check.test.mjs` → 16/16 pass - `node --test .github/scripts/*.test.mjs` → 389 tests, 383 pass, 4 fail, 2 skipped (the 4 are below) - `node .github/scripts/testing-layers.mjs --check` → 350 test files in 15 workflows, all classified - `node .github/scripts/changelog.mjs check` → 54 fragments well formed ## Not run - `npm run verify` and `oxlint`: this box has no `node_modules` and no dependency install, so the `core` suite, `scripts/lint-plugins.mjs` and the linter cannot run here. CI's `tests-ok` and `package` jobs run them at this tip. - The 4 failures in the full scripts run are all of `ds-bot-patches.test.mjs`, which needs `git`; there is none on this box, and `main`'s own tree fails the same four (384 tests, 378 pass, 4 fail). ## Risk T3 — `.github/**`, `AGENTS.md` and `docs/autonomous-dev.md` are on the T3 list, so this needs a PASS at this tip on top of green CI. The change is a vocabulary widening plus one refusal; it touches no workflow, no policy file and no merge path, and the check it edits is the one that reads the body. ## Scope One function in one gate, its tests, and two doc sentences. No policy file change, no second reviewers list, no change to who may PASS, no change to `review-gate` / `merge-gate` behaviour.
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.