Skip to content

feat(OMN-9752): batch-validate all node contracts via model_validate() with CI gate - #1533

Merged
jonahgabriel merged 2 commits into
mainfrom
jonah/omn-9752-batch-validate-contracts
May 8, 2026
Merged

jonahgabriel merged 2 commits into
mainfrom
jonah/omn-9752-batch-validate-contracts

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented May 8, 2026 •

Copy link
Copy Markdown
Collaborator

Evidence

Evidence-Source: OCC#817
Evidence-Ticket: OMN-9752

Summary

  • Adds scripts/batch_validate_node_contracts.py that walks all nodes/*/contract.yaml files and runs ModelNodeTypeProbe.model_validate() on each, using the OMN-9746 choke-point introduced in Task 8
  • Adds 10 unit tests covering: valid contracts (all 4 node types), lowercase aliases, missing node_type, invalid node_type, bad YAML, mixed pass/fail counts, CLI argument handling, and a smoke test against all 138 real infra node contracts
  • Wires the script as a blocking step in the onex-validation CI job — any contract with an invalid node_type now blocks merge

Design decision

Uses ModelNodeTypeProbe.model_validate() directly rather than load_and_validate_contract_yaml(). The latter requires a handler_routing section which is legitimately absent in many COMPUTE/REDUCER contracts (they use FSM or operation_match patterns). OMN-9752's mandate is specifically node_type validation via model_validate().

Test plan

  • uv run pytest tests/unit/contracts/test_batch_validate_node_contracts.py -v — 10/10 passed
  • uv run pytest tests/ -m unit -q — 12548 passed (pre-existing test_kernel.py::TestIntegration failure confirmed on main before this PR)
  • pre-commit run --all-files — all hooks passed
  • uv run mypy scripts/batch_validate_node_contracts.py --ignore-missing-imports — no issues

Closes OMN-9752

Summary by CodeRabbit

  • Chores

    • CI now runs an automated batch validator for node contract files as part of the validation job.
    • Added a new CLI tool to discover and validate node contracts, with verbose and non-recursive options.
  • Tests

    • Added comprehensive tests covering valid/invalid contracts, malformed files, CLI error handling, verbose output, and validation of real-world contracts.

…) with CI gate

Wires ModelNodeTypeProbe.model_validate() over all nodes/*/contract.yaml
files as a required CI step. Every contract that fails node_type validation
or YAML parsing now blocks merge.

- scripts/batch_validate_node_contracts.py: CLI that walks all contract.yaml
  files and runs ModelNodeTypeProbe.model_validate() on each one, reporting
  per-contract pass/fail and exiting non-zero on any failure
- tests/unit/contracts/test_batch_validate_node_contracts.py: 10 unit tests
  covering valid/invalid node_type, lowercase aliases, missing field, bad YAML,
  mixed counts, CLI flags, and a smoke test against all real infra node contracts
- .github/workflows/ci.yml: adds "Batch-validate all node contracts" step to
  the onex-validation job as a blocking CI gate
@coderabbitai

coderabbitai Bot commented May 8, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR introduces a batch validation system for node contracts. It adds a new CLI script (scripts/batch_validate_node_contracts.py) that discovers and validates all contract.yaml files using ModelNodeTypeProbe.model_validate(), with comprehensive test coverage and a corresponding CI workflow step. The validator supports recursive discovery, verbose output, and reports aggregated pass/fail counts with detailed error messages.

Changes

Node Contract Validation Feature

Layer / File(s) Summary
Script Purpose & Setup
scripts/batch_validate_node_contracts.py
Module documentation describes batch validation behavior via ModelNodeTypeProbe. Imports and sys.path setup enable repo-root execution.
Contract Discovery
scripts/batch_validate_node_contracts.py
discover_contracts() gathers sorted contract.yaml paths using recursive rglob() or shallow glob() based on flags.
Single Contract Validation
scripts/batch_validate_node_contracts.py
validate_contract() safely parses YAML, enforces node_type presence/non-emptiness, validates via ModelNodeTypeProbe.model_validate(), and raises ValueError with detailed context on failure.
Batch Processing & Reporting
scripts/batch_validate_node_contracts.py
run_batch_validation() iterates contracts, counts passes/failures, accumulates (path, error_message) tuples, controls verbose output, and returns (passed, failed, failures).
CLI Interface & Entry Point
scripts/batch_validate_node_contracts.py
Argument parser handles --directory, --verbose, --non-recursive; missing directory exits 2, import errors exit 2, validation failures exit 1, success exits 0. Script entrypoint delegates to main().
Test Infrastructure & Helpers
tests/unit/contracts/test_batch_validate_node_contracts.py
Module docstring, imports, pytestmark, and helper functions _write_contract() and _run() for fixture creation and subprocess invocation.
Validation Test Coverage
tests/unit/contracts/test_batch_validate_node_contracts.py
TestBatchValidateAllPass verifies exit 0 and correct pass counts; TestBatchValidateFailures verifies exit 1 and aggregated failure counts; TestBatchValidateCLI verifies missing directory exit 2 and verbose output.
Real Contract Smoke Test
tests/unit/contracts/test_batch_validate_node_contracts.py
TestBatchValidateRealContracts runs the validator against actual src/omnibase_infra/nodes/*/contract.yaml files to confirm production contracts validate.
CI Integration
.github/workflows/ci.yml
onex-validation step invokes scripts/batch_validate_node_contracts.py --verbose after the existing check_published_events_consistency.py check with OMN-9752 banner.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A rabbit hops through YAML files so neat, 🐰
Validating contracts—each node type a treat!
From discovery to batch, the logic rings true,
Exit codes whisper what failures will do.
CI now checks every contract in sight—
One hoppy validator makes everything right! ✓

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding batch validation of node contracts via model_validate() with a CI gate, and references the ticket OMN-9752.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jonah/omn-9752-batch-validate-contracts

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

@jonahgabriel
jonahgabriel enabled auto-merge (squash) May 8, 2026 15:33

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
scripts/batch_validate_node_contracts.py (1)

6-9: ⚡ Quick win

Docstring still mentions load_and_validate_contract_yaml() despite direct model_validate() flow.

Lines 6-9 are stale and can mislead future maintenance/debugging.

Suggested edit
-Walks all nodes/*/contract.yaml files under a given directory and runs
-load_and_validate_contract_yaml() (the OMN-9746 choke-point that uses
-model_validate()) on each one. Any contract that fails node_type validation,
+Walks all nodes/*/contract.yaml files under a given directory and runs
+ModelNodeTypeProbe.model_validate() on each one. Any contract that fails node_type validation,
 YAML parsing, or structure checks causes a non-zero exit.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/batch_validate_node_contracts.py` around lines 6 - 9, Update the
stale docstring in the batch_validate_node_contracts module: remove the
reference to load_and_validate_contract_yaml() and instead describe the current
direct use of model_validate() (or whichever function the script now invokes)
and the exact behavior (walking nodes/*/contract.yaml, calling model_validate()
on each file, and exiting non-zero on validation/YAML/structure failures);
locate the module/function that contains the top-of-file docstring and replace
the outdated description with the concise, accurate flow mentioning
model_validate() and the failure exit behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/batch_validate_node_contracts.py`:
- Around line 153-156: The code currently only checks
Path(args.directory).exists(); update the validation for the CLI flag so that
when parsing args.directory you explicitly reject non-directory paths: after
creating directory = Path(args.directory) verify directory.exists() and
directory.is_dir(), and if not a directory print an error to stderr (including
the provided path) and return a non-zero exit code (e.g., 2). Locate the check
around the directory variable in scripts/batch_validate_node_contracts.py (the
block that prints "ERROR: Directory not found") and modify it to handle the
"exists but is a file" case by failing loudly instead of continuing.
- Around line 115-116: The except block that currently catches all exceptions
and appends (path, str(exc)) is misclassifying ImportError from
_validate_contract_node_type() as a contract failure; update the handler so it
re-raises ImportError (and other fatal exceptions if desired) instead of
recording them: inside the except Exception as exc around the call to
_validate_contract_node_type(), check isinstance(exc, ImportError) and raise it
(or simply re-raise for ImportError) before appending to failures so ImportError
propagates and triggers the runtime error exit path.

---

Nitpick comments:
In `@scripts/batch_validate_node_contracts.py`:
- Around line 6-9: Update the stale docstring in the
batch_validate_node_contracts module: remove the reference to
load_and_validate_contract_yaml() and instead describe the current direct use of
model_validate() (or whichever function the script now invokes) and the exact
behavior (walking nodes/*/contract.yaml, calling model_validate() on each file,
and exiting non-zero on validation/YAML/structure failures); locate the
module/function that contains the top-of-file docstring and replace the outdated
description with the concise, accurate flow mentioning model_validate() and the
failure exit behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 53d316cb-4d88-4e25-85e5-2fb4baeaaf65

📥 Commits

Reviewing files that changed from the base of the PR and between af2124b and 29d1240.

📒 Files selected for processing (3)
  • .github/workflows/ci.yml
  • scripts/batch_validate_node_contracts.py
  • tests/unit/contracts/test_batch_validate_node_contracts.py

Comment thread scripts/batch_validate_node_contracts.py
Comment thread scripts/batch_validate_node_contracts.py
@jonahgabriel
jonahgabriel merged commit fafb376 into main May 8, 2026
64 of 66 checks passed
@jonahgabriel
jonahgabriel deleted the jonah/omn-9752-batch-validate-contracts branch May 8, 2026 19:36
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