Repository navigation
Release governance gap: admin self-merge bypass and v0.1.0 tag churn (follow-up to #81) #124
Copy link
Copy link
Closed
Labels
area:infraCI, release, packaging, and repository infrastructureCI, release, packaging, and repository infrastructureevidence:e3-reproducedMaintainer reproduced with deterministic stepsMaintainer reproduced with deterministic stepsstatus:readyScope and acceptance criteria are ready for developmentScope and acceptance criteria are ready for developmenttype:maintenanceMaintenance, tooling, refactoring, or repository workMaintenance, tooling, refactoring, or repository work
Description
schemaVersion: requirement-record.v1
revision: R4
status: ready
priority: P1
productOwner: "@PeterGuy326"
technicalOwner: "@PeterGuy326"
implementationOwner: "@waterbro-8"
automatedPreReviewOwner: "GitHub Actions"
humanReviewOwner: "@Bindy-lbb"
userOutcome: "Release-blocking pull requests retain independent CODEOWNER review while no single reviewer creates an avoidable availability bottleneck."
requirements:
- REQ-001
- REQ-002
- REQ-003
acceptanceCriteria:
- AC-001
- AC-002
- AC-003
parent: null
dependencies: []
supersedes:
- "R1 free-form governance record"
lastDecisionAt: "2026-08-31T12:09:30Z"User problem and observable outcome
The repository already requires a current independent CODEOWNER approval and
strict CI, but only two owners made every author-owned release candidate depend
on the one remaining reviewer. The owner-approved third reviewer is available
as a bounded availability improvement, not as a relaxation of protections.
Observable outcome: .github/CODEOWNERS lists exactly
@PeterGuy326 @Bindy-lbb @waterbro-8 for the repository, and a current-head
candidate is independently reviewed under the unchanged branch protections.
Requirements
- REQ-001: Add only
@waterbro-8as the third CODEOWNER in the existing global
rule. - REQ-002: Preserve strict required checks, code-owner review, last-push
approval, linear history, conversation resolution, no force pushes, no
deletions, and admin enforcement. - REQ-003: Preserve release-tag authority boundaries; the code-owner change does
not grant tag creation, update, deletion, or new repository roles.
Acceptance criteria
- AC-001: The exact candidate diff changes only
.github/CODEOWNERSto the
approved three-owner line. - AC-002: All required CI is green on an up-to-date exact head.
- AC-003: A non-author, non-last-pusher current CODEOWNER gives the final
approval; no admin bypass or self-approval occurs.
Scope and non-goals
- Scope: the single CODEOWNERS line and its review evidence.
- Non-goals: changing branch protections, collaborator roles, tag rulesets,
required-approval counts, orGOVERNANCE.mdrelease guidance. - Related work: docs(governance): add GOVERNANCE.md release governance charter #125 remains a separate documentation candidate and must be
corrected independently to match the live configuration.
Lifecycle, priority, blockers, and open decisions
- status=ready; priority P1; implementation candidate is chore(codeowners): add a third independent code owner #132.
- Blocker: chore(codeowners): add a third independent code owner #132 is behind
main; its source must be brought to the current base
and its exact head must receive fresh required CI. - Final human review owner:
@Bindy-lbbif@PeterGuy326performs the normal
non-force source-branch synchronization; no participant may review their own
implementation head.
Evidence plan and latest evidence
| AC | Planned evidence | Current result |
|---|---|---|
| AC-001 | Exact pull-request file diff | Candidate currently has one CODEOWNERS-line change; re-read after sync |
| AC-002 | Required check URLs on current head | NOT VERIFIED: #132 is behind main |
| AC-003 | GitHub review record and protection read-back | NOT VERIFIED: final reviewer waits for a stable green synchronized head |
Decisions and revision history
- R1: original free-form release-governance record.
- R2 (2026-08-31): admin enforcement was applied without changing other
protections; it initially retained two CODEOWNERS. - R3 (2026-08-31T11:54:27Z): the founder-approved addition of
@waterbro-8is
canonicalized; decision:
Release governance gap: admin self-merge bypass and v0.1.0 tag churn (follow-up to #81) #124 (comment). - R4 (2026-08-31T12:09:30Z): lifecycle correction establishes the completed
R3 scope as ready for normal CI and independent review; decision:
Release governance gap: admin self-merge bypass and v0.1.0 tag churn (follow-up to #81) #124 (comment).
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area:infraCI, release, packaging, and repository infrastructureCI, release, packaging, and repository infrastructureevidence:e3-reproducedMaintainer reproduced with deterministic stepsMaintainer reproduced with deterministic stepsstatus:readyScope and acceptance criteria are ready for developmentScope and acceptance criteria are ready for developmenttype:maintenanceMaintenance, tooling, refactoring, or repository workMaintenance, tooling, refactoring, or repository work
Activity
PeterGuy326 commentedon Aug 31, 2026
Blocking correction before any admin action:
I read the live protection object back from the API. The current
mainsettings already have:strict: truedismiss_stale_reviews: truerequire_code_owner_reviews: truerequire_last_push_approval: truerequired_approving_review_count: 1required_linear_history: truerequired_conversation_resolution: trueenforce_admins.enabled: falseThe full-replacement PUT payload in this issue is unsafe as written: it changes
require_last_push_approvalto false, changesrequired_linear_historyto false, and omits the currently enabledrequired_conversation_resolutionfield. Applying it would close one bypass while weakening at least three existing gates.No branch-protection mutation is authorized by the current tag-ruleset approval, so do not run that PUT. If the owner separately authorizes enforcing protection for admins, GitHub exposes a narrow endpoint that preserves the rest of the protection object:
Before/after must be read back and asserted field-for-field, with the only intended delta
enforce_admins.enabled: false -> true. GitHub documents this as “Set admin branch protection”: https://docs.github.com/en/rest/branches/branch-protection#protect-repository-adminsAlso, PR #125 currently fails the canonical issue/title policy. This issue needs the repository's required type/status/area/evidence labels and readiness gate; the PR should link the canonical ready issue and must not imply that the setting change is already authorized or mechanically enforced.
PeterGuy326 commentedon Aug 31, 2026
Maintainer decision and applied admin action (2026-08-31, Asia/Shanghai):
@PeterGuy326and@Bindy-lbb(Totoro). A third owner is optional redundancy, not a correctness requirement. For a PR authored by either owner, the other owner provides the required independent CODEOWNER approval; authors cannot approve their own PR.Bindy-lbb, notlibibi; no extra identity should be added based on that name.POST /repos/fullstack-ai-infra/mem/branches/main/protection/enforce_admins.enforce_admins.enabled: false -> true.Protect stable release tagsis active onrefs/tags/v*, blocks update and deletion, and has no bypass actors.The admin-bypass portion of this issue is now resolved. Remaining work is to correct, re-review, and merge #125 without weakening the live settings.
PeterGuy326 commentedon Aug 31, 2026
Additive maintainer decision (2026-08-31, Asia/Shanghai): the founder authorized adding Feng Haoran as an individual minimal reviewer; his verified GitHub login is waterbro-8. The earlier two-owner setup remains valid, but the observed #125/#130 bottleneck justifies exercising the optional third-owner redundancy. Before granting write, tag authority was separated safely: new active ruleset 21899500 lets only RepositoryRole admin create refs/tags/v*, while existing ruleset 21888356 remains unchanged and blocks tag update/deletion with no bypass. waterbro-8 now has write, not maintain/admin, and cannot create, update, or delete release tags. @waterbro-8: please open a PR from exact main 731a468 whose only diff changes .github/CODEOWNERS to * @PeterGuy326 @Bindy-lbb @waterbro-8; use Refs #124, do not push main/tag/self-review/admin-merge, and reply with the PR URL plus exact head SHA. Peter can review that waterbro-authored PR under the existing base CODEOWNERS policy.
PeterGuy326 commentedon Aug 31, 2026
Owner record correction: the later founder decision is now the canonical R3
record. #132 must still be up to date, have current required CI, and receive an
independent current-head CODEOWNER approval; it is not an authorization to
self-approve, bypass protection, or grant further repository permissions.
PeterGuy326 commentedon Aug 31, 2026
Owner lifecycle correction: the accepted requirement is ready for normal CI and
review. It is not accepted, merged, or permission-effective until those distinct
events occur under unchanged protections.
PeterGuy326 commentedon Aug 31, 2026
Implementation candidate correction (R4 scope unchanged)
474fb334478a0569bed903181cca2d54e44abd95, basecc727db0bc72655f299166de1f60756f5c686cc7..github/CODEOWNERS.@Bindy-lbbwas requested once for independent current-head CODEOWNER review. The author and last pusher will not self-approve.This is candidate evidence, not merge/acceptance evidence; R4 remains open until normal authorized merge, push/main checks, verification ledger, and product acceptance.
chore(codeowners): add third independent reviewer (bytefolk#124)
sun-970 commentedon Sep 1, 2026
Implementation candidate #138 was behind
main; rebased and re-opened as #145 (exact headfd20da8, rebased onto currentmain). The diff is unchanged: one-line.github/CODEOWNERSupdate per R4. Awaiting required CI and independent@Bindy-lbbCODEOWNER review.Bindy-lbb commentedon Sep 1, 2026
Resolution update (Bindy-lbb, independent CODEOWNER review).
Two implementation candidates had accumulated for this record: #132 (original, went stale behind main), #138 (a clean re-creation, single self-consistent PeterGuy326-authored commit), and #145 (a duplicate that appeared via a fork PR from a 2-day-old, read-only account "sun-970," carrying an unsigned commit with a mismatched author/committer identity — author claimed "PeterGuy326," committer was "liyuanyang," who is not an org member).
Action taken:
mainvia the standard update-branch API (merge commit7a532f2e), re-verified to still contain only the single approved.github/CODEOWNERSline change, confirmed CI 15/15 green on the exact resulting head, and independently APPROVED by @Bindy-lbb.AC-001/AC-002 satisfied on #138's exact head. AC-003 satisfied: the reviewer (@Bindy-lbb) is neither the PR author nor the account that pushed the last content commit (the update-branch merge commit added no content), and is not the subject being added.
Next step: PeterGuy326 (or another maintainer with merge rights) squash-merges #138 through the normal flow; no admin bypass needed since it's already green and approved.
chore(codeowners): add third independent reviewer (#138)
waterbro-8 commentedon Sep 3, 2026
Closed: all three acceptance criteria verified after the merge
Merged as squash commit
4cf4452ee3e05cf28509f7ab575ac9aaf26393fe(chore(codeowners): add third independent reviewer (#138)), parent2e4ec461(the merge of #159). Evidence below is read back from GitHub, not inferred from the PR description.AC-001 — exact candidate diff changes only
.github/CODEOWNERSto the approved three-owner line: PASSGET /pulls/138/filesreturns exactly one file,modified 1+/1-:Read-back on the resulting
main:.github/CODEOWNERSnow contains* @PeterGuy326 @Bindy-lbb @waterbro-8and nothing else changed.AC-002 — all required CI green on an up-to-date exact head: PASS
This PR sat at
mergeable_state=behindfor most of the day becausemainkept moving. After #159 landed (2e4ec461, 14:05:02 local), the branch was synced, producing heada12f388aon base2e4ec461.GET /commits/a12f388a/check-runsthen reports 15/15 legscompleted/success, andmergeable_stateflippedblocked → cleanas the last two legs (Go,PostgreSQL integration) finished. TheWeb → Audit dependenciesleg that had been red — onmainitself, from thebrowserslist <=4.28.6high advisory — is green here only because #159 landed first; that dependency bump is what unblocked this candidate.AC-003 — a non-author, non-last-pusher current CODEOWNER gives the final approval; no admin bypass, no self-approval: PASS
PeterGuy326.waterbro-8(the base-sync merge commita12f388a).Bindy-lbb APPROVED, andGET /pulls/138/reviewsattributes it tocommit_id = a12f388a— i.e. the approval is current on the exact head that was merged, not on the pre-sync headbb9415d6.PUT /pulls/138/merge(merge_method=squash).waterbro-8holdspush/triageandadmin: false, so there was no bypass capability available, and none was used.Bindy-lbbis neither the author nor the last pusher, and is a listed code owner.REQ-002 / REQ-003 read-back: no branch protection, collaborator role, tag ruleset or workflow file was touched by this change — the diff is the single CODEOWNERS line, so protections and release-tag authority boundaries are unchanged by construction.
What this does not close
docs(governance): add GOVERNANCE.md) is alsoRefs #124, but it is not one of this issue's acceptance criteria and is still open — it currently carries aCHANGES_REQUESTEDfromPeterGuy326on its head4a16bd83. Nothing in this closure implies docs(governance): add GOVERNANCE.md release governance charter #125 is done.One consequence worth stating out loud, since it is the thing this issue was about
waterbro-8is now a code owner on this repository. That means a self-approval path exists on PRs authored bywaterbro-8(#125,#131,#161today) that did not exist yesterday — the review requirement could now be satisfied by the author's own account. This issue's premise was that no single reviewer should be an avoidable bottleneck, not that the author may sign their own work, and AC-003 names self-approval as something that must not occur. There is no technical barrier to it after this merge; only policy. "A code owner does not approve PRs they authored or last pushed" is the reading that keeps #124's outcome intact. For this merge specifically the record is unambiguous: the approval came fromBindy-lbb, and no review fromwaterbro-8was needed or used.docs(governance): track live CODEOWNERS policy and both tag rulesets
docs(governance): track live CODEOWNERS policy and both tag rulesets
docs(governance): add GOVERNANCE.md with the tag-ruleset record corre…