Feedback Loops Services
Complete feedback loop automation for bug discovery with regression test generation, fix verification, and ROI tracking.
Overview
The feedback loops package provides three services that close the bug discovery lifecycle:
- RegressionTestGenerator: Convert BugReports to reproducible pytest test files
- BugFixVerifier: Monitor GitHub Issues, re-run tests, auto-close verified fixes
- ROITracker: Track ROI metrics and demonstrate business value
RegressionTestGenerator
Converts discovered bugs into permanent regression tests.
Usage
from tests.bug_discovery.feedback_loops import RegressionTestGenerator
generator = RegressionTestGenerator()
# Generate test from single bug
test_path = generator.generate_test_from_bug(bug_report)
print(f"Generated: {test_path}")
# Generate tests from bug list
test_paths = generator.generate_tests_from_bug_list(bug_reports)
print(f"Generated {len(test_paths)} tests")
# Archive test for verified fix
archived_path = generator.archive_test(test_path, reason="verified")
Templates
RegressionTestGenerator uses Jinja2 templates for each discovery method:
pytest_regression_template.py.j2: Base templatefuzzing_regression_template.py.j2: Fuzzing-specific testschaos_regression_template.py.j2: Chaos engineering testsproperty_regression_template.py.j2: Property-based testsbrowser_regression_template.py.j2: Browser discovery tests
Archival Strategy
Tests are moved to archived/ subdirectory when:
- Bug fix is verified (2 consecutive test passes)
- GitHub issue is closed
Retention policy:
- Critical severity: Indefinite
- High severity: 1 year
- Medium/Low severity: 90 days
BugFixVerifier
Automatically verifies bug fixes by re-running regression tests.
Usage
from tests.bug_discovery.feedback_loops import BugFixVerifier
verifier = BugFixVerifier(
github_token=os.getenv("GITHUB_TOKEN"),
github_repository=os.getenv("GITHUB_REPOSITORY")
)
# Verify all fixes labeled in last 24 hours
results = verifier.verify_fixes(label="fix", hours_ago=24)
for result in results:
if result["issue_closed"]:
print(f"Issue #{result['issue_number']}: CLOSED ✅")
elif result["test_passed"]:
print(f"Issue #{result['issue_number']}: PENDING ({result['consecutive_passes']}/2 passes)")
else:
print(f"Issue #{result['issue_number']}: FAILED ❌")
Verification Workflow
- Poll GitHub Issues for "fix" label
- Extract bug_id from issue title/body
- Find associated regression test file
- Re-run test via subprocess pytest
- If passes: Increment consecutive pass counter
- If 2 consecutive passes: Add success comment, close issue
- If fails: Reset counter, add failure comment
Consecutive Passes
Requires 2 consecutive test passes before closing to prevent flaky test false positives.
State tracked in .verification_state.json:
{
"issue_123": {
"bug_id": "abc123de",
"consecutive_passes": 1,
"last_passed": "2026-03-25T10:00:00Z"
}
}
ROITracker
Tracks ROI metrics for bug discovery automation.
Usage
from tests.bug_discovery.feedback_loops import ROITracker
tracker = ROITracker()
# Record discovery run
tracker.record_discovery_run(
bugs_found=42,
unique_bugs=35,
filed_bugs=30,
duration_seconds=3600,
by_method={"fuzzing": 20, "chaos": 10, "property": 8, "browser": 4},
by_severity={"critical": 2, "high": 10, "medium": 15, "low": 15}
)
# Record bug fixes
tracker.record_fixes(
bug_ids=["abc123", "def456"],
issue_numbers=[123, 124],
filed_dates=["2026-03-20T10:00:00Z", "2026-03-21T14:00:00Z"],
fix_duration_hours=8.0
)
# Generate ROI report
roi_report = tracker.generate_roi_report(weeks=4)
print(f"Hours Saved: {roi_report['hours_saved']:.0f}h")
print(f"Cost Saved: ${roi_report['cost_saved']:,.0f}")
print(f"Bugs Prevented: {roi_report['bugs_prevented']}")
print(f"ROI: {roi_report['roi_ratio']:.1f}x")
# Save weekly summary
tracker.save_weekly_summary(roi_report)
# Get weekly trends for charts
trends = tracker.get_weekly_trends(weeks=12)
for week in trends:
print(f"{week['week_start']}: {week['bugs_found']} bugs")
Cost Assumptions
Default cost assumptions (configurable via __init__):
| Assumption | Default | Description |
|---|---|---|
manual_qa_hourly_rate |
$75/hour | Cost of manual QA labor |
developer_hourly_rate |
$100/hour | Cost of developer time |
bug_production_cost |
$10,000 | Average cost of production bug |
manual_qa_hours_per_bug |
2 hours | Hours to manually find/report bug |
ROI Calculation
Manual QA Cost = bugs_found × 2 hours × $75 = $150 × bugs_found
Automation Cost = (duration_seconds / 3600) × $100
Cost Saved = Manual QA Cost - Automation Cost
Bugs Prevented = bugs_found × 10% × $10,000
Total Savings = Cost Saved + Bugs Prevented
ROI Ratio = Total Savings / Automation Cost
Database Schema
-- Discovery runs
CREATE TABLE discovery_runs (
id INTEGER PRIMARY KEY,
timestamp TEXT,
bugs_found INTEGER,
unique_bugs INTEGER,
filed_bugs INTEGER,
duration_seconds REAL,
by_method TEXT, -- JSON
by_severity TEXT, -- JSON
automation_cost REAL
);
-- Bug fixes
CREATE TABLE bug_fixes (
id INTEGER PRIMARY KEY,
bug_id TEXT,
issue_number INTEGER,
filed_at TEXT,
fixed_at TEXT,
fix_duration_hours REAL,
severity TEXT,
discovery_method TEXT
);
-- ROI summary (aggregated weekly)
CREATE TABLE roi_summary (
id INTEGER PRIMARY KEY,
week_start TEXT UNIQUE,
bugs_found INTEGER,
bugs_fixed INTEGER,
hours_saved REAL,
cost_saved REAL,
automation_cost REAL,
roi REAL,
bugs_prevented INTEGER,
cost_avoidance REAL,
total_savings REAL,
created_at TEXT
);
Integration Example
Complete feedback loop integration:
from tests.bug_discovery.core import DiscoveryCoordinator
from tests.bug_discovery.feedback_loops import BugFixVerifier, ROITracker
import os
# 1. Run discovery with feedback loops
coordinator = DiscoveryCoordinator(
github_token=os.getenv("GITHUB_TOKEN"),
github_repository=os.getenv("GITHUB_REPOSITORY"),
enable_regression_tests=True,
enable_roi_tracking=True
)
result = coordinator.run_full_discovery(duration_seconds=3600)
print(f"Bugs found: {result['bugs_found']}")
print(f"Regression tests: {len(result['regression_tests'])}")
print(f"ROI: {result['roi_data']['roi_ratio']:.1f}x")
# 2. Later, verify fixes
verifier = BugFixVerifier(
github_token=os.getenv("GITHUB_TOKEN"),
github_repository=os.getenv("GITHUB_REPOSITORY")
)
verification_results = verifier.verify_fixes()
# 3. Generate ROI report
roi_report = coordinator.get_roi_report(weeks=4)
weekly_trends = coordinator.get_weekly_trends(weeks=12)
Testing
Unit tests for all feedback loop services:
# RegressionTestGenerator tests
pytest backend/tests/bug_discovery/feedback_loops/tests/test_regression_test_generator.py -v
# BugFixVerifier tests
pytest backend/tests/bug_discovery/feedback_loops/tests/test_bug_fix_verifier.py -v
# ROITracker tests
pytest backend/tests/bug_discovery/feedback_loops/tests/test_roi_tracker.py -v
# Dashboard enhancement tests
pytest backend/tests/bug_discovery/feedback_loops/tests/test_dashboard_enhancements.py -v
Configuration
Environment Variables
# GitHub Integration (BugFixVerifier)
GITHUB_TOKEN=ghp_xxx
GITHUB_REPOSITORY=owner/repo
# Cost Assumptions (ROITracker)
MANUAL_QA_HOURLY_RATE=75
DEVELOPER_HOURLY_RATE=100
BUG_PRODUCTION_COST=10000
MANUAL_QA_HOURS_PER_BUG=2
File Locations
# Templates
backend/tests/bug_discovery/templates/*.j2
# Regression tests
backend/tests/bug_discovery/storage/regression_tests/test_regression_*.py
backend/tests/bug_discovery/storage/regression_tests/archived/
# Metrics database
backend/tests/bug_discovery/storage/metrics.db
# Verification state
backend/tests/bug_discovery/storage/regression_tests/.verification_state.json
Best Practices
- Review generated tests: Auto-generated tests are minimal - review and enhance
- Archive verified fixes: Keep regression tests directory clean by archiving
- Validate ROI assumptions: Review cost assumptions with finance team quarterly
- Monitor false positives: Track false positive rate, adjust verification threshold if >5%
Troubleshooting
Regression test generation fails
# Check templates directory
ls backend/tests/bug_discovery/templates/
# Verify BugReport has error_signature
python -c "from tests.bug_discovery.models import BugReport; b = BugReport(...); print(b.error_signature)"
Bug fix verification not running
# Check GitHub token has repo scope
gh auth status
# Verify "fix" label exists
gh label list
ROI metrics seem inflated
# Review cost assumptions
python -c "from tests.bug_discovery.feedback_loops import ROITracker; t = ROITracker(); print(t.manual_qa_hourly_rate)"
# Adjust based on actual project costs
tracker = ROITracker(manual_qa_hourly_rate=50, developer_hourly_rate=80)