Skip to content

Sweep the stale 21-day mentions #1941 left behind (#1937 follow-through) - #1942

Merged
erikdarlingdata merged 2 commits into
devfrom
fix/1937-stale-21d-sweep
Jul 31, 2026
Merged

Sweep the stale 21-day mentions #1941 left behind (#1937 follow-through)#1942
erikdarlingdata merged 2 commits into
devfrom
fix/1937-stale-21d-sweep

Conversation

@erikdarlingdata

Copy link
Copy Markdown
Owner

The #1941 review bot listed pre-existing comment/message drift outside that PR's diff: thirteen comment sites and one operator-facing CLI line (the --backfill-rollups completion output still taught the 21-day trim timing - actively misleading after the horizon moved). This PR is that sweep:

  • DarlingCliCommands completion line now INTERPOLATES TimescaleSupport.HourlyRetentionInterval - the one user-facing string can never drift from the constant again.
  • Current-behavior comments corrected to 90 or made horizon-neutral (destroy-history warnings now say 'the retained hourly tier' rather than naming a number that changes).
  • Historical-defect narration deliberately keeps its 21s (it describes why the old world was wrong, and rewriting history is its own drift).

Comment/message-only plus one interpolated string; service project builds 0 warnings.

🤖 Generated with Claude Code

The review on #1941 listed them: thirteen comment sites and one
operator-facing CLI line (the --backfill-rollups completion guidance)
still described the 21-day world. The CLI line now interpolates
HourlyRetentionInterval so it cannot drift again; current-behavior
comments are corrected or horizon-neutralized; historical narration
keeps its 21s because it describes the defect, not the behavior.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment on lines 134 to 135
/// <para>Route thresholds sit a margin BELOW each retention horizon (raw kept 4d → route ≤3d; hourly kept 90d
/// route ≤20d), so a drop lagging the boundary (1-day chunk granularity + the 3-day CAGG refresh) can never leave

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sweep changed "hourly kept 21d" to "hourly kept 90d" here but left the derived threshold as "route ≤20d" — that's now internally inconsistent. The doc explicitly says thresholds sit a 1-day margin below the horizon (RouteMargin = TimeSpan.FromDays(1), HourlyMaxAge = HourlyRetentionSpan - RouteMargin), so kept 90d should route ≤89d, not ≤20d. The old "21d → ≤20d" pairing was internally consistent (margin=1), but the mechanical 21→90 substitution wasn't applied to the derived "≤20d" figure. Compare with the very next member doc a few lines down (line 147), which correctly says "a day inside the 90-day hourly retention" (i.e. 89 days) — so this paragraph now contradicts the member doc directly beneath it, and reintroduces exactly the kind of stale/misleading number this PR exists to sweep away.

Suggested change
/// <para>Route thresholds sit a margin BELOW each retention horizon (raw kept 4d → route ≤3d; hourly kept 90d →
/// route ≤20d), so a drop lagging the boundary (1-day chunk granularity + the 3-day CAGG refresh) can never leave
/// <para>Route thresholds sit a margin BELOW each retention horizon (raw kept 4d → route ≤3d; hourly kept 90d →
/// route ≤89d), so a drop lagging the boundary (1-day chunk granularity + the 3-day CAGG refresh) can never leave

output.WriteLine("is the confirmation; the first purge then reclaims the raw tables in one pass.");
output.WriteLine();
output.WriteLine("Do not delay the restart. The hourly rollups carry their OWN 21-day retention policy, already");
output.WriteLine($"Do not delay the restart. The hourly rollups carry their OWN {TimescaleSupport.HourlyRetentionInterval} retention policy, already");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor wording nit on the interpolated line, since the whole point of this change is that this exact string can't silently drift again: HourlyRetentionInterval is the noun phrase "90 days", but it's spliced into an adjectival slot ("carry their OWN 90 days retention policy"), which reads ungrammatically. The old literal text was correctly hyphenated as an adjective ("OWN 21-day retention policy"). Might be worth rephrasing to something like "...carry their OWN retention policy ({TimescaleSupport.HourlyRetentionInterval}), already..." so the interpolated value sits in a position where "90 days" reads naturally as a noun phrase rather than a compound adjective.

