Skip to content

Point every rung citation for alert_persistence_state at V118, and pin that they do (#3282) - #3338

Merged
erikdarlingdata merged 3 commits into
devfrom
fix/3282-rung-citations
Sep 12, 2026
Merged

Point every rung citation for alert_persistence_state at V118, and pin that they do (#3282)#3338
erikdarlingdata merged 3 commits into
devfrom
fix/3282-rung-citations

Conversation

@erikdarlingdata

Copy link
Copy Markdown
Owner

Follow-up to #3282 / #3328. Close #3282 explicitly once this lands — PM merges to dev, where closing keywords never fire.

What is wrong on dev right now

config.alert_persistence_state is created by V118 (builtin-alert-persistence), and StorageVersion.SchemaVersion is 118. Five comments across both SKUs still cite V117, which is now #3315's mute-rule reload-beacon rung:

file says
Lite/Database/Schema.cs "config.alert_persistence_state (PgMigrations V117)"
Lite/Database/DuckDbInitializer.cs "porting Darling's V117"
Lite/Services/DuckDbAlertHistoryStore.cs "the Lite twin of Darling's V117 table"
Lite/Services/LiteAlertStateStore.cs "of Darling's V117 table"
Darling/PerformanceMonitor.Darling.Service/PgAlertStateStore.cs "record from the V117 …"

#3282's rung was V117 until #3315 merged first and the ladder rule sent the later merge to renumber. The renumber moved the code and missed the prose. This repo uses exactly these citations to verify Lite/Darling parity, so a wrong one sends the next person to the wrong rung.

claude[bot] flagged three of them on #3328. The other two — LiteAlertStateStore and PgAlertStateStore — were found by grepping for the rung number rather than working from the review list.

Why it is a separate PR

This was the last commit on #3328 and the merge landed one commit short of it (1a3a928a went in; this did not). Verified by content rather than by ancestry: git diff origin/dev <that commit> over the six paths is non-empty, so it genuinely did not land. Nothing else from that branch is missing — it was the only commit after the merged head.

The pin, and the two ways it was wrong first

A rung number in prose is a frozen claim, so the number is derived from StorageVersion.SchemaVersion rather than compared against a literal: a future renumber reds this instead of leaving silent copies behind.

Both of its first spellings were wrong in ways worth recording, because each one would have passed:

  • Scoped to the file, it flagged nine correct citations. Those files cite V40, V44, V50, V60, V61, V80, V81, V32 for their own tables, all correct. A check that fires on correct code is a check someone turns off, so the scope is now the comment block that names this table — a citation is attributed to the thing its own block is about.
  • Its floor was assumed, not measured. Keying the block match on the table name alone found four blocks, not the five I had written down: DuckDbInitializer names the table only in a log string and its comment says "persistence-gate state". Both keys are matched now, and the floor is the counted number.

Reddened two ways before its pass was trusted: one citation reverted to V117 (fails, naming that file), and a SchemaVersion bump to 119 with the comments left alone (fails, naming all five).

Verification

Darling.Tests/Lite.Tests are net10.0-windows and cannot run on macOS, so the actual test .cs files were compiled into a net10.0 console harness with an xunit shim and run against this tree: 194 passed, 0 failed, including the repo-wide guards this change has to satisfy (AlertReadFailureSurfaceTests, RepoFileAdoptionTests, DocCommentHygieneTests). Comment-only changes otherwise, plus one new test; all four affected projects build.

@claude

claude Bot commented Sep 12, 2026

Copy link
Copy Markdown

Reviewed. This is a clean, self-contained fix: it corrects five stale V117V118 comment citations for config.alert_persistence_state (renumbered when #3315 landed first) and adds a regression test (EveryCommentCitingThisRungsNumber_CitesTheRealOne) that pins the citation to StorageVersion.SchemaVersion instead of a literal.

Verification performed:

  • Traced the CommentBlocks state machine (doc-comment /// runs and /* … */ blocks) against the actual comment layout in all five touched files — it correctly isolates each file's alert_persistence_state/persistence-gate state block from unrelated rung citations in the same file (e.g. Schema.cs's adjacent blocks citing V44, V60, V32, V50, V40, V61 for other tables), so the "scoped to file" false-positive problem described in the PR body is genuinely fixed by scoping to the comment block.
  • Confirmed the asserted floor (5 blocks, 5 citations) matches reality: each of the five files has exactly one qualifying comment block with exactly one V\d+ citation.
  • Grepped the whole repo for remaining V117 references — everything left is legitimately about the unrelated mute-rule-reload-beacon rung ([BUG] create_mute_rule returns "created" but the mute does not take effect - config_mute_rules has no bump trigger, so the evaluator's cached rules are not reloaded #3315); nothing citing alert_persistence_state still says V117.
  • No T-SQL, schema, or runtime behavior changes — comment text and one new test only, so no Lite/Darling parity risk (if anything, this is the parity-citation fix) and no security/performance surface.

No correctness issues found. Nothing blocking.

…n that they do

#3282's rung renumbered from V117 to V118 when #3315 merged first, and five
comments across both SKUs still cite V117 - which is now the mute-rule
reload-beacon rung. Review found three of them on #3328; the other two are
in LiteAlertStateStore and PgAlertStateStore. The repo uses exactly these
citations to check Lite/Darling parity, so a wrong one sends the next person
to the wrong rung.

This was the last commit on #3328 and the merge landed one commit short of
it, so it comes back on its own.

The pin derives the number from StorageVersion.SchemaVersion rather than
comparing against a literal, so a future renumber reds it instead of leaving
silent copies. Each phrase carries its own SUBJECT, which is what makes a
citation attributable without parsing comments at all - and both earlier
spellings are why. Scoped to the FILE it flagged nine correct citations for
other rungs, which is a check someone turns off. Scoped to comment BLOCKS it
needed a hand-rolled line-prefix comment filter, which
CommentFilterAdoptionTests refuses without a stated bound - correctly, and
the bound I measured for it came back unreliable on its own terms. A phrase
naming both the table and the rung needs neither.

Reddened three ways before its pass was trusted: one citation reverted to
V117, a SchemaVersion bump that leaves all five behind, and a reworded
phrase - which has to fail loudly rather than silently matching nothing, so
the pattern is asserted to match at all before its captures are compared.
Assert.NotEmpty is load-bearing there: Regex.Escape escapes '{' and not '}',
which was verified by running it rather than assumed.
@claude

claude Bot commented Sep 12, 2026

Copy link
Copy Markdown

Reviewed. This is a clean, narrowly-scoped fix — five stale V117 comment citations for config.alert_persistence_state corrected to V118, plus a regression test pinning them to StorageVersion.SchemaVersion so a future renumber reds instead of leaving silent copies.

Checked:

  • Verified StorageVersion.SchemaVersion is indeed 118 on this tree, and grepped the whole repo for V117/V118 — every remaining V117 reference is legitimately about [BUG] create_mute_rule returns "created" but the mute does not take effect - config_mute_rules has no bump trigger, so the evaluator's cached rules are not reloaded #3315's mute-rule-reload-beacon rung, not a missed copy. All five alert_persistence_state citations across Lite/Darling now agree.
  • Traced the new test's regex construction (Regex.Escape(phrase).Replace(@"V\{0}", @"V(\d+)", ...)) by hand — the escape/replace pairing is correct and the built pattern matches the intended per-file phrase.
  • Specifically checked whether this PR's new cross-app read (Darling.Tests reading Lite/Database/Schema.cs etc. via Path.Combine("Lite", ...)) would evade CrossAppGuardCiGateTests, since CONTRIBUTING.md documents this exact hazard class. It doesn't: that guard's matcher does a plain regex scan for Path.Combine("<root>", ...) with the root as a literal first argument, which is exactly the shape used here, so the read is visible to it.
  • No T-SQL touched, no Lite/Darling behavioral drift (comment-only + test), no security-relevant surface.

Only a non-blocking nit: BuiltinAlertPersistenceRungTests.cs adds using System.Collections.Generic; that isn't used anywhere in the file. Harmless (no analyzer enforcing unused-using removal in this repo), just noting it.

🤖 Generated with Claude Code

Review nit. System.Collections.Generic came in with the first spelling of
the pin, which used a List, and stayed behind when the phrase-based version
replaced it. The added lines also put System.Text.RegularExpressions ahead
of System.Reflection.
@claude

claude Bot commented Sep 12, 2026

Copy link
Copy Markdown

Reviewed. This is a narrow, well-scoped fix — no SQL/schema changes, so T-SQL style and the missing-index-DMV concern don't apply here.

  • Verified all five citations actually said V117 pre-fix and now correctly say V118, matching StorageVersion.SchemaVersion = 118 (Darling/PerformanceMonitor.Darling.Storage/StorageVersion.cs:19).
  • Traced the new EveryCommentCitingThisRungsNumber_CitesTheRealOne test by hand: Regex.Escape in .NET escapes { but not }, so Regex.Escape("V{0}") produces the literal 5-char substring V\{0}, and the subsequent .Replace(@"V\{0}", @"V(\d+)") targets exactly that substring for all five phrases without collateral matches. Confirmed each phrase is a unique substring of its target file today.
  • Lite/Darling parity is maintained — the fix touches the 4 Lite-side comments and 1 Darling-side comment consistently, and the new guard test lives in Darling.Tests but reads the Lite files via Path.Combine("Lite", ...), which is one of the three spellings CrossAppGuardCiGateTests recognizes, so it stays CI-reachable through the darling filter's derived Lite/**/*.cs entry.
  • Second commit's using cleanup (dropping unused System.Collections.Generic, reordering System.IO/System.Linq/System.Reflection/System.Text.RegularExpressions) is correct and alphabetical; confirmed no remaining List<>/Dictionary<>/etc. usage in the file.

No correctness, parity, security, or performance issues found.

@erikdarlingdata
erikdarlingdata merged commit 859f113 into dev Sep 12, 2026
8 checks passed
@erikdarlingdata
erikdarlingdata deleted the fix/3282-rung-citations branch September 12, 2026 00:38
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