Skip to content

Release v2.3.0#627

Merged
erikdarlingdata merged 139 commits intomainfrom
dev
Mar 18, 2026
Merged

Release v2.3.0#627
erikdarlingdata merged 139 commits intomainfrom
dev

Conversation

@erikdarlingdata
Copy link
Owner

@erikdarlingdata erikdarlingdata commented Mar 18, 2026

Release v2.3.0

See CHANGELOG.md for full details.

Highlights

  • ErikAI analysis engine — rule-based inference engine for Lite and Dashboard with anomaly detection, bad actor scoring, and CPU spike detection
  • FinOps cost optimization — Phase 1-4 recommendations (enterprise feature audit, CPU/memory right-sizing, compression savings, VM right-sizing, reserved capacity)
  • Azure SQL DB fixes — all FinOps collectors now query each database individually
  • Server unreachable email alerts
  • Lite data import from previous install
  • SQL Server version check in both installers (rejects 2014 and earlier)
  • Installer adversarial tests — 35 automated tests covering upgrade failures, data survival, idempotency
  • Full MCP tool coverage — Dashboard 57 tools, Lite 51 tools
  • Growth rate and VLF count columns in Database Sizes

Testing completed

  • Fresh install: sql2016 (CLI)
  • Upgrade: sql2017, sql2022 (CLI), sql2025 (GUI)
  • Clean install: sql2019 (GUI)
  • Multi-hop: 2.0.0 → 2.1.0 → 2.2.0 → 2.3.0 on sql2019
  • Idempotency: sql2022 (ran twice, 0 failures)
  • Uninstall/reinstall: sql2016 (CLI + GUI)
  • Cloud: Azure SQL DB (Lite), AWS RDS (Lite + Dashboard + installer)
  • Automated: 35 installer adversarial tests passed
  • Data survival verified on all upgrade paths

Summary by CodeRabbit

  • New Features

    • Diagnostic analysis engine generates findings and insights from performance data
    • Monthly cost tracking for servers enables FinOps-based cost attribution
    • Analysis findings can be muted to suppress recurring alerts
    • Partial tab refresh improves UI responsiveness when viewing specific dashboard sections
  • Bug Fixes

    • Email notifications now sent when servers go offline/restored
    • SQL Server version validation ensures compatibility before installation
    • Upgrade failures no longer corrupt existing database data
    • Installation fallback logic handles incomplete prior installations gracefully
  • Documentation

    • Expanded MCP tool instructions and diagnostic workflow guidance

erikdarlingdata and others added 30 commits March 11, 2026 23:42
Auto-refresh timer was firing all sub-tab queries (~32 SQL queries) every
30 seconds regardless of which sub-tab was visible. Now only the active
sub-tab refreshes on timer ticks (1-2 queries). Full refresh preserved
for initial load, manual refresh, and Apply-to-All time range changes.

