Context
Static-defect analyzer for the review-enrichment service (REES). Depends on the scaffold. The engine reasons but runs no tools; REES runs real linters/SAST on the diff by detected language plus cyclomatic-complexity + churn hotspots.
Requirements
- By detected language over the request diff/files: eslint (TS/JS), ruff (Python), golangci-lint (Go), and semgrep rulesets where applicable. Plus cyclomatic-complexity + churn hotspots.
- Respect the per-repo
enrichment.static.maxFindings cap (default e.g. 25) so the brief stays bounded.
- Own sub-budget; a slow/failed tool degrades independently (
analyzerStatus.static:'degraded', partial:true).
- Bake the chosen deterministic toolchain into the runtime image (pin versions); prefer language detection so only the needed tools run.
Deliverables
review-enrichment/src/analyzers/static-analysis.ts: lint/semgrep over the diff + complexity → static findings [{ file, line, rule, severity, message }] and complexity [{ file, function, cyclomatic, churn }].
- Register in
brief.ts (gated by enrichment.analyzers + static.maxFindings), render in render.ts, add static to analyzerStatus. Update the Dockerfile to bake/pin the toolchain.
Acceptance criteria
- A diff with a lintable defect (e.g.
no-floating-promises) and a high-complexity function produce the expected findings; clean code produces none.
maxFindings truncates the list; the cap is configurable per repo.
- Tool timeout/missing-language degrades that analyzer only. Unit tests cover language detection, the cap, and the degrade path.
npm audit --audit-level=moderate clean.
Parent: #1029
Context
Static-defect analyzer for the review-enrichment service (REES). Depends on the scaffold. The engine reasons but runs no tools; REES runs real linters/SAST on the diff by detected language plus cyclomatic-complexity + churn hotspots.
Requirements
enrichment.static.maxFindingscap (default e.g. 25) so the brief stays bounded.analyzerStatus.static:'degraded',partial:true).Deliverables
review-enrichment/src/analyzers/static-analysis.ts: lint/semgrep over the diff + complexity →staticfindings[{ file, line, rule, severity, message }]andcomplexity[{ file, function, cyclomatic, churn }].brief.ts(gated byenrichment.analyzers+static.maxFindings), render inrender.ts, addstatictoanalyzerStatus. Update the Dockerfile to bake/pin the toolchain.Acceptance criteria
no-floating-promises) and a high-complexity function produce the expected findings; clean code produces none.maxFindingstruncates the list; the cap is configurable per repo.npm audit --audit-level=moderateclean.Parent: #1029