Repository navigation
The PostgreSQL engine absorbs what the v2 lanes reported back: the I/O and WAL baseline tables are floored, the I/O baseline restores hour-of-week at a quarter-hour grain, the WAL co-fire reads the anomaly and not a base-0 fact, a Lock wait reaches its idle holder, and the blocking family exists as stubs for lane 17 (partial #3691, between waves) - #3737
Merged
Merged
Conversation
…tables are floored at the baseline window, the I/O baseline restores hour-of-week at a quarter-hour grain with a 250-read floor, the WAL co-fire reads the anomaly instead of a base-0 context fact, a Lock wait walks to its idle-in-transaction holder, the idle fact gets its horizon and blocking reads, the wave-3 blocking family exists as stubs, and a census makes an unrouted key impossible
This was referenced Sep 19, 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.
What does this PR do?
Headline mechanism. The between-waves shared-file batch of #3691 — what #3688 was for v1. Four content lanes of the v2 wave (11 I/O, 12 replication, 14 idle-in-transaction, 15 WAL volume) each reported items they could not make inside their file-disjoint boundary: two baseline tables nobody floored, a baseline grain that could never restore hour-of-week, a co-fire that read a fact whose base severity is 0 by design, an edge lane 14 could not declare without moving lane 5's pin, next-reads the idle fact's advice names but its row did not, three stale docs and a tool description two engines share. This PR decides and makes all of them as one shared-file change, adds the census that makes the class of miss lane 14 found (a declared key no root dispatcher routes) impossible, and lays the wave-3 stubs for the blocking family (lane 17) so that lane never touches a shared file. PARTIAL for #3691 — do not close. No checklist line on #3691 is this PR's; the body says what it does for the coordinator to record.
The lies it stops telling
DarlingRetentionHorizons.BaselineServingRawCollectorsfloors a baseline-serving table's purge horizon at the 30-day baseline window (PostgreSQL baselines survive a shortened retention, and pg_cpu carries the CPU dispersion floor, so a 7-day PG retention no longer silently switches anomaly detection off (#3691) #3711 for the v1 four; lane 12 addedpg_replication_statswith its arm). Lane 11'spg_io_statsand lane 15'spg_write_statsservepg_io_read_latencyandpg_wal_bytes_per_secdirectly and were unfloored: an operator setting PostgreSQL retention to 7 days would have emptiedANOMALY_PG_IO_LATENCYandANOMALY_PG_WAL_VOLUMEwith nothing said. Both are floored now, andBaselineSupplyTestsno longer keeps a hand list — it derives the expected set by reflecting everyMetricNames.Pg*constant, asking the provider for its SQL, and collecting everyFROM pg_*it names. The next arm without a floor fails there by construction.pg_io_read_latencyat the HOUR grain; the scaffold keys rows by hour-of-day × day-of-week, so one row an hour is one sample per hour-of-week bucket per week — four or five in 30 days, underBaselineMath.RestoreThreshold(15) — andSelectBucketcollapsed to hour-of-day at 0.85 confidence on every pass; lane 11's live e2e pinned the collapse and reported it. The baseline arm and the detector's window read now bucket at 15 minutes (date_bin('15 minutes', collection_time, TIMESTAMP '2000-01-01')— a fixed quarter-hour origin so every server samples at :00/:15/:30/:45) under a 250-read per-sample floor (PgTargetScorer.IoBaselineBucketMinimumReads, a quarter-hour's share of the collector's hourlyIoMinimumOps, which the window fact keeps). The ms-per-read quotient survives re-bucketing (a ratio of two sums is the same ratio over any partition of the rows); 16–20 samples per bucket restore the Full tier. Lineage: the restore threshold served is engine-defined; the 250 is unmeasured and says so — §B1 distributed reads per HOUR (per-server p50 spanning 1–790 k) and never a per-quarter-hour count — and it is a sample-ADMISSION floor, not a grading bar, so the anomaly keepsthreshold_lineage = 1for its measured fire bars and publishes the floor beside them asbucket_reads_floor. The live e2e's pin flips fromHourOnly / 0.85toFull / ≥ 0.8, deliberately; the advice's "peak HOURLY … 1,000-read floor" sentence follows the grain.PG_WAL_VOLUME_SHIFT → PG_SLOT_RETENTIONand two amplifiers (on the lag fact and the slot fact) reading the shift'sBaseSeverity > 0; lane 15 shipped the shift as a CONTEXT fact (base 0 by design, the numbers for the advice) with the judgment inANOMALY_PG_WAL_VOLUME.InferenceEnginewalks edges only from facts in the fired set, andBaseSeverity > 0on a base-0 fact is never true — so the edge could not open and neither amplifier could match; the two advice sentences that readSeverity > 0on the shift never rendered either. The edge is gone; both amplifiers and both sentences read the anomaly (ANOMALY_PG_WAL_VOLUME co-fired — …), the shape lane 15 used for the checkpoint trigger amplifier. No edge from the anomaly either — it folds ontoPG_CHECKPOINT_PRESSUREandPgTargetWriteTestspins it has no edges.PgTargetKnobsTests' membership pin on the shift edge andPgTargetReplicationTests' two pins moved with it, each saying why.PgTargetWaitTestspinned themSingle. Declared now from the partial that owns the Lock waits' edges (PgTargetRelationshipGraph.Saturation.cs— lane 5 wrote the saturation mesh there; one source node's edges live in one place), predicate on the idle fact's BASE severity, NOT gated on the saturation share (the pool need not be full for a parked holder to be what the waiters are behind). A Lock wait with no idle fact keeps exactly its previous single active edge — pinned byte-identical. TheSinglepins became two-destination pins; the file'sAddEdgecount 9 → 11.get_pg_xmin_horizonandget_pg_blocking; the row offered onlyget_pg_session_states. Both added, after the session read.The items, as decided
pg_io_stats/pg_write_statsunfloored (11, 15)DailySummaryHorizon.csset + doc;BaselineSupplyTestsderives the set from the provider's SQL over everyMetricNames.Pg*const (a stub arm contributes nothing)PgTargetBaselineProvider.Io.cs,PgTargetAnomalyDetector.Io.cs(SQL + metadatarated_samples/peak_sample_reads/peak_sample_ticks/bucket_reads_floor),PgTargetScorer.Io.csnew const with lineage,PgTargetAdvice.Io.csprosedate_binexpression twice in each read; same floor literal beside the constant's name in both; noreads >= 1000left; collector SQL carries no floor; live e2e:Fulltier, ≥ 15 samples, confidence 0.8–1.0,peak_sample_reads ≥ 250,bucket_reads_floor = 250WalVolumeShift → SlotRetentionedge (15)PgTargetRelationshipGraph.Replication.cs,PgTargetScorer.Replication.cs,PgTargetAdvice.Replication.csANOMALY_PG_WAL_VOLUME co-fired;GetAllEdges(WalVolumeShift)empty; source: noWalVolumeShifttoken in either filePgTargetRelationshipGraph.Saturation.cs(+2 edges, traversal para rewritten)[Lock:relation, PG_IDLE_IN_TRANSACTION]; holder outranks (1.2 vs 0.688):[idle, Lock:relation]; saturation-only: single active edge, path[Lock:relation, saturation]; under-floor idle with inflated Severity opens nothing; every Lock edge lives in this file+ get_pg_xmin_horizon,+ get_pg_blockingPgTargetToolRecommendations.csPgTargetAdvice.Sessions.cs; the McpSurface census verifies registrationpg_blocking; keysPG_BLOCKING_CHAIN,PG_LOCK_WAIT_EVENTS,PG_LONG_RUNNING_QUERY,ANOMALY_PG_BLOCKING;MetricNames.PgBlockedSessions;AnomalyToFamiliesfold; deviation-scored membership; six stub files/* filled by lane 17 */; root arms in scorer / advice / graph / collector / detector / baseline;ComposeAnomalyhook (ComposeBlockingAnomaly, a partial declared in the root so lane 17 never edits the anomaly partial); tool rowsPgTargetFactKeys.cs,MetricNames.cs,FactScorer.KnownSources29 → 30, both SKUs'get_analysis_factssource list, 6 new files, 7 root files,PgTargetToolRecommendations.csaurora_stat_; whitelist pinned by name forpg_log_events/pg_session_states(pg_blocking_edges,pg_lock_statsalready pinned)PgTargetSharedSwitchRoutingTestsEveryDeclaredPgKey_IsRoutedByEveryRootDispatcher_OrExcludedHereByNamePG_key named inAmplifiersandComposeor excluded by name with reason (10 / 2 exclusions, each also asserted NOT routed so a stale exclusion fails); everyANOMALY_PG_key has acaseinComposeAnomaly; every source has aScoreBasearm; the four prefix arms by exact text; every key has a tool rowPgTargetBaselineProvider.csD10 para (seven tables, floored);PgTargetFactKeys.WalVolumeShiftdoc (context fact; the anomaly carries the co-fire; no edge);PgTargetAnomalyTestsfence test renamed…FencesEachOfEightFilledDetectors…and extended to the three v2 partials, the blocking stub named as the exemptioncompare_analysisdescription + band rule (since #3713)BandRulesPayload.baselinesays "the reading's delta"DarlingMcpTools.cs,Lite/Mcp/McpAnalysisTools.cs,ComparisonBanding.cspg_metric; the rule textLeft undone, deliberately: nothing from the brief. Item 3 went one step further than asked — the LAG fact's WAL amplifier and both advice sentences had the same base-0 defect as the slot's and are fixed with it (falsified-code rule, same PR).
Censuses that fired, and how each was satisfied
PgTargetFactCollectorTests: collect surface 15 → 16, stub files 13 → 14,Blocking.csmarker pinned; whitelist gains two named pins (tables already catalog targets, no admission). Edited deliberately (the plumbing precedent).PgTargetSharedSwitchRoutingTests: sources 14 → 15;AnomalyToFamiliesgains the blocking fold; advice delegation census gains fourNulllines for the stubs (null IS the delegation); the new routing census.PgTargetAnomalyTests: anomaly keys 8 → 9 (deviation-scored); the inert-stub loop gainsPgBlockedSessionsand the two Darling stub files; the detector order check gains the blocking call; fence test renamed and extended.FactSourceRegistryTests: 29 → 30 with the sentence extended.PgTargetMcpSurfaceTests: derived — rows added for the four keys, no edit.PgTargetIoTests: constants pin, baseline-arm pin, detector pin, static-advice pin and the live e2e's tier pin — each moved with the grain, each saying so.PgTargetWaitTests: the twoSinglepins → two destinations.PgTargetSessionsTests:AddEdge9 → 11.PgTargetReplicationTests/PgTargetKnobsTests: the shift-edge pins →Empty.BaselineSupplyTests: hand list → derivation.PgTargetThresholdLineageTests(new const carriesunmeasured; no new comparison line),StoreSqlClockDisciplineTests,DocCommentHygieneTests,RepoFileAdoptionTests(single-line anchors;ReadRepoFile, notLf),CommentFilterAdoptionTests,AuroraOnlySqlIsGatedTests(no newaurora_stat_mention),LiveCleanupConversionRatchetTests: green, no edit.Blast radius
SQL Server pass: byte-identical. The only shared-class edits are
FactScorer.KnownSources(+1pg_member the registry sweep requires),ComparisonBanding.BandRulesPayload(one word of prose), and both SKUs' two description strings. No shared switch changed; the routing pins that proved v1's byte-identity pass unchanged. PostgreSQL pass: a Lock-wait root now walks to a fired idle holder (one story where there were two); a slot-retention or lag finding beside a fired WAL anomaly is lifted 0.2 and its advice says so (previously never); the I/O anomaly is judged against the hour-of-week bucket (previously hour-of-day) and its metadata keys arepeak_sample_*(previouslypeak_hour_*— read by no tool or view; grepped); a 7-day PostgreSQL retention now keeps 30 days ofpg_io_stats/pg_write_stats. The blocking stubs emit nothing. No schema, no rung, noStorageVersionbump (V135 is dev's).What it does NOT do
No blocking content (lane 17). No Aurora suppression of checkpoint pressure (the residue lane). No
MaintenanceShapeShiftstub (v3). No second calibration read — the 250 floor is stated unmeasured. No two-sided TPS banding (v3 on #3691). No Lite twin beyond the two literals (D1).Test plan
New
Darling/Darling.Tests/PgTargetBetweenWavesV2Tests.cs(7 tests, the table above) and the routing census inPgTargetSharedSwitchRoutingTests. Executed here, not only compiled — a net10.0 harness (AssemblyName=Darling.Tests, the 45-file PgTarget census set incl.BaselineSupplyTests,PgTargetReplicationTests,PgTargetWriteTests,PgTargetBloatTests,PgTargetDeadlockDrillDownTests) against a throwawaytimescale/timescaledb:2.28.1-pg18on Docker contextdesktop-linux, migrated by the fixture, torn down after: 635 / 636 green, the one red being the harness csproj's own presence trippingDocCommentHygieneTests.TheDerivedProjectListCoversEveryProjectInTheTree(the artifact #3665 / #3688 / #3715 each recorded). That run includes everyDARLING_TEST_PG-gated e2e in the set — lane 11'sThirtyOneDaysAtOnePointFiveMs_…executed alone as well (1 / 1 green) with the flippedFull-tier expectation, so the exit criterion (analyze_serveron the planted Aurora 17 target: latency finding ≥ 1.1375 with its anomaly in the same incident) holds at the new grain.Builds, zero warnings of ours:
PerformanceMonitor.Analysis,PerformanceMonitor.Darling.Service(pulls Darling.Analysis + Storage),Darling.Tests,Lite.Tests,deprecated/Dashboard.Tests(-p:EnableWindowsTargeting=trueon the test projects). The oneLite.Testswarning (LogTailOverlapThresholdPinTests.cs:95xUnit2000) is pre-existing on dev. CI's Windows job is the first execution of the Lite pins on the two Lite literals.Which component(s) does this affect?
get_analysis_factssource list and thecompare_analysisdescription — census pins)How was this tested?
Above. No production store or fleet server was read; the rig was a local container, torn down.
Checklist
dotnet build -c Debug)Partial for #3691 (between waves; wave-3 stubs for the blocking family, lane 17). CHANGELOG deliberately untouched — the coordinator splices this wave's entries.