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
2 changes: 1 addition & 1 deletion .github/omnimarket-contract-pin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@
# An `Omnimarket-Source-Ref: <ref>` PR-body trailer still overrides this pin for
# cross-repo co-development (OMN-15703's escape hatch, unchanged).
repository: OmniNode-ai/omnimarket
omnimarket_contract_ref: a0941e08eb80dc4d6f1baefac4f6582b12ac3e34
omnimarket_contract_ref: 8863472ce4730652d5074cdaad0cdf7f63215554
21 changes: 21 additions & 0 deletions docker/migrations/forward/_ledger/application-migrations.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,24 @@ nodes/node_projection_receipt_gate/0002_grant_omninode_runtime_receipt_gate_sequ
nodes/node_canary_score_reducer/0004_grant_tenant_projection_writer_capability_scores_sequence.sql node:node_canary_score_reducer node:node_canary_score_reducer omninode_internal node:node_canary_score_reducer:0004_grant_tenant_projection_writer_capability_scores_sequence.sql e88e31a208ea0e1f17dfc46edbe002f2932dfcdb51f7cf4396bd7780de6f9530
nodes/node_delegation_routing_reducer/0003_grant_tenant_projection_writer_overlay_sequence.sql node:node_delegation_routing_reducer node:node_delegation_routing_reducer omninode_internal node:node_delegation_routing_reducer:0003_grant_tenant_projection_writer_overlay_sequence.sql 9b65f5d17d4dd7a4288160ee5832b09e7b66c7ae12533726f72b7d6e822fe4ff
nodes/node_projection_dep_health/003_grant_tenant_projection_writer_dep_health_sequence.sql node:node_projection_dep_health node:node_projection_dep_health omninode_internal node:node_projection_dep_health:003_grant_tenant_projection_writer_dep_health_sequence.sql d776dced7888832011d1086b378693dc4f06b9241a9cc978e92fb948d0180d6a
nodes/node_deployment_evidence_reducer/0002_grant_omninode_runtime_deployment_evidence_tables.sql node:node_deployment_evidence_reducer node:node_deployment_evidence_reducer omninode_internal node:node_deployment_evidence_reducer:0002_grant_omninode_runtime_deployment_evidence_tables.sql dbe97c896cacd985977a22ee2997eb26ae3c4bfe019d2907165269878343e5ae
nodes/node_evidence_dashboard_reducer/0002_grant_omninode_runtime_evidence_dashboard_tables.sql node:node_evidence_dashboard_reducer node:node_evidence_dashboard_reducer omninode_internal node:node_evidence_dashboard_reducer:0002_grant_omninode_runtime_evidence_dashboard_tables.sql fd619046af813abb7a3e0c9441635277a1fe31040a207ede035409b33e91a46c
nodes/node_llm_delegation_projection/0002_grant_omninode_runtime_llm_delegation_daily_projection.sql node:node_llm_delegation_projection node:node_llm_delegation_projection omninode_internal node:node_llm_delegation_projection:0002_grant_omninode_runtime_llm_delegation_daily_projection.sql 971d02041f07744e26158fe7533b80cd82ec4c85d578ce81042fbede5fef4f93
nodes/node_nightly_loop_controller/002_grant_omninode_runtime_nightly_loop_tables.sql node:node_nightly_loop_controller node:node_nightly_loop_controller omninode_internal node:node_nightly_loop_controller:002_grant_omninode_runtime_nightly_loop_tables.sql 1f3811924f38915d81002881c6396a3b216107c3e7869b30c0c895ecf88c47c8
nodes/node_projection_baselines_quality/003_grant_omninode_runtime_baselines_quality_snapshots.sql node:node_projection_baselines_quality node:node_projection_baselines_quality omninode_internal node:node_projection_baselines_quality:003_grant_omninode_runtime_baselines_quality_snapshots.sql 9e02c9bfea641951898cf244208a95b622fad6470aae57e6cd1a2fc88321e56b
nodes/node_projection_baselines_roi/003_grant_omninode_runtime_baselines_roi_snapshots.sql node:node_projection_baselines_roi node:node_projection_baselines_roi omninode_internal node:node_projection_baselines_roi:003_grant_omninode_runtime_baselines_roi_snapshots.sql 20cf763840a6bf37f657a0688b50dc8cf739e184d03533c5e37fa74af8f4a995
nodes/node_projection_capsule_store/080_grant_omninode_runtime_capsule_store.sql node:node_projection_capsule_store node:node_projection_capsule_store omninode_internal node:node_projection_capsule_store:080_grant_omninode_runtime_capsule_store.sql 029a9607b0b72576de70e9411c673d3816a03f2f446038bbc06cdad611b24540
nodes/node_projection_consumer_flow/0003_grant_omninode_runtime_consumer_flow_tables.sql node:node_projection_consumer_flow node:node_projection_consumer_flow omninode_internal node:node_projection_consumer_flow:0003_grant_omninode_runtime_consumer_flow_tables.sql b5501f307278babfa25cdf857d4eff1e1419376302def0e691a1d38b77b25011
nodes/node_projection_cost_by_repo/0002_grant_omninode_runtime_cost_by_repo_snapshots.sql node:node_projection_cost_by_repo node:node_projection_cost_by_repo omninode_internal node:node_projection_cost_by_repo:0002_grant_omninode_runtime_cost_by_repo_snapshots.sql fc54009197878a29eb4d8c342b6591e829e4f6a95363017b94de87de1b4d0231
nodes/node_projection_delegation/0035_grant_omninode_runtime_generation_events.sql node:node_projection_delegation node:node_projection_delegation omninode_internal node:node_projection_delegation:0035_grant_omninode_runtime_generation_events.sql 91b652cffe8b45e3461b29ae568487574eeba3d6be37823a476eadb2bb0ba8d7
nodes/node_projection_event_chain/0002_grant_omninode_runtime_event_chain.sql node:node_projection_event_chain node:node_projection_event_chain omninode_internal node:node_projection_event_chain:0002_grant_omninode_runtime_event_chain.sql d50723691cc0d2449cba3fe0d03978dd5bf93821021f8c7c597d2a9aadd09aca
nodes/node_projection_llm_cost/0002_grant_omninode_runtime_llm_call_metrics.sql node:node_projection_llm_cost node:node_projection_llm_cost omninode_internal node:node_projection_llm_cost:0002_grant_omninode_runtime_llm_call_metrics.sql 37dfc97f4d88770e9c7ad43554b25f964168b689afd57e1394796341927a7bab
nodes/node_projection_llm_routing/0002_grant_omninode_runtime_llm_routing_decisions.sql node:node_projection_llm_routing node:node_projection_llm_routing omninode_internal node:node_projection_llm_routing:0002_grant_omninode_runtime_llm_routing_decisions.sql 650852159b56e38c8d63f8662ac721b1342755ab219ef1a5c0a7e40c1cd4efff
nodes/node_projection_mcp_tools/0002_grant_omninode_runtime_mcp_tools.sql node:node_projection_mcp_tools node:node_projection_mcp_tools omninode_internal node:node_projection_mcp_tools:0002_grant_omninode_runtime_mcp_tools.sql bc569052aca8369bda3d04e3947e30ad74085b57ed05002828df67c6d0304068
nodes/node_projection_registration/0006_grant_omninode_runtime_node_service_registry.sql node:node_projection_registration node:node_projection_registration omninode_internal node:node_projection_registration:0006_grant_omninode_runtime_node_service_registry.sql acee8d9a8c316986298b639cdfe02e01c4f416529a3f4f2fe3c78ceeeae5a0e4
nodes/node_projection_sandbox_decisions/0002_grant_omninode_runtime_sandbox_decisions.sql node:node_projection_sandbox_decisions node:node_projection_sandbox_decisions omninode_internal node:node_projection_sandbox_decisions:0002_grant_omninode_runtime_sandbox_decisions.sql 164ced5dd108a6fed67449aaadd306291ed816abbe9aad6aa6e6f0049b4a3b76
nodes/node_projection_session_outcome/0022_grant_omninode_runtime_session_outcomes.sql node:node_projection_session_outcome node:node_projection_session_outcome omninode_internal node:node_projection_session_outcome:0022_grant_omninode_runtime_session_outcomes.sql a6fb760e0669fe0157b12b67ed8083f15a6a61916bae5e188b1d44671a05db82
nodes/node_projection_swarm/0002_grant_omninode_runtime_swarm_runs.sql node:node_projection_swarm node:node_projection_swarm omninode_internal node:node_projection_swarm:0002_grant_omninode_runtime_swarm_runs.sql 00ab3cf5e1d87a82f10331cffe5a3290bdf39ceaa109c874732dfa3c0edd9129
nodes/node_projection_traces/0002_grant_omninode_runtime_traces.sql node:node_projection_traces node:node_projection_traces omninode_internal node:node_projection_traces:0002_grant_omninode_runtime_traces.sql ac6ddf2d26b8e9608ee53d0fd2c95ee9927a2a6d4776550207e7d8de3b43eae0
nodes/node_projection_voice_sessions/0002_grant_omninode_runtime_voice_sessions.sql node:node_projection_voice_sessions node:node_projection_voice_sessions omninode_internal node:node_projection_voice_sessions:0002_grant_omninode_runtime_voice_sessions.sql 08c3dfad14758d423fb75656d5737496106dde0b81f167773b6cff75d9477311
nodes/node_renderer_capability_projection/0002_grant_omninode_runtime_renderer_capability_projection.sql node:node_renderer_capability_projection node:node_renderer_capability_projection omninode_internal node:node_renderer_capability_projection:0002_grant_omninode_runtime_renderer_capability_projection.sql 56f3c455359f0ca5733a518b1136693ee1fd009e018a0c650dfb611cb34f55b6
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
-- OMN-17440: topology-derived omninode_runtime TABLE grants for node_deployment_evidence_reducer.
-- Target DB: omnidash_analytics (NODE_POSTGRES_DB)
-- Node: node_deployment_evidence_reducer
--
-- ============================================================================
-- WHAT IS BROKEN
-- ============================================================================
-- All three topology instances
-- (`omnibase_infra/src/omnibase_infra/topology/instances/{local,onex-dev,
-- onex-prod}.yaml`) declare `deployment_evidence_projection` and `deployment_readiness_projection` under
-- `databases.application.principals.omninode_runtime.grants[object_type:
-- TABLE, schema: public]` with `[INSERT, SELECT, UPDATE]`. That list is
-- GENERATED from node contract `db_io.db_tables` declarations by
-- `scripts/generate_application_database_table_grants.py --write`, so it is
-- the platform's machine-derived statement of intent.
--
-- No migration in either repo has ever ISSUED them. The two halves --
-- what the platform declares, and what a database is actually told -- drifted
-- apart silently, and the drift only ever surfaces as a live outage on
-- whichever relation happens to take traffic next: `InsufficientPrivilege`
-- on every write while the runtime reports healthy and commits its offsets
-- (the OMN-16993 / OMN-17379 failure shape).
--
-- ============================================================================
-- MEASURED, NOT ASSUMED
-- ============================================================================
-- `scripts/validation/check_topology_grant_delivery.py` at omnibase_infra
-- dev 4053dc3c0 reported `topology grant delivery: 27 undelivered (of 65
-- declared)`, and `deployment_evidence_projection`, `deployment_readiness_projection` were among them.
--
-- Read-only probe of the `.201` dev lane (compose project `omnibase-infra`,
-- database `omnidash_analytics`) on 2026-09-03 against
-- `information_schema.role_table_grants`: 63 of the 65 declared grants are
-- present live, but only 38 of them are issued by any migration. The other
-- 26 -- `deployment_evidence_projection`, `deployment_readiness_projection` included -- exist ONLY because they were granted
-- out of band, BY HAND. That is precisely why the gap stayed invisible: a
-- lane that has never been hand-patched (a fresh staging namespace, a rebuilt
-- onex-dev, prod) gets none of them.
--
-- ============================================================================
-- WHY THIS LINEAGE, AND NOT ONE BULK GRANT FILE
-- ============================================================================
-- This grant belongs next to the file that creates the relation, in the
-- lineage of the node that OWNS it -- the convention
-- `node_projection_session_replay/0002` (OMN-16993),
-- `node_projection_tenant_registry/0001` (OMN-17374) and the eight files the
-- first OMN-17440 tranche landed already follow.
--
-- Deliberately NOT a shared cross-node grant file. That is the shape
-- `0004_grant_tenant_projection_writer.sql` took under protest -- "Homing a
-- cross-node grant block under one node is a real ownership compromise" --
-- and it is exactly why a relation added to a node later silently misses its
-- grant. OMN-15701 is that failure: a pin regeneration reverted eight
-- house-tenant grants at once because they all lived in one place.
--
-- The flat corpus cannot carry it either. Flat migrations are applied by a
-- `psql -f` loop gated on `directive_db == "$DB_NAME"`, while the node-owned
-- loop is the sanctioned path that connects directly to omnidash_analytics
-- (NODE_POSTGRES_DB). So the AUTHORIZATION rides here.
--
-- ============================================================================
-- PRIVILEGES
-- ============================================================================
-- SELECT, INSERT, UPDATE and deliberately NO DELETE -- a projection writer
-- upserts, it does not reshape the table. Same invariant flat 096 states for
-- role_omnidash and flat 099 for this principal on
-- `omninode_internal.live_events`. PostgreSQL requires SELECT alongside
-- INSERT/UPDATE for the adapter's `INSERT ... ON CONFLICT DO UPDATE`, which
-- is why the write set is three privileges and not two.
--
-- This widens NOTHING beyond what the generated topology already declares.
-- It grants only the relations THIS node owns.
--
-- Physical schema is `public`: `0001_create_deployment_evidence_projection_tables.sql` is the file that creates
-- them, and a grant must name the PHYSICAL schema.
--
-- `0001_create_deployment_evidence_projection_tables.sql` itself is NOT edited. It is applied on the `.201` dev
-- lane with a recorded content_sha256, so repairing its grant block in place
-- would raise "conflicting migration checksum in canonical node history"
-- (the OMN-16705 constraint). The grant is therefore a forward ADD.
--
-- Idempotency: GRANT is idempotent; re-running is a no-op. Nothing here
-- touches RLS, ownership, table shape, or any role attribute.

