Root cause: DeploymentDriftProbe (a singleton shared by every circuit) cached its verdict until
the ConfigEdit audit watermark (MAX(EditedAtUtc), COUNT(*)) moved, assuming every configuration
write appends a ConfigEdit row. Only deployments and driver restart/reconnect do; the AdminUI
editors (RawTreeService, UnsTreeService, ScriptEdit, cluster/node/ACL pages) write the config
tables directly. So after a draft change the page kept showing the cached "In sync" until
something unrelated moved the watermark.
- DeploymentDriftProbe: the watermark cache is gone; every verdict comes from a composition that
started after the caller asked. Compositions stay serialised behind the gate, and callers queued
behind one share a verdict only when that composition started after they arrived (start
sequence number) for the same sealed hash, so sharing is exact, never stale.
- Deployments page: the drift check runs in OnAfterRenderAsync (interactive render only, so a
visit costs one composition, not two with prerender); the first render shows a neutral
"Checking for changes..." chip, never a verdict; a failed check shows "Drift check failed" and
logs a warning instead of crashing the page. A deploy re-runs the check.
- Tests: probe tests for an un-audited draft change (real ConfigComposer over InMemory), fresh
composition per call, and queued callers not reusing an older composition; bUnit page tests that
a second page load after a direct draft change shows "Configuration drift" and that the first
render shows "Checking" until the comparison answers. All fail against the previous code.
DeploymentDriftProbeSqlServerTests is removed: it pinned the SQL translation of the watermark
query, which no longer exists.
Claude-Session: https://claude.ai/code/session_01GT67ACmpMR7b9LGRPLijMi
Akka.TestKit.Xunit2 -> Akka.TestKit.Xunit 1.5.62 (xunit.v3 TestKit; needs xunit.v3 3.2.2, set via
VersionOverride on the four projects). Removes the xunit 2.9.3 pin. IAsyncLifetime returns ValueTask,
SqlServerFactAttribute gains the source-info ctor, and xUnit1051 call sites pass
TestContext.Current.CancellationToken. Test counts unchanged.
Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV