Skip to content

chore(OMN-17425): prune grant-2840de81 — expired unconsumed, and neither record was wrong - #10879

Merged
jake-b-omni merged 4 commits into
mainfrom
hotfix/omn-17425-prune-expired-staging-grant
Sep 23, 2026
Merged

jake-b-omni merged 4 commits into
mainfrom
hotfix/omn-17425-prune-expired-staging-grant

Conversation

@jake-b-omni

Copy link
Copy Markdown
Contributor

Prunes the expired, unconsumed staging-namespace grant under OMN-17425, and records the verdict the ticket was opened to produce: neither of the two contradicting records is wrong.

hotfix-evidence: OCC-7731
backmerge: #7731

On those two lines. The evidence source is OCC#7731 (merge 7dcce0b78dd9c7f90131b9f20a5689ecb0f439f6), the authoritative landing of the entry being pruned — it is what establishes the entry's verbatim state on this branch. No backmerge applies: dev already carries entries: [] for this file and has nothing to receive, so there is no backmerge PR to point at. The guard requires the field unconditionally, so it names the same evidence pull request.

What is being pruned

grant-2840de81-b6de-4963-bb7e-ab022b2d0cc9, the sole entry in grants/staging_namespace_grants.yaml, expired unconsumed at 2026-08-31T02:00:00Z. Its consumed, consumed_at and consumed_by_correlation_id fields are absent — not false, absent.

This file's own LIFECYCLE section prescribes the remedy: "At rest this file is entries: []. An expired entry fails CI (it must be pruned)." The entry's own trailing comment says the same: "PRUNE THIS ENTRY once consumed, or set consumed: true."

The entry is replaced by a PRUNE RECORD comment rather than deleted outright. OMN-17425's scope is explicit that a registry correction must not erase its own reason, and there is precedent in this file: grant-00ba7b7e-fc60-4938-9a32-70f9df9a9c7a was retired the same way, with the same kind of note, when this entry replaced it.

The verdict — OMN-17425 AC2

Two durable records asserted incompatible things about the same 2026-08-30 roll. They do not actually conflict.

The registry is correct. The entry's reason field names exactly what it authorized: the deploy-onex-prod.yml deploy_target=public-only convergence run. That run is omninode_infra 33330766948, dispatched 2026-08-30T19:24:08Z, conclusion failure — the job "Converge public-cluster staging namespaces (OMN-16702)" failed and promote-to-prod was skipped. The gated path this grant authorized never completed successfully, so the registry was right to carry no consumption record.

OMN-16702 is also correct. Its roll did complete and was live-proven — through the manual SSM sequence at 21:04–21:08Z, corroborated by the 2026-09-09T18:35Z retained-record review (invocations 5a8945ca, 47333cff, b19b0257, 830eb4d9). That path does not read, write or consume this registry.

So the contradiction was apparent, not real: two records describing two different execution paths. No retroactive consumption is claimed and none is asserted by this change.

Blast radius

  • No grant is authored, approved or consumed. One expired entry is removed.
  • Future staging-namespace dispatch is revoked, which is the intended effect of a merged prune and is already the effective state — the entry has been expired for 23 days, and the dispatch-time gate refuses on expires_at before reading any other premise.
  • Nothing on onex-prod is reachable from this file. omninode_infra/scripts/validate_prod_promotion_grant.py reads grants/prod_promotion_grants.yaml and only that path, and every entry here is pinned to runtime_lane: staging-namespace while the prod resolver matches runtime_lane == "prod".

Verification

The pruned file was parsed with the real dispatch-time validator, omninode_infra/scripts/validate_staging_namespace_grant.py at origin/dev, not with a grep — comments in these files name retired grant ids, so a grep fails falsely or passes wrongly.

BEFORE  parse_entries -> 1 entry: grant-2840de81-b6de-4963-bb7e-ab022b2d0cc9
AFTER   parse_entries -> 0 entries: []   (clean at-rest state, no exception)

The before-state control matters: it proves the parser is reading this file and not vacuously passing.

One defect found while doing this, not fixed here

This file's header claims its schema is "enforced by uv run validate-staging-namespace-grants". That entrypoint does not exist — not in this repo's pyproject.toml, not in any workflow here. The only validator is omninode_infra/scripts/validate_staging_namespace_grant.py, which runs at dispatch time, not on pull requests to this repo. So this file's "an expired entry fails CI" claim is false, and that is why this entry sat expired for 23 days without anything going red. That is the general case OMN-16960 already owns; it is recorded there rather than re-filed.

Jonah — this needs your look

grants/staging_namespace_grants.yaml is not in CODEOWNERS (only prod_promotion_grants.yaml is), so GitHub will not force a review here. Asking for one anyway: you are the approved_by on the entry being pruned, your 2026-09-09 reviews are what corroborate the manual-SSM half of the verdict, and a registry correction should not land on your anchor without you seeing it. If you read AC5's proof_class: receipt-bound as requiring a hashed OCC receipt bound to a contracts/OMN-17425.yaml rather than this merge receipt, say so and I will author the contract — that string appears nowhere in this repo today, so I took the narrower reading.

