Pattern: Ensure AI-generated code is production-ready before showing it to users.
Problem: AI agents present broken or untested code, causing frustrating back-and-forth cycles. Users waste time debugging code that should have been validated first.
Solution: Build validation into the agent workflow. Code gets tested before presentation, fixed autonomously when possible, and blocked at commit time as a final safety net.
Get a working validation loop in your project:
mkdir -p scripts/validation
cat > scripts/validation/check.sh << 'EOF'
#!/bin/bash
set -e
echo "Running validation..."
# Add your checks here:
npm run lint 2>&1 || exit 1
npm run test 2>&1 || exit 1
echo "All checks passed"
EOF
chmod +x scripts/validation/check.shcat > scripts/validation/auto-fix.sh << 'EOF'
#!/bin/bash
set -e
MAX=3
for i in $(seq 1 $MAX); do
echo "Attempt $i/$MAX"
if ./scripts/validation/check.sh; then
echo "Validation passed"
exit 0
fi
echo "Failed - fix and re-run"
exit 1
done
EOF
chmod +x scripts/validation/auto-fix.shcat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
./scripts/validation/check.sh
EOF
chmod +x .git/hooks/pre-commit# Run validation manually
./scripts/validation/auto-fix.sh
# Try to commit - hook will validate
git add . && git commit -m "test"Done! You now have autonomous validation with a git hook safety net.
- Customize
check.shfor your project's linting/testing - Add process rule reminders (see Process Rules section)
- Add more validation types (security, types, etc.)
AQE combines three mechanisms that reinforce each other:
flowchart LR
A[Code] --> B[Validate]
B -->|Fail| C[Fix & Retry]
C --> B
B -->|Pass| D[Commit]
D --> E[Git Hook]
E -->|Fail| C
E -->|Pass| F[Done]
| Component | Purpose | When It Runs |
|---|---|---|
| Process Rules | Remind agent to validate | During development |
| Validation Loops | Fix failures autonomously | Before presenting code |
| Git Hooks | Final safety net | At commit time |
All three use the same validation scripts. One source of truth.
Process rules are instructions in your agent configuration that remind it to validate code.
## Code Quality Rules
**MANDATORY**: Before presenting ANY code to the user:
1. Run `./scripts/validation/check.sh`
2. If validation fails, fix the issue and re-run
3. Maximum 3 fix attempts before asking user for help
4. NEVER present code that hasn't passed validation- Proactive, not reactive: Catches issues before user sees them
- Self-correcting: Agent fixes its own mistakes
- Configurable tolerance: Set max iterations based on project needs
The autonomous fix loop is the core mechanism. When validation fails, the agent:
- Analyzes the error output
- Identifies the root cause
- Applies a fix
- Re-runs validation
- Repeats until success or max iterations reached
See the demo-fastapi repository for a reference implementation of the autonomous fix loop.
Git hooks are the final safety net. Even if process rules are ignored, broken code cannot be committed.
#!/bin/bash
# .git/hooks/pre-commit
echo "Running pre-commit validation..."
if ! ./scripts/validation/check.sh; then
echo ""
echo "Commit blocked: validation failed"
echo "Run './scripts/validation/check.sh' to see errors"
exit 1
fi
echo "Pre-commit validation passed"# Make hook executable
chmod +x .git/hooks/pre-commit
# Verify hook is active
ls -la .git/hooks/pre-commit
# Test the hook
git add . && git commit -m "test" # Will run validation| Metric | Before AQE | Target | How to Measure |
|---|---|---|---|
| Broken code presentations | 2-5 per feature | 0 | Count user-reported crashes |
| "Try this fix" iterations | 3-5 per bug | 0-1 | Count back-and-forth cycles |
| Time to working code | Variable | First presentation | Track presentation-to-approval time |
| Commits blocked by hooks | N/A | >0 | Git hook rejection count |
- Validation speed at cost of coverage
- Skipping hooks to "move faster"
- Reducing max iterations to avoid fixing hard bugs
Symptom: Validation keeps failing, AI keeps "fixing" but never succeeds.
Causes:
- Test is flaky (passes/fails randomly)
- Fix creates new bug that causes different failure
- Underlying issue requires human judgment
Solution:
# Set max iterations in your loop script
MAX_ITERATIONS=3 # Stop after 3 attempts
# Add circuit breaker
if [ $iteration -ge $MAX_ITERATIONS ]; then
echo "Max iterations reached"
echo "Manual intervention required"
echo "Last error: $LAST_ERROR"
exit 1
fiSymptom: Broken code ends up in git despite hooks.
Causes:
- User ran
git commit --no-verify - Hook file not executable
- Hook path misconfigured
Solution:
# Verify hook is active
ls -la .git/hooks/pre-commit # Should be executable
# Check hook path
git config core.hooksPath # Should be empty or .git/hooks
# Add CI as final safety net (see CI/CD section)The same validation scripts used locally should run in CI. One source of truth.
# .github/workflows/validate.yml
name: Validate
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup
run: npm ci
- name: Run Validation
run: ./scripts/validation/check.sh
- name: Comment on PR Failure
if: failure() && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: 'Validation failed. Run `./scripts/validation/check.sh` locally to debug.'
})Require validation to pass before merge:
- Go to Settings > Branches > Branch protection rules
- Enable "Require status checks to pass"
- Select your validation workflow
Same scripts everywhere:
- Local development:
./scripts/validation/check.sh - Git hooks:
./scripts/validation/check.sh - CI/CD:
./scripts/validation/check.sh
No divergence. If CI fails, local will fail too.
| Benefit | Description |
|---|---|
| Zero broken presentations | Users only see working code |
| Faster iteration | Agent self-corrects before asking for help |
| Clean git history | Broken commits never enter the repository |
| Consistent quality | Same standards enforced everywhere |
| Reduced cognitive load | No manual validation steps to remember |
- Self-Review Reflection - Agent self-reviews before presenting work
- Multi-Agent Code Review - Parallel agent review before presentation