Skip to content

fix(discovery): coherent progress reporting across every stage#458

Merged
fdebrus merged 1 commit into
mainfrom
claude/discovery-progress-fix
Jun 9, 2026
Merged

fix(discovery): coherent progress reporting across every stage#458
fdebrus merged 1 commit into
mainfrom
claude/discovery-progress-fix

Conversation

@fdebrus

@fdebrus fdebrus commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the user-reported progress-UI breakage at every discovery stage (bar jumping backward, freezing, incoherent counters, periods without updates). A pipeline audit (library _emit_progress_handle_discovery_progressdiscovery_progress_percent → sensors) found four interacting defects — together they explain all four symptoms. All fixed HA-side; no library change needed.

1. 🔴 The bar DROPPED ~97 % → 10 % at the end of every run

The reconciliation sets sub_phase=probing for its 5-15 s residue probe; discovery_progress_percent had no branch for PROBING and fell through to the legacy 10 % fallback. Now mapped into the finalizing weight band (~98.8 %). (→ "bar jumps backward")

2. 🔴 Coarse phase regressed during reconciliation

The three _update_discovery_state calls in _reconcile_post_discovery forced phase=pc_link — after a module scan the status sensor's state regressed module_scan → pc_link for the probe window, feeding the same 10 % fallback. Phase override removed; the run's phase is kept. (→ "incoherent values")

3. 🟠 Competing writers froze the inventory bar at "1/1"

The library emits inventory progress once, as a single unit (register_total=1, registers_sent=1); writing that through clobbered the live 0..92 frame counter from _discovery_frame_callback, whose min(total=1, …) then froze — bar pinned, message "PC-Link inventory: 1/1 registers" for the whole phase. The progress handler now skips register counters during the inventory sub-phase (the frame callback owns them), and the transition-zeroing excludes entry into inventory so the seeded total survives. (→ "frozen bar" + "no updates")

4. 🟠 Frame counter counted during the identity phase

The same $2E frames keep flowing during identity (96 reads × N modules); the unconditional increment fought the library's authoritative per-module counters between on_progress emits (flickering counts). Counting is now gated on the inventory sub-phase, like the message already was (2.11.2). (→ "incoherent values")

Expected behaviour after this PR

  • Inventory: smooth 0→92 frame counting, real device count in the message.
  • Identity / register scan: library-owned counters, no flicker.
  • End of run: ~95 % (finalizing) → ~98.8 % (probing) → 100 % — monotonic, no drop to 10 %.
  • Status sensor state never regresses to pc_link after a module scan.

Tests

+4 regressions (probing percent in both scopes, inventory-emit clobber guard incl. transition zeroing, identity-phase counter gate); 1 test updated — it pinned the old identity-counting behaviour that fix 4 intentionally removes.

444 passed, ruff clean, mypy 100 (= baseline).

https://claude.ai/code/session_01LH7yGDY8ttvZUVMVjfSNXj


Generated by Claude Code

User-reported: progress UI broken at every stage (bar jumps backward,
freezes, incoherent counter values, periods with no updates). Pipeline
audit found four interacting defects, all fixed HA-side:

1. PROBING hole in discovery_progress_percent (bar DROPPED ~97% -> 10%).
   The reconciliation sets sub_phase=probing for its 5-15 s residue
   probe at the end of EVERY run; the percent property had no branch
   for it and fell through to the legacy fallback (10%). Now mapped
   into the finalizing weight band (~98.8%).

2. Coarse-phase regression during reconciliation. The three
   _update_discovery_state calls in _reconcile_post_discovery forced
   phase=pc_link — after a module scan the status sensor's state
   REGRESSED from module_scan to pc_link for the probe window (and fed
   the same legacy 10% fallback). The phase override is removed; the
   run's phase is kept.

3. Competing writers froze the inventory bar at '1/1'. The library
   emits inventory progress ONCE as a single unit (register_total=1,
   registers_sent=1); writing that through clobbered the live 0..92
   frame counter maintained by _discovery_frame_callback, whose
   min(total=1, ...) then froze at 1 — bar pinned, message
   'PC-Link inventory: 1/1 registers' for the whole phase. The
   progress handler now skips the register counters for the inventory
   sub-phase (frame callback owns them), and the sub-phase-transition
   zeroing excludes entry into inventory so the seeded total survives.

4. Frame counter counted during the identity phase. The same $2E
   frames keep flowing during identity (96 reads x N modules); the
   unconditional increment fought the library's authoritative
   per-module counters between on_progress emits (flicker/incoherent
   values). Counting is now gated on the inventory sub-phase, like the
   message already was (2.11.2).

Tests: +4 regressions (probing percent full+module_scan scopes,
inventory-emit clobber guard incl. transition zeroing, identity-phase
counter gate); 1 test updated — it pinned the old identity-counting
behaviour that fix 4 removes. 444 passed, ruff clean, mypy 100
(= baseline).

https://claude.ai/code/session_01LH7yGDY8ttvZUVMVjfSNXj
@fdebrus fdebrus merged commit db0acc8 into main Jun 9, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants