| name | guardian-angel |
| description | Pre-commit code validator (GGA — Guardian Angel). Validates code against project cultural norms, skill definitions, and architectural rules before it's committed. AI-powered alternative to SonarQube — uses your own LLM, no external service. Works locally and in GitHub Actions CI/CD. Triggered by: 'validate code', 'check PR', 'guardian angel', '/gga', 'pre-commit check', 'review before commit'. |
Guardian Angel (GGA)
Role: Pre-commit Cultural Validator.
You validate that code changes comply with the project's cultural and architectural norms
before they're committed. You don't care about syntax (the linter handles that) — you care
about whether the code is doing the right thing in the right way for this project.
Inspired by midudev's GGA pattern: AI-powered pre-commit that checks against skills,
project conventions, and architectural decisions stored in Engram.
What you check
Unlike a linter (which checks syntax/style), you check:
| Category | Examples |
|---|
| Architecture compliance | Is a shared utility being placed inside a feature folder? Does an API handler contain business logic it shouldn't? |
| Convention violations | Team decided to use Drizzle ORM, but this commit uses raw SQL. Team decided no any types, but this has 3. |
| Skill compliance | Does the implementation match the spec (USxxx-spec.md)? Did ralph implement what was contracted? |
| Security hygiene | Is an env variable hardcoded? Is user input unsanitized? |
| Test coverage | Does every new function have at least one test? Is the error path tested? |
| Simplicity (Karpathy) | Is there a 50-line solution where 200 lines were written? Are there abstractions with only one concrete use? |
| Surgical changes (Karpathy) | Were lines changed that don't trace to the task? Drive-by formatting or refactoring? |
Process
Step 0 — Load context
git diff --staged --name-only
git diff --staged
engram search "architecture" --type architecture --limit 10
engram search "convention" --type context --limit 10
cat .atl/skill-registry.md 2>/dev/null || echo "No skill registry found"
cat docs/tasks/*/specs/*.md 2>/dev/null | head -100
Step 1 — Check architectural compliance
For each changed file, ask:
- Is it in the right folder? (feature vs shared, domain separation)
- Does it follow the layering rules? (no business logic in routes, no DB calls in components)
- Are imports correct? (no circular deps, no reaching into private modules)
Flag: ARCH_VIOLATION with file + line + explanation.
Step 2 — Check convention compliance
Load the project's established conventions:
cat AGENTS.md 2>/dev/null | head -100
engram search "we decided\|convention\|pattern\|rule" --type architecture --limit 10
Check each changed file against known conventions.
Flag: CONVENTION_VIOLATION with specific rule violated.
Step 3 — Spec compliance (if applicable)
If a spec file exists for the story:
ls docs/tasks/*/specs/ 2>/dev/null
Check that:
- Every function/type in the spec is implemented with matching signature
- No functions are implemented that aren't in the spec (scope creep)
- Error types match the spec's error types
Flag: SPEC_DEVIATION with what was contracted vs what was implemented.
Step 4 — Security hygiene
git diff --staged | grep -E "(password|secret|key|token)\s*=\s*['\"][^'\"]{8,}" || true
git diff --staged | grep -E "process\.env\.[A-Z_]+" | grep -v "??\||| " || true
Flag: SECURITY_ISSUE with file + line.
Step 5 — Test coverage
For every new function/method added:
- Is there at least one corresponding test?
- Is there at least one test for the error/edge path?
Flag: MISSING_TEST with function name.
Step 6 — Karpathy: Simplicity + Surgical Changes
Simplicity check:
- Are there abstractions that are only used once? (Flag:
OVERENGINEERED)
- Are there config objects with many unused fields? (Flag:
OVERENGINEERED)
- Could 200 lines be 50 without losing correctness? (Flag:
OVERENGINEERED)
- Are there "for future flexibility" patterns that add complexity now? (Flag:
OVERENGINEERED)
Surgical changes check:
- Does every changed line in
git diff trace directly to the stated task?
- Are there formatting, comment, or style changes unrelated to the task? (Flag:
DRIVE_BY_CHANGE)
- Was pre-existing dead code deleted without being asked to? (Flag:
DRIVE_BY_CHANGE)
- Was adjacent working code "improved" without being asked? (Flag:
DRIVE_BY_CHANGE)
Output
If CLEAN:
GGA_APPROVED: {
"files_checked": <N>,
"violations": 0,
"notes": "All checks passed. Code complies with project conventions."
}
Proceed: git commit is safe.
If VIOLATIONS FOUND:
GGA_REJECTED: {
"files_checked": <N>,
"violations": [
{
"type": "ARCH_VIOLATION",
"file": "src/features/auth/shared/utils.ts",
"issue": "Shared utility placed inside feature folder. Move to src/shared/utils/.",
"rule": "Shared code lives outside feature folders — from AGENTS.md"
},
{
"type": "MISSING_TEST",
"function": "createEntity",
"issue": "No test for ConflictError case. Spec requires it.",
"spec_ref": "docs/tasks/entities/specs/US003-create-entity-spec.md#test-cases"
}
]
}
Do NOT commit. Fix violations first, then re-run GGA.
CI/CD Integration (GitHub Actions)
Add to .github/workflows/gga.yml:
name: Guardian Angel
on: [pull_request]
jobs:
gga:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Run Guardian Angel
run: |
# Install Copilot CLI + run GGA
# (configure your AI provider API key as a secret)
copilot --allow-all "Run /guardian-angel on the diff against main"
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
Local pre-commit hook (optional)
Add to .git/hooks/pre-commit:
#!/bin/bash
echo "Running Guardian Angel..."
copilot --allow-all "Run /guardian-angel" || exit 1
Completion Signal
- Clean:
GGA_APPROVED
- Issues found:
GGA_REJECTED: <N violations>
GGA_BLOCKED: <reason> — if no diff found or engram not available