Skip to content

fix(OMN-15430): shlex-aware shape-guard tokenization - #1958

Merged
jonahgabriel merged 2 commits into
devfrom
jonah/omn-15430-shlex-shape-guard
Jul 29, 2026
Merged

jonahgabriel merged 2 commits into
devfrom
jonah/omn-15430-shlex-shape-guard

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes _invalid_check_value_reason in src/omnimarket/nodes/node_dod_verify/services/evidence_collector.py (OMN-15430). The OMN-15382 pre-execution "prose vs command" shape guard tokenized check_value with a naive cmd_str.strip().split() after stripping a leading VAR= token. On the OMN-15170 sigpipe-safe shape (OMN-15411):

body="$(gh api repos/.../contents/....py?ref=... --jq .content | base64 -d)" && printf '%s' "$body" | grep -qF '<marker>'

the naive split breaks apart inside the quoted $(...) command substitution and inspects an inner word (api) as the "first token", producing a false INVALID_CHECK_VALUE_NOT_A_COMMAND on a check that runs correctly (bash -o pipefail -c '<same string>' exits 0). This was the single blocker keeping dod_verify OMN-15170 from a clean table.

Fix

  • Tokenize with shlex.split(cmd_str, posix=True) — quote-respecting, so the whole quoted substitution stays one token.
  • Strip leading VAR=VAL assignment tokens and leading shell control operators (&&, ||, ;, ;;, |, &) before resolving the first real command token. The OMN-15170 shape's first shlex token is the whole body=$(...) assignment; the next is &&; only the token after that (printf) is the real command.
  • On a genuine shlex parse failure (unbalanced quotes), the guard stays fail-closed INVALID — a check_value bash itself cannot parse is genuinely invalid, never silently passed through.

RED-first proof

Checked out the pre-fix source at origin/dev HEAD (git show HEAD:.../evidence_collector.py), exec'd the naive-split guard in isolation, and confirmed it rejects the exact OMN-15170 check_value with first token 'api' is not a resolvable executable.... Post-fix, the same string resolves cleanly (_invalid_check_value_reason returns None).

Non-regression

  • Bare prose (Recorded product receipt: ...) still INVALID
  • First-token-ends-with-colon still INVALID
  • ./script.sh + declared cwd: (the round-1 OMN-15382 fix) still resolves
  • Genuinely unparseable string (unbalanced quote) still INVALID
  • Leading VAR=VAL assignment stripping unchanged
  • Leading-operator-only command with no real command token stays fail-closed INVALID

Test plan

  • New tests/unit/nodes/node_dod_verify/test_omn_15430_shlex_shape_guard.py (10 tests) covering the OMN-15170 shape acceptance + all non-regression cases above
  • Full tests/unit/nodes/node_dod_verify/ suite: 267/267 passed
  • ruff format --check / ruff check clean on touched files
  • mypy --strict clean on evidence_collector.py
  • pre-commit run clean on touched files (run on .200 with OMNIBASE_INFRA_PATH set for topic-naming-lint)

Cites OMN-15430. Related: OMN-15382 (guard origin), OMN-15411 (the OMN-15170 sigpipe-safe rewrite this unblocks), OMN-15170 (the blocked flip).

Evidence-Source: OCC#5516
Evidence-Ticket: OMN-15430

_invalid_check_value_reason (the OMN-15382 pre-execution prose guard)
tokenized check_value with a naive cmd_str.strip().split() after
stripping a leading VAR= token. On the OMN-15170 sigpipe-safe shape
(OMN-15411) -- body="$(gh api ... | base64 -d)" && printf '%s' "$body" |
grep -qF '<marker>' -- the naive split breaks apart inside the quoted
command substitution and inspects an inner word (api) as the first
token, producing a false INVALID_CHECK_VALUE_NOT_A_COMMAND on a check
that runs correctly under bash -o pipefail -c.

Tokenizes with shlex.split(cmd_str, posix=True) instead: quote-respecting,
so the whole quoted substitution stays one token. Strips leading VAR=VAL
assignment tokens AND leading shell control operators (&&, ||, ;, |, ...)
before resolving the first real command token -- the OMN-15170 shape's
first shlex token is the whole body=$(...) assignment, the next is &&,
and only the token after that (printf) is the real command. On a genuine
shlex parse failure (unbalanced quotes) the guard stays fail-closed
INVALID -- a check_value bash itself cannot parse is genuinely invalid.

RED-first proof: the pre-fix naive-split guard (checked out from origin/dev
HEAD before this diff) rejects the exact OMN-15170 check_value with
first token 'api' is not a resolvable executable -- confirmed via
git show HEAD:.../evidence_collector.py exec'd in isolation. Post-fix the
same string resolves cleanly (no INVALID reason).

Non-regression: bare prose (Recorded product receipt: ...) still INVALID;
first-token-ends-with-colon still INVALID; ./script.sh + declared cwd
(the round-1 OMN-15382 fix) still resolves; a genuinely unparseable
string (unbalanced quote) still INVALID; leading VAR=VAL assignment
stripping unchanged; a leading-operator-only command with no real
command token stays fail-closed INVALID.

267/267 node_dod_verify tests pass, ruff format/check clean, mypy --strict
clean, pre-commit clean (OMNIBASE_INFRA_PATH set for topic-naming-lint).

Closes OMN-15430.
@coderabbitai

coderabbitai Bot commented Jul 29, 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: 59 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: 7cf3330f-b469-489a-9237-fb219e8f2745