-- ---------------------------------------------------------------------------
-- 1. Schema USAGE, mirroring topology
-- `principals.omninode_runtime.grants[object_type: SCHEMA, schema: public]`.
-- Idempotent, and re-asserted here for the same reason flat 099 re-asserts
-- the omninode_internal one: a migration must not assume a sibling file ran.
-- ---------------------------------------------------------------------------
GRANT USAGE ON SCHEMA public TO omninode_runtime;

-- ---------------------------------------------------------------------------
-- 2. Table grants (topology-derived, OMN-17440)
-- ---------------------------------------------------------------------------
GRANT SELECT, INSERT, UPDATE ON public.deployment_evidence_projection TO omninode_runtime;
GRANT SELECT, INSERT, UPDATE ON public.deployment_readiness_projection TO omninode_runtime;

-- ---------------------------------------------------------------------------
-- 3. Assertions: fail the migration if a grant did not take. Division by zero
-- when the grant is absent -- the same fail-loud shape flat 099,
-- node_log_persistence_effect/0000, node_projection_session_replay/0002 and
-- node_projection_tenant_registry/0001 already use.
--
-- BOTH directions are asserted per relation, not just INSERT. A lane where
-- the INSERT landed and the SELECT did not would accept writes and still
-- fail every `ON CONFLICT DO UPDATE` read-back, which is the harder of the
-- two failures to diagnose.
-- ---------------------------------------------------------------------------
SELECT 1 / count(*) AS deployment_evidence_projection_insert_grant_assertion
FROM information_schema.role_table_grants
WHERE table_schema = 'public'
AND table_name = 'deployment_evidence_projection'
AND grantee = 'omninode_runtime'
AND privilege_type = 'INSERT';

SELECT 1 / count(*) AS deployment_evidence_projection_select_grant_assertion
FROM information_schema.role_table_grants
WHERE table_schema = 'public'
AND table_name = 'deployment_evidence_projection'
AND grantee = 'omninode_runtime'
AND privilege_type = 'SELECT';

SELECT 1 / count(*) AS deployment_readiness_projection_insert_grant_assertion
FROM information_schema.role_table_grants
WHERE table_schema = 'public'
AND table_name = 'deployment_readiness_projection'
AND grantee = 'omninode_runtime'
AND privilege_type = 'INSERT';

SELECT 1 / count(*) AS deployment_readiness_projection_select_grant_assertion
FROM information_schema.role_table_grants
WHERE table_schema = 'public'
AND table_name = 'deployment_readiness_projection'
AND grantee = 'omninode_runtime'
AND privilege_type = 'SELECT';
Loading
Loading