Repository navigation
chore(OMN-16799): prod-promotion grant for the onex-api cutover + api.omninode.ai hostname reclaim - #7418
Merged
Conversation
…omninode.ai hostname reclaim Two entries under a new promotion_batch_id batch-404af076-32a6-449c-b60a-1e8848e3fe3c, authorizing exactly one gated deploy-onex-prod.yml dispatch with deploy_target=onex-api AND reclaim_api_hostname=true: grant-7ebd7674 runtime same-digest sha256:13c96028... (mechanically required) grant-7013b49e onex-api promotion sha256:bc95b9bc... (the actual change) Entry 1 is not optional. deploy-onex-prod.yml's "Enforce prod-promotion grant - runtime image (OMN-14209)" step carries NO `if:` guard, so it runs on a deploy_target=onex-api dispatch too and resolves RUNTIME_IMAGE_REF from k8s/onex-prod/runtime/kustomization.yaml (sha256:13c96028 on both omninode_infra main and dev). A single-entry grant covering only the onex-api digest would have blocked at the first gate. Because the committed runtime pin equals what is live, the apply is a no-op for the runtime image. Digest provenance for entry 2, verified rather than asserted: ECR 272493677981.dkr.ecr.us-east-1.amazonaws.com/omnicloud/core, built by "Build and push onex-api image to ECR" run 33179880143 (success, 2026-08-28T14:23:12Z) from omninode_infra main at headSha 8a4ebe6919a52f8de272fb908e90866e8514e3cd and tagged with that SHA - which is how resolve-ecr-digest (exact-match only; fallback-to-latest is not passed) resolves it at dispatch. approved_by is disclosed as a PROPOSAL, not an approval. As staged the PR author and approved_by are both jonahgabriel, which is self-approval on main's own header rule; that is written down rather than claimed away. Consumer-side anti-self-approval is satisfied only by dispatcher != approved_by, so the dispatcher must be daniyalabbas96 as staged. Verified both directions by running the consumer's own script offline against this file: daniyalabbas96 + either digest -> PASS jonahgabriel + either digest -> BLOCKED (self_granted) expires_at 2026-08-30T16:00:00Z is a PROPOSAL (~49h); the approver may shorten it at merge time. PRUNED: the two OMN-16626 entries (grant-3c885a33 runtime, grant-9c23ed5d omniintelligence) both expire 2026-08-28T20:00:00Z, hours from this staging. The OMN-13424 invariant refuses any expired entry, so the file cannot pass CI with them present past that timestamp. grant-3c885a33 was already spent in substance by run 33117155819 and its digest is re-authorized identically by entry 1; grant-9c23ed5d was never mechanically read by any gate (its own reason says so) and the pin it recorded is already on omninode_infra main (#1016) and applied. Re-issue it in its own PR if a fresh omniintelligence authorization is wanted. Header lines 1-46 carried forward byte-identical from main. PREP ONLY - must be landed on main by a human operator (CODEOWNERS). That merge is the approval act; no agent merges this. Evidence-Ticket: OMN-16799
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
…t eligibility resolves occ-preflight / eligibility and verify / verify resolve OCC evidence from the PR diff for onex_change_control's OWN PRs (design invariant I3, in-tree checkout) -- call-occ-preflight.yml sets sha=$(git rev-parse HEAD) and reads contracts/ and drift/dod_receipts/ against the PR head checkout, never against the base branch. So the pinned OCC evidence for #7418 IS #7418's own tree, and the contract has to land on the branch itself. Landing it on OCC dev would not be read at all; this PR targets main. Adds, on the branch: contracts/OMN-16799.yaml drift/dod_receipts/OMN-16799/dod-prod-promotion-grant-values-omn16799/command.yaml drift/dod_receipts/OMN-16799/dod-prod-promotion-grant-validation-omn16799/command.yaml drift/dod_receipts/OMN-16799/dod-prod-promotion-grant-consumer-gate-omn16799/command.yaml drift/dod_receipts/OMN-16799/occ-self-bind-pr-7418/command.yaml Same shape OCC#7084 (OMN-16205) and OCC#7213 (OMN-16626) used for grant PREP on this same base: contract + receipts in the grant PR itself. All three substantive check_values are real falsifiable probes, never `grep -q '^status: PASS$' <the receipt itself>`, which tests/test_evidence_admissibility.py lists as a REFUSED shape. - grant-values: three-clause grep for both grant_ids plus the shared promotion_batch_id. Exits 0 here, non-zero on onex_change_control@main, which carries neither grant_id. - grant-validation: uv run pytest tests/test_prod_promotion_grants.py -q (18 passed), which includes the OMN-13424 at-rest invariant test that fails on any expired entry -- the falsifying test for the OMN-16626 prune. - consumer-gate: the CONSUMER's own script (omninode_infra/scripts/validate_prod_promotion_grant.py, the exact one deploy-onex-prod.yml runs) driven offline via --grants-file, all four combinations. daniyalabbas96 + either digest -> exit 0 PASS; jonahgabriel + either digest -> exit 1 BLOCKED (self_granted). The BLOCKED rows are the substance: they prove the anti-self-approval interlock is live on this path rather than asserted in prose, and they establish that with approved_by staged as jonahgabriel the dispatcher MUST be daniyalabbas96. Receipts carry contract_entry_sha256 (OMN-13888 per-entry binding) plus the whole-file contract_sha256. No skip tokens. No gate edits. No change to grants/prod_promotion_grants.yaml in this commit. #7418 remains for a CODEOWNERS operator to merge -- that merge is the approval act (OMN-13418), and no agent merges it. Evidence-Ticket: OMN-16799
…ted OCC gate declines it
The dod-prod-promotion-grant-consumer-gate-omn16799 check rooted its command at
$OMNINODE_INFRA, an env var the hosted Contract Compliance gate does not set, so
it resolved to /scripts/validate_prod_promotion_grant.py and hard-BLOCKed the PR.
Declare cwd ${OMNI_HOME}/omninode_infra instead (OMN-16824): the hosted gate
checks out exactly one product repo, leaves ${OMNI_HOME} empty, and DECLINES the
check as NOT-EVALUATED rather than rerouting it at a tree it was never pointed at.
Proven live on this same gate by OCC#7403 (OMN-16838).
The grants-file argument moves to a required OCC_GRANTS_FILE env var so the
command fails loud rather than silently validating the wrong checkout.
Receipt re-run locally against the new shape: all four probe rows (2 dispatchers
x 2 digests) re-executed with real exit codes, contract_entry_sha256 and
contract_sha256 recomputed.
…receipt ModelDodReceipt forbids extra inputs; occ-preflight rejected the receipt with 'cwd Extra inputs are not permitted'. cwd is a CONTRACT check field (OMN-16824), not a receipt field — the contract keeps it, the receipt states the cross-repo execution context in actual_output instead.
This was referenced Sep 1, 2026
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.
What the approver is being asked to do
Merge this PR. That merge is the approval act (OMN-13418) — an agent structurally cannot complete a CODEOWNERS-gated merge to
main, which is exactly why the merge, not any field in the file, is the anti-self-issue anchor. No agent will merge this.Ticket: OMN-16799.
After this lands, the operator surface is two more things, in order: un-draft + merge
omninode_infra#1044, then have the dispatcher fire the deploy. Nothing else.What this grant authorizes
Exactly one gated
deploy-onex-prod.ymldispatch, run withdeploy_target=onex-apiANDreclaim_api_hostname=truein the same run. Those are deliberately coupled:omninode_infra#1044'sValidate reclaim_api_hostname inputstep refusesreclaim_api_hostname=trueunlessdeploy_targetisonex-api/all, precisely soapi.omninode.aican only ever be pointed at an onex-api digest this gate has already cleared. Promotion and hostname reclaim ride one dispatch.It authorizes no other prod mutation, and no prod mutation has occurred.
Two entries, both mechanically required
deploy-onex-prod.ymlruns the OMN-14209 grant gate twice on adeploy_target=onex-apidispatch:Enforce prod-promotion grant — runtime imageRUNTIME_IMAGE_REFfromk8s/onex-prod/runtime/kustomization.yaml→sha256:13c96028…grant-7ebd7674-9b25-466c-920d-a74a0f3efadbEnforce prod-promotion grant — onex-api imageif: deploy_target != 'runtime-only'commit_sha→sha256:bc95b9bc…grant-7013b49e-f714-4ead-8910-e6ffda84df56The runtime step's own comment states it: "Runtime image is deployed unconditionally for every deploy_target value … so this check also runs unconditionally." A single-entry grant covering only the onex-api digest would have blocked at the first gate before ever reaching the second. Entry 1 is a same-digest authorization —
sha256:13c96028…is what onex-prod's runtime plane is already running and what is pinned on omninode_inframain(8a4ebe69) anddev(ab92b08b) alike, sokubectl apply -kis a no-op for the runtime image and no runtime pod is rescheduled.Digest provenance (entry 2 — the real promotion)
272493677981.dkr.ecr.us-east-1.amazonaws.com/omnicloud/coresha256:bc95b9bc5a1860dd666ecea4e82e278ff4ddb2d08da5d280ba8472b7041309abBuild and push onex-api image to ECRrun 33179880143 — conclusionsuccess,2026-08-28T14:23:12Z,headBranch: main,headSha: 8a4ebe6919a52f8de272fb908e90866e8514e3cd(the currentmainHEAD), tagged with that commit SHA.docker/onex-api/tenant_event_outbox.py.deploy-onex-prod.ymlresolves it viaresolve-ecr-digestin exact-match-only mode (fallback-to-latestis not passed,fail-on-missing: 'true'), so a wrongcommit_shafails loud rather than silently resolving some other image.It replaces
sha256:b4c325545e1012aef53772d1a3f5a30eb9af3809b9a4036e28a156db906581bc, the digest pinned ink8s/onex-prod/api/deployment.yaml.expires_atis a PROPOSALexpires_at: 2026-08-30T16:00:00Z(~49h from staging) is a proposal — the approver may amend it before merge; merging is approving. Same forapproved_by.approved_by— disclosed, not claimed awayAs staged, the PR author and
approved_byare bothjonahgabriel. On this branch's own header rule ("The approver MUST differ from the PR author") that is self-approval as staged, and it is written down here rather than argued around. The approver closes it by confirming or replacing the value at merge time.It is a real login and not a placeholder string for the reason OCC#7213 recorded: the schema requires a non-empty string, and the consumer enforces
approved_by != requested_byagainstgithub.actor— a synthetic placeholder would compare unequal to every dispatcher and would silently disable the only mechanical anti-self-approval check on this path.Anti-self-approval is satisfied on the dispatcher side, not here. With the staged value the
workflow_dispatchactor must bedaniyalabbas96— the same identity that dispatched the proven-shape run 33117155819 on 2026-08-27 against thejonahgabriel-approvedbatch-92a794cd. Ifapproved_bychanges at merge time, re-derive the permitted dispatcher.Validation — run locally, both directions, against the real implementations
Producer side (this repo's own schema suite, includes the OMN-13424 at-rest invariant that refuses any expired entry):
Consumer side —
omninode_infra/scripts/validate_prod_promotion_grant.py, the exact script the workflow runs, driven offline against this file via its own--grants-filepath:daniyalabbas96sha256:13c96028…PASS: grant grant-7ebd7674… approved_by=jonahgabriel expires_at=2026-08-30T16:00:00Zdaniyalabbas96sha256:bc95b9bc…PASS: grant grant-7013b49e… approved_by=jonahgabriel expires_at=2026-08-30T16:00:00Zjonahgabrielsha256:13c96028…BLOCKED (self_granted)jonahgabrielsha256:bc95b9bc…BLOCKED (self_granted)The BLOCKED rows are the point: the interlock is live, not asserted.
Pruned in this PR — and why nothing is lost
The two OMN-16626 entries added by OCC#7213 (
grant-3c885a33…runtime,grant-9c23ed5d…omniintelligence) both carryexpires_at: 2026-08-28T20:00:00Z— hours from this staging. The OMN-13424 invariant refuses to let any expired entry remain, so this file cannot pass CI with them present once that timestamp passes, which is likely before the approver reaches it. They are removed rather than silently extended.grant-3c885a33…was consumed in substance by run 33117155819 (2026-08-27,runtime-only, dispatcherdaniyalabbas96) — its runtime gate passed and the apply succeeded. Entry 1 re-authorizes the identical digest, so the runtime gate loses no coverage.grant-9c23ed5d…(omniintelligencesha256:a66ff063…) was never mechanically read by any gate — its ownreasonsays so — and the pin it recorded is already merged on omninode_inframain(docs(OMN-11024): add delegation wire DTO evidence #1016,f127b84) and was applied by that same run. If a fresh omniintelligence authorization is wanted it must be re-issued in its own PR; this batch authorizes an onex-api cutover and nothing else.Header lines 1–46 (the durable schema / invariant / four-step process block) are carried forward byte-identical from
main. The only text dropped is the OMN-16626 per-request paragraph, which documents the entries this PR prunes.Rollback
The workflow's own
Rollback deployment on failurestep coversdeployment/onex-api(returning it to the prior ReplicaSet onsha256:b4c32554…) plus objects newly created by a partially-failed apply.The Ingress DELETE is not covered by that rollback. Re-applying the
onex-dev/onex-apiIngress by hand would restore the pre-existing dual-claim defect, not a healthy state — so the declared rollback target for the hostname half is "leaveonex-prod/onex-apias sole claimant and fix forward". That is precisely why #1044 refuses the delete unless onex-prod'sonex-apiisAvailable=True, itsonex-api-tlsCertificate isReady=True(verifiedReady=Trueon 2026-08-28), and onex-prod already claims the host.Routing
Consumer is
omninode_infra'sscripts/validate_prod_promotion_grant.py(k3s/EKS cloud plane, OMN-14209) — not the.201compose-lanenode_redeploy_orchestratorpath. No raw SSH/kubectl retag/recreate path is used or implied.Evidence-Ticket: OMN-16799
main-target-guardtrailers — what the two fields below actually point atmain-target-guard(the version resolved frommain) accepts amain-targeting PR from ahotfix/*head only when the body carries both ahotfix-evidence:and abackmerge:line. Both are stated literally rather than satisfied with a placeholder:hotfix-evidence: OCC-7420— OCC#7420, the hand-authored evidence companion foromninode_infra#1044on this same ticket. It carries the behaviour proof for the gated hostname reclaim that this grant authorises the other half of.backmerge: #7420— the same PR, and this needs saying plainly: there is no content backmerge of the grants file intodev, deliberately.onex_change_control@devcarries a grants registry with zerogrant_identries (verified:git show origin/dev:grants/prod_promotion_grants.yaml | grep -c grant_id:finds only header/schema prose, no entries;mainhas the live entries). The registry lives onmainon purpose — that is the branch the consumer resolves from. Backmerging grant rows intodevwould create a second registry that no gate reads and that the OMN-13424 at-rest expiry invariant would then start failing on independently.#7420is named here as the dev-side PR of record for OMN-16799, which is the same convention OCC#7213 (OMN-16626) used on this identical base (hotfix-evidence: OCC-7211/backmerge: #7211, both naming that ticket's dev-side companion).CI fix applied after the first push (
aaa0a0f56)Contract Compliance Checkhard-BLOCKed ondod-prod-promotion-grant-consumer-gate-omn16799: its command was rooted at$OMNINODE_INFRA, an env var the hosted gate does not set, so it resolved topython3 /scripts/validate_prod_promotion_grant.py→No such file or directory, exit 2.Fixed by declaring the check cross-repo the way the runner asks for (OMN-16824):
cwd: "${OMNI_HOME}/omninode_infra", with the grants-file argument moved to a requiredOCC_GRANTS_FILEenv var so it fails loud instead of silently validating the wrong checkout. The hosted gate checks out exactly one product repo and leaves${OMNI_HOME}empty, so it now reportsNOT-EVALUATED [cwd]for this item — non-blocking, and an honest "this gate did not evaluate it" rather than a verdict about a tree it was never pointed at. Same shape OCC#7403 (OMN-16838) ran live on this gate earlier today.The evidence itself did not weaken: all four consumer-gate rows were re-executed against the new command shape with real exit codes read from the processes (
daniyalabbas96→exit=0on both digests;jonahgabriel→exit=1 BLOCKED (self_granted)on both), andcontract_entry_sha256/contract_sha256were recomputed.hotfix-evidence: OCC-7420
backmerge: #7420