tts-voice-creator-clone-and.../architecture/sonar-triage.md
mARTin-B78 9baa8ad5ba docs(qa): sonar-fixer moves finished multica issues to Done
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 04:05:12 +02:00

5.5 KiB

SonarQube triage loop

Local script scripts/sonar_triage.mjs (npm run sonar:triage). Dry-run by default; nothing is pushed, ever.

SonarQube /api/issues/search (GET, paged, OPEN/CONFIRMED/REOPENED)
        |
   classify  --skip-list--> SKIPPED (reported only)
        |
   +----+-----------------------------+
 SMALL                         MEDIUM / LARGE
   |  (--apply --fix-small)          |  (--apply)
 task file -> `claude -p`      group by rule (<=40 locations) -> `gh issue create`
 -> ONE local commit           (labels sonar, agent-fix; dedupe marker)
 `fix(sonar): ...`                   |
                               `multica issue create --assignee sonar-fixer`
                               -> agent fixes, local commit only

Classification

  • SMALL: severity INFO/MINOR (or MAJOR with effort <= 5 min) AND rule in scripts/sonar_triage.rules.json AND file under core/ routes/ static/js/ scripts/.
  • Never small: any VULNERABILITY; path or message mentioning auth/crypto/async/thread/lock/SQL/secret/token/password; files elsewhere (incl. tests).
  • LARGE: severity BLOCKER/CRITICAL or effort > 60 min; otherwise MEDIUM.
  • SKIPPED: matches an entry of scripts/sonar_triage.skip.json (rule, file regex, message regex; every given field must match). Entries: server.py 0.0.0.0 bind, tmp-dir dev script, Math.random ids, http:// LAN URLs, md5 cache key.
  • Allowlist (each reason is in the JSON): python/javascript S1481 unused local, S1116 empty statement, javascript S1128 unused import, python/javascript S125 commented-out code.

Flags

--dry-run (default) | --apply | --since-new-code (default) | --all | --json <file> | --max-issues N | --cap N (GitHub issues per run, default 10) | --fix-small (needs --apply) | --list-rules.

GitHub issues

One per rule (all files); title [sonar] <rule>: <short> in N file(s); body has a table of file, line, Sonar key, message (capped at 40 rows, then 'and N more'), rule link, effort, approach, acceptance. A rule with more than 40 locations is split into numbered parts (part 1/3), 40 locations each. Hidden marker <!-- sonar-keys: k1,k2 --> lists every key of the part; an open sonar issue containing any of the keys suppresses a new one. Bodies contain paths/lines only, no code. If gh auth status fails the script reports and continues.

multica hookup

Preferred: a multica webhook autopilot (Autopilots -> New autopilot -> Trigger: Webhook, assignee sonar-fixer, output mode Create issue, project Voice Creator Clone & Design 2). Multica shows the webhook URL after the autopilot is created; it carries its own secret, so save it only in ~/.config/multica-webhook (chmod 600) or MULTICA_WEBHOOK_URL, never in the repo. After each GitHub issue the script POSTs JSON (source, rule, title, github_issue_url, files, sonar_keys, effort_min, body) to it, passing the URL to curl on stdin only. Fallback if no webhook is configured: the CLI command below.

After a GitHub issue is created the script runs multica issue create --project <id> --assignee sonar-fixer --description-stdin (the multica issue links the GitHub URL; assigning starts the agent run). Override with MULTICA_AGENT, MULTICA_PROJECT. Failure is reported, not fatal. Agent sonar-fixer instructions: see the end of this file.

--fix-small

Refuses on a dirty tracked tree. Writes a task file to a temp dir (not committed), runs claude -p with only Read/Edit/Grep/Glob and Bash for check-frontend, node --test, git add/commit/status/diff, then verifies the new commit count and clean tree. Local commit only.

Secrets

The token is read inside the script from ~/.config/sonar-token (or SONAR_TOKEN) and sent as HTTP Basic auth (token as user, empty password). It is never printed, put in argv/URLs or written to files; a unit test asserts it is absent from output.

Run

npm run sonar:triage                        # dry-run, new code
npm run sonar:triage -- --all --json /tmp/t.json
npm run sonar:triage -- --apply --cap 5     # create GitHub + multica issues
npm run sonar:triage -- --apply --fix-small

Rollback

Local fix commits: git reset --hard <sha before> / git revert. Issues: close the GitHub issue and the multica issue. Nothing is pushed by the script.

sonar-fixer agent instructions

Fix only the given Sonar issue. Read CLAUDE.md and PROJECT_MAP.md first. Run node scripts/check-frontend.mjs and Python unittest with an isolated HOME; tests mock the API and import from tests/_guard.js. Browser (Playwright) specs run against the live app and cannot see worktree edits: say which checks you did not run. One local Conventional Commit fix(sonar): ...; never push; never touch secrets; if a design decision is needed, stop and comment.

When done:

  1. Comment on the multica issue: commit SHA, files changed, what you verified, checks NOT run, findings skipped as false positives (with reason).
  2. Post the same report on the GitHub issue from github_issue_url: gh issue comment <number> --body-file - (paths and line numbers only, no code; say the commit is LOCAL and not pushed), add the label fixed-local, then close it: gh issue close <number> --reason completed. If you fixed only part of the findings, do NOT close it: list what is left in the comment.
  3. When the fix is complete and reported (steps 1 and 2), move the multica issue to Done. If only part is fixed, or a design decision is needed, or you could not fix it: comment on both issues, leave the GitHub issue open, and leave the multica issue in In Review (or Blocked if you need an answer).