From f1c9fd527fc01d3b548cb9158ff5babae4df3633 Mon Sep 17 00:00:00 2001 From: jonahgabriel Date: Fri, 29 May 2026 05:21:43 -0400 Subject: [PATCH 1/5] fix(OMN-10409): skip Bifrost render for projection API --- docker/docker-compose.infra.yml | 3 ++ .../render_bifrost_delegation_contract.py | 30 ++++++++++++++++--- ...test_render_bifrost_delegation_contract.py | 15 ++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/docker/docker-compose.infra.yml b/docker/docker-compose.infra.yml index cd7d466a04..7bc577c82b 100644 --- a/docker/docker-compose.infra.yml +++ b/docker/docker-compose.infra.yml @@ -774,6 +774,9 @@ services: !!merge <<: *runtime-env OTEL_SERVICE_NAME: omnimarket-projection-api RUNTIME_PROFILE: projection-api + # Projection API serves materialized read models and has no runtime data + # volume for the rendered Bifrost delegation contract. + BIFROST_CONTRACT_PATH: "" ports: - "${PROJECTION_API_PORT:-3002}:3002" healthcheck: diff --git a/src/omnibase_infra/runtime/render_bifrost_delegation_contract.py b/src/omnibase_infra/runtime/render_bifrost_delegation_contract.py index 84f6e51385..9881fb5a7c 100644 --- a/src/omnibase_infra/runtime/render_bifrost_delegation_contract.py +++ b/src/omnibase_infra/runtime/render_bifrost_delegation_contract.py @@ -324,6 +324,22 @@ def _populate_backend_endpoints( return populated +def _resolve_target_path( + *, + target_path: Path | None, + env: Mapping[str, str], +) -> Path | None: + if target_path is not None: + return target_path + configured_path = env.get("BIFROST_CONTRACT_PATH") + if configured_path is None: + return _DEFAULT_TARGET_PATH + stripped_path = configured_path.strip() + if not stripped_path: + return None + return Path(stripped_path) + + def render_bifrost_delegation_contract( *, source_path: Path | None = None, @@ -331,7 +347,7 @@ def render_bifrost_delegation_contract( environ: Mapping[str, str] | None = None, verify_endpoints: bool | None = None, endpoint_probe: EndpointProbe | None = None, -) -> Path: +) -> Path | None: """Render the deployed Bifrost delegation contract and return its path.""" env = environ if environ is not None else os.environ should_verify = ( @@ -342,9 +358,9 @@ def render_bifrost_delegation_contract( probe = endpoint_probe or _probe_openai_model_endpoint _source_env = env.get("BIFROST_SOURCE_CONTRACT_PATH", "").strip() source = source_path or (Path(_source_env) if _source_env else _DEFAULT_SOURCE_PATH) - target = target_path or Path( - env.get("BIFROST_CONTRACT_PATH", str(_DEFAULT_TARGET_PATH)) - ) + target = _resolve_target_path(target_path=target_path, env=env) + if target is None: + return None if not should_verify and _has_populated_endpoint(target): _strip_render_hint_fields(target) @@ -391,6 +407,12 @@ def render_bifrost_delegation_contract( def main() -> int: rendered = render_bifrost_delegation_contract() + if rendered is None: + sys.stdout.write( + "[entrypoint] Bifrost delegation contract rendering disabled: " + "BIFROST_CONTRACT_PATH is empty\n" + ) + return 0 sys.stdout.write(f"[entrypoint] Bifrost delegation contract ready: {rendered}\n") return 0 diff --git a/tests/unit/runtime/test_render_bifrost_delegation_contract.py b/tests/unit/runtime/test_render_bifrost_delegation_contract.py index 9ab301a885..03cc4da7ae 100644 --- a/tests/unit/runtime/test_render_bifrost_delegation_contract.py +++ b/tests/unit/runtime/test_render_bifrost_delegation_contract.py @@ -354,3 +354,18 @@ def test_empty_bifrost_source_env_uses_resolved_default(tmp_path: Path) -> None: assert rendered == target loaded = yaml.safe_load(target.read_text(encoding="utf-8")) assert loaded["backends"][0]["endpoint_url"] == _http_url("coder.local:8000") + + +@pytest.mark.unit +def test_empty_bifrost_contract_path_disables_render(tmp_path: Path) -> None: + source = _source_contract(tmp_path / "source.yaml", required=True) + rendered = render_bifrost_delegation_contract( + source_path=source, + environ={ + "BIFROST_CONTRACT_PATH": "", + "BIFROST_VERIFY_ENDPOINTS": "1", + }, + endpoint_probe=lambda _url, _model, _timeout: "should not run", + ) + + assert rendered is None From ed9009f7b197204115e5132a6079284f3d66f454 Mon Sep 17 00:00:00 2001 From: jonahgabriel Date: Fri, 29 May 2026 06:19:27 -0400 Subject: [PATCH 2/5] test(OMN-10409): align integration gates with current contracts --- ...t_registry_api_projection_tail_integration.py | 16 +++++++--------- .../test_omnibase_spi_runtime_protocol_floor.py | 8 ++++---- uv.lock | 2 +- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/tests/integration/projectors/test_registry_api_projection_tail_integration.py b/tests/integration/projectors/test_registry_api_projection_tail_integration.py index a61b310816..a64568acf6 100644 --- a/tests/integration/projectors/test_registry_api_projection_tail_integration.py +++ b/tests/integration/projectors/test_registry_api_projection_tail_integration.py @@ -156,7 +156,7 @@ async def test_discovery_marks_instance_surface_as_degraded( projector: ProjectorShell, reader: ProjectionReaderRegistration, ) -> None: - """Discovery should explicitly mark post-Consul instance unavailability.""" + """Discovery should omit removed post-Consul instance fields.""" projection = _make_projection() projection.last_applied_offset = _make_sequence(101).offset or 101 @@ -170,13 +170,11 @@ async def test_discovery_marks_instance_surface_as_degraded( discovery = await service.get_discovery(limit=10, offset=0) - assert discovery.instance_discovery_status == "unavailable" - assert discovery.instance_discovery_message == ( - "Service discovery not available (Consul removed)" - ) - assert discovery.live_instances == [] + assert not hasattr(discovery, "instance_discovery_status") + assert not hasattr(discovery, "instance_discovery_message") + assert not hasattr(discovery, "live_instances") assert discovery.summary.total_nodes == 1 assert discovery.summary.active_nodes == 1 - assert discovery.summary.healthy_instances == 0 - assert discovery.summary.unhealthy_instances == 0 - assert any(w.code == "NO_CONSUL_HANDLER" for w in discovery.warnings) + assert not hasattr(discovery.summary, "healthy_instances") + assert not hasattr(discovery.summary, "unhealthy_instances") + assert not any(w.code == "NO_CONSUL_HANDLER" for w in discovery.warnings) diff --git a/tests/integration/test_omnibase_spi_runtime_protocol_floor.py b/tests/integration/test_omnibase_spi_runtime_protocol_floor.py index 5baa14b32d..c26683e520 100644 --- a/tests/integration/test_omnibase_spi_runtime_protocol_floor.py +++ b/tests/integration/test_omnibase_spi_runtime_protocol_floor.py @@ -1,7 +1,7 @@ # SPDX-FileCopyrightText: 2025 OmniNode.ai Inc. # SPDX-License-Identifier: MIT -"""Integration sentinel for the omnibase-spi 0.21.0 runtime protocol floor. +"""Integration sentinel for the omnibase-spi 0.22.0 runtime protocol floor. OMN-10169 raises the dependency floor because runtime auto-wiring imports ``omnibase_spi.protocols.runtime``. The fallback compatibility matrix must @@ -30,7 +30,7 @@ def _minimum_for(package: str, matrix: Sequence[VersionConstraint]) -> str: @pytest.mark.integration -def test_omnibase_spi_runtime_protocols_match_0210_floor() -> None: +def test_omnibase_spi_runtime_protocols_match_0220_floor() -> None: """The declared and fallback SPI floors both expose runtime protocols.""" from omnibase_spi.protocols.runtime.protocol_handler_ownership_query import ( ProtocolHandlerOwnershipQuery, @@ -39,7 +39,7 @@ def test_omnibase_spi_runtime_protocols_match_0210_floor() -> None: ProtocolHandlerResolver, ) - assert _minimum_for("omnibase_spi", VERSION_MATRIX) == "0.21.0" - assert _minimum_for("omnibase_spi", _FALLBACK_MATRIX) == "0.21.0" + assert _minimum_for("omnibase_spi", VERSION_MATRIX) == "0.22.0" + assert _minimum_for("omnibase_spi", _FALLBACK_MATRIX) == "0.22.0" assert hasattr(ProtocolHandlerResolver, "__class_getitem__") assert hasattr(ProtocolHandlerOwnershipQuery, "__class_getitem__") diff --git a/uv.lock b/uv.lock index b025fa04ec..7f7289a7f0 100644 --- a/uv.lock +++ b/uv.lock @@ -2159,7 +2159,7 @@ dependencies = [ [[package]] name = "onex-change-control" version = "0.5.0" -source = { git = "https://github.com/OmniNode-ai/onex_change_control.git?branch=main#c3d38e71fb17dc71380be2aeeb204994c885424a" } +source = { git = "https://github.com/OmniNode-ai/onex_change_control.git?branch=main#2741a4096e2eaa48ce516a374b9765beda908073" } dependencies = [ { name = "colorama" }, { name = "omnibase-core" }, From 0100d1c718e17817b88570400464fe1f2270d757 Mon Sep 17 00:00:00 2001 From: jonahgabriel Date: Fri, 29 May 2026 07:20:07 -0400 Subject: [PATCH 3/5] ci(OMN-10409): disable cache on timeout-sensitive checks --- .github/workflows/check-sibling-compat.yml | 1 + .github/workflows/reusable-runtime-boot.yml | 2 +- tests/ci/test_ci_workflow_resilience.py | 10 ++++++++++ tests/ci/test_reusable_runtime_boot_schema.py | 8 ++++++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-sibling-compat.yml b/.github/workflows/check-sibling-compat.yml index 3576b20b85..88397952dc 100644 --- a/.github/workflows/check-sibling-compat.yml +++ b/.github/workflows/check-sibling-compat.yml @@ -63,6 +63,7 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} uv-version: ${{ env.UV_VERSION }} cache-version: ${{ env.CACHE_VERSION }} + cache-enabled: "false" cache-key-prefix: uv-sibling-compat lock-file-path: 'omnibase_infra/**/uv.lock' skip-install: 'true' diff --git a/.github/workflows/reusable-runtime-boot.yml b/.github/workflows/reusable-runtime-boot.yml index 5d737a5dbe..4e0a1dfd6e 100644 --- a/.github/workflows/reusable-runtime-boot.yml +++ b/.github/workflows/reusable-runtime-boot.yml @@ -117,7 +117,7 @@ jobs: with: version: "0.6.14" python-version: "3.12" - enable-cache: true + enable-cache: false - name: Install CLI dependencies (jq, curl) if: inputs.mode == 'compose' diff --git a/tests/ci/test_ci_workflow_resilience.py b/tests/ci/test_ci_workflow_resilience.py index 89e88effc0..a9674b23ee 100644 --- a/tests/ci/test_ci_workflow_resilience.py +++ b/tests/ci/test_ci_workflow_resilience.py @@ -185,6 +185,16 @@ def test_short_gates_can_disable_uv_cache_cleanup() -> None: ) assert setup_step["with"]["cache-enabled"] == "false" + sibling_workflow = _load_yaml( + REPO_ROOT / ".github" / "workflows" / "check-sibling-compat.yml" + ) + setup_step = next( + step + for step in sibling_workflow["jobs"]["sibling-compat"]["steps"] + if step.get("uses") == "./omnibase_infra/.github/actions/setup-python-uv" + ) + assert setup_step["with"]["cache-enabled"] == "false" + docker_workflow = _load_yaml(DOCKER_BUILD_WORKFLOW) docker_cache_step = next( step diff --git a/tests/ci/test_reusable_runtime_boot_schema.py b/tests/ci/test_reusable_runtime_boot_schema.py index bde13e4b6f..5916917f58 100644 --- a/tests/ci/test_reusable_runtime_boot_schema.py +++ b/tests/ci/test_reusable_runtime_boot_schema.py @@ -235,6 +235,14 @@ def test_boot_has_uv_setup_step(workflow: Workflow) -> None: ) +def test_boot_disables_uv_cache_cleanup(workflow: Workflow) -> None: + steps = _boot_steps(workflow) + setup_step = next( + s for s in steps if "astral-sh/setup-uv" in str(s.get("uses", "")) + ) + assert setup_step["with"]["enable-cache"] is False + + def test_boot_has_conditional_compose_bringup(workflow: Workflow) -> None: steps = _boot_steps(workflow) matched = [ From 0a6a7dd422c2a0af31ec28252b02a014ef044531 Mon Sep 17 00:00:00 2001 From: jonahgabriel Date: Fri, 29 May 2026 08:03:31 -0400 Subject: [PATCH 4/5] ci(OMN-10409): retry topic drift dependency sync --- .github/workflows/ci.yml | 6 +----- tests/ci/test_ci_workflow_resilience.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 41cc7efc0d..34e942c2f3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -431,11 +431,7 @@ jobs: cache-enabled: "false" cache-key-prefix: uv-topic-drift lock-file-path: 'omnibase_infra/**/uv.lock' - skip-install: 'true' - - - name: Install omnibase_infra dependencies - working-directory: omnibase_infra - run: uv sync --no-cache + working-directory: omnibase_infra - name: Check topic drift (cross-repo) working-directory: omnibase_infra diff --git a/tests/ci/test_ci_workflow_resilience.py b/tests/ci/test_ci_workflow_resilience.py index a9674b23ee..dd395dcb23 100644 --- a/tests/ci/test_ci_workflow_resilience.py +++ b/tests/ci/test_ci_workflow_resilience.py @@ -205,6 +205,21 @@ def test_short_gates_can_disable_uv_cache_cleanup() -> None: assert docker_cache_step["uses"] == "actions/cache/restore@v5" +def test_topic_drift_uses_retrying_uv_install() -> None: + ci_workflow = _load_yaml(CI_WORKFLOW) + steps = ci_workflow["jobs"]["topic-drift-check"]["steps"] + setup_step = next( + step + for step in steps + if step.get("uses") == "./omnibase_infra/.github/actions/setup-python-uv" + ) + + assert setup_step["with"]["cache-enabled"] == "false" + assert setup_step["with"]["working-directory"] == "omnibase_infra" + assert setup_step["with"].get("skip-install") != "true" + assert not any(step.get("run") == "uv sync --no-cache" for step in steps) + + def test_setup_python_uv_retries_uv_sync_and_logs_transport_settings() -> None: action = _load_yaml(SETUP_PYTHON_UV_ACTION) From 19f9cbe741db43aa8fb0230e21523e26c3bbad65 Mon Sep 17 00:00:00 2001 From: jonahgabriel Date: Fri, 29 May 2026 08:34:43 -0400 Subject: [PATCH 5/5] ci(OMN-10409): retry schema handshake dependency sync --- .github/workflows/ci.yml | 6 +----- tests/ci/test_ci_workflow_resilience.py | 23 ++++++++++++----------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 34e942c2f3..f7b4cf585d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -500,11 +500,7 @@ jobs: cache-enabled: "false" cache-key-prefix: uv-handshake lock-file-path: 'omnibase_infra/**/uv.lock' - skip-install: 'true' - - - name: Install omnibase_infra dev dependencies - working-directory: omnibase_infra - run: uv sync --no-cache + working-directory: omnibase_infra - name: Install sibling repos as editable (boundary pair deps) working-directory: omnibase_infra diff --git a/tests/ci/test_ci_workflow_resilience.py b/tests/ci/test_ci_workflow_resilience.py index dd395dcb23..66ea08f504 100644 --- a/tests/ci/test_ci_workflow_resilience.py +++ b/tests/ci/test_ci_workflow_resilience.py @@ -205,19 +205,20 @@ def test_short_gates_can_disable_uv_cache_cleanup() -> None: assert docker_cache_step["uses"] == "actions/cache/restore@v5" -def test_topic_drift_uses_retrying_uv_install() -> None: +def test_cross_repo_ci_jobs_use_retrying_uv_install() -> None: ci_workflow = _load_yaml(CI_WORKFLOW) - steps = ci_workflow["jobs"]["topic-drift-check"]["steps"] - setup_step = next( - step - for step in steps - if step.get("uses") == "./omnibase_infra/.github/actions/setup-python-uv" - ) + for job_name in ("topic-drift-check", "schema-handshake"): + steps = ci_workflow["jobs"][job_name]["steps"] + setup_step = next( + step + for step in steps + if step.get("uses") == "./omnibase_infra/.github/actions/setup-python-uv" + ) - assert setup_step["with"]["cache-enabled"] == "false" - assert setup_step["with"]["working-directory"] == "omnibase_infra" - assert setup_step["with"].get("skip-install") != "true" - assert not any(step.get("run") == "uv sync --no-cache" for step in steps) + assert setup_step["with"]["cache-enabled"] == "false" + assert setup_step["with"]["working-directory"] == "omnibase_infra" + assert setup_step["with"].get("skip-install") != "true" + assert not any(step.get("run") == "uv sync --no-cache" for step in steps) def test_setup_python_uv_retries_uv_sync_and_logs_transport_settings() -> None: