Skip to content

feat(OMN-14051): reject non-hermetic check_value in contract-compliance validator - #4426

Merged
jonahgabriel merged 3 commits into
devfrom
jonah/omn-14051-reject-non-hermetic-check-value
Jul 19, 2026
Merged

jonahgabriel merged 3 commits into
devfrom
jonah/omn-14051-reject-non-hermetic-check-value

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Jul 19, 2026 •

Copy link
Copy Markdown
Contributor

OMN-14051 — OCC contract compliance: reject non-hermetic check_value at authoring time

Evidence-Ticket: OMN-14051
Evidence-Source: OCC#4427
Evidence-Commit: 489887a

Closes OMN-14051.

Problem

An OCC contract's dod_evidence[].checks[].check_value is executed verbatim by the contract-compliance runner in CI. When an author inlines a non-hermetic command (ssh / live docker / network egress / LAN-Tailscale IP), it can never pass in CI and BLOCKs the PR with a cryptic runtime error (sh: 1: ssh: not found, exit 127) even when the underlying work is real. Observed on OCC PR #3642 (OMN-14001): a dod-deploy-scope item inlined ssh jonah@100.109.203.94 "docker ps ..." → "3/4 PASS, 1 BLOCK". The failure surfaced late (in CI) instead of at validation time.

Change (net-negative-surface — NO new gate/workflow)

Folded a non-hermetic check_value guard into the existing validator (onex_change_control.scripts.contract_compliance_check):

  • _non_hermetic_reason(check) — inspects only check_type: command (the executed-shell surface) and returns an actionable rejection message when the command, in command position, invokes a remote-shell binary (ssh/scp/sftp/rsync/telnet), a live container/orchestration daemon (docker/podman/kubectl/…), network egress to a non-loopback host (curl/wget/nc to a non-localhost/127.* URL), or references a private/Tailscale-CGNAT IPv4 literal (192.168.*, 10.*, 172.16–31.*, 100.64–127.*).
  • Quote-aware via shlex (_command_binaries): the word "docker" inside a quoted grep pattern is not flagged — only real command-position invocations are; sudo/env FOO=bar wrappers are seen through.
  • The guard runs at the top of _run_single_check and returns a BLOCK; the existing OMN-14436 _demote path still applies, so a grandfathered (content-pinned legacy) contract is demoted BLOCK → WARN (reported, not wedged) while a new/touched contract is enforced from its first PR. This keeps the pre-existing corpus of docker exec runtime-proof checks (25 command-position instances) from wedging.
  • The rejection message names the offending check_value and steers the author to the canonical receipt-preservation pattern (drift/dod_receipts/<TICKET>/<evidence-id>/command.yaml with probe_command/probe_stdout/exit_code/status: PASS, then check_value: grep -q '^status: PASS$' "$CONTRACT_REPO_DIR/…/command.yaml").
  • Re-exported through the thin scripts/ci/run_contract_compliance_check.py wrapper.

Conservative by design (per ticket): known gap — a binary hidden inside a command substitution ($(ssh …)) is not yet detected; documented inline for a later expansion.

Acceptance criteria mapping

  • ✅ Non-hermetic (ssh/live-docker/LAN-IP) check_value rejected by the existing validator with an actionable message; no separate workflow added.
  • ✅ Canonical receipt-grep pattern and hermetic local-file checks still pass (_non_hermetic_reason returns None).
  • ✅ Focused unit test covers (a) ssh/live-docker/LAN-IP/scp/rsync/sudo-wrapped rejected; (b) receipt-grep + local-file + loopback-curl + quoted-docker-word accepted; plus new-ticket BLOCK vs grandfathered WARN integration.
  • ✅ Doc/comment block in the validator points authors to the receipt-preservation pattern.

dod_evidence

  • src/onex_change_control/scripts/contract_compliance_check.py — _non_hermetic_reason + _command_binaries + guard wired into _run_single_check.
  • tests/test_contract_compliance_check.py — 20 new tests. Local: uv run pytest tests/test_contract_compliance_check.py tests/test_dod_runner_ratchet.py tests/test_ci_script_exists.py -q → 66 passed.
  • Local gates: ruff format clean, ruff check clean, mypy --strict clean (module + wrapper + tests), pre-commit on changed files all Pass/Skip, pre-push mypy Pass.

OCC companion

OCC evidence companion is owed to Codex (net-new-file-only; machine-authored per OMN-14055 — implementer does not self-author their own companion). Not authored in this PR.

…ce validator

Fold a non-hermetic check_value guard into the existing contract-compliance
engine (onex_change_control.scripts.contract_compliance_check) so an ssh /
live-docker / network-egress / LAN-Tailscale-IP command check_value is rejected
up front with an actionable message steering the author to the receipt-grep
pattern, instead of surfacing as a late, cryptic CI BLOCK ('sh: 1: ssh: not
found', exit 127). No new gate/workflow (net-negative-surface); the guard reuses
the OMN-14436 demotion path so grandfathered legacy contracts are reported (WARN)
not wedged, while new/touched contracts are enforced.

Observed on OCC PR #3642 (OMN-14001).

- _non_hermetic_reason() + quote-aware _command_binaries() command-position scan
- guard called at top of _run_single_check(); _demote() still applies ratchet
- re-exported via the thin scripts/ci wrapper
- 20 new focused tests (reject ssh/docker/LAN-IP/scp/rsync/sudo-wrapped; accept
  receipt-grep/local-file/loopback-curl/quoted-docker-word; new-ticket BLOCK vs
  grandfathered WARN integration)
@coderabbitai

coderabbitai Bot commented Jul 19, 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: 31 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: 3b4ff83e-4e8e-4722-a027-61378f21f45a

📥 Commits

Reviewing files that changed from the base of the PR and between 489887a and 46f1c67.

📒 Files selected for processing (5)
  • contracts/OMN-14051.yaml
  • drift/dod_receipts/OMN-14051/dod-pr4426-head-contains-5120e3fa/command.yaml
  • scripts/ci/run_contract_compliance_check.py
  • src/onex_change_control/scripts/contract_compliance_check.py
  • tests/test_contract_compliance_check.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jonah/omn-14051-reject-non-hermetic-check-value

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

@jonahgabriel
jonahgabriel merged commit 3334088 into dev Jul 19, 2026
54 checks passed
@jonahgabriel
jonahgabriel deleted the jonah/omn-14051-reject-non-hermetic-check-value branch July 19, 2026 05:55
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