Pular para conteúdo

AUR-434 — Every finding cites the project review rule that sustains it

Documento histórico do board. Pode descrever componentes removidos; para uso atual, consulte o guia do produto.

Card AUR-434 makes aurumcode review follow the project's review standard: every problem the command prints cites the rule that sustains it, and a finding that cannot cite such a rule never reaches the user.

Command

aurumcode review --base <ref>

Unchanged from AUR-430 (see docs/specs/AUR-430.md for the full command reference): diffs <ref> against HEAD in the git repository at the current working directory, sends the diff to the configured LLM provider, and prints the findings. No new flags.

What this card changes in the output

Each printed finding now ends with the citation of the sustaining rule:

<file>:<line>: [<severity>] <message> (rule <rule-id>: <rule-title>)

Example (offline, no secret — the fixture is a canned model response):

cd tests/fixtures/repos/git-demo/repo.git
AURUMCODE_LLM_FIXTURE=../../../review/known-problem-response.json \
  aurumcode review --base HEAD~1

prints

config/demo-tokens.txt:4: [error] A credential-shaped value was committed in plain text (DEMO_API_TOKEN). (rule security/hardcoded-secret: Hardcoded Secrets)

A model finding whose rule_id is missing, or names a rule that does not exist in the embedded catalog, is discarded before printing: it never reaches the user. A run where every finding is discarded prints the unchanged AUR-430 no-findings output:

No issues found.

The reviewer records how many findings it discarded in the review result's metadata (issues_rejected_without_rule); the CLI does not print metadata.

The rule catalog

The catalog is embedded in the binary via go:embed from internal/review/rules/*.yml. The three files (security.yml, quality.yml, performance.yml) are the c12d7ab .aurumcode/rules catalog, restored by this card, with one id normalized: security/hardcoded-secrets is now security/hardcoded-secret, the singular form the engine's prompt contract and fixtures emit. Because the catalog is embedded, the binary carries its rules everywhere — the historical defect where running the binary outside the repository root found zero rules silently is structurally gone.

internal/review/rules.go is the restored c12d7ab RulesLoader (Get/GetAll/GetByCategory over rules indexed by id) re-pointed at the embedded catalog. Loading fails loudly — error, not an empty catalog — when:

  • no rules/*.yml file is embedded (also a compile-time error: the go:embed pattern refuses to match nothing);
  • the embedded files declare zero rules in total;
  • a rule has an empty id (an empty id would let findings with no rule_id resolve against it, silently defeating the gate);
  • two rules share an id (the winner would depend on file order);
  • a file is not valid YAML.

The rejection itself is NEW logic added by this card (enforceRuleCitations in internal/review/reviewer.go): the historical c12d7ab mapRulesToIssues only enriched issues (filling an empty Message/Severity from the rule, cleaning the file path) and let findings without a resolvable rule pass through. That enrichment is kept; the gate on top of it is what this card adds. ISO/IEC 25010 scoring (internal/review/iso25010) remains out of scope for this card.

Exit codes

Unchanged from AUR-430:

Exit Meaning
0 Review completed (with or without surviving findings).
1 Runtime failure: not a git repository, diff failure, no provider configured, unparseable model response — or, new with this card, a broken embedded rules catalog (review rules unavailable: ...).
2 Usage error (unknown command, missing --base).

Diagnosing a failure

Symptom Likely cause
A finding the model reported does not print It did not cite a rule of the project standard: rule_id was missing or unknown. This is the card's contract, not a bug. Degraded-mode parses (Metadata["parse_mode"] == "degraded") carry no rule_id, so their findings are always discarded.
aurumcode review: review rules unavailable: ... The embedded catalog failed to load (see the loud failure list above). This indicates a broken build of the binary.
No issues found. where findings were expected Either the model reported none, or every reported finding failed the rule gate.

For everything else (repository backends, provider selection, parser fallback, diff limits) see docs/specs/AUR-430.md.

Validation

  • Acceptance: tests/acceptance/AUR-434.sh (scenario AC-001; selectors TestAUR434, IntegrationAUR434, E2EAUR434, AC-001-MUT-001). Runs fully offline against deterministic fixtures; requires the engine packages and the git-demo fixture repository to be materialized, and reports exit 69 (inconclusive infrastructure), never a behavioral RED, when they are not.
  • MUT-001: the acceptance mutates a staged copy of reviewer.go so the gate stops discarding ungrounded findings, rebuilds, and proves the planted rule_id-less finding then reaches the output — i.e. accepting a finding without a cited rule makes the acceptance fail. The committed source contains no mutation hook.