Seen on a customer's SQL Server 2005 SP4 (legacy ODBC):
- agent-jobs declared @since with an initial value (2008+): "Incorrect syntax
near CONVERT" and SQLI-JOB-001/002 never ran. Now DECLARE; SET.
- plan-analysis used query_hash (2008+) and failed every 30 minutes for
SQLI-PLAN-001/002/003. On 2005 a statement is now identified by
sql_handle + offsets, as top SQL does. It needs sys.dm_exec_text_query_plan,
so the new capability TextQueryPlan (2005 SP2, 9.0.3042) is required.
- COM-DB-001 used OBJECT_SCHEMA_NAME (2005 SP2+); now joins sys.objects and
sys.schemas.
Audit of all collector SQL and community rules without minimumVersion 10.0:
the rest is 2005 syntax or behind a version/capability check.
Sql2005CompatibilityTests (2005 cannot run in CI): every collector that can
run on 2005 is scanned for 2008+ syntax in its SQL (inline DECLARE, +=,
MERGE, CONCAT/IIF/FORMAT/TRY_*, OFFSET/FETCH, date/time types, multi-row
VALUES), version-branched files listed explicitly; the same for community
rules; and the 2005 variants of plan analysis and top SQL must not use
query_hash. Verified to fail on the old agent-jobs SQL.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Managed Instance reports 12.0.2000.8 but is evergreen: treated as the
newest engine with all capabilities; new SelfManagedInfrastructure
capability so backup, CHECKDB, files, tempdb, memory, patch level and
lifecycle rules report 'handled by Azure' instead of false findings
- Microsoft Entra ID login (managed identity, service principal, default
credential chain) via SqlConnection.AccessTokenCallback
- Least-privilege script recognizes Managed Instance; deadlock collector
falls back to the ring buffer when event files cannot be read
- Web UI shows the right release for Managed Instance
- README and installation docs: notifications and Managed Instance
- Catalog test: 61 rules with unique, well-formed ids
Integration suite green on SQL Server 2017 and 2022.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E3EExwndy8Z22EK2Qpt6BK
Collector takes the 50 heaviest statements (CPU, last 24 h), fetches
statement plans as text (dm_exec_query_plan returns NULL for deeply
nested plans) and analyzes them in C#. Rules:
- SQLI-PLAN-001 implicit conversion preventing an index seek
- SQLI-PLAN-002 join without predicate (deliberate CROSS JOIN excluded)
- SQLI-PLAN-003 non-inlined scalar UDF in a heavy statement
- SQLI-PLAN-004 spills to tempdb, SQLI-PLAN-005 oversized memory grants
(2016 SP2+ / 2017 CU3+ columns, new capability)
Verified against real plans in SQL Server.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E3EExwndy8Z22EK2Qpt6BK
Collectors (SQL Server 2000+, version-specific SQL, least privilege):
server, configuration, trace flags, databases (settings, backups in UTC,
CHECKDB, VLFs, Query Store, files, tempdb), suspect pages, plan cache,
wait stats and file I/O as deltas with restart/clear detection,
performance counters, CPU from the scheduler monitor ring buffer,
blocking (sleeping head blockers with open transactions), and deadlocks
from system_health continuing from the last file offset.
Rules: configuration (memory, MAXDOP per Microsoft NUMA guidance, cost
threshold, ad hoc bloat, risky options, pending changes), databases
(state, settings, backups, log backups, CHECKDB, suspect pages, VLFs,
autogrowth, max size, Query Store, tempdb), waits (THREADPOOL, signal
waits, locks, I/O, WRITELOG, parallelism, PAGELATCH), I/O latency, CPU,
memory grants, blocking and deadlocks. Missing data makes a rule not
measurable with the collector's reason.
Integration tests run every collector as the least-privilege login and
reproduce real blocking and a real deadlock; green on 2017 and 2022.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E3EExwndy8Z22EK2Qpt6BK
- .NET 10 solution with Core, Connectivity, Rules, Contracts, Agent, Web and Hub
- Capability model gating collectors and rules by SQL Server version (2000 and later);
rules that cannot run are reported as not measurable, never as passed
- Connectivity via Microsoft.Data.SqlClient with ODBC fallback for legacy instances,
hardened monitoring session settings valid back to SQL Server 2000
- Support lifecycle rule (SQLI-VER-001) with lifecycle data shipped as a rule pack
- Version-aware least-privilege permissions script, verified by integration tests
against SQL Server in Docker (reads monitoring sources, cannot read customer data)
- Forgejo Actions CI, contributing guide, code of conduct, issue templates,
legacy version notes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E3EExwndy8Z22EK2Qpt6BK