Repository navigation
fix(OMN-17447): extend the grant gate to SEQUENCES and deliver all 10 - #3113
Merged
Merged
Conversation
Contributor
|
| Verdict | Meaning | Blocks merge? |
|---|---|---|
passed |
No critical findings | No |
blocked |
CRITICAL findings found | Yes |
degraded |
All models unavailable (infra) | No (pilot) |
Powered by omniintelligence.review_pairing.cli_review — multi-model adversarial review (OMN-8468/OMN-8524)
jonahgabriel
pushed a commit
to OmniNode-ai/onex_change_control
that referenced
this pull request
Sep 1, 2026
#7952) * evidence: OCC companion pass 1 for OmniNode-ai/omnibase_infra#3113 * evidence: OCC companion self-bind for #7952 --------- Co-authored-by: node-occ-companion-effect <occ-companion-effect@omninode.ai>
A delivered TABLE grant does not make a BIGSERIAL-keyed relation writable. PostgreSQL rewrites a SERIAL/BIGSERIAL column into a nextval() DEFAULT over a STANDALONE sequence and checks that sequence's OWN acl on every INSERT -- a privilege GRANT INSERT ON TABLE does not reach. OMN-17379 proved the consequence live: pr_merged_events sat 24 days behind its topic at consumer LAG 0 while every write raised InsufficientPrivilege on the sequence and the offset was committed anyway. OMN-17377 independently found three more of these relations at zero rows. This gate could not see that half AT ALL. _GRANT_RE reads a relation-and-role pair; GRANT USAGE ON SEQUENCE <name> TO <role> does not parse as one, so sequence grants were INVISIBLE rather than merely filtered -- no ratchet movement could ever have revealed them. The requirement is DERIVED, not hand-listed. The topology models no object_type: SEQUENCE anywhere, so every declared TABLE grant carrying INSERT is resolved against the corpus's own column shapes. IDENTITY columns are excluded -- their sequence is owned by the column and rides the table's INSERT privilege. TWO CORRECTIONS TO THE TICKET, both from deriving instead of trusting the list: 1. Column shapes must come from the APPLIED END STATE, replaying the corpus in apply order so a later DROP+recreate wins. OMN-17447 listed the three baselines_* child tables as BIGSERIAL, having read the CREATE in node_projection_baselines/0001. 0002 DROPs and recreates all three with `id TEXT PRIMARY KEY`. Proven on a scratch Postgres: pg_get_serial_sequence returns NULL and pg_attrdef reads `default=NONE`. Had those three migrations been written as filed, each would have hit its own fail-loud NULL guard and broken every lane's deploy -- demonstrated by running that guard against baselines_breakdown and getting the RAISE. 2. Deriving found three gaps the ticket's omninode_runtime-only scope never looked at: tenant_projection_writer on capability_scores, delegation_routing_tenant_overlay and dep_health_findings. So the real set is 7 runtime + 3 tenant-writer = 10 -- the same count the ticket gives, but not the same ten. All 10 are delivered here, taking MAX_UNDELIVERED_SEQUENCES to 0. Each migration resolves its sequence via pg_get_serial_sequence rather than spelling <table>_<column>_seq (a restore or rename must still converge), RAISEs if the column is not sequence-backed instead of no-oping into another silent half-grant, and asserts has_sequence_privilege post-grant -- the shape omnimarket#2256 proved. PROVEN END TO END on a scratch Postgres against real bytes: 7/7 sequence usage=false BEFORE, 7/7 true AFTER. Then the decisive isolation -- revoke ONLY the sequence privilege on receipt_gate_rows, leaving the TABLE grant fully intact: has_table_privilege INSERT reads true and nextval() still fails `permission denied for sequence receipt_gate_rows_id_seq`. Re-applying the migration makes the same nextval() succeed. That is the defect, isolated to the one privilege this ticket is about. Refs: OMN-17447, OMN-17440, OMN-17379, OMN-17377, OMN-15423
jonahgabriel
force-pushed
the
jonah/omn-17447-sequence-grant-delivery
branch
from
September 1, 2026 16:20
4c49ed0 to
5a6b410
Compare
github-actions
Bot
deleted the
jonah/omn-17447-sequence-grant-delivery
branch
September 1, 2026 16:37
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.
OMN-17447
A delivered TABLE grant does not make a
BIGSERIAL-keyed relation writable. PostgreSQL rewrites aSERIAL/BIGSERIALcolumn into anextval()DEFAULT over a standalone sequence and checks that sequence's own ACL on every INSERT — a privilegeGRANT INSERT ON TABLEdoes not reach.OMN-17379 proved the consequence live:
pr_merged_eventssat 24 days behind its topic at consumer LAG 0 while every write raisedInsufficientPrivilegeon the sequence and the offset was committed anyway. OMN-17377 independently found three more of these relations at zero rows.This gate could not see that half at all.
_GRANT_REreads a relation-and-role pair;GRANT USAGE ON SEQUENCE <name> TO <role>does not parse as one — so sequence grants were invisible rather than merely filtered, and no ratchet movement could ever have revealed them.What this delivers
The requirement is derived, not hand-listed. The topology models no
object_type: SEQUENCEanywhere, so every declared TABLE grant carrying INSERT is resolved against the corpus's own column shapes.GENERATED ... AS IDENTITYcolumns are excluded — their sequence is owned by the column and rides the table's INSERT privilege.10 sequence grants,
MAX_UNDELIVERED_SEQUENCES→ 0, each in its owning node's lineage.Two corrections to the ticket, both proven
1. Three of the listed ten are NOT sequence-backed.
node_projection_baselines/0002DROPs and recreatesbaselines_breakdown,baselines_comparisonsandbaselines_trendwithid TEXT PRIMARY KEY. The filed list read only theCREATE TABLEin0001.Had those three been written as filed, each would have hit its own AC3-mandated
RAISE EXCEPTIONand broken every lane's deploy. Demonstrated by running that guard:So the checker derives column shapes from the applied end state, replaying the corpus in apply order so a later
DROP+recreate wins.test_recreated_tables_are_not_reported_as_sequence_backedis the regression guard.2. Three gaps the ticket's
omninode_runtime-only scope never looked at —tenant_projection_writeroncapability_scores,delegation_routing_tenant_overlayanddep_health_findings. (The middle one is the same relation OMN-16436 already fixed once for TABLE-grant drift; the sequence behind its key was never granted.)Net: same count, different set.
dod_evidence
Scratch Postgres, real bytes:
usage=falseBEFORE,trueAFTERreceipt_gate_rows, leaving the TABLE grant fully intact:has_table_privilegeINSERT readstrueandnextval()still failspermission denied for sequence receipt_gate_rows_id_seq; re-applying the migration makes the samenextval()return1. That is the defect isolated to the one privilege this PR is about.check_topology_grant_delivery.py→sequence grant delivery: 0 undelivered (bound 0), exit 0tests/ci/test_topology_grant_delivery.py→ 37 passed, including a RED control (--max-undelivered-sequences -1→ exit 1)sync-node-migrations.sh --check→in syncPREPUSH_*override, no--no-verify, no override grantNo live lane touched; scratch container destroyed.
Ordering
Source half is
omnimarketand lands after this, pernode-migration-vendor-parity-gate. The ownership-manifest prerequisite is a separate omnimarket PR that lands before #3108.Refs: OMN-17447, OMN-17440, OMN-17379, OMN-17377, OMN-15423
Evidence-Ticket: OMN-17447
Evidence-Source: OCC#7952