Skip to content

feat(OMN-15731): pilot label-gated CI (ci:ready) on onex_change_control - #6216

Merged
jonahgabriel merged 1 commit into
devfrom
jonah/omn-15731-label-gated-ci-pilot-occ
Aug 8, 2026
Merged

jonahgabriel merged 1 commit into
devfrom
jonah/omn-15731-label-gated-ci-pilot-occ

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Aug 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Operator-authorized scoped pilot (2026-08-08 go-ahead recorded on OMN-15731): the pre-commit job -- the one CI job that runs unconditionally on every dev-targeting PR today -- is gated behind the ci:ready label. Unlabeled dev-targeting PRs remain unmergeable: CI Summary (the sole required status check on dev) reports FAILURE via a new explicit strict block, never green-by-skip.

Ticket: OMN-15731 (design doc + pilot-authorization addendum). Scope: omnibase_infra + onex_change_control only — this PR is the OCC half. No other repo touched.

Why pre-commit, not test (the ticket's literal original ask)

Live-reading ci.yml surfaced a shape the design doc didn't anticipate: test and type-check already skip entirely on dev-targeting PRs today (if: ... && (github.event_name != 'pull_request' || github.base_ref != 'dev') — smart-test-select was meant to replace them there and is declared but never consumed/wired). Consequences:

  • Gating test/type-check further would add zero incremental runner-cost savings on the everyday dev-PR path — they already don't run there.
  • Gating either for main-targeting PRs would weaken the unconditional full-suite guarantee root CLAUDE.md rule M1: Implement Pydantic schema models v1 (Day Close + Ticket Contract) #4 requires at the dev→main promotion boundary — a real regression, not a pilot win.

pre-commit (if: always() before this PR) is the job that actually costs CI time on every single dev PR, so it is the one gated — and only for dev-targeting PRs. push/merge_group/main-or-hotfix-targeting PRs are untouched (always() still holds for them), so the main promotion boundary — where Pre-commit is a REQUIRED branch-protection context — keeps running it unconditionally exactly as before.

What changed and why it's fail-closed

  • ci.yml pre-commit job: if: always() && (github.event_name != 'pull_request' || github.base_ref != 'dev' || contains(github.event.pull_request.labels.*.name, 'ci:ready')).
  • ci-summary: new explicit strict success-only block for pre-commit (mirrors the existing OMN-15484/OMN-15669 pattern used for merge-hold-gate/contract-shape-v1) — skipped/cancelled/failure ALL block. Without this, the generic contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') rollup treats a label-skip as pass — the exact AC(b) trap named on OMN-15731.
  • ci.yml pull_request.types extended with labeled/unlabeled/ready_for_review so applying/removing the label retriggers evaluation without a new push.
  • .github/required-checks.yaml: the "Pre-commit" gate's skip_semantics flipped never → neutral_ok with a rationale citing this ticket — satisfies required-check-skip-guard's (OMN-15241/OMN-14865) own sanctioned escape hatch (the hook flagged both vector-2-ungated-job-if and vector-5-ungated-needs-cascade on first attempt — this is the fix, not a bypass). The row's branch: main scope is unchanged: main-targeting PRs are unaffected by the label gate; dev enforcement moves to the new ci-summary strict block.
  • gh label create ci:ready (idempotent, already applied to the repo).

Operator workflow

  1. Open a PR into dev as normal. Cheap checks (zone-filter, most standalone gates) run immediately; pre-commit (and hence CI Summary) reads red/pending until labeled.
  2. Apply ci:ready to trigger the full pre-commit hook suite.
  3. CI Summary reports its normal pass/fail verdict once the labeled run completes.
  4. PRs targeting main (dev→main promotion) are unaffected by this pilot — pre-commit always runs there, unconditionally, exactly as before.

Testing

  • uv run pytest tests/unit/scripts/test_label_gated_ci_pilot_omn15731.py -q → 10 passed. Renders and executes the real ci-summary shell block (same technique as test_merge_hold_gate_wiring_omn15484.py): proves success passes, skipped/failure/cancelled all fail closed, removing the strict check restores the pre-pilot bypass (RED-before control), the failure message names both the job and OMN-15731, and a control asserting test/type-check are untouched by this pilot.
  • uv run mypy tests/unit/scripts/test_label_gated_ci_pilot_omn15731.py --strict → clean.
  • bash .pre-commit-hooks/reject-required-check-skip-vector.sh → PASS: no required-check skip vectors found. (both vectors it flagged pre-fix are now resolved via the required-checks.yaml change above).
  • Full local pre-commit run --all-files via the commit hook chain — all hooks passed.

Acceptance criteria mapping (OMN-15731)

  • (a) zero runner minutes for pre-commit on unlabeled dev-PR push — job-level if: means it is never scheduled; live runner-telemetry verification is a follow-up once this PR is live.
  • (b) unlabeled PR never green-by-skip — see the fail-closed proof above; the new ci-summary strict block is the load-bearing mechanism, proven by executing the real script against all four possible job results.
  • (c) labeling fires the full pre-commit run and an all-green labeled PR merges normally — unchanged required-check set, if: evaluates true once labeled.
  • (d) required-check-skip-guard stays green — verified locally, see Testing above.
  • (e) mechanized ci:hold→ci:ready label flipping — not in scope for this PR (design item 4; needs pull-requests:write wiring, flagged as an open risk on the design comment).

Risks / follow-ups (carried from the design + this PR's own findings)

  • test/type-check already skip on dev PRs for an unrelated, pre-existing reason (smart-test-select declared but unwired) — this PR does not fix that gap; it is out of scope for OMN-15731 and flagged here for visibility, not silently absorbed into this pilot's claims.
  • AC(a)/AC(e) need live verification once this merges (runner telemetry; a real mechanized label flip) — not achievable pre-merge from a worktree.

Evidence-Ticket: OMN-15731
Evidence-Source: OCC#6219

@coderabbitai

coderabbitai Bot commented Aug 8, 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: 52 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: 78e6599f-3e86-4a76-a426-71b4e311d3e1

📥 Commits

Reviewing files that changed from the base of the PR and between 68b266b and cee8f2c.

📒 Files selected for processing (7)
  • .github/required-checks.yaml
  • .github/workflows/ci.yml
  • contracts/OMN-15731.yaml
  • drift/dod_receipts/OMN-15731/dod-OmniNode-ai-onex_change_control-pr-6216/command.yaml
  • drift/dod_receipts/OMN-15731/dod-omn15731-fail-closed-proof-run-31277189469/command.yaml
  • drift/dod_receipts/OMN-15731/occ-self-bind-pr-6216/command.yaml
  • tests/unit/scripts/test_label_gated_ci_pilot_omn15731.py

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

Operator-authorized scoped pilot (2026-08-08): the `pre-commit` job -- the
one CI job that runs unconditionally on every dev-targeting PR today -- is
gated behind the `ci:ready` label. Unlabeled dev PRs remain unmergeable:
the sole required context `CI Summary` reports FAILURE via a new explicit
strict block, never green-by-skip.

Rebased onto dev to pick up #6214's merged OMN-15731 contract (occ-preflight
was BLOCKing with missing_contract -- this branch predated that merge and
carried no contracts/OMN-15731.yaml at all). Adds three net-new dod_evidence
items + PASS receipts, independently binding THIS PR (#6216):

- dod-omn15731-fail-closed-proof-run-31277189469: live gh-api read of two
  job conclusions from CI run 31277189469 (this PR's own original unlabeled
  commit) -- Pre-commit=skipped, CI Summary=failure -- the pilot's AC(b)
  fail-closed proof read from the GitHub Actions run record.
- dod-OmniNode-ai-onex_change_control-pr-6216: content-pinned probe against
  the test file this PR adds.
- occ-self-bind-pr-6216: #6214's companion bound to a different PR
  (omnibase_infra#2693) and #6219's companion is CONFLICTING with dev
  (predates the #6214 merge), so neither supplies a receipt whose pr_number
  binds to #6216 itself; this self-bind does.

Evidence-Ticket: OMN-15731
@jonahgabriel
jonahgabriel force-pushed the jonah/omn-15731-label-gated-ci-pilot-occ branch from 3215d72 to cee8f2c Compare August 8, 2026 21:25
@jonahgabriel jonahgabriel added the ci:ready Full CI runs on this PR (OMN-15731 label-gated CI pilot) label Aug 8, 2026
@jonahgabriel
jonahgabriel enabled auto-merge (squash) August 8, 2026 21:43
@jonahgabriel
jonahgabriel merged commit a1bab1a into dev Aug 8, 2026
100 of 101 checks passed
@jonahgabriel
jonahgabriel deleted the jonah/omn-15731-label-gated-ci-pilot-occ branch August 8, 2026 21:43
jonahgabriel added a commit that referenced this pull request Aug 8, 2026
…l-gated CI pilot

#6216 (OMN-15731 label-gated ci:ready pilot on pre-commit) landed on dev
between this PR's original push and now, touching the same ci-summary
strict-block region of ci.yml as this fix's test/type-check strict block.
Both blocks are independent, additive fail-closed mechanisms for different
jobs — kept both. Also corrected a stale comment on the pre-commit job's
`if:` (added by #6216) that claimed test/type-check "already skip on PRs
targeting dev by design" — that claim was exactly the bug this ticket
fixes; test/type-check no longer carry that carve-out.

Verified non-vacuous post-merge: all 23 tests across both OMN-15731 test
files (this PR's + #6216's) pass against the merged ci.yml. Full local
suite: 5938 passed / 47 skipped / 0 failed. mypy src/ tests/: clean,
398 files.
jonahgabriel added a commit that referenced this pull request Aug 13, 2026
Same class as OMN-15755 (test/type-check): schema-purity,
no-localhost-fallbacks, imperative-contract-guard,
context-integrity-contracts, migration-conflicts, migration-inventory,
kafka-boundary-parity, cross-repo-null-contract, seam-contract-coverage,
ai-slop-check, no-new-os-environ, and url-authority-gate all carried an
undocumented `github.base_ref != 'dev'` clause on top of their legitimate
docs_only (OMN-14098) fast-lane guard. Since dev is this repo's default
branch, all 12 silently skipped on essentially every ordinary dev PR.
9 of the 12 sat in ci-summary's needs guarded only by the generic
failure/cancelled rollup (which doesn't catch skipped); the other 3
(ai-slop-check, no-new-os-environ, url-authority-gate) weren't in needs
at all.

Reviewed every job's steps for a genuine main-only rationale before
touching it -- found none; all 12 operate on PR-diff or full-repo state
equally validly on dev as on main. No job is documented as intentionally
dev-excluded.

Fix: remove the base_ref clause from all 12, add the 3 missing jobs to
ci-summary's needs, and add a strict success-only fail-closed block in
ci-summary for all 12 (docs_only-gated, mirroring the OMN-15755/OMN-15731
pattern). New rendered-bash regression test
(tests/unit/scripts/test_ci_skip_hole_12_jobs_omn15768.py) proves
non-vacuity: 50/52 cases fail against the pre-fix file, 52/52 pass at head.

Same ci.yml region OMN-15755 (#6221/#6226) and OMN-15731 (#6216) both
touch -- rebase/merge onto dev after those land to avoid a repeat of the
#6221/#6216 conflict resolved this session.

Full local suite: 5977 passed / 47 skipped / 0 failed. mypy src/ tests/:
clean, 398 files.

Cites OMN-15768.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:ready Full CI runs on this PR (OMN-15731 label-gated CI pilot)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant