Skip to content

feat(OMN-9143): grep guard + CI gate blocking polymorphic-agent in enforcement paths - #1795

Merged
jonahgabriel merged 2 commits into
devfrom
jonah/omn-9143-grep-guard-no-polymorphic-agent
Jun 23, 2026
Merged

jonahgabriel merged 2 commits into
devfrom
jonah/omn-9143-grep-guard-no-polymorphic-agent

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Jun 23, 2026 •

Copy link
Copy Markdown
Contributor

Evidence-Source: 02fde8dcb5426fc6ab0083d0a0c48f581be01080
Evidence-Ticket: OMN-9143

OMN-9143 — [Pattern G] Scrub polymorphic-agent from omniclaude enforcement paths

Closes OMN-9143.

Context / verified state

The polymorphic-agent dispatch target was already scrubbed from the omniclaude hook enforcement surface before this PR. Verified against origin/dev:

$ git grep -nI 'polymorphic-agent\|polymorphic_agent' origin/dev -- 'plugins/onex/hooks/**'
(no matches)

The enforcement hooks now enforce onex:-prefixed subagents (with general-purpose allowed unprefixed) — e.g. plugins/onex/hooks/scripts/pre_tool_use_poly_enforcer.sh. What was missing — and what this PR lands — is the regression guard half of the ticket (the enforcement-not-detection requirement, CLAUDE.md Rule #5).

What this PR adds

  • plugins/onex/hooks/scripts/grep_guard_no_polymorphic_agent.sh — fail-closed grep guard over the enforcement surface (plugins/onex/hooks/{scripts,lib} + hooks.json). Full-tree mode (CI) and pre-commit file-mode (scoped to the enforcement surface). Self-allowlisted so its own header doesn't trip it.
  • tests/unit/hooks/test_no_polymorphic_agent_references.py — asserts 0 offenders in enforcement paths, asserts the guard agrees (exit 0), and a negative test asserting the guard fails closed (exit 1) on an injected enforcement-path offender.
  • .pre-commit-config.yaml — no-polymorphic-agent hook (blocking), scoped to enforcement-path files.
  • .github/workflows/ci.yml — no-polymorphic-agent job wired into the quality-gate aggregator (needs + aggregation loop). The job is a pure bash grep guard (no uv/python).

Scope decisions (documented per CLAUDE.md Rule #2)

  • Out of scope, intentionally not matched: scripts/observability/routing_metrics.sql (historical transformation-rate metrics over past event rows) and tests/lib/core/* routing-fallback tests (assert the documented low-confidence fallback). These legitimately reference the retired name and are not enforcement code paths. The ticket scopes to "enforcement-critical code paths."
  • pre_tool_use_poly_enforcer.sh not renamed. The file is already reference-free; the rename is cosmetic and would churn the deployed hooks.json wiring for no enforcement benefit. The ticket's primary intent — no polymorphic-agent in enforcement paths + a regression guard — is fully achieved.
  • Docs untouched (CHANGELOG / docs/architecture/* / ADR / getting-started / reference), per the ticket DoD.
  • OMNICLAUDE_HOOKS_DISABLE kill-switch (OMN-9140) preserved — not touched.
  • Branch-protection required-checks update (add no-polymorphic-agent to main protection): noted as a repo-settings action; the CI job is wired into the API-stable Quality Gate aggregator, which is already a required check, so the guard blocks merge today via that aggregator.

dod_evidence

- id: dod-001-guard-passes-clean-tree
  description: grep guard exits 0 on the current enforcement surface
  source: command
  result: |
    $ bash plugins/onex/hooks/scripts/grep_guard_no_polymorphic_agent.sh; echo $?
    OK: no 'polymorphic-agent' references in enforcement paths
    0

- id: dod-002-guard-fails-on-offender
  description: grep guard exits 1 on an injected enforcement-path offender
  source: command
  result: |
    (injected plugins/onex/hooks/scripts/_tmp_offender.sh containing 'polymorphic-agent')
    FORBIDDEN: legacy 'polymorphic-agent' dispatch target in enforcement path: ...
    exit=1

- id: dod-003-pytest-passes
  description: regression test passes (0 offenders + guard agreement + negative test)
  source: command
  result: |
    $ uv run pytest tests/unit/hooks/test_no_polymorphic_agent_references.py -q
    4 passed

- id: dod-004-ci-job-wired
  description: no-polymorphic-agent CI job present and wired into Quality Gate needs + aggregation loop
  source: generated
  checks:
    - check_type: command
      check_value: "grep -q 'no-polymorphic-agent:' .github/workflows/ci.yml && grep -q '      - no-polymorphic-agent' .github/workflows/ci.yml"

- id: dod-005-precommit-passes
  description: pre-commit (incl. the new no-polymorphic-agent hook) passes on all changed files
  source: command
  result: "pre-commit run --files <4 changed files> -> all hooks Passed"

Notes

  • Pre-existing, environment-sensitive test tests/unit/hooks/test_mode_resolution.py::test_auto_detect_external_project fails locally inside the worktree (mode resolver returns full because the worktree path is classified as an omninode repo; the test hardcodes lite for an external-project layout). It is byte-identical to origin/dev (git diff origin/dev -- tests/unit/hooks/test_mode_resolution.py is empty) and unrelated to this changeset; it passes in CI's clean external-project runner.

Summary by CodeRabbit

  • Tests

    • Added regression test module for enforcement surface validation.
  • Chores

    • Enhanced CI quality-gate workflow with additional validation job.
    • Added pre-commit hook for enforcement path compliance checks.

Receipt Gate / OCC pairing

Paired OCC evidence PR: OmniNode-ai/onex_change_control#2962 (contract contracts/OMN-9143.yaml + DoD receipts binding to this PR head, commit ea01ddc36). MERGED to onex_change_control@main as merge-commit 02fde8dcb5426fc6ab0083d0a0c48f581be01080. Evidence-Source above is repointed to that OCC merge-commit SHA (per the OCC-squash-invalidates-Evidence-Source rule — the pre-squash branch SHA is not used). The verify / Run Receipt-Gate "Resolve Evidence-Source" step now resolves against the durable OCC merge commit that contains contracts/OMN-9143.yaml and the OMN-9143 DoD receipts.

…forcement paths

The legacy 'polymorphic-agent' dispatch target was already scrubbed from the
omniclaude hook enforcement surface (now 'onex:'-prefixed subagents). This lands
the regression guard half of OMN-9143 (Pattern G) so it cannot reappear:

- plugins/onex/hooks/scripts/grep_guard_no_polymorphic_agent.sh: fail-closed
  grep guard over plugins/onex/hooks/{scripts,lib} + hooks.json. Full-tree mode
  and pre-commit file-mode (scoped to the enforcement surface).
- tests/unit/hooks/test_no_polymorphic_agent_references.py: 0-offender assertion
  + guard agreement + injected-offender negative test.
- .pre-commit-config.yaml: no-polymorphic-agent hook (blocking).
- .github/workflows/ci.yml: no-polymorphic-agent job wired into Quality Gate
  needs + aggregation loop.

Scope: enforcement paths only. Historical observability SQL
(scripts/observability/routing_metrics.sql) and routing-fallback tests
(tests/lib/core/*) legitimately reference the retired name and are out of scope.
Docs untouched per ticket. pre_tool_use_poly_enforcer.sh not renamed (already
reference-free; rename is cosmetic and would churn deployed hooks.json wiring).
@coderabbitai

coderabbitai Bot commented Jun 23, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds OMN-9143 enforcement: a new Bash grep guard script blocks reintroduction of the retired polymorphic-agent dispatch target in plugins/onex/hooks/. The guard is wired as a CI job integrated into the quality gate, a pre-commit hook, and a Python regression test suite.

Changes

polymorphic-agent Regression Guard

Layer / File(s) Summary
Bash grep guard script
plugins/onex/hooks/scripts/grep_guard_no_polymorphic_agent.sh
New script with strict Bash options, forbidden token regex (polymorphic[-_]agent), self-allowlist logic, is_allowlisted/scan_files helpers, and a main function supporting both full-tree and pre-commit (filtered) scan modes; exits 1 on any match, 0 when clean.
CI job and pre-commit hook wiring
.github/workflows/ci.yml, .pre-commit-config.yaml
New no-polymorphic-agent CI job runs the guard script and is added to the quality-gate needs list and its result-aggregation loop. New pre-commit hook runs the same script scoped to plugins/onex/hooks/(scripts|lib)/ and hooks.json.
Python unit tests
tests/unit/hooks/test_no_polymorphic_agent_references.py
Test module defines enforcement roots, collects files, scans for the forbidden token (skipping the guard script itself), asserts the guard exits 0 on the live tree, and asserts it exits 1 when a temporary injected offender is placed in an enforcement root.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 A token once roamed through the hooks with great flair,
polymorphic-agent — but it shouldn't be there!
So we wrote a grep guard with a firm exit one,
Hooked it to CI so the mischief is done.
Now the rabbit sleeps soundly, no legacy to fear! 🌙

🚥 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 and specifically describes the main changes: introducing a grep guard and CI gate to block polymorphic-agent in enforcement paths, directly matching the PR's core purpose and all file changes.
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-9143-grep-guard-no-polymorphic-agent

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

@github-actions
github-actions Bot enabled auto-merge June 23, 2026 13:40
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Hostile Reviewer — DEGRADED (informational)

Blocking findings (critical/error): 0
Total findings: 0
Models succeeded: none

Note: All reviewer models failed or were unavailable. Degraded results are informational during the pilot phase (OMN-8524) and do not block merge. Error: cli_review exited non-zero (all models failed or binary error)


Gate semantics (pilot phase)

Verdict Meaning Blocks merge?
passed No critical/error findings No
blocked CRITICAL or ERROR findings found Yes
degraded All models unavailable (infra) No (pilot)

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

@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.

🧹 Nitpick comments (1)
tests/unit/hooks/test_no_polymorphic_agent_references.py (1)

103-120: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider removing unused tmp_path fixture parameter.

The test declares tmp_path: Path but intentionally creates the offender file directly in the enforcement directory (ENFORCEMENT_ROOTS[0]) rather than using the temp directory. While the try/finally cleanup is correct, the unused fixture parameter may confuse readers.

♻️ Proposed cleanup
-def test_grep_guard_detects_injected_offender(tmp_path: Path) -> None:
+def test_grep_guard_detects_injected_offender() -> None:
     """The grep guard must fail closed on an injected enforcement-path offender."""
🤖 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 `@tests/unit/hooks/test_no_polymorphic_agent_references.py` around lines 103 -
120, Remove the unused `tmp_path: Path` parameter from the function signature of
`test_grep_guard_detects_injected_offender`. This parameter is declared but
never used in the test body since the test intentionally creates the offender
file directly in `ENFORCEMENT_ROOTS[0]` rather than using a temporary directory.
Simply remove it from the function definition to avoid confusing readers about
the test's actual 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.

Nitpick comments:
In `@tests/unit/hooks/test_no_polymorphic_agent_references.py`:
- Around line 103-120: Remove the unused `tmp_path: Path` parameter from the
function signature of `test_grep_guard_detects_injected_offender`. This
parameter is declared but never used in the test body since the test
intentionally creates the offender file directly in `ENFORCEMENT_ROOTS[0]`
rather than using a temporary directory. Simply remove it from the function
definition to avoid confusing readers about the test's actual behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d414c49a-7185-4b6c-b28e-92410282ae36

📥 Commits

Reviewing files that changed from the base of the PR and between ed35186 and ea01ddc.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • .pre-commit-config.yaml
  • plugins/onex/hooks/scripts/grep_guard_no_polymorphic_agent.sh
  • tests/unit/hooks/test_no_polymorphic_agent_references.py

@github-actions
github-actions Bot added this pull request to the merge queue Jun 23, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks Jun 23, 2026
@github-actions
github-actions Bot enabled auto-merge June 23, 2026 15:56
@github-actions
github-actions Bot added this pull request to the merge queue Jun 23, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks Jun 23, 2026
@jonahgabriel
jonahgabriel added this pull request to the merge queue Jun 23, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 23, 2026
@jonahgabriel
jonahgabriel added this pull request to the merge queue Jun 23, 2026
Merged via the queue into dev with commit 0959517 Jun 23, 2026
110 checks passed
@jonahgabriel
jonahgabriel deleted the jonah/omn-9143-grep-guard-no-polymorphic-agent branch June 23, 2026 18:20
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