Skip to content

docs(OMN-17437): make the grant registry header describe the gate that now exists - #7946

Merged
jonahgabriel merged 3 commits into
mainfrom
hotfix/omn-17437-grant-header-accuracy
Sep 18, 2026
Merged

jonahgabriel merged 3 commits into
mainfrom
hotfix/omn-17437-grant-header-accuracy

Conversation

@jonahgabriel

Copy link
Copy Markdown
Contributor

Follow-up to #7939 (merged as 3022d69e). Closes OMN-17437 AC-4, and doubles as the behavioural proof of AC-1.

hotfix-evidence: OCC-7938
backmerge: #7938

Why

The header of grants/prod_promotion_grants.yaml asserts that landing a grant on main is

the anti-self-issue anchor an agent structurally cannot complete (OMN-13418)

Until 2026-09-01 that was false. main carried requiresApprovingReviews: false / requiresCodeOwnerReviews: false, and the repo's only ruleset (Merge Queue) was DISABLED with no PULL_REQUEST rule, so the CODEOWNERS entry auto-requested a reviewer and blocked nothing. Every grant PR merged in that window — #7084, #7213, #7418, #7464, #7554, #7561, #7662, #7731 — was merge-blocked by CI breadth alone, an accident rather than a control.

#7939 installed the requirement. This PR makes the header say what is actually true, rather than leaving doctrine that asserts an absent gate — the defect class OMN-16847 names.

What the header now records

  • Where the requirement lives: main branch protection, requiresCodeOwnerReviews: true, isAdminEnforced: true — not the CODEOWNERS file on its own.
  • Why the branch-wide controls are off: required_approving_review_count and require_last_push_approval gate every PR into main regardless of code ownership. require_code_owner_reviews is the path-scoped one and covers exactly this file and allowlists/skip_token_approvals.yaml.
  • The window the gap was live, with the eight grant PRs that merged through it.
  • The operational consequence: platform-leads has one member, and GitHub forbids self-approval, so a grant PR authored by that member cannot be approved by anyone. That is the anti-self-issue property working, not a misconfiguration — and the header says explicitly not to "fix" it by relaxing branch protection, adding bypass actors, or broadening CODEOWNERS.

This PR is itself the proof, twice over

It touches grants/prod_promotion_grants.yaml — a CODEOWNERS-covered path — so it should demonstrate both halves of OMN-17437 live:

  1. AC-1: reviewDecision should be REVIEW_REQUIRED and the PR should not be mergeable without a platform-leads approval. Before fix(OMN-17437): make the prod-promotion grant merge mechanically gated on OCC main #7939 the same diff would have been mergeable the moment checks went green.
  2. Leg 2: auto-merge.yml on main now carries the OMN-16117 governance-path exclusion, so this PR must not be armed for auto-merge (autoMergeRequest: null).

Both are recorded on OMN-17437 as the closing evidence.

Blast radius

Comment-only. entries: [] is byte-unchanged and the file still parses with zero grant entries. No grant is issued, approved, consumed or modified; no prod, stability or judge mutation.

@jonahgabriel
jonahgabriel requested a review from a team as a code owner September 1, 2026 09:37
jonahgabriel added a commit that referenced this pull request Sep 1, 2026
…eipts

Adds the occ-self-bind-pr-7946 entry and its PASS receipt per the
eligibility validator's own remediation text, and recomputes
contract_sha256 on the two existing OMN-17437 receipts — the whole-file
hash moves when the contract gains an entry, while per-entry
contract_entry_sha256 values do not (OMN-13888).
@jonahgabriel jonahgabriel reopened this Sep 1, 2026
@jonahgabriel jonahgabriel reopened this Sep 1, 2026
@jonahgabriel
jonahgabriel enabled auto-merge (squash) September 1, 2026 10:10
@jonahgabriel
jonahgabriel enabled auto-merge (squash) September 4, 2026 12:30
@jonahgabriel
jonahgabriel enabled auto-merge (squash) September 6, 2026 05:57
@jonahgabriel

