Principles Gate

Enforce golden-principles compliance by running the violation scanner against .claude/principles.yaml and failing on any blocking…

bowen31337 1 updated 2mo ago
Claude CodeGeneric
View source ↗
# Harness Principles Gate

Enforce **golden-principles compliance** by running the violation scanner
against `.claude/principles.yaml` and failing on any `blocking`-severity
violation.

The gate loads the project's principle definitions, maps each principle's
YAML `severity` to a scanner output level, runs built-in AST scanners for
auto-detectable violations, and exits non-zero when critical violations are
found — preventing merge until all blocking principles are satisfied.

Default behaviour: **fail on critical (blocking) violations only**.
Non-critical violations are reported as warnings but do not block.

---

## Usage

```bash
# Run with defaults — fail on blocking violations
/harness:principles-gate

# Advisory mode — report all violations as warnings, never block
/harness:principles-gate --no-fail-on-critical

# Fail on ALL error-severity violations (not just blocking ones)
/harness:principles-gate --fail-on-error

# Point at a custom principles file
/harness:principles-gate --principles-file path/to/custom-principles.yaml

# Run only specific scanners
/harness:principles-gate --rules no_magic_numbers no_hardcoded_urls

# Output JSON (for CI integrations)
/harness:principles-gate --format json

# Integrate into a full evaluate run
/harness:evaluate --gate principles

Instructions

Step 0: Resolve inputs

Collect the following from the invocation (applying defaults where absent):

Argument Default Description
--fail-on-critical true Fail the gate on blocking-severity violations
--no-fail-on-critical (flag) Disable critical-violation blocking (advisory mode)
--fail-on-error false Fail on ALL error violations (superset of fail-on-critical)
--principles-file .claude/principles.yaml Path to principles YAML relative to project root
--rules all Space-separated list of scanner names to run
--format text Output format: text or json
--project-root . Repository root for resolving relative paths

Step 1: Verify the principles file exists

Check that .claude/principles.yaml (or the custom path) is present.

If missing, emit:

⚠️  No principles file found at '.claude/principles.yaml'.
    Run /define-principles to create project-specific golden rules.
    The gate will run with built-in defaults only.

Do not exit — the gate still runs built-in scanners even without a principles file.


Step 2: Run the principles gate CLI

uv run python -m harness_skills.gates.principles \
  --root <project-root> \
  --principles-file <principles-file> \
  [--no-fail-on-critical] \
  [--fail-on-error] \
  [--rules <rule1> <rule2> ...] \
  [--format text|json]

Fallback — if uv is not available:

python -m harness_skills.gates.principles \
  --root <project-root> \
  --principles-file <principles-file>

Capture both stdout and the exit code.


Step 3: Parse and render the result

The CLI emits a summary block. Render it in this format:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  Principles Gate — <PASS ✅ | FAIL ❌>
  Principles loaded  : <N>
  Scanners run       : <N>
  Total violations   : <N>
  Blocking (errors)  : <N>
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

For each violation, show:

🔴 [P011] Magic number 42 — extract to a named constant.
  src/config.py:87
   → Replace 42 with a named constant such as `MAX_RETRIES = 42`
     in a `constants.py` module.

Severity icons:

Severity Icon Meaning
error 🔴 Blocking — must fix before merge
warning 🟡 Advisory — should fix, does not block
info 🔵 Suggestion — consider addressing

If the gate passes (no blocking violations):

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  ✅  Principles gate passed — no blocking violations
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

If the gate fails (blocking violations present), add:

🔴 BLOCKING — principles violations found, merge prevented
────────────────────────────────────────────────────────
  <N> blocking violation(s) must be resolved before merging.
  Run /define-principles to review or update project rules.

Advisory mode (--no-fail-on-critical): replace every 🔴 BLOCKING header with 🟡 WARNING — advisory only, merge not blocked.


Step 4: Exit behaviour

Outcome Exit code
No blocking violations 0
Blocking violations present (fail_on_critical=true) 1
No principles file + no violations from built-in scanners 0
Gate runner internal error 2
Advisory mode (any violations) 0 (warnings emitted)

Mirror the CLI exit code.

If exit code is 1, explicitly state: "This branch is not ready to merge — resolve all 🔴 blocking violations before the pull request can land."


Step 5: Suggest next steps on failure

When blocking violations are found, suggest concrete actions per violation type:

Magic numbers (P011):

  1. Identify all numeric literals flagged by the scanner
  2. Extract each to a named constant in constants.py:
    # src/<pkg>/constants.py
    MAX_RETRY_ATTEMPTS = 3
    DEFAULT_PAGE_SIZE = 20
    
  3. Replace inline occurrences with the constant name

Hard-coded URLs (P012):

  1. Move URLs to src/config.py via environment variables:
    # src/config.py
    import os
    API_BASE_URL = os.environ["API_BASE_URL"]
    
  2. Or add them to harness.config.yaml for non-secret config values

Function naming (P014):

# Find non-snake_case functions
grep -rn "def [A-Z]" src/ tests/

Class naming (P016):

  • Rename classes to PascalCase — all words capitalised, no underscores

File naming (P017):

# Find non-snake_case Python files
find . -name "*.py" | grep -E "[A-Z]"

Review or update project principles:

/define-principle

Maintain Principles Gate?

Let people know it's listed here — add the badge (live metrics, light/dark aware) or a plain link to your README or docs.

[Principles Gate on getagentictools](https://getagentictools.com/loops/bowen31337-harness-principles-gate?ref=badge)