🤖 Generated with Claude Code

https://claude.ai/code/session_01P5jA4UseYGEptrKijm4X9g

…her record was wrong

grant-2840de81-b6de-4963-bb7e-ab022b2d0cc9 expired UNCONSUMED at
2026-08-31T02:00:00Z. Pruned per this file's own LIFECYCLE section, which
states the at-rest form is `entries: []` and that an expired entry must not
linger. The prune carries a PRUNE RECORD comment rather than deleting the
entry silently — OMN-17425's scope forbids a correction that erases its own
reason, and grant-00ba7b7e was retired the same way.

OMN-17425 asked which of two contradicting records is wrong. Neither is.

The entry's `reason` named the deploy-onex-prod.yml `deploy_target=public-only`
convergence run: omninode_infra run 33330766948, dispatched
2026-08-30T19:24:08Z, conclusion FAILURE — the "Converge public-cluster staging
namespaces (OMN-16702)" job failed and promote-to-prod was skipped. The gated
path this grant authorized never completed, so the registry was correct to
carry no consumption record.

OMN-16702 is also correct: its roll completed and was live-proven, but through
the manual SSM sequence at 21:04-21:08Z corroborated by the 2026-09-09T18:35Z
retained-record review (5a8945ca, 47333cff, b19b0257, 830eb4d9). That path does
not read, write or consume this registry. The contradiction was apparent, not
real — two durable records describing two different execution paths.

No retroactive consumption is claimed. No grant is authored or approved here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P5jA4UseYGEptrKijm4X9g
jake-b-omni and others added 3 commits September 22, 2026 20:09
…de81 prune

occ-preflight refused the PR with reason=missing_contract, missing_contracts
["OMN-17425"]: a PR touching a governed anchor needs a central OCC contract with
a passing receipt per dod_evidence item. This adds both.

Two evidence items, each measured rather than asserted:

  dod-omn17425-grant-pruned — imports omninode_infra's own dispatch-time
  validate_staging_namespace_grant.parse_entries (origin/dev) and runs it on both
  trees: 0 entries here, 1 on onex_change_control@main at 533f348, and that one
  is grant-2840de81. The main-tree reading is the positive control; a probe
  pointed at the wrong path returns 0 on both. No grep is used to decide whether
  an entry exists, because this file's comments name retired grant ids — the
  header names grant-00ba7b7e and the prune record now names grant-2840de81 — so
  an id grep measures comment text, not registry state.

  dod-omn17425-reason-retained — asserts the correction keeps its own reason,
  which is OMN-17425's explicit scope condition, and bounds what the prune took:
  the 2743 bytes of header above `entries:` are byte-identical to main, and
  grant-2840de81 appears nowhere ahead of the prune record.

Both contract checks read their receipt rather than the live registry. That is
deliberate and is the OMN-18601 lesson: this PR changes the file the measurement
is about, so a live re-run after merge inverts the control and reports a false
failure. The receipts are bound to 533f348 as the control tree.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P5jA4UseYGEptrKijm4X9g
…act hash

occ-preflight returned reason=contract_hash_mismatch: both receipts carried a
contract_entry_sha256 computed as sha256(yaml.safe_dump(entry, sort_keys=True)),
which is not the canonical form the gate recomputes.

The authority is omnibase_core.validation.validator_receipt_gate.compute_contract_entry_sha256
(OMN-13888): the hash is sha256 over canonical JSON — sorted keys, no
whitespace, ensure_ascii=False — of {"header": {ticket_id, schema_version},
"entry": <the dod_evidence item>}. It deliberately does NOT cover the whole
contract file, which is what makes appending a later evidence item
non-destructive to the hashes of the earlier ones.

Both values were recomputed with that function's own algorithm and reproduce the
gate's recomputation exactly, so the binding is verified rather than pasted from
the error text:

  dod-omn17425-grant-pruned      sha256:6d3bdc4a…c6e27203
  dod-omn17425-reason-retained   sha256:36e0d3c3…1c48c668

No probe output, verdict or contract entry changed — only the two binding
hashes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P5jA4UseYGEptrKijm4X9g
The Pre-commit gate's yamlfmt hook (google/yamlfmt v0.21.0) reflowed all three
files. The per-entry contract bindings were re-verified after the reformat and
are unchanged, which is the behaviour compute_contract_entry_sha256 documents:
it hashes the PARSED contract as canonical JSON, so a reflow that preserves
parsed semantics yields an identical hash. Both receipts still declare status
PASS. No probe output or verdict changed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P5jA4UseYGEptrKijm4X9g
@jake-b-omni
jake-b-omni merged commit a89a6f3 into main Sep 23, 2026
38 checks passed
@jake-b-omni
jake-b-omni deleted the hotfix/omn-17425-prune-expired-staging-grant branch September 23, 2026 01:22
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.

1 participant