AUR-471 -- ISO/IEC 25010 weights and team convention are explicit configuration
Outcome
The eight ISO/IEC 25010 product quality characteristics now carry weights the
team declares in a versioned file, .aurumcode/iso25010-weights.yml, and the
review reports a per-characteristic score plus an aggregate coherent with
those weights. The team may also declare its own convention: a
per-characteristic severity limit and which characteristics are blocking
versus informative.
Authority model
There are two kinds of input and they are not interchangeable:
- Explicit user configuration.
.aurumcode/iso25010-weights.ymlis written and versioned by the team. It has authority over the review's severity policy, because the team is the principal and the file is its declaration. - Untrusted context. Repository prompt text, skills, MCP results, RAG
chunks and any other provider-contributed material are DATA. They inform the
reviewer and can never change a rule, a severity, the
--fail-ongate, secret redaction, or a cost ceiling.
internal/config/policy reads, parses and validates the policy file and
nothing else. It has no code path that consumes provider or prompt text, so the
distinction is structural, not a runtime check.
The boundary explicit configuration still cannot cross
Authority over severity does not extend to switching off the deterministic security pass or secret redaction. A policy that tries to disable either is refused at load time with a named error that quotes the refused clause:
security_pass: false,security: false,security.pass: falseredaction: off,redact_secrets: false,security.redact_secrets: false
YAML aliases are dereferenced before the check, so an anchored spelling
off: &off false plus redaction: *off is refused the same way, naming
redaction; the indirection is not a bypass.
The Policy type has no field through which redaction or the security pass
could be disabled, so the refusal holds even if a caller ignored the error.
File schema
weights: # required; the eight ISO/IEC 25010 characteristics
functionality: 0.15
reliability: 0.15
usability: 0.10
efficiency: 0.12
maintainability: 0.18
portability: 0.08
security: 0.17
compatibility: 0.05 # must sum to 1.0 (tolerance 1e-9)
convention: # optional
severity_limit:
security: error
portability: info
blocking: [security, reliability]
informative: [portability]
Historical sections such as thresholds and static_signals are ignored for
forward compatibility; a file that carries them still loads.
Named errors
All failures are errors.Is-able and print a stable code:
| Error | Trigger |
|---|---|
policy: weights-sum |
weights missing or not summing to 1.0 |
policy: invalid-weight |
a weight value cannot be decoded as a number |
policy: non-finite-weight |
a weight is NaN or infinite (e.g. .nan) |
policy: negative-weight |
a weight is negative |
policy: unknown-characteristic |
a name outside ISO/IEC 25010 |
policy: invalid-severity |
a limit outside error/warning/info |
policy: blocking-informative-overlap |
a characteristic is both |
policy: refused-clause |
policy tries to disable security pass or redaction |
The weights and refusal checks run inside Load, before any caller could
reach the model, so an invalid declaration can never produce a model call.
Zero-configuration contract
A missing file is not an error and not an empty policy. Load returns
(nil, nil), Evaluate returns (nil, nil), and Render emits exactly
json.Marshal(result). A repository that has not declared weights gets
today's output, byte for byte.
Scoring
For each characteristic in the canonical ISO order,
contribution = score * weight; the aggregate is round(sum(contribution)).
The report is coherent with the file by construction, so two declarations that
move weight between characteristics produce different aggregates.
Validation
- Unit:
tests/unit/AUR-471.go::TestAUR471 - Integration:
tests/integration/AUR-471.go::IntegrationAUR471 - Acceptance:
tests/acceptance/AUR-471.sh(all,AC-001..AC-004) - E2E:
tests/e2e/AUR-471.sh::E2EAUR471
Skeptical mutations AC-002-MUT-001 (silently normalize a non-1.0 sum) and
AC-004-MUT-002 (let the policy disable redaction) each make the acceptance
RED and restore GREEN on the unmutated package.