Repository navigation
feat(OMN-13973): wire governed impacted-test selector as pre-push hook (WS7 fan-out) - #2322
Conversation
…k (WS7 fan-out) Wires the governed change-aware test selector (scripts/ci/detect_test_paths.py + scripts/ci/test_selection_adjacency.yaml, ENABLE_SMART_TESTS) as a pre-push pre-commit hook on omnibase_infra. Fan-out from the omnibase_core#1451 canary. PER-REPO SEAM-MATCH (not a paste): infra's selector hardcodes SRC_PREFIX=src/omnibase_infra/ + its own adjacency map, and unlike core does NOT accept --base-ref -- so the wrapper omits it (matches infra CI's own invocation). Full-suite escalation runs tests/unit/ (not all of tests/) to stay unit-scoped and service-free; integration/chaos/replay/performance stay CI-only. Fail-closed: escalates to the full unit suite on shared-module / pyproject / tests-infra / >=6-module / main changes. Fail-loud: hard-errors (exit 1) if the base/selector/adjacency cannot resolve; never a green skip. Net-negative-surface: retires the 'run the whole unit suite by hand before every push' default (CLAUDE.md Rule #4). Closes OMN-13973. Refs OMN-14655 (WS7).
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 53 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the 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 configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
Merge-controller maintenance: closing and reopening to refresh pull_request checks against current dev base without changing the exact head or OCC evidence. |
OMN-13973 — Governed impacted-test selector wired as a PRE-PUSH hook (omnibase_infra fan-out)
Wires the governed change-aware test selector (
scripts/ci/detect_test_paths.py+scripts/ci/test_selection_adjacency.yaml,ENABLE_SMART_TESTS) as a pre-push pre-commit hook onomnibase_infra. Fan-out from the proven canaryomnibase_core#1451.Closes OMN-13973. Refs OMN-14655 (WS7).
What changed (2 files)
scripts/hooks/prepush_smart_tests.sh(new) — the pre-push wrapper. Computes changed files vs theorigin/devmerge-base and DRY-invokes the exact CI moduleuv run python -m scripts.ci.detect_test_pathswith the same flags infra CI uses, then runsuv run pytest <selected_paths> --ignore=tests/integration..pre-commit-config.yaml— newrepo: localhookprepush-smart-tests,stages: [pre-push],always_run: true,pass_filenames: false,verbose: true.This is a per-repo SEAM-MATCH, not a paste
Each repo's
detect_test_paths.pyis hardcoded to its ownSRC_PREFIX+ its own adjacency map. The infra-specific adaptations vs the core canary:SRC_PREFIX = "src/omnibase_infra/"and infra's owntest_selection_adjacency.yaml(shared modules:models,enums,runtime,errors,nodes,topics;modules_changed_for_full_suite: 6). Handled inside the selector — the wrapper just invokes it.--base-refis OMITTED. Infra'sdetect_test_paths.py main()does not define a--base-refargument (core's does), and infra CI (.github/workflows/ci.yml) does not pass one either. Forwarding it would make the selector argparse hard-error on every push. The wrapper computes the merge-base locally forgit diffbut never forwards it — DRY parity is with infra's own CI invocation.tests/unit/, not all oftests/. Infra'stests/integration,tests/chaos,tests/replay,tests/performanceneed a live runtime (Docker/Postgres/Kafka) and stay a CI-only concern. The pre-push subset is unit-scoped by design;tests/integrationis always--ignored.Label: advisory local mirror, NOT byte-parity
On CI the selector is gated behind
ENABLE_SMART_TESTS(off by default during rollout) and the enforced merge gate is the full suite. This hook is deliberately net-new, fast local impacted-subset enforcement — an ADVISORY local mirror of the full CI suite, not a claim of parity with an enforced CI context. Labeled as such in both the hook script and the config comment.pyproject.toml/ test-infra / ≥6 modules /main).precommit-fail-loud-meta-gate, which scans this script and passes it.default_install_hook_typesalready includespre-push(.pre-commit-config.yaml) — no install-gap; verified the git hook is actually written (below).scripts.ci.detect_test_pathsmodule +test_selection_adjacency.yamlCI runs; no re-implementation of the selection rule.Net-negative-surface (CLAUDE.md net-negative-surface rule)
This hook retires the "run the whole unit suite by hand before every push" default that CLAUDE.md Rule #4 mandates as the fail-closed local stopgap ("until OMN-13973 lands, the full local suite remains the fail-closed default"). One new hook replaces a manual, un-enforced, whole-suite pre-push step with a governed, fail-closed, fail-loud impacted subset. No new bespoke validator — it invokes the existing CI entrypoint.
Installation-proof + measured evidence (fresh isolated clone; a green
pre-commit runproves nothing about the git-push path)All proofs ran in a fresh clone pushing to a local bare remote, so the real
.git/hooks/pre-pushpath fires. (origin/dev=e2dc4666.)1. Installation (git-push path):
pre-commit installwrotepre-commit installed at .git/hooks/pre-push; a realgit pushfired the hook:2. Subset selection: a single-module change under
src/omnibase_infra/scope/selected onlytests/unit/scope/(is_full_suite=False). Hook-only duration 11.55s (uv cold-start dominated; pytest itself 0.45s / 21 tests). Total push wall-clock incl. mypy + arch-layer pre-push gates: 49.3s.3. Fail-closed escalation: a change to a shared module (
src/omnibase_infra/models/__init__.py) escalated correctly:(pyproject.toml change likewise escalates with
reason=test_infrastructure— verified via the selector directly.)4. Fail-loud (hard error, not skip): an unresolvable adjacency config (
PREPUSH_ADJACENCY=/tmp/does-not-exist.yaml):git pushexit code 1 — push BLOCKED; the remote ref did not advance (10bbe6e4→ still10bbe6e4).Note on this PR's own push
This diff touches only config + the hook script (zero src/test behavior change), so the selector's conservative fallback maps it to the whole
tests/unit/suite — exactly the manual full-suite tax this hook exists to retire. Consistent with the canary's isolated-harness proof method, the introducing push skipped only the brand-new hook (SKIP=prepush-smart-tests); mypy + architecture-layer pre-push gates and all pre-commit gates ran, and CI runs the full suite on this PR regardless. The hook itself is fully proven above via the real git-push path.dod_evidence
dod_evidence: pre-push hook installation proven on the git-push path (.git/hooks/pre-pushwritten bypre-commit install+ fired on realgit push); governed subset selection (tests/unit/scope/, 21 passed / 0.45s, hook duration 11.55s); fail-closed escalation on a shared-module change (is_full_suite=True,reason=shared_module, ran the fulltests/unit/suite) and on apyproject.tomlchange (reason=test_infrastructure); and fail-loud hard-error (exit 1 + remediation, push blocked) on unresolvable config — all captured above.validate_precommit_fail_loud.pypasses over the new hook (fail-loud meta-gate green). shellcheck clean.proof_class: receipt-bound (local-readback: real git-push hook fire + pytest execution + hard-error exit code + remote-ref-did-not-advance).Notes
verify/ receipt-gate may be red until that companion lands.Evidence-Ticket: OMN-13973
Evidence-Source: OCC#4296
Evidence-Commit: a18c4b662d03347f4f3166e5abaca112488ad88c
Evidence-Head: 2862ee0