Conversation
…pension A Z-Wave lock without Supervision is verified by the driver reading the code back. When that read times out the driver reports the outcome as unknown, and its cache keeps showing the slot empty. Every later read goes through the same path and shows the same nothing, so the coordinator gave the write up at its deadline, the sync rewrote it, and the slot was suspended while the PIN worked at the keypad (#1307). A write the stack reported as unverifiable is now kept as unconfirmed when it is not seen by its deadline, and reads as unreadable, which sync judges by the last PIN it wrote. A readable value, an empty slot pushed by the lock itself, or a new write or clear ends it. Writes the stack confirmed are still counted failed when a read never shows them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 00091a8fc90e
…uccess Setting the data through the coordinator marked the failed read a success and cancelled the refresh queued to probe for recovery. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 0ce1bede55a9
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1575 +/- ##
========================================
Coverage 99.23% 99.24%
========================================
Files 66 66
Lines 8935 9041 +106
Branches 530 530
========================================
+ Hits 8867 8973 +106
Misses 68 68
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
5 tasks
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: db951e15fc74
A write the stack could not verify may be on the lock while the stack's cache does not show it. A clear resolved the credential's owner from that cache, found none, and sent nothing: a disabled user's code could keep opening the door, and with the write trusted the slot never settled. The lock user an unverified write went to is kept per slot, and a clear that finds no owner in the cache deletes the credential through that user. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 440e3e13a767
…not verify A cache that never saw an unverifiable write keeps answering with the code the slot held before, which is no more evidence than an empty slot; the coordinator now remembers that value per write and treats a read repeating it as no answer. Z-Wave deletes reported as unknown are trusted empty the same way instead of raising into a clear loop, the unconfirmed PIN still counts in the duplicate check, and the owner an unverified clear went through is kept for a later clear. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 57b27123fbce
The lock saying the slot holds a code it will not show is what the write would look like, so it is no reason to stop trusting it; the test now reads the stale cache after the push to tell the two apart. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 46c836050ebe
A read that settles the slot makes the remembered user a stale guess, and releasing the slot then would delete a code that may be someone else's. Writing back the code the slot held also no longer treats a read of that code as a stale cache. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: b638515389fe
…e slot Gating on the coordinator's doubt missed a disable while the write was still pending: sync drops the pending write before it clears, so the clear found no owner and sent nothing. What protects another person's code is whether the cache shows one at the slot, so the fallback now asks exactly that. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: fcd7a3a2b49b
The code a stale cache answers with is the last one read or pushed, not whatever data shows: a believed write that sync replaced while pending, or a write-back that kept no record, made the next write or clear take the wrong old code and charge or repeat once. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: b37a1297b7de
…owner on doubt Sync dropping a pending write when the configuration changed also erased what was known about the lock, which is why the owner fallback kept needing a different guard. Superseding keeps an unverified write standing as unconfirmed, so the fallback can ask the one question that matters -- is the slot still in doubt -- whatever the stack's cache shows. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 042caf26484a
…rite The unreadable value kept for a write the stack could not verify stayed in the data after a clear the driver did verify, so the slot showed a code for a disabled user. The duplicate check also reads kept PINs on their own, since a read may leave their slot out. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 4a26a085435e
5 tasks
Owner
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proposed change
A Z-Wave lock without the Supervision command class is verified by the driver reading the code back after each write. On a lossy link that read often times out. The driver then reports the outcome as unknown (
credential_rejected_unknown, mapped toWriteResult.OPTIMISTIC), and its value database keeps showing the slot as available. Every later read goes through the same path and shows the same nothing. The coordinator gave the write up at its deadline, sync rewrote it, and after three laps the slot was suspended, while the PIN worked at the keypad. That is the loop in #1307 (and #1397 before it).An empty read after an unverifiable write is not evidence the write failed: it is the same read the driver already could not complete. So:
believed) that is not seen by its deadline is kept as unconfirmed instead of counted failed. It reads asSlotCredential.unreadable(), which sync already judges by the last PIN it wrote, the same way it treats a lock that never shows its codes (Matter).unconfirmed_writes, so a report shows which slots are trusted on the strength of their write.This reverses one earlier choice on purpose: a confirmation read that fails outright past the deadline used to fail a believed write too, so that a lock whose reads never return ended in a visible suspension. For an unverifiable write that read is exactly the one the stack could not complete, so it is now treated the same way. Only Z-Wave returns
OPTIMISTICtoday, and only forERROR_UNKNOWN, which the driver reports when its own read-back did not arrive.Trade-offs:
Tests:
last_update_successas it was; diagnostics name the unconfirmed slots.Full suite green at 100% coverage.
Type of change
Additional information
🤖 Generated with Claude Code