- coordinator: _poll_subdevice_flat_hrefs called sess.pace() outside its
try block and re-read self._session instead of using the caller's
already-None-checked reference -- a session closed mid-poll (async_close()
doesn't hold _session_lock) could crash the whole poll cycle instead of
just dropping that one sibling. Now takes sess from the caller and guards
pace() the same as get().
- coordinator: skip flat hrefs already covered by the hot/warm sub-poll
tiers -- those are refreshed every few seconds by _run_subpolls already,
so re-fetching them again on the once-per-summary-poll flat pass only adds
GETs, not freshness. Matters because, unlike the Collection path (always
one GET), a flat subdevice's summary-poll cost scales with its href count.
- subdevices.py module docstring: corrected an overclaim inherited from PR
#199 that GET /<uuid>/device/0 had been "confirmed live" on jhkwon19's
unit. Only an individual /information/vs/0 read was ever actually
confirmed; the Collection endpoint itself has never been observed to
answer on any known unit, which is exactly what issue #205 exposes.
- SKILL.md: fixed the numofsubdevice cross-check formula to match what
coordinator.py actually compares (len(materialized) + 1, not
len(subdevices) + len(subdevices_skipped)).
- Documented, not yet guarded against: a firmware that echoes state back
under any unrecognized prefix instead of 4.04ing could pass the flat probe
and the liveness gate, materializing a phantom duplicate of the master.
Every board seen so far genuinely 4.04s on paths it doesn't own.
- Added test coverage the review flagged as missing: a materialized (not
just skipped) flat subdevice re-polling end-to-end through to
canonical_resources, the hot/warm skip itself, zero-master-hrefs and
two-UUID no-cross-contamination edge cases, and a golden file for the
#205 fixture (SKILL.md's "fixture + golden + test" discipline).