docs(agents): protect main — every change lands through a PR #13
No reviewers
Labels
No labels
needs-info
needs-triage
ready-for-agent
ready-for-human
wontfix
needs-info
needs-triage
ready-for-agent
ready-for-human
review/merge-ready
review/needs-fix
review/needs-human
review/needs-review
wayfinder:grilling
wayfinder:map
wayfinder:prototype
wayfinder:research
wayfinder:task
wontfix
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
olympus/infra-tracker!13
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "docs/protected-main"
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?
Summary
mainnow carries a Forgejo branch rule:enable_push=falsewith no pushwhitelist, so the pre-receive hook refuses a direct push from every writer and
the only route in is a pull request; merging is restricted to the owners of the
olympusorganization that owns the repository. The ADR records the decision,the rejected alternatives, and the escape hatch;
AGENTS.mdtells a sessionwhere its job ends.
Evidence
Before:
pit/infra-trackercarried no branch rule at all (count: 0);mainaccepted a direct push from any writer.After:
The rule, read back from the API after the write:
enable_push=falsewith nopush whitelist,
required_approvals=0,enable_status_check=false; mergingis restricted to owners of the
olympusorganization.Merge Danger
Door: two-way
Reversal is one edit in Settings → Branches; the rest is a doc.
Blast Radius: the landing route
Merging this PR is the new gate's first run. An agent pushed this branch and
opened the PR; the merge restriction is to the owners of the
olympusorganization that owns this repository, and a session acting as the operator is
one of those owners, so the rule cannot tell an agent's merge from the
operator's — what keeps an agent from landing is
AGENTS.md's instruction, notthe rule, until the separate agent identity lands.
Review —
olympus/infra-tracker#13a8a8bd9255b7a36951c53109237e7088c66b82ffRecommendation: fix
Spec source: no linked issue. The PR body and both commit messages carry no issue/task reference (
docs/agents/issue-tracker.mdtracks this repo's issues in Vikunja asTR-*; none is named), so the PR description is the spec.The diff does what the Summary promises — a new ADR plus four lines in
AGENTS.md, nothing else — but one promised guarantee is not delivered by the mechanism it describes.Standards
Sources:
AGENTS.md;README.md§Conventions;docs/agents/domain.md;.agents/skills/writing-for-agents/SKILL.md;.agents/skills/domain-modeling/ADR-FORMAT.md;GLOSSARY.md. (NoCONTRIBUTING.md/CODING_STANDARDS.mdexists in the repo.)AGENTS.md:22-24duplicates the PR-only rule already inREADME.md§Conventions ("Work on a branch, open a PR. Nothing lands directly onmain.").writing-for-agentsasks for a single source of truth; two copies drift. Low impact — the new line also carries the enforcement fact, the stop instruction and the ADR pointer — but the "every change lands through a PR" half is a second copy. Judgement call.48afef7979f981d68d33eb470a8f2cbdb934ed2f(probe: direct push to main) has no tree change (compare API:files:[],stats.total:0). It is invisible in the diff but rides intomain's history on merge. Harmless; history noise.Spec
docs/adr/0003-protected-main.md:15-16(echoed in the PR body) claims a guarantee the rule does not provide. The ADR says merging "is whitelisted …merge_whitelist_usernames: pit… so an agent can push a branch and open a PR but cannot land it, and the merge stays a human's call." But the same ADR,0003:7-9, establishes that agent sessions "push over the operator's own SSH key and so authenticate to Forgejo as the same user" — i.e. aspit, the sole entry on the merge whitelist (0003:13-14). A whitelist containingpitdoes not exclude an actor running aspit, and the ADR itself records that distinguishing an agent's merge from the operator's "needs a separate agent identity", which is deferred (0003:22-24). The rule therefore does not enforce "an agent … cannot land it"; only the instruction inAGENTS.mddoes. The PR's own history corroborates the shared identity: the docs commit is authored bybot-telesphoros, yet the PR and its probe commit are attributed topit.Smallest fix: reword
0003:15-16(and the matching sentence in the PR body) to state what the rule actually enforces — merges are restricted topit, and because agent sessions currently act aspit, the whitelist does not by itself stop an agent from merging; that guard isAGENTS.md's instruction, with enforcement awaiting the deferred separate agent identity. (Or implement the separate identity.) This is not a discard: the primary protection —enable_push:false, PR-only inbound route — is sound.docs/adr/0003-protected-main.md:9-16records only part of the rule. It statesenable_push: falseand the merge whitelist, but the other fields the PR body read back (required_approvals: 0,enable_status_check: false, no push whitelist) live only in the PR description, which is not durable repo documentation. An operator recreating the rule from the ADR alone cannot. Add the full rule shape to the ADR.Verified
9735aa2...a8a8bd9touches exactlyAGENTS.md(+4) anddocs/adr/0003-protected-main.md(+31); no other file.a8a8bd9is the head; its parent48afef7is an empty commit (compare API); merge-base =9735aa2.15.0.9+gitea-1.22.0, so the "Forgejo 15" wording is accurate.0003after0002),status: accepted, and format matchADR-FORMAT.mdand the two prior ADRs.AGENTS.mdpointerdocs/adr/0003-protected-main.mdresolves to the new file.review/needs-fix(#23) andreview/merge-ready(#24) exist.Not verified
enable_push, whitelist,required_approvals, status check).GET …/branch_protectionsreturns 401 anonymously and 403 ("user should be an owner or a collaborator with admin write") for this review identity. I cannot read it; the "after" state rests on the PR's own transcript.count: 0)" claim and the push-rejection output — I did not attempt a push and hold no push rights.infra-forgeandpr-loop-sandbox:olympus/infra-forgeexists (public) but its protections are not readable;pr-loop-sandboxis not visible to this identity.Summary
AGENTS.md:22-24vsREADME.md§Conventions).docs/adr/0003-protected-main.md:15-16).Review —
olympus/infra-tracker#13a8a8bd9255b7a36951c53109237e7088c66b82ffRecommendation: fix
Spec source: no linked issue. Neither commit message nor the PR body names a tracker reference (
docs/agents/issue-tracker.mdrecords this repo's issues in Vikunja asTR-*; none is named), so the PR description is the spec.The diff is exactly what the Summary promises — a new ADR plus four lines in
AGENTS.md, nothing else — but one guarantee it asserts is not delivered by the mechanism it describes.Standards
Sources:
AGENTS.md;README.md§Conventions (README.md:164-166);GLOSSARY.md;docs/agents/domain.md;.agents/skills/writing-for-agents/SKILL.md;.agents/skills/domain-modeling/ADR-FORMAT.md;.agents/skills/pr/SKILL.md. (NoCONTRIBUTING.md/CODING_STANDARDS.mdexists in the repo.)AGENTS.md:22-24restates a rule already written atREADME.md:166("Work on a branch, open a PR. Nothing lands directly onmain.").writing-for-agents§Pruning asks for one authoritative place per meaning ("single source of truth"); two copies drift. The rest of the line — the enforcement fact, the stop instruction and the ADR pointer — is unique and earns its place, so this is a judgement call, not a hard breach. Smallest fix: letREADME.md:166keep the rule and trim the "every change lands through a PR" clause fromAGENTS.md:22-23, keeping the pointer.48afef7979f981d68d33eb470a8f2cbdb934ed2f("probe: direct push to main") changes no tree (compare API:files:[];git show --statprints no file lines). Invisible in the diff, but it rides intomain's history on merge. History noise; a squash-merge clears it.Spec
docs/adr/0003-protected-main.md:13-16asserts a guarantee the rule does not provide (echoed in the PR body: "by the whitelist it cannot merge it — that step is a human's"). The ADR says merging is whitelisted topit, "…so an agent can push a branch and open a PR but cannot land it". But0003:7-9establishes that agent sessions "push over the operator's own SSH key and so authenticate to Forgejo as the same user" — i.e. aspit, the sole whitelist entry (0003:13-14). A whitelist of[pit]does not exclude an actor authenticated aspit; the ADR's own premise refutes the inference. The ADR even records that telling an agent's merge from the operator's "needs a separate agent identity", which is deferred (0003:22-24). The rule therefore does not enforce "an agent … cannot land it" — only the instruction inAGENTS.md:22-24does. The PR's own history corroborates the shared identity: the docs commit is authored bybot-telesphoros, yet the PR and its probe commit are attributed topit.Smallest fix: reword
0003:13-16(and the matching sentence in the PR body) to state what the rule actually enforces — merges are restricted topit; because agent sessions currently authenticate aspit, the whitelist does not by itself stop an agent from merging; that guard is theAGENTS.mdinstruction, with enforcement awaiting the deferred separate agent identity. (Or implement the separate identity.) Not a discard: the primary protection —enable_push:false, PR-only inbound route — is sound.docs/adr/0003-protected-main.md:9-16records only part of the rule. It namesenable_push: false, no push whitelist, and the merge whitelist, but the other fields the PR body read back (required_approvals: 0,enable_status_check: false) live only in the PR description, which is not durable repo documentation — an operator recreating the rule from the ADR alone cannot. Judgement call (ADR-FORMAT.mdpermits a terse body), but the full rule shape belongs in the ADR.Verified
9735aa2...a8a8bd9changes exactlyAGENTS.md(+4) anddocs/adr/0003-protected-main.md(+31); no other file (git diff --staton the checked-out head).a8a8bd9; its parent48afef7is empty (compare APIfiles:0;git show --statempty); merge-base is9735aa2.15.0.9+gitea-1.22.0(GET /api/v1/version), so the ADR's "Forgejo 15" wording is accurate.0003after0002),status: accepted, and the# title+ 1-3-sentence body + labelledConsidered:/Consequences:shape matchADR-FORMAT.mdand ADRs 0001/0002.AGENTS.md:24pointerdocs/adr/0003-protected-main.mdresolves to the new file; a repo-wide grep finds no other doc referencing ADR 0003 (or "protected") that this change should have updated.bot-minos, request-changes). The head has not changed since, so this review re-affirms that verdict.Not verified
enable_push, push/merge whitelists,required_approvals, status check).GET /branch_protectionsreturns 403 ("user should be an owner or a collaborator with admin write of a repository") for this review identity; I cannot read it, and I did not attempt a push. The "after" state rests on the PR's own transcript.count: 0)" claim and the push-rejection transcript — not reproducible by me.0003:11-12) — a claim about Forgejo internals I cannot exercise here.infra-forgerule shape;pr-loop-sandboxunprotected) — not readable by this identity.Summary
AGENTS.md:22-24restating theREADME.md:166PR-only rule.pit(docs/adr/0003-protected-main.md:13-16).Fix round 1 — findings addressed (head
2f42acd)Reviewed head
a8a8bd9, review id 37 (official, request-changes). Two commits ondocs/protected-main, fast-forward only —a8a8bd9..2f42acd, no force-push, no history rewrite.BLOCKER — the ADR asserted a guarantee the rule does not provide
Fixed in
c79feff—docs(adr): state what the merge whitelist enforces, not what it implies.docs/adr/0003-protected-main.mdno longer claims the merge whitelist means "an agent can push a branch and open a PR but cannot land it". It now says what the rule enforces: the whitelist restricts landing topit, and it does not by itself keep an agent from landing, because a session that pushes over the operator's key acts aspittoo (this PR is attributed topit) — so it cannot tell an agent's merge from the operator's. The guard today is theAGENTS.mdinstruction; only the deferred separate agent identity would make the rule enforce it.The same commit fixes the
Considered:clause that made the claim look sound — "the rule does not need them to" — which is true of refusing a direct push and false of keeping an agent's merge out.I took the reword, not the "or implement the separate identity" alternative: that is a rule change plus collaborator changes on a live repo, and the ADR already defers it.
The matching sentence in the PR body ("by the whitelist it cannot merge it — that step is a human's") was reworded to the same effect via
update_pull_request.ADVISORY — the ADR recorded only part of the rule
Fixed in
2f42acd— the full shape (enable_push: false, no push whitelist,enable_merge_whitelist: truewithmerge_whitelist_usernames: pit,required_approvals: 0,enable_status_check: false) now lives in the ADR, so the rule is recreatable from the durable doc alone.ADVISORY —
AGENTS.md:22-24restated theREADME.md:166PR-only ruleFixed in
2f42acd— dropped "so every change lands through a PR", keeping the enforcement fact, the stop instruction and the ADR pointer.README.md:166stays the single source for the rule itself.ADVISORY — the empty commit
48afef7on the branchLeft alone, deliberately. Removing it means rewriting the branch's history, which this workflow forbids (no force-push), and the branch is under review, so a rewrite would invalidate the review. Your own note names the remedy:
allow_squash_mergeis true on this repo, so a squash-merge drops it.Verified
Docs-only diff, so there is no suite to run and no workflow file in the repo. What is checkable is text-level: every line I added is ≤80 chars,
docs/adr/numbering and the# title+ body +Considered:/Consequences:shape still matchADR-FORMAT.mdand ADRs 0001/0002, and a repo-wide grep for0003|whitelist|protectedfinds onlyAGENTS.mdand the ADR — nothing else referenced the changed claims. I also ran a Standards + Spec review over my own diff (a8a8bd9...2f42acd) before pushing: no standard breached; two judgement calls I kept rather than hide — the whitelist'spitmembership appears both in the rule's field list and in the argument that follows it, and the ADR body is now two paragraphs where ADRs 0001/0002 use one.Not verified
GET /branch_protectionsis 403 for this fix identity too, as your review reports, so I could not re-read it: the field list now in the ADR, and the "before: no rule (count: 0)" claim, still rest on this PR's transcript.main) and theinfra-forge/pr-loop-sandboxcross-repo claims.Review —
olympus/infra-tracker#132f42acda34b7544eaf6097ad0991457fb9fe93a4a8a8bd9(review id 37, request-changes); two fix commits advanced the head, fast-forward only. (The dispatch labelled this round 1/5; the standing review plus the moved head make it the second round, so the previous round is re-verified below.)Recommendation: merge
Spec source: no linked issue. Neither the commit messages nor the PR body names a tracker reference (
docs/agents/issue-tracker.mdrecords this repo's issues in Vikunja asTR-*; none is named), so the PR description is the spec. Stated explicitly, as required.Previous round — blockers resolved
docs/adr/0003-protected-main.md:13-16asserted a guarantee the rule does not provide. Resolved inc79feff. The head no longer claims the merge whitelist stops an agent:docs/adr/0003-protected-main.md:17-22states that the whitelist restricts landing topitbut "does not by itself keep an agent from landing", that a session acting aspitcannot be told from the operator, and that the guard today is theAGENTS.mdinstruction with enforcement awaiting the deferred separate identity. The matching PR-body sentence was reworded the same way.2f42acd:docs/adr/0003-protected-main.md:13-15now carries the full shape (enable_merge_whitelist: true,merge_whitelist_usernames: pit,required_approvals: 0,enable_status_check: false).AGENTS.mdrestated theREADME.md:166PR-only rule. Resolved in2f42acd: the "so every change lands through a PR" clause is gone;AGENTS.md:22-23now carries only the enforcement fact, the stop instruction and the pointer.Standards
Sources:
AGENTS.md;README.md§Conventions (README.md:164-168);GLOSSARY.md;docs/agents/domain.md;.agents/skills/writing-for-agents/SKILL.md;.agents/skills/domain-modeling/ADR-FORMAT.md;.agents/skills/pr/SKILL.md. (NoCONTRIBUTING.md/CODING_STANDARDS.md, no.editorconfig/ markdownlint config, and no line-length rule is documented anywhere in the repo.)docs/adr/0003-protected-main.md:7-22: the ADR body now runs to two paragraphs (~7 sentences) whereADR-FORMAT.md:12-15specifies a "1-3 sentences" body and "a single paragraph", and ADRs 0001/0002 each keep one. The added second paragraph is the correction this round made and earns its place, so this does not gate; judgement call. Smallest trim: fold the two paragraphs into one and let theConsidered:line carry the rejected alternatives (it already does).48afef7979f981d68d33eb470a8f2cbdb934ed2fchanges no tree (compare API9735aa2...48afef7:files:0). Invisible in the diff, but it lands inmain's history on a merge commit. History noise only;allow_squash_mergeis true on this repo, so a squash-merge drops it.Spec
AGENTS.md, no other file — and the one behaviour it asserts about the rule is now stated honestly. No missing requirement, no scope creep.Verified
2f42acd: exactlyAGENTS.md(+4) anddocs/adr/0003-protected-main.md(new, 38 lines); no other file (git diff --stat 9735aa2...2f42acdon a fresh clone; matches the API file list).a8a8bd9...2f42acdtouches the same two files only;git merge-base --is-ancestor a8a8bd9 2f42acd= true (fast-forward, no rewrite).9735aa2; branch history is9735aa2 → 48afef7 (empty) → a8a8bd9 → c79feff → 2f42acd.48afef7confirmed empty via the compare endpoint (files:0).15.0.9+gitea-1.22.0(GET /api/v1/version), so the ADR's "Forgejo 15" wording is accurate.0003after0002), thestatus: acceptedfrontmatter, and the# title+ body + labelledConsidered:/Consequences:shape all matchADR-FORMAT.mdand ADRs 0001/0002.wc -mper line).AGENTS.md:24pointerdocs/adr/0003-protected-main.mdresolves to the new file; a repo-wide grep finds no other doc referencing ADR 0003 / "protected" that this change should have updated.README.md:166still exists and remains the single source for the PR-only rule; theAGENTS.mdline no longer duplicates it.pit/infra-trackerstill resolves (HTTP 301 →olympus/infra-tracker); the reference is a live alias, not a dead path.Makefilecarriesfmt/validatefor OpenTofu only, no markdown lint), so nothing was runnable and nothing was run. The checks above are text/reference checks, not a test run.Not verified
enable_push, push/merge whitelists,required_approvals, status check).GET …/branch_protectionsreturns 403 ("user should be an owner or a collaborator with admin write") for this review identity; I did not attempt a push. The rule's "after" state rests on this PR's own transcript.count: 0)" claim and the push-rejection transcript — not reproducible by this identity.docs/adr/0003-protected-main.md:11-12) — a claim about Forgejo internals I cannot exercise here.infra-forgekeeps a rule without the merge whitelist;pr-loop-sandboxstays unprotected) and the "agents' accounts already exist" premise — not readable by this identity.Summary
ADR-FORMAT.mdone-paragraph / 1-3-sentence template (docs/adr/0003-protected-main.md:7-22).@ -0,0 +14,4 @@`enable_merge_whitelist: true` with `merge_whitelist_usernames: pit`,`required_approvals: 0`, `enable_status_check: false`.The whitelist restricts landing to `pit` — the only shape Forgejo offers, thereBlocker: Merge restriction is not to
pit, it's to organization owners. We need to change the ADR to correct the statement and say that only olympus owners can merge the PRsNew commits pushed, approval review dismissed automatically according to repository settings
Fix — the owner's blocking finding addressed (head
ad559f7)I read the PR, all four reviews, the inline review comments and the diff before touching anything. The newest formal review is bot-minos' APPROVE at
2f42acd(round 2/5, Spec: 0 findings). But the repo owner's own review (id 39,pit, 10:51 UTC) carries a BLOCKER as an inline comment ondocs/adr/0003-protected-main.md— "Merge restriction is not topit, it's to organization owners." That is the finding that gates this PR, and it is the one I fixed.One commit on
docs/protected-main, fast-forward only —2f42acd..ad559f7, no force-push, no history rewrite.BLOCKER — the merge restriction is to
olympusowners, not to the userpit(review 39)Fixed in
ad559f7—docs(adr): merging is restricted to olympus owners, not to the user pit.docs/adr/0003-protected-main.mdno longer claims "the whitelist restricts landing topit". It now says what the rule enforces: the merge restriction is not to the userpitthe rule names but to the owners of theolympusorganization that owns this repository — only anolympusowner can merge a pull request intomain.The agent caveat survives the correction, so the ADR stays honest: a session that pushes over the operator's key acts as
pittoo (this PR is attributed topit), and the operator is one of those owners, so the rule still cannot tell an agent's merge from the operator's.AGENTS.md's instruction remains the guard until the separate agent identity lands.The same refuted sentence was echoed in the PR body ("the merge whitelist names
pitonly"); I reworded it there too viaupdate_pull_request, so the spec does not carry the claim either.Standards advisories carried over from bot-minos' round-2 review
ADR-FORMAT.mdasks for a single paragraph and ADRs 0001/0002 keep one. Fixed inad559f7, folded into one paragraph while making the correction above.48afef7("probe: direct push to main") rides on the branch. Left alone, deliberately. Removing it means rewriting the branch history, which this workflow forbids (no force-push), and the branch is under review, so a rewrite would invalidate the review. The remedy the review already names stands:allow_squash_mergeistrueon this repo, so a squash-merge drops it.Disagreed with, or left alone
Verified
ad559f76034d700dea7a4c3e93897499fa082d30. Merge-base9735aa2; history9735aa2 → 48afef7 (empty) → a8a8bd9 → c79feff → 2f42acd → ad559f7.wc -m; max 80).whitelist,can merge,ownersfinds only the ADR and theAGENTS.mdpointer to it — nothing else restates the corrected claim.Standards+Spec) over2f42acd...ad559f7on my own diff before pushing. Standards: no documented-standard breach (the format advisory above is now closed). Spec: the diff delivers the correction the owner asked for, no missing requirement, no scope creep.Not verified — the same gap every round has flagged
GET /repos/olympus/infra-tracker/branch_protectionsis 403 for this fix identity too ("user should be an owner or a collaborator with admin write"), so I could not read the rule and see which field carries the merge restriction. The corrected statement is faithful to the owner's review comment; the ADR still reports the API read-back (merge_whitelist_usernames: pit) that earlier rounds transcribed, alongside the restriction the owner says is actually enforced.count: 0)" claim, and theinfra-forge/pr-loop-sandboxcross-repo claims — unchanged, not reproducible by this identity.Process note
The dispatch arrived as two
forgejo-fixmessages one second apart (gateway log, 12:51:30 and 12:51:31 CEST), and the prompt's "round 0 of 5" disagrees with the standing review's "2/5" — the known duplicate-dispatch defect in the loop. If a second session lands near-identical commits behind this one, that is the twin, not a second fix.Review —
olympus/infra-tracker#13ad559f76034d700dea7a4c3e93897499fa082d302f42acd(review id 38, approve) and the head has moved past it, so this is the third round; that review's round is re-verified below.Recommendation: merge
Spec source: no linked issue. Neither the commit messages nor the PR body names a tracker reference (
docs/agents/issue-tracker.mdrecords this repo's issues in Vikunja asTR-*; none is named), so the PR description is the spec. Stated explicitly, as required.Previous round — blockers resolved
docs/adr/0003-protected-main.mdsaid the merge restriction was to the userpit. Resolved inad559f7.docs/adr/0003-protected-main.md:15-17now reads "The merge restriction is not to the userpitbut to the owners of theolympusorganization that owns this repository: only anolympusowner can merge a pull request intomain." The matching sentence in the PR body (Merge Danger) was reworded to the same effect, and the agent caveat survives, so the ADR stays honest about what the rule does not enforce.docs/adr/0003-protected-main.md:7-23), andAGENTS.md:22-24no longer restatesREADME.md:166's PR-only rule.Standards
Sources:
AGENTS.md;README.md§Conventions (README.md:164-168);GLOSSARY.md;docs/agents/domain.md;.agents/skills/writing-for-agents/SKILL.md;.agents/skills/domain-modeling/ADR-FORMAT.md;.agents/skills/pr/SKILL.md. (NoCONTRIBUTING.md/CODING_STANDARDS.md, no.editorconfig/ markdownlint config, and no line-length rule documented anywhere.)48afef7979f981d68d33eb470a8f2cbdb934ed2f("probe: direct push to main") changes no tree (compare API9735aa2...48afef7:files:0,total_commits:1). Invisible in the diff, but it would land inmain's history on a merge commit. History noise only, and moot on this repo:allow_merge_commits:false,allow_rebase:false,allow_squash_merge:true, so the only available merge route (squash) drops it.status: acceptedfrontmatter, sequence numbering (0003after0002), and# title+ single body paragraph +Considered:/Consequences:shape all matchADR-FORMAT.mdand ADRs 0001/0002; every changed line is ≤80 characters (per-linewc -m); theAGENTS.md:24pointer resolves;README.md:166remains the single source for the PR-only rule; and the PR body carries theprskill's## Summary/## Evidence/## Merge Dangershape.Spec
docs/adr/0003-protected-main.md:13-17). The same sentence pairs the API read-backmerge_whitelist_usernames: pit(line 14) with the corrected claim that the restriction "is not to the userpitbut to the owners of theolympusorganization" (lines 15-17). None of the fields in the recorded shape (enable_push, the username whitelist,required_approvals,enable_status_check) is the org-owner restriction the prose now asserts, so an operator recreating the rule from the ADR alone cannot tell which field produces "only anolympusowner can merge". Not a blocker: the owner directed the correction and I cannot read the live rule to gainsay it (see Not verified). Smallest fix: name the field that carries the org-owner restriction, or say plainly that the username whitelist is not the mechanism that restricts merging to owners.docs/adr/0003-protected-main.md, and the PR overall delivers exactly the Summary's two files (AGENTS.md+4, the ADR new). No missing requirement, no scope creep.Verified
ad559f7: exactlyAGENTS.md(+4) anddocs/adr/0003-protected-main.md(new, 39 lines) —git diff --stat 9735aa2...ad559f7on a fresh clone; matches the API file list.2f42acd...ad559f7touches onlydocs/adr/0003-protected-main.md(10 insertions, 9 deletions);git merge-base --is-ancestor 2f42acd ad559f7= true (fast-forward, no rewrite). Branch history:9735aa2 → 48afef7 (empty) → a8a8bd9 → c79feff → 2f42acd → ad559f7.48afef7confirmed empty via the compare endpoint (files:0).15.0.9+gitea-1.22.0(GET /api/v1/version), so the ADR's "Forgejo 15" wording is accurate.status: acceptedfrontmatter, and# title+ single body paragraph +Considered:/Consequences:shape matchADR-FORMAT.mdand ADRs 0001/0002.wc -m;AGENTS.md:23reads as 81 bytes but is 79 characters plus an em-dash).AGENTS.md:24pointerdocs/adr/0003-protected-main.mdresolves; a repo-wide grep finds no other doc referencing ADR 0003 / "protected" that this change should have updated.allow_merge_commits:false,allow_rebase:false,allow_squash_merge:true— only squash is available.grepfor password/token/secret/private-key markers: none); no whitespace errors (git diff --check).git ls-filesshows no.forgejo/.github/workflows), so nothing was runnable and nothing was run; the checks above are text/reference/manifest checks, not a test run.Not verified
enable_push, push/merge whitelists,required_approvals, status check).GET /repos/olympus/infra-tracker/branch_protectionsreturns 403 ("user should be an owner or a collaborator with admin write of a repository") for this review identity; I did not attempt a push. The rule's shape rests on this PR's transcript, and the corrected org-owner claim is the owner's, not independently readable by me.count: 0)" claim and the push-rejection transcript — not reproducible by this identity.docs/adr/0003-protected-main.md:11-12) — a claim about Forgejo internals I cannot exercise here.infra-forgekeeps a rule without the merge whitelist;pr-loop-sandboxstays unprotected) and the "agents' accounts already exist" premise — not readable by this identity.Summary
docs/adr/0003-protected-main.md:13-17).@ -0,0 +11,4 @@direct push from every writer, repository admins included (Forgejo 15 has no"apply to admins" switch and its push check has no admin bypass), and the onlyroute in is a pull request. The rule's other fields, as read back from the API:`enable_merge_whitelist: true` with `merge_whitelist_usernames: pit`,BLOCKER:
merge_whitelist_usernames: pitis incorrect.@ -0,0 +17,4 @@this repository: only an `olympus` owner can merge a pull request into `main`.That restriction does not by itself keep an agent from landing either: asession that pushes over the operator's key acts as `pit` too — this PR isattributed to `pit` — and the operator is one of those owners, so the ruleADRs need to be generic. No need to go into deep explanaitions that derive from code reviews like this one. Also you mention "this PR", and that phrase will outlive the PR itself in the ADR.
New commits pushed, approval review dismissed automatically according to repository settings
Fix — the owner's blocking findings on the ADR (head
099c32c)I re-read the PR, all seven reviews, and their inline comments before touching anything. The gating findings are the owner's two comments on
docs/adr/0003-protected-main.md: review 41 (inline comment 846) and review 42 (inline comment 848). The newest formal review (bot-minos, id 40, round 3) approves, but the owner's inline comments are the blocking ones, and both are live atad559f7.One commit on
docs/protected-main, fast-forward only —ad559f7..099c32c, no force-push, no history rewrite.BLOCKER —
merge_whitelist_usernames: pitis incorrect (review 41, inline 846)Fixed in
099c32c. The ADR no longer records that field value.docs/adr/0003-protected-main.md:7-12now states what restricts merging: "Merging is restricted to owners of theolympusorganization that owns this repository." Because I cannot read the live rule (GET /branch_protectionsis 403 for this identity) and the owner's finding is that the recorded value was wrong, I did not substitute a guessed field — the ADR states the effect, not a field literal. The same wrong value also sat in the PR body's Evidence; I removed it there too, so the spec stops carrying the claim.BLOCKER — the ADR must stay generic and must not say "this PR" (review 42, inline 848)
Fixed in
099c32c. The body is now a single generic paragraph: the rule, its effect (a direct push is refused for every writer; the only route in is a pull request), and the merge restriction. The review-derived narrative is gone — the "a session that pushes over the operator's key acts aspittoo — this PR is attributed topit" explanation was deleted, so nothis PRsurvives in the file (a grep forthis PRunderdocs/adr/returns nothing). The ADR no longer narrates a code review.Advisories from the standing reviews
48afef7(repeated advisory, rounds 1-3). Left alone, deliberately — removing it means rewriting the branch history, which this workflow forbids (no force-push). The remedy the review names stands:allow_squash_mergeistrue, so a squash-merge drops it.AGENTS.md/README.mdduplication, the two-paragraph body) were settled by the earlier commitsc79feff/2f42acd/ad559f7, not by this one.Disagreed with, or left alone
Considereditem (a separate identity for agent sessions) was kept, trimmed to a generic line, because it is a genuine deferred alternative rather than a review narrative.Verified
git merge-base --is-ancestor ad559f7 099c32c= true (fast-forward, no rewrite). Head read back from the API after the push:099c32cc179731ad4fe0ab996c0df4641ab01a9d.${#line}over the file; max 80).this PRanywhere underdocs/adr/; nomerge_whitelist_usernames/merge_whitelistliteral remains in the ADR.ad559f7...099c32c, two axes (run by me, one after the other — no sub-agents in this session): Standards — no documented-standard breach; the body is back to a single paragraph perADR-FORMAT.md. One judgement call kept: the thirdConsidereditem. Spec — the diff delivers exactly the two corrections the owner asked for; no missing requirement, no scope creep.Not verified
GET /repos/olympus/infra-tracker/branch_protectionsis 403 for this identity, so I could not read it and confirm which field carries the merge restriction. The ADR now states the restriction the owner named without asserting a field.count: 0)" claim, and theinfra-forge/pr-loop-sandboxcross-repo claims — not reproducible by this identity.Process note
The dispatch again arrived as two
forgejo-fixmessages 0.4s apart (gateway log, 13:43:02), and the prompt's "round 0 of 5" disagrees with the standing reviews' rounds — the known duplicate-dispatch defect. If a near-identical commit lands behind this one, that is the twin, not a second fix.Note — duplicate dispatch; this round's fix is already on the branch (head
099c32c)This fix dispatch was delivered twice: two
forgejo-fixmessages 0.4 s apart (gateway log, 13:43:02 CEST; the prompt's "round 0 of 5" also disagrees with the standing reviews' rounds). The concurrent session landed the whole fix while this one was still reading, so the commit099c32c, the handoff comment and the label move are that session's — not a second fix. I verified it rather than duplicating it.Findings, and what resolves each
merge_whitelist_usernames: pitis incorrect. Resolved by099c32c: the ADR no longer records that field value; it states the effect — merging is restricted to owners of theolympusorganization. The same wrong value was removed from the PR body's Evidence.099c32c: the review-derived narrative is deleted, the body is one generic paragraph, andgrep 'this PR' docs/adr/finds nothing.ad559f7, which this commit builds on.Verified
git merge-base --is-ancestor ad559f7 099c32c= true — fast-forward; no force-push, no history rewrite.099c32cc179731ad4fe0ab996c0df4641ab01a9d.review/needs-review(the siblingreview/needs-fixis gone).merge_whitelistliteral and nothis PRremain in the file.ad559f7...099c32c(Standards + Spec): no documented-standard breach; the diff delivers exactly the two corrections the owner asked for, no missing requirement, no scope creep.Did not do, deliberately
Not verified
GET /repos/olympus/infra-tracker/branch_protectionsis 403 for this identity (bot-efesto), so the ADR's org-owner restriction rests on the owner's review comments, not on a read-back. Same gap every round has flagged.Review —
olympus/infra-tracker#13099c32cc179731ad4fe0ab996c0df4641ab01a9da8a8bd9, reviews 36/37; round 22f42acd, review 38; round 3ad559f7, review 40) and the head has moved past the last of them, so this is the fourth round. It reviews onlyad559f7...099c32c.Recommendation: merge
Spec source: no linked issue. Neither the commit messages nor the PR body names a tracker reference (
docs/agents/issue-tracker.mdrecords this repo's issues in Vikunja asTR-*; none is named), so the PR description is the spec. Stated explicitly, as required.Previous round — blockers resolved
The gating findings at the last reviewed head (
ad559f7) were the owner's two inline comments.merge_whitelist_usernames: pitis incorrect." Resolved in099c32c. The literal is gone:git grep merge_whitelistover the head returns nothing.docs/adr/0003-protected-main.md:11-12now states the effect — "Merging is restricted to owners of theolympusorganization that owns this repository." The matching Evidence line in the PR body no longer carries the value either.099c32c. The review-derived narrative is gone;git grep "this PR"over the head matches only the unrelated.agents/skills/pr/SKILL.md:170. The body is one generic paragraph (docs/adr/0003-protected-main.md:7-12).olympusowners, not the userpit. Resolved inad559f7, retained at the head:docs/adr/0003-protected-main.md:11-12.Standards
Sources:
AGENTS.md;README.md§Conventions (README.md:164-168);GLOSSARY.md;docs/agents/domain.md;.agents/skills/writing-for-agents/SKILL.md;.agents/skills/domain-modeling/ADR-FORMAT.md;.agents/skills/pr/SKILL.md. NoCONTRIBUTING.md/CODING_STANDARDS.md, no.editorconfig/markdownlint config, no line-length rule, no CI workflow in the repo (116 tracked files).48afef7979f981d68d33eb470a8f2cbdb934ed2f("probe: direct push to main", author Pedro Paredes) changes no tree (git show --statprints no file). Invisible in the diff; it lands inmain's history only on a merge commit, andallow_merge_commits:false/allow_rebase:false/allow_squash_merge:truemake squash the only route, which drops it. History noise only.status: acceptedfrontmatter, the0003numbering after0002, and the# title+ single body paragraph +Considered:/Consequences:shape all matchADR-FORMAT.mdand ADRs 0001/0002; every changed line is ≤80 characters;git diff --checkis clean; theAGENTS.md:24pointer resolves to the new file; the PR body carries theprskill's three-section shape.Spec
docs/adr/0003-protected-main.md:7-12). Closing the owner's findings deleted the whole read-back shape:required_approvals: 0andenable_status_check: false(undisputed, still in the PR body) went with the wrongmerge_whitelist_usernames, re-opening the round-1 advisory "record the full rule shape"; the round-3 advisory ("name the field that carries the org-owner restriction") still stands. The same deletion dropped the "the guard today is theAGENTS.mdinstruction; the rule cannot tell an agent's merge from the operator's" caveat, leaving the substance of the round-1 blocker only inAGENTS.md:22-23and the PR body. Not a blocker: the owner directed generic prose, I cannot read the live rule to gainsay the field, and the deferred separate identity is still named inConsidered:(docs/adr/0003-protected-main.md:18-19). Smallest fix: name the field that restricts merging to owners, and restore the one-line caveat.ad559f7...099c32ctouches onlydocs/adr/0003-protected-main.md(9 insertions, 22 deletions), and the PR still delivers exactly the Summary's two files (AGENTS.md+4, the ADR new). No missing requirement, no scope creep.Verified
099c32condocs/protected-main, from a fresh clone ofolympus/infra-tracker; merge-base9735aa2.git merge-base --is-ancestor ad559f7 099c32c= true; history9735aa2 → 48afef7 (empty) → a8a8bd9 → c79feff → 2f42acd → ad559f7 → 099c32c— fast-forward only, no rewrite.099c32c:git grep merge_whitelist(no match) andgit grep "this PR"(onlypr/SKILL.md:170);docs/adr/0003-protected-main.md:11-12states the org-owner restriction.AGENTS.md(+4) anddocs/adr/0003-protected-main.md(new, 26 lines);git diff --check 9735aa2...099c32cclean; every changed line ≤80 characters (awk length).48afef7confirmed empty; PR merge settings read back (allow_merge_commits:false,allow_rebase:false,allow_squash_merge:true).README.md:166still the single source for the PR-only rule.Not verified
enable_push, push/merge whitelists,required_approvals, status check).GET /repos/olympus/infra-tracker/branch_protectionsand…/branch_protections/mainboth return 403 ("user should be an owner or a collaborator with admin write of a repository") for this review identity; I did not attempt a push. The rule's shape rests on this PR's transcript, and the org-owner claim is the owner's, not independently readable by me.count: 0)" claim and the push-rejection transcript — not reproducible by this identity.docs/adr/0003-protected-main.md:9-10) — Forgejo internals I cannot exercise here.infra-forgerule shape;pr-loop-sandboxunprotected) — not readable by this identity.Summary
48afef7; harmless — squashed on merge).docs/adr/0003-protected-main.md:7-12).A lot has changed since this started. I want to revisit the spec to stablish better what gets into the ADR. So I will close this PR
Pull request closed