# Guardian Angel

> 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'.

- Skill: `elihuvillaraus/guardian-angel` (Agent Skill)
- Install (CLI): `npx skillmds@latest add elihuvillaraus/guardian-angel`
- Raw SKILL.md: https://api.skillmd.com/api/skills/elihuvillaraus/guardian-angel/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: elihuvillaraus (https://skillmd.com/u/elihuvillaraus)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/elihuvillaraus/guardian-angel

---


# 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

```bash
# What changed?
git diff --staged --name-only
git diff --staged

# Load project memory (architectural decisions, norms)
engram search "architecture" --type architecture --limit 10
engram search "convention" --type context --limit 10

# Load skill registry for context on this project's patterns
cat .atl/skill-registry.md 2>/dev/null || echo "No skill registry found"

# If a spec exists for the story being implemented, load it
cat docs/tasks/*/specs/*.md 2>/dev/null | head -100
```

### Step 1 — Check architectural compliance

For each changed file, ask:
1. Is it in the right folder? (feature vs shared, domain separation)
2. Does it follow the layering rules? (no business logic in routes, no DB calls in components)
3. 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:
```bash
# Project AGENTS.md has universal conventions
cat AGENTS.md 2>/dev/null | head -100

# Engram has architectural decisions
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:
```bash
# Find relevant spec
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

```bash
# Check for hardcoded secrets
git diff --staged | grep -E "(password|secret|key|token)\s*=\s*['\"][^'\"]{8,}" || true

# Check for unvalidated env usage
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.

For every new/changed function that **writes to a database or persistent store**:
- Does at least one test run against a real test DB and read the value back, or does every test mock the DB client?
- A test that only asserts "the mock was called with X" is coverage in name only — it proves the call happened, not that the write was accepted.

Flag: `MOCK_ONLY_TEST` with function name — "story writes data but every test mocks the DB; no test proves the write is actually accepted (RLS, constraints, defaults)."

### 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`:

```yaml
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`:
```bash
#!/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

