add-lint-rule
Skill572 starsChanged 19 days agoApache-2.0View on GitHub
Add or change lint rules and static analysis in dd-trace-dotnet. Use when adding a lint rule, Roslyn analyzer, diagnostic, BannedSymbols entry, StyleCop/editorconfig severity, CppCheck suppression, or Clang-Tidy check, or when the user asks how to enforce a coding convention at compile time.
2 other projects use a version of this.
Adopted by
Most recently taken up by
- UnknownPlatypus/djangofmttheir own version, first seen Oct 9, 2026
- jolars/panachetheir own version, first seen Oct 8, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- jolars/panache★ 246same name
- UnknownPlatypus/djangofmt★ 103same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository6 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- analyze-azdo-buildSkill
- azure-functionsSkill
- bump-libdatadogSkill
- sdk-reviewSkill
The file
We split this skill into the rules it gives an agent
11 rules. About 0 are common, 5 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 29
If the rule is not worth Error, do not add it.
- Distinctive: line 31
Read reference.md for file layout, ID allocation, and copy-paste templates.
- Distinctive: line 46
If the same idea is both “style” and “maybe faster”, it is style.
- Distinctive: line 51
Do not classify a rule as Performance, mention allocations/CPU in the diagnostic message, or sell the PR as a perf win unless at least one …
- Very specific: line 70
If the case is not strong enough for Error, do not add the rule.
- Very specific: line 88
Do not enable EnableNETAnalyzers / EnforceCodeStyleInBuild globally.
- Distinctive: line 103
Do not introduce Roslyn, clang-format CI, or a new analyzer framework.
- Very specific: line 110
Default posture: fix the code or add a narrow suppression.
- Very specific: line 137
If cleanup is large, use stacked PRs to fix hits, then enable the rule as Error.
- Distinctive: line 147
Follow reference.md: analyzer, tests, optional code fix.
- Very specific: line 156
Do not add Nuke targets, Azure stages, GitHub workflows, CodeQL config, or static-analysis.datadog.yml entries.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Add Lint Rules / Static Analysis
This repo has no dotnet format or clang-format --check CI job. Managed
enforcement is compile-time Roslyn (TreatWarningsAsErrors=true). Do not add a
new pipeline stage for a C# rule.
Scope: enforcement of rules and scripts applies only to "core"
production code for now (Datadog.Trace and other tracer/src libraries;
native tracer/loader/profiler product code). Do not apply new analyzers,
Banned APIs, CppCheck/Clang-Tidy tightenings, or helper scripts to tests,
helpers, samples, or test-applications unless the user explicitly asks to
expand scope.
Still add unit tests for the analyzer itself under
Datadog.Trace.Tools.Analyzers.Tests — that is testing the rule, not
enforcing it on test code.
New rules are introduced as Error. Info diagnostics are legacy:
they are IDE-only, they are ignored, and they must not be used for new rules.
If the rule is not worth Error, do not add it.
Read reference.md for file layout, ID allocation, and copy-paste templates. Stay in this file until the rule is classified.
1. Classify the rule first
Pick one primary category. Do not mix them in the diagnostic title, category, or PR description.
| Category | What it is | Severity (new rules) | Typical mechanism |
| Correctness / safety | Wrong code, security, config-key misuse, infinite-loop hazard | Error | Custom Roslyn analyzer |
| Product convention | Must use a helper, logging shape, duck-type null check | Error | Analyzer or BannedSymbols.txt |
| Style | Naming, usings, headers, layout, “looks nicer” | Error, or do not add. Prefer existing StyleCop / .editorconfig | StyleCop, editorconfig, or analyzer |
| Performance | Proven hot-path win | Error only if the win is clear. Otherwise do not add | Analyzer or Banned API, with an evidence-backed message |
If the same idea is both “style” and “maybe faster”, it is style. Do not rebrand it as performance to justify blocking PRs.
2. Do not over-claim performance
Do not classify a rule as Performance, mention allocations/CPU in the diagnostic message, or sell the PR as a perf win unless at least one of these is true:
- The replacement mechanistically avoids a known allocation or extra work
on a tracer hot path (span create/tag, instrumentation callback, logging,
config read). Example already in-tree:
Environment.Versionallocates aVersionon every get;BannedSymbols.txtsays so. - You have a benchmark or a tight proof (the API’s implementation obviously allocates; the helper is documented as the zero-alloc path).
Not enough:
- “Sealing types can improve performance” as a reason to add a rule
(
DDSEAL001is a legacyInfodiagnostic; do not copy it). - Micro-optimizations outside bootstrap/hot paths in
AGENTS.md. - Style preferences (braces,
var, usings,is not null) dressed up as perf. - “Might help the JIT / inlining / virtual dispatch” without a measured case.
If the case is not strong enough for Error, do not add the rule. Never
use a speculative perf claim to justify shipping it.
3. Choose the mechanism
Managed C# (preferred: Roslyn)
Cheapest fit wins:
- Ban a specific API → add a line to repo-root
BannedSymbols.txt(RS0030is already error). This file is currently supplied only toDatadog.Trace.csproj; for another project, include it asAdditionalFilesthere or choose a custom analyzer. Message must state the replacement and the real reason (correctness, config, or a clear perf win). - Ban a pattern (syntax, types, logging templates,
WithKeysarguments) → custom analyzer undertracer/src/Datadog.Trace.Tools.Analyzers/. - Existing StyleCop / IDE diagnostic, new severity →
.editorconfigdotnet_diagnostic.<ID>.severity. Do not invent StyleCop IDs. - Do not enable
EnableNETAnalyzers/EnforceCodeStyleInBuildglobally. Built-in .NET analyzers are off on purpose (shared/CodeAnalysis.props).
Custom analyzers are referenced only from tracer/src/Directory.Build.props
as OutputItemType="Analyzer". New [DiagnosticAnalyzer] types are picked
up with no CI YAML changes. BannedSymbols.txt is an AdditionalFiles item
on Datadog.Trace.csproj (core), not on test projects.
StyleCop and .editorconfig are broader (they include tests). Do not raise
a StyleCop/IDE diagnostic severity repo-wide as a way to lint test code, and
do not treat that existing breadth as a reason to extend custom rules or
scripts beyond core.
Native C/C++ (light)
Do not introduce Roslyn, clang-format CI, or a new analyzer framework.
| Area | Primary tools | Where they run |
| Native tracer + native loader | CppCheck | Azure static_analysis_checks_tracer |
| Profiler | Clang-Tidy (fails on error:) and CppCheck | Azure static_analysis_tests_profiler (only if profiler changed) |
Default posture: fix the code or add a narrow suppression. Do not
tighten check sets or remove --suppress= flags unless the user asked for a
new native rule and existing noise is acceptable.
- Tracer/loader suppressions are CLI
--suppress=lists on theCppCheckNativeSrc/CppCheckNativeLoaderNuke targets. - Profiler CppCheck:
profiler/cppcheck-suppressions.txt(--inline-suppris enabled). - Profiler Clang-Tidy: base set is
profiler/.clang-tidy. CI-checks(ClangTidyChecksinBuild.Profiler.Steps.cs) is appended, not a replacement. Do not add style checks by default; a new check is opt-in and fails the profiler analysis stage onerror:. .clang-formatis local style only; CI does not verify it.
4. Severity (managed)
Introduce every new diagnostic as Error. Set
defaultSeverity: DiagnosticSeverity.Error.
Error— the only acceptable severity for a new rule. Fails the build and blocks the PR.Warning— not a softer landing.TreatWarningsAsErrorsis true, so it already fails the build. Do not use it as the final state.Info— legacy only (DDSEAL001). IDE-only, ignored in CI, and ignored in practice. Do not add newInforules. Do not “try Info first and bump later.”
If cleanup is large, use stacked PRs to fix hits, then enable the rule
as Error. If it is not worth that, do not add it. Match category to §1
(Usage, CodeQuality, Maintainability, Performance only when §2 is
satisfied).
5. Implementation workflow (managed)
- Classify (§1) and confirm the perf bar (§2).
- Grep
DiagnosticIdundertracer/src/Datadog.Trace.Tools.Analyzersfor the nextDDxxxxor startDD<AREA>001for a family (DDLOG,DDDUCK). - Follow reference.md: analyzer, tests, optional code fix.
- Clean up all current hits in the same PR (or in stacked PRs before
enabling
Error), or the tree will not compile. Prefer real fixes over#pragma/GlobalSuppressions. - Tests:
Datadog.Trace.Tools.Analyzers.TestsviaCSharpAnalyzerVerifier/CSharpCodeFixVerifier. - Compile:
CompileManagedSrcorBuildAndRunManagedUnitTestswith a filter on the new test class.
Do not add Nuke targets, Azure stages, GitHub workflows, CodeQL config, or
static-analysis.datadog.yml entries.
6. PR description
State: category (style / convention / correctness / performance), diagnostic ID, what is forbidden, the replacement, and why. If performance, cite the allocation/hot-path evidence in one sentence. If style, say so and do not claim runtime impact.
Checklist
- Category is explicit; style is not labeled Performance
- Perf claims meet §2; otherwise no perf language in the diagnostic
- Enforcement is "core" production code only; analyzer unit tests still added
- Managed: Roslyn analyzer or
BannedSymbols.txt, not a new CI job - Native: CppCheck and/or existing Clang-Tidy surface only
- Introduced as
Error(Infois legacy and will be ignored) - Analyzer tests cover a flag case and a no-flag case
- Existing violations fixed in the same change
- Generated-code analysis left
None; concurrent execution enabled
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