Copy link
Copy Markdown
Contributor Author

Merge-sweep attribution (read-only pass, no mutation made to this PR).

This PR was escalated to a deeper sweep on the claim that a required status check — required-check-skip-guard / check-skip-vectors — "never ran on this PR at all". That claim does not hold, and it is a false red:

  • This PR targets main. required-check-skip-guard / check-skip-vectors is in the required_status_checks contexts of dev, not of main. main's 23 required contexts do not include it.
  • No workflow producing that context exists at origin/main; the only skip-related workflow file there is .github/workflows/call-reject-skip.yml, which produces call-reject-skip-token / scan / reject-skip-gate-token — and that context is required on main and is green here.
  • All 23 of main's required contexts are SUCCESS on head 51a932b9, verified against the check-runs and combined-status APIs rather than against a rendered checks tab.

So there is no missing check and no workflow bug. The actual reason mergeStateStatus is BLOCKED is the CODEOWNERS review requirement: main's CODEOWNERS assigns grants/prod_promotion_grants.yaml to the platform-leads team, this PR adds 37 lines to that file, and the review request to that team is still outstanding. That is the OMN-17437 gate doing exactly what it was built to do — this PR is the deliberate "BLOCKED arm" of that ticket's controlled experiment, and the sibling PR with no CODEOWNERS path merged cleanly under the identical configuration.

That review cannot come from this lane, and it cannot come from the author: GitHub forbids self-approval, and the author is a member of the reviewing team. The team now has two members, so an approval from the other member is the unblock. No gate change, no CODEOWNERS broadening, and no bypass actor was considered or applied.

Left open deliberately. Recorded so the next sweep does not re-escalate this as a workflow defect.

@jonahgabriel
jonahgabriel enabled auto-merge (squash) September 12, 2026 15:22
@jonahgabriel

Copy link
Copy Markdown
Contributor Author

Manual merge-sweep update: live checks are green (38 success, 0 fail, 0 pending), but this PR touches grants/prod_promotion_grants.yaml and its own proof contract says auto-merge must remain null for the governance-path exclusion. Live state had auto-merge armed, so I disabled auto-merge. Not merging this through the governance/codeowner gate from the sweep lane.

@jonahgabriel
jonahgabriel enabled auto-merge (squash) September 14, 2026 06:26
@jonahgabriel
jonahgabriel enabled auto-merge (squash) September 14, 2026 23:32
@onexbot-occ-writer

Copy link
Copy Markdown
Contributor

OCC autobind stood down for OmniNode-ai/onex_change_control#7938 (OMN-17437): this PR (hand_authored) already carries evidence for that ticket, so no competing companion was minted (OMN-15247 defer-on-contention).

@jonahgabriel
jonahgabriel enabled auto-merge (squash) September 15, 2026 13:15
@jonahgabriel

Copy link
Copy Markdown
Contributor Author

codex-merge-sweep update: disabled auto-merge again on head 9ab973c78f7c. This PR remains intentionally held behind the main-branch CODEOWNERS/governance review for grants/prod_promotion_grants.yaml; not merging from the sweep lane.

@jonahgabriel
jonahgabriel enabled auto-merge (squash) September 16, 2026 18:14
@jonahgabriel

Copy link
Copy Markdown
Contributor Author

codex-merge-sweep update: disabled auto-merge again on head 9ab973c78f7c. Checks are green, but this PR is intentionally held behind the main-branch CODEOWNERS/governance review for grants/prod_promotion_grants.yaml; the sweep lane is not merging it or letting auto-merge bypass that proof condition.

@jonahgabriel
jonahgabriel enabled auto-merge (squash) September 17, 2026 02:00
@onexbot-occ-writer

Copy link
Copy Markdown
Contributor

OCC autobind stood down for OmniNode-ai/onex_change_control#9944 (OMN-17437): this PR (hand_authored) already carries evidence for that ticket, so no competing companion was minted (OMN-15247 defer-on-contention).

…t now actually exists

The header asserted that landing a grant on main is 'the anti-self-issue
anchor an agent structurally cannot complete'. Until 2026-09-01 that was
false: main carried requiresApprovingReviews=false and
requiresCodeOwnerReviews=false, and the only ruleset was DISABLED with no
PULL_REQUEST rule, so the CODEOWNERS entry auto-requested a reviewer and
blocked nothing. Every grant PR in that window was merge-blocked by CI
breadth alone.

Records where the requirement actually lives now, why the branch-wide
controls (required_approving_review_count, require_last_push_approval) are
deliberately off while the path-scoped require_code_owner_reviews is on, the
window in which the gap was live, and the consequence that matters
operationally: platform-leads has one member, so a grant PR authored by that
member cannot be approved by anyone. That is the property working, and the
header now says so rather than implying the flow is unchanged.
…eipts

Adds the occ-self-bind-pr-7946 entry and its PASS receipt per the
eligibility validator's own remediation text, and recomputes
contract_sha256 on the two existing OMN-17437 receipts — the whole-file
hash moves when the contract gains an entry, while per-entry
contract_entry_sha256 values do not (OMN-13888).
@jonahgabriel
jonahgabriel force-pushed the hotfix/omn-17437-grant-header-accuracy branch from 9ab973c to 17fb4ff Compare September 17, 2026 16:12
@jonahgabriel

Copy link
Copy Markdown
Contributor Author

codex-merge-sweep update: disabled auto-merge again on head 17fb4ffa60b3. This PR remains intentionally held behind the main-branch CODEOWNERS/governance review for grants/prod_promotion_grants.yaml; the sweep lane is not merging it or letting auto-merge bypass that proof condition.

…is-not-author basis

The header asserted that platform-leads has a single member and that a grant PR
authored by that member could not be approved by anyone. That was accurate on
2026-09-01 and is not accurate now: the team has two members, verified live via
gh api orgs/OmniNode-ai/teams/platform-leads/members, so a grant PR authored by
one member is approvable by the other and the code-owner review is a review a
second person actually performs.

Restates the anti-self-issuance property on its real basis — approver-is-not-author
refusals evaluated against the grant's own fields — rather than on an approver set
too small to approve anything. Names both refusals and where each one runs:

  - the dispatch gate in omninode_infra scripts/validate_prod_promotion_grant.py,
    which refuses approved_by == the requesting identity as self_granted;
  - the authoring-time refusal in this repo's grants validator, which per a live
    tree read is present on dev and ABSENT on main, the branch grant PRs target,
    so it does not run on this path.

Stating that second half rather than implying it, because the header exists to
stop this file from asserting a control it does not have.

Doc-only. One file, comments only. No entry, schema, runtime or src change.
@jonahgabriel

Copy link
Copy Markdown
Contributor Author

Amended: the approver-set paragraph now says two members, on the approver-is-not-author basis

Addresses the review finding that three lines asserted a one-member reviewing team. That was accurate when the header was written on 2026-09-01. It is not accurate now.

Live member count, read at amend time:

$ gh api orgs/OmniNode-ai/teams/platform-leads/members --jq '[.[].login]'
["jonahgabriel","jake-b-omni"]

Two members. The header names the count only, not the people — a governance document should not go stale on a roster change.

What changed

One file, comments only: grants/prod_promotion_grants.yaml. No entry, no schema field, no src/, no runtime.

Before (the three lines the review flagged, plus their conclusion):

# CONSEQUENCE WORTH KNOWING BEFORE YOU OPEN A GRANT PR. `platform-leads` has a
# single member. GitHub forbids approving your own pull request, so a grant PR
# authored by that member cannot be approved by anyone and will not merge. That
# is the anti-self-issue property working as designed, not a misconfiguration:
# closing it needs a second platform-lead, or grant PRs opened under a non-lead
# identity so the operator can approve.

