Rules, Rule Types, Severities, Quality Profiles, and Customization: Guided Hands-On Workflow
Run a bounded same-revision experiment: extend Python Sonar way, lower one S3776 threshold in a project-specific child profile, prove the rule-specific issue delta, then revert to parent policy.
Learning objectives
- Create a synthetic Python fixture and least-privilege analysis token.
- Record instance mode, S3776 metadata and baseline profile assignment.
- Create a disposable child profile without changing the language default.
- Override one rule parameter and correlate analysis to CE/issue/gate evidence.
- Revert the override and clean up credentials safely.
1. Preflight and safety boundaries
Use only the private/local Community Build server from earlier chapters. Scanner execution uses a project-analysis token; profile changes use an interactive account with Administer Quality Profiles permission. Do not scan with an administrator token.
Academy Python Guardrails,
associated only with academy-sonarqube-p09.
export SONAR_HOST_URL='http://127.0.0.1:9000'
sonar-scanner --version
git --version
curl -fsS "$SONAR_HOST_URL/api/system/status" || true
2. Create the disposable fixture
rm -rf sonar-p09
mkdir -p sonar-p09/src sonar-p09/tests
cd sonar-p09
git init
git config user.name 'Academy Learner'
git config user.email 'learner@example.invalid'
cat > src/routing.py <<'PYCODE'
def route(score, premium, active):
if active:
if premium:
if score > 80:
return "priority"
return "premium"
if score > 50:
return "standard-plus"
return "standard"
PYCODE
cat > tests/test_routing.py <<'PYTEST'
from src.routing import route
def test_route():
assert route(90, True, True) == "priority"
PYTEST
cat > sonar-project.properties <<'PROPS'
sonar.projectKey=academy-sonarqube-p09
sonar.projectName=Academy SonarQube P09 Rule Policy Lab
sonar.sources=src
sonar.tests=tests
sonar.sourceEncoding=UTF-8
PROPS
git add . && git commit -m 'p09 controlled rule fixture'
git rev-parse HEAD | tee revision.txt
The function is deliberately below the normal Python S3776 default threshold of 15 but complex enough to cross a much smaller experimental threshold. Record the actual complexity reported by your installed analyzer rather than assuming it.
3. Inspect current policy before mutation
- Record Administration → Configuration → Mode; do not switch it.
-
In Rules, filter Python and retrieve
python:S3776. - Record its repository/key, status, tags, current mode-specific classification and configurable threshold. Current guidance uses 15 as the Python default; the installed analyzer is authoritative.
- In Quality Profiles → Python, record Sonar way's BUILT-IN/DEFAULT status and active/deprecated counts.
- In the disposable project's Quality Profiles settings, record the current Python profile.
4. Baseline scan
read -rsp 'Project-analysis token: ' SONAR_TOKEN; echo
export SONAR_TOKEN
sonar-scanner -X -Dsonar.host.url="$SONAR_HOST_URL" 2>&1 | tee baseline-debug.log
cp .scannerwork/report-task.txt baseline-report-task.txt
grep -E '^(ceTaskId|dashboardUrl|serverUrl|projectKey)=' baseline-report-task.txt
Wait for the referenced Compute Engine task to finish. Record the S3776 issue search and Quality Gate separately. Scanner success, CE success and gate status are three distinct states.
5. Extend Sonar way and associate only the lab project
- Quality Profiles → Python → Sonar way → Extend.
- Name the child
Academy Python Guardrails. - Verify Sonar way is the parent and rules are inherited.
- Do not set it as the Python default.
-
Associate only
academy-sonarqube-p09with the child.
Prediction 1: project-policy state changes while source revision, scanner binary and indexed files stay unchanged. Verify the association independently before changing a rule.
6. Change one inherited parameter
-
Open the child profile's active rule list and retrieve
python:S3776. - Record the inherited threshold and current mode classification.
- Select Change and set only the Cognitive Complexity threshold to 3.
- Leave severity/impact, the Quality Gate and all other rules unchanged.
- Confirm the rule is now shown as overridden.
Prediction 2: the child effective rule configuration changes; Sonar way remains unchanged. If the current analyzer rejects 3, use the smallest valid positive threshold below the measured fixture complexity and record the deviation.
7. Reanalyze the exact same revision
test -z "$(git status --porcelain)" || { git status --short; exit 1; }
git rev-parse HEAD | tee revision-overridden.txt
sonar-scanner -X -Dsonar.host.url="$SONAR_HOST_URL" 2>&1 | tee overridden-debug.log
cp .scannerwork/report-task.txt overridden-report-task.txt
After CE success, filter Issues by python:S3776.
Expected evidence is a new cognitive-complexity issue caused by the
stricter child threshold. Because the revision is unchanged, the
profile override is the causal variable. Preserve the issue's actual
measured complexity and allowed threshold.
8. Revert to parent definition
- Return to S3776 in the child profile.
- Select Revert to Parent Definition.
- Keep the project associated with the child for one restore scan so only one variable changes.
sonar-scanner -X -Dsonar.host.url="$SONAR_HOST_URL" 2>&1 | tee restored-debug.log
cp .scannerwork/report-task.txt restored-report-task.txt
Verify that the override marker is gone and the stricter-threshold issue is no longer newly raised under parent policy. Preserve history rather than deleting it.
9. Required evidence
manifest.md — server/scanner/mode/analyzer
assumptionsrevision.txt — identical revision for
all comparisonsrule-before.md — S3776
key/status/classification/thresholdprofile-before.md
— Sonar way/default/project associationbaseline-report-task.txt
+ CE/issue/gate stateprofile-change.md — child
parent + threshold old→new + actor/rationaleoverridden-report-task.txt
+ CE/issue/gate staterollback.md — Revert to
Parent Definition proofrestored-report-task.txt +
CE/issue statecredentials.md — token metadata
only, never the value
10. Cleanup
-
Revoke the project-analysis token and unset
SONAR_TOKEN. - Remove the explicit project/profile association after rollback evidence is complete.
- Delete the child profile only after proving no project uses it and preserving its backup/change record.
- Delete the lab project/fixture only after evidence is copied.
- Leave Sonar way, language defaults, shared caches and server/database/search state untouched.
11. Challenge: choose the correct layer
A teammate wants to loosen the Quality Gate because threshold 3 produces a new maintainability issue. Explain why that changes the wrong layer: this experiment is evaluating a rule parameter in a quality profile. Gate changes alter downstream pass/fail policy and would confound the policy experiment.
Knowledge check
Why use a project-analysis token instead of an admin token for scanning?
Scanning needs only analysis permission; least privilege keeps administration separate.
Why hold the source revision constant?
To attribute the issue delta to profile policy rather than code changes.
Why extend Sonar way?
It creates a customizable child while retaining parent evolution.
What proves the override affected analysis?
Same-revision before/after scans with separate CE tasks plus rule-specific issue evidence.
Why revert the rule before removing the project association?
It tests one rollback variable: the child override itself.
Official references and version notes
- Community Build — SonarQube rules — repositories, statuses, rule categories, custom/template rules and mode-dependent severity semantics.
- Community Build — Instance mode overview, including MQR Mode and Standard Experience.
- Community Build — Understanding quality profiles — built-in/default profiles, inheritance, overrides and project association.
- Community Build — Creating a quality profile — Extend, Copy, blank creation and import/export.
- Community Build — Editing a custom quality profile — activate/deactivate rules, customize parameters and Revert to Parent Definition.
- Community Build — Associating a quality profile with projects.
- Sonar Rules — Python S3776 — Cognitive Complexity rule used in the controlled parameter experiment.
- SonarQube releases — current Community Build and Server release identities.
Rechecked on 2026-09-07. Mandatory examples target private/local
SonarQube Community Build 26.9.0.129388 and
SonarScanner CLI 8.1.0.6389. Current Community
Build baseline is 26.9.0.129388; current commercial SonarQube
Server baseline is 2026 Release 4.1 with 2026.1.5 as the current
2026 LTA patch line. New Community Build instances use MQR Mode by
default, but every lab records the actual mode and never switches
it. MQR uses Blocker/High/Medium/Low/Info severities on
software-quality impacts; Standard Experience uses
Bug/Vulnerability/Code Smell/Security Hotspot types with
Blocker/Critical/Major/Minor/Info severity. Sonar way is built-in
and immutable. The hands-on experiment extends Python Sonar way
and tunes python:S3776; verify installed rule
metadata before changing it because analyzer behavior can evolve.
No third-party plugin, commercial edition, CI provider, enterprise
identity, SonarQube Cloud account, branch/PR analysis or
production source is required.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.