fix(cassettes): break the same-second tie with the machine's counter
Some checks failed
ci.yml / fix(cassettes): break the same-second tie with the machine's counter (pull_request) Failing after 0s

The ordering gate compares created_at, which NIP-01 defines at one-second
granularity. A dispense and the publish that follows it land inside one
second routinely, so the report was dropped and the operator kept the
pre-dispense count until the next heartbeat five minutes later.

The machine bumps a counter on every local change to a bay count and
carries it in its state document. m015 stores it per row, and the gate
consults it only when the stamps are equal, where created_at carries no
information at all.

Only on equality, deliberately. A machine whose state.db was replaced
restarts its counter at zero while its wall clock keeps moving forward;
gating on the counter across different stamps would lock that machine out
for good. Equal stamps with no counter on either side stay closed, which
costs one heartbeat and risks nothing.
This commit is contained in:
Padreug 2026-09-23 12:58:04 +02:00
commit 5f60b3fe31
4 changed files with 89 additions and 14 deletions

View file

@ -208,3 +208,31 @@ class TestShouldApplyStateEvent:
"""Fail closed: an unparseable incoming stamp must not overwrite
state that is known-good."""
assert _should_apply_state_event(NOW, "nonsense") is False
def test_seq_breaks_a_same_second_tie(self):
"""NIP-01 stamps at one-second granularity, so a dispense and the
publish that follows it share a stamp routinely. Without the counter
the later report is dropped and the operator keeps the pre-dispense
count until the next heartbeat."""
assert _should_apply_state_event(NOW, NOW, 4, 5) is True
assert _should_apply_state_event(NOW, NOW, 5, 5) is False
assert _should_apply_state_event(NOW, NOW, 5, 4) is False
def test_seq_is_ignored_when_the_stamps_differ(self):
"""A machine whose state.db was replaced restarts its counter at zero
while its wall clock keeps moving forward. Gating on the counter
across different stamps would lock that machine out for good."""
assert (
_should_apply_state_event(NOW, NOW + timedelta(seconds=1), 900, 0) is True
)
assert (
_should_apply_state_event(NOW, NOW - timedelta(seconds=1), 0, 900) is False
)
def test_same_second_without_a_counter_stays_closed(self):
"""An older machine sends no seq at all. Equal stamps then carry no
evidence the report is newer, and fail-closed is the safe read: the
machine republishes on its heartbeat a second later."""
assert _should_apply_state_event(NOW, NOW, None, None) is False
assert _should_apply_state_event(NOW, NOW, None, 5) is False
assert _should_apply_state_event(NOW, NOW, 5, None) is False