feat: inline suppression (# codelens-ignore) — closes #50#75
Conversation
Adds cross-language inline suppression annotations to CodeLens. ## New files - scripts/suppression.py: detect_suppression(), SuppressionInfo dataclass, apply_suppressions(), update_stats_with_suppressions() - tests/test_suppression.py: 67 test cases (12 languages × 3+ cases each) ## Modified files - scripts/formatters/sarif.py: populate SARIF suppressions field per spec - scripts/codelens.py: 2 new CLI flags (--codelens-ignore-pattern, --disable-suppression), post-processing hook before format_output ## Features - 3 keyword aliases: codelens-ignore, nolens, nosemgrep - Syntax: // codelens-ignore, // codelens-ignore: rule-id -- reason, // codelens-ignore-next: rule-id - 12 languages: Python, JS, TS, Rust, Go, Java, C, C++, Ruby, PHP, HTML, CSS - Suppressed findings remain in output with status: suppressed - SARIF suppressions field populated (kind: inSource, justification) - Count pipeline audited: stats.suppressed_count added, total stays as total (includes suppressed) — prevents UBS bug #51 pattern
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Review - APPROVEReviewed full diff (4 files, +1200/-0). Comprehensive implementation that meets issue #50 spec. Strengths
Minor concerns (non-blocking)
VerdictMerging. Comprehensive, well-tested (68 cases), SARIF compliant, addresses UBS bug #51. Minor concerns can be follow-ups. Reviewed by BOS (orchestrate-workers skill) - diff read in full before approval. |
|



Summary
Adds cross-language inline suppression annotations (
# codelens-ignore,// codelens-ignore,/* codelens-ignore */,<!-- codelens-ignore -->) to CodeLens. Suppressed findings remain in output withstatus: "suppressed"for auditability. SARIFsuppressionsfield populated per spec.Closes #50
Why
Three independent worker reports (UBS, Opengrep, Semgrep) converged on the same proposal: inline suppression with
# codelens-ignoresyntax. This is critical for production adoption in large codebases with false positives — currently users must disable rules entirely or filter via CLI, both of which are blunt instruments.UBS specifically warns: audit ALL count pipelines because UBS bug #51 showed 21 bypass patterns were missed in v5.3.0. This PR addresses that by:
stats.suppressed_countto all enginesstats.total_findingsas the true total (includes suppressed)What changed
New files
scripts/suppression.py(460 lines) — Core suppression module:SuppressionInfodataclass:rule_ids,reason,is_next_line,keyworddetect_suppression(comment_text, keyword_pattern)→Optional[SuppressionInfo]apply_suppressions(findings, source_files, keyword_pattern)→ findings withsuppressed/suppressed_rules/suppressed_reasonfields setupdate_stats_with_suppressions(result)→ addsstats.suppressed_count//inside string literals)tests/test_suppression.py(600+ lines, 67 test cases):codelens rule-validate,codelens rule-test) #51 pattern)Modified files
scripts/formatters/sarif.py— Populatesuppressionsfield per SARIF v2.1.0 spec:kind: "inSource"for inline suppressionsjustificationfrom suppression reasonkind: "informational"on suppressed resultsscripts/codelens.py— 2 new CLI flags + post-processing hook:--codelens-ignore-pattern <regex>(default:codelens-ignore|nolens|nosemgrep)--disable-suppression(strict CI mode — skips suppression processing)format_output(), runsapply_suppressions()+update_stats_with_suppressions()Syntax variants (all working)
Supported languages (12)
Python (
#), JavaScript (//,/*), TypeScript (//,/*), Rust (//,/*), Go (//,/*), Java (//,/*), C (//,/*), C++ (//,/*), Ruby (#), PHP (#,//,/*), HTML (<!--), CSS (/*)Test results
Manual test demo
Before (no suppression — finding is active):
$ python3 scripts/codelens.py smell fixtures/smell_test.py --format json { "findings": [ {"line": 5, "category": "long_fn", "severity": "high", "suppressed": false} ], "stats": {"total_findings": 1, "suppressed_count": 0} }After (with
# codelens-ignore— finding is suppressed but still visible):$ python3 scripts/codelens.py smell fixtures/smell_test.py --format json { "findings": [ {"line": 5, "category": "long_fn", "severity": "high", "suppressed": true, "suppressed_rules": ["long_fn"], "suppressed_reason": "acceptable in tests"} ], "stats": {"total_findings": 1, "suppressed_count": 1} }SARIF output (suppressions field populated):
{ "ruleId": "codelens/smell/long-function", "level": "error", "kind": "informational", "suppressions": [{ "kind": "inSource", "justification": "acceptable in tests" }] }Count pipeline audit (UBS bug #51 pattern)
stats.total_findingsstats.suppressed_counttotal_findings(misleading)total_findings - suppressed_countThis ensures suppressed findings are never silently missed in count pipelines.
Found but not fixed (out of scope)
scripts/smell_engine.py:390—total_findingsis computed before suppression is applied (correct behavior — suppression is in output layer, not engine layer)scripts/secrets_engine.py:1433—_compute_stats()doesn't havesuppressed_countfield (fixed byupdate_stats_with_suppressions()in post-processing)