guardrail

Generate custom lint rules that enforce architectural decisions at edit time.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "guardrail" with this command: npx skills add phrazzld/claude-config/phrazzld-claude-config-guardrail

/guardrail

Generate custom lint rules that enforce architectural decisions at edit time.

Philosophy

Lint rules are the highest-leverage codification target. They're cheaper than hooks (no custom Python), more durable than CLAUDE.md (automated, not advisory), and work in CI too (not just Claude Code). A lint rule catches violations the moment code is written — and fast-feedback.py surfaces the error immediately so Claude self-corrects.

When to Use

  • Import boundaries ("all DB access through repository layer")

  • API conventions ("routes must start with /api/v1")

  • Deprecated pattern blocking ("no direct fetch, use apiClient")

  • Auth enforcement ("handlers must call requireAuth")

  • Naming conventions that go beyond basic linting

Workflow

Phase 1: Accept Pattern

Parse the input. It can be:

  • Natural language: "all database queries must go through the repository layer"

  • Code example: "this import is wrong: import { db } from './db' "

  • Discovery mode: scan codebase for architectural invariants (when invoked by /tune-repo )

Clarify the constraint:

  • What EXACTLY should be flagged? (imports, function calls, patterns)

  • What's the fix? (alternative import, wrapper function)

  • Are there exceptions? (test files, migrations, the repository itself)

Phase 2: Choose Engine

Criterion ESLint ast-grep

Language JS/TS only Any (Python, Go, Rust, etc.)

Fixable Yes (auto-fix) Yes (rewrite)

Testing RuleTester built-in YAML snapshot tests

Config Flat config plugin sgconfig.yml

Speed Fast Very fast

Default: ESLint for JS/TS projects, ast-grep for everything else. If --engine is specified, use that.

Phase 3: Generate Rule

Read the reference docs for the chosen engine:

  • ESLint: references/eslint-rule-anatomy.md

  • ast-grep: references/ast-grep-rule-anatomy.md

Read the appropriate template:

  • ESLint: templates/eslint-rule.js
  • templates/eslint-rule-test.js
  • ast-grep: templates/ast-grep-rule.yml

Generate:

  • Rule implementation with clear error message and fix suggestion

  • Rule metadata (docs URL, fixable, schema)

  • Test cases (valid AND invalid examples from the actual codebase)

Phase 4: Test

ESLint:

Run RuleTester

node guardrails/rules/<rule-name>.test.js

Or if project uses a test runner:

npx vitest run guardrails/rules/<rule-name>.test.js

ast-grep:

sg scan --config guardrails/sgconfig.yml --test

Also verify against the real codebase:

ESLint: run rule on entire project, expect 0 or known violations

npx eslint --no-warn-ignored --rule 'guardrails/<rule-name>: error' .

ast-grep: scan project

sg scan --config guardrails/sgconfig.yml

Phase 5: Install

Create the guardrails/ directory structure if it doesn't exist:

guardrails/ README.md # Catalog of all custom rules index.js # ESLint local plugin barrel (JS/TS projects) sgconfig.yml # ast-grep config (if non-JS rules exist) rules/ <rule-name>.js # ESLint rule implementation <rule-name>.test.js # ESLint RuleTester <rule-name>.yml # ast-grep rule

ESLint integration (flat config, zero npm dependencies):

// guardrails/index.js import noDirectDbImport from "./rules/no-direct-db-import.js";

export default { rules: { "no-direct-db-import": noDirectDbImport, }, };

// eslint.config.js — add to existing config import guardrails from "./guardrails/index.js";

export default [ // ... existing config { plugins: { guardrails }, rules: { "guardrails/no-direct-db-import": "error", }, }, ];

ast-grep integration:

guardrails/sgconfig.yml

ruleDirs:

  • rules

Phase 6: Document

Update guardrails/README.md with:

<rule-name>

Engine: ESLint | ast-grep Pattern: <what it enforces> Rationale: <why — link ADR if exists> Auto-fix: yes | no Exceptions: <files/patterns excluded>

Output

GUARDRAIL CREATED:

  • Rule: guardrails/rules/<name>.<ext>
  • Test: guardrails/rules/<name>.test.<ext>
  • Engine: ESLint | ast-grep
  • Violations found: N (in current codebase)
  • Auto-fixable: yes | no
  • Config updated: eslint.config.js | guardrails/sgconfig.yml

Anti-Patterns

  • Rules that fire on >20% of files (too broad, probably wrong constraint)

  • Rules without tests (defeats the purpose)

  • Rules without clear error messages (Claude can't self-correct from "error")

  • Duplicating built-in ESLint/Ruff rules (check first)

  • Over-specific rules that match one file (use CLAUDE.md instead)

Integration

Consumed by How

fast-feedback.py

Runs eslint <file> and sg scan <file> on every edit

/codify-learning

Routes "lint rule" target here

/done

Routes "lint rule" target here

/tune-repo

Discovers patterns, recommends /guardrail invocations

/check-quality

Audits guardrails/ completeness

CI (GitHub Actions) Standard eslint . or sg scan in workflow

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

pencil-renderer

No summary provided by upstream source.

Repository SourceNeeds Review
General

ui-skills

No summary provided by upstream source.

Repository SourceNeeds Review
General

llm-gateway-routing

No summary provided by upstream source.

Repository SourceNeeds Review