After, in substance: the team has two members, so a grant PR authored by one is approvable by the other, and the code-owner review above is a review a second person actually performs rather than a requirement nobody can satisfy. The anti-self-issuance property does not rest on an approver set too small to approve anything. It rests on approver-is-not-author refusals evaluated against the grant's own fields.

The closing guidance is unchanged: a stalled grant PR is waiting on a review a colleague can give, and is never repaired by relaxing branch protection, adding bypass actors, or broadening the CODEOWNERS rule.

One thing I found while writing it, which you should read before approving

The amendment names both approver-is-not-author refusals and where each one actually runs, because on this PR's base branch they are not both live:

  • At dispatch. omninode_infra scripts/validate_prod_promotion_grant.py refuses an entry whose approved_by equals the promoting identity, as outcome self_granted. Verified live: comparison at :503, enum member at :175. That identity is the deploy dispatcher, unknowable at authoring time, so it cannot be pre-satisfied from the grants file.
  • At authoring time, on dev only. This repo's grants validator makes the same refusal against the PR author, but the module is not on main, and grant PRs target main:
$ git ls-tree -r --name-only origin/main | grep -i prod_promotion
grants/prod_promotion_grants.yaml
tests/test_prod_promotion_grants.py
tests/test_prod_promotion_grants_manifest_kind.py

$ git ls-tree -r --name-only origin/dev | grep -i prod_promotion
grants/prod_promotion_grants.yaml
src/onex_change_control/scripts/revoke_prod_promotion_grants.py
src/onex_change_control/scripts/validate_prod_promotion_grants.py
tests/test_prod_promotion_grants.py
...

main's inline validator in .github/workflows/validate-prod-promotion-grants.yml carries no self-approval refusal either; its own comment says the property is enforced at dispatch. So on the branch grants are authored against, the dispatch gate is the surviving mechanical control, and the header now says that instead of implying both halves are live. I wrote it that way deliberately: this header exists to stop the file asserting a control it does not have, so under-claiming is the only safe direction.

State

  • Head 6fbe83596e5adb81534dd64fa610d8a12fde0d91, all checks pass, zero non-passing contexts.
  • Base branch protection re-read live and unchanged: require_code_owner_reviews: true, required_approving_review_count: 0, enforce_admins: true, require_last_push_approval: false. The header's description of the gate is still accurate.
  • mergeStateStatus: BLOCKED pending the code-owner review, and autoMergeRequest is null. Both of this ticket's behavioural probes therefore still read correctly after the amendment.

I have not approved this, have not landed it, and have not requested review from anyone — platform-leads was auto-requested by the CODEOWNERS rule. Over to you.

@jake-b-omni jake-b-omni left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. Verified the header's claims against live state on 2026-09-18 rather than reading them:

  • main branch protection: require_code_owner_reviews true, required_approving_review_count 0, dismiss_stale_reviews true, enforce_admins true, require_last_push_approval false — matches the block as written.
  • platform-leads has two members, so the code-owner review is one a second person can actually give.
  • src/onex_change_control/scripts/validate_prod_promotion_grants.py is present on dev (f42ba1fb) and 404s on main, so the authoring-time half genuinely does not run on the branch grant PRs target.
  • omninode_infra/scripts/validate_prod_promotion_grant.py: SELF_GRANTED enum member at :175, approved_by == requested_by comparison at :503. The dispatch refusal is the surviving mechanical control, as stated.

One operational consequence worth naming somewhere, since the dispatch gate compares approved_by against the dispatching identity: on the grants I author, you have to be the one who dispatches the promotion, or the gate refuses it as self_granted.

@jonahgabriel
jonahgabriel merged commit 2a98f9c into main Sep 18, 2026
38 of 39 checks passed
@jonahgabriel
jonahgabriel deleted the hotfix/omn-17437-grant-header-accuracy branch September 18, 2026 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants