From dc6410dfad5b098498f093aa2c24a0fc61b6c2c4 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Tue, 11 Aug 2026 04:15:10 -0400 Subject: [PATCH] =?UTF-8?q?docs(playbook):=20name=20the=20recurring=20fail?= =?UTF-8?q?ure=20=E2=80=94=20a=20set-wide=20claim=20from=20a=20partial=20c?= =?UTF-8?q?heck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three instances in one round (btn-block universality, sweep behavior-preservation, the mxgw Bootstrap exemption), all the same shape, all caught by the asserter re-checking rather than by challenge. Fix is a cheap per-member check that runs, or an honestly-scoped claim when it hasn't. --- admin_ui_cleanup.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/admin_ui_cleanup.md b/admin_ui_cleanup.md index 47795ca..9c4ecc6 100644 --- a/admin_ui_cleanup.md +++ b/admin_ui_cleanup.md @@ -246,6 +246,13 @@ foundation branch merges — all branches build independently and compose at mer also carry app-specific *shape* declarations that predate the sweep and that the kit does not ship; mxgw's carried `border-radius: 5px; font-weight: 500; white-space: nowrap`, and a wholesale delete would have silently dropped all three. Diff your block against the kit's before removing + **And check whether your app has one at all** — "every app carries this block" was asserted after + checking the apps that were convenient to check, and it was false. HistorianGateway has NO local + `.btn` sizing in either tree, only vendored Bootstrap, so for it the bump is a **visible change** + (buttons shrink from Bootstrap's 1rem to `.85rem`), not the no-op cleanup the note promised. The + per-repo check is one grep for `bs-btn-font-size` excluding `lib/bootstrap` — under ten seconds, + against a claim that was wrong for 20% of the family. + anything: four of the five apps' blocks were pure sizing and safe to delete outright, one was not, and the difference is invisible unless you look. Two of the four that were safe deleted without diffing first and said so — they were lucky, not careful, and that is the same shape of @@ -352,6 +359,24 @@ must return the button, not the backdrop — mxgw's modal gate), and **realistic data** (ScadaBridge injected a 150-char OPC UA node id; HistorianGateway created a key with an 88-char display name, which rendered as 40 chars + ellipsis with Revoke still in the viewport). +**The recurring failure of this whole playbook is a property asserted about a set after checking +the convenient part of it.** It happened three times in one round, in three different guises, and +each time the claim was made in good faith by someone who had genuinely looked at *something*: + +- "All five apps carry a local `.btn` block, so the bump is a cleanup" — inferred from the apps that + had one. HistorianGateway had none, making its bump a visible restyle. +- "The sweep is behavior-preserving" — asserted about a 76-file diff after reviewing the wrapper and + class changes it was *supposed* to contain. Four files carried an unrequested state-model refactor + that closes a modal when a background refresh drops its row. +- "mxgw is Bootstrap-free so the modal defect can't affect it" — an exemption from a family-wide gate, + granted on a property nobody re-derived. It was a Bootstrap host and *was* affected. + +The shape is identical every time: a universal claim, a partial check, and a conclusion that happens +to be convenient. The fix is not more caution, it is a **cheap per-member check that actually runs** — +one grep, ten seconds — plus stating the claim's scope honestly ("verified in these three; not checked +in the other two") when the check hasn't run. Note that all three were caught by someone re-examining +their own earlier assertion, never by the assertion being challenged. + **Record what you could not exercise rather than rounding it up.** HistorianGateway proved 2 of its 4 truncation sites live and said so: `sf.Error` needs a genuine drain failure, which needs a historian that accepts a connection and *then* rejects the write, and a box with nothing listening