Repository navigation
fix(merge): no self-armed merges; tri merges only what a reviewer bee passed - #1242
Merged
Merged
Conversation
… passed Owner's rule 2026-10-02: no automation merges on its own verdict. - t27-world-scan.yml: stop arming gh pr merge --squash --auto on the PR the job opens; disarm any earlier arming; the PR waits for a reviewer. - tri cloud pipeline: no automatic cloudMergePR after a green local build. - GitHubClient.mergePr (tri pr merge, tri cloud merge): refuse unless the PR has an APPROVED review and the bee-reviewed label applied after the head commit (gate of gHashTag/t27#5526); merge pinned to that head sha. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…age (t27#5526 hardening) Reviewer-bee fix on top of the author's gate. reviewerBeeGate compared the bee-reviewed label against the head commit's committer date only. A commit made at 10:00 and pushed at 10:10 carries 10:00, so a label put on at 10:05 passed unreviewed code; a force-push back to an older SHA carries an older date still. Same hole gHashTag/t27#5526 closed in f9a6c9b. Now the head's time is the latest of its committer date, the first check run started on the head, and the last head_ref_force_pushed event. Events are read page by page to the end (a force-push on an unread page would fail open); more than 30 pages is refused. Every read or parse failure refuses. Tests: three new github_client tests (late push, force-push to old SHA, unreadable responses fail closed, Stamp ordering). zig 0.15.2: `zig test src/tri/github_client.zig` 18/18 pass; `zig build tri` builds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag
added a commit
to gHashTag/trinity-fpga
that referenced
this pull request
Oct 2, 2026
…to-merges Reviewer-bee fix. The workflow gate was not the only merge path in this repo: src/tri carries a copy of trinity's tri, and `tri cloud pipeline` still called cloudMergePR on its own verdict (a green local build), and GitHubClient.mergePr merged anything it was asked to (gh pr merge / PUT /pulls/N/merge) with no gate. Ported the gate from gHashTag/trinity#1242 (with the reviewer-bee hardening pushed there): mergePr refuses unless the PR has an APPROVED review and the `bee-reviewed` label applied after the head's arrival -- the latest of its committer date, its first check run and the last force-push, events read to the last page -- and pins the merge to the checked head sha. Every read failure refuses. The pipeline leaves the PR open for a reviewer bee; `tri pr merge` reports the refusal. zig 0.16.0 (this repo's CI version): `zig test src/tri/github_client.zig` 18/18 pass; `zig build tri` builds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag
added a commit
to gHashTag/trinity-fpga
that referenced
this pull request
Oct 2, 2026
… APPROVED) (#805) * fix(queen-bot): merge only what a reviewer bee passed (bee-reviewed + APPROVED) Owner's rule 2026-10-02: no automation merges on its own verdict. The merge step now requires an APPROVED review and the bee-reviewed label applied after the head commit (same gate as gHashTag/t27#5526), and pins the merge to the checked head sha. Also: PR body passed via env instead of shell interpolation under pull_request_target, untrusted checkout dropped, dead check_suite trigger removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(queen-bot): date the head by its arrival, not its commit (t27#5526 hardening) Reviewer-bee fix on top of the author's gate. The gate compared the bee-reviewed label against the head commit's committer date only. A commit made at 10:00 and pushed at 10:10 carries 10:00, so a label put on at 10:05 passed unreviewed code; a force-push back to an older SHA carries an older date still. Same hole gHashTag/t27#5526 closed in f9a6c9b. Now the head's time is max(committer date, first check run started on the head, last head_ref_force_pushed event). The gate also judges exactly the head the merge step pins (payload head.sha) and refuses if the API head has moved. Every read throws on an API error, which fails the step and skips the merge: fail closed. Simulated with mocked API: normal PASS; late push, force-push to old SHA, no label, no approval, head moved all REFUSE; read error throws. actionlint clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(tri): gate every merge on the reviewer bee; pipeline no longer auto-merges Reviewer-bee fix. The workflow gate was not the only merge path in this repo: src/tri carries a copy of trinity's tri, and `tri cloud pipeline` still called cloudMergePR on its own verdict (a green local build), and GitHubClient.mergePr merged anything it was asked to (gh pr merge / PUT /pulls/N/merge) with no gate. Ported the gate from gHashTag/trinity#1242 (with the reviewer-bee hardening pushed there): mergePr refuses unless the PR has an APPROVED review and the `bee-reviewed` label applied after the head's arrival -- the latest of its committer date, its first check run and the last force-push, events read to the last page -- and pins the merge to the checked head sha. Every read failure refuses. The pipeline leaves the PR open for a reviewer bee; `tri pr merge` reports the refusal. zig 0.16.0 (this repo's CI version): `zig test src/tri/github_client.zig` 18/18 pass; `zig build tri` builds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag
commented
Oct 2, 2026
gHashTag
left a comment
Owner
Author
There was a problem hiding this comment.
Reviewer-bee review (COMMENT; an APPROVE is impossible because every actor here is gHashTag).
Verdict: merge, with one reviewer-bee fix commit I authored and pushed to this branch.
Defect found and fixed: f8ec055 (authored by the reviewer bee)
- Late-push hole.
reviewerBeeGatecomparedbee-reviewedonly against the head commit's committer date. A commit dated 10:00 but pushed at 10:10 passed a label added at 10:05. A force-push back to an older SHA was worse. This is the same hole t27#5526 closed in f9a6c9b. The head's time is now the latest of the committer date, the first check run started on the head, and the lasthead_ref_force_pushedevent. - First-page-only events. The gate read only the first page of events, so a force-push on an unread page would fail open. It now reads page by page to the end and refuses beyond 30 pages.
- Fail closed. Every read or parse failure refuses.
- Tests. Three new tests cover the late push, the force-push to an old SHA, unreadable responses (
{"message":"Not Found"}and non-JSON) and Stamp ordering. - PR body. I updated the work report's
head_shato the new head; it is now validated.
Checked
- (a) The gate now uses max(...), not committedDate.
- (b) Grep for
gh pr merge,--auto,enablePullRequestAutoMerge,mergePullRequestand/mergeREST:t27-world-scan.ymlnow only runs--disable-auto;mergePris the single merge function, used bytri pr mergeandtri cloud merge, and both are gated;- the pipeline no longer merges;
- I found no other live path.
- (c)
httpRequesterrors on non-2xx andghCliRunerrors on non-zero exit; both turn into a refusal. - (d) The workflow change only removes the merge line; no new interpolation of untrusted input.
- Minor, not blocking:
tri pr mergeexits 0 on a refusal.
Checks run
- zig 0.15.2 (the CI version):
zig test src/tri/github_client.zigpasses 18/18, andzig build tribuilds and runs. - The same patch also builds under zig 0.16.0 in trinity-fpga (merged there as bb37d00), with 18/18 tests passing.
- CI on f8ec055:
- Build & Test, Build Check, Code Format, Headless profile (aarch64/x86_64), VIBEE codegen, GitGuardian, no-new-dangling-paths and T27 work report pass.
- Red: Brain Health Check and Brain Health Report. Both also fail on main 3204243, so they are noise.
Owner
Author
|
Reviewer-bee evidence (I did not write this PR).
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Owner rule, 2026-10-02:
In short: the Queen only manages, and no board merger merges on its own verdict. A merge happens only after a reviewer bee passes the PR: an APPROVED review plus the
bee-reviewedlabel, added after the head arrived. This is the same gate as gHashTag/t27#5526.What changed
.github/workflows/t27-world-scan.yml: removed the self-arminggh pr merge "$PR" --squash --auto. The job now disarms any leftover auto-merge (--disable-auto, best effort) and leaves the PR open for a reviewer bee.src/tri/tri_cloud.zig: the cloud pipeline no longer callscloudMergePRafter verify. It prints that the PR is verified locally and left open for a reviewer bee. The manualtri cloud mergestays, and it is gated (below).src/tri/github_client.zig:mergePrrunsreviewerBeeGate(number)before merging and fails closed. The gate reads:/pulls/N;head_ref_force_pushedevent;labeledbee-reviewedmust be at or after the head's arrival.The merge is pinned to the head SHA the gate checked:
"sha"in the REST body,--match-head-commitfor gh. The purebeeGateReasonfunction, the JSON readers and the event and check-run scanners have unit tests.src/tri/github_commands.zig:tri pr mergereports a refusal and exits cleanly. The help text says it needs APPROVED + bee-reviewed.The
bee-reviewedlabel was created in this repo.Reviewer-bee commit f8ec055 (authored by the reviewer bee, not the author)
The author's gate compared the label against the head commit's committer date only, which is the late-push hole t27#5526 closed in f9a6c9b. It also read only the first page of events. This commit:
Verification
zig test src/tri/github_client.zig(zig 0.15.2, same as CI): 18/18 pass after f8ec055. With the author's head it was 15/15, and a mutation check made 2 gate tests fail.zig build tri(zig 0.15.2): builds and runs.tri pr merge 1239on an already-merged PR refused with "nobee-reviewedlabel".actionlint .github/workflows/t27-world-scan.yml: clean.{ "version": 1, "head_sha": "f8ec05509c4c1b0b8b22e51d44bda3de7d0212b1", "summary": "Automation in trinity can no longer merge on its own verdict: the world-scan job stops arming auto-merge, the cloud pipeline stops merging after verify, and tri merges only PRs with an APPROVED review plus a bee-reviewed label added after the head arrived.", "changes": [ "t27-world-scan workflow no longer runs gh pr merge --squash --auto and disarms leftover auto-merge", "tri cloud pipeline leaves the verified PR open for a reviewer bee instead of calling cloudMergePR", "github_client mergePr runs a fail-closed reviewer bee gate and pins the merge to the checked head SHA", "the gate dates the head by its arrival, the latest of commit date, first check run and last force-push, reading every events page", "tri pr merge reports the gate refusal and its help text names the APPROVED plus bee-reviewed requirement" ], "tests": [ { "command": "zig test src/tri/github_client.zig (zig 0.15.2)", "result": "All eighteen tests pass including six bee gate tests", "status": "passed", "evidence": "Late push, force-push to an older SHA and unreadable responses are all refused in the new tests" }, { "command": "zig build tri (zig 0.15.2)", "result": "The tri executable compiles and runs", "status": "passed", "evidence": "Exit code zero on the reviewer bee head" }, { "command": "tri pr merge 1239", "result": "The gate refused because the PR has no bee-reviewed label", "status": "passed", "evidence": "PR 1239 was already merged and its state on GitHub stayed unchanged" }, { "command": "actionlint .github/workflows/t27-world-scan.yml", "result": "No findings on the edited workflow file", "status": "passed", "evidence": "actionlint exited with code zero and printed nothing" } ], "limitations": [ "A full zig build of every target was not run locally, only the tri executable and unit tests", "The gate reads at most one hundred reviews and check runs, which can only make it stricter" ], "tags": ["governance", "merge_gate", "tri"], "blog": { "title": "No automation merges on its own verdict in trinity", "summary": "The owner ruled that the Queen and board mergers only manage. Trinity now leaves merging to a reviewer bee: an APPROVED review plus a bee-reviewed label newer than the head's arrival.", "outline": [ "The owner rule of October second says the Queen manages and board mergers lose the right to merge on their own", "The world scan workflow used to arm squash auto-merge on its own pull requests, and that line is now removed", "The tri cloud pipeline used to merge right after local verification, and now it leaves the pull request open for review", "The tri merge command checks an approved review and a bee-reviewed label newer than the head's arrival before merging" ] } }🤖 Generated with Claude Code