Skip to content

fix(OMN-14531): close the omnimarket drift guard's fail-open blind spot - #2291

Merged
jonahgabriel merged 2 commits into
devfrom
jonah/omn-14531-aislop-sweep-dispatch
Jul 13, 2026
Merged

jonahgabriel merged 2 commits into
devfrom
jonah/omn-14531-aislop-sweep-dispatch

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Jul 13, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

OMN-14531 (detector-shelf unblinding): the onex:aislop_sweep skill's only
documented dispatch path — uv run onex skill aislop_sweep — was
hard-failing with Unknown node 'node_aislop_sweep' because omnimarket
(the co-installed provider of onex.nodes entry points for market nodes,
including node_aislop_sweep) was completely absent from the
omnibase_infra venv on this operator's machine. This is the OMN-13829 →
OMN-14060 recurrence going one step further: the co-install regressed from
"stale" to "gone", and nothing caught it.

Two compounding gaps in omnimarket_drift_guard.py / cli_skill.py let
this go undetected instead of failing loud:

  1. check_omnimarket_drift() failed open on "not installed" unconditionally.
    It returned silently whenever installed_omnimarket_commit() was None,
    even when a canonical $OMNI_HOME/omnimarket clone WAS present and
    reachable — a determinable, actionable state, not the "can't reason about
    it" case the fail-open design exists for. Reordered the checks: canonical
    clone absent → still fails open (CI, fresh machines, unchanged). Canonical
    clone present + omnimarket absent/non-VCS → now raises
    OmnimarketDriftError naming the exact repair command.
  2. --omni-home had no envvar binding. Even with gap (1) fixed, the
    guard never received a real value in normal usage: callers never pass
    --omni-home explicitly, and exporting $OMNI_HOME in the shell had zero
    effect on the CLI. Bound the option to the OMNI_HOME environment
    variable so the guard is actually reachable without an undocumented flag.

Also includes an unrelated, pre-existing chore commit: vendoring
node_projection_context_roi/002_...sql to satisfy the local
onex-check-node-migration-sync pre-commit hook (repo-wide drift introduced
by OMN-14535, already fixed for real in omnibase_infra#2290 / OMN-14555,
not yet merged to dev). This hook is not a required GitHub status check
(confirmed live in ROLLING_WORK_LEDGER 2026-07-13), so it has no bearing on
mergeability — it only unblocks the local commit gate for the actual fix in
this PR. Expected to be a no-op once #2290 merges and this branch rebases.

RED → GREEN evidence (dod_evidence)

Manually reproduced against the real onex CLI (the exact uv run onex skill aislop_sweep path documented in plugins/onex/skills/aislop_sweep/):

BEFORE (omnimarket absent from the omnibase_infra venv):

$ uv run onex skill aislop_sweep --target-dirs <node_aislop_sweep source> --dry-run
Error: Unknown node 'node_aislop_sweep'. Known nodes: node_architecture_validator, ...
exit 1

AFTER (scripts/install-node-skill-package.sh --execute repairs the
venv; this PR's fix is what makes the failure loud/actionable instead of a
silent, unhelpful "Unknown node" wall of text next time it drifts):

$ uv run onex skill aislop_sweep --target-dirs <node_aislop_sweep source> --dry-run
exit 0
{"status":"success", ..., "result":{"findings":[
  {"check":"prohibited-patterns","message":"Prohibited pattern: ONEX_EVENT_BUS_TYPE=inmemory", "severity":"CRITICAL", ...},
  ... 11 findings total ...
], "repos_scanned":1, "status":"findings", "dry_run":true}}

repos_scanned=1, 11 real findings including CRITICAL-severity hits — the
handler and dispatch pipeline were never broken; only the venv provisioning
and this guard's blind spot were.

