Skip to content

00b-h β€” Invariant harvest (WORKING LIST, unclassified)

Generated by python scripts/invariant_census.py --seed <this file> and then edited by hand. The STATUS column is the whole point and no regeneration can recompute it.

Every entry in 00b arrived from the audit corpus β€” a filed defect, grouped into a repair family, promoted. This is the other route: rules written down in comments by whoever learned them, and never registered.

Classify against 00b's own discriminator: an invariant states a rule AND its consequence. No consequence β†’ it is a CONVENTION and should stay one; promoting it manufactures the unfalsifiable claim the registry exists to remove.

⚠ STALE WAS WRONG ON ALL FIVE ROWS THAT CARRIED IT (corrected 2026-08-21, by ablation). Two are defended by existing tests, one is the undefended sibling of a defended rule, and two are real constraints the suite CANNOT observe. Two parentheticals were added because the original vocabulary had no way to say them:

  • INVARIANT (UNDEFENDED) β€” ablation-proven real, and nothing goes red. A gap, not a demotion.
  • INVARIANT (not test-enforceable) β€” real, but ablation is STRUCTURALLY BLIND to it. Two known classes: rules asserting an absence (nothing exists to break), and rules governing build-time artifacts (the suite never runs them). Both ablate to "nothing red" and would be falsely demoted to CONVENTION. Their enforcement is code review; the input that makes them red is a future commit. Any future ablation sweep must carry this third verdict or it will quietly demote exactly the rules most worth writing down.

STATUS: unclassified Β· INVARIANT Β· CONVENTION Β· PN (binding but no code site) Β· STALE (asserts something no longer true).

INVARIANT (cite IN……) means it RESTATES an existing registry entry β€” the action is a citation, not a new token. Bare INVARIANT means no entry covers it and a ruling is still owed. CONTESTED means two independent reads reached opposite verdicts and it needs a human call.

Evidence for every .py verdict below lives in .claude/notes/LEDGER-defects-code-vs-doc.md (batches 2–6, 2026-08-20), including the enforcement site, whether a test can make it red, and whether one exists. Classifying here is NOT minting: the order stays human ruling β†’ mint β†’ declare β†’ cite.

Ranking is not a ruling. A candidate here is a lead. The order stays human ruling β†’ mint β†’ declare β†’ cite.

236 lines state a rule AND a consequence in a file with no IN anchor, across 119 files.

Two populations, and they need different work

A 14-row sample on 2026-08-19 split roughly 4:10, and the split matters because one half is nearly free:

Places an EXISTING invariant binds and is not cited. services/stall_capture.py::_set_stall_capture says "Never mint a record for a vacuum this install does not manage" β€” that is [[INKV8ZQD]], in a file carrying no anchor. room_entities.py::EufyVacuumRoomEntity states [[IN4CW5Y9]]. bindings/room-editor.js::_alertRoomProfileResult states [[INNPA4ZV]]. cards/dashboard-card.js::_handleStart states [[ENFV9F37]]. The rule already exists; only the citation is missing, so closing these is a reference, not a ruling. This is the same gap the 2026-08-18 tagging pass closed from the corpus side β€” found here from the prose side, which reaches files no finding ever named.

Rules never registered at all. "NEVER int() on a float β€” int(3.7) is 3, a real Eufy code", "an unrecognised fault must not be subtracted, because that is the failure", "proof, never assumption" for font support. These need the full order: read the code, rule, mint, declare, cite.

Why a comment is good evidence, and why it rots anyway

A code comment is normally written live β€” at the moment of the change, by the person who had just worked out what was true. That is the whole reason this repo trusts prose at the site over a document: nobody was reconstructing it weeks later from memory.

But the property that makes it accurate at birth is the property that lets it drift. A comment is protected from casual rewriting β€” nobody edits one for fun β€” and that same inertia means nothing forces it to change when the code around it does. High accuracy when written, no maintenance pressure afterwards.

So it decays silently, and worse, it decays while still reading as authoritative, because sitting beside the code is exactly why you believed it. A stale document is suspected on sight; a stale comment is trusted. That asymmetry makes comment rot the more dangerous of the two, not the safer one.

This is not theoretical here, and the evidence is from this repo in one week:

  • 35 of 60 (closed RP-x) claims written into source name a packet whose commits never touched the file. Two were read; both were still live.
  • mapping/mapping_services.py said re-analysis preserves the user's room links because they are "independent of the image-derived segments". They are keyed BY those segments β€” the comment asserted the exact inverse, and read as a decision.
  • queue/queue_engine.py's TypedDicts opened "Canonical shape for…" while a NOTE forty lines above said they describe a shape the module has never emitted.
  • themes/manager.py documented "write-time normalization… without touching storage on every read" in a function whose own body normalizes on every read.
  • The replica harvest needed a STALE status added by the walk itself, for a notice naming a real mechanism at a path it no longer occupies.

What that means for every row below. A candidate is evidence that someone once knew a rule. It is not evidence the rule still binds, that the code still enforces it, or that the sentence was ever right. STALE is not an edge case here β€” it is an expected outcome, and a row that turns out stale is a more valuable find than one that turns out registerable, because it was actively misleading whoever read it next.

What the count is not

236 is a count of leads, not of invariants. Three things will thin it, and each is a verdict a human has to make:

  • Test prose. Several candidates are docstrings in *.test.mjs stating a rule the TEST checks. The rule belongs to the code under test; the test is a citation site at best.
  • Local contracts. "Returns a def or null; never throws" is an API contract for one function, not a system invariant. CONVENTION.
  • Stale assertions. This repo has already found comments asserting a closure that never happened, and prose at a site reads as authority whether or not it earned that. A candidate is not evidence its own claim is still true.
STATUS File Notice
CONVENTION custom_components/eufy_vacuum/adapters/eufy/const.py:44 derived from DOMAIN so that framework namespace changes never silently
INVARIANT (cite IN11T0FS) custom_components/eufy_vacuum/adapters/eufy/room_profiles.py:115 The non-carpet rows are a PREFERENCE applied to users who never asked for it: floor_type
INVARIANT (defended) custom_components/eufy_vacuum/adapters/eufy/vocabulary.py:250 fault that never stopped the robot cleaning silently zeroes a productive run. Observed ⟡ RE-CLASSIFIED 2026-08-21, was STALE. Not stale β€” live, and defended by tests/adapters/eufy/test_error_source.py, which imports both code sets and eufy_error_invalidates_cleaning and asserts they are disjoint and correctly sized. EVIDENCE GRADE: by inspection, NOT ablated. Its consequence is dated and real: alfred job_2026-08-01T23-23-35 cleaned 4 mΒ² in 360 s and recorded cleaning_time_seconds 0.
INVARIANT custom_components/eufy_vacuum/adapters/eufy/vocabulary.py:274 BOTH SETS ARE DECLARED. A code in neither resolves to UNKNOWN, and unknown NEVER
INVARIANT custom_components/eufy_vacuum/adapters/eufy/vocabulary.py:275 invalidates -- an unrecognised fault must not be subtracted, because that is the failure
INVARIANT custom_components/eufy_vacuum/adapters/eufy/vocabulary.py:564 """Coerce to an error code, or None. NEVER int(): int(3.7) is 3, a real code (SIDE
INVARIANT (cite IN40W49E) custom_components/eufy_vacuum/adapters/roborock/adapter.py:344 mode-specific. Without this, _detect_cancel_likely_run never fires
INVARIANT (defended) custom_components/eufy_vacuum/adapters/roborock/vocabulary.py:47 Card-facing dropdown option lists (the framework never reads these). ⟡ RE-CLASSIFIED 2026-08-21, was STALE. ABLATION-PROVEN: swapping the two weakest entries so the list is no longer ascending-suction turned tests/adapters/roborock/test_adapter.py::test_vocabulary red (1 failed / 4471 passed). Restored byte-exact.
INVARIANT (cite IN11T0FS) custom_components/eufy_vacuum/adapters/roborock/vocabulary.py:195 The non-carpet rows are a PREFERENCE applied to users who never asked for it: floor_type
INVARIANT custom_components/eufy_vacuum/adapters/roborock/vocabulary.py:353 follows the rule the Eufy table already states: never invent a label for a code whose
INVARIANT (cite IN3ASEP8) custom_components/eufy_vacuum/battery/manager.py:800 excluded from the delta/rate/drain accounting above, but must not
INVARIANT (cite INNJ6SGC) custom_components/eufy_vacuum/battery/manager.py:866 is already True so this branch never fires, and tracking goes dark
INVARIANT custom_components/eufy_vacuum/battery/manager.py:1231 live:BATT-CV-1 β€” the ratio is unbounded by construction, so plausibility is
INVARIANT (cite IN5ATBW9) custom_components/eufy_vacuum/battery/manager.py:1285 that means it must be cleared here too, or the very next
INVARIANT (cite IN5ATBW9) custom_components/eufy_vacuum/button.py:103 writing state onto the STALE existing object would never
CONVENTION custom_components/eufy_vacuum/button.py:325 start_run_profile is a COROUTINE β€” it MUST be awaited or its body never runs:
CONVENTION custom_components/eufy_vacuum/button.py:326 the press silently no-ops with only a "coroutine was never awaited" warning,
CONVENTION custom_components/eufy_vacuum/config_flow.py:63 must NOT also reload. Single-instance anyway, so this just aborts.
INVARIANT (cite INYA5T84) custom_components/eufy_vacuum/const.py:43 : MUST NOT be stored as an adapter config. Stored configs load first and are
INVARIANT (not test-enforceable) custom_components/eufy_vacuum/const.py:190 live_map_rotation and surfaced in the dashboard snapshot. Display only β€” never ⟡ RE-CLASSIFIED 2026-08-21, was STALE. ⚠ NOT ABLATABLE β€” the claim asserts an ABSENCE ("display only β€” never affects dispatch") and the forbidden coupling does not exist (grep: zero dispatch-side references). To violate it you must ADD a dependency, and no test defends against a coupling never built. Its enforcement is CODE REVIEW; the input that makes it red is a future commit, not a test case. Ablating it would report "nothing red" and FALSELY demote it to CONVENTION.
INVARIANT custom_components/eufy_vacuum/core/capabilities.py:70 : pinning a dead id, but a user choice that has quietly stopped working must be
INVARIANT custom_components/eufy_vacuum/core/capabilities.py:764 each must be DECISIVE (exactly one survivor) or the next is tried:
INVARIANT custom_components/eufy_vacuum/core/capabilities.py:896 live:ENT-7 β€” an override that did not win must SAY so. It is first in
INVARIANT custom_components/eufy_vacuum/core/error_tracker.py:285 NEVER int() on a float β€” int(3.7) is 3, a real Eufy code (SIDE BRUSH
INVARIANT (UNDEFENDED) custom_components/eufy_vacuum/core/error_tracker.py:311 """Exact integers only. NEVER int(): int(3.7) is 3, which is a real Eufy code (SIDE ⟡ CORRECTED TWICE 2026-08-21. Final: DEAD CODE, now DELETED (ledger C18). First read STALE, then re-classified INVARIANT (UNDEFENDED) on an ablation that showed int(3.7) resolving to code 3 (SIDE BRUSH STUCK) with 4,472 tests passing. That second verdict was ALSO wrong, and the error is the more instructive one: _exact_int's only live reference was inside _int_set, and _int_set had NO callers anywhere β€” the pair was UNREACHABLE, superseded by _code_key/_code_set under live:RB-ERR-1 so core could carry enum-string codes. ⚠ ABLATION CANNOT TELL "unguarded" FROM "unreachable": both read as nothing-red. Nor can it tell "defended" from "dead but tested" β€” the Eufy-side twin _exact_error_code turns THREE tests red and also has no production caller (ledger C20). Ablation proves a TEST observes the code; it says nothing about whether PRODUCTION does. A reachability check is a separate step. Both int guards this documented survive verbatim in _code_key's docstring, so the deletion lost nothing. ORIGINAL ABLATION NOTE: int(3.7) made to resolve to code 3 (SIDE BRUSH STUCK) and 4,472 tests passed. ⚠ ONE RULE, THREE COPIES β€” the adapter copy (adapters/eufy/vocabulary.py::_exact_error_code, owed ruling #2) IS defended by 3 tests parametrised on 3.7/2112.9; this core copy and the string variant at error_tracker.py::_code_key (owed ruling #9) are not. Same rule, filed here THREE times under TWO verdicts. Ruling should cover the SET, not the site. See LEDGER "THE NEVER int() RULE".
INVARIANT (cite IN40W49E) custom_components/eufy_vacuum/core/error_tracker.py:655 declare it β€” it was simply never read, so a brand whose firmware says
INVARIANT custom_components/eufy_vacuum/counter_segmentation.py:507 live:RECHARGE-ATTR-1 β€” drop never-boundary kinds BEFORE every mode, including
INVARIANT custom_components/eufy_vacuum/learning/room_attribution_engines.py:223 "cleaned" on it directly. The winding short-circuit must NOT pre-empt it:
CONTESTED custom_components/eufy_vacuum/learning/stats_rebuilder.py:996 flag (missing key -> coerced False here) is never mislabeled "Sanity
CONVENTION custom_components/eufy_vacuum/listeners/stall_capture.py:60 : Fired after a capture lands. Carries the path so an automation never has to
INVARIANT custom_components/eufy_vacuum/listeners/stall_capture.py:65 : images of someone's home must be opted into, never inherited by an upgrade.
CONVENTION custom_components/eufy_vacuum/live_refresh/manager.py:172 RP-039/RF-33: a subclass of HomeAssistantError, so it MUST be caught
CONVENTION custom_components/eufy_vacuum/mapping/stall_capture_render.py:162 """Chevrons along pts, pointing the way the robot travelled. Never raises.
INVARIANT custom_components/eufy_vacuum/mapping/stall_capture_render.py:426 normalize_rendered. They are never offset by (ro_dx, ro_dy) and never flipped;
INVARIANT custom_components/eufy_vacuum/mapping/stall_capture_render.py:496 capture is correct and unrecognisable β€” the room is a shape the user has never seen
INVARIANT (cite INMKEHPQ) custom_components/eufy_vacuum/onboarding/manager.py:237 never saw it. The damage is silent and card-reachable: reconcile_room's
INVARIANT custom_components/eufy_vacuum/receipts/__init__.py:57 : D is the one Β§4 never stated. Β§4 says success may not be silent; a legitimate
INVARIANT custom_components/eufy_vacuum/receipts/__init__.py:103 : DECLARED, NEVER DERIVED from __name__. Deriving would make a file move silently change a
INVARIANT custom_components/eufy_vacuum/receipts/__init__.py:104 : station identity, and Β§18 says a semantic id never silently changes meaning. Declared +
INVARIANT (cite IN4CW5Y9) custom_components/eufy_vacuum/room_entities.py:63 RP-009 (REVIEW D2): ownership is answered by ATTRIBUTES, never by parsing
CONVENTION custom_components/eufy_vacuum/room_entities.py:145 managed subset above, so anything else must still reach the generic
INVARIANT (cite IN40W49E) custom_components/eufy_vacuum/rooms/vocabulary_migration.py:70 : must agree on which axes a brand has, or the repair undoes itself one room at a time.
INVARIANT (cite INKR1TW7) custom_components/eufy_vacuum/rooms/vocabulary_migration.py:274 The rule is EVERY target, not "any adapter answered". With two vacuums, one
INVARIANT (cite INKR1TW7) custom_components/eufy_vacuum/rooms/vocabulary_migration.py:275 provider being ready must not burn the opportunity for a provider that starts
INVARIANT (cite INKV8ZQD) custom_components/eufy_vacuum/services/stall_capture.py:84 Never mint a record for a vacuum this install does not manage β€” that is the
CONVENTION custom_components/eufy_vacuum/services/stall_capture.py:118 renderer. The instrument must not hand anyone that.
CONVENTION custom_components/eufy_vacuum/setup/protection.py:38 DR-SETUP-4: a malformed bucket/room record must degrade like drift.py's
INVARIANT (cite IN6VSBJ1) custom_components/eufy_vacuum/step_types.py:11 different matter and must NOT be merged; read the block.
CONVENTION custom_components/eufy_vacuum/user_fonts.py:165 explicitly (manifest does). This is "cannot verify", never "covers
CONVENTION custom_components/eufy_vacuum/user_fonts.py:166 nothing": the two verdicts must not be conflated.
harness/dist/mount.js:78 raw code, in parens, so a refusal is never blank and never silently renders as success. ---
harness/dist/mount.js:1534 emits {code, params} (params never pre-joined) and the card resolves them via
harness/dist/mount.js:2264 Secondary caption under a renamed room's NEW name in the reconciliation banner's "Renamed" group; {name}=the room's previous name (escaped by the call
harness/dist/mount.js:39959 omitted so the now-relative "Due in N days" projection never fires.
harness/dist/mount.js:44492 Keys MUST match resolveFloorType()'s output β€” e.g. granite resolves to "granite_light",
harness/dist/mount.js:49364 without this the call silently no-ops, file never gets written.
harness/dist/mount.js:49866 and must receive display-ready text. Falls back to the key: a visible miss, never
harness/dist/mount.js:49867 a throw and never a silent drop.
harness/dist/mount.js:50881 server read must never clobber a choice the user just made. Fails soft to
harness/dist/mount.js:50902 verified locales β€” the card never render-verifies; the font file was the
harness/dist/mount.js:53414 Rooms belong to a specific map; a vacuum can have several. The room list must show
harness/dist/mount.js:54586 MUST match custom_components/eufy_vacuum/frontend/animal-svg/animals/index.json.
harness/fixtures/gallery.js:507 omitted so the now-relative "Due in N days" projection never fires.
harness/lib/gallery-html.mjs:80 is the published store and never calls out a merged theme's failure; the "why
harness/lib/mount-page.mjs:19 no such route, so the request 404s, the face never loads, and everything
harness/lib/mount-page.mjs:58 has never once fired for a mountHarness spec. That is why the OpenDyslexic
harness/lib/mount-page.mjs:131 UA paints in its own popup layer and never inline. A
harness/lib/pseudo-locale.mjs:13 ({one,other,...}); transform each FORM string, never the object, or the
harness/lib/site-nav.mjs:29 fall back to "./" so the href is never empty or a "..//" double-slash.
harness/mount-entry.js:78 MUST match custom_components/eufy_vacuum/frontend/animal-svg/animals/index.json.
harness/mount-entry.js:297 never the font itself β€” exactly the gap applyDir was added to close for
harness/mount-entry.js:501 - drop non-primitive values; never eval.
harness/shoot-gallery.mjs:17 run never overwrites the plain baseline shots)
harness/tests/gallery-completeness.spec.mjs:36 coverage that never renders in CI β€” the same "declaration reads as coverage" trap
harness/tests/i18n-layout.spec.mjs:2 I18N LAYOUT GATE β€” a translated locale must not break the layout.
harness/tests/i18n-layout.spec.mjs:178 Hiding text must not strip the name β€” that would trade a layout fix for
harness/tests/i18n-layout.spec.mjs:305 catalogue that registers but never reaches the renderer (a resolve/pin
harness/tests/i18n-rtl.spec.mjs:18 gate can never pass by silently rendering an LTR layout.
harness/tests/i18n-rtl.spec.mjs:30 this spec never imports en.js/flatten.js (Playwright's loader treats a
harness/tests/i18n-rtl.spec.mjs:67 Fidelity guard: the host must actually be RTL, or the gate is vacuous.
harness/tests/smoke.spec.mjs:32 It must have rendered real content into the active view-root,
scripts/animal-descriptor.mjs:13 _render), is EXECUTABLE JS with raw SVG markup. We never accept JS.
scripts/animal-descriptor.mjs:28 intake β€” the SUSPENDERS. Defence in depth; never rely on one alone.
scripts/animal-descriptor.mjs:415 no SVG/string content can break out into executable code. Submitters never
scripts/animal-descriptor.test.mjs:217 so the generated source can never break out into executable code.
scripts/check-i18n.mjs:14 The adversarial case is explicit: a locale value carrying <script> must
scripts/check-i18n.mjs:17 catalog renders byte-identical; it never sees a foreign locale or a
scripts/check-i18n.mjs:21 every literal t("…") / tRaw("…") key used in src/ MUST exist in
scripts/check-i18n.mjs:23 and every en.js key MUST be reachable from source β€” proven three ways
scripts/check-i18n.mjs:25 from the code), never a hand-maintained allowlist. A key reachable by
scripts/check-i18n.mjs:413 picker. A missing index resolves soft (ok:false), never throws.
scripts/check-i18n.mjs:532 never silently exempt the whole catalog.
scripts/check-styles.mjs:4 template literal must be whole. A stray backtick INSIDE one (e.g. .is-open
CONVENTION scripts/check_doc_citations.py:74 The :: branch MUST come first and MUST be spelled with two colons. The original
CONVENTION scripts/check_doc_citations.py:75 pattern had one, so it matched file.py:symbol and never file.py::symbol β€” the
CONVENTION scripts/check_doc_citations.py:77 skipped silently, which meant NO-SYMBOL reported zero findings because it had never
CONVENTION scripts/check_receipts.py:81 dimensionless, but it must be SAID, for the same reason provenance states
CONVENTION scripts/check_receipts.py:166 and a reader trusting the catalog would wait for a signal that never comes.
scripts/gen-theme-token-docs.mjs:103 produced spurious churn, and CI could never agree with a local run.
scripts/gen-theme-token-docs.mjs:248 Split the count so a dynamic family can never be mistaken for a dead one.
CONVENTION scripts/gen_event_docs.py:387 they went stale on commits that never touched an event. Parent links are
INVARIANT (not test-enforceable) scripts/gen_floor_masks.py:59 calibrated for that canvas, so every mask must match or the shift misaligns. ⟡ RE-CLASSIFIED 2026-08-21, was STALE. Ablated SIZE = 2048 β†’ 1024: 4,472 passed, nothing red. But this is a BUILD-TIME generator under scripts/, which the suite never exercises β€” violating it produces wrong masks only when someone REGENERATES. Same blind spot class as the absence-rule above: real, consequential, and structurally invisible to ablation. Do not read "nothing red" here as CONVENTION.
scripts/sanitize-animal-svg.mjs:20 - href / xlink:href must be an internal #fragment (drops external refs).
src/actions/core.js:167 never break the call it's reporting on β€” same defensive pattern as the
src/actions/fetch-failure-tristate.test.mjs:151 FE-ERR-4: a failed saved-zones fetch must not overwrite the library with [].
src/actions/fetch-failure-tristate.test.mjs:163 FE-ERR-6: the trouble-rooms LATCH must be conditional. Unconditional, one failed
src/actions/index.js:56 and must receive display-ready text. Falls back to the key: a visible miss, never
src/actions/index.js:57 a throw and never a silent drop.
src/actions/map.js:242 without this the call silently no-ops, file never gets written.
src/actions/map.js:249 backend means we must opt into returnResponse or the call silently
src/actions/review-snapshot-origin.test.mjs:1 Regression: getLearningHistorySnapshot must FORWARD every filter param to the service.
src/actions/rooms-clear-applied.test.mjs:1 Regression tests for Defect #8 β€” post-apply room mutations must DROP the pending applied
src/actions/rooms.js:366 A zone has no editable value here, but its ids must survive a wholesale resend
src/actions/rooms.js:387 WHY: an explicit save is a strong user action; chips must not show stale data after it.
src/actions/rooms.js:505 source of truth for this room's color, so a reset must persist as an explicit clear. The
src/actions/rooms.js:506 backend only writes color when the key is present, so this never clobbers other callers.
src/actions/saved-zones.js:18 so a background refresh can never clobber the map's optimistic overlays (mirrors
src/actions/theme-refusal-toast.test.mjs:11 generic {success:false} check in actions/core.js's callService never
src/actions/theme-refusal-toast.test.mjs:12 fires for a theme call β€” theme refusals never carry a success field).
src/actions/theme.js:22 that generic check never fires for a theme call. Centralizing the {ok:
src/bindings/map-segments-staleness.test.mjs:1 Regression tests β€” the map-segments slice must follow the ACTIVE MAP, not be fetched
src/bindings/map.js:30 Keys MUST match resolveFloorType()'s output β€” e.g. granite resolves to "granite_light",
src/bindings/map.js:492 map β€” the ft-name list alone never changed on a recolour, leaving the floor image stale.
src/bindings/map.js:1441 silently saving room links onto segments that never persisted.
src/bindings/map.js:2178 An ABORTED gesture (scroll/gesture takeover, focus loss) is NOT a tap β€” never
src/bindings/map.js:2785 panning. This MUST live inside this one handler β€” _on() is idempotent per
src/bindings/map.js:3166 2) Too big. CV variants must never be silently downscaled.
src/bindings/room-editor.js:106 Prefer a human-readable backend message; NEVER surface the raw reason CODE
src/bindings/room-editor.js:429 path added anywhere joins this set β€” it is not optional plumbing, it is the
src/bindings/room-rules-payload.test.mjs:89 is_on/is_off/exists/missing are in NO_VALUE_OPERATORS -> value never set.
src/bindings/setup-reconciliation.test.mjs:16 error, and NEVER auto-confirms the refreshed plan.
src/bindings/setup-reconciliation.test.mjs:191 clearing of a PRIOR note) β€” what must never happen is it being set true,
src/bindings/setup.js:208 configures rooms immediately β€” ghost rooms are never saved otherwise.
src/bindings/setup.js:632 NEVER auto-confirms the refreshed plan; only re-renders State B for the
src/bindings/theme-import-rejected.test.mjs:6 result?.ok === false (inline error) but never looked at
src/bindings/theme-overwrite-confirm.test.mjs:21 so this.t()/this.esc() are actually evaluated and must resolve.
src/bindings/theme-preset-confirm.test.mjs:44 undefined: if (!proceed) return fired, setActiveTheme was never reached, and
src/bindings/theme-preset-confirm.test.mjs:115 passed while the handler was never reaching setActiveTheme for the wrong
src/bindings/theme.js:162 silently filtered out and never made it into the new library theme). A
src/bindings/theme.js:1424 Trigger download via temp anchor. Anchor must live on the
src/cards/card-suggestions.test.mjs:44 Never suggest for an unmanaged vacuum or a non-vacuum entity.
src/cards/dashboard-card.js:212 Never rebuild the DOM mid-draw β€” it would wipe the in-progress zone box.
src/cards/dashboard-card.js:278 Rooms belong to a specific map; a vacuum can have several. The room list must show
src/cards/dashboard-card.js:750 stale scene must never fire select_option (selecting IS the run).
src/cards/dashboard-dispatch.js:6 module produces β€” it never builds service calls itself.
src/cards/map-room-color.js:39 never be themed; remove one and the editor offers a swatch for a token nothing
src/cards/profile-card.js:476 never appeared under "By entity" for a managed vacuum.
src/i18n/card4-untranslated-strings.test.mjs:3 are defined in the English base (src/i18n/en.js:35,371,338) but were never
src/i18n/en.js:70 raw code, in parens, so a refusal is never blank and never silently renders as success. ---
src/i18n/en.js:1130 emits {code, params} (params never pre-joined) and the card resolves them via
src/i18n/flatten.js:11 organizational/dedup benefits live in the FILE, never on the render hot path.
src/i18n/font-store.js:17 chrome. Not against "languages that look Latin": proof, never assumption.
src/i18n/font-store.js:75 are never touched β€” a drop-in cannot widen a shipped font's verified set.
src/i18n/index.js:54 native-reviewed β€” it must NOT auto-activate from the HA system language (it can
src/i18n/index.js:109 An unreviewed locale that must NOT auto-activate from the system language β€” a
src/i18n/index.js:151 catalog is the one translate() uses, so the label must agree (never show a
src/i18n/index.js:250 value carrying markup must never reach the innerHTML sink raw. options.raw
src/i18n/index.js:435 - catalog must be a plain object (else everything is dropped).
src/i18n/index.js:444 is stripped at build, so a key that merely READS as plural must still
src/i18n/lang-store.js:23 pin / system language exactly as before. A language toggle must never be able
src/i18n/lang-store.js:89 object so it never clobbers other keys stored under USER_DATA_KEY. Never
src/main.js:634 If the user already picked this session, their choice wins β€” never let
src/main.js:650 server read must never clobber a choice the user just made. Fails soft to
src/main.js:674 verified locales β€” the card never render-verifies; the font file was the
src/main.js:973 Never switch to a capability-gated tab the adapter doesn't show β€” closes
src/main.js:1550 element's transform INLINE and must not be interrupted by a re-render: the live-map
src/main.js:2131 applied and silently overwrote it β€” mobile_shell has therefore never worked
src/renderers/job-summary.test.mjs:13 [JS-6] per-room battery is never surfaced
src/renderers/job-summary.test.mjs:14 [JS-7] an unrecovered fault never claims it stopped the run
src/renderers/learning-charge-status.test.mjs:1 Render-path tests for the live charge status (slice c / b fix). The banner must render
src/renderers/maintenance-census6.test.mjs:47 Forward-compat: a backend that adds a status this release has not keyed must
src/renderers/maintenance-derive.test.mjs:347 the harness hass null-object is truthy, so || never fires, String() gives
src/renderers/maintenance-derive.test.mjs:349 maintenance render for the default locale. Defaulting must happen AFTER
src/renderers/maintenance.js:785 safety net for a payload that carries a percentage but no status; it must
src/renderers/maintenance.js:849 - reset_at, used_since_reset_hours, remaining_hours must be present
src/renderers/maintenance.js:1004 to "", so || never fires and toLocaleUpperCase("") throws RangeError β€”
src/renderers/map.js:421 When a compose shape is selected for placement, the full-frame art must be
src/renderers/map.js:1198 --fill backdrop must NOT rotate (its polygons would drift, same rule as
src/renderers/pause-timeout.js:6 without a settable dock never rendered it β€” and a pause timeout is not a dock
src/renderers/pause-timeout.js:22 interface could produce silently, via a service call, but never display or
src/renderers/review.js:510 or learning verdict, so it never reads as "Sanity Failed" (backend also forces
src/renderers/review.js:537 Only sources with seconds are named, so a purely robot-side run never
src/renderers/review.js:577 room for a segment β€” flagged for review, never auto-overridden (see reconcile_dispatched_identity).
src/renderers/review.js:601 English β€” never a raw key. tVocabRaw (not tVocab) because the note is sunk
src/renderers/review.js:603 join β€” never zip codes[] with the index-filtered *_texts[] arrays, which can
src/renderers/room-estimate-allocated.test.mjs:28 "default" note must keep firing, so a fix that touches this file can't
src/renderers/run-profiles-unsupported-position.test.mjs:12 required_behavior text says must never happen: "a legacy profile carrying one
src/renderers/run-profiles-unsupported-position.test.mjs:14 position)' ... never a silently-shown step that won't run."
src/renderers/run-profiles.js:234 never actually run. Flag it struck-through with an explanatory note rather than
src/renderers/setup-reconciliation.test.mjs:106 (never concatenated into one sentence with the room name).
src/renderers/setup-reconciliation.test.mjs:178 reports has_changes:false. The stale manual re-discover prompt must not
src/renderers/setup-reconciliation.test.mjs:250 resolvedToken is for a DIFFERENT (older) plan β€” must not suppress the fresh review.
src/renderers/setup.js:409 changes" read is authoritative and must win β€” otherwise the manual
src/renderers/setup.js:922 was never contested β€” NOT that nothing decided it β€” so it must not
src/renderers/setup.js:926 specific rung fired -- for a role whose source was never recorded. On a
src/state/access-graph-model.js:171 Excludes self, and rooms claimed by ANOTHER room β€” but never a room this one
src/state/access-graph-model.test.mjs:14 [AGM-11] validateEdit does NOT enforce completeness (a graph must be
src/state/coded-label.js:17 never heard of from rendering blank β€” a newer backend can add a reason
src/state/coded-label.js:104 that the raw code, which at least names the condition; never blank, and
src/state/coded-label.js:105 never a silent success.
src/state/core.js:142 I've never noticed it's missing"), which is what a silent upstream
src/state/dialog.js:8 the BROWSER's locale (so they can never follow the card's per-user
src/state/external-jobs.js:156 REV-2: same as openExternalWizard β€” suggest, never pre-select. A
src/state/learning.js:837 working branches behind it were unreachable and the warning could never render on
src/state/live-trail.js:15 order return docks WITHIN a clean and must not split the trace). The card fires
src/state/map.js:283 never on first load (oldMapId undefined) or a transient null-clear, which
src/state/map.js:353 not been uploaded yet must read as "missing" (-> upload prompt), never
src/state/map.js:358 the brand's live image as its backdrop β€” never an uploaded variant β€” so you
src/state/map.js:411 backdrop). The composer must then render the backdrop with object-fit:contain
src/state/metrics.js:159 (accumulated, never cleared), so a selected/filtered-down chip or card keeps
src/state/room-editor-matching.test.mjs:139 Roborock declares no clean_intensity axis at all. Absent must stay absent β€”
src/state/rooms-logic.test.mjs:375 prose and no reason must not go silent just because the card now leads
src/state/run-profiles-steps.test.mjs:56 live there), so a brand-new draft must still open it even with nothing to
src/state/run-profiles-steps.test.mjs:154 ---- Defect #4f: pendingStepRunProfileId + has_stops must gate on SEQUENCED runs,
src/state/run-profiles-steps.test.mjs:155 not charge-only. A WAIT-only or multi-group profile is stepped and MUST route
src/state/run-profiles.js:327 Insert just before the last existing step, never at the very end -- a
src/state/run-profiles.js:333 so a brand-new draft must still open it even when it has nothing to
src/state/saved-zones.js:6 Isolated slot fed by refreshSavedZones -> getSavedZones. It NEVER mutates the shared
src/state/saved-zones.js:44 so "Clean N selected" never carries a stale id that the service would refuse.
src/state/steps-order.js:71 sequence -- it would be silently skipped, never run (CARD-6 clause (1), Q17). Refuse
src/state/steps-order.js:165 dispatch (the per-group overlay only overrides what is actually set) β€” never clobber a real
src/state/steps-order.test.mjs:80 skipped, never run -- refused as a no-op (mirrors LB-1's leading case).
src/state/steps-queue-order.js:13 (rooms) adapter, so this must be applied AFTER applyRoomsOrderState.
src/state/theme-resolve.test.mjs:154 combine must apply the draft alpha to the theme color, not keep a stale bake.
src/state/theme.js:382 and alpha multipliers (0–1 numbers) never overwrite each other during
src/state/viewport-landscape.test.mjs:73 Tests and SSR have no window; the predicate must not invent a height and
src/state/zone-draft.test.mjs:160 Roborock never enters custom/live-backdrop mode (segmentationMode stays 'cv'),
src/styles/animal-hsl.test.mjs:5 tokens must be BARE HSL COMPONENTS. The theme system stores colours as
src/styles/animal-hsl.test.mjs:22 Yellow at 88% β€” the value in the bug report. Must NOT drop the opacity:
src/styles/animal-hsl.test.mjs:46 triplet, or a var() reference, must pass through untouched rather than be
src/styles/fonts.js:59 stack MUST be a full fallback chain, and every inner var() MUST carry a
src/styles/fonts.js:178 Validate + normalize one CATALOG entry. Returns a def or null; never
src/styles/fonts.js:245 bad entry) is a skip, never a throw β€” the shipped fonts must be untouched
src/styles/typeface-wiring.test.mjs:181 FONT_STACK_PRESETS appends FONT_DEFS automatically β€” a new card font must
src/styles/user-fonts.test.mjs:122 A drop-in can never widen a shipped font's HUMAN-verified set.
src/theme-tags/derive.mjs:8 are computed on the fly and never stored, so tweaking the taxonomy updates every