Principles Gate
Enforce golden-principles compliance by running the violation scanner against .claude/principles.yaml and failing on any blocking…
# 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
uvis 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):
- Identify all numeric literals flagged by the scanner
- Extract each to a named constant in
constants.py:# src/<pkg>/constants.py MAX_RETRY_ATTEMPTS = 3 DEFAULT_PAGE_SIZE = 20 - Replace inline occurrences with the constant name
Hard-coded URLs (P012):
- Move URLs to
src/config.pyvia environment variables:# src/config.py import os API_BASE_URL = os.environ["API_BASE_URL"] - Or add them to
harness.config.yamlfor 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)