Skip to content

Empty the Sonar backlog - #390

Merged
Reefact merged 3 commits into
mainfrom
claude/sonar-points-restants-12zlnr
Jul 30, 2026
Merged

Empty the Sonar backlog#390
Reefact merged 3 commits into
mainfrom
claude/sonar-points-restants-12zlnr

Conversation

@Reefact

@Reefact Reefact commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Summary

The backlog block in .editorconfig is empty. All 377 rules the quality profile activates are
enforced; the 83 outstanding sites across 27 rules are gone.

Each rule left by one of the three doors the repository already documents — its sites cleared, its
whole domain declined for test code with the reason written next to it, or the few deliberate sites
carrying a [SuppressMessage] at the site. The block itself is kept, empty, because the mechanism
outlives the list: the next generated profile may activate a rule this tree violates, and that is
where it goes.

Type of change

  • Refactoring

Changes

4c54f4e — seven mechanical rules, 26 sites

Noise, not judgement: S3878 (14 arrays a params parameter already builds), S1481 (5 discards
named __ because _ was taken — C# allows repeating it), S3358 (2 nested ternaries), S1905,
S6608, S2342.

One of the 26 was a latent defect rather than noise: S6580 in the binder's own test model —
DateOnly.TryParse with no format provider, so the fixture could read a date differently on a machine
with another culture. It now passes InvariantCulture.

A small trap worth recording: renaming the [Flags] enum Wide to WideFlags to satisfy S2342
("a flags enum wants a plural name") immediately trips S2344 ("remove the 'Flags' suffix").
WideBits satisfies both and says what the twenty-one members are.

96452b6 — four rules declined for tests, four cleared, 38 sites

Declined in the existing [*Tests/**.cs] section, which already holds CA1861 — same scope, same
shape of reason, and all four stay enforced for shipping code:

rule why its whole domain here is deliberate
S1244 (15) Exact float equality is the assertion. Between(value, value) declares a degenerate interval and the property is that the draw is that value; Zero() pins a value and == Half.Zero is the contract. A tolerance would stop these checks testing what they exist to test.
S107 (6) The capped lambdas are the eight-operand Any.Combine composer. The arity is the subject, fixed by the API being exercised.
S2326 (2) An unused <T> in a fixture built to be read by reflection is the shape under test.
S108 (2) using (Any.UseSeed(1, …)) { } enters and leaves a scope to assert what disposal does.

Cleared: S3218 (8 — the nested Code classes mirror the factories that raise them, so
Code.DateInvalid reads inside DateInvalid(); one suppression per class keeps the correspondence),
S927 (2), S4136 (1 — Sample(IAny<Uri>) was the Uri case of Sample<T> with an identical body,
so deleting it fixed the adjacency and removed a duplicate).

Two redundant tests deleted, which is what S4144 was pointing at:
ASuccessfulOutcomeCanBeEscalatedToAValue was byte-identical to SuccessfulOutcomeExposesItsValue,
and AnErrorDocumentationBuilderRejectsANullExampleFactory byte-identical to
AnErrorDocumentationBuilderCannotAcceptANullExamplesCollection — both calling
WithExamples<DomainError>(null!). In each case two names claimed two behaviours and one assertion was
made. The genuine "null factory among the provided ones" case is still covered by the test next to it.

1ed42d3 — the last thirteen rules, 19 sites

All deliberate, each now carrying its reason at the site: S1854 (4 — the assignment is dead and the
call is not; these builders exist to provoke a declaration-time conflict), S6966 (2 —
CancelAsync is .NET 8+ and these suites run on the net472 floor, the same downlevel wall as CA1870
and CA1865, ADR-0058), S125 (2 — prose the rule reads as code), S3220 (2), S4144 (1 — a theory
pair whose bodies match because the data differs), S2692 (1 — IndexOf(':') > 0 excludes 0 on
purpose: a colon at index 0 is an empty user part), S2219 (1), and five fixture types.

One finding about my own method

The measurement that produced "zero sites" elevated every parked rule to warning and built the
solution — which only ever compiles the net10 leg. Building the net472 floor legs afterwards
surfaced an S1144 site that measurement could not see: SurfaceParityTests.InstantAlgebra, a field
used solely inside #if NET8_0_OR_GREATER. It is now conditioned like its only consumer.

Worth recording because the gap is in the method, not this diff: a per-leg count is not a repository
count, and the floor legs have to be built before "clear" can be claimed.

Testing

  • dotnet build FirstClassErrors.sln0 warnings, Debug and Release (--no-incremental)
  • dotnet test FirstClassErrors.sln2166 passed, 0 failed across 13 suites
  • Analyzer tests pass (FirstClassErrors.Analyzers.UnitTests 132, JustDummies.Analyzers.UnitTests 246)

2166 rather than 2168 is the two deleted duplicates, and nothing else.

All six net472 floor legs build clean with -p:TreatWarningsAsErrors=true.

The end state is measured, not assumed: with every former backlog entry enforced, the build reports
zero sites on the default build and on all six net472 legs.

Documentation

  • No documentation change required

The .editorconfig block's own header is rewritten to record that it is empty and why it is kept.
No public API moves; every change is in test code or in analyzer-suppression metadata.

Architecture decisions

  • No architectural decision in this pull request

ADR-0062's backlog working as recorded, to its conclusion. The [*Tests/**.cs] declines follow the
precedent that section already set for CA1861, and ADR-0060's rule that a refused rule belongs at
none with its reason.

Related issues

None.


Generated by Claude Code

claude added 3 commits July 30, 2026 22:12
Seven parked rules whose sites were noise rather than judgement. Each is cleared outright, so each
line leaves the backlog block.

S3878 (14) — `Gen.Elements(new[] { … })` spelled the array a params parameter already builds, in five
property-test files, plus one `Split(new[] { '@' })`. The array said nothing the arguments did not.

S1481 (5) — a deconstruction discarded its third element into `__` because `_` was already taken by
the second. C# allows repeated `_` in a deconstruction, so both are now `_` and neither is a variable.

S3358 (2) — the nested ternary in the web and WebSocket draw checks, introduced when those checks moved
out of their lambdas. `WebScheme`/`WebSocketScheme` name the scheme a pinned generator must draw; they
are the read side of the `PinScheme` helpers that were already there.

S1905 (2) — `(sbyte)Any.SByte().Positive().Generate()` cast a value already of that type. The `(sbyte)0`
on the other side stays: it picks the assertion overload.

S6608 (1) — `Split('/').Last()` over an array, now indexed.

S6580 (1) — `DateOnly.TryParse` with no format provider, in the binder's own test model. The only site of
the seven that was a latent defect rather than noise: the parse was culture-dependent, so the fixture
could have read a date differently on a machine with another culture. It now passes InvariantCulture.

S2342 (1) — a [Flags] enum wants a plural name. `Wide` became `WideFlags` first, which trips S2344
("remove the 'Flags' suffix"); `WideBits` satisfies both, and says what the twenty-one members are.

Measured: 83 sites across 27 rules before, 57 across 20 after. Solution builds with zero warnings,
2168 tests pass across 13 suites, and the three touched projects' net472 floor legs build clean with
-p:TreatWarningsAsErrors=true.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017bxVrnCNsXW3RvwmLc9Kvy
Seven more rules leave the backlog, by both of the doors the block documents.

Four are declined for test code only, in the `[*Tests/**.cs]` section that already holds CA1861 —
same reasoning, same scope, and each with the reason written next to it. They are not "not yet"; they
are rules whose whole domain in these suites is deliberate, and `suggestion` was the wrong shelf.

* S1244 (15) — exact floating-point equality. It assumes an `==` between doubles is an accident of
  arithmetic; here it is the assertion. `Between(value, value)` declares a degenerate interval and the
  property is that the draw IS that value; `Zero()` pins a value and `== Half.Zero` is the contract.
  A tolerance would stop these checks testing what they exist to test.
* S107 (6) — the lambdas it caps are the eight-operand `Any.Combine` composer. The arity is the subject
  of the test and is fixed by the API being exercised.
* S2326 (2) — an unused `<T>` in a fixture built to be read by reflection is the shape under test.
* S108 (2) — `using (Any.UseSeed(1, …)) { }` enters and leaves a scope to assert what disposal does.
  Filling the block would add a statement with nothing to say.

All four stay enforced for shipping code, which is the point of scoping them here.

Three more are cleared outright:

* S3218 (8) — the nested `Code` classes mirror the factories that raise them, so `Code.DateInvalid`
  reads inside `DateInvalid()`. One suppression per nested class covers its members and keeps the
  correspondence; renaming to `DateInvalidCode` would break it and buy nothing.
* S927 (2) — two `Equals` overrides named their parameter `other`; the base calls it `obj`.
* S4136 (1) — `AnyUriTests` had `Sample(IAny<Uri>)` and `Sample<T>(IAny<T>)` with identical bodies, the
  first being the second's `Uri` case. Deleting it fixes the adjacency the rule wanted and removes a
  duplicate rather than moving one.

Two redundant tests are deleted, which is what S4144 was pointing at:

* `ASuccessfulOutcomeCanBeEscalatedToAValue` was byte-identical to `SuccessfulOutcomeExposesItsValue` —
  two names, one assertion. The kept one sits with the other two tests about a successful outcome.
* `AnErrorDocumentationBuilderRejectsANullExampleFactory` was byte-identical to
  `AnErrorDocumentationBuilderCannotAcceptANullExamplesCollection`: both called
  `WithExamples<DomainError>(null!)`. The kept name is the accurate one for a null array, and the
  genuine "null factory" case is already covered by the `AmongTheProvidedFactories` test next to it.

Measured: 57 sites across 20 rules before, 19 across 13 after. Zero build warnings, 2166 tests pass
across 13 suites — 2168 less the two deleted duplicates — and the three touched projects' net472 floor
legs build clean with -p:TreatWarningsAsErrors=true.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017bxVrnCNsXW3RvwmLc9Kvy
The last thirteen rules leave the block, by the door the block calls its second one: the few sites that
remain are deliberate, and each now carries a [SuppressMessage] with its reason at the site. The rule
stays enforced everywhere else, which parking it never did.

What the thirteen are, and why each site stands:

* S1854 (4) — the conflict builders. The assignment is dead and the CALL is not: they exist to provoke a
  declaration-time conflict, so what matters is that Except() runs.
* S6966 (2) — CancellationTokenSource.CancelAsync arrived in .NET 8 and these suites also run on the
  net472 floor, where it does not exist. Same downlevel wall as CA1870 and CA1865 (ADR-0058).
* S125 (2) — prose the rule reads as code: one line explains why an outcome is projected to a bool, the
  other what obj/ and bin/ contain.
* S3220 (2) — a bare null passed to a params parameter IS the input under test; and two Split separators
  whose only other spelling immediately trips S3878.
* S4144 (1) — a theory pair whose bodies match because the DATA is what differs, constructor cases against
  method cases.
* S2692 (1) — `IndexOf(':') > 0` excludes 0 on purpose: a colon at index 0 is an empty user part, which
  must fail the property.
* S2219 (1) — not a disguised null check but the compatibility guarantee the comment states, that the
  narrower snapshot exception still derives from InvalidOperationException.
* S3871 + S3376 (1 type), S3877 (1), S3881 (1), S3459 + S1144 (1) — fixtures: a test-local exception, a
  ToString() that throws because the test needs one, xUnit's teardown hook, and a DTO whose name says it
  is misdeclared.

The block is now EMPTY and is kept empty rather than deleted: the mechanism outlives the list, and the
next generated profile may activate a rule this tree violates. All 377 rules the profile activates are
enforced.

One site was invisible to the earlier measurements and is fixed here. Elevating every parked rule and
building the solution only ever compiled the net10 leg, so S1144 on SurfaceParityTests.InstantAlgebra —
a field used solely inside `#if NET8_0_OR_GREATER` — surfaced only when the net472 floor legs were built.
It is now conditioned like its only consumer.

Measured: with every rule enforced, zero sites on the default build AND on all six net472 floor legs with
-p:TreatWarningsAsErrors=true. Zero warnings in Debug and Release, 2166 tests pass across 13 suites.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017bxVrnCNsXW3RvwmLc9Kvy
@Reefact
Reefact force-pushed the claude/sonar-points-restants-12zlnr branch from 1ed42d3 to f8f20e8 Compare July 30, 2026 22:12
@Reefact
Reefact enabled auto-merge July 30, 2026 22:13
@Reefact
Reefact merged commit 7d49526 into main Jul 30, 2026
29 checks passed
@Reefact
Reefact deleted the claude/sonar-points-restants-12zlnr branch July 30, 2026 22:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants