Skip to content

feat: add check_bare_feature_flags.py pre-commit validator [OMN-5573] - #79

Merged
jonahgabriel merged 1 commit into
mainfrom
jonahgabriel/omn-5573-check-bare-feature-flags
Mar 19, 2026
Merged

jonahgabriel merged 1 commit into
mainfrom
jonahgabriel/omn-5573-check-bare-feature-flags

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Mar 19, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Cross-repo pre-commit hook (no-bare-feature-flags) that rejects bare os.getenv("ENABLE_*"), os.environ.get/["ENABLE_*"], process.env.ENABLE_*, and *_ENABLED suffix env var reads
  • Lines with # ONEX_FLAG_EXEMPT: <reason> are exempt; exemptions without a reason token are themselves violations
  • Approved basenames (feature_flag_resolver.py, contract.yaml, check_bare_feature_flags.py, model_contract_feature_flag.py) and path segments (/tests/, /capabilities/, /config_discovery/) are never flagged
  • 21 unit tests covering all detection, exemption, and approval cases

Test plan

  • 21 unit tests pass (uv run pytest tests/unit/scripts/test_check_bare_feature_flags.py -v)
  • Full test suite passes (452 tests)
  • pre-commit run --all-files passes
  • Entry point registered in pyproject.toml
  • Hook entry added to .pre-commit-hooks.yaml

Closes OMN-5573

Summary by CodeRabbit

  • New Features

    • Introduced a feature flag validation tool that automatically detects and reports improper environment variable usage patterns in Python, TypeScript, and JavaScript source files, helping maintain consistent feature flag practices across the codebase.
  • Chores

    • Added pre-commit hook configuration enabling automated validation during development commits, with support for exemptions through inline code markers for intentional exceptions.

Cross-repo pre-commit hook that rejects bare os.getenv("ENABLE_*"),
os.environ.get/["ENABLE_*"], process.env.ENABLE_*, and *_ENABLED
suffix patterns. Lines with ONEX_FLAG_EXEMPT: <reason> are exempt;
exemptions without a reason token are themselves violations.

Approved basenames (feature_flag_resolver.py, contract.yaml,
check_bare_feature_flags.py, model_contract_feature_flag.py) and
path segments (/tests/, /capabilities/, /config_discovery/) are
never flagged.

- New script with entry point check-bare-feature-flags
- 21 unit tests covering all detection/exemption/approval cases
- Hook entry in .pre-commit-hooks.yaml (no-bare-feature-flags)
@coderabbitai

coderabbitai Bot commented Mar 19, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This pull request introduces a new pre-commit hook named no-bare-feature-flags that scans Python, TypeScript, and JavaScript files for bare feature-flag environment variable reads. The implementation includes a CLI script with support for approved files/paths, exemption markers, and comprehensive test coverage.

Changes

Cohort / File(s) Summary
Pre-commit Hook Configuration
.pre-commit-hooks.yaml, pyproject.toml
Added no-bare-feature-flags hook definition and registered check-bare-feature-flags as a CLI entry point script.
Feature-Flag Scanner Implementation
src/onex_change_control/scripts/check_bare_feature_flags.py
Implemented regex-based scanner for bare environment variable reads matching ENABLE_* and *_ENABLED patterns in Python and TypeScript/JavaScript, with support for approved basenames/paths and ONEX_FLAG_EXEMPT: exemption markers.
Unit Tests
tests/unit/scripts/test_check_bare_feature_flags.py
Comprehensive test suite covering Python and TypeScript pattern detection, approved file/path exclusions, comment filtering, exemption handling, and CLI exit codes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Bare flags wander wild and free,
But now I hunt them carefully!
With regex sharp and paths approved,
Feature gates are gently grooved—
No naked reads shall pass my sight,
Pre-commit hooks make code just right! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a pre-commit validator for bare feature flags. It is specific, concise, and clearly conveys the primary purpose of the changeset.

✏️ 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 jonahgabriel/omn-5573-check-bare-feature-flags
📝 Coding Plan
  • Generate coding plan for human review comments

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

@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)
src/onex_change_control/scripts/check_bare_feature_flags.py (1)

71-74: Consider making _ScanResult public or documenting its semi-public status.

