master
md 190 lines 8.25 KB
Rendered Raw
1 ---
2 name: sonarqube-audit
3 description: Triage SonarCloud findings (issues, hotspots, code smells, vulnerabilities) for this project — search what's open, mark False Positive / Won't Fix / Confirm / Safe / Acknowledged / Fixed, batch-mark whole rule families. Use when the user asks to "review Sonar findings", "triage SonarCloud", "mark False Positive on Sonar", or anything mentioning sonarqube/sonarcloud, S2259, S5008, code smells, security hotspots, or sonarcloud.io.
4 ---
5
6 # SonarCloud triage skill
7
8 This skill drives the SonarCloud Web API
9 (<https://docs.sonarsource.com/sonarcloud/api/>) to enumerate findings and apply
10 triage decisions: False Positive / Won't Fix / Confirmed for issues; Reviewed
11 with one of Safe / Acknowledged / Fixed for hotspots. Family-mode lets
12 you mark every open finding for a rule in one go.
13
14 The skill operates on the project configured in `.env` (see Setup). Scripts
15 auto-detect the repo root and write all artifacts under `<repo-root>/.local/`.
16
17 ## MANDATORY — keep this skill alive
18
19 **If you (the agent) discover a new pattern, gotcha, working flow, correction,
20 or any piece of knowledge while running this skill — update this `SKILL.md`
21 AND commit it BEFORE proceeding. Knowledge that isn't committed is lost.**
22
23 Examples of things to capture:
24 - New rule with a known FP pattern (and the exact comment to use)
25 - A bulk-FP family that's safe to apply project-wide
26 - A SonarCloud API quirk (rate limits, undocumented response shapes)
27 - A new path/issue exclusion that's safer than per-finding marking
28
29 ## Setup
30
31 ### .env entries
32
33 ```bash
34 # SonarCloud
35 SONAR_TOKEN='<paste your token from https://sonarcloud.io/account/security>'
36 SONAR_HOST_URL=https://sonarcloud.io
37 SONAR_PROJECT=<project_key, e.g. netdata_netdata>
38 SONAR_ORG=<organization_key, e.g. netdata>
39 ```
40
41 The token is used as **HTTP Basic auth username with empty password**:
42 `-u "$SONAR_TOKEN:"` (note the trailing colon).
43
44 No browser tab is required — token-based auth is stable across sessions.
45
46 ## Triage decision matrix
47
48 ### Issues (Bug, Vulnerability, Code Smell)
49
50 | Decision | API transition | When to use |
51 |--------------|-----------------|--------------------------------------------------------------------|
52 | Confirm | `confirm` | Sonar is right, we're going to fix it |
53 | Won't Fix | `wontfix` | Real but acceptable — won't fix (e.g., legacy code being deleted) |
54 | False Positive | `falsepositive` | Sonar is wrong (guard exists, unreachable, tool model error) |
55
56 ### Security Hotspots
57
58 Hotspots have a separate state machine. They go from `TO_REVIEW` to
59 `REVIEWED` with one of three resolutions:
60
61 | Resolution | When to use |
62 |---------------|---------------------------------------------------------------|
63 | `SAFE` | Hotspot reviewed, code is fine as-is (no risk in context) |
64 | `ACKNOWLEDGED`| Risk understood, no immediate action — leave for future review |
65 | `FIXED` | Hotspot reviewed and the code was changed to remove the risk |
66
67 ## ASCII-only comments — non-negotiable
68
69 `api.sonarcloud.io` sits behind Cloudflare, which rejects bodies containing
70 non-ASCII bytes (em-dashes, smart quotes) with a 403 challenge. The scripts
71 fail before the network round-trip if non-ASCII is detected.
72
73 - Use `--` instead of em-dash (U+2014).
74 - Use straight quotes `"` `'` instead of smart quotes.
75
76 ## Workflow
77
78 ### Step 1 — see what's open
79
80 ```
81 bash .agents/skills/sonarqube-audit/scripts/sonar-search.sh summary
82 ```
83
84 Prints per-rule counts of open issues + open hotspots. Use this to spot
85 high-volume rules that are candidates for family-mode bulk marking, and
86 project-wide quality-profile or exclusion changes.
87
88 ### Step 2 — search for specific rule's findings
89
90 Issues:
91 ```
92 bash .agents/skills/sonarqube-audit/scripts/sonar-search.sh issues --rule cpp:S5827
93 ```
94
95 Hotspots:
96 ```
97 bash .agents/skills/sonarqube-audit/scripts/sonar-search.sh hotspots --status=TO_REVIEW \
98 | jq '.hotspots[] | select(.ruleKey=="c:S5443")'
99 ```
100
101 ### Step 3 — triage
102
103 #### Single finding
104
105 ```
106 bash .agents/skills/sonarqube-audit/scripts/sonar-mark.sh fp <ISSUE_KEY> "<COMMENT>"
107 bash .agents/skills/sonarqube-audit/scripts/sonar-mark.sh wontfix <ISSUE_KEY> "<COMMENT>"
108 bash .agents/skills/sonarqube-audit/scripts/sonar-mark.sh confirm <ISSUE_KEY> "<COMMENT>"
109
110 bash .agents/skills/sonarqube-audit/scripts/sonar-mark.sh safe <HOTSPOT_KEY> "<COMMENT>"
111 bash .agents/skills/sonarqube-audit/scripts/sonar-mark.sh ack <HOTSPOT_KEY> "<COMMENT>"
112 bash .agents/skills/sonarqube-audit/scripts/sonar-mark.sh fixed <HOTSPOT_KEY> "<COMMENT>"
113 ```
114
115 #### Family mode (every open finding for a rule)
116
117 ```
118 bash .agents/skills/sonarqube-audit/scripts/sonar-mark.sh family-fp <RULE_ID> "<COMMENT>"
119 bash .agents/skills/sonarqube-audit/scripts/sonar-mark.sh family-safe <RULE_ID> "<COMMENT>"
120 ```
121
122 Family mode prints all matched keys and prompts before acting unless
123 `SONAR_MARK_YES=1` is set.
124
125 ### Step 4 — dry runs
126
127 ```
128 SONAR_DRY_RUN=1 bash .agents/skills/sonarqube-audit/scripts/sonar-mark.sh fp KEY "Comment"
129 ```
130
131 In dry-run mode, **write** API calls (mark issues, change hotspot status,
132 add comments) are printed but not executed. **Read** API calls (issue
133 search, hotspot search used to enumerate findings in family mode) still
134 run -- otherwise family mode could not show what it would have acted on.
135
136 ## What this skill does NOT do
137
138 - **Disable rules**: use `api/qualityprofiles/deactivate_rule` directly, or do
139 it in the SonarCloud UI under Quality Profiles.
140 - **Configure issue exclusions**: use Project Settings -> Analysis Scope ->
141 Issue Exclusions in the UI.
142 - **Rule-tuning audit**: when you want a per-rule KEEP/DISABLE/NARROW decision
143 log, document that separately (it's project-wide policy, not per-finding
144 triage).
145
146 ## Project-wide quality profile / exclusion configuration
147
148 Effective profile lookup:
149 ```
150 GET /api/qualityprofiles/search?project=$SONAR_PROJECT&organization=$SONAR_ORG
151 ```
152
153 To make project-wide changes (deactivate a rule or override severity):
154 1. Copy the inherited profile (`api/qualityprofiles/copy`)
155 2. Make your edits there
156 3. Assign the project to the new profile (`api/qualityprofiles/add_project`)
157
158 This is a one-shot operation per language. SonarCloud language keys are:
159 `c`, `cpp`, `go`, `javascript`, `py`, `shell`, `plsql`, `docker`, `css`,
160 `ipynb`, `php` (and others depending on the project). Note the rule-id
161 namespaces in `api/issues/search` results may differ from the language
162 keys -- e.g. shell rules use the `shelldre:` prefix, Go rules can use
163 either `go:` or `godre:` depending on which analyzer fired -- so the
164 language argument to qualityprofile APIs is the SHORT key (`shell`,
165 `go`), not the rule-namespace prefix.
166
167 Keep a record of profile decisions in a project-local doc under
168 `.local/audits/sonarqube/`.
169
170 ## Failure modes — quick diagnosis
171
172 | Symptom | Likely cause |
173 |----------------------------------------|-------------------------------------------------------------|
174 | HTTP 401 / 403 with HTML body | Token wrong/expired, or Cloudflare blocking non-ASCII |
175 | Token works for issues but not hotspots| Hotspot endpoints have separate auth checks — token must have `Browse` permission |
176 | Family-mode appears to stop at 500 | Outdated -- `sonar-mark.sh` family-mode now paginates transparently via `sq_paginate`. If you still see truncation, check `sq_paginate`'s array-key recognition list. |
177 | `falsepositive` transition rejected | Issue is not in `OPEN` or `CONFIRMED` state — check current status |
178 | Hotspot transition rejected | Hotspot already in `REVIEWED` state — re-check before retry |
179
180 ## Recurring tips
181
182 - `api/issues/search` is paged at `ps=500` max. The `sq_paginate` helper
183 in `_lib.sh` walks every page until `paging.total`; use it from any
184 new script instead of re-implementing the loop.
185 - Hotspot `ruleKey` filtering is client-side (search only filters by
186 status/project), so the family-mode helper does it in Python.
187 - An issue may be transitioned only between certain states; if you get
188 "Cannot do transition from STATUS X to Y", it's already past that state.
189 - `SONAR_DRY_RUN=1` is the right knob when iterating on comments
190 before committing to a bulk operation.