Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions contracts/OMN-17425.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
schema_version: "1.0.0"
ticket_id: OMN-17425
title: Central OCC evidence for pruning the expired staging-namespace grant grant-2840de81 on onex_change_control@main
summary: >-
Central OCC evidence for the OMN-17425 registry correction: grant-2840de81-b6de-4963-bb7e-ab022b2d0cc9,
the sole entry in grants/staging_namespace_grants.yaml, expired UNCONSUMED at 2026-08-31T02:00:00Z and
is pruned here, returning the file to the `entries: []` at-rest form its own LIFECYCLE section prescribes.
This contract lives on the PR branch itself because occ-preflight pins OCC evidence at the PR head SHA
for onex_change_control's own PRs — the same shape the OMN-18601 grant PRs used on this base. NO AUTHORIZATION
IS CREATED AND NONE IS CONSUMED. The merge removes one lapsed entry; no dispatch, deploy, rollback or
restart happens, and nothing on onex-prod is reachable from this file at all — omninode_infra's 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". The verdict OMN-17425 was
opened to produce is recorded in the file rather than only in the ticket: NEITHER of the two contradicting
records was wrong. The grant's own reason named the deploy-onex-prod.yml deploy_target=public-only convergence
run, which is omninode_infra run 33330766948, conclusion FAILURE — so the gated path never completed
and the registry was correct to carry no consumption record; OMN-16702's roll did complete, but through
the manual SSM sequence at 21:04-21:08Z that consumes no grant. Two records, two execution paths, no
contradiction.
is_seam_ticket: false
interface_change: false
interfaces_touched: []
evidence_requirements:
- kind: manual
description: >-
The staging-namespace anchor is returned to its at-rest form and the pruned entry's reason is retained
as a durable record rather than deleted silently.
command: >-
grep -Fq 'PRUNE RECORD — grant-2840de81-b6de-4963-bb7e-ab022b2d0cc9 (OMN-17425)' grants/staging_namespace_grants.yaml
emergency_bypass:
enabled: false
justification: ""
follow_up_ticket_id: ""
dod_evidence:
- id: "dod-omn17425-grant-pruned"
description: >-
PRUNED STATE, measured with the real dispatch-time parser rather than a grep. Comments in this file
name retired grant ids — grant-00ba7b7e is named in the header and grant-2840de81 is now named in
the prune record itself — so a grep for an id proves nothing about whether an ENTRY exists. The
measurement therefore imports omninode_infra/scripts/validate_staging_namespace_grant.py at origin/dev,
the same module the deploy-onex-prod.yml gate resolves with, and calls its parse_entries on both
trees. This branch yields 0 entries; onex_change_control@main at 533f3487e yields 1, and that one
is grant-2840de81-b6de-4963-bb7e-ab022b2d0cc9. The main-tree reading is the positive control and
it is the half that makes this a measurement: a parser that had silently stopped reading this file,
or a probe pointed at the wrong path, would have returned 0 on BOTH trees. It did not. READ FROM
THE RECEIPT, NOT THE LIVE FILE. Once this PR merges, `main` is the pruned tree, so the control inverts
and a live re-run of the pair would report a false failure. What is asserted is narrower and stated
plainly: the prune WAS measured against a main tree that still carried the entry, at 533f3487e.
source: "manual"
status: "verified"
checks:
- check_type: "command"
check_value: >-
grep -q '^status: PASS$' drift/dod_receipts/OMN-17425/dod-omn17425-grant-pruned/command.yaml
- id: "dod-omn17425-reason-retained"
description: >-
THE CORRECTION DOES NOT ERASE ITS OWN REASON, which is OMN-17425's explicit scope condition: "Do
not silently delete it without recording the finding; a registry correction that erases its own
reason is the failure mode this ticket exists to prevent." The pruned entry is replaced by a PRUNE
RECORD comment that names the grant id, its expiry, the absence of consumption fields, the failed
run 33330766948 that explains why it was never consumed, the manual-SSM invocations that explain
why OMN-16702 is nonetheless correct, and the grant-00ba7b7e precedent for the same disposition.
Two further facts are asserted because a prune could quietly take more than it should: the 2743
bytes of file header above the `entries:` key are byte-identical to main, so the schema and LIFECYCLE
documentation the next author reads is unchanged, and the id grant-2840de81 no longer appears anywhere
ahead of the prune record — it survives only inside it, as a record, never as an entry.
source: "manual"
status: "verified"
checks:
- check_type: "command"
check_value: >-
grep -q '^status: PASS$' drift/dod_receipts/OMN-17425/dod-omn17425-reason-retained/command.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
schema_version: 1.0.0
ticket_id: OMN-17425
evidence_item_id: dod-omn17425-grant-pruned
check_type: command
check_value: 'grep -q ''^status: PASS$'' drift/dod_receipts/OMN-17425/dod-omn17425-grant-pruned/command.yaml'
contract_sha256: sha256:4de52d71f85992c6c7cac064913dc2870c0263fa40bf44bd9d20432d6b687e5e
contract_entry_sha256: sha256:6d3bdc4aa9fd0034b36334f5f3d0a2c80763b8fa7c09c367ed3a86d0c6e27203
status: PASS
run_timestamp: '2026-09-23T01:05:23Z'
commit_sha: 0b346f5795db11f44f50c9c36fafafcc0655a337
pr_number: 10879
runner: occ-grant-prune-omn17425
verifier: validate_staging_namespace_grant.parse_entries
probe_command: "# The item's own measurement: the real dispatch-time parser, on BOTH trees.\npython3 -
<<'EOF'\nimport sys, subprocess, tempfile, pathlib\nrepo = \"/Users/rbs/OmniNode/repos/omninode_infra\"\ntmp
= tempfile.mkdtemp()\nfor f in subprocess.run([\"git\",\"-C\",repo,\"ls-tree\",\"-r\",\"--name-only\",\"origin/dev\",\"scripts/\"],\n
\ capture_output=True, text=True).stdout.split():\n if f.endswith(\".py\"):\n
\ b = subprocess.run([\"git\",\"-C\",repo,\"show\",f\"origin/dev:{f}\"], capture_output=True).stdout\n
\ p = pathlib.Path(tmp, f); p.parent.mkdir(parents=True, exist_ok=True); p.write_bytes(b)\npathlib.Path(tmp,
\"scripts\", \"__init__.py\").touch(exist_ok=True)\nsys.path.insert(0, tmp)\nfrom scripts.validate_staging_namespace_grant
import parse_entries\nocc = \"/Users/rbs/OmniNode/repos/onex_change_control\"\nafter = open(occ + \"/grants/staging_namespace_grants.yaml\",
\"rb\").read()\nbefore = subprocess.run([\"git\",\"-C\",occ,\"show\",\"origin/main:grants/staging_namespace_grants.yaml\"],\n
\ capture_output=True).stdout\na = parse_entries(after); b = parse_entries(before)\nprint(\"[this
branch ] entries=%d %s\" % (len(a), list(a)))\nprint(\"[main 533f3487e] entries=%d POSITIVE CONTROL:
%s is still live there\" % (len(b), b[0][\"grant_id\"]))\nEOF"
probe_stdout: '[this branch ] entries=0 [] #magic___^_^___line [main 533f3487e] entries=1 POSITIVE
CONTROL: grant-2840de81-b6de-4963-bb7e-ab022b2d0cc9 is still live there #magic___^_^___line '
exit_code: 0
actual_output: 'PASS. parse_entries returns 0 entries on this branch and 1 on onex_change_control@main
at 533f3487e, where that 1 is grant-2840de81-b6de-4963-bb7e-ab022b2d0cc9. The main-tree reading is the
positive control and it is what makes this a measurement rather than an assertion: a parser pointed
at the wrong path, or one that had silently stopped reading this anchor, returns 0 on both trees. It
returned 1 on main. No grep was used for the entry''s existence, deliberately — this file''s header
names the retired grant-00ba7b7e and the prune record now names grant-2840de81, so an id grep measures
comment text, not registry state. The module imported is the same one the deploy-onex-prod.yml gate
resolves with, omninode_infra/scripts/validate_staging_namespace_grant.py at origin/dev, not a reimplementation.
This reading is bound to 533f3487e as the control tree; after this PR merges, main IS the pruned tree
and the pair inverts, which is why the contract item reads this receipt rather than re-running the live
comparison.'
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
schema_version: 1.0.0
ticket_id: OMN-17425
evidence_item_id: dod-omn17425-reason-retained
check_type: command
check_value: 'grep -q ''^status: PASS$'' drift/dod_receipts/OMN-17425/dod-omn17425-reason-retained/command.yaml'
contract_sha256: sha256:4de52d71f85992c6c7cac064913dc2870c0263fa40bf44bd9d20432d6b687e5e
contract_entry_sha256: sha256:36e0d3c3453934d9739c0e86708d57f549549e87f3f9bf237b1632311c48c668
status: PASS
run_timestamp: '2026-09-23T01:05:23Z'
commit_sha: 0b346f5795db11f44f50c9c36fafafcc0655a337
pr_number: 10879
runner: occ-grant-prune-omn17425
verifier: python3-bytes-comparison
probe_command: "# Three facts about what the prune took and what it kept.\npython3 - <<'EOF'\nimport subprocess\nocc
= \"/Users/rbs/OmniNode/repos/onex_change_control\"\nafter = open(occ + \"/grants/staging_namespace_grants.yaml\",
\"rb\").read()\nbefore = subprocess.run([\"git\",\"-C\",occ,\"show\",\"origin/main:grants/staging_namespace_grants.yaml\"],\n
\ capture_output=True).stdout\nha = after.split(b\"entries:\")[0]; hb = before.split(b\"entries:\")[0]\nprint(\"header
above 'entries:' byte-identical to main:\", ha == hb, \"(%d bytes)\" % len(ha))\nprint(\"PRUNE RECORD
block present:\", b\"PRUNE RECORD\" in after)\nprint(\"grant id appears only inside the record:\", b\"grant-2840de81\"
not in after.split(b\"PRUNE RECORD\")[0])\nprint(\"failed run 33330766948 cited in the record:\", b\"33330766948\"
in after)\nEOF"
probe_stdout: 'header above ''entries:'' byte-identical to main: True (2743 bytes) #magic___^_^___line
PRUNE RECORD block present: True #magic___^_^___line grant id appears only inside the record: True #magic___^_^___line
failed run 33330766948 cited in the record: True #magic___^_^___line '
exit_code: 0
actual_output: 'PASS on all four. The pruned entry is replaced by a PRUNE RECORD comment that names the
grant id, its 2026-08-31T02:00:00Z expiry, the absent consumption fields, the failed run 33330766948
that explains why it was never consumed, the manual-SSM invocations that explain why OMN-16702 is nonetheless
correct, and the grant-00ba7b7e precedent for the same disposition. So the correction carries its own
reason, which is the scope condition OMN-17425 states explicitly. The two containment facts are asserted
because a prune can quietly take more than it should: the 2743 bytes of header above the `entries:`
key are byte-identical to main, so the SCHEMA and LIFECYCLE documentation the next author reads is untouched,
and grant-2840de81 appears nowhere ahead of the prune record — it survives inside it as a record and
nowhere as an entry. The third line is the one that would catch the lazy version of this change, a prune
that deleted the entry and left no explanation behind.'
79 changes: 28 additions & 51 deletions grants/staging_namespace_grants.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,54 +57,31 @@
# omni_home@main commit", which is the strongest available anchor and is what
# the ruling itself demands — but an actor who can land an omni_home commit
# can mint the record. This anchor constrains BLAST RADIUS, not authenticity.
entries:
# OMN-16702 / OMN-17153 — RE-STAGE of the 2026-08-30 staging-namespace
# authorization. The first entry (grant-00ba7b7e-fc60-4938-9a32-70f9df9a9c7a,
# landed by #7662) expired UNCONSUMED at 2026-08-30T16:00:00Z: no dispatch was
# ever performed under it. It has been PRUNED here per this file's LIFECYCLE
# section (an expired entry must not linger), and is replaced by this entry.
#
# NOTHING ELSE CHANGES. Same cluster, same two namespaces, same operator
# quote byte-for-byte, same operator_quote_at, same authorization_record
# commit, same approver. Only `grant_id`, `created_at` and `expires_at` are
# new. The quote is still inside its 24h freshness window
# (2026-08-30T05:30:00Z + 24h = 2026-08-31T05:30:00Z) and this entry's
# approver-set absolute expiry is set strictly inside that window.
#
# Covers BOTH halves of OMN-16702, unchanged:
# * onex-dev — the k8s/onex-public convergence (include_onex_public), i.e.
# the omnidash session-store repoint to the authenticated data-plane
# Valkey, plus the OMN-17155 NetworkPolicy convergence that admits it;
# * dev — the dev-valkey --requirepass roll and its Infisical consumer.
# PRUNE THIS ENTRY once consumed, or set consumed: true. It expires absolutely
# at 2026-08-31T02:00:00Z regardless.
- grant_id: grant-2840de81-b6de-4963-bb7e-ab022b2d0cc9
scope: staging-namespace
runtime_lane: staging-namespace
cluster: omninode-k3s-system-public
namespaces:
- dev
- onex-dev
authorization: in-session-operator-go
# Verbatim, byte-for-byte, from the 2026-08-30 in-session ruling — the same
# string carried by the pruned grant-00ba7b7e entry. It is readable in the
# authorization_record commit below (it appears twice in that commit's diff,
# in CLAUDE.md 2a and 12), which is what the omninode_infra gate's
# UNRECORDED_QUOTE check resolves against.
operator_quote: "Amend doctrine: in-session operator 'go' counts"
operator_quote_at: "2026-08-30T05:30:00Z"
authorization_record: "omni_home@e72943be6d7d27e69d00a017511a41fe3a7ac9a6"
# Equal to the dispatcher on purpose. THIS is the relaxation the ruling
# granted, and it applies to this anchor only. Prod runtime promotion still
# requires approved_by != requested_by via grants/prod_promotion_grants.yaml.
approved_by: jonahgabriel
expires_at: "2026-08-31T02:00:00Z"
created_at: "2026-08-30T17:20:00Z"
reason: >-
OMN-16702 / OMN-17153: re-stage after grant-00ba7b7e expired unconsumed at 16:00Z. Authorizes the
deploy-onex-prod.yml `deploy_target=public-only` convergence run (namespace onex-dev, including
the OMN-17155 NetworkPolicy egress that the omnidash pod needs to reach the data-plane Valkey) and
the subsequent dev-valkey --requirepass roll with its Infisical consumer (namespace dev). Promotes
no image and touches no onex-prod object; `public-only` skips promote-to-prod entirely, and the
applied trees are proven to render only into {dev, onex-dev} by scripts/assert_staging_namespace_scope.py
before this grant is even read.
entries: []
# ---------------------------------------------------------------------------
# PRUNE RECORD — grant-2840de81-b6de-4963-bb7e-ab022b2d0cc9 (OMN-17425)
#
# Pruned per this file's LIFECYCLE section: it expired UNCONSUMED at
# 2026-08-31T02:00:00Z. Consumption fields (`consumed`, `consumed_at`,
# `consumed_by_correlation_id`) were absent — not false, absent.
#
# WHY UNCONSUMED, AND WHY THAT IS CORRECT. The entry's own `reason` named 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 — job "Converge public-cluster
# staging namespaces (OMN-16702)" failed and `promote-to-prod` was skipped. The
# gated path this grant authorized never completed, so the registry was right to
# carry no consumption record.
#
# OMN-16702 IS ALSO CORRECT. Its roll did complete 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 (invocations 5a8945ca, 47333cff,
# b19b0257, 830eb4d9). That path does not read, write or consume this registry.
#
# So the OMN-17425 contradiction was apparent, not real: two durable records
# describing two different execution paths. NEITHER record is wrong. No
# retroactive consumption is claimed and none is asserted here.
#
# Precedent: grant-00ba7b7e-fc60-4938-9a32-70f9df9a9c7a was pruned the same way
# for the same reason (expired unconsumed) when this entry replaced it.
# ---------------------------------------------------------------------------
Loading