↑ ↓ para mover · Enter para abrir · Esc para fecharToque em um resultado

Arquitetura
skill · classe report · opus

sonar-lessons

Roda a análise do SonarQube do projeto, liga cada grupo de achados à norma ou configuração que o produziu e escreve um arquivo de lições.

skill · reportopuseffort high1 caminhos permitidosvai para o projeto gerado
§ a definição da skill

sonar-lessons, seção a seção

As seções do próprio SKILL.md da skill, em trechos. Passe o mouse ou clique numa delas para ver quais regras do projeto, templates e arquivos de references/ ela cita. As seções também são chips: clique num para ir até ela.

nerviz/.claude/skills/sonar-lessons/SKILL.md

## Why this is a skill (Form 2) and not an agent

Form 2 because a full verify plus analysis is a side effect the model must not trigger on its own — axis 2 of the design interview: the user types /sonar-lessons, nothing chains it. Publishing the issue was the second such effect until 0103 moved it to /report-issue, the one door from a generated project to the meta-repository. The symptom behind it (axis 1) was the same long prompt pasted into every feature round to produce a Sonar lessons-learned by hand. The closest rejected form was the same skill plus a sonnet collector agent holding the build log and raw JSON; it failed the counter-test of invariant 5, since facets and small pages already keep the extraction short. Record: @.claude/decisions/0100-sonar-lessons-skill.md.

Runs on opus: step 4 — deciding which norm or template owns a finding, and what the fix at the owner is — is the judgment the hand-written lessons-learned needed.

## Procedure

Endpoints, parameters and response fields of every call below: references/sonar-web-api.md. Every curl authenticates with -u "$SONAR_TOKEN:" and never prints the variable.

