13 KiB
Regression Prevention Protocol
Comprehensive guide to preventing bug reintroduction using the failure registry and prevention rules.
Related: AGENT_GUARDRAILS.md | AGENT_EXECUTION.md | AGENT_REVIEW_PROTOCOL.md
Overview
The Regression Prevention System ensures that once a bug is fixed, it stays fixed. It consists of:
- Failure Registry - Append-only log of all bugs
- Prevention Rules - Automated pattern detection
- Pre-Work Checks - Mandatory verification before editing
- Regression Tests - Permanent tests for fixed bugs
- CI Integration - Automated enforcement
Core Philosophy
┌─────────────────────────────────────────────────────────────┐
│ REGRESSION PREVENTION MANDATE │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. Every bug is a learning opportunity │
│ 2. Every fix must be documented │
│ 3. Every pattern must be prevented │
│ 4. Every edit must be checked │
│ 5. Every fix must have a regression test │
│ │
└─────────────────────────────────────────────────────────────┘
Failure Registry
Location
.guardrails/failure-registry.jsonl
Format
Each line is a JSON object:
{
"failure_id": "FAIL-abc123de",
"timestamp": "2026-02-07T10:00:00Z",
"category": "runtime",
"severity": "high",
"error_message": "TypeError: Cannot read property of undefined",
"root_cause": "Missing null check after JSON.parse",
"affected_files": ["src/parser.js"],
"fix_commit": "a1b2c3d4",
"regression_pattern": "JSON\\.parse\\(.*\\)\\.\\w+",
"prevention_rule": "Always null-check parsed JSON before property access",
"status": "active"
}
Categories
| Category | Description | Example |
|---|---|---|
build |
Build/compilation errors | Missing import, syntax error |
runtime |
Runtime exceptions | Null pointer, undefined access |
test |
Test failures | Assertion errors, timeouts |
type |
Type system errors | Type mismatches, inference failures |
lint |
Style/lint violations | ESLint, pylint errors |
deploy |
Deployment failures | CI/CD errors, publish failures |
config |
Configuration errors | Missing env vars, invalid config |
regression |
Reintroduced bugs | Previously fixed bugs that returned |
Severity Levels
| Level | Impact | Response Time |
|---|---|---|
critical |
System down, data loss | Immediate |
high |
Major feature broken | Within 4 hours |
medium |
Minor feature issue | Within 24 hours |
low |
Cosmetic, non-blocking | Next sprint |
Using the Registry
Log a New Failure
Interactive mode (recommended):
python scripts/log_failure.py --interactive
Quick entry from error message:
python scripts/log_failure.py \
--from-error "TypeError: Cannot read property 'x' of undefined" \
--category runtime \
--severity high \
--root-cause "Missing null check" \
--affected-files src/parser.js \
--fix-commit abc1234
List Failures
All active failures:
python scripts/log_failure.py --list
Filtered by category:
python scripts/log_failure.py --list | grep runtime
View Specific Failure
python scripts/log_failure.py --show FAIL-abc123de
Update Status
Mark as resolved:
python scripts/log_failure.py --resolve FAIL-abc123de
Mark as deprecated (no longer relevant):
python scripts/log_failure.py --deprecate FAIL-abc123de
Prevention Rules
Location
.guardrails/prevention-rules/
├── pattern-rules.json # Regex-based rules
└── semantic-rules.json # AST-based rules
Pattern Rules
Detect problematic code patterns using regex:
{
"rule_id": "PREVENT-001",
"failure_id": "FAIL-abc123de",
"name": "Null check after async parse",
"enabled": true,
"pattern": "JSON\\.parse\\(.*\\)\\s*\\.\\w+",
"forbidden_context": "without.*null.*check",
"message": "Previous bug: Direct property access on JSON.parse without null check",
"severity": "error",
"file_glob": ["*.js", "*.ts"],
"suggestion": "Add null check: const data = JSON.parse(...); if (data) { ... }"
}
Semantic Rules
Detect issues using AST analysis:
{
"rule_id": "SEMANTIC-001",
"failure_id": "FAIL-def567gh",
"name": "Unhandled promise rejection",
"enabled": true,
"language": "javascript",
"ast_pattern": {
"type": "CallExpression",
"callee": {
"type": "MemberExpression",
"property": { "name": "then" }
},
"missing": "catch"
},
"message": "Promise chain missing .catch() handler",
"severity": "warning"
}
Enabling/Disabling Rules
Edit the rule file and set enabled: true/false.
Never delete rules - only disable them. History is important.
Pre-Work Check Protocol
MANDATORY: Before ANY File Edit
Step 1: Read Pre-Work Check Document
cat .guardrails/pre-work-check.md
Step 2: Run Regression Check
python scripts/regression_check.py --all
Step 3: Check Registry for Your Files
python scripts/log_failure.py --list | grep <your-file>
Step 4: Verify Understanding
- I know what bugs have been fixed in these files
- I understand the patterns that caused them
- I will not reintroduce these patterns
During Development
Run regression check frequently:
# After making changes
python scripts/regression_check.py --unstaged
Before Commit
Final verification:
python scripts/regression_check.py --staged
Regression Testing Requirements
Every Bug Fix MUST Include:
- The fix itself (production code)
- A regression test (test code)
- A registry entry (documentation)
Regression Test Location
tests/regression/
├── test_<module>_regression_<failure_id>.py
└── README.md
Regression Test Template
"""
Regression test for FAILURE-ID: FAIL-abc123de
Bug: Brief description of what was broken
Fix: Brief description of how it was fixed
"""
import unittest
class TestParserRegressionFAILabc123de(unittest.TestCase):
"""
Test that null check regression doesn't reoccur.
Original bug: JSON.parse result accessed without null check
caused TypeError when input was invalid JSON.
"""
def test_json_parse_with_null_input(self):
"""Should handle null result from JSON.parse gracefully."""
# This test should fail with the buggy code, pass with the fix
from src.parser import parse_json
with self.assertRaises(ValueError) as ctx:
parse_json("invalid json")
self.assertIn("Invalid JSON", str(ctx.exception))
def test_json_parse_with_valid_input(self):
"""Should work normally with valid JSON."""
from src.parser import parse_json
result = parse_json('{"key": "value"}')
self.assertEqual(result["key"], "value")
Regression Test Naming Convention
test_<module>_regression_<failure_id>.py
Examples:
- test_parser_regression_FAIL_abc123de.py
- test_api_regression_FAIL_def456gh.py
- test_config_regression_FAIL_ghi789jk.py
Regression Test Docstring Requirements
Every regression test MUST include:
- The failure_id
- Brief bug description
- Brief fix description
- Link to the registry entry
CI/CD Integration
GitHub Action
The regression guard runs on every PR:
# .github/workflows/regression-guard.yml
# See full file in repository
What It Checks
- Diff Analysis - Scans PR diff against prevention rules
- File History - Warns if modifying files with known bugs
- Test Requirements - Requires regression tests for bug fixes
- Pattern Matching - Fails if known bad patterns detected
Pre-Commit Hook
Add to .git/hooks/pre-commit:
#!/bin/bash
# Regression check pre-commit hook
echo "Running regression check..."
python scripts/regression_check.py --staged --pre-commit
if [ $? -ne 0 ]; then
echo ""
echo "Potential regressions detected!"
echo "Review the output above or use --no-verify to skip (not recommended)"
exit 1
fi
Make it executable:
chmod +x .git/hooks/pre-commit
Review Protocol
For Authors
Before requesting review:
- Regression check passes (
python scripts/regression_check.py --staged) - All bug fixes have regression tests
- Registry entries created for new bugs
- No previous fixes were undone
For Reviewers
Checklist:
- Changes don't match known bug patterns
- Files with active failures reviewed carefully
- Regression tests exist for bug fixes
- Prevention rules updated if needed
Common Scenarios
Scenario 1: Fixing a New Bug
- Fix the bug
- Create regression test
- Log in registry:
python scripts/log_failure.py --interactive - Consider adding prevention rule
- Commit with
fix:prefix
Scenario 2: Modifying File with Known Bugs
- Read registry entries for the file
- Understand what was fixed before
- Run regression check before editing
- Be extra careful with similar patterns
- Verify your changes don't undo fixes
Scenario 3: Bug Reintroduced
- Don't panic - this is why we have the system
- Fix it again (with better understanding)
- Update registry entry:
- Increase severity
- Update regression_pattern
- Add prevention rule if missing
- Strengthen regression test
- Review why check didn't catch it
Scenario 4: False Positive
- Verify it's truly a false positive
- Update rule to exclude valid cases:
- Add
forbidden_contextpattern - Refine regex
- Disable rule if necessary
- Add
- Document the decision
Metrics and Success Criteria
System Health Metrics
Track these monthly:
| Metric | Target | Measurement |
|---|---|---|
| Registry Coverage | 100% | % of bugs logged |
| Regression Rate | 0% | Bugs reintroduced / total bugs |
| Prevention Rate | >90% | Issues caught by automation |
| Check Adoption | 100% | % of edits with pre-check |
Quality Indicators
Healthy system:
- Zero regressions of registered bugs
- All bug fixes include regression tests
- Prevention rules catch issues pre-commit
- CI catches issues pre-merge
Warning signs:
- Same bug fixed multiple times
- Registry entries without regression tests
- Skipped pre-work checks
- Disabled rules without justification
Best Practices
DO
✓ Log every bug to the registry ✓ Write regression tests for every fix ✓ Run regression check before committing ✓ Update prevention rules when patterns emerge ✓ Review registry before modifying files ✓ Mark bugs resolved when appropriate
DON'T
✗ Delete registry entries (mark deprecated instead) ✗ Skip pre-work checks ✗ Disable rules without documenting why ✗ Write vague prevention rules ✗ Forget to add regression tests ✗ Assume "I won't make that mistake again"
Troubleshooting
Regression check is too slow
- Use
--stagedinstead of--all - Disable expensive semantic rules
- Run only on changed files
Too many false positives
- Refine regex patterns
- Add
forbidden_contextexceptions - Update rules to be more specific
Registry is too large
- Mark old entries as deprecated
- Archive entries older than 2 years
- Focus on patterns, not every instance
Team isn't using it
- Add to CI as mandatory check
- Include in code review checklist
- Share regression success stories
- Make it part of onboarding
Quick Reference
# Before work
cat .guardrails/pre-work-check.md
python scripts/regression_check.py --all
# During work
python scripts/regression_check.py --unstaged
# Before commit
python scripts/regression_check.py --staged
# Log new bug
python scripts/log_failure.py --interactive
# List bugs
python scripts/log_failure.py --list
# Resolve bug
python scripts/log_failure.py --resolve FAIL-xxx
Related Documents:
- AGENT_GUARDRAILS.md - Core safety protocols
- AGENT_EXECUTION.md - Execution protocol
- AGENT_REVIEW_PROTOCOL.md - Review checklist
- TESTING_VALIDATION.md - Testing requirements
Last Updated: 2026-02-07 Version: 1.0 Document Owner: Project Maintainers