@claude

claude Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review

Scope: comment/doc-string sweep plus one operator-facing CLI string, following up on #1937 (21-day → 90-day hourly retention horizon). Touches CHANGELOG.md and 6 C# files under Darling/; no T-SQL, no Lite/ files.

Overview

Cleans up thirteen stale "21-day" mentions left after the retention horizon moved to 90 days, and makes the one operator-facing line (--backfill-rollups completion output in DarlingCliCommands.cs) interpolate TimescaleSupport.HourlyRetentionInterval instead of hardcoding a number, so it can't drift again. Historical-defect narration (e.g. "DERIVED, since #1937, and that was the whole bug... hardcoded 21-day horizon") is correctly left alone, since it's describing the old, wrong behavior on purpose.

Parity check

No Lite/ changes, and that's correct here — Lite doesn't have this Timescale CAGG/retention-tier concept at all (confirmed: no hits for HourlyRetentionInterval/CAGG/retention in Lite/), and the PR body itself calls out that 90 days is deliberately not a Lite-parity number. No drift between the apps introduced by this PR.

Issues found (posted inline)

  • ComposeSourceRouter.cs (line 134-135): the mechanical 21→90 substitution updated "hourly kept 21d" to "hourly kept 90d" but left the derived threshold as "route ≤20d". Per the file's own margin logic (RouteMargin = 1 day, thresholds sit a day below the horizon), that should now read "≤89d" — the old "21d → ≤20d" pairing was consistent, the new "90d → ≤20d" isn't, and it now directly contradicts the correct "a day inside the 90-day hourly retention" wording a few lines below in the same file. This is exactly the kind of stale-number drift this PR is meant to eliminate, just newly introduced by the sweep itself.
  • DarlingCliCommands.cs (line 2670): minor grammar nit on the newly-interpolated line — HourlyRetentionInterval is the string "90 days" (a noun phrase), spliced into an adjectival slot ("carry their OWN 90 days retention policy"), which reads awkwardly versus the original hyphenated "OWN 21-day retention policy". Suggested a rephrase so the interpolated value sits in a position where "90 days" reads naturally.

Other notes

  • CHANGELOG entry is well-formed and the [#1937] link reference already exists elsewhere in the file, so no dangling reference.
  • Everything else in the diff is comment-only text correction (21-day → horizon-neutral phrasing or explicit 90) and reads correctly against current behavior.
  • Didn't confirm the "0 warnings" build claim in-session (build tool required approval I couldn't get in this pass); the interpolation change itself is a straightforward public const string reference via an already-present using PerformanceMonitor.Darling.Storage;, so it should compile cleanly.

