Four parallel reviews (reuse, simplification, efficiency, altitude). The two
that change behavior:
- observe() could report "changed" on every poll forever, rewriting the
config entry each time. If both tokens name the same slot with different
payloads -- a downloaded program with its settings tweaked for one run is
exactly that shape -- each pass wrote the default's blob then the one-shot's
over it, so neither was ever already stored. On the SD-card installs this
integration runs on, sustained entry rewrites are the one cost here that
bites. The end state is stable, so "changed" is now start-vs-end, not
per-assignment.
- The write path copied every tracked href to read one rep, walking past the
accessor added to avoid exactly that. New entity_rep() does the merge for a
single href; cycle_write drops the resources parameter it never used.
Structure:
- device_resources() is a second accessor giving the pure device view, used
by diagnostics and the debug read service. That deletes strip_synthetic,
the _SYNTHETIC_KEY_PREFIX convention and the redact filter added last
commit: "a dump is what the device said" is now which method you call
rather than something every future exporter has to remember.
- apply_cloud_courses() is the single mutation path. The flow was reaching
past the coordinator into the store and relying on a later call to persist
and invalidate for it; nine names are also now one entry write, not nine.
- option_value/hex_pairs move to capabilities/common.py. The duplicate's
stated reason -- that the coordinator shouldn't import from
registry.capabilities -- was simply false; it already does, and so does
learned.py. The real constraint is narrower: laundry.py imports
cloudcourse, so the reverse would be a cycle.
Dropped rather than kept:
- The cloud-vs-translated-local-course name check, and catalog.
translated_state_labels with it. The catalog this process can read is
English while the dropdown is localized in the frontend, so it rejected
"Cotton" for a German user seeing "Baumwolle" and missed the real collision
when they typed "Baumwolle" -- wrong in both directions outside one locale,
against an outcome option ordering already makes deterministic. The checks
that survive compare strings that are the same in every locale: the user's
own names, and the device's personal-course labels.
- stored(), clear()/forget_cloud_courses(), blob(), download_course() -- no
production callers. stored() was a template artifact whose docstring
described a caller that cannot exist here.
Diagnostics gains a cloud_courses block, which the store was missing next to
learned_modes -- payloads and which slots are named, but not the names
themselves, since those are the user's words and dumps get pasted publicly.
Kept against one reviewer's advice: option_tokens (two others called
generalizing option_write the right direction) and select._display's
uncatalogued branch, which names a condition the old fallback-is-None proxy
only got right by accident. Deferred: making the store per-subdevice. It is
MAIN-only today and no device seen advertises cloud programs elsewhere; the
limitation is now documented where it is made.