Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
27df990
docs(OMN-12962): contract-store durability audit — cold-runtime censu…
jonahgabriel Jun 11, 2026
8d7da12
fix(OMN-12970): vendor omnimarket projection node migrations into for…
jonahgabriel Jun 11, 2026
36f71e8
fix(OMN-12965): stamp runtime image identity (version + revision) in …
jonahgabriel Jun 11, 2026
7eec9f9
fix(OMN-12987): workspace-build sibling lock-pin preflight + provenan…
jonahgabriel Jun 11, 2026
35b0b0f
fix(OMN-12988): pin stability runtime-worker to replicas 1 + census r…
jonahgabriel Jun 11, 2026
811f588
fix(OMN-12979): expire-bound topic completeness suppressions (#1940)
jonahgabriel Jun 11, 2026
d7aac6a
fix(OMN-12966): accept community-edition Infisical /api/status in pro…
jonahgabriel Jun 11, 2026
5617714
feat(OMN-12958): volume-config drift gate + runtime config provenance…
jonahgabriel Jun 11, 2026
1992388
feat(OMN-12957): wire runtime-profile validator + core registry parit…
jonahgabriel Jun 11, 2026
a242faa
fix(OMN-12973): widen migration-gate healthcheck start_period + ratch…
jonahgabriel Jun 11, 2026
ada95a5
feat(OMN-12971): deliver Vertex ADC bearer token to runtime effects c…
jonahgabriel Jun 11, 2026
2c27d17
feat(OMN-13008): automated .201 disk maintenance — worktree GC + dock…
jonahgabriel Jun 11, 2026
36d9827
fix(OMN-13005): materialize blocking event_consumer in runtime auto-w…
jonahgabriel Jun 12, 2026
e430e95
fix(OMN-12990): pin worker replicas in ledgered config + fail-fast la…
jonahgabriel Jun 12, 2026
1e4cfa3
feat(OMN-12909): add gateway bus forwarder P0A (#1946)
jonahgabriel Jun 12, 2026
9910b52
feat(OMN-13011): LANE CENSUS RECONCILIATION ratchet — declared desire…
jonahgabriel Jun 12, 2026
556bfb7
fix(OMN-13020): vendor missing node migrations — llm_routing 0000 + c…
jonahgabriel Jun 12, 2026
89385cb
fix(OMN-13058): close TerminalConsumerSession on open() failure (work…
jonahgabriel Jun 12, 2026
577281a
feat(OMN-13021): non-dev-base guard — fail feature-base PRs absent St…
jonahgabriel Jun 12, 2026
6da941d
feat(OMN-13014): hot-patch ledger rebuild preflight gate (retro B-1) …
jonahgabriel Jun 12, 2026
c691963
fix(OMN-12977): workspace-build sibling-pin ratchet — honor consuming…
jonahgabriel Jun 12, 2026
b261583
fix(OMN-12989): workspace-mode image build must honor sibling lock pi…
jonahgabriel Jun 12, 2026
e342e27
fix(OMN-13055): absent repos in REPOS list warn and exit 0 instead of…
jonahgabriel Jun 12, 2026
72142f8
fix(OMN-13070): config_prefetcher overlay wins on controlled lanes (#…
jonahgabriel Jun 12, 2026
ee39030
fix(OMN-13062): migration-gate vacuity fix — sentinel discipline, wai…
jonahgabriel Jun 12, 2026
574ac92
feat(OMN-12864): Bifrost endpoints → committed overlay authority + fa…
jonahgabriel Jun 12, 2026
34d6e93
feat(OMN-12858/OMN-12879/OMN-12880): dispatcher route-coverage CI gat…
jonahgabriel Jun 12, 2026
c050552
feat(OMN-13026): wire transport-mock-lint pre-commit hook + CI gate (…
jonahgabriel Jun 12, 2026
20273e5
feat(OMN-13094): --output receipt mode on onex node/run — quiet typed…
jonahgabriel Jun 13, 2026
78d8984
feat(OMN-13097): onex skill subcommand + declarative skill->node mapp…
jonahgabriel Jun 13, 2026
7aa998b
fix+test(OMN-13012): force terminal-topic metadata refresh so both ep…
jonahgabriel Jun 13, 2026
9d09e6e
feat(OMN-13096): onex delegate single-command subcommand (Phase 2b) (…
jonahgabriel Jun 13, 2026
ab9d606
fix(OMN-13118): tolerate partition-less reply topic in terminal consu…
jonahgabriel Jun 13, 2026
cdf53d9
fix(OMN-13118): pin terminal-consumer read offset synchronously (clos…
jonahgabriel Jun 13, 2026
8fdf767
fix(OMN-13137): _validate_routing strategy-aware event_model checks (…
jonahgabriel Jun 13, 2026
88eda0d
fix(OMN-13118): independent per-terminal-topic consumers in Pattern B…
jonahgabriel Jun 13, 2026
7aea40e
fix(OMN-13118): long-lived terminal correlator replaces per-trial eph…
jonahgabriel Jun 13, 2026
d703ca7
fix(OMN-13118): correlator resolves matched terminal in place for lat…
jonahgabriel Jun 14, 2026
7bbb06e
fix(OMN-12987): deploy-runtime.sh sibling lock-pin preflight uses cur…
jonahgabriel Jun 14, 2026
c513071
fix(OMN-13124): vendor pattern_learning node migration + always-run v…
jonahgabriel Jun 14, 2026
2d2a634
fix(OMN-12987): stage workspace/sibling-pin-comparison.json into depl…
jonahgabriel Jun 14, 2026
4847d00
fix(OMN-13124): retire legacy 064 pattern_learning_artifacts migratio…
jonahgabriel Jun 14, 2026
40c849e
fix(OMN-12987): project-namespace forward-migration container_name to…
jonahgabriel Jun 14, 2026
b56a3ff
fix(OMN-13141): runtime executor skips event_model import for operati…
jonahgabriel Jun 14, 2026
0159438
fix(OMN-8724): coerce dict payload into typed handler model at dispat…
jonahgabriel Jun 14, 2026
649b233
fix(OMN-13149): savings consumer decodes typed ModelEventMessage inst…
jonahgabriel Jun 14, 2026
a96fb35
fix(OMN-13150): vendor node_projection_routing_decision agent_routing…
jonahgabriel Jun 14, 2026
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
29 changes: 29 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,28 @@ jobs:
- name: LLM topology contract drift validator (OMN-11926)
run: PYTHONPATH=src uv run python -m omnibase_infra.validators.llm_topology_validator contracts/llm_endpoints.yaml

# OMN-13026: Transport-mock lint. Bare AsyncMock/MagicMock without
# spec=/spec_set= on EventBus/transport/kafka surfaces. Ratchet: existing
# violations frozen in config/validation/transport_mock_baseline.yaml. New
# violations in any PR are blocked. Drain tracked by per-site tickets.
# SYNC with pre-commit hook 'transport-mock-lint'.
# Clone omnibase_core HEAD so the validator is available before the
# OMN-13026 omnibase_core pin bump lands in the lockfile.
- name: Checkout omnibase_core validator source
uses: actions/checkout@v6
with:
repository: OmniNode-ai/omnibase_core
ref: dev
path: .ci/omnibase_core
token: ${{ secrets.OMNIBASE_CORE_TOKEN || secrets.GITHUB_TOKEN }}

- name: Transport-mock lint (OMN-13026)
run: |
PYTHONPATH=.ci/omnibase_core/src uv run python \
-m omnibase_core.validators.transport_mock_lint \
--baseline config/validation/transport_mock_baseline.yaml \
tests/

- name: Run mypy type checking
run: uv run mypy src/omnibase_infra

Expand Down Expand Up @@ -982,6 +1004,13 @@ jobs:
echo "================================================================"
uv run python scripts/check_dockerfile_pins.py

- name: Check runtime image identity stamping
run: |
echo "================================================================"
echo "Runtime Image Identity Check (OMN-12965)"
echo "================================================================"
uv run python scripts/check_runtime_image_identity.py

# ============================================================================
# ONEX Compliance Check
# Runs `onex compliance check` to validate contracts, handlers, and schemas.
Expand Down
134 changes: 134 additions & 0 deletions .github/workflows/dispatcher-route-coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# SPDX-FileCopyrightText: 2025 OmniNode.ai Inc.
# SPDX-License-Identifier: MIT
#
# dispatcher-route-coverage.yml — OMN-12858 / OMN-12879 / OMN-12880
#
# CI gate: for every contract.yaml in omnibase_infra + omnimarket that
# subscribes to a command topic (onex.cmd.*), assert that the contract
# declares a dispatcher route via handler_routing or runtime_dispatch.
#
# Missing wiring causes the command to go to DLQ silently. This gate
# catches that regression before it reaches the runtime.
#
# MOTIVATION — two incidents this gate would have caught:
#
# 1. June 9 2026 DLQ regression: node_generation_consumer subscribed
# onex.cmd.omnimarket.node-generation-requested.v1 but auto-wiring
# produced zero dispatchers after a sole-handler revert was merged.
# Messages silently went to DLQ. (OMN-12858 post-mortem)
#
# 2. June 12 2026 DEL-01 live finding: onex.cmd.omnimarket.delegate-skill.v1
# was consumed by the dev lane bus but no dispatcher route existed in any
# deployed contract, so delegation requests went to DLQ silently.
# Discovered via manual rpk consumer-group lag probe (DEL-01 evidence).
#
# Coverage scope (OMN-12880):
# - All subscribed topics where topic contains '.cmd.'
# - compatibility_publish_topics are sender-side only; they are NOT
# checked for missing routes (no false positives).
#
# Changed-command-topic mode (OMN-12879):
# - When the PR diff touches contract.yaml files, only those contracts are
# checked. Pre-existing allowlisted violations are not re-reported.
#
# Ratchet / baseline model:
# - Known pre-existing violations are in scripts/check_dispatcher_route_coverage.py
# _ALLOWLISTED_CMD_TOPICS with ticket refs and expiry dates.
# - New violations are NEVER silently added — they must be fixed.

name: Dispatcher Route Coverage

on:
pull_request:
branches: [main, dev]
push:
branches: [main]
merge_group:

permissions:
contents: read

jobs:
dispatcher-route-coverage:
name: dispatcher-route-coverage
runs-on: >-
${{
(github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name != github.repository)
&& fromJSON(vars.OMNI_PUBLIC_PR_RUNS_ON_JSON || '["ubuntu-latest"]')
|| fromJSON(vars.OMNI_TRUSTED_CI_RUNS_ON_JSON || '["self-hosted","omnibase-ci"]')
}}
timeout-minutes: 5

steps:
- name: Checkout omnibase_infra
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Checkout omnimarket (sibling)
uses: actions/checkout@v6
with:
repository: OmniNode-ai/omnimarket
ref: dev
path: omnimarket
token: ${{ secrets.OMNI_GITHUB_TOKEN || github.token }}
# Sparse checkout: only the contract files needed for coverage analysis
sparse-checkout: |
src/omnimarket/nodes
sparse-checkout-cone-mode: false

- name: Install pyyaml (only dep for gate script)
shell: bash
run: |
# The gate script uses only stdlib + pyyaml; skip full uv sync to keep
# this job fast (no Kafka, no DB, no handler imports).
python3 -m pip install --quiet pyyaml

- name: Collect changed contract paths (OMN-12879)
id: changed_contracts
shell: bash
run: |
set -euo pipefail
# Find contract.yaml files changed in this PR diff vs the base branch.
# For push/merge_group events there is no PR diff; run full scan.
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
BASE="${{ github.event.pull_request.base.sha }}"
HEAD="${{ github.event.pull_request.head.sha }}"
CHANGED=$(git diff --name-only "$BASE" "$HEAD" -- '**/contract.yaml' || true)
if [[ -n "$CHANGED" ]]; then
# Convert to absolute paths so the script can match them
ABS_PATHS=$(echo "$CHANGED" | xargs -I{} realpath --relative-to=. {} 2>/dev/null || echo "$CHANGED")
echo "changed_contracts=$ABS_PATHS" >> "$GITHUB_OUTPUT"
echo "Found changed contracts:"
echo "$CHANGED" | head -20
else
echo "changed_contracts=" >> "$GITHUB_OUTPUT"
echo "No contract.yaml files changed; full scan will run."
fi
else
echo "changed_contracts=" >> "$GITHUB_OUTPUT"
echo "Non-PR event; running full scan."
fi

- name: Run dispatcher route-coverage gate
shell: bash
run: |
set -euo pipefail

CHANGED="${{ steps.changed_contracts.outputs.changed_contracts }}"
EXTRA_DIR="omnimarket/src/omnimarket/nodes"

ARGS=(
"--contracts-dir" "src/omnibase_infra/nodes"
"--extra-contracts-dir" "$EXTRA_DIR"
)

if [[ -n "${CHANGED}" ]]; then
echo "::notice::Running in changed-contract mode (OMN-12879): $(echo "${CHANGED}" | wc -w) paths"
ARGS+=("--changed-contracts" "${CHANGED}")
else
echo "::notice::Running full scan across both contract directories"
fi

python3 scripts/check_dispatcher_route_coverage.py "${ARGS[@]}"
85 changes: 85 additions & 0 deletions .github/workflows/node-migration-sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Node Migration Vendor Sync Gate (OMN-13124)
#
# WHY THIS EXISTS
# omnimarket projection nodes ship SQL under
# src/omnimarket/nodes/<node>/migrations/*.sql
# which must be vendored into omnibase_infra under
# docker/migrations/forward/nodes/<node>/ (by scripts/sync-node-migrations.sh)
# so the forward-migration runner recreates the projection tables on a clean
# redeploy. The local pre-commit hook (onex-check-node-migration-sync) only
# runs in the infra repo and only when an infra commit is made; an omnimarket
# PR that adds a node migration cannot fire it. OMN-13124's
# node_projection_pattern_learning merged WITHOUT its vendored copy, so
# pattern_learning_artifacts was absent from omnidash_analytics on a clean
# redeploy and the golden-chain pattern_learning chain only passed via a live
# hot-fix (golden-chain sweep run12 Finding). This gate is the enforcement
# layer: every infra PR (and merge_group) re-runs the vendor --check against
# the current omnimarket dev tip, so an un-vendored or drifted node migration
# fails CI before merge.

name: node-migration-sync

on:
pull_request:
branches: [main, dev]
push:
branches: [main]
merge_group:

permissions:
contents: read

jobs:
node-migration-sync:
name: node-migration-sync
runs-on: >-
${{
(github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name != github.repository)
&& fromJSON(vars.OMNI_PUBLIC_PR_RUNS_ON_JSON || '["ubuntu-latest"]')
|| fromJSON(vars.OMNI_TRUSTED_CI_RUNS_ON_JSON || '["self-hosted","omnibase-ci"]')
}}
timeout-minutes: 5

steps:
- name: Checkout omnibase_infra
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Checkout omnimarket (sibling — node migration source of truth)
uses: actions/checkout@v6
with:
repository: OmniNode-ai/omnimarket
ref: dev
path: omnimarket-src
token: ${{ secrets.OMNI_GITHUB_TOKEN || github.token }}
# Sparse checkout: only the node tree carrying migrations/*.sql.
sparse-checkout: |
src/omnimarket/nodes
sparse-checkout-cone-mode: false

- name: Run node migration vendor sync --check
shell: bash
env:
# The script's resolution order prefers OMNIMARKET_SRC (a repo root that
# contains src/omnimarket/nodes). Point it at the sibling checkout so the
# gate compares the vendored tree against the omnimarket dev tip and never
# silently passes on an unresolvable source.
OMNIMARKET_SRC: ${{ github.workspace }}/omnimarket-src
run: |
set -euo pipefail
echo "::group::node migration vendor sync --check"
if bash scripts/sync-node-migrations.sh --check; then
echo "::endgroup::"
echo "::notice::node migration vendor tree is in sync with omnimarket dev tip."
else
rc=$?
echo "::endgroup::"
if [[ "${rc}" -eq 2 ]]; then
echo "::error::Could not resolve the omnimarket source tree (exit 2). The sibling checkout is missing or empty."
else
echo "::error::Vendored node migrations under docker/migrations/forward/nodes/ are OUT OF SYNC with omnimarket. Run 'scripts/sync-node-migrations.sh' locally and commit the diff. An un-vendored node migration means its projection table will be MISSING after a clean redeploy (golden-chain run12 Finding)."
fi
exit "${rc}"
fi
65 changes: 65 additions & 0 deletions .github/workflows/non-dev-base-guard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# SPDX-FileCopyrightText: 2026 OmniNode.ai Inc.
# SPDX-License-Identifier: MIT
#
# OMN-13021 (retro A-6): Fail PRs whose base is neither dev nor main unless
# the body declares an intentional stack via `Stacked-Parent: #<pr-number>`.
#
# Failure class: feedback_stacked_prs_orphan_from_dev — PRs #1185/#1954 were
# auto-merged INTO parent feature branches, producing misleading MERGED states
# and stranding the work off dev (recurrence of the June 5 incident, 3 tickets
# stranded). Base=main is governed by main-target-guard (OMN-12243/OMN-12477).

name: Non-dev base guard

on:
pull_request:
types: [opened, edited, synchronize]

permissions:
contents: read

jobs:
non-dev-base-guard:
name: non-dev-base-guard
runs-on: >-
${{
(github.event.pull_request.head.repo.full_name != github.repository)
&& fromJSON(vars.OMNI_PUBLIC_PR_RUNS_ON_JSON || '["ubuntu-latest"]')
|| fromJSON(vars.OMNI_TRUSTED_CI_RUNS_ON_JSON || '["self-hosted","omnibase-ci"]')
}}
timeout-minutes: 5

steps:
- name: Check PR base branch
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
HEAD_REF: ${{ github.event.pull_request.head.ref }}
PR_BODY: ${{ github.event.pull_request.body }}
run: |
set -euo pipefail

if [[ "${BASE_REF}" == "dev" ]]; then
echo "::notice::PR targets dev; guard does not apply."
exit 0
fi

if [[ "${BASE_REF}" == "main" ]]; then
echo "::notice::PR targets main; main-target-guard governs that path."
exit 0
fi

echo "PR targets feature base '${BASE_REF}' from head '${HEAD_REF}'."

if echo "${PR_BODY}" | grep -qE 'Stacked-Parent:[[:space:]]*#[0-9]+'; then
echo "::notice::Declared stacked PR (Stacked-Parent found). Allowed."
echo "::warning::Stacked PRs merge INTO their parent branch, not dev."
echo "::warning::Do NOT arm auto-merge on this PR; land the parent into dev first."
exit 0
fi

echo "::error::PR base '${BASE_REF}' is not the integration branch (dev)."
echo "::error::Auto-merge on this PR would fold it INTO '${BASE_REF}' and strand it off dev"
echo "::error::(feedback_stacked_prs_orphan_from_dev — the #1185/#1954 incident class)."
echo "::error::Either retarget to dev, or declare an intentional stack by adding a body line:"
echo "::error:: Stacked-Parent: #<parent-pr-number>"
exit 1
53 changes: 46 additions & 7 deletions .github/workflows/reusable-runtime-boot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -287,13 +287,52 @@ jobs:
echo "E2E_REDPANDA_ADVERTISE_HOST=${E2E_REDPANDA_ADVERTISE_HOST}"
} >> "$GITHUB_ENV"

POSTGRES_PORT="${POSTGRES_PORT}" \
KAFKA_PORT="${KAFKA_PORT}" \
REDPANDA_ADMIN_PORT="${REDPANDA_ADMIN_PORT}" \
REDPANDA_SCHEMA_REGISTRY_PORT="${REDPANDA_SCHEMA_REGISTRY_PORT}" \
REDPANDA_PANDAPROXY_PORT="${REDPANDA_PANDAPROXY_PORT}" \
E2E_REDPANDA_ADVERTISE_HOST="${E2E_REDPANDA_ADVERTISE_HOST}" \
"${compose_cmd[@]}" -p "${OMNIBASE_INFRA_COMPOSE_PROJECT}" -f docker/docker-compose.e2e.yml up -d postgres redpanda
compose_up() {
POSTGRES_PORT="${POSTGRES_PORT}" \
KAFKA_PORT="${KAFKA_PORT}" \
REDPANDA_ADMIN_PORT="${REDPANDA_ADMIN_PORT}" \
REDPANDA_SCHEMA_REGISTRY_PORT="${REDPANDA_SCHEMA_REGISTRY_PORT}" \
REDPANDA_PANDAPROXY_PORT="${REDPANDA_PANDAPROXY_PORT}" \
E2E_REDPANDA_ADVERTISE_HOST="${E2E_REDPANDA_ADVERTISE_HOST}" \
"${compose_cmd[@]}" -p "${OMNIBASE_INFRA_COMPOSE_PROJECT}" -f docker/docker-compose.e2e.yml up -d postgres redpanda
}

retry_compose_down() {
"${compose_cmd[@]}" -p "${OMNIBASE_INFRA_COMPOSE_PROJECT}" -f docker/docker-compose.e2e.yml down -v --remove-orphans || true
docker network rm "${OMNIBASE_INFRA_NETWORK}" "${OMNIBASE_INFRA_COMPOSE_PROJECT}_default" 2>/dev/null || true
}

compose_started=false
for compose_attempt in 1 2 3; do
if compose_up; then
compose_started=true
break
fi
compose_status=$?
if [[ "${compose_attempt}" -eq 3 ]]; then
exit "${compose_status}"
fi
echo "::warning::compose infra bring-up failed on attempt ${compose_attempt}; repicking host ports and retrying"
retry_compose_down
export POSTGRES_PORT="$(pick_free_port)"
export KAFKA_PORT="$(pick_free_port)"
export REDPANDA_ADMIN_PORT="$(pick_free_port)"
export REDPANDA_SCHEMA_REGISTRY_PORT="$(pick_free_port)"
export REDPANDA_PANDAPROXY_PORT="$(pick_free_port)"
{
echo "POSTGRES_PORT=${POSTGRES_PORT}"
echo "PG_PORT=${POSTGRES_PORT}"
echo "KAFKA_PORT=${KAFKA_PORT}"
echo "REDPANDA_ADMIN_PORT=${REDPANDA_ADMIN_PORT}"
echo "REDPANDA_SCHEMA_REGISTRY_PORT=${REDPANDA_SCHEMA_REGISTRY_PORT}"
echo "REDPANDA_PANDAPROXY_PORT=${REDPANDA_PANDAPROXY_PORT}"
} >> "$GITHUB_ENV"
done

if [[ "${compose_started}" != "true" ]]; then
echo "::error::compose infra bring-up failed before health checks"
exit 1
fi

capture_compose_infra_diagnostics() {
{
Expand Down
Loading
Loading