Controls updated: ResourceMetricsContent (8 sub-tabs), QueryPerformanceContent
(8 sub-tabs), SystemEventsContent (9 sub-tabs), MemoryContent (5 sub-tabs).

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- Add database_size_stats_collector and server_properties_collector to
  install seed data so fresh installs get FinOps collectors (fixes #531)
- Load all per-server FinOps sub-tabs on server switch (fixes #530)
- Clear stale utilization grids when switching servers (fixes #532)
- Fix NoUtilizationMessage layout (RowSpan, alignment, margin)
- Change CROSS JOIN to LEFT JOIN for server_info in Lite utilization
  query so data shows even without v_server_properties (fixes #533)
- Remove stale debug JSON files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…-ui-fixes

Fix FinOps collector scheduling and UI bugs
RetrievedFromCache is an attribute on the StmtSimple XML element,
but the parser was reading it from the child QueryPlan element
where it never exists. Changed to read from stmtEl instead of
queryPlanEl in both Dashboard and Lite copies.

Ported from PerformanceStudio#88 / PerformanceStudio#89.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The database_size_stats and server_properties collectors iterate
databases with cursor-based dynamic SQL. On mirroring passive servers,
RESTORING databases must be excluded to prevent severity 22 engine
crashes (same root cause as #384 and #430).

- database_size_stats: Change state_desc filter to d.state = 0
- server_properties: Change state_desc filter to d.state = 0,
  add HAS_DBACCESS() check (was missing entirely)

Fixes #535

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…e-crash

Fix SQL dumps on mirroring passive servers from FinOps collectors
00_uninstall.sql (added in #431 for standalone uninstall) was placed in
install/ and picked up by the file glob, making it the first script
executed on every install — including upgrades. This silently dropped
the PerformanceMonitor database before recreating it empty.

Four fixes:

1. Exclude 00_* from the install file list (both CLI and GUI), matching
   the existing 97_/99_ exclusion pattern.

2. Abort installation when any upgrade script fails instead of falling
   through to the full install path over a partially-upgraded database.
   New CLI exit code 8 (UpgradesFailed).

3. Version detection fallback: when the database exists but
   installation_history has no SUCCESS rows (prior GUI bug), return
   "1.0.0" so all idempotent upgrades are attempted rather than
   treating it as a fresh install.

4. Increase upgrade script timeout from 5 minutes to 1 hour for data
   migrations on large tables (compress_query_stats on 240GB+ DBs).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix installer dropping database on every upgrade
Rule-based inference engine for automated SQL Server diagnostics:
- FactCollector gathers wait stats, blocking, deadlocks, config, memory
- FactScorer applies threshold formulas + contextual amplifiers
- RelationshipGraph encodes diagnostic reasoning as conditional edges
- InferenceEngine does greedy traversal to build evidence-backed stories
- FindingStore persists/retrieves/mutes findings in DuckDB

MCP tools (6 total):
- analyze_server: full pipeline with next_tools recommendations per finding
- get_analysis_facts: raw scored facts with amplifier details
- compare_analysis: two-period comparison with severity deltas
- audit_config: edition-aware CTFP/MAXDOP/memory/threads evaluation
- get_analysis_findings: retrieve persisted findings
- mute_analysis_finding: suppress known patterns

Stripped UI (Narrator, AnalysisTab) — AI clients consume via MCP, not prose.
83 tests passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New fact categories with scoring, amplifiers, and graph edges:
- CPU_SQL_PERCENT: avg SQL CPU % (thresholds 75/95%), cross-refs SOS_SCHEDULER_YIELD
- IO_READ_LATENCY_MS / IO_WRITE_LATENCY_MS: avg latency from file_io_stats deltas
- TEMPDB_USAGE: usage fraction from tempdb_stats (thresholds 75/90%)
- MEMORY_GRANT_PENDING: max waiters from resource semaphore (thresholds 1/5)
- QUERY_SPILLS / QUERY_HIGH_DOP: aggregate query stats (spill counts, DOP > 8)

Amplifier cross-references connect the new facts:
- SOS_SCHEDULER_YIELD boosted by CPU > 80%
- PAGEIOLATCH boosted by read latency > 20ms and grant waiters
- CXPACKET boosted by high-DOP query count
- MEMORY_GRANT_PENDING boosted by RESOURCE_SEMAPHORE and spills
- QUERY_SPILLS boosted by grant waiters

Relationship graph edges for full diagnostic chains:
- CPU: CPU_SQL_PERCENT ↔ SOS_SCHEDULER_YIELD ↔ CXPACKET
- I/O: IO_READ_LATENCY ↔ PAGEIOLATCH, IO_WRITE_LATENCY ↔ WRITELOG
- Memory: RESOURCE_SEMAPHORE ↔ MEMORY_GRANT_PENDING ↔ QUERY_SPILLS
- TempDB: TEMPDB_USAGE → PAGEIOLATCH, TEMPDB_USAGE → QUERY_SPILLS
- Query: QUERY_HIGH_DOP → CXPACKET/SOS, QUERY_SPILLS ↔ TEMPDB/grants

Tool recommendations added for all new fact keys.
MinimumDataHours raised from 0.5 to 72 (production threshold).
Cleaned up stale narrator references in comments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
10 new collectors covering all non-plumbing DuckDB tables:
- perfmon_stats: PLE (scored, <300 concerning), Batch Req/sec, compilations
- memory_clerks: top 10 by size with breakdown
- database_config: aggregated RCSI/auto_shrink/auto_close/page_verify counts
- procedure_stats: aggregate proc execution stats (CPU, reads, elapsed)
- query_snapshots: active query counts (long-running, blocked, parallel)
- running_jobs: long-running job detection (scored, is_running_long count)
- session_stats: connection counts by state and per-app max
- trace_flags: active global trace flags list
- server_properties: CPU count, cores, sockets, memory, HADR status
- database_size_stats: disk volume free space (scored, <10% concerning)

Scoring rules for PLE (inverted threshold), DB config (auto_shrink/close),
running jobs, and disk space. Amplifiers cross-reference:
- PLE boosted by PAGEIOLATCH and RESOURCE_SEMAPHORE
- Deadlocks boosted by RCSI-off databases
- DB_CONFIG boosted by I/O latency (auto_shrink fragmentation)
- Disk space boosted by TempDB pressure and query spills

Tool recommendations for PLE, DB_CONFIG, RUNNING_JOBS, DISK_SPACE.
83 tests passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ports the 5 plan analysis tools from PerformanceStudio to both apps:
- analyze_query_plan: Analyze cached plan by query_hash
- analyze_procedure_plan: Analyze procedure plan by sql_handle/plan_handle
- analyze_query_store_plan: Analyze Query Store plan (fetched on-demand from SQL Server)
- analyze_plan_xml: Analyze raw showplan XML directly
- get_plan_xml: Retrieve raw showplan XML by query_hash

Uses ShowPlanParser + PlanAnalyzer (31 anti-pattern rules) to return
structured JSON with warnings, missing indexes, parameters, memory
grants, and top operators.

Dashboard fetches plans from SQL Server PerformanceMonitor database.
Lite fetches from DuckDB cache, with Query Store as on-demand SQL
Server fallback.

Tested end-to-end on both apps against SQL2022.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add execution plan analysis MCP tools to Dashboard and Lite
- Add 24 adversarial tests (FactCollectorMiseryTests) covering division
  by zero, empty tables, reversed time ranges, DMV corruption, overflow,
  boundary conditions, and full-pipeline zero-period resilience
- Add 15 new seed methods to TestDataSeeder for all remaining collectors
  (CPU, IO, TempDB, memory grants, query stats, perfmon, memory clerks,
  database config, procedure stats, active queries, running jobs,
  session stats, trace flags, server properties, disk space)
- Enrich all 6 test scenarios with new seed data for integration coverage
- Add 24 new happy-path collector tests in FactCollectorTests
- Fix FactScorer bug: PLE=0 scored as severity 0.0 instead of 1.0
  (zero page life expectancy = worst memory pressure, not harmless)
- Widen CXPACKET amplifier test range to accommodate new CPU amplifier

131/131 tests passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
, #545)

Lite perfmon fixes (#544):
- Aggregate chart query by collection_time (SUM across instance_name)
  so multi-instance counters show one clean line instead of jagged duplicates
- Add gap detection to DeltaCalculator — if >5min since last cached value,
  return 0 delta instead of inflated value spanning the entire gap
- Seed timestamps from DuckDB so gap detection works after app restarts
- Fix sample_interval_seconds from hardcoded 600 to 60 (actual interval)

Dashboard fix (#545):
- Wrap ServerTab construction in try-catch with user-friendly error message
  pointing to VC++ Redistributable download for SkiaSharp failures

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…n-and-scottplot

Fix Lite perfmon chart bugs and Dashboard ScottPlot crash handling
DMV sys.dm_exec_query_stats returns min_dop, max_dop, and thread
columns as bigint, but our temp table and permanent table used
smallint/integer — causing overflow on INSERT.

Widened to match actual DMV types:
- min_dop, max_dop: smallint -> bigint
- min/max_reserved_threads, min/max_used_threads: integer -> bigint

Includes upgrade script for existing 2.2.0 installations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The publish/ directory is gitignored; the type fix was already
applied to install/02_create_tables.sql (the source of truth).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…verflow

Fix arithmetic overflow in query_stats collector
Schema.cs: min_dop, max_dop changed from INTEGER to BIGINT
Collector: Convert.ToInt32 changed to Convert.ToInt64 for dop reads

Mirrors the Dashboard fix — same root cause, different codebase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix Lite query_stats dop columns to match DMV bigint type
Missed the third copy of the query_stats schema in
06_ensure_collection_table.sql — same smallint/integer -> bigint
fix for min_dop, max_dop, and thread columns.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix ensure_collection_table query_stats column types
Full audit of all collector tables against Microsoft DMV docs found
6 SQL Server columns and 2 Lite columns narrower than documented types:

SQL Server:
- cpu_scheduler_stats: total_work_queue_count, total_active_parallel_thread_count (int -> bigint)
- cpu_scheduler_stats: system_memory_state_desc (nvarchar(120) -> nvarchar(256))
- waiting_tasks: resource_description (nvarchar(1000) -> nvarchar(3072))
- database_size_stats: recovery_model_desc (nvarchar(12) -> nvarchar(60))
- database_size_stats: volume_mount_point (nvarchar(256) -> nvarchar(512))

Lite (DuckDB):
- tempdb_stats: total_sessions_using_tempdb (INTEGER -> BIGINT, removed narrowing cast)
- session_stats: connection_count (INTEGER -> BIGINT, COUNT_BIG result)

Also fixes Azure SQL DB collector CONVERT(nvarchar(12),...) -> nvarchar(60)
for recovery_model_desc.

Idempotent upgrade script tested on sql2022.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…smatches

Widen collector columns to match DMV documentation
The summary DataGrid was in a RowDefinition Height="Auto" row, which
lets it grow unbounded to fit all content. With enough rows the grid
extends past the window and the detail grid gets pushed off-screen.

Changed both grids to proportional heights (*  and 2*) so they share
the available space and scroll internally. Fix applied to both Lite
and Dashboard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…l-554

Fix Index Analysis scroll not working with many results (#554)
The existing NotifyOnConnectionLost/Restored settings only sent tray
notifications. Now also sends an email (if SMTP is configured) on the
online→offline transition and a "Server Restored" email when it comes
back. Fires exactly once per transition — no repeated alerts while
the server stays down.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…le-email-529

Email alerts when monitored servers go offline (#529)
Azure SQL DB isolates each database — you can't cross-database query.
The collector was running sys.database_files against the connection's
default database (usually master), so only master's files appeared in
Storage Growth and Database Sizes.

Now enumerates databases via sys.databases on master, then connects to
each individually to collect file sizes. Extracted ReadSizeRow helper
to deduplicate the reader parsing for both paths.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
erikdarlingdata and others added 28 commits March 17, 2026 17:29
- Add missing "Optional" case to encryption switch — previously fell
  through to default (Mandatory), making the dropdown option non-functional
- Remove bare catch in LogInstallationHistoryAsync — exceptions now
  propagate to the caller which already logs them as warnings. Prevents
  silent history write failures that cause version detection fallback.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
57 tests covering CpuScore, MemoryScore, StorageScore, Overall,
ScoreColor, PercentRank, and HighImpactScorer with adversarial inputs.

Found and fixed: PercentRank returned 1.5 when value exceeded all list
entries (rank/count-1 exceeded 1.0). Clamped with Math.Min(1.0m, ...).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add HealthCalculator tests + fix PercentRank >1.0 bug
Lite: Add column-level filtering to all 5 Optimization sub-tab grids
(IdleDatabases, TempdbPressure, WaitCategorySummary, ExpensiveQueries,
MemoryGrantEfficiency) using the existing shared filter infrastructure.

Dashboard: Add column-level filtering to all 10 FinOps DataGrids
(Recommendations, DatabaseResources, StorageGrowth, DatabaseSizes,
WaitCategorySummary, ExpensiveQueries, MemoryGrantEfficiency,
ApplicationConnections, ServerInventory, HighImpact). Uses a single
FinOpsFilter_Click handler that finds the parent DataGrid via visual
tree walk, with per-grid filter state dictionaries.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Full SQL Server port of the Lite analysis engine. Dashboard now has
the same inference engine, scoring, anomaly detection, drill-downs,
and 6 MCP analysis tools as Lite.

Portable files (copied from Lite, namespace updated):
- AnalysisModels.cs, IFactCollector.cs, IPlanFetcher.cs
- InferenceEngine.cs, RelationshipGraph.cs, FactScorer.cs

SQL Server implementations (new):
- SqlServerFactCollector.cs — 23 fact collectors querying collect.* tables
- SqlServerFindingStore.cs — persists findings, auto-creates config.analysis_* tables
- SqlServerAnomalyDetector.cs — CPU/wait/blocking/IO anomaly detection
- SqlServerDrillDownCollector.cs — 11 drill-down categories
- SqlServerPlanFetcher.cs — on-demand plan fetch via sys.dm_exec_query_plan
- AnalysisService.cs — orchestrates pipeline with SQL Server backend

MCP tools (6 new):
- analyze_server, get_analysis_facts, compare_analysis
- audit_config, get_analysis_findings, mute_analysis_finding

Dashboard now has 63 total MCP tools (was 57).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…-port-590

Port ErikAI analysis engine to Dashboard (#590)
Add column filter buttons (FinOpsFilter_Click + ColumnFilterButtonStyle) to the
remaining 4 FinOps DataGrids that were missing them: IdleDatabasesDataGrid (4 cols),
TempdbPressureDataGrid (4 cols), IndexAnalysisSummaryGrid (28 cols), and
IndexAnalysisDetailGrid (15 cols). All existing ElementStyle properties preserved.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…filters

Add filters to remaining Dashboard FinOps grids
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Hide IdleDatabases grid when empty to fix scrollbar artifact
SqlServerDrillDownCollector was splitting on ASCII ' -> ' but story
paths use Unicode ' → '. The split produced the entire path as one
key, so pathKeys.Contains("DEADLOCKS") always returned false.

Single character fix: ' -> ' → ' → '. All 8 applicable findings
now have populated drill-down data.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…arrow

Fix Dashboard drill-down: Unicode arrow in story path split
TempDB grid showed white scrollbar when empty (same fix as IdleDatabases).
Warning column was changed from Width=* to Width=200 during filter button
addition, causing horizontal scrollbar with data present.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ning-width

Fix TempDB grid scrollbar and Warning column width
Collapse DataGrid.Visibility when data count is 0 for all FinOps grids:
Recommendations, DatabaseResources, StorageGrowth, WaitCategorySummary,
ExpensiveQueries, MemoryGrantEfficiency, HighImpact.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Hide all empty FinOps DataGrids to prevent scrollbar artifacts
Add ScrollViewer.HorizontalScrollBarVisibility=Disabled to all 12
FinOps DataGrids. Revert the visibility-collapse workarounds that
hid grids entirely when empty.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…crollbar

Fix FinOps grid scrollbars — disable horizontal scroll
MaxHeight was 700px which wasn't enough to fit the Username/Password
fields plus Connection Options plus buttons. Bumped to 850px.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ight

Fix Add Server dialog buttons hidden with SQL auth
- Bump Version/AssemblyVersion/FileVersion/InformationalVersion to
  2.3.0 in all 4 csproj files
- Fix GUI installer: set _installedVersion after successful install
  so the Uninstall button is enabled

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Version bump to 2.3.0 + fix GUI uninstall button
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Implement #567 for dashboard

* Implement #567 for lite

* Fix columns "order by" for dashboard

* Fix columns "order by" for Lite

* Fix upgrade script

* Add filters to "Database Size" columns (matching Lite)

* Do not swallow v22 migration failures.

Update Lite/Database/DuckDbInitializer.cs

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Add upgrade script to the upgrade.txt

* Remove the IF OBJECT_ID … ALTER TABLE block

* Tidy up duplicate code

* Fix collection health overflow and query stats DOP type mismatch

- collection_health view: cast duration_ms and rows_collected to bigint
  before AVG/SUM to prevent arithmetic overflow after 7 days of data
- collection_health C# reader: use Convert.ToInt64 for avg_duration_ms,
  update model property from int to long
- query_stats reader: min_dop/max_dop columns are bigint in the table
  but reader called GetInt16() — changed to Convert.ToInt16(GetValue())

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Clamp negative duration_ms to 0 in master collector

DST clock-backward adjustments cause DATEDIFF(MILLISECOND, @start, SYSDATETIME())
to return negative values when the wall clock jumps back. This pollutes
avg_duration_ms in report.collection_health. Clamp to 0 with IIF rather
than switching to UTC, which would break consistency with existing data.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix Database Sizes grid: scrollbar, filter handlers, per-file VLF count

- Enable horizontal scrollbar (was Disabled, clipping new columns)
- Unify all column filter buttons to DatabaseSizesFilter_Click (existing
  columns used FinOpsFilter_Click, causing split filter state)
- VLF count: filter sys.dm_db_log_info by file_id so each log file gets
  its own count instead of the whole-database total (Dashboard + Lite)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix uninitialized @error_message in database size collector CATCH

The per-database inner CATCH referenced @error_message which was never
set — debug output always showed NULL. Use ERROR_MESSAGE() directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: ClaudioESSilva <claudiosil100@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Cláudio Silva <ClaudioESSilva@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ServerSelector used DisplayName instead of DisplayNameWithIntent,
so read-only intent connections were indistinguishable from normal ones.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix FinOps server dropdown missing (Read-Only) suffix
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 18, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7881d334-589d-4ad6-85b3-6b2071e2ecb4

📥 Commits

Reviewing files that changed from the base of the PR and between 8ed7a95 and 6722fb7.

📒 Files selected for processing (142)
  • .coderabbit.yaml
  • CHANGELOG.md
  • Dashboard/AddServerDialog.xaml
  • Dashboard/AddServerDialog.xaml.cs
  • Dashboard/Analysis/AnalysisModels.cs
  • Dashboard/Analysis/AnalysisService.cs
  • Dashboard/Analysis/FactScorer.cs
  • Dashboard/Analysis/IFactCollector.cs
  • Dashboard/Analysis/IPlanFetcher.cs
  • Dashboard/Analysis/InferenceEngine.cs
  • Dashboard/Analysis/RelationshipGraph.cs
  • Dashboard/Analysis/SqlServerAnomalyDetector.cs
  • Dashboard/Analysis/SqlServerDrillDownCollector.cs
  • Dashboard/Analysis/SqlServerFactCollector.cs
  • Dashboard/Analysis/SqlServerFindingStore.cs
  • Dashboard/Analysis/SqlServerPlanFetcher.cs
  • Dashboard/Controls/FinOpsContent.xaml
  • Dashboard/Controls/FinOpsContent.xaml.cs
  • Dashboard/Controls/MemoryContent.xaml
  • Dashboard/Controls/MemoryContent.xaml.cs
  • Dashboard/Controls/QueryPerformanceContent.xaml
  • Dashboard/Controls/QueryPerformanceContent.xaml.cs
  • Dashboard/Controls/ResourceMetricsContent.xaml
  • Dashboard/Controls/ResourceMetricsContent.xaml.cs
  • Dashboard/Controls/SystemEventsContent.xaml
  • Dashboard/Controls/SystemEventsContent.xaml.cs
  • Dashboard/Dashboard.csproj
  • Dashboard/MainWindow.xaml.cs
  • Dashboard/ManageServersWindow.xaml
  • Dashboard/Mcp/McpActiveQueryTools.cs
  • Dashboard/Mcp/McpAnalysisTools.cs
  • Dashboard/Mcp/McpConfigHistoryTools.cs
  • Dashboard/Mcp/McpDiagnosticTools.cs
  • Dashboard/Mcp/McpHealthParserTools.cs
  • Dashboard/Mcp/McpHostService.cs
  • Dashboard/Mcp/McpInstructions.cs
  • Dashboard/Mcp/McpLatchSpinlockTools.cs
  • Dashboard/Mcp/McpPlanTools.cs
  • Dashboard/Mcp/McpSchedulerTools.cs
  • Dashboard/Mcp/McpServerInventoryTools.cs
  • Dashboard/Mcp/McpSystemEventTools.cs
  • Dashboard/Models/CollectionHealthItem.cs
  • Dashboard/Models/ServerConnection.cs
  • Dashboard/ServerTab.xaml.cs
  • Dashboard/Services/DataGridFilterManager.cs
  • Dashboard/Services/DatabaseService.FinOps.cs
  • Dashboard/Services/DatabaseService.QueryPerformance.cs
  • Dashboard/Services/DatabaseService.cs
  • Dashboard/Services/EmailTemplateBuilder.cs
  • Dashboard/Services/ShowPlanParser.cs
  • Dashboard/SettingsWindow.xaml.cs
  • Installer.Tests/AdversarialTests.cs
  • Installer.Tests/FileFilteringTests.cs
  • Installer.Tests/GlobalUsings.cs
  • Installer.Tests/Helpers/TempDirectoryBuilder.cs
  • Installer.Tests/Helpers/TestDatabaseHelper.cs
  • Installer.Tests/IdempotencyTests.cs
  • Installer.Tests/Installer.Tests.csproj
  • Installer.Tests/UpgradeOrderingTests.cs
  • Installer.Tests/VersionDetectionTests.cs
  • Installer/PerformanceMonitorInstaller.csproj
  • Installer/Program.cs
  • InstallerGui/InstallerGui.csproj
  • InstallerGui/MainWindow.xaml.cs
  • InstallerGui/Services/InstallationService.cs
  • Lite.Tests/AnalysisServiceTests.cs
  • Lite.Tests/FactCollectorMiseryTests.cs
  • Lite.Tests/FactCollectorTests.cs
  • Lite.Tests/FactScorerTests.cs
  • Lite.Tests/FinOpsTests.cs
  • Lite.Tests/FindingStoreTests.cs
  • Lite.Tests/HealthCalculatorTests.cs
  • Lite.Tests/InferenceEngineTests.cs
  • Lite.Tests/ScenarioTests.cs
  • Lite/Analysis/AnalysisModels.cs
  • Lite/Analysis/AnalysisService.cs
  • Lite/Analysis/AnomalyDetector.cs
  • Lite/Analysis/DrillDownCollector.cs
  • Lite/Analysis/DuckDbFactCollector.cs
  • Lite/Analysis/FactScorer.cs
  • Lite/Analysis/FindingStore.cs
  • Lite/Analysis/IFactCollector.cs
  • Lite/Analysis/IPlanFetcher.cs
  • Lite/Analysis/InferenceEngine.cs
  • Lite/Analysis/RelationshipGraph.cs
  • Lite/Analysis/SqlPlanFetcher.cs
  • Lite/Analysis/TestDataSeeder.cs
  • Lite/Controls/FinOpsTab.xaml
  • Lite/Controls/FinOpsTab.xaml.cs
  • Lite/Controls/PlanViewerControl.xaml.cs
  • Lite/Database/AnalysisSchema.cs
  • Lite/Database/DuckDbInitializer.cs
  • Lite/Database/Schema.cs
  • Lite/MainWindow.xaml
  • Lite/MainWindow.xaml.cs
  • Lite/Mcp/McpAnalysisTools.cs
  • Lite/Mcp/McpConfigTools.cs
  • Lite/Mcp/McpHostService.cs
  • Lite/Mcp/McpInstructions.cs
  • Lite/Mcp/McpPlanTools.cs
  • Lite/Mcp/McpServerInfoTools.cs
  • Lite/Mcp/McpSessionTools.cs
  • Lite/Models/ServerConnection.cs
  • Lite/PerformanceMonitorLite.csproj
  • Lite/Services/ArchiveService.cs
  • Lite/Services/DataImportService.cs
  • Lite/Services/DeltaCalculator.cs
  • Lite/Services/LocalDataService.DailySummary.cs
  • Lite/Services/LocalDataService.FinOps.cs
  • Lite/Services/LocalDataService.Perfmon.cs
  • Lite/Services/LocalDataService.ServerInfo.cs
  • Lite/Services/LocalDataService.WaitStats.cs
  • Lite/Services/RemoteCollectorService.DatabaseSize.cs
  • Lite/Services/RemoteCollectorService.FileIo.cs
  • Lite/Services/RemoteCollectorService.Perfmon.cs
  • Lite/Services/RemoteCollectorService.QueryStats.cs
  • Lite/Services/RemoteCollectorService.SessionStats.cs
  • Lite/Services/RemoteCollectorService.TempDb.cs
  • Lite/Services/RemoteCollectorService.cs
  • Lite/Services/ShowPlanParser.cs
  • Lite/Windows/AddServerDialog.xaml
  • Lite/Windows/AddServerDialog.xaml.cs
  • Lite/Windows/ManageServersWindow.xaml
  • Lite/Windows/SettingsWindow.xaml
  • Lite/Windows/SettingsWindow.xaml.cs
  • PerformanceMonitor.sln
  • README.md
  • THIRD_PARTY_NOTICES.md
  • collection_schedule.json
  • install/02_create_tables.sql
  • install/04_create_schedule_table.sql
  • install/06_ensure_collection_table.sql
  • install/08_collect_query_stats.sql
  • install/42_scheduled_master_collector.sql
  • install/47_create_reporting_views.sql
  • install/52_collect_database_size_stats.sql
  • install/53_collect_server_properties.sql
  • servers.json
  • upgrades/2.2.0-to-2.3.0/01_widen_query_stats_columns.sql
  • upgrades/2.2.0-to-2.3.0/02_widen_audit_columns.sql
  • upgrades/2.2.0-to-2.3.0/03_add_growth_vlf_columns.sql
  • upgrades/2.2.0-to-2.3.0/upgrade.txt

📝 Walkthrough

Walkthrough

Introduces version 2.3.0 featuring a comprehensive Analysis engine for diagnostic fact collection, anomaly detection, two-layer scoring, and relationship graph-based story inference. Adds extensive MCP tools for query/plan analysis, health metrics, and diagnostics. Implements FinOps enhancements with monthly cost tracking, health scoring, and recommendations. Updates installers with SQL version validation, upgrade timeout handling, and new test coverage. Expands UI with cost inputs and partial refresh capabilities.

Changes

Cohort / File(s) Summary
Analysis Engine Core
Dashboard/Analysis/*.cs, Lite/Analysis/*.cs
New fact collection, scoring, anomaly detection, and inference engine; includes AnalysisService orchestration, two-layer scoring with amplifiers, relationship graph-based story building, SQL/DuckDB collectors, findings persistence, and drill-down enrichment.
MCP Tool Expansion
Dashboard/Mcp/*.cs
Adds 9 new MCP tool classes (PlanTools, LatchSpinlock, Scheduler, ConfigHistory, Diagnostic, ActiveQuery, SystemEvent, HealthParser, ServerInventory, Analysis); exposes query/plan analysis, scheduler pressure, health metrics, config history, and server diagnostics.
FinOps Enhancements
Dashboard/Services/DatabaseService.FinOps.cs, Dashboard/Controls/FinOpsContent.xaml.cs
Adds monthly cost attribution (MonthlyCostUsd), health scoring (CPU/memory/storage), recommendations engine with licensing/provisioning checks, per-dataset cost shares, new recommendation data model with savings estimates, high-impact query tracking, and dynamic filtering UI.
Installer & Version Management
Installer/Program.cs, InstallerGui/MainWindow.xaml.cs, InstallerGui/Services/InstallationService.cs, Installer.Tests/*
Implements SQL Server version validation (rejects pre-2016), upgrade timeout handling (1 hour), fallback for incomplete installs (1.0.0), uninstall script exclusion (00_/97_/99_ prefixes), and new test suites (adversarial, idempotency, version detection, upgrade ordering).
Configuration & Versioning
.coderabbit.yaml, CHANGELOG.md, Dashboard/Dashboard.csproj, Installer/PerformanceMonitorInstaller.csproj, InstallerGui/InstallerGui.csproj
Adds CodeRabbit config with path-specific review guidance (Dashboard, Lite, SQL scripts, Installers), comprehensive changelog for v2.3.0 schema changes, and version bumps to 2.3.0 across all projects.
Models & Data Contracts
Dashboard/Analysis/AnalysisModels.cs, Lite/Analysis/AnalysisModels.cs, Dashboard/Models/ServerConnection.cs, Dashboard/Models/CollectionHealthItem.cs
Introduces parallel AnalysisModels (Fact, AmplifierResult, Edge, AnalysisStory, AnalysisFinding, AnalysisMuted, AnalysisExclusion, AnalysisThreshold) in Dashboard and Lite; adds MonthlyCostUsd property to ServerConnection; changes AvgDurationMs from int to long.
UI Updates & Refresh Optimization
Dashboard/AddServerDialog.xaml*, Dashboard/ManageServersWindow.xaml*, Dashboard/Controls/*.xaml*, Dashboard/ServerTab.xaml.cs
Adds monthly cost input dialog (increased max height 700→850, new MonthlyCostTextBox), cost column in server grid, per-tab refresh optimization (fullRefresh parameter), and SubTabControl named references for selective tab refreshing in Memory/Query/Resource/SystemEvents.
Test Infrastructure
Lite.Tests/*.cs
Comprehensive test suites: AnalysisServiceTests, FactCollectorTests, FactScorerTests, InferenceEngineTests, FindingStoreTests, HealthCalculatorTests, ScenarioTests, FactCollectorMiseryTests, FinOpsTests with extensive seeding and assertion coverage across memory pressure, blocking, CPU, disk, and clean server scenarios.
SQL & Database Services
Dashboard/Services/DatabaseService.cs, Dashboard/Services/DatabaseService.QueryPerformance.cs
Adds plan XML retrieval methods (GetPlanXmlByQueryHashAsync, GetProcedurePlanXmlBySqlHandleAsync) with 120s timeout, AvgDurationMs type change, and improved Dop field handling via Convert.ToInt16.
Utilities & Helpers
Dashboard/Services/DataGridFilterManager.cs, Dashboard/Services/EmailTemplateBuilder.cs, Dashboard/MainWindow.xaml.cs, Dashboard/Services/ShowPlanParser.cs, Installer.Tests/Helpers/*
Adds generic DataGridFilterManager with column-level filtering and state persistence; extends email alerts for server offline/restored events; fixes ShowPlanParser RetrievedFromCache alignment; provides test helpers (TempDirectoryBuilder, TestDatabaseHelper) for installer tests.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

@erikdarlingdata erikdarlingdata merged commit 876dd0b into main Mar 18, 2026
4 of 5 checks passed
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