Contracts
sonar-config-contract.md
Contract: SonarCloud QA config slice
The observable contracts this mission must uphold (verified by the tests + reviews cited in acceptance-matrix.json).
C1 — projectVersion is single-sourced (#2421, FR-001/FR-002)
- Producer:
scripts/ci/sonar_project_version.py— reads[project].versionfrompyproject.tomlviatomllib. - Invariant: returns exactly
pyproject.toml's version; raisesProjectVersionError(never returns/prints empty) on missing/unreadable/blank version. - Consumer: the
sonarcloudjob in.github/workflows/ci-quality.ymlinjects-Dsonar.projectVersion=<version>(or appendssonar.projectVersion=<version>in the Materialize step), guarded by[ -z "$version" ] && exit 1. - Boundary note: the
sonarcloudjob runs only onschedule/workflow_dispatch(never PR/push) — so the wiring is verified statically (SC-001a), and the live baseline reset (SC-001b) is a post-merge observation on the next nightly cron / manual dispatch.
C2 — the review tool is strictly read-only (FR-005/FR-006, NFR-001)
scripts/ci/sonarcloud_branch_review.shissues only HTTPGETs through a single_http_getseam (--get, no-X/--request, noPOST/PUT/DELETE/PATCH). No subcommand bypasses the seam.- Subcommands:
quality-gate,coverage,uncovered <file>,issues,version/analyses(the last backs SC-001b). - Needs no
SONAR_TOKEN— public read endpoints; the smoke test passes with the token unset, network stubbed to fixtures.
C3 — coverage reconciliation clarifies, never masks (#2422, FR-003/FR-004, C-002, NFR-002)
docs/guides/coverage-signals.mddocuments why SonarCloudcoverage/new_coverageand the internaldiff-coveragegate differ (file-set + philosophy), backed by API evidence.- No
sonar.sources/sonar.exclusionschange unless a genuine misconfiguration is found (none was) — narrowing Sonar scope would mask untested code (no-ratchet standing order).