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/*.ymlfile is embedded (also a compile-time error: thego:embedpattern 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 norule_idresolve 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(scenarioAC-001; selectorsTestAUR434,IntegrationAUR434,E2EAUR434,AC-001-MUT-001). Runs fully offline against deterministic fixtures; requires the engine packages and thegit-demofixture 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.goso the gate stops discarding ungrounded findings, rebuilds, and proves the plantedrule_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.