…d the adjectival splice

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review: comment/message sweep (#1937 follow-through)

Verified this against the diff and the surrounding code. Overall this is exactly what the description claims — a low-risk documentation/message sweep with one behavior-relevant change (the CLI now reads the constant instead of a literal).

What I checked:

  • Counted the edits: 1 (ComposeCompiler) + 4 (ComposeSourceRouter) + 2 (DarlingCliCommands: 1 comment + 1 CLI line) + 1 (DarlingWorker) + 1 (RetentionTierRouter) + 4 (TimescaleSupport) = 13 comments + 1 CLI line, matching the PR description's count.
  • DarlingCliCommands.cs:2670TimescaleSupport.HourlyRetentionInterval resolves correctly (the file already usings PerformanceMonitor.Darling.Storage), and the interpolated sentence reads naturally: "the hourly rollups carry their OWN retention policy (90 days), already armed...". Good fix — this was genuinely misleading before since it hardcoded "21-day" after the horizon moved to 90.
  • Grepped the rest of the repo for remaining 21-day/21d mentions. The ones left in TimescaleSupport.cs (lines ~1622/1652, the "90, not 21" doc block) and RetentionTierRouter.cs:76 are legitimately historical/comparative ("had it simply inherited the 21-day horizon...", "this was a hardcoded 20 days sitting a day under a hardcoded 21-day horizon") — they explain why the number changed, not what it currently is, so correctly left alone per the PR's own stated rule.
  • Remaining 21 days/21d mentions in Darling.Tests/* (RollupCoverageRoutingTests, TimescaleSupportTests, ComposeSourceRouterTests, etc.) are all test narration describing the pre-Hourly-CAGG retention defaults to 21 days, so a 30-day view can never render at hourly grain — raise to 90 #1937 behavior being tested against — out of scope for an operator/comment-facing sweep, and not misleading since they're framed as "under the old horizon."
  • Confirmed this is a Darling-only concern: Lite has no TimescaleDB CAGGs/retention-tier constants (its long-term tier is the parquet archive), so there's no Lite/Darling parity gap here — nothing to mirror on the Lite side.
  • CHANGELOG entry follows the existing format (bold summary + issue link + explanation) and [#1937] is already a defined reference link at the bottom of the file.

No correctness, security, or performance concerns — this is comments/docs plus one string interpolation, no logic changes. Nothing further to flag.

@erikdarlingdata
erikdarlingdata merged commit 014b40f into dev Jul 31, 2026
4 checks passed
@erikdarlingdata
erikdarlingdata deleted the fix/1937-stale-21d-sweep branch July 31, 2026 12:38
MisterZeus pushed a commit to MisterZeus/PerformanceMonitor that referenced this pull request Aug 3, 2026
…stops overclaiming

erikdarlingdata#1957: the SECURITY WARNING was honest. After applying the hardened ACL the
installer set the service account as owner by handing Set-Acl a freshly
constructed FileSecurity carrying nothing but that owner. Set-Acl applies the
whole descriptor it is given, so that call also wrote an empty, unprotected
DACL - re-enabling inheritance and handing BUILTIN\Users read back on an install
under C:\, one statement after the hardening. Confirmed on a scratch layout
under C:\ before changing anything: immediately after the owner step the file
read protected=False with BUILTIN\Users present, all four inherited ACEs back
and every hardened ACE gone. erikdarlingdata#1818's startup sweep re-hardened everything
seconds later at the first service start, which is why the operator's own
before/after captures both looked clean and only the installer disagreed.

The owner now goes onto the file's CURRENT descriptor, so the hardened DACL
rides along and the verified state is the final state. Proven by running the
SHIPPING hardening block against the scratch layout: fresh install and a second
install over the already-hardened layout both report 3 hardened / 0 warned with
protected=True, no BUILTIN\Users, owner = the service SID; and a control where
the harden genuinely fails still names the files, which are world-readable on
disk at that moment. The per-file verification predicate is untouched - it was
correct throughout. The install summary now states that the service re-verifies
these ACLs at every start.

erikdarlingdata#1958: the retention summary read "(raw 4 days, hourly CAGGs 90 days; daily
CAGGs kept indefinitely)" - a universal claim with three counterexamples in
timescaledb_information.jobs, where the docs send an operator to check it.
query_store_stats_interval_hourly carries 7 days by design (erikdarlingdata#1849's dedup tier,
sized to outlive raw), its daily twin carries 10, and the nine baseline
aggregates keep 35. The line now names every tier that has a policy, with every
number interpolated from its constant per erikdarlingdata#1942. Darling/README.md gains the
rollup-tier ladder, which was not documented anywhere user-facing - its
Retention section described only the collector horizons, so the three rolled-up
raw tables read as 30 days when a 4-day policy is what actually drops them.

Both fixes are newly pinned; neither line had a test before. The summary pin
derives its expectation from RetentionPolicies itself, so a tier added on a new
horizon fails until the summary mentions it. Watched red: the summary pin fails
naming IntervalRetentionInterval against the old wording, and the installer pin
fails both against the bare descriptor and against a second bare descriptor left
after a correct re-read.

Also fixes two pre-existing xUnit2013 warnings on dev in
ProcedureStatsCollectorDefinitionTests, restoring the zero-warning build.

Closes erikdarlingdata#1957
Closes erikdarlingdata#1958

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant