Repository navigation
Tell 'never registered' from 'deliberately removed' (#2258) - #2285
Conversation
e264145 to
6fb5d83
Compare
Review summaryReviewed the diff (CHANGELOG.md, Correctness —
Lite/Darling parity — no drift. Lite has no equivalent to this feature: it has a single Security — no new attack surface. No user input reaches the new query (it's a fixed Performance — negligible: one extra Nothing else stood out. |
A server named in darling.json but absent from the registry had two indistinguishable causes: added to the file after the first seed and never registered (the #2252 report -- the operator expects monitoring and is not getting it), or registered once and removed via the Viewer, which is correct. So the line reported at Information and worded itself for both: honest, but it could neither warn about the first nor stay calm about the second. Now two lines -- a warning for the never-monitored, naming what to do, and an Information line for the deliberately removed that advises nothing and notes their history is kept. No tombstone table and no rung, which is the point. The issue proposed config_removed_servers or an is_removed flag; the fact both would record already exists. collect.servers -- the OBSERVED registry -- gets a row on every successful connect, Remove deletes only from config_monitored_servers (the DESIRED config), and nothing purges the observed registry because it is a registry, not a time series. The is_removed flag was worth rejecting explicitly rather than merely not choosing: is_enabled = FALSE already means "registered but paused", so a second flag makes (is_enabled, is_removed) a four-state space with two meaningless combinations, and every existing reader of that table would have to learn the new flag or silently start including removed servers -- the same seam failure #2280 had to fix in the dedupe gate. Limits stated on the method rather than left to be discovered: a server registered but never connected to reads as never-monitored, which is the right answer to "is this monitored?" if not to "was it registered?"; and a rebuilt store has no observed rows, so everything reads as never-monitored until it connects once -- degrading to a warning rather than silence, the safe direction where the file genuinely is the intent. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
6fb5d83 to
18dce79
Compare
Closes #2258 — without the tombstone table or the migration rung it proposed, because the fact both would record already exists.
The ambiguity
A server named in
darling.jsonbut absent from the registry had two indistinguishable causes:So the reconciliation reported at Information and worded itself for both. Honest, but it could neither warn about the first nor stay calm about the second, and a naive fix that warned about both would tell the operator to re-add a server they'd deliberately dropped, at every startup forever.
No tombstone needed —
collect.serversalready is oneThe issue proposed a
config_removed_serverstable or anis_removedflag, plus a rung, and noted it wasn't worth a rung on its own. It doesn't need one:collect.servers— the observed registry — gets a row upserted on every successful connectconfig_monitored_servers, the desired configSo "was this server ever really monitored" is answerable today, for free, with no schema change and — more importantly — no second piece of state that could disagree with the first.
The
is_removedflag was worth rejecting explicitly rather than merely not choosing.is_enabled = FALSEalready means "registered but paused", so a second flag makes(is_enabled, is_removed)a four-state space where two combinations are meaningless, and every existing reader of that table would have to learn the new flag or silently start including removed servers. That's the same seam failure #2280 had to fix in the dedupe gate — a widened concept that old call sites never learned about. I'd rather not manufacture another one for a cosmetic gain.What it reports now
Two lines with different severities rather than one blended list, because a single list forces the sharper cause to inherit the calmer wording.
The limits, documented on the method
Stated rather than left to be discovered, since they bound what the log may claim:
ServersOnlyInFilealready gives: identity drift predating [BUG] Editing a server's Host/Database/ReadOnlyIntent re-keys its runtime server_id — registry PK orphaned, collected history split #2158 makes the id the least reliable of the three keys, and a miss here warns rather than going quiet.Testing
SplitByEverMonitoredis pure, so the truth table is ordinary tests, and I executed it locally — all green: both causes in one pass with order preserved, case-insensitivity, the empty-registry (fresh store) case landing in the warning arm, nothing-to-report, and null tolerance on a startup diagnostic path.The two log arms and their severities are pinned at the source, including that the removed arm advises nothing and does say the history is kept.
Full solution builds, 0 warnings; doc-comment detector clean (run as its own gate).
🤖 Generated with Claude Code