Summary
REACTOR_DOC_002 (XmlDocCrefAnalyzer) duplicates the built-in compiler diagnostic CS1574 ("XML comment has cref attribute that could not be resolved") without adding any analysis on top. It should be removed and replaced with CS1574 configuration on the framework project.
Background
While fixing the doc-analyzer customer-leak in #491, we audited what REACTOR_DOC_001 and REACTOR_DOC_002 actually do beyond the built-in .NET diagnostics:
-
REACTOR_DOC_001 vs CS1591: earns its keep. It specifically requires a <summary> tag (CS1591 accepts any XML doc, even just <remarks>), and applies broader skip rules for overrides, explicit interface implementations, and [GeneratedCode] types that match Reactor''s docs pipeline (spec 041 §10.4). Keep it.
-
REACTOR_DOC_002 vs CS1574: pure re-skin. The whole analyzer body is:
var symbol = context.SemanticModel.GetSymbolInfo(node, context.CancellationToken).Symbol;
if (symbol is not null) return;
context.ReportDiagnostic(Diagnostic.Create(Rule, node.GetLocation(), text));
That is identical to what CS1574 does internally — same call, same null check, same condition. The analyzer''s own XML doc admits this:
Roslyn raises CS1574 for the same condition; this analyzer surfaces it under a Reactor code so doc PRs can elevate severity independently.
The "independent severity" rationale is weak — CS1574 can already be elevated/suppressed per-project via .editorconfig (dotnet_diagnostic.CS1574.severity = error).
Proposed change
- Delete
src/Reactor.Analyzers.Internal/XmlDocCrefAnalyzer.cs and its tests in tests/Reactor.Tests/AnalyzerTests/XmlDocCrefAnalyzerTests.cs.
- Remove the
REACTOR_DOC_002 row from src/Reactor.Analyzers.Internal/AnalyzerReleases.Unshipped.md (it never shipped externally).
- Remove
REACTOR_DOC_002 from Reactor.csproj''s NoWarn list.
- Update the
Contains("REACTOR_DOC_002", docIds) assertion in tests/Reactor.Tests/AnalyzerTests/AnalyzerPackagingTests.cs (the InternalAnalyzerAssembly_Hosts_DocCoverageRules test).
- If we want enforcement equivalent to what
REACTOR_DOC_002 was reserved for, add an .editorconfig entry on src/Reactor/ to configure CS1574 severity (currently passes through default warning).
- Update spec 041 §10.4 and
docs/guide/analyzer-architecture.md / docs/guide/rules-of-reactor.md to remove the REACTOR_DOC_002 references and point at CS1574 (and CS1580, CS1581, CS1584 for the related cref-malformed family if useful).
Out of scope
REACTOR_DOC_001 stays — it provides real value beyond CS1591 (see "Background" above).
Optional follow-up
If we do want a Reactor-specific cref analyzer that earns its keep, it would need to do something CS1574 doesn''t — e.g.:
- Flag crefs that resolve but point to
internal/non-public symbols (real ref-gen failure mode, since the generator emits a relative MD link that won''t exist).
- Validate
<see href="..."> external URLs against an allow-list.
- Catch crefs that cross
[DocCategory(...)] boundaries in ways that produce broken navigation.
That''s a separate spec and is not blocking this cleanup.
Context
Summary
REACTOR_DOC_002(XmlDocCrefAnalyzer) duplicates the built-in compiler diagnosticCS1574("XML comment has cref attribute that could not be resolved") without adding any analysis on top. It should be removed and replaced withCS1574configuration on the framework project.Background
While fixing the doc-analyzer customer-leak in #491, we audited what
REACTOR_DOC_001andREACTOR_DOC_002actually do beyond the built-in .NET diagnostics:REACTOR_DOC_001vsCS1591: earns its keep. It specifically requires a<summary>tag (CS1591 accepts any XML doc, even just<remarks>), and applies broader skip rules for overrides, explicit interface implementations, and[GeneratedCode]types that match Reactor''s docs pipeline (spec 041 §10.4). Keep it.REACTOR_DOC_002vsCS1574: pure re-skin. The whole analyzer body is:That is identical to what
CS1574does internally — same call, same null check, same condition. The analyzer''s own XML doc admits this:The "independent severity" rationale is weak —
CS1574can already be elevated/suppressed per-project via.editorconfig(dotnet_diagnostic.CS1574.severity = error).Proposed change
src/Reactor.Analyzers.Internal/XmlDocCrefAnalyzer.csand its tests intests/Reactor.Tests/AnalyzerTests/XmlDocCrefAnalyzerTests.cs.REACTOR_DOC_002row fromsrc/Reactor.Analyzers.Internal/AnalyzerReleases.Unshipped.md(it never shipped externally).REACTOR_DOC_002fromReactor.csproj''sNoWarnlist.Contains("REACTOR_DOC_002", docIds)assertion intests/Reactor.Tests/AnalyzerTests/AnalyzerPackagingTests.cs(theInternalAnalyzerAssembly_Hosts_DocCoverageRulestest).REACTOR_DOC_002was reserved for, add an.editorconfigentry onsrc/Reactor/to configureCS1574severity (currently passes through default warning).docs/guide/analyzer-architecture.md/docs/guide/rules-of-reactor.mdto remove theREACTOR_DOC_002references and point atCS1574(andCS1580,CS1581,CS1584for the related cref-malformed family if useful).Out of scope
REACTOR_DOC_001stays — it provides real value beyondCS1591(see "Background" above).Optional follow-up
If we do want a Reactor-specific cref analyzer that earns its keep, it would need to do something
CS1574doesn''t — e.g.:internal/non-public symbols (real ref-gen failure mode, since the generator emits a relative MD link that won''t exist).<see href="...">external URLs against an allow-list.[DocCategory(...)]boundaries in ways that produce broken navigation.That''s a separate spec and is not blocking this cleanup.
Context
fix(analyzers): stop REACTOR_DOC_* rules leaking to customer builds)docs/specs/041-docs-comprehensive-uplift.md§10.4src/Reactor.Analyzers.Internal/XmlDocCrefAnalyzer.cs