Repository navigation
Add authored-notebook context plumbing (#4223) - #4425
Merged
Merged
Conversation
Adds the immutable AuthoredContext record, an optional context builder on AuthoredTemplateEntry validated at construction (exactly one builder), an Invoke call site, exact-then-longest-prefix routing with an empty prefix table, and an async pre-fetch (custom rule by id, analysis finding by 8-character hash) that runs only for context entries. Refs #4223.
erikdarlingdata
marked this pull request as ready for review
September 26, 2026 15:26
erikdarlingdata
added a commit
that referenced
this pull request
Sep 26, 2026
Adds the authored Custom-rules alert notebook. It's the first family that uses the context step from #4425. - Registers a Custom: prefix row (AuthoredContextKind.CustomRule) in s_authoredPrefixTemplates. The builder is in AlertNotebookEndpoint.Templates.CustomRules.cs. - The notebook holds a header, a status cell and one composed panel. The panel uses the rule's own stored plan: the same source, measure or ratio, aggregate and filters. It's forced to hour buckets over the alert window. The rule's thresholds (warning and critical, or both bounds of a range) appear as the panel's reference lines. - A deleted rule or a bad id gives a note that the rule no longer exists. A definition that can't be read gives a note saying so. Neither throws. - The pin that the production prefix table is empty now checks that it holds exactly the registered context families. - Tests: AlertNotebookTemplateCustomRulesTests, plus the shared template and context theories. Refs #4223
This was referenced Sep 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #4223.
Why
The alert-notebook endpoint's authored templates are pure and synchronous
today: they build cells from what
Mapalready has in scope, and nevertouch a store. The next authored families need the endpoint to read a
custom alert rule (
Custom:<id>) or a recent analysis finding(
Analysis: {category} [{hash8}]) before the template can render, withoutturning every builder into an async, store-aware function. This is the
core step: the plumbing those families will register into, with no family
template added yet.
What changes
Darling/PerformanceMonitor.Darling.Service/AlertNotebookEndpoint.cs:AuthoredContext(CustomRule, CustomRuleMissing, Finding, FindingMissing),with a shared
AuthoredContext.Emptyfor families that need nothing.AuthoredTemplateEntrygains an optionalBuildCellsWithContextdelegatealongside the existing
BuildCells. Its constructor rejects an entry withboth builders set or neither, so exactly one builder exists per entry.
Every existing registration row (
new AuthoredTemplateEntry("authored/x", V, BuildX))compiles unchanged.
AuthoredTemplateEntry.Invoke(...)is the single call site for bothshapes: it calls
BuildCellsWithContextwith the context for a contextfamily, or
BuildCellsfor a plain one. The endpoint's call site and theexisting
AlertNotebookAuthoredTemplateTeststheories now go throughInvokeinstead of callingBuildCellsdirectly.s_authoredPrefixTemplatesandAuthoredContextKindenum (None,CustomRule,AnalysisFinding).ResolveAuthoredresolves exact names first (unchanged), then thelongest matching prefix, ordinal case-insensitive; no match falls
through to the mechanical template.
ResolveAuthoredPrefixedtakes theprefix table as a parameter so tests can exercise prefix routing against
a table that isn't empty.
PrefetchAsyncreads exactly the store its resolvedAuthoredContextKindnames: a
Custom:<id>rule viaCustomAlertRuleStore.GetAsync, or anAnalysis: {category} [{hash8}]finding viaDarlingAnalysisService.GetRecentFindingsAsync, matched on the findingwhose full
StoryPathHashstarts with all 8 hash characters. A badparse, a deleted rule, or no matching finding sets the relevant missing
flag and returns an otherwise-empty context — never an exception,
per Alert deliveries lack Datadog-parity structure: no structured context tags, no linked triage artifact #2710's degrade rule. A store failure (not cancellation) is reported
through
DarlingWebFailureLog.Reportand adds a note to the response;cancellation propagates. The endpoint calls this only when the resolved
entry has
BuildCellsWithContextset and its kind isn'tNone, so ano-context family costs zero store reads.
New file
Darling/Darling.Tests/AlertNotebookAuthoredContextTests.cspinsall of the above (construction validation,
Invokerouting to the rightbuilder, exact-vs-prefix and longest-prefix-wins routing,
Custom:idparsing, the 8-character hash match, live cancellation and missing-rule
behavior, and the no-store-read guarantee for a no-context family).
Darling/Darling.Tests/AlertNotebookAuthoredTemplateTests.cs: only theentry.BuildCells(...)call expressions becameentry.Invoke(..., AlertNotebookEndpoint.AuthoredContext.Empty);nothing else in that file changed.
Test plan
dotnet buildonPerformanceMonitor.Darling.ServiceandDarling.Tests(with
-p:EnableWindowsTargeting=true): 0 errors on both.Darling.Tests.dll -class ...), against athrowaway
timescale/timescaledb:2.30.1-pg18container migrated withPgMigrations.MigrateAsync:AlertNotebookAuthoredContextTests: 24/24, including four live cases against the real container:ShouldPrefetch) is false for every registered family without a context builder, so none of them makes a store read.PickFindingByHash): two findings sharing a 4-character prefix are told apart at the 8th character.AlertNotebookAuthoredTemplateTests,AlertNotebookEndpointTestsandDocCommentHygieneTests: 154/154 combined, at the final head.AlertNotebookEndpointTests: 29/29 passed.DocCommentHygieneTests(required — this PR adds members near existingdoc blocks): 77/77 passed.
AuthoredContext,AuthoredContextKind,Invoke,ResolveAuthored,PrefetchAsync) don'texist on
dev, so the new test file and the edited theories are acompile-RED against the pre-fix code, not a runtime failure.
this PR touches.
Lite.Tests: untouched by this PR (no Lite-side changes).Mutation checks
ShouldPrefetchcheck where the notebook is built (always pre-fetch) makesBuildCellsAsync_NoContextFamily_MakesZeroPrefetchCallsfail (a pre-fetch counter moved for "Blocking Detected"). Restored, all pass.Constructor_BothBuildersSet_ThrowsandConstructor_NeitherBuilderSet_Throwsfail. Those two are the guard; a table-wide theory can't fail while every registered row is valid, so it's a backstop only.CHANGELOG entry
SECTION: None
ENTRY: None: internal notebook plumbing; the families that use it follow (#4223)