Repository navigation
fix(OMN-17440): deliver 13 topology TABLE grants no migration ever issued - #3108
Merged
github-actions[bot] merged 2 commits intoSep 1, 2026
Merged
Conversation
…sued The topology declares, per principal, the exact relation set that principal may read and write. That block is GENERATED from node contract `db_io.db_tables` declarations. Nothing has ever checked that a migration ISSUES those grants against a real database, and for 40 of the 65 declared pairs, none did. The `.201` dev lane holds most of them live only because they were granted OUT OF BAND, BY HAND. A lane that has never been hand-patched -- a fresh staging namespace, a rebuilt onex-dev, prod -- gets NONE of them, and every projection writing those relations refuses on first traffic with InsufficientPrivilege while the runtime reports healthy and commits its offsets. That is the OMN-16993 failure mode, and it has now recurred five times in a fortnight (OMN-15701, OMN-16436, OMN-16993, OMN-17290, OMN-17374). This delivers 13 of them across 8 owning node lineages, taking the ratchet 40 -> 27. The tranche is chosen mechanically, not by taste: the nodes OMN-17447 derived as sequence-backed, i.e. where a TABLE grant alone still cannot write. Three of the relations (merge_state_transitions, pr_lifecycle_ledger_entries, receipt_gate_rows) are the ones OMN-17377 measured at ZERO ROWS and OMN-17379 proved refusing on the real wired path. Each grant lands in its OWNING node's lineage next to the file that creates the relation -- the node_projection_session_replay/0002 and node_projection_tenant_registry/0001 convention -- and deliberately NOT in one bulk grant file. A shared grant block is the shape that let OMN-15701 revert eight grants at once. PROVEN, not asserted. Scratch Postgres, real bytes, real creating migrations: applied all 10 creating migrations for these 8 nodes, probed BEFORE (13/13 insert=false select=false), applied the 8 grant migrations, probed AFTER (13/13 insert/select/update=true, DELETE correctly still false -- a projection writer upserts, it does not reshape). Every migration's own fail-loud `1/count(*)` assertions passed in that run. CORRECTION TO OMN-17447, found by that same replay: its derived list calls the three baselines_* child tables BIGSERIAL, having read the CREATE TABLE in node_projection_baselines/0001. `0002` DROPs and recreates all three with `id TEXT PRIMARY KEY`, so in the APPLIED end state they carry no sequence -- pg_get_serial_sequence returns NULL and pg_attrdef reads `default=NONE`. Its real deliverable is 7 sequences, not 10. Recorded in the test's own comment so the next reader does not re-derive it. savings_estimates is deliberately untouched: it is declared for tenant_projection_writer only (already delivered) and for omninode_runtime NOT AT ALL. Granting the runtime principal a SELECT there would be actively wrong -- FORCE RLS with an unset GUC makes a granted SELECT return zero rows, inverting the NOT EXISTS anti-join into re-finalizing every session forever (OMN-16770). Source lives in omnimarket and is vendored byte-identical here; the omnimarket source PR follows once this is at dev tip, per node-migration-vendor-parity-gate. Refs: OMN-17440, OMN-17447, OMN-17374, OMN-17377, OMN-17379, OMN-16770
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
#7944) * evidence: OCC companion pass 1 for OmniNode-ai/omnibase_infra#3108 * evidence: OCC companion self-bind for #7944 --------- Co-authored-by: node-occ-companion-effect <occ-companion-effect@omninode.ai>
github-actions
Bot
deleted the
jonah/omn-17440-deliver-topology-table-grants
branch
September 1, 2026 13:21
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-17440
The topology declares, per principal, the exact relation set that principal may read and write. That block is generated from node contract
db_io.db_tablesdeclarations. Nothing has ever checked that a migration ISSUES those grants against a real database, and for 40 of the 65 declared pairs, none did.The
.201dev lane holds most of them live only because they were granted out of band, by hand. A lane that has never been hand-patched — a fresh staging namespace, a rebuilt onex-dev, prod — gets none of them, and every projection writing those relations refuses on first traffic withInsufficientPrivilegewhile the runtime reports healthy and commits its offsets.Five instances of this class in a fortnight: OMN-15701, OMN-16436, OMN-16993, OMN-17290, OMN-17374.
What this delivers
13 grants across 8 owning node lineages, ratchet 40 → 27.
node_contract_registry/0001contract_registrynode_merge_state_projection/0002merge_state_transitionsnode_omnigate_projection/0001gate_activity,gate_metricsnode_pr_lifecycle_state_reducer/0002pr_lifecycle_ledger_entriesnode_projection_baselines/0003breakdown,comparisons,snapshots,trendnode_projection_intent_classification/0002intent_classification_eventsnode_projection_overnight/0002session_phases,sessionsnode_projection_receipt_gate/0001receipt_gate_rowsEach grant lands in its owning node's lineage next to the file that creates the relation — the
node_projection_session_replay/0002/node_projection_tenant_registry/0001convention — and deliberately not in one bulk grant file. A shared grant block is the shape that let OMN-15701 revert eight grants at once.The tranche is chosen mechanically, not by taste: the nodes OMN-17447 derived as sequence-backed, i.e. where a TABLE grant alone still cannot write.
merge_state_transitions,pr_lifecycle_ledger_entriesandreceipt_gate_rowsare the three OMN-17377 measured at zero rows and OMN-17379 proved refusing on the real wired path.dod_evidence
Proven on a scratch Postgres against real bytes and the real creating migrations (all 10 applied first), not asserted:
insert=false select=falseinsert/select/update=true,delete=false(a projection writer upserts, it does not reshape)1/count(*)assertions passed in that runsync-node-migrations.sh --check→in synccheck_topology_grant_delivery.py→27 undelivered (bound 27), exit 0tests/ci/test_topology_grant_delivery.py+test_application_migration_manifest.py→ 41 passed1a9d8586ac19(suite log sha256592e109f62e06f8f11ea2e9eda9e25576f19f5d60047c1e463555d068c7cc087, 1578s)No live lane touched; the scratch container was destroyed and no residue kept.
Correction to OMN-17447, found by that replay
Its derived list calls the three
baselines_*child tables BIGSERIAL, having read the CREATE innode_projection_baselines/0001.0002DROPs and recreates all three withid TEXT PRIMARY KEY, so in the applied end state they carry no sequence —pg_get_serial_sequencereturns NULL andpg_attrdefreadsdefault=NONE. Its real deliverable is 7, not 10. Recorded in the test's own comment.OMN-16770 carve-out — verified, not assumed
savings_estimatesis declared undertenant_projection_writeronly (already delivered);omninode_runtimedeclares no grant on it anywhere, so it is absent from the undelivered set by construction and nothing here grants it. A runtime SELECT there would be actively wrong — FORCE RLS with an unset GUC returns zero rows and inverts theNOT EXISTSanti-join into re-finalizing every session forever. Now written into the checker's docstring so the next person driving the count toward zero does not "fix" it.Notes
nightly_loop_configsis declared and has noCREATE TABLEanywhere, so its grant has no lineage to land in.test_residual_relation_has_no_creating_migrationasserts that reason still holds rather than trusting prose. OMN-17440 AC2's plain== 0target needs amending to== 1.omnimarketand lands after this, pernode-migration-vendor-parity-gate.Refs: OMN-17440, OMN-17447, OMN-17374, OMN-17377, OMN-17379, OMN-16770
Evidence-Ticket: OMN-17440
Evidence-Source: OCC#7944