### 1 · Preconditions — stop on the first that fails

  1. Root build file: pom.xml → maven, build.gradle → gradle. Neither → stop: nothing to
  2. Scanner declared — sonar-maven-plugin / org.sonarqube in that file. Absent → stop:
  3. sonar.host.url and sonar.projectKey read from the build file (sonar.organization
  4. curl -sS <host>/api/system/status answers "status":"UP". Connection refused on
  5. SONAR_TOKEN set and valid — curl -sS -u "$SONAR_TOKEN:" <host>/api/authentication/validate
  6. Browse permission — one component_tree read with ps=1, the call step 3's duplication

### 2 · Run the analysis

ToolCommand
maven./mvnw -B -q verify sonar:sonar
gradle./gradlew -q build sonar

-q rather than a redirect to a log file: the output stays short, and a redirect is a write outside this skill's territory. A red build stops here — report the failing module and the first error line; a lessons-learned about an analysis that never ran is fiction.

The analysis is asynchronous. Read ceTaskId from target/sonar/report-task.txt (build/sonar/report-task.txt for gradle) and poll /api/ce/task?id=<ceTaskId> until SUCCESS. Reading measures before that returns the previous analysis, silently. FAILED or CANCELED → stop with the task's errorMessage.

### 3 · Extract

In this order, all read-only:

  1. Quality gate — status and every condition, with its threshold and actual value.
  2. Measures — the list in the reference: bugs, vulnerabilities, code smells, hotspots,
  3. Issues by rule — one call with ps=1 and facets on rules, software qualities,
  4. Rule text — /api/rules/show for each rule key: its name and why it matters.
  5. Duplication — files with duplicated blocks, then the blocks of each.
  6. Coverage — the files with the most uncovered lines.

Large answers are the only real cost of this skill: always request the facet first and page only what step 4 needs.

### 4 · Trace each finding group to its owner

Group by Sonar rule (a duplicated block is its own group). For each group, find the piece of this project's .claude/ that produced it, in this order, and stop at the first hit:

OriginHow to find it
Template copied verbatimGrep the flagged construct in .claude/skills/*/templates/*.example. A hit means every project gets the issue
Norm that allows or requires it.claude/rules/00-index.md → the norm for that layer; a norm that prescribes the flagged shape, or explicitly permits it
Checkstyle / build configurationconfig/checkstyle/*.xml and the root build file — a check that is missing, or disabled, where Sonar has the equivalent rule
Test template teaches the patternSame as the first row, restricted to test-architect and new-feature test templates
Code the bootstrap generatedNo template in the project — project-bootstrap does not travel. Name it project-bootstrap plus the role of the file (entry point, exception handler, config class)
Nothing — the model decided aloneNo norm and no template covers the construct. The fix is a norm, or a line in the one that owns that layer

Then decide the fix at the owner: which file in .claude/, what change, and whether it also needs enforcement (a Checkstyle check, an ArchUnit rule) so the issue cannot come back. Say it concretely — a file path, a line, the shape of the change — never "improve the template".

Check whether an owner file was edited locally since the export: java .claude/hooks/ArchHook.java doctor names the edited .claude/ files. When the file at fault is one of them, the lesson says so: the meta-repository's version may not have the defect.

### 5 · Write `docs/lessons-learned/sonar-NNN.md`

NNN is the highest existing sonar-*.md plus one, 001 when the directory is empty. Fill templates/lessons-learned.md.example: snapshot, issues by origin, one section per group, and the structural lesson — what in .claude/ would have caught the whole class of issue before the analysis did. Complete here: project paths, lines, excerpts all belong in this file.

Progress against the previous run. When sonar-<NNN-1>.md exists, read its snapshot and fill the snapshot's *Previous* and *Δ* columns, and mark each finding group *new*, *recurring* (same rule key in the previous file) or — in a closing list — *gone*. The goal is fewer issues each round; this is the only place that says whether it is happening. A recurring group whose previous file already named the fix at the owner says so: the fix was proposed and has not reached this project (not merged upstream, or not pulled with /arch-adopt).

Report the path and the snapshot line, then go on to step 6.

### 6 · Hand it to `/report-issue` — print the command, invoke nothing

Write not filed yet — /report-issue docs/lessons-learned/sonar-NNN.md in the ## Issue line at the end of sonar-NNN.md, and end the report with that command. /report-issue is manual-only: it picks the sonar-lessons form, strips the project from the body, searches duplicates, asks, and overwrites the ## Issue line with the outcome. The user types it, or the lesson stays local — the line says which, for a later reader and for the next run's step 5.

## Failure modes

No scanner in the build file: `` ❌ pom.xml declares no sonar-maven-plugin. Run /sonarqube-setup, then /sonar-lessons. Nothing written. ``

Server down: `` ❌ http://localhost:9000 refused the connection. Run docker compose up -d sonarqube, wait for /api/system/status to answer UP, re-run. ``

Token missing, invalid, or unable to read: `` ❌ SONAR_TOKEN is not set — export a user token (My Account → Security) and re-run. ❌ <call> answered 403 — SONAR_TOKEN can analyze but not browse this project. A project analysis token cannot read the Web API; use a user token with Browse. ``

Build red: `` ❌ verify failed in <module> — <first error line>. No analysis ran; nothing written. ``

… cortado aqui, o resto está no arquivo

## Report

✅ Sonar lessons — <quality gate status> · <N> issues (<main> main / <test> test) · coverage <x> % · duplication <y> %

Lessons ..... docs/lessons-learned/sonar-NNN.md — <G> groups: <t> template, <r> norm, <c> checkstyle, <b> bootstrap, <m> model alone
Top owners .. <.claude path> (<n> issues) · <.claude path> (<n>) · …
Dashboard ... <host>/dashboard?id=<projectKey>
File it ..... /report-issue docs/lessons-learned/sonar-NNN.md
Abrir o arquivo completo no GitHub →
§ comportamento

O que lê, escreve e recusa

O contrato da própria skill, do SKILL.md, no texto original.

Class

report — the territory is skill_classes.report in @.claude/schemas/extensions.json: docs/lessons-learned/**, nothing else. ArchHook.java guard enforces it; target/ and build/, which the analysis writes, are ignored by git and outside what guard sweep sees.

Reads

the root build file, target/sonar/report-task.txt (or build/sonar/), .claude/rules/**, .claude/skills/*/templates/, config/checkstyle/, .claude/.arch-provenance.json (the version line of the file), and the SonarQube Web API.

Writes

docs/lessons-learned/sonar-NNN.md.

Publishes

nothing. The issue is /report-issue's, typed by the user with the path step 6 prints; the body file sonar-NNN.issue.md is written there.

Never writes

the build file, docker-compose.yml, a token, or anything under src/. A finding is fixed at its owner in the meta-repository, or by /new-feature in this project — not by this skill.

Not chained

by any skill. Travels into the generated project (export.skills.include); in the Nerviz repository itself it stops at step 1, which has no build file.

Fonte: SKILL.md § Contract, no nerviz e4cae27.

§ guard e hook

O que o guard faz com ela

report é a classe da skill, e a lista à esquerda é o seu território. A fase abre quando a skill roda em um prompt próprio, e o ArchHook julga cada escrita contra essa lista. O texto à direita é o do próprio hook.

write_allow de sonar-lessons

  • ✓docs/lessons-learned/**
  • qualquer caminho fora desta lista, quando a própria skill abre a fase

A recusa sai com código 2 e a mensagem volta para o modelo.

> /sonar-lessons …
UserPromptSubmit
  guard prompt                     exit 0
# phase opened: sonar-lessons (class report)
# write_allow: docs/lessons-learned/**
§ como é chamada

Quem a chama

Não é um passo de uma cadeia. Ela começa em um prompt próprio, /sonar-lessons, e o guard a trata como qualquer outra skill: a fase abre e vale o território da sua classe.

← voltar às cadeias