Quality Gate Checker
Goal: Validate code quality against thresholds: coverage ≥70%, complexity ≤10, linting clean, no dead code
Description
Validates code against quality thresholds from config/quality-gates.yaml. Checks test coverage, cyclomatic complexity, linting errors, dead code, and documentation. Attempts auto-fix for linting issues (max 3 attempts), then escalates to human if failures persist.
Usage
- •"Run quality gate checks on [files]"
- •"Validate code quality"
- •"Check coverage and complexity"
When to Use
- •After tdd-implementer completes implementation
- •Before code review
- •Verify quality thresholds before deployment
Pipeline Contract (sdlc-tdd-full.lobster)
Inputs:
- •
files(JSON array): Implementation files to check - •
config(string): Path to quality-gates.yaml (default: config/quality-gates.yaml)
Output: JSON with structure:
{
"status": "PASS",
"coverage": {
"line_percent": 82,
"branch_percent": 75,
"threshold": 70,
"result": "PASS"
},
"complexity": {
"max_per_function": 8,
"threshold": 10,
"violations": [],
"result": "PASS"
},
"linting": {
"errors": 0,
"warnings": 2,
"result": "PASS"
},
"dead_code": {
"found": 0,
"result": "PASS"
},
"documentation": {
"missing_docstrings": 0,
"result": "PASS"
},
"blocking_failures": [],
"warnings": ["File profile.py is 215 lines (recommend < 200)"],
"auto_fix_attempts": 0
}
Implementation
Execute in order. Do not run Lobster or any pipeline.
Step 1: Load Configuration
- •Read thresholds from config/quality-gates.yaml
- •Parse: coverage.minimum_line_coverage (70%), complexity.cyclomatic_complexity.max_per_function (10)
- •Parse: agent_behavior.max_auto_fix_attempts (3)
Step 2: Detect Language
- •Scan files to determine language (Python vs JavaScript/TypeScript)
- •Use file extensions (.py, .js, .ts) or check for language-specific files
- •Select appropriate tools for detected language
Step 3: Coverage Check
Python:
pytest --cov=src --cov=api --cov-report=json --cov-report=term
- •Parse coverage.json: line_percent, branch_percent
- •FAIL if line_percent < 70 (blocking)
JavaScript:
npm test -- --coverage --coverageReporters=json --coverageReporters=text
- •Parse coverage/coverage-summary.json: lines.pct, branches.pct
- •FAIL if lines.pct < 70 (blocking)
Output:
{
"line_percent": 82,
"branch_percent": 75,
"threshold": 70,
"result": "PASS",
"uncovered_lines": ["api/endpoints/profile.py:42-45"]
}
Step 4: Complexity Check
Python (radon):
radon cc src/ api/ -j --min C
- •Parse JSON output: function_name, complexity score
- •FAIL if any function > 10 (blocking)
- •WARN if any function > 7
JavaScript (ESLint):
eslint src/ --rule 'complexity: ["error", 10]' -f json
- •Parse JSON: function complexity
- •FAIL if any > 10
Output:
{
"max_per_function": 8,
"threshold": 10,
"violations": [],
"hotspots": [
{"function": "process_payment", "complexity": 8, "file": "api/payments.py", "line": 42}
],
"result": "PASS"
}
Step 5: Linting Check
Python (ruff):
ruff check src/ api/ --format json
- •Parse JSON: errors, warnings
- •FAIL if errors > 0 (blocking)
- •WARN if warnings > 5
JavaScript (ESLint):
eslint src/ -f json
- •Parse JSON: errorCount, warningCount
- •FAIL if errorCount > 0
Output:
{
"errors": 0,
"warnings": 2,
"result": "PASS",
"issues": [
{"file": "api/profile.py", "line": 42, "rule": "line-too-long", "severity": "warning"}
]
}
Step 6: Dead Code Check
Python (vulture):
vulture src/ api/ --min-confidence 80
- •Report unused functions, variables, imports
- •WARN if found (non-blocking)
JavaScript (ESLint no-unused-vars):
eslint src/ --rule 'no-unused-vars: error' -f json
Output:
{
"found": 0,
"result": "PASS",
"unused_items": []
}
Step 7: Documentation Check
Python:
- •Check for docstrings in public functions (not starting with _)
- •Parse AST to find functions without docstrings
- •WARN if missing (non-blocking)
JavaScript:
- •Check for JSDoc comments on exported functions
- •WARN if missing
Output:
{
"missing_docstrings": 0,
"result": "PASS",
"functions_without_docs": []
}
Step 8: Aggregate Results
Determine overall status:
- •PASS: No blocking failures
- •FAIL: Any of:
- •coverage < 70%
- •complexity > 10
- •linting errors > 0
Collect blocking_failures array:
{
"blocking_failures": [
"Coverage 65% below threshold 70%",
"Function process_payment has complexity 12 (limit 10)"
]
}
Step 9: Auto-Fix (If Failures)
If status = "FAIL" and auto_fix_enabled = true:
Attempt 1:
# Python ruff check --fix src/ api/ # JavaScript eslint src/ --fix
Re-run quality checks after fix.
Attempt 2 (if still failing):
- •Try more aggressive fixes
- •Simplify complex functions (extract methods)
- •Add missing tests for coverage
Attempt 3 (if still failing):
- •Last attempt at automated fixes
- •Re-run all checks
If still failing after 3 attempts:
- •Set status = "FAIL"
- •Set auto_fix_attempts = 3
- •Escalate to human with specific failure details
Step 10: Output Results
Generate JSON with:
- •status: PASS or FAIL
- •coverage, complexity, linting, dead_code, documentation objects
- •blocking_failures: Array of critical issues (empty if PASS)
- •warnings: Array of non-blocking issues
- •auto_fix_attempts: Number of fix attempts made
Output Format
Markdown summary + JSON block for pipeline consumption:
# Quality Gate Report
## Summary
**Status**: ✅ PASS
## Coverage
✅ **Line Coverage**: 82% (threshold: 70%)
✅ **Branch Coverage**: 75% (threshold: 65%)
Uncovered lines:
- None
## Complexity
✅ **Max Complexity**: 8/function (limit: 10)
Complexity hotspots (for awareness):
- `process_payment()` in api/payments.py:42 - complexity 8
## Linting
✅ **Errors**: 0
⚠️ **Warnings**: 2
Warnings:
- api/profile.py:42 - Line too long (88 > 80 characters)
- api/profile.py:105 - Missing trailing comma
## Dead Code
✅ **Unused Code**: None found
## Documentation
✅ **Docstrings**: All public functions documented
## Auto-Fix
- Auto-fix attempts: 0 (no fixes needed)
## Blocking Failures
None - Quality gate PASSED ✅
## Warnings (Non-Blocking)
- File api/profile.py is 215 lines (recommend < 200)
- Consider splitting into smaller modules
```json
{
"status": "PASS",
"coverage": {
"line_percent": 82,
"branch_percent": 75,
"threshold": 70,
"result": "PASS"
},
"complexity": {
"max_per_function": 8,
"threshold": 10,
"violations": [],
"result": "PASS"
},
"linting": {
"errors": 0,
"warnings": 2,
"result": "PASS"
},
"dead_code": {
"found": 0,
"result": "PASS"
},
"documentation": {
"missing_docstrings": 0,
"result": "PASS"
},
"blocking_failures": [],
"warnings": ["File profile.py is 215 lines (recommend < 200)"],
"auto_fix_attempts": 0
}
## Notes - Blocking failures prevent proceeding to code review - Auto-fix attempts max 3 times (avoid infinite loops) - Warnings are informational, don't block pipeline - Coverage threshold 70% is minimum; target 80%+ for critical code - Complexity limit 10 follows industry standards (SonarQube, Code Climate) - Run checks on implementation files only (not tests, migrations)