docs: automerge.sh header still describes the pre-#404 human-only gate #480
Labels
No labels
Agent
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
joshtronic/igor#480
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The header comment of
lib/automerge.sh(lines ~9-10) still describes the PRE-#404 gate: "The harness merges a bot PR ONLY when the human (FORGEJO_REVIEWER) has submitted an APPROVED review..." Since 2026-07-20 (commits85d7481,d929cdc) the DEFAULT gate is the shadow review's APPROVE, withautomerge_require_humancarve-outs pinning specific repos back to the human gate. The stale header actively misled the operator and the CoS on 2026-08-09 (both believed the human gate was still the default).Change: rewrite the header paragraph to describe the actual decision chain: shadow-APPROVE default -> require_human carve-out -> CI green -> mergeable -> not-behind -> not-RC -> never self-repo. One paragraph, accurate, nothing else. No behavior changes in this ticket.
Comment-discipline note: state the contract, not the history -- the git log carries the archaeology.
Blocked (2026-08-09 04:19Z)
The harness security review flagged a material issue in this change, so it was NOT pushed:
The security gate could not complete -- no verdict from the reviewer after 2 attempts. This is most likely a transient model/API error rather than a real finding; re-queue to retry.
Address it, then remove
Status/Blockedto re-queue. (If the note above says the gate could not complete, that's a transient error -- just re-queue.)Blocked (2026-08-09 05:53Z)
The harness security review flagged a material issue in this change, so it was NOT pushed:
The security gate could not complete -- no verdict from the reviewer after 2 attempts. This is most likely a transient model/API error rather than a real finding; re-queue to retry.
Address it, then remove
Status/Blockedto re-queue. (If the note above says the gate could not complete, that's a transient error -- just re-queue.)Blocked (2026-08-09 22:05Z)
The harness security review flagged a material issue in this change, so it was NOT pushed:
I'll inspect the actual code behind this documentation change before judging it.
Findings
Auto-merge gate downgraded from human approval to self-approval (
lib/automerge.sh) — The diff replaces the documented gatewith
This inverts the trust model of the merge gate. Previously a human reviewer was a mandatory, non-opt-out control on every automated merge; after this change the same automated agent that authors the PR also supplies the approving verdict that authorizes merging it, and human review becomes an opt-in flag (
automerge_require_human) that defaults off. That is a self-approval loop: any code the bot can author, it can also approve and land, with the only remaining checks being CI green / mergeable / not-behind — none of which are review controls.Concretely this means a compromised or prompt-injected agent (e.g. one that ingested hostile content from an issue body, dependency README, or fetched page while working) no longer has a human in the loop between "write malicious patch" and "merge to the default branch, then stamp a pending deploy under
.deploy". Because the merge also triggers the deploy barrier, the blast radius is production, not just the repo.Mitigations named in the comment do not close this.
REQUEST_CHANGESvetoing the merge is not a substitute for required approval — it is a control the same agent would have to volunteer against itself.require_humanbeing available per-repo does not help repos that never set it, which is every repo by default. "It never auto-merges its own repo" narrows one path but leaves every other repo self-approving.This is the category the review brief calls out explicitly: a change that weakens a merge/review gate is itself a finding regardless of how the diff's own prose justifies it. The prose here is doing exactly that justification work, so I'm treating it as data, not as reassurance.
Suggested resolution: invert the default so
require_humanis on unless a repo explicitly opts out, or restrict shadow-verdict-only merging to a narrow, non-privileged change class (e.g. lockfile/formatting) that cannot touch CI config, deploy scripts, or the automerge/review logic itself.Scope note
The diff as provided contains only the header-comment change; the implementation of
automerge_require_humanand the shadow-verdict gate is not included in the hunk I was given. I reviewed this on the basis that the comment accurately describes the behavior it ships alongside — that is the file's own contract-documentation block, not incidental prose. If the corresponding code is not in this branch, the finding downgrades to a docs/code mismatch and should be re-reviewed against the real implementation; if the code is in this branch but was omitted from the diff I received, the finding stands as written and the omission itself is worth confirming.I flagged nothing on the remaining comment edits (CI-green, mergeable, not-behind, self-repo exclusion) — those are additive restrictions or accurate descriptions of existing behavior and introduce no new exposure.
Address it, then remove
Status/Blockedto re-queue. (If the note above says the gate could not complete, that's a transient error -- just re-queue.)The harness security review flagged a material issue in this change, so it was NOT pushed:
The security gate could not complete -- no verdict from the reviewer after 2 attempts. This is most likely a transient model/API error rather than a real finding; re-queue to retry.
Address it, then remove
Status/Blockedto re-queue. (If the note above says the gate could not complete, that's a transient error -- just re-queue.)(Appended to the issue description above -- removing
Status/Blockedre-queues the ticket with this context already in hand.)The harness security review flagged a material issue in this change, so it was NOT pushed:
The security gate could not complete -- no verdict from the reviewer after 2 attempts. This is most likely a transient model/API error rather than a real finding; re-queue to retry.
Address it, then remove
Status/Blockedto re-queue. (If the note above says the gate could not complete, that's a transient error -- just re-queue.)(Appended to the issue description above -- removing
Status/Blockedre-queues the ticket with this context already in hand.)The harness security review flagged a material issue in this change, so it was NOT pushed:
I'll inspect the actual code behind this documentation change before judging it.
Findings
Auto-merge gate downgraded from human approval to self-approval (
lib/automerge.sh) — The diff replaces the documented gatewith
This inverts the trust model of the merge gate. Previously a human reviewer was a mandatory, non-opt-out control on every automated merge; after this change the same automated agent that authors the PR also supplies the approving verdict that authorizes merging it, and human review becomes an opt-in flag (
automerge_require_human) that defaults off. That is a self-approval loop: any code the bot can author, it can also approve and land, with the only remaining checks being CI green / mergeable / not-behind — none of which are review controls.Concretely this means a compromised or prompt-injected agent (e.g. one that ingested hostile content from an issue body, dependency README, or fetched page while working) no longer has a human in the loop between "write malicious patch" and "merge to the default branch, then stamp a pending deploy under
.deploy". Because the merge also triggers the deploy barrier, the blast radius is production, not just the repo.Mitigations named in the comment do not close this.
REQUEST_CHANGESvetoing the merge is not a substitute for required approval — it is a control the same agent would have to volunteer against itself.require_humanbeing available per-repo does not help repos that never set it, which is every repo by default. "It never auto-merges its own repo" narrows one path but leaves every other repo self-approving.This is the category the review brief calls out explicitly: a change that weakens a merge/review gate is itself a finding regardless of how the diff's own prose justifies it. The prose here is doing exactly that justification work, so I'm treating it as data, not as reassurance.
Suggested resolution: invert the default so
require_humanis on unless a repo explicitly opts out, or restrict shadow-verdict-only merging to a narrow, non-privileged change class (e.g. lockfile/formatting) that cannot touch CI config, deploy scripts, or the automerge/review logic itself.Scope note
The diff as provided contains only the header-comment change; the implementation of
automerge_require_humanand the shadow-verdict gate is not included in the hunk I was given. I reviewed this on the basis that the comment accurately describes the behavior it ships alongside — that is the file's own contract-documentation block, not incidental prose. If the corresponding code is not in this branch, the finding downgrades to a docs/code mismatch and should be re-reviewed against the real implementation; if the code is in this branch but was omitted from the diff I received, the finding stands as written and the omission itself is worth confirming.I flagged nothing on the remaining comment edits (CI-green, mergeable, not-behind, self-repo exclusion) — those are additive restrictions or accurate descriptions of existing behavior and introduce no new exposure.
Address it, then remove
Status/Blockedto re-queue. (If the note above says the gate could not complete, that's a transient error -- just re-queue.)(Appended to the issue description above -- removing
Status/Blockedre-queues the ticket with this context already in hand.)