Skip to content

Commit 65fd810

Browse files
committed
access-controller: clear backoff_until on grant-after-sync
Defensively reset `backoff_until` alongside `failed_attempts` in the SyncComplete-allowed branch of AccessCore so the two counters stay in lockstep on a successful grant-after-sync. The state machine as written cannot currently reach SyncComplete-grant with a future `backoff_until` (a sync-denial clears pending_recheck via .take(), and re-arming pending_recheck requires a card outside the backoff window), so this is not a fix for an observable bug — it's hygiene against future refactors weakening that invariant. Strengthens grant_after_sync_resets_failed_attempts to also assert backoff_until == 0 after the sync-grant.
1 parent 6512707 commit 65fd810

2 files changed

Lines changed: 11 additions & 5 deletions

File tree

access-controller/src/core.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,16 @@ impl AccessCore {
152152
let allowed =
153153
fobs.iter().any(|&f| f == fob) || fobs.iter().any(|&f| f == nfc);
154154
if allowed {
155-
// Mirror main.rs:336-340 — failed_attempts is reset
156-
// to 0 here, but `backoff_until` is intentionally
157-
// *not* cleared. A grant after sync therefore still
158-
// honors any outstanding backoff window for future
159-
// card reads. Tests pin this behavior.
155+
// Defensively clear both failed_attempts and
156+
// backoff_until on a grant-after-sync. The state
157+
// machine currently can't reach SyncComplete-grant
158+
// with a future backoff_until (a sync-denial clears
159+
// pending_recheck, and a card outside backoff is
160+
// required to re-arm it), but keeping the two
161+
// counters in lockstep avoids surprises if that
162+
// invariant ever weakens.
160163
self.failed_attempts = 0;
164+
self.backoff_until = 0;
161165
let _ = out.push(Effect::Feedback(Outcome::Granted));
162166
let _ = out.push(Effect::OpenDoor);
163167
} else {

access-controller/tests/access_core.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,8 @@ fn grant_after_sync_resets_failed_attempts() {
268268
let eff = s.sync();
269269
assert!(contains_open_door(&eff));
270270
assert_eq!(s.core.failed_attempts(), 0);
271+
assert_eq!(s.core.backoff_until(), 0,
272+
"grant-after-sync must clear backoff_until alongside failed_attempts");
271273
}
272274

273275
// ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)