check_file_full is a public function that returns _ScanResult, but the underscore prefix suggests it's a private type. This creates a minor API inconsistency. For a pre-commit hook with limited external consumers, this is acceptable, but consider renaming to ScanResult if external callers are expected.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/onex_change_control/scripts/check_bare_feature_flags.py` around lines 71
- 74, The public function check_file_full returns a dataclass named _ScanResult
whose leading underscore implies private scope; either make the type public by
renaming _ScanResult to ScanResult or explicitly document its semi-public API
surface. Locate the dataclass definition named _ScanResult and either change its
identifier to ScanResult and update all references (e.g., return annotations and
any instantiations in check_file_full) or add a module-level docstring/comment
stating that _ScanResult is intentionally exported for callers of
check_file_full, and update __all__ if present to include "_ScanResult" (or
"ScanResult" if renamed).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/onex_change_control/scripts/check_bare_feature_flags.py`:
- Around line 71-74: The public function check_file_full returns a dataclass
named _ScanResult whose leading underscore implies private scope; either make
the type public by renaming _ScanResult to ScanResult or explicitly document its
semi-public API surface. Locate the dataclass definition named _ScanResult and
either change its identifier to ScanResult and update all references (e.g.,
return annotations and any instantiations in check_file_full) or add a
module-level docstring/comment stating that _ScanResult is intentionally
exported for callers of check_file_full, and update __all__ if present to
include "_ScanResult" (or "ScanResult" if renamed).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 249bc879-8c5a-447d-99fc-faa6e06f94c8

📥 Commits

Reviewing files that changed from the base of the PR and between bc2b338 and bdd09d6.

📒 Files selected for processing (4)
  • .pre-commit-hooks.yaml
  • pyproject.toml
  • src/onex_change_control/scripts/check_bare_feature_flags.py
  • tests/unit/scripts/test_check_bare_feature_flags.py

@jonahgabriel
jonahgabriel added this pull request to the merge queue Mar 19, 2026
Merged via the queue into main with commit ddffb89 Mar 19, 2026
14 checks passed
@jonahgabriel
jonahgabriel deleted the jonahgabriel/omn-5573-check-bare-feature-flags branch March 19, 2026 22:30
jonahgabriel added a commit that referenced this pull request Apr 30, 2026
Adds contracts/OMN-10316.yaml (ModelTicketContract) and
drift/dod_receipts/OMN-10316/ receipts required by the omnibase_infra
Receipt Gate CI check.

Evidence:
- dod-001: pre-commit run --all-files PASSED in all 9 repo worktrees
- dod-002: docs-validate / call CI check PASSED on omnibase_compat PR #79
  (representative sample; all 9 PRs have auto-merge armed)
jonahgabriel added a commit that referenced this pull request May 22, 2026
OMN-11497:
- Update dod-product-pr-79 receipt to final SHA 763ed90 (mypy fix)
- Update contract to reflect final SHA

OMN-11502 (new):
- Add contract for rich terminal display module (PR #80)
- dod-product-pr-80: PR #80 head SHA 8f4827c
- dod-unit-tests: full suite pass
- dod-occ-self: self-binding to OCC PR #1312

Closes OMN-11497, OMN-11502
jonahgabriel added a commit that referenced this pull request May 22, 2026
* docs(OMN-11497): bind ToolRegistry evidence — PR #79 receipts

- contracts/OMN-11497.yaml: contract for in-process ToolRegistry ticket
- drift/dod_receipts/OMN-11497/dod-product-pr-79: PR #79 head SHA db84543
- drift/dod_receipts/OMN-11497/dod-unit-tests: 12 tool registry tests pass, 616 total
- drift/dod_receipts/OMN-11497/dod-occ-self: self-binding receipt

Addresses CodeRabbit review: restricted exec globals + ThreadPoolExecutor timeout.

Closes OMN-11497

* docs(OMN-11497): update self-binding receipt with OCC PR #1312 SHA

* docs(OMN-11497,OMN-11502): update PR #79 receipt + add PR #80 evidence

OMN-11497:
- Update dod-product-pr-79 receipt to final SHA 763ed90 (mypy fix)
- Update contract to reflect final SHA

OMN-11502 (new):
- Add contract for rich terminal display module (PR #80)
- dod-product-pr-80: PR #80 head SHA 8f4827c
- dod-unit-tests: full suite pass
- dod-occ-self: self-binding to OCC PR #1312

Closes OMN-11497, OMN-11502

* docs(OMN-11497,OMN-11502): fix receipt schema validation errors

- OMN-11497 dod-unit-tests: remove extra "12 passed: true" field (extra_forbidden)
- OMN-11497 dod-unit-tests: update commit_sha to final SHA 763ed90
- OMN-11502 dod-unit-tests: add required probe_command + probe_stdout fields
- OMN-11502 dod-occ-self: fix commit_sha (was "PENDING"), add probe_command + probe_stdout

All 6 receipts validate against ModelDodReceipt schema.

Closes OMN-11497, OMN-11502

* fix(OMN-11497,OMN-11502): add contract_sha256 to all receipts (OMN-10421 requirement)

Receipts produced after 2026-04-30 must record the contract hash.
Added sha256 fingerprint of OMN-11497.yaml and OMN-11502.yaml to all
six dod_receipt files for these two tickets.
andywu42 pushed a commit to andywu42/onex_change_control that referenced this pull request Jun 10, 2026
…e_control (OmniNode-ai#558)

* feat(OMN-10316): wire docs-validate as required CI gate in onex_change_control

Adds .github/workflows/docs-validate.yml caller to the reusable
OmniNode-ai/omnibase_core/.github/workflows/validate-docs.yml@main workflow.

Also adds .markdown-link-check.json with omni_worktrees/** exclusion (OMN-9607
pattern) so the gate does not scan nested worktree checkouts.

dod_evidence:
  - pre-commit run --all-files: PASSED
  - workflow file: .github/workflows/docs-validate.yml
  - link-check config: .markdown-link-check.json

* feat(OMN-10316): add ticket contract and DoD receipts for gate wiring

Adds contracts/OMN-10316.yaml (ModelTicketContract) and
drift/dod_receipts/OMN-10316/ receipts required by the omnibase_infra
Receipt Gate CI check.

Evidence:
- dod-001: pre-commit run --all-files PASSED in all 9 repo worktrees
- dod-002: docs-validate / call CI check PASSED on omnibase_compat PR OmniNode-ai#79
  (representative sample; all 9 PRs have auto-merge armed)

* fix(OMN-10316): remove paths filter so required check runs on every PR

* fix(OMN-10316): use file_exists checks to avoid CI shell timeout/pipe issues
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