📥 Commits

Reviewing files that changed from the base of the PR and between 691f2de and 26efdbb.

📒 Files selected for processing (2)
  • src/omnimarket/nodes/node_dod_verify/services/evidence_collector.py
  • tests/unit/nodes/node_dod_verify/test_omn_15430_shlex_shape_guard.py

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

@github-actions

Copy link
Copy Markdown

✅ Hostile Reviewer — PASSED

Blocking findings (critical/error): 0
Total findings: 0
Models succeeded: qwen3-review,qwen3-review-b


Gate semantics

Verdict Meaning Blocks merge?
passed >=2 models succeeded, no critical/error findings No
blocked CRITICAL or ERROR findings found Yes
degraded Fewer than 2 models succeeded (infra unavailable/timeout) Yes (OMN-15110)

Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8524)

@github-actions

Copy link
Copy Markdown

⚠️ Architectural Review — WARNINGS

Errors: 0
Warnings: 1

What this checks

Rule Description
ARCH-TOPIC-001 No hardcoded Kafka topic strings in handler code
ARCH-DI-001 No event_bus=None bypass
ARCH-DI-002 No direct Handler instantiation outside workflow_runner/adapters
ARCH-DI-003 No reinvented DI containers
ARCH-TOPIC-002 contract.yaml topics follow `onex.{cmd

ARCH-DI-002: Direct Handler instantiation (warning)\n\n```\nsrc/omnimarket/nodes/node_dod_verify/services/evidence_collector.py:1196: output = HandlerDodEvidenceGithubEffect().handle(command)

src/omnimarket/nodes/node_dod_verify/services/evidence_collector.py:1232: output = HandlerDodEvidenceGithubEffect().handle(command)
src/omnimarket/nodes/node_dod_verify/services/evidence_collector.py:1692: output = HandlerDodEvidenceGithubEffect().handle(command)
src/omnimarket/nodes/node_dod_verify/services/evidence_collector.py:1718: output = HandlerDodEvidenceGithubEffect().handle(command)\n```\n\nHandler classes should be wired only in workflow_runner.py or adapter modules. Direct instantiation elsewhere bypasses the contract system.\n\n

Static architectural lint — no model inference (OMN-14176).

…ure literal

The new test embeds the real OMN-15170/OMN-15411 check_value string
verbatim (required for a faithful shape-guard regression proof), which
contains the jonahgabriel/steel_onslaught path the Leaked Literals Gate
(OMN-10580) flags. Adds a ticketed onex-allow-test-fixture annotation on
the same line, per the gate's documented allowlist mechanism.
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Jul 29, 2026
jonahgabriel added a commit to OmniNode-ai/onex_change_control that referenced this pull request Jul 29, 2026
…5516)

* evidence: OCC companion pass 1 for OmniNode-ai/omnimarket#1958

* evidence: OCC companion self-bind for #5516

* fix(OMN-15430): format OCC companion receipts

---------

Co-authored-by: node-occ-companion-effect <occ-companion-effect@omninode.ai>
Co-authored-by: Jonah Gray <jonah@omninode.ai>
@jonahgabriel
jonahgabriel merged commit 62ae15a into dev Jul 29, 2026
118 of 125 checks passed
@jonahgabriel
jonahgabriel deleted the jonah/omn-15430-shlex-shape-guard branch July 29, 2026 23:05
jonahgabriel added a commit to OmniNode-ai/onex_change_control that referenced this pull request Jul 30, 2026
…rsession (#5543)

* fix(OMN-15430): literal-pin the deploy-scope DoD via append-only supersession

contracts/OMN-15430.yaml dod-deploy-assessment carried bare runner-substituted
PR_NUMBER/REPO placeholder tokens under an id embedding no pr-<N> segment. The
id does not match node_dod_verify _EVIDENCE_ID_BINDING_RE, so
_repo_and_pr_from_evidence_id yields no binding, _lookup_pr_for_ticket has no
repo to scope a PR search to, and the item hard-REDs at
_resolve_command_placeholders with PR_LOOKUP_FAILED before the command is ever
shelled out. Reproduced on three independent dod_verify runs; it is the single
red blocking the OMN-15430 flip.

Supersedes that entry (append-only, supersedes_dod_evidence idiom per
OMN-14875/OMN-15382, precedent OCC#5496/#5523) with
dod-deploy-assessment-pr-1958-literal-pin: same deploy-scope path regex,
literally pinned to OmniNode-ai/omnimarket#1958 with a literal --repo and no
runner-substituted token, SIGPIPE-safe (producer drained into a shell variable
before any grep reads), shlex-parseable, fail-closed on producer failure.

Proven by execution: GREEN 3/3 under bash -o pipefail -c, 1/1 under sh -c; RED
under three mutations (absent anchor path, repointed at OCC#5516, nonexistent
repo).

* evidence(OMN-15430): PASS receipts + self-bind for the literal-pinned deploy DoD

Adds the OCC self-bind entry occ-self-bind-pr-5543 (the occ-preflight
eligibility gate requires a PASS receipt binding OMN-15430 to this PR) and
executed-probe PASS receipts for it and for
dod-deploy-assessment-pr-1958-literal-pin.

Both receipts were minted by executing the declared check_value live on the
gate host under bash -o pipefail -c, not hand-authored: exit 0 for both.
contract_entry_sha256 bindings verified against
compute_contract_entry_sha256() post-yamlfmt (unchanged across the append, per
OMN-13888/OMN-14411).
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