diff --git a/.sonarlint/sonar-local.globalconfig b/.sonarlint/sonar-local.globalconfig index b52b70b..2dc460a 100644 --- a/.sonarlint/sonar-local.globalconfig +++ b/.sonarlint/sonar-local.globalconfig @@ -8,8 +8,10 @@ is_global = true # disabled by default. Raise them so a local run sees what CI sees. # # S3267 and S2699 are here because CI reported them on PR #87 - S3267 as new issues on -# DocComment.Validate, S2699 against the older test files. The rest are carried over from the -# equivalent config in ktsu.Semantics, whose quality profile is the closest available reference. +# DocComment.Validate, S2699 against the older test files. S8969 is here because it is the +# remaining issue this repository's SonarCloud project reports (see below). The rest are carried +# over from the equivalent config in ktsu.Semantics, whose quality profile is the closest +# available reference. dotnet_diagnostic.S107.severity = warning dotnet_diagnostic.S1075.severity = warning dotnet_diagnostic.S1172.severity = warning @@ -22,13 +24,25 @@ dotnet_diagnostic.S3358.severity = warning dotnet_diagnostic.S3458.severity = warning dotnet_diagnostic.S3776.severity = warning dotnet_diagnostic.S6444.severity = warning +dotnet_diagnostic.S8969.severity = warning # Enabled by default in the analyzer package. Left enabled here: unlike ktsu.Semantics, this # repository has not been shown to have a profile that excludes it, so a false positive is # cheaper than a missed finding. # dotnet_diagnostic.S1481.severity = none -# KNOWN GAP: SonarCloud reported one new issue on PR #87 that this configuration does not -# reproduce. The rule behind it is either absent from the analyzer package or shipped disabled -# and not listed above. If you have dashboard access and can identify it, add it here - the -# calibration is only as good as the rules it names. +# Calibration. The list above is only as good as the rules it names, so check it against the +# dashboard rather than guessing. The project is public, so this needs no token: +# +# curl -s 'https://sonarcloud.io/api/issues/search?componentKeys=ktsu-dev_CodeBlocker&resolved=false&ps=100' +# +# Every rule that query returns should appear above, and a local run should report the same set. +# As of this writing both sides agree: 5x S2699 in CodeBlocker.Test, and S8969 on +# DocComment.cs:191. +# +# S8969 ("Null-forgiving operators should not be redundant") was the issue previously recorded +# here as an unidentified gap. It was not a missing severity line - the rule ships disabled AND +# was absent from the pinned analyzer package, so adding it alone would have changed nothing. +# It needed the package bump to 10.30.0.144632 as well. That is the failure mode to watch for: +# a rule CI reports that stays silent locally after being listed here is a package-version +# problem, not a severity problem. diff --git a/.sonarlint/sonar-local.props b/.sonarlint/sonar-local.props index 311f56c..4d39c51 100644 --- a/.sonarlint/sonar-local.props +++ b/.sonarlint/sonar-local.props @@ -19,13 +19,20 @@ restore to pick up the PackageReference below. sonar-local.globalconfig (next to this file) sets the rule severities so the local warning set - approximates CI's. + matches CI's. + + The analyzer version is pinned deliberately. A rule CI reports cannot be reproduced locally if + the pinned package predates it - that is a silent gap, not a visible failure, because a rule + the package does not carry simply never fires. 10.30.0.144632 is the first release carrying + S8969, which is why the pin sits here rather than on an older release. When calibrating against + a rule CI reports and this build does not, check that the package actually contains it before + assuming the severity line is wrong. Nothing in the repository imports this, so normal builds, the CI pipeline, and packaging are all unaffected. --> - + diff --git a/CLAUDE.md b/CLAUDE.md index 287dfe1..57061ee 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -42,16 +42,30 @@ The opt-in lives in `.sonarlint/sonar-local.props` (the analyzer package) and analyzer package ships disabled). Nothing imports these automatically, so normal builds, the CI pipeline, and packaging are unaffected. -On current `main` the run is clean apart from five `S2699` warnings (test methods that assert -nothing) in `CodeBlocker.Test`. It found and named `S4144` on `ScopeTests.cs` — two test methods with -identical bodies, one of which did not test what its name claimed — which is the kind of finding the -setup exists for. - -**Known gap:** SonarCloud reported one new issue on PR #87 that this configuration does not -reproduce, and sonarcloud.io is not reachable from the agent sandbox to identify it. The rule -behind it is either absent from the analyzer package or shipped disabled and not listed in the -globalconfig. If you have dashboard access, add it — the calibration is only as good as the rules -it names. +On current `main` the run reports six findings, and they are the same six SonarCloud reports: +five `S2699` (test methods that assert nothing) in `CodeBlocker.Test`, and one `S8969` on +`CodeBlocker/Templates/DocComment.cs:191` — a null-forgiving `text!` that the +`string.IsNullOrEmpty(text)` guard directly above already makes redundant. The setup also earlier +found and named `S4144` on `ScopeTests.cs` — two test methods with identical bodies, one of which +did not test what its name claimed — which is the kind of finding it exists for. + +### Recalibrating + +The local set is only as good as the rules `sonar-local.globalconfig` names, so check it against +the dashboard rather than guessing. The SonarCloud project is public, so this needs no token: + +```bash +curl -s 'https://sonarcloud.io/api/issues/search?componentKeys=ktsu-dev_CodeBlocker&resolved=false&ps=100' +``` + +Every rule it returns should be listed in the globalconfig, and a local run should report the same +file-and-line set. + +If a rule CI reports stays silent locally *after* you add its severity line, the problem is the +analyzer package version, not the severity. Rules ship in the package; one released after the +pinned version simply cannot fire. That is exactly what hid `S8969` — it is both disabled by +default and absent from the previously pinned `10.18.0.131500`, so it needed the bump to +`10.30.0.144632` (its first release) as well as the severity line. ## Project Structure