Automated regression coverage (new, both pass RED→GREEN against the prior
code):

  • test_drift_check_raises_when_not_installed_but_canonical_clone_present —
    fails under the old unconditional fail-open code, passes under the fix.
  • test_omnimarket_drift_guard.py full suite: 14 passed.
  • test_cli_skill.py full suite (with a new autouse fixture keeping
    command-wiring tests hermetic against the now-live --omni-home envvar):
    341 passed, 19 skipped (pre-existing omnimarket-not-in-CI-venv skips,
    unrelated).

Local gates: ruff format --check / ruff check / mypy clean on touched
files; full pre-commit run clean.

Known related gap (out of scope for this PR)

cli_node.py (onex node / onex run) has NO drift-guard call at all —
the runbook's own documented symptom example (onex run-node node_pr_lifecycle_orchestrator) uses that exact path. aislop_sweep is
only reachable via onex skill, so this PR stays scoped there; flagging for
a follow-up ticket.

Evidence-Ticket: OMN-14531

OCC Evidence

Evidence-Source: OCC#4103
Evidence-Ticket: OMN-14531
Evidence-Commit: 798602635940a856f78f13d126406578e770e1f6

…ft, OMN-14555)

Unrelated to this ticket's fix. The local onex-check-node-migration-sync
pre-commit hook blocks ALL commits in this repo right now because the
vendored migration tree drifted from omnimarket's node_projection_context_roi
node (introduced by OMN-14535 / omnimarket#1743, not this branch). The
canonical fix already landed as its own PR (omnibase_infra#2290, OMN-14555)
but is not yet merged to dev, so this worktree (branched from pre-#2290 dev)
still has the drift locally. Vendoring the same file here only unblocks the
local commit gate for this unrelated change; it is a mechanical, deterministic
sync from the canonical omnimarket source (scripts/sync-node-migrations.sh,
no --check) and is expected to be a no-op once #2290 merges and this branch
rebases.

node-migration-sync is NOT a required GitHub status check (confirmed in
ROLLING_WORK_LEDGER 2026-07-13T08:3xZ), so this has no bearing on mergeability
-- it only satisfies the local pre-commit gate.
The onex:aislop_sweep skill's ONLY documented dispatch path (`onex skill
aislop_sweep`) was hard-failing with "Unknown node 'node_aislop_sweep'"
because omnimarket -- the co-installed provider of onex.nodes entry points
for market nodes -- was completely absent from the omnibase_infra venv
(not merely stale: the OMN-13829 -> OMN-14060 recurrence regressed one
step further, from "stale" to "gone").

Two compounding gaps let this go undetected:

1. check_omnimarket_drift() unconditionally failed open whenever
   installed_omnimarket_commit() returned None, even when a canonical
   $OMNI_HOME/omnimarket clone was present and reachable (a determinable,
   actionable state -- not the "can't reason about it" case the fail-open
   design was meant for). Reorder the checks so a present canonical clone
   plus an absent/non-VCS install now raises OmnimarketDriftError with a
   pointer to the repair command, instead of silently returning.

2. cli_skill.py's `--omni-home` option had no `envvar` binding, so even a
   correct guard never received a real value in normal usage -- callers
   never pass --omni-home explicitly, and $OMNI_HOME being exported in the
   shell had zero effect. Bind it to the OMNI_HOME environment variable so
   the guard is actually reachable.

Verified locally: co-installing omnimarket via
scripts/install-node-skill-package.sh --execute flips `onex skill
aislop_sweep --dry-run` from exit 1 ("Unknown node") to exit 0 with
repos_scanned=1 and 11 real findings (CRITICAL prohibited-pattern hits
included) -- the dispatch path and the aislop handler were never the
problem; the venv provisioning + guard blind spot were.

test_cli_skill.py gets an autouse fixture to keep command-wiring tests
hermetic against the now-live --omni-home envvar binding.
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8ff3b190-6795-4189-9f72-e85a0a0f51b4

📥 Commits

Reviewing files that changed from the base of the PR and between 79c97d5 and d8b5e4c.

📒 Files selected for processing (5)
  • docker/migrations/forward/nodes/node_projection_context_roi/002_add_factor_subset_hash_and_routing_source.sql
  • src/omnibase_infra/cli/cli_skill.py
  • src/omnibase_infra/cli/omnimarket_drift_guard.py
  • tests/unit/cli/test_cli_skill.py
  • tests/unit/cli/test_omnimarket_drift_guard.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jonah/omn-14531-aislop-sweep-dispatch

Comment @coderabbitai help to get the list of available commands.

@jonahgabriel
jonahgabriel merged commit 525efba into dev Jul 13, 2026
209 of 243 checks passed
@jonahgabriel
jonahgabriel deleted the jonah/omn-14531-aislop-sweep-dispatch branch July 13, 2026 16:37
jonahgabriel pushed a commit that referenced this pull request Jul 13, 2026
The `onex node`/`onex run` dispatch path had ZERO drift-guard wiring --
it raised a bare "Unknown node '<name>'" whenever the omnimarket
co-install was drifted or absent, with no pointer to the actual cause
or the repair command. This is the identical gap OMN-14531 fixed for
`onex skill` (cli_skill.py), flagged there as a known follow-up.

Mirrors that fix exactly, reusing the same
`omnimarket_drift_guard.check_omnimarket_drift()` helper (no
duplicated logic):

1. Added `--omni-home` bound to the `$OMNI_HOME` envvar.
2. Call `check_omnimarket_drift()` at the top of `run_node_by_name`,
   before `_resolve_packaged_contract`, converting
   `OmnimarketDriftError` to a `click.ClickException`.

Since `onex node` and `onex run` are both entry-point aliases for the
same `run_node_by_name` function (pyproject.toml
`[project.entry-points."onex.cli"]`), one wiring point fixes both.

RED -> GREEN evidence (dod_evidence): new
`test_drift_guard_fires_before_unknown_node_lookup` in
tests/unit/cli/test_cli_node.py fails against the pre-fix cli_node.py
(no --omni-home option, no guard call -- reports the old bare
"Unknown node" error) and passes against the fix (raises the loud
OmnimarketDriftError with repair command, before node resolution ever
runs).

Wiring the guard surfaced the same non-hermeticity gap OMN-14531 had
to guard against, but across three test files that all reach
run_node_by_name (test_cli_node.py, test_cli_node_receipt.py,
test_onex_run.py) rather than one -- added a shared
tests/unit/cli/conftest.py autouse fixture (neutralize + delenv
OMNI_HOME) instead of duplicating a file-local fixture three times.

Manually reproduced against the real `onex node`/`onex run` CLI on
this operator's drifted venv (omnimarket absent, canonical clone
present):

    $ uv run onex node definitely_not_a_real_node
    Error: omnimarket is NOT INSTALLED from git in this interpreter
    ..., but a canonical clone exists at $OMNI_HOME/omnimarket (HEAD
    48c03808155e). ... Repair with:
    scripts/install-node-skill-package.sh --execute ...
    exit 1

    $ uv run onex run definitely_not_a_real_node
    (identical output -- same underlying function via the "run" alias)

Local gates: `ruff format --check` / `ruff check` / `mypy` clean on
touched files; full `pre-commit run` clean; tests/unit/cli/ full
suite: 342 passed, 19 skipped (pre-existing omnimarket-not-in-CI-venv
skips, unrelated).

Stacked on OMN-14531 (#2291, not yet merged) -- this branch is built
on top of jonah/omn-14531-aislop-sweep-dispatch to reuse its
omnimarket_drift_guard.py fix rather than duplicating the reordering
logic. This PR's diff will resolve down to just the cli_node.py +
test changes once #2291 merges to dev.

OCC companion owed to Codex (per operating rules -- no self-authored
OCC in this lane).

Evidence-Ticket: OMN-14560
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant