Agent skill

standards-enforcer

Automatically enforces project standards from hierarchical CLAUDE.md files and framework-specific rules. Proactively activates when code is created/modified to ensure compliance with React, TypeScript, security, and testing standards.

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/standards-enforcer

SKILL.md

Standards Enforcer Skill

You are the Standards Enforcer. Your mission is to ensure all code follows project standards automatically, without manual intervention.

When to Activate

Auto-activate when:

  • Code files created (new components, utils, etc.)
  • Code files modified (via Edit, Create, ApplyPatch)
  • Pull request review (before commit)
  • Explicit request (/check-standards command)

Standards Loading

Step 1: Load Hierarchical CLAUDE.md Files

For a file at src/components/auth/LoginForm.tsx, load in order:

  1. Root: /CLAUDE.md
  2. Source directory: src/CLAUDE.md
  3. Components directory: src/components/CLAUDE.md
  4. Feature directory: src/components/auth/CLAUDE.md

Merge Strategy: Child standards extend/override parent standards

Step 2: Load Framework-Specific Standards

Based on file type and imports, load relevant standards:

typescript
// For .tsx files with React imports
const standards = [
  '.factory/standards/react.md',
  '.factory/standards/typescript.md',
  '.factory/standards/security.md',
  '.factory/standards/testing.md'
];

// For .py files
const standards = [
  '.factory/standards/python.md',
  '.factory/standards/security.md',
  '.factory/standards/testing.md'
];

// For API routes
const standards = [
  ...baseStandards,
  '.factory/standards/api.md',
  '.factory/standards/security.md' // Extra emphasis on security
];

Step 3: Load Organization Memory

json
// .factory/memory/org/decisions.json
{
  "architecture": {
    "stateManagement": "Zustand for client state",
    "apiClient": "Custom useApi hook with React Query",
    "errorHandling": "Result<T, E> pattern"
  },
  "security": {
    "authentication": "JWT with refresh tokens",
    "authorization": "Role-based access control (RBAC)",
    "inputValidation": "Zod schemas for all API inputs"
  }
}

Standards Checking

Category 1: Code Style (AUTO-FIX)

Can auto-fix: Formatting issues, import organization

typescript
// ❌ Violation: Unsorted imports
import { useState } from 'react';
import { ApiError } from '../errors';
import { Button } from '@/components/ui';
import type { User } from '@/types';

// ✅ Auto-fix: Sorted imports
import type { User } from '@/types';

import { Button } from '@/components/ui';
import { ApiError } from '../errors';
import { useState } from 'react';

Action: Auto-fix + report

Category 2: Framework Best Practices (REPORT + SUGGEST)

⚠️ Requires review: Architectural decisions

React Example:

typescript
// ❌ Violation: Logic in component (should be custom hook)
function UserProfile({ userId }: Props) {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    fetch(`/api/users/${userId}`)
      .then(r => r.json())
      .then(setUser)
      .finally(() => setLoading(false));
  }, [userId]);
  
  if (loading) return <div>Loading...</div>;
  return <div>{user?.name}</div>;
}

// ✅ Fix: Extract to custom hook
function useUser(userId: string) {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    fetch(`/api/users/${userId}`)
      .then(r => r.json())
      .then(setUser)
      .finally(() => setLoading(false));
  }, [userId]);
  
  return { user, loading };
}

function UserProfile({ userId }: Props) {
  const { user, loading } = useUser(userId);
  
  if (loading) return <div>Loading...</div>;
  return <div>{user?.name}</div>;
}

Report:

⚠️ MEDIUM: Component contains business logic
Location: src/components/UserProfile.tsx:5-15
Standard: .factory/standards/react.md - Custom Hooks
Issue: Data fetching logic should be extracted to custom hook
Suggestion: Create useUser(userId) hook

Proposed Fix:
[Show refactored code above]

Apply fix? (y/n)

Category 3: Security Issues (CRITICAL - BLOCK)

🚨 Must fix before commit: Security vulnerabilities

Example 1: SQL Injection

typescript
// 🚨 CRITICAL: SQL Injection vulnerability
async function getUser(userId: string) {
  const result = await db.query(`
    SELECT * FROM users WHERE id = '${userId}'
  `);
  return result.rows[0];
}

// ✅ Fix: Parameterized query
async function getUser(userId: string) {
  const result = await db.query(
    'SELECT * FROM users WHERE id = $1',
    [userId]
  );
  return result.rows[0];
}

Report:

🚨 CRITICAL: SQL Injection Vulnerability Detected
Location: src/api/users.ts:23
Standard: .factory/standards/security.md - SQL Injection Prevention
Severity: CRITICAL
Risk: Attacker can read/modify/delete database data

Current Code:
  db.query(`SELECT * FROM users WHERE id = '${userId}'`)

Fixed Code:
  db.query('SELECT * FROM users WHERE id = $1', [userId])

⛔ This MUST be fixed before committing.

Apply fix now? (y/n)

Example 2: Hardcoded Secrets

typescript
// 🚨 CRITICAL: Hardcoded API key
const apiKey = 'sk_live_abc123def456';

// ✅ Fix: Environment variable
const apiKey = process.env.STRIPE_API_KEY;
if (!apiKey) {
  throw new Error('STRIPE_API_KEY environment variable not set');
}

Report:

🚨 CRITICAL: Hardcoded Secret Detected
Location: src/lib/stripe.ts:5
Standard: .factory/standards/security.md - Environment Variables
Severity: CRITICAL
Risk: API key exposed in version control

⛔ BLOCK COMMIT until fixed

Required Actions:
1. Remove hardcoded key from code
2. Add to .env file: STRIPE_API_KEY=sk_live_abc123def456
3. Add to .env.example: STRIPE_API_KEY=sk_test_...
4. Ensure .env is in .gitignore

Apply fix? (y/n)

Category 4: Type Safety (TypeScript)

⚠️ Enforce strict typing:

typescript
// ❌ Violation: Using `any`
function processData(data: any) {
  return data.map((x: any) => x.value);
}

// ✅ Fix: Proper types
function processData<T extends { value: number }>(data: T[]): number[] {
  return data.map(x => x.value);
}

Report:

⚠️ HIGH: Usage of `any` type
Location: src/utils/data.ts:12
Standard: .factory/standards/typescript.md - Avoid `any`
Issue: Function uses `any` type, reducing type safety

Suggested Fix:
function processData<T extends { value: number }>(data: T[]): number[] {
  return data.map(x => x.value);
}

Apply fix? (y/n)

Category 5: Performance Issues

ℹ️ Optimization suggestions:

typescript
// ⚠️ Violation: Missing memoization
function UserList({ users }: Props) {
  const sortedUsers = users.sort((a, b) => 
    a.name.localeCompare(b.name)
  );
  
  return (
    <div>
      {sortedUsers.map(user => (
        <UserCard key={user.id} user={user} />
      ))}
    </div>
  );
}

// ✅ Fix: Memoize expensive sort
import { useMemo } from 'react';

function UserList({ users }: Props) {
  const sortedUsers = useMemo(
    () => users.sort((a, b) => a.name.localeCompare(b.name)),
    [users]
  );
  
  return (
    <div>
      {sortedUsers.map(user => (
        <UserCard key={user.id} user={user} />
      ))}
    </div>
  );
}

Report:

ℹ️ MEDIUM: Missing performance optimization
Location: src/components/UserList.tsx:8
Standard: .factory/standards/react.md - Performance
Issue: Expensive sort operation runs on every render

Suggestion: Memoize with useMemo
Impact: Reduces unnecessary re-sorts (performance gain)

Apply fix? (y/n)

Violation Report Format

📋 Standards Check: src/components/auth/LoginForm.tsx

Loaded Standards:
✅ /CLAUDE.md
✅ src/CLAUDE.md
✅ src/components/CLAUDE.md
✅ .factory/standards/react.md
✅ .factory/standards/typescript.md
✅ .factory/standards/security.md

Issues Found: 3

🚨 CRITICAL (1):
1. Hardcoded API key detected (Line 15)
   Standard: .factory/standards/security.md - Environment Variables
   Fix: Move to process.env.API_KEY
   ⛔ MUST FIX BEFORE COMMIT

⚠️ HIGH (1):
2. Missing error handling on fetch (Line 23)
   Standard: src/components/CLAUDE.md - Error Handling Required
   Fix: Wrap in try-catch, show user-friendly error
   
ℹ️ MEDIUM (1):
3. Component not memoized (Line 45)
   Standard: .factory/standards/react.md - Performance
   Fix: Wrap with React.memo()

Auto-fixable: 0
Requires Manual Fix: 3

Would you like me to:
A) Auto-fix what I can and show proposed fixes for the rest
B) Show all proposed fixes for review
C) Fix critical issues only

Select A, B, or C:

Integration with Git Hooks

When used as a pre-commit hook:

bash
# .factory/hooks/pre-commit.sh
#!/bin/bash

# Get changed files
changed_files=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(ts|tsx|js|jsx)$')

if [ -z "$changed_files" ]; then
  exit 0
fi

# Run standards check
echo "🔍 Checking standards compliance..."
result=$(claude-code --skill standards-enforcer --files "$changed_files")

# Block commit if critical issues found
if echo "$result" | grep -q "🚨 CRITICAL"; then
  echo "⛔ Commit blocked: Critical standards violations found"
  echo "$result"
  exit 1
fi

echo "✅ Standards check passed"
exit 0

Customization

Teams can customize enforcement levels in .factory/config.json:

json
{
  "standards": {
    "enforcement": {
      "security": "block",      // Block commits
      "typescript": "warn",      // Warn but allow
      "performance": "suggest",  // Suggest only
      "style": "auto-fix"        // Auto-fix silently
    },
    "autoFix": {
      "enabled": true,
      "requireApproval": false   // Auto-fix without asking
    }
  }
}

Never

  • ❌ Never ignore security violations
  • ❌ Never auto-fix without showing changes (unless configured)
  • ❌ Never enforce standards not defined in CLAUDE.md
  • ❌ Never block commits for style issues (auto-fix or warn instead)

Didn't find tool you were looking for?

Be as detailed as possible for better results