Require a population large enough for a maximum to bound anything (#3193) - #3195
Conversation
) RefreshCeilingProvenancePinTests held each ceiling constant equal to the maximum of a population its doc comment publishes, and had no opinion about whether that population could support a maximum. A constant could be re-derived DOWNWARD on a handful of runs and satisfy every relationship in the file. PopulationFloor is derived from NearestRank rather than chosen: the first n at which the nearest-rank 95th percentile is a different reading from the maximum, which is the divergence both ceiling summaries argue their estimator from. It is asserted minimal, so it cannot be silently raised either. The floor is applied where each run count is already read - the heaviest ceiling's population length and the light ceiling's census count - and ahead of the derivation clauses, because Verify is fail-fast and clause order decides whether the next reader is told to move the constant or to widen the population.
|
Reviewed. This PR only touches Traced the new logic against the base commit's diff by hand:
No correctness, security, or performance concerns. The heavy prose/ALL-CAPS comment style matches this file's and CONTRIBUTING.md's already-established convention ("comments explain WHY, at length"), so no style flags either. |
The mutation comment counted occurrences of the census figure in a doc run and got both numerals wrong: the run states it five times, three of them pinned. A count over prose that can be reworded is the frozen-enumeration defect this file exists to catch, and addressing by ordinal has the property it needs regardless of how many there are - so the reason is stated without a tally rather than with a corrected one.
ReviewScope: this PR touches exactly one file, Correctness of the new logic — checked out independently rather than taken on faith:
I don't see a correctness bug, a parity gap, or a security/performance concern here. One process gap: the PR description includes a fully-written "CHANGELOG entry text" section, but |
# Conflicts: # Darling/Darling.Tests/RefreshCeilingProvenancePinTests.cs
|
Reviewed. This is a test-only change to Correctness — verified by hand:
One minor (non-blocking) note: the floor is a necessary condition derived from a strictly-ascending synthetic population, not a guarantee for every real population of size ≥20 — if the two largest real readings were ever tied, nearest-rank 95th could still equal the max at n=20. That's an inherent property of a count-only floor (the PR text already acknowledges the floor "cannot see composition"), not a code bug, and not worth guarding given real timing data essentially never ties exactly. No functional or security concerns found. |
…ix merged pull requests (#3213) * Record the CHANGELOG entries for thirty-one changes across twenty-five merged pull requests Applies the `[Unreleased]` entries for the pull requests merged to `dev` from #3150 (the previous batch) through #3203. Lanes do not edit `CHANGELOG.md` -- every one of them appends to the same block, so a per-PR edit conflicts with whichever sibling merges first -- and the entry text rides each PR's own description instead. This is the periodic commit that applies it. `CHANGELOG.md` only, 56 insertions and no deletions: 31 entries prepended inside `## [Unreleased]` (6 under `### Added`, 2 under `### Changed`, 23 under `### Fixed`), newest merge first within each section, plus the 25 link-reference definitions they need appended at the foot of the file. Nothing already in the block was edited, reworded or reordered. Three of the 28 pull requests in the range earn no entry, each on measured precedent rather than judgement: #3150 is the previous batch pass itself, and no batch pass -- #2260, #2980, #3150 -- is cited anywhere in the file; #3130 and #3131 are routine Dependabot bumps, and none of the six merged Dependabot pull requests in the repository's history is cited either. Two pull requests carried no entry text anywhere, so theirs are written from their descriptions: #3176 (`pg_index_bloat`'s measured block rate) and #3184 (the PostgreSQL target's permissions section). * Record #3205's entry, which arrived on the merged base mid-batch #3205 merged while this batch was assembled, so `origin/dev` was merged in rather than rebased and its entry lands on top. An entry omitted because it arrived mid-batch is how a backlog restarts, and the batch's purpose is to make `[Unreleased]` current at its own merged base. One entry under `### Changed`, newest merge first ahead of #3195's, plus its link-reference definition. #3205 has no other pull request in the range behind it. * Take #3164's and #3166's entries from the lane handoff files instead of the PR bodies The entry text does not only ride the PR description. #3150's own account of the previous batch says 11 of its 66 entries came from a lane's handoff file in `~/Documents/pm-issue-queue-inbox/inbox/` rather than the body, and three files there carry dedicated entry text inside this range: `3164-changelog-entry.md`, `3166-changelog-entry.md` and `3169-changelog-entry.md`. Searching only the bodies missed the first two. - **#3164** (PR #3176) is no longer written from the PR description. Its lane wrote a full entry, and that text is used verbatim: it carries the 1,036 blocks/s upper bound, the reason the decoupling #3153 deferred is unreachable, the declined command-deadline route, the census deliberately not restated at the new ceiling, and the mutation that caught nothing. `[#2997]` joins the definition block at its ascending position, which that text cites and the file did not define. - **#3166** (PR #3168, absorbed and superseded by #3178) had no entry at all. #3178 grouped it into its own citation with a one-line summary, but its lane wrote a separate entry for the census that took `HeaviestHourlyRefreshObservedCeilingSeconds` from 594 s to 896 s and inverted the watch-line ordering. It sits beside #3178's, on #3178's merge. - **#3191's entry** said "#3184 named four of the six". #3184 was squash-merged and the four-of-six state never reached `dev`; it was a commit inside that PR, corrected before merge. "shipped" in this file means merged, so the clause now says a commit in #3184, which is what the #3187 lane's own report establishes. `CHANGELOG.md` only, 60 insertions and no deletions against `origin/dev`: 33 entries (6 Added, 3 Changed, 24 Fixed) and 27 definitions. All 15 definition runs keep the ordering they had, 9 of 15 ascending before and after. * Use the staged #3184 entry text instead of one written from the PR description #3184's entry now exists, staged by the lane that did the work, so the batch no longer invents one. Used verbatim, in `### Fixed` where its author targeted it and for the reason they gave: the section did not merely lack detail, it asserted "One role covers every collector", which is false in the direction that fails silently and which an operator would act on. Their text carries what a description-derived entry could not: the `pg_read_all_data` grant is PostgreSQL 14+ and the pre-14 fallback the section gave was `GRANT SELECT` on a schema, which is not valid PostgreSQL at all; the six collectors that need an extension, four of which additionally need `shared_preload_libraries` and a server restart; and why `pg_index_bloat` is unaffected by any grant. Both figures are live pre-change store reads rather than estimates. The citation is `[#3184]`, the pull request, because the change has no issue behind it, and its definition uses the `/pull/` form. `CHANGELOG.md` only, still 60 insertions and no deletions against `origin/dev`.
Closes #3193.
RefreshCeilingProvenancePinTestsrequired each ceiling constant to equal the maximum of a population its doc comment publishes, and had no opinion about whether that population could support a maximum. Both constants could be re-derived DOWNWARD on a handful of runs and satisfy every relationship in the file.What was measured before choosing a floor
Both halves of #3193's claim were tested against the shipped file rather than reasoned about, and they do not agree with each other.
OtherHourlyRefreshObservedCeilingSeconds: The ceiling provenance pin accepts any population size, so a constant can be TIGHTENED on three observations with nothing going red #3193 is right. Its census cut from 874 runs to 4 — the count sentence and the filter-control sentence rewritten consistently — was green across the whole file. That population is deliberately not republished; only its count is, so every figure the paragraph states is consistent with any count whatever.HeaviestHourlyRefreshObservedCeilingSeconds: The ceiling provenance pin accepts any population size, so a constant can be TIGHTENED on three observations with nothing going red #3193 is wrong that nothing goes red, and the detail matters. A consistent 4-run re-derivation with the constant tightened to 697 trips the pre-existingNearestRank(sorted, 95) < maxclause, because below 20 draws the nearest-rank 95th percentile IS the maximum. But that clause is a guard on the estimator paragraph's premise, not on the population, and its message says "the sample-size half of the estimator argument is live again. Re-read HeaviestHourlyRefreshObservedCeilingSeconds belongs to neither regime: too fast for the wide window, too slow for the narrow one, and the clean maximum is ~594s #3101's trade rather than editing this assertion" — which sends the reader to re-take the maximum-versus-percentile decision, never mentions population size, and never mentions that tightening is the direction that costs. It also sits behind the summary clauses in a fail-fast chain, so it is reached only after every other prose figure has been made consistent.Also worth recording: the published lists are pinned as
[0-9]+(?:, [0-9]+)+, so the smallest publishable heaviest population is four runs, not three.The floor, and why this one
PopulationFlooris the firstnat which the nearest-rank 95th percentile of an ascending population is a different reading from that population's maximum. It computes to 20, and it is searched withNearestRankitself rather than written down — change the percentile the summaries quote, or the definition of nearest rank, and the floor moves with them. It is also asserted minimal: at one draw below it the 95th percentile must BE the maximum, so it cannot be quietly raised either.The derivation is the constants' own estimator argument. Both summaries take the maximum rather than a percentile on the ground that the two answers have DIVERGED. Below 20 draws that divergence cannot exist at any values, so a population that thin cannot support the argument its own doc makes for taking a maximum over it.
Why this beats the other two candidates #3193 weighed:
nine,twenty-two,twenty-four) and the light one saysover three days, all deliberately invisible toNumbers(). It would also not have blocked the defect: The ceiling provenance pin accepts any population size, so a constant can be TIGHTENED on three observations with nothing going red #3193's three runs sit inside a 23:00–01:00 window that straddles two calendar days.Verifyalready requires the light maximum to BE the00:30run its paragraph names, with an earlier midnight run strictly below it, and the date is inside that pin's own pattern — so a population with no midnight in it is already a parse miss. For the heaviest ceiling the mechanism does not transfer: its published population is a list of durations carrying no clock, and its summary attributes its maximum to a per-day growth trend rather than to an hour of the day.It is a conjunction, and the other half was already here
The honest requirement is size AND composition. The two fail differently and neither implies the other — a run count can be met by a hundred draws from one quiet stretch, and midnight coverage can be met by a two-hour population. But the composition conjunct was already in
Verifyat both sites, in the form each constant's own evidence can support:So what neither site had was the size conjunct, and that is all this adds. The added strictness is priced rather than hidden: any future census under 20 runs is now rejected, including an honest early reading of a fresh regime — which is why the failure message's whole job is to tell that reader to widen the population rather than to lower the floor or move the constant.
Where it is asserted, and what the message says
At the two points where a run count is already in hand — the heaviest population's parsed length and the light census sentence's third captured group — so this is an assertion, not a new extraction. It is placed ahead of the derivation clauses at both sites:
Verifyis fail-fast, and clause order decides whether the next reader is told to move the constant or to widen the population. On a population re-derived downward those are the same edit read two ways, and the wrong one of them is the cheap one.The message states that a maximum over
ndraws is a prefix maximum and therefore a weak lower bound; that the weakness has a direction, because loosening a sizing constant on thin evidence is conservative while tightening one narrows the clearance the compression grid is asserted against; and that the repair is one of exactly two things — widen the population and re-derive, or leave the constant where it is. It also names, per constant, what widening actually means: extending the published lists for the heaviest, a fresh read at a later instant for the light one, whose population is not republished.The stated bound, said plainly rather than left looking covered
The two sites are not equally well guarded, and the difference is inherent rather than deferred.
The heaviest ceiling's floor reads a parsed population —
population.Lengthover the readings the comment actually lists — so it cannot be satisfied by a claim. The light ceiling's floor reads its census count, which is a number in prose over a population the doc deliberately does not republish. So a re-derivation that statesover 900 runswhile having read four satisfies this floor.That gap cannot be closed here.
OtherHourlyRefreshObservedCeilingSeconds' own summary declines to republish its 874 readings, with a reason — "a list that long stops being re-derivable by reading and starts being a wall of digits" — and re-deriving the estimator from a transcription of 874 numbers would trade this weakness for a worse one. What the floor buys at that site is that the count is now load-bearing: it was previously consistent with any value at all, and a thin census had to be asserted as wide before it can pass. Corroborated, not proved, by the exclusion-control sentence, which states the same number a second time.Stated here because the alternative is a PR that reads as if both sites were closed to the same degree.
Red-proofing
EveryNumericPin_ReportsAnInjectedDriftenumeratesPins()and bumps captured numbers, so it covers extractions. The floor adds no pattern and consumes no pin — a digit bump moves a stated value and never a population's size — so it is unreachable from that sweep, and no equivalent harness for a non-pin assertion exists beyond the file's own idiom: a dedicated mutating fact, which is whatTheInadmissibleReadings_CannotBeFoldedIntoTheStatusVerifiedSeries,TheInadmissibilityClaim_MatchesTheShippedSqlandTheOpenPopulationGuard_ReportsEachForbiddenShapealready use.ThePopulationFloor_ReportsAPopulationTooThinToSupportAMaximumfollows it: baseline verified green first and again at the end, the floor pinned minimal in both directions, both real populations required to clear it, and both sites mutated on copies with the failure required to carry aPIN POPULATION FLOORmarker — because shrinking a population falsifies several claims at once, and without the marker the test would pass on whichever of themVerifyreached first.Mutations run against the real
TimescaleSupport.cson disk, each confirmed present by content and restoration confirmed by content:4 runs, under the 20-draw floor874→4PIN POPULATION FLOORRun on macOS by compiling the real shipped
RefreshCeilingProvenancePinTests.csinto anet10.0xunit.v3 harness namedDarling.Tests, soInternalsVisibleToapplies and[CallerFilePath]still resolves to the realTimescaleSupport.cs.PopulationFloor = 20and the 19-versus-20 boundary were read out of the shippedNearestRankby reflection rather than from a transcription of its formula.Base
Based on
devat723ae0cbe. PR #3190 is still open and touches the same file; the two conflict in exactly one place — both insert a<para>at the same anchor in the class summary, and everything else auto-merges. Resolution is to keep both paragraphs, once, after #3190 lands.CHANGELOG entry text — deliberately not in this diff
CHANGELOG.mdis not part of this change, and that is the lane convention rather than an omission. Several lanes are working this queue concurrently and every one of them would append to the same[Unreleased]block, so a per-PR edit turns a batched, conflict-free append into N conflicting ones. The entry text is therefore reported here for the coordinator to batch, which is where the reference link gets added with it.Under Changed:
RefreshCeilingProvenancePinTestsnow requires each hourly-refresh ceiling's published population to clear a floor derived from its own nearest-rank percentile definition, so a sizing constant cannot be tightened on a population too thin for a maximum over it to bound anything (#3193).