Skip to content

fix(menu): rebuild dialog no longer promises duplication it cannot cause (#132) - #148

Merged
simons-plugins merged 3 commits into
mainfrom
fix/132-rebuild-warning
Aug 8, 2026
Merged

fix(menu): rebuild dialog no longer promises duplication it cannot cause (#132)#148
simons-plugins merged 3 commits into
mainfrom
fix/132-rebuild-warning

Conversation

@simons-plugins

@simons-plugins simons-plugins commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Closes #132.

What

The Rebuild Matter Endpoint Map… dialog warned that rebuilding WILL duplicate accessories in already-paired ecosystems. It cannot: rebuild() adopts the live endpoint numbers as the new baseline and renumbers nothing, so it cannot itself change what any ecosystem sees. The duplication risk belongs to the drift/storage-loss event that already happened — rebuilding only stops reporting it. Observed live 2026-08-06: after a last-fabric factory reset, rebuilding was the correct and harmless action while the dialog read as though it was about to break the house.

Where

The issue named four files; the same false claim actually lived in seven user-facing places — including the attach-refusal log line the user reads immediately before opening the dialog. All rewritten to distinguish the issue's two cases:

  • only the map file was damaged (Matter storage intact) → accessories keep their numbers, no ecosystem sees any change, the rebuild simply clears the refusal;
  • the bridge's Matter storage was lost → the ecosystems already hold dead accessories under the old numbers; rebuilding accepts that rather than causing it.
Place Change
MenuItems.xml dialog warning + confirm-tick label
plugin.py tick error, REBUILT log, callback docstring
bridge_client.py TERMINAL_ATTACH_ERRORS map remedy
export_bridge.py map-unreadable refusal log (now also names the menu path)
bridge_protocol.py build_rebuild_endpoint_map docstring — "reallocate from scratch" was mechanically wrong too
node.ts refuse-to-serve remedy line
BRIDGE_PROTOCOL.md §1.1 + §3.11, INSTALL.md matching passages; INSTALL drops the "worse one first / UNRECOVERABLE" framing

Deliberately kept

  • The confirm tick — the rebuild still irreversibly discards the only repairable record (quarantined aside, not deleted), so it still earns a pause.
  • The healthy-node refusal wording — a rebuild against a non-refusing node genuinely would discard §3.3's retained endpoint numbers.
  • Every claim that silent reallocation duplicates accessories (DriftEntry docstring, PRD §7 table) — that claim is about renumbering, which drift auto-repair would do and the confirmed rebuild does not.

Tests

Pins moved to the new claim rather than the absence of the old phrase: the dialog test asserts "cannot itself duplicate accessories" / "renumbers NOTHING"; the refusal-log tests assert "renumbers nothing"; the identity-vs-map branch test's map-remedy-leak canary moves from "duplicate accessories" not in said (which would now pass trivially) to "renumbers nothing" not in said.

Suites: 2256 Python / 383 TS, both green. pylint 9.52 on touched modules. Version 2026.8.5 → 2026.8.6. Strings only — no behaviour change.

🤖 Generated with Claude Code

https://claude.ai/code/session_018Unpt5UPRdLoZkahH6a4gL

Summary by CodeRabbit

  • Bug Fixes

    • Corrected endpoint-map recovery messaging to clarify that rebuilding preserves existing endpoint numbers and does not itself duplicate accessories.
    • Distinguished map corruption from lost bridge storage, including their different recovery outcomes.
    • Clarified that pairing and Indigo devices remain unchanged during recovery.
  • Documentation

    • Updated recovery guidance, warnings, confirmations, and troubleshooting information.
    • Clarified that rebuilds replace the endpoint-number record, preserve the damaged record, and cannot be undone.
  • Chores

    • Updated the plugin version to 2026.8.6.

simons-plugins and others added 2 commits August 8, 2026 18:20
…use (#132)

The Rebuild Matter Endpoint Map… dialog warned that rebuilding WILL
duplicate accessories in already-paired ecosystems. It cannot: rebuild()
adopts the live endpoint numbers and renumbers nothing, so any
duplication belongs to the storage-loss event that already happened —
observed live 2026-08-06, where post-reset drift made the rebuild the
correct and harmless action while the dialog read as though it was about
to break the house.

The same false claim lived in seven user-facing places, including the
attach-refusal log the user reads immediately before opening the dialog.
All now distinguish the issue's two cases: a damaged map file with
Matter storage intact (no ecosystem sees any change) vs lost Matter
storage (the duplicates already exist; rebuilding accepts that rather
than causing it).

- MenuItems.xml: dialog warning + confirm-tick label
- plugin.py: tick error, REBUILT log, callback docstring
- bridge_client.py: TERMINAL_ATTACH_ERRORS map remedy
- export_bridge.py: map-unreadable refusal log (now also names the menu path)
- bridge_protocol.py: build_rebuild_endpoint_map docstring ("reallocate
  from scratch" was mechanically wrong too)
- node.ts: refuse-to-serve remedy line
- BRIDGE_PROTOCOL.md §1.1 remedy table + §3.11; INSTALL.md
  destructive-actions section (drops the "worse one first / UNRECOVERABLE"
  framing)

Kept, deliberately: the confirm tick (the rebuild still irreversibly
discards the only repairable record — quarantined aside, not deleted);
the healthy-node refusal (that one genuinely would discard §3.3's
retained numbers); and every claim that SILENT reallocation duplicates
accessories (DriftEntry, PRD §7 table) — that is about renumbering,
which drift auto-repair would do and the confirmed rebuild does not.

Tests pin the new claim rather than the absence of the old phrase; the
identity-vs-map branch test's leak canary moves from "duplicate
accessories" to "renumbers nothing", which the map remedy actually says.

Suites: 2256 Python, 383 TS, both green. Version 2026.8.5 → 2026.8.6.

Closes #132

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Unpt5UPRdLoZkahH6a4gL
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Unpt5UPRdLoZkahH6a4gL
@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@simons-plugins, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 24 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 83b4b6d4-60d4-40b5-af90-117cd0aa74ee

📥 Commits

Reviewing files that changed from the base of the PR and between 20c396f and db93f8b.

📒 Files selected for processing (10)
  • bridge-node/src/endpoint-map.ts
  • docs/BRIDGE_PROTOCOL.md
  • docs/HANDOVER.md
  • docs/INSTALL.md
  • indigo-matter.indigoPlugin/Contents/Server Plugin/MenuItems.xml
  • indigo-matter.indigoPlugin/Contents/Server Plugin/bridge_client.py
  • indigo-matter.indigoPlugin/Contents/Server Plugin/plugin.py
  • tests/test_bridge_client.py
  • tests/test_bridge_protocol_frames.py
  • tests/test_export_menu.py
📝 Walkthrough

Walkthrough

The change corrects endpoint-map recovery wording across bridge messages, plugin UI, logs, tests, and documentation. Rebuilding now adopts live endpoint numbers without renumbering. Storage-loss consequences remain separate from map-file damage.

Changes

Endpoint Map Recovery

Layer / File(s) Summary
Recovery semantics and refusal contracts
bridge-node/src/node.ts, bridge-node/test/persistence.test.ts, docs/BRIDGE_PROTOCOL.md, indigo-matter.indigoPlugin/Contents/Server Plugin/bridge_client.py, indigo-matter.indigoPlugin/Contents/Server Plugin/bridge_protocol.py, indigo-matter.indigoPlugin/Contents/Server Plugin/export_bridge.py, tests/test_export_bridge.py
Refusal messages and protocol documentation state that rebuilding adopts current endpoint numbers. Tests distinguish endpoint-map refusal from identity-file refusal.
Rebuild menu and runtime flow
indigo-matter.indigoPlugin/Contents/Server Plugin/MenuItems.xml, indigo-matter.indigoPlugin/Contents/Server Plugin/plugin.py, tests/test_bridge_client.py, tests/test_export_menu.py
The menu, confirmation, success log, and tests describe irreversible map replacement without renumbering or pairing changes.
Recovery documentation and release metadata
docs/INSTALL.md, docs/HANDOVER.md, indigo-matter.indigoPlugin/Contents/Info.plist
Recovery outcomes and handover status are updated. The plugin version changes to 2026.8.6.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: correcting the rebuild dialog so it does not claim that rebuilding causes duplication.
Linked Issues check ✅ Passed The changes satisfy issue [#132] by correcting rebuild warnings, distinguishing map damage from storage loss, and updating related documentation and tests.
Out of Scope Changes check ✅ Passed The changes remain within scope for [#132], including messaging, documentation, tests, handover notes, and the related version increment.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/132-rebuild-warning

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/BRIDGE_PROTOCOL.md`:
- Around line 308-310: Update the explanatory sentence near the endpoint-map
quarantine command so existing duplication is attributed specifically to the
earlier loss of Matter storage, not to loss or damage of the endpoint map.
Preserve the distinction that the command discards the surviving mapping record
without itself duplicating accessories.

In `@docs/INSTALL.md`:
- Line 555: In the documentation text near “accessories,” replace the British
English word “afterwards” with the American English form “afterward,” leaving
the surrounding wording unchanged.

In `@indigo-matter.indigoPlugin/Contents/Server` Plugin/export_bridge.py:
- Around line 1355-1358: Update the unreadable-map warning in the export bridge
to remove the assertion that duplication has already happened. Use the
established storage-loss wording from the corresponding MenuItems.xml and
INSTALL.md guidance, describing the potential for paired ecosystems to retain
dead accessories under old endpoint numbers without claiming duplication is
guaranteed.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0f161f93-05ac-4ac7-9990-91a2001f94c0

📥 Commits

Reviewing files that changed from the base of the PR and between 89f9de5 and 20c396f.

📒 Files selected for processing (14)
  • bridge-node/src/node.ts
  • bridge-node/test/persistence.test.ts
  • docs/BRIDGE_PROTOCOL.md
  • docs/HANDOVER.md
  • docs/INSTALL.md
  • indigo-matter.indigoPlugin/Contents/Info.plist
  • indigo-matter.indigoPlugin/Contents/Server Plugin/MenuItems.xml
  • indigo-matter.indigoPlugin/Contents/Server Plugin/bridge_client.py
  • indigo-matter.indigoPlugin/Contents/Server Plugin/bridge_protocol.py
  • indigo-matter.indigoPlugin/Contents/Server Plugin/export_bridge.py
  • indigo-matter.indigoPlugin/Contents/Server Plugin/plugin.py
  • tests/test_bridge_client.py
  • tests/test_export_bridge.py
  • tests/test_export_menu.py

Comment thread docs/BRIDGE_PROTOCOL.md Outdated
Comment thread docs/INSTALL.md
which Matter accessory number belongs to which Indigo device; rebuilding it
discards the unreadable record and adopts whatever numbers exist now as the new
one. It renumbers nothing, so **the rebuild itself cannot duplicate
accessories** — what you see afterwards depends on which fault brought you

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use the American English form.

Line 555 uses afterwards. Replace it with afterward.

Proposed fix
- accessories** — what you see afterwards depends on which fault brought you
+ accessories** — what you see afterward depends on which fault brought you

The static analysis hint identifies afterwards as the non-preferred American English variant.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
accessories** — what you see afterwards depends on which fault brought you
accessories** — what you see afterward depends on which fault brought you
🧰 Tools
🪛 LanguageTool

[locale-violation] ~555-~555: In American English, ‘afterward’ is the preferred variant. ‘Afterwards’ is more commonly used in British English and other dialects.
Context: ... duplicate accessories** — what you see afterwards depends on which fault brought you here...

(AFTERWARDS_US)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/INSTALL.md` at line 555, In the documentation text near “accessories,”
replace the British English word “afterwards” with the American English form
“afterward,” leaving the surrounding wording unchanged.

Source: Linters/SAST tools

Comment on lines +1355 to +1358
"map is unreadable (%s). Nothing will be exported until it is rebuilt (Plugins "
"▸ Matter ▸ Rebuild Matter Endpoint Map…). The rebuild renumbers nothing: if "
"only the map file was damaged no paired ecosystem will see any change, and if "
"the bridge's Matter storage was lost the duplication has already happened.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Do not assert that duplication has already happened.

At Line 1358, the node is still refusing to serve the rebuilt endpoint set. Lost Matter storage can leave paired ecosystems with dead accessories under old endpoint numbers, but duplication is not guaranteed at this point. Use the same storage-loss wording as indigo-matter.indigoPlugin/Contents/Server Plugin/MenuItems.xml Lines 346-352 and docs/INSTALL.md Lines 558-568.

Proposed wording
-                "the bridge's Matter storage was lost the duplication has already happened.",
+                "the bridge's Matter storage was lost, paired ecosystems may already contain "
+                "dead accessories under the old numbers; rebuilding accepts that state.",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"map is unreadable (%s). Nothing will be exported until it is rebuilt (Plugins "
"▸ Matter ▸ Rebuild Matter Endpoint Map…). The rebuild renumbers nothing: if "
"only the map file was damaged no paired ecosystem will see any change, and if "
"the bridge's Matter storage was lost the duplication has already happened.",
"map is unreadable (%s). Nothing will be exported until it is rebuilt (Plugins "
"▸ Matter ▸ Rebuild Matter Endpoint Map…). The rebuild renumbers nothing: if "
"only the map file was damaged no paired ecosystem will see any change, and if "
"the bridge's Matter storage was lost, paired ecosystems may already contain "
"dead accessories under the old numbers; rebuilding accepts that state.",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@indigo-matter.indigoPlugin/Contents/Server` Plugin/export_bridge.py around
lines 1355 - 1358, Update the unreadable-map warning in the export bridge to
remove the assertion that duplication has already happened. Use the established
storage-loss wording from the corresponding MenuItems.xml and INSTALL.md
guidance, describing the potential for paired ecosystems to retain dead
accessories under old endpoint numbers without claiming duplication is
guaranteed.

…tible string (#132)

The review-pr pass (code-reviewer, comment-analyzer, pr-test-analyzer)
on PR #148 found that the phrase-keyed sweep missed the false model
stated in different words:

- bridge_client.rebuild_endpoint_map() docstring still said "Reallocate
  endpoint numbers from scratch… This DUPLICATES accessories" — the
  docstring of the very method that executes the confirmed rebuild
- two test comments taught "§3.11 exists to hand out NEW endpoint
  numbers" (test_bridge_protocol_frames, test_bridge_client) — the
  fixture's differing numbers depict a post-storage-loss node, not
  §3.11 reallocating

Also from review:

- pin the TERMINAL_ATTACH_ERRORS map remedy ("renumbers nothing") —
  the one corrected string a revert could silently restore — plus the
  symmetric not-in canary on the identity branch
- pin the confirm-tick label and tick-error text; shorten the tick
  label from 108 chars to one-line length
- "sees any change" → "sees any further change" (dialog + INSTALL):
  a damaged-map user may already have watched accessories go
  unavailable while the node refused (the #141 condition)
- reflow the orphaned line in menuRebuildEndpointMap's docstring
- BRIDGE_PROTOCOL.md: return the two stranded §1.1 rows
  (commissioning_window_failed, internal) to the error-code table
  (pre-existing breakage in the passage being edited); "a lost map
  implies" → "lost Matter storage implies" here and in endpoint-map.ts
- INSTALL.md: Reset header "recoverable, at the cost of pairing again"
  dangled once its "UNRECOVERABLE" counterpart died → "recoverable by
  pairing again"

Suites: 2256 Python, 383 TS, both green. pylint on
bridge_client+plugin 9.32, measured identical on the pre-fix baseline.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Unpt5UPRdLoZkahH6a4gL
@simons-plugins
simons-plugins merged commit 775de2e into main Aug 8, 2026
3 checks passed
@simons-plugins
simons-plugins deleted the fix/132-rebuild-warning branch August 8, 2026 18:18
simons-plugins added a commit that referenced this pull request Aug 8, 2026
[no-release] docs(handover): #148 merged, v2026.8.6 released
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.

Rebuild Endpoint Map warning overstates what the action does

1 participant