Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,6 @@ updates:
nuget:
patterns:
- "*"
ignore:
# The MCP SDK 2.x major changes runtime behavior on both MCP hosts (stateless-by-default
# HTTP, discovery-first negotiation, deprecated Roots/Sampling/Logging APIs) and must move
# in every referencing project + lockfile at once — a grouped auto-bump half-applied it and
# poisoned the whole group (#1822). Majors are taken deliberately via #1990; minors/patches
# keep flowing. Remove this once #1990 lands.
- dependency-name: "ModelContextProtocol*"
update-types: ["version-update:semver-major"]

# GitHub Actions used by the workflows in .github/workflows.
- package-ecosystem: "github-actions"
directory: "/"
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- **Both MCP hosts move to ModelContextProtocol SDK 2.0 (the MCP 2026-07-28 specification)** ([#1990]) - taken deliberately rather than riding a routine bump, because the 1.x-to-2.x major changes HTTP transport behavior and a grouped auto-bump had already demonstrated the failure mode (half-applied across projects, poisoning every lockfile - [#1822]). The version moves in every referencing project in one commit (shared Common, Lite, the Darling service, the deprecated Dashboard) with all lockfiles regenerated together under the CI-pinned SDK. **No code changes were needed**: 2.0's headline behavior switch - stateless-by-default HTTP - is a no-op here because both hosts have run \`Stateless = true\` explicitly since [#1074] (clients that don't echo \`Mcp-Session-Id\` otherwise connect but list zero tools), and the deprecated-API audit (Roots/Sampling/Logging) found no usage in either host or the shared tool plumbing. The Host-header/bearer/CIDR guards install ahead of \`MapMcp\` as pipeline middleware, so 2.0's discovery-first endpoint surface routes through the same checks - verified live against the SDK 2.0 host: initialize/tools-list/tools-call succeed statelessly and a non-loopback Host is still rejected before any handler. The SDK 2.0 surface was additionally validated end-to-end on Performance Studio's identical hosting stack before this migration. With the major taken, the Dependabot ignore rule that deferred \`ModelContextProtocol*\` majors to this issue is removed, so future SDK patches and minors resume flowing through the weekly group.

- **`get_analysis_findings` now returns one entry per diagnostic chain instead of one per engine cycle - a 24h read shrinks ~28x** ([#2000], found dogfooding the MCP surface on the 52-replica production monitor) - the analysis engine re-persists the same stories every cycle, so a multi-hour read returned each chain dozens of times, every occurrence re-carrying the full advice prose and copy-paste remediation command: measured fleet-wide, 21,623 rows in 24 hours collapse to 774 distinct (story, incident) chains - 27.9x mean duplication, 39x on the worst server, ~257KB for a single server's 10-hour read. Both MCP twins (and Darling's web API bridge) now group by `story_path_hash` + `incident_id` and return the chain's LATEST occurrence - value-bearing advice is frozen at analysis time, so latest is current truth - plus the stats that replace the collapsed timeline: `occurrences`, `first_seen`, `last_seen`, and `peak_severity`, which matter because severity genuinely moves within a chain (275 of the 774 measured groups spread more than 0.1). `finding_count` counts deduplicated chains and a new `total_occurrences` reports the raw rows, so the compression is visible rather than silent. The read also stops being quietly WRONG at depth: the store read's row cap of 100 covered only the ~5 most recent cycles of a 24h request and silently dropped the rest, so the findings tools now pass a window-covering cap sized for the deepest legal read - occurrence stats computed over a truncated read would lie about `first_seen` - and a read that ever FILLS that cap says so in a `truncation_note` instead of under-reporting silently. The store keeps every occurrence; nothing changes for viewer timelines or what is persisted.

- **Memory-pressure anomalies no longer fire on healthy servers with young baselines** ([#1996], found dogfooding the robust-baselines nightly on the 52-replica production monitor) - every server on the fleet reported the same self-contradicting finding, "Memory pressure spiked to 100% - 0σ above its 100% baseline for this time of week", 1,279 times across two eras. The mechanism, proven against the store rather than guessed: memory's absolute-fallback bar sat at 95%, BELOW the metric's healthy operating value - a warmed-up SQL Server holds total ≈ target = 100% by design, and the fleet's median is exactly 100.0 on every server - so whenever a baseline bucket was too young to trust (403 of 406 firing buckets had exactly 2 distinct days, one under the Full tier's floor of 3, with ~82 samples each), the untrustworthy-baseline path fired the absolute bar on completely normal behavior and displayed the honest-but-absurd 0σ. The bar moves to 101: total EXCEEDING target is genuine over-target pressure and still fires; total sitting at target stays silent however thin the baseline. Pre-existing (identical findings before the robust upgrade), young-store-shaped (it would have faded as buckets crossed the day floor, then returned with every new server), and exactly the class of thing the dogfood loop exists to catch - the finding volume was the single largest noise source on the MCP surface, 31 of the busiest tenant's latest 100 findings.
Expand Down Expand Up @@ -2473,3 +2475,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#1606]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/1606
[#1996]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/1996
[#2000]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/2000
[#1074]: https://github.com/erikdarlingdata/PerformanceMonitor/issues/1074
61 changes: 38 additions & 23 deletions Darling/Darling.Tests/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,15 @@
},
"Microsoft.Extensions.AI.Abstractions": {
"type": "Transitive",
"resolved": "10.5.2",
"contentHash": "Ei+YWV9Ybnps7pR1dgjlG29gelXEwZkhLVAcWmKe6HvXS6LNBYgSdWiY3Hk9OZXYtK34rv/NtLWBQYQGOBQYPQ=="
"resolved": "10.8.3",
"contentHash": "K0B05oApxmviWalNHPMBBcRC7erKiDATz3ENNR/jqTR9JwIwLRefgDhj2jCRwL1aca99pXUe0qyQC73/xIuZig=="
},
"Microsoft.Extensions.Caching.Abstractions": {
"type": "Transitive",
"resolved": "10.0.7",
"contentHash": "pUDgQKEqNUFlerDIFRg7zzoDVRPEWIG7nR40h8Gzg8RXza4Ry0lWZ7u91bmwu3iUDCxw3Dv6TLHVFoAgY0gy7Q==",
"resolved": "10.0.10",
"contentHash": "4ZFBNE+jzR+CrWWlhOesnmywCW7pYKT0dxyAQRdL11yJwxe4jvcAu31eorFtEkoFeCDcUTeNssgPv2yaRRptaQ==",
"dependencies": {
"Microsoft.Extensions.Primitives": "10.0.7"
"Microsoft.Extensions.Primitives": "10.0.10"
}
},
"Microsoft.Extensions.Caching.Memory": {
Expand Down Expand Up @@ -386,7 +386,8 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10",
"Microsoft.Extensions.Logging": "10.0.10",
"Microsoft.Extensions.Logging.Abstractions": "10.0.10",
"Microsoft.Extensions.Options": "10.0.10"
"Microsoft.Extensions.Options": "10.0.10",
"System.Diagnostics.EventLog": "10.0.10"
}
},
"Microsoft.Extensions.Logging.EventSource": {
Expand Down Expand Up @@ -529,29 +530,29 @@
},
"ModelContextProtocol": {
"type": "Transitive",
"resolved": "1.4.1",
"contentHash": "mP5hvBpoWe5EbWBqHWD09A4Dy6Pq+/vV2dumOV4uegCZcg+yqf8q8wrxtuZ3EQyXEJn9jzsnoiI/qyfJAihlZQ==",
"resolved": "2.0.0",
"contentHash": "X/KDNZDP9Zgs7YXXxxpKiDMWWPXYrs764lVgc6vEM4pCg87bYz4VaceeiKW91XDTGgUvIbmRYXgWqyNpV32xRg==",
"dependencies": {
"Microsoft.Extensions.Caching.Abstractions": "10.0.7",
"Microsoft.Extensions.Hosting.Abstractions": "10.0.7",
"ModelContextProtocol.Core": "1.4.1"
"Microsoft.Extensions.Caching.Abstractions": "10.0.10",
"Microsoft.Extensions.Hosting.Abstractions": "10.0.10",
"ModelContextProtocol.Core": "[2.0.0]"
}
},
"ModelContextProtocol.AspNetCore": {
"type": "Transitive",
"resolved": "1.4.1",
"contentHash": "AoI+00fRxb0GAMMabMUgpV5QhNoa/F7I9oiVGHfJKtBZ4g/DEyoDdTS9Rp/m4e3MnXhhvSBeu2wTafhesdf52w==",
"resolved": "2.0.0",
"contentHash": "dXrB7sBpQjUQU0UcdyFPJbOTFw7yaceD+OgAZVAeBveRzbiBlg89jEygAtcgOwd/L+O+YpM98zfwaXz067NFDQ==",
"dependencies": {
"ModelContextProtocol": "1.4.1"
"ModelContextProtocol": "[2.0.0]"
}
},
"ModelContextProtocol.Core": {
"type": "Transitive",
"resolved": "1.4.1",
"contentHash": "G/hOBZkJsvF3MSy0sOvXdxca5uRe2Sb4xk7xRuTWNZI45khVBjOLo6nSzGilctIICavNVxbxUF908fLYI9RxkQ==",
"resolved": "2.0.0",
"contentHash": "piFR0HtA/2Oc1tgk96EE5Tye6qA2sg3WGRAXBhUqo/BWikdEYEs2UuqtmwLrQZJUge1nUOPgGHYsb15VIBK8iw==",
"dependencies": {
"Microsoft.Extensions.AI.Abstractions": "10.5.2",
"Microsoft.Extensions.Logging.Abstractions": "10.0.7"
"Microsoft.Extensions.AI.Abstractions": "10.8.3",
"Microsoft.Extensions.Logging.Abstractions": "10.0.10"
}
},
"Npgsql": {
Expand Down Expand Up @@ -732,6 +733,11 @@
"SkiaSharp.Views.Desktop.Common": "3.119.0"
}
},
"System.Diagnostics.EventLog": {
"type": "Transitive",
"resolved": "10.0.10",
"contentHash": "OvGz3PrzuAI/Sj7LTcXcCe3FClRI1IyRMZjNONcZtFh+Ww7nAtSh4kh08r8KVe/xxkXJPjR0Y1jF7H+N42d4xQ=="
},
"System.IdentityModel.Tokens.Jwt": {
"type": "Transitive",
"resolved": "8.16.0",
Expand All @@ -746,10 +752,18 @@
"resolved": "5.0.0",
"contentHash": "SxHB3nuNrpptVk+vZ/F+7OHEpoHUIKKMl02bUmYHQr1r+glbZQxs7pRtsf4ENO29TVm2TH3AEeep2fJcy92oYw=="
},
"System.Security.Cryptography.ProtectedData": {
"type": "Transitive",
"resolved": "10.0.10",
"contentHash": "BKt0SQgq2lq3ESE68jkeLwv95ypANrPDtkTOIFGcnhg2aRUeUUBDrQlkVDZctrg1WenVcvn5P5XZnuYI7q6rFQ=="
},
"System.ServiceProcess.ServiceController": {
"type": "Transitive",
"resolved": "10.0.10",
"contentHash": "9tI/EtlMimwJn9EEtbqFrVqGCD98VfVdnW6UekC7/YHO5Ky/LMUfXibBv9+AV8g9u7uim20oHgiOqzaeEWAhqg=="
"contentHash": "9tI/EtlMimwJn9EEtbqFrVqGCD98VfVdnW6UekC7/YHO5Ky/LMUfXibBv9+AV8g9u7uim20oHgiOqzaeEWAhqg==",
"dependencies": {
"System.Diagnostics.EventLog": "10.0.10"
}
},
"Velopack": {
"type": "Transitive",
Expand Down Expand Up @@ -840,7 +854,7 @@
"dependencies": {
"CredentialManagement": "[1.0.2, )",
"Microsoft.Extensions.Logging.Abstractions": "[10.0.10, )",
"ModelContextProtocol": "[1.4.1, )"
"ModelContextProtocol": "[2.0.0, )"
}
},
"performancemonitor.darling.analysis": {
Expand All @@ -860,15 +874,16 @@
"Microsoft.Data.SqlClient": "[7.0.2, )",
"Microsoft.Extensions.Hosting": "[10.0.10, )",
"Microsoft.Extensions.Hosting.WindowsServices": "[10.0.10, )",
"ModelContextProtocol": "[1.4.1, )",
"ModelContextProtocol.AspNetCore": "[1.4.1, )",
"ModelContextProtocol": "[2.0.0, )",
"ModelContextProtocol.AspNetCore": "[2.0.0, )",
"PerformanceMonitor.Alerting": "[1.0.0, )",
"PerformanceMonitor.Collectors": "[1.0.0, )",
"PerformanceMonitor.Common": "[1.0.0, )",
"PerformanceMonitor.Darling.Analysis": "[1.0.0, )",
"PerformanceMonitor.Darling.Storage": "[1.0.0, )",
"PerformanceMonitor.PlanAnalysis": "[1.0.0, )",
"System.IO.FileSystem.AccessControl": "[5.0.0, )"
"System.IO.FileSystem.AccessControl": "[5.0.0, )",
"System.Security.Cryptography.ProtectedData": "[10.0.10, )"
}
},
"performancemonitor.darling.storage": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
<!-- AN4: the analysis MCP tools over Streamable HTTP — Lite's exact MCP stack/version.
The AspNetCore package brings the Microsoft.AspNetCore.App framework reference
(Kestrel/WebApplication) transitively, same as it does for Lite. -->
<PackageReference Include="ModelContextProtocol" Version="1.4.1" />
<PackageReference Include="ModelContextProtocol.AspNetCore" Version="1.4.1" />
<PackageReference Include="ModelContextProtocol" Version="2.0.0" />
<PackageReference Include="ModelContextProtocol.AspNetCore" Version="2.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
76 changes: 38 additions & 38 deletions Darling/PerformanceMonitor.Darling.Viewer/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,15 @@
},
"Microsoft.Extensions.AI.Abstractions": {
"type": "Transitive",
"resolved": "10.5.2",
"contentHash": "Ei+YWV9Ybnps7pR1dgjlG29gelXEwZkhLVAcWmKe6HvXS6LNBYgSdWiY3Hk9OZXYtK34rv/NtLWBQYQGOBQYPQ=="
"resolved": "10.8.3",
"contentHash": "K0B05oApxmviWalNHPMBBcRC7erKiDATz3ENNR/jqTR9JwIwLRefgDhj2jCRwL1aca99pXUe0qyQC73/xIuZig=="
},
"Microsoft.Extensions.Caching.Abstractions": {
"type": "Transitive",
"resolved": "10.0.7",
"contentHash": "pUDgQKEqNUFlerDIFRg7zzoDVRPEWIG7nR40h8Gzg8RXza4Ry0lWZ7u91bmwu3iUDCxw3Dv6TLHVFoAgY0gy7Q==",
"resolved": "10.0.10",
"contentHash": "4ZFBNE+jzR+CrWWlhOesnmywCW7pYKT0dxyAQRdL11yJwxe4jvcAu31eorFtEkoFeCDcUTeNssgPv2yaRRptaQ==",
"dependencies": {
"Microsoft.Extensions.Primitives": "10.0.7"
"Microsoft.Extensions.Primitives": "10.0.10"
}
},
"Microsoft.Extensions.Caching.Memory": {
Expand All @@ -120,10 +120,10 @@
},
"Microsoft.Extensions.Configuration.Abstractions": {
"type": "Transitive",
"resolved": "10.0.7",
"contentHash": "t56nEgvECcyLPojZIUFWJknQQDAbgfTf9J+QMYJE1YYvVgz69vN6B/AKL8Grvj3Lcnp8kTpNqwmwFhb3YLJmtQ==",
"resolved": "10.0.10",
"contentHash": "5Vnd2I75DmZCVEjSynIdJ/0EGafgnLQwgR3t2C2/fkjx/nRG+cLwxLLdInoHeCEpkD5K4Ov/g9ZCRYrl4TRsaA==",
"dependencies": {
"Microsoft.Extensions.Primitives": "10.0.7"
"Microsoft.Extensions.Primitives": "10.0.10"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
Expand All @@ -133,31 +133,31 @@
},
"Microsoft.Extensions.Diagnostics.Abstractions": {
"type": "Transitive",
"resolved": "10.0.7",
"contentHash": "uJ9JP677y+uy+C0vtaSfi7XXgFAdz8DhU3M9lwwIXDfQKcyQ0yxM9DVYa0NXDtdVTYA2eBUtVFZ8LY0GCdeE/w==",
"resolved": "10.0.10",
"contentHash": "9uWiKpeOVac355STyChWR/pliFX/5CeLqChW9kKsaxyDH4EUTZxMkT4Jwp/J/peLm0GBFmSX5c0WCse3yCnq1Q==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.7",
"Microsoft.Extensions.Options": "10.0.7"
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10",
"Microsoft.Extensions.Options": "10.0.10"
}
},
"Microsoft.Extensions.FileProviders.Abstractions": {
"type": "Transitive",
"resolved": "10.0.7",
"contentHash": "teioDgVpi8L186wUfrXQV1YuBt6lCSPmFZiMZo53+FZxHFjOV+f4GXo4LXgJ273Mku9//AdXWVjk9J7eJP6inw==",
"resolved": "10.0.10",
"contentHash": "c5zqFCY9DiIpMovLd7/d/CTiEtrMOuQ639dhv3PABtKQIKNQikSHwQt8+N679uii9q+B55lgK28Uv64FOwEu8w==",
"dependencies": {
"Microsoft.Extensions.Primitives": "10.0.7"
"Microsoft.Extensions.Primitives": "10.0.10"
}
},
"Microsoft.Extensions.Hosting.Abstractions": {
"type": "Transitive",
"resolved": "10.0.7",
"contentHash": "5s8d6qC6EA8UOI4wR/+zlsq7SXttJMRb9d7zvVZ7+bE3CQEfVtC9ITUDCommm87R1zzj6WJBbCnztuIJXnP3DA==",
"resolved": "10.0.10",
"contentHash": "5LugpYGHk+mkn0a8IZgcyfBca8PCTAU9RQFoMrTdtOOidq88M2SI5f3px6ugnzgxC+eTkvYYJi8pzlUnG5xdAQ==",
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "10.0.7",
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.7",
"Microsoft.Extensions.Diagnostics.Abstractions": "10.0.7",
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.7",
"Microsoft.Extensions.Logging.Abstractions": "10.0.7"
"Microsoft.Extensions.Configuration.Abstractions": "10.0.10",
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10",
"Microsoft.Extensions.Diagnostics.Abstractions": "10.0.10",
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.10",
"Microsoft.Extensions.Logging.Abstractions": "10.0.10"
}
},
"Microsoft.Extensions.Logging.Abstractions": {
Expand All @@ -170,17 +170,17 @@
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "10.0.7",
"contentHash": "00SHUGTh2jSMvIr6x9Xwd2nE+B5/qFCO/9hDwUDhJsjYRDlADmaBZ7tqehXzBDsfjHSXJzuRHJzPYPPjphBQ7Q==",
"resolved": "10.0.10",
"contentHash": "srnhnk7nE8krBiIXp71LvBmKBtraBONWSRzdjJgRv1Ko9Mp8IVNqv4vIS9hGeVteBig8aQkva9ZG+sC+o5sVcA==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.7",
"Microsoft.Extensions.Primitives": "10.0.7"
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10",
"Microsoft.Extensions.Primitives": "10.0.10"
}
},
"Microsoft.Extensions.Primitives": {
"type": "Transitive",
"resolved": "10.0.7",
"contentHash": "D5M0Jr551iTgwkZMN9rm0pSkgNLj5quUWQUmQPMZh7k/bnvZTnXRGfE2KuvXf1EEjt/ofD9yw9IumpgdP9QCnw=="
"resolved": "10.0.10",
"contentHash": "5wu/GrYVd8mG2DVUw3vFJzF+O336TyTGg/Kmcgw9bfwYhCoFiV5lR5QeEmKecJyrW4W54nMfD3p3589E8a7czQ=="
},
"Microsoft.IdentityModel.Abstractions": {
"type": "Transitive",
Expand Down Expand Up @@ -236,21 +236,21 @@
},
"ModelContextProtocol": {
"type": "Transitive",
"resolved": "1.4.1",
"contentHash": "mP5hvBpoWe5EbWBqHWD09A4Dy6Pq+/vV2dumOV4uegCZcg+yqf8q8wrxtuZ3EQyXEJn9jzsnoiI/qyfJAihlZQ==",
"resolved": "2.0.0",
"contentHash": "X/KDNZDP9Zgs7YXXxxpKiDMWWPXYrs764lVgc6vEM4pCg87bYz4VaceeiKW91XDTGgUvIbmRYXgWqyNpV32xRg==",
"dependencies": {
"Microsoft.Extensions.Caching.Abstractions": "10.0.7",
"Microsoft.Extensions.Hosting.Abstractions": "10.0.7",
"ModelContextProtocol.Core": "1.4.1"
"Microsoft.Extensions.Caching.Abstractions": "10.0.10",
"Microsoft.Extensions.Hosting.Abstractions": "10.0.10",
"ModelContextProtocol.Core": "[2.0.0]"
}
},
"ModelContextProtocol.Core": {
"type": "Transitive",
"resolved": "1.4.1",
"contentHash": "G/hOBZkJsvF3MSy0sOvXdxca5uRe2Sb4xk7xRuTWNZI45khVBjOLo6nSzGilctIICavNVxbxUF908fLYI9RxkQ==",
"resolved": "2.0.0",
"contentHash": "piFR0HtA/2Oc1tgk96EE5Tye6qA2sg3WGRAXBhUqo/BWikdEYEs2UuqtmwLrQZJUge1nUOPgGHYsb15VIBK8iw==",
"dependencies": {
"Microsoft.Extensions.AI.Abstractions": "10.5.2",
"Microsoft.Extensions.Logging.Abstractions": "10.0.7"
"Microsoft.Extensions.AI.Abstractions": "10.8.3",
"Microsoft.Extensions.Logging.Abstractions": "10.0.10"
}
},
"Npgsql": {
Expand Down Expand Up @@ -446,7 +446,7 @@
"dependencies": {
"CredentialManagement": "[1.0.2, )",
"Microsoft.Extensions.Logging.Abstractions": "[10.0.10, )",
"ModelContextProtocol": "[1.4.1, )"
"ModelContextProtocol": "[2.0.0, )"
}
},
"performancemonitor.darling.analysis": {
Expand Down
Loading
Loading