diff --git a/AGENTS.md b/AGENTS.md index cf3a47647..c4bf136f2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -169,7 +169,7 @@ What this buys is presence and a name from a closed list, not truth: with one sh - **The label awaiting-approval is retired.** A PASS at the tip goes straight to the queue through the enqueue guard (#687); no pull request waits for an approval click and the label is not set again. - **A pull request enters the queue with its issue and its `agent-pr` label.** On a branch this repository owns, the enqueue guard also refuses one whose body names no issue (`Fixes #` / `Closes #`) and one without the `agent-pr` label (#718), so "one issue, one pull request" is checked rather than remembered. It refuses a **live, non-draft** request whose body carries no `Owner:` line or no `Reviewer:` line in its first 20 lines, or a `Reviewer:` that is neither a `reviewers` login nor a `writers` Bot name, or that names nobody who can record a PASS — a Bot name counts only through the one identity every Bot writes as, `Birfy`, so it names nobody while that account is outside `reviewers` (#947); a `Reviewer:` that names the same Bot as the `Owner:` is refused too, compared name by name after commas, a leading `@` and case are normalised, because one Bot owning and reviewing the same pull request is the shape #940 had with no lines at all (#951); both lines also need a value the policy knows — a `Reviewer:` outside both vocabularies and an `Owner:` outside `writers` are refused, and a line with no value is the missing line, so an empty `Owner:` cannot clear the comparison (#951); the refusal names the missing line, or the word and the list it missed (#943, #947, #951; #940 merged in about seven minutes with the largest diff of the day and neither line). A **merged** pull request is never re-judged: this check also runs on every comment, and history is not a request. Two exemptions: a mechanical release PR, which carries neither by design, and a **fork** (`pull.head.repo.full_name` is not this repository), whose head we cannot push to and where the contributor keeps their own workflow. -**`enqueue-guard` writes a check on the head, and the queue's ruleset does not require it** (#812, re-read 2026-10-24). Team pull requests merge upstream in `ThinkFlowLab/FlyBot` through the `main merge queue`, whose ruleset requires three contexts — `Node 24 · DSH 0.2.0-rc.2`, `tests-ok` and `merge-gate`; the paragraph below (#960) is how `merge-gate` reads the body the queue does not read. `enqueue-guard` still runs on that head, and on the queue entry: [`enqueue-guard.yml`](.github/workflows/enqueue-guard.yml) takes its code from `main` and never from the pull request, on every event that can change the answer for a fixed head — a push, a label added or removed, a comment, a review body, or a manual run — and calls [`enqueue-guard.mjs`](.github/scripts/enqueue-guard.mjs)'s own decision, the same function that prints the command, so the check and the command cannot disagree. It refuses a head that carries a `hold`, that has no PASS naming that exact tip, a PASS that lists no `Ran:`, a pull request with no `agent-pr`, or a body that names no issue; a new commit is a new head and a new check run, and a green check never carries over. +**`enqueue-guard` writes a check on the head, and the queue's ruleset does not require it** (#812, re-read 2026-10-24). Team pull requests merge upstream in `ThinkFlowLab/FlyBot` through the `main merge queue`, whose ruleset requires three contexts — `Node 24 · DSH 0.2.0-rc.2`, `tests-ok` and `merge-gate`; the paragraph below (#960) is how `merge-gate` reads the body the queue does not read. `enqueue-guard` still runs on that head, and on the queue entry: [`enqueue-guard.yml`](.github/workflows/enqueue-guard.yml) takes its code from `main` and never from the pull request, on every event that can change the answer for a fixed head — a push, a label added or removed, a comment, a review body, or a manual run — and calls [`enqueue-guard.mjs`](.github/scripts/enqueue-guard.mjs)'s own decision, the same function that prints the command, so the check and the command cannot disagree. It refuses a head that carries a `hold`, a pull request with no `agent-pr`, or a body that names no issue, and — **for T2 and T3 only** — a head that has no PASS naming that exact tip or a PASS that lists no `Ran:`; a T0/T1 change and the mechanical release pull request need no PASS at all, because the tier is computed from the diff and never read from a `risk:T*` label (#640). A new commit is a new head and a new check run, and a green check never carries over. **Historical: the fork's own ruleset (#812, used until 2026-10-23).** While the team's pull requests merged on the code fork `Birfy/FlyBot`, that repository's `main` required two contexts — `tests-ok` and `enqueue-guard` — with `bypass_actors: []`, so `PUT /pulls//merge` was refused (405/422); [`merge-gate-ruleset.json`](.github/agent/merge-gate-ruleset.json) is that protection, and `node .github/scripts/gate-ruleset.mjs --check` still reads a repository's live state and writes nothing. The fork is an archive now — nothing merges into it — so those two contexts are not this repository's gate, and `--apply` / `--rollback` are not part of any routine — no Bot runs them — and the ordering instruction that came with them (the check had to report on every open pull request before the ruleset went on) described that fork alone.