Repository navigation
Release 3.10.0: version, changelog, archive - #5548
Merged
Merged
Conversation
Version 3.9.0 to 3.10.0 in Directory.Build.props. The pending entries are spliced into CHANGELOG.md as [3.10.0] - 2026-10-08 with an Important entry for store migrations V158 through V170, then archived to docs/changelog/3.10.md with a regenerated census.
… upgrade ladder fixture
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.
Release checklist steps 1, 2, 2a and 4 for 3.10.0, on the dev side only. No dev to main PR, no tag, no GitHub release, nothing on main.
The splice covers every PR merged to dev through #5536 (merged 2026-10-08 08:05Z, dev 25983b8). PRs that land after this cut (#5528, #5532, #5537, #5543, #5540, the #5457 fix and the foreground-thread test fix) go in a follow-up splice PR. #5491 and #5545 have no entry by design.
What the seat's rulings changed (fix round 1)
Every change below is before -> after. The prose now lives in
docs/changelog/3.10.md;CHANGELOG.mdholds the compacted index, regenerated bysplit. The two new link definitions this needed ([#5052],[#5427]) are inCHANGELOG.md.[#5064 dev bea647e62 folded in: ...]and carried only([#5041]). After: the note is gone and the refs read([#5041], [#5064]). The window picker wording was already in the entry text.([#5016], [#5052])and the entry gains one sentence, checked against Custom view panels say a silent store's open timed out, whatever the driver wraps the timeout in, and the open-timeout test names the exception chain when it fails #5052's diff (PostgresOpenTimeout.IsTimedOutByClock,ClockSlackof 100 ms): a failure that arrives at or after the connection's timeout, less 100 ms, with no server answer and the caller still waiting, is also reported as "could not get a store connection in time"; a failure the server answered keeps its own message. Custom view panels say a silent store's open timed out, whatever the driver wraps the timeout in, and the open-timeout test names the exception chain when it fails #5052's other change, the fix for a flaky Windows CI test, is not product behavior and is not in the entry.([#5032], [#5029], [#5038], [#5028], [#5047]), with the four other entries kept word for word as indented sub-items under it. They moved from Fixed to Added with it. Reading taken: "fold" means one top-level entry that keeps every fact, so nothing is rewritten.([#4966], ...)for every member, with each member kept as an indented sub-item. The lead sentence is the only new text, and every clause of it is in a member. Two members changed: WEB: the web server page's grids say where their data starts (part of #4966) #5000 lost its two detail sentences (the Waiting Tasks 30-row cap and the one-hour probe note) as its "trim", and its table list moved into the sentence after the dash; Lite: Collection Log, System Events, Config Changes and Long Queries say where the data starts, and Duration Trends draws the whole range (#4966, group C) #4989's two refs became([#4989], [#4966]). MCP: four Lite tools say where their data starts, and the Queries tools print the window's start in UTC in both apps #5004 stayed its own Added entry (its instruction was only "trim").truncated) is unchanged, and a window of 90 minutes or less is not probed." Darling and Lite: a daily collector runs at a time of day you set, in every surface, and a schedule Reset clears it (#4938) #5018 lost the clause about a Viewer released before the change resetting only schedule rows. Ambiguous "LONG, trim": I took the smallest cut that drops detail and no headline fact.([#5018], [#5007]); the inline([#5007])in the text was removed.run_custom_view_panel, Active Queries and Current Waits in both apps, the Queries tab banner and the four MCP tools), all from Custom Views panels, Active Queries and Current Waits say where their data starts #4953's body.(#4986)in the text stays plain, as the buffer wrote it.([#5080], [#4902])and a closing sentence: it reverses part of FinOps: storage growth for a database with no history shows n/a instead of 0, in both apps #4902, which showed n/a for every table with no earlier sample; a table created inside the window now ranks by its current size and its percent stays n/a. Checked against Storage Growth counts a table created during the window as growing by its whole size (#5077) #5080's body.**Title** ([#N]) - text; the first sentence after the ref was reworded only enough to follow a dash (for example([#4946]), the longest window nearly every panel readsbecame([#4946]) - It is the longest window nearly every panel reads). collection_log compression: segment by collector as well as by server #4951 split its bold sentence: the title is "Darling compresses newcollection_logchunks by collector as well as by server" and the dash text is "Reading one collector decompresses only its own runs." A second PagerDuty recovery inside the alert cooldown now resolves the incident (#5469) #5470 is([#5470], [#5469]). Lite: Collection Log, System Events, Config Changes and Long Queries say where the data starts, and Duration Trends draws the whole range (#4966, group C) #4989 is([#4989], [#4966])(inside the data-start fold). WEB: the web server page's grids say where their data starts (part of #4966) #5000 is([#5000]) - ...(inside the fold). collection_log compression: segment by collector as well as by server #4951 keeps its issue-keyed ref.([#5427]). Checked against the PR body and its diff: the text lookup is bounded to the current and baseline ranges, the period joins use plain equalities, a NULL key and an empty key no longer merge in the outer join, the Query Store inline-text fallback is bounded in the viewer and the MCP reader, and Lite is unchanged. The numbers are the PR's rig table (procedure comparison, 15 days seeded): 24 h, 12.5-30.5 s before and 0.23-0.28 s after; 7 d, 24.4-27.5 s before and 1.6-3.1 s after. It also says a procedure whose only captured text is older than the window now shows no text, as the PR documents.Darling/Darling.Tests/Fixtures/migration-ladder-v3.9.0.sqlis new: generated from agit worktreeof tag v3.9.0 withDarling/tools/generate-ladder-fixtureand-p:StorageProject=pointing at that worktree's storage project (156 rungs, top V157, which is the 3.9.0 SchemaVersion). The worktree is removed.MigrationUpgradeLadderLiveTestsran against a throwaway PostgreSQL (stopped and deleted after): Total 7, Failed 0.Counts after the rulings: 257 index lines for 257 archived entries in 3.10.0 (before: 275). 275 - 4 (snapshot-time fold) - 15 (data-start fold: 16 lines into 1) + 1 (#5427) = 257. The splice covers 255 buffer PRs plus #5255, #5259 and #5427; #5052 is now inside #5016. The accounting table below still reads "No record anywhere: 1"; that PR is #5427 and it now has an entry.
Why
The 3.10.0 release needs its version, its changelog entry and its archive, and a clean rebuild.
What changes
<Version>3.10.0</Version>inDirectory.Build.props, that line only. The only other 3.9.0 strings in the tree are project-version ranges inside thepackages.lock.jsonfiles and a comment inMigrationDataMovingRungCensusPins.cs. The 3.9.0 release left the lock files alone too, and the rebuild below restored and built cleanly.CHANGELOG.mdgets## [3.10.0] - 2026-10-08under an empty## [Unreleased], with Important, Added, Changed and Fixed in that order. One script, kept outside the repo, wrote it. It stripsdev <sha> (<bookkeeping>):with a balanced-parenthesis match and keeps the rest of each entry as it was. It adds([#N])after the title only where the entry had none. Entries stay in buffer order. 264 reference links are added at the bottom, in ascending order, for every[#N]the new block uses that had no definition.splitmoved the prose to the newdocs/changelog/3.10.mdand compacted the index.tools/changelog/archive-census.txtgains the 3.10.0 row (275 entries at the first write, 257 after the rulings).StorageVersion.cs:19). I read every migration in the range (PgMigrations.cs:1071-1083, the SQL at lines 347-880). None rewrites a large table or needs an offline window. Ten create new tables that start empty (V158, V160 to V165, V167, V168, V170). V159 adds two nullable columns to the one-row install id table (PgMigrations.cs:378). V166 adds a boolean with a constant default toconfig.config_notification(:688), which PostgreSQL 11 and later does without a rewrite. V168 adds a trigger tocollect.query_store_interval_latest(:815), a short lock and no rewrite. Two touch existing rows, both in small config tables. V167 copies one row per saved old-format password out of the server list (LegacyPinCandidateTables.cs:78). V169 adds columns and a check constraint toconfig.config_monitored_servers(:847), one row per configured server. The data-moving census inMigrationDataMovingRungCensusPins.cs:222declares V169 as the only data-moving rung in this range. The entry says so, and says no maintenance window is needed.Entry-line proof (step 2d), as first written, before the rulings above
The table compares the house-style lines before the write (the buffer plus two PR-body entries) with the lines read back from
CHANGELOG.mdon disk. Each row has the SHA-256 of the sorted lines.The script also asserts that every older line of the file is unchanged (only the new block and the appended links differ). The working tree is CRLF and the blob is LF, as
.gitattributesmakes it. After the write, CR and LF counts are equal inCHANGELOG.md(5145 each),docs/changelog/3.10.md(558) andarchive-census.txt(23).Accounting (347 PRs merged to dev since the v3.9.0 tag at 2026-10-02T11:46:18Z)
At the cut, #5427 had no record: it was not in the buffer, the splice log, or its own body (no SECTION or ENTRY line). Ruling 5 added its Fixed entry, written from its PR body and checked against its diff.
Of the 255, one is #5052, which ruling 2 folded into #5016's entry. The buffer holds 273 entry lines for those PRs, since a few carry two or three. Minus the excluded line and plus the two PR-body entries, that is the 274 lines of the first write in the proof below.
Test plan
python tools/changelog/changelog_archive.py splitexits 0 (last line:wrote 12 files), thencensusexits 0 (last line:wrote tools/changelog/archive-census.txt), after the rulings above.verifyexits 0 with no FAIL. The 3.10.0 rows read257 index lines for 257 archived entriesand257 entries, prose sha256 a4ad534519744df0 matches tools/changelog/archive-census.txt.roundtripexits 0 (last line:NOT the whole document: the index has moved on since then, so this is the durable half of the claim rather than the byte comparison; the line before it readsPROSE INTACT every version 3653e8d63a08 held is byte-identical in prose, and every link definition still resolves).CHANGELOG.md5129 CRLF and 5129 LF,docs/changelog/3.10.md563 and 563,archive-census.txt23 and 23, no bare CR.git ls-files --eolshows the index blobs as LF for all three.dotnet buildof Darling.Tests and Lite.Tests: 0 Warning(s), 0 Error(s).ChangelogIndexAndArchiveTests: Total 5, Failed 0.ProductVersionDeclarationTests: Total 26, Failed 0.ReleaseStatementGateWorkflowTests: Total 4, Failed 0.MigrationUpgradeLadderLiveTestson a throwaway PostgreSQL 18 rig with TimescaleDB: Total 7, Failed 0, Skipped 0.-trait Stage=Guard -failSkips: Total 1387, Failed 0, Skipped 0.*Census*: Total 462, Failed 0, Skipped 1.*Ratchet*: Total 15, Failed 0.-trait Stage=Guard -failSkips: Total 429, Failed 0, Skipped 0.DARLING_RELEASE_CUT=1 ... StatementCensus_PendingEntries_BlockAReleaserun was not repeated; no statement-census input changed in this round.