FA-75101 / CRDT convergence / Open access
Epoch-resettable counter: a newer epoch is merged into pre-reset slots · case 01
Increments made before a reset reappear after the reset propagates.
ROOT CAUSE
On receiving a newer epoch the receiver keeps its old slots and merges the new ones in by maximum.
VERIFIED REPAIR
When the incoming epoch is newer, replace the local slots with the incoming slots and adopt the epoch.
Unsuccessful approach: Copying the slots without adopting the epoch lets a later merge from the old epoch overwrite them again.
Case contract
Each replica holds an epoch and grow-only slots for that epoch. ["inc", r, k] grows r's slot; ["reset", r] increments r's epoch and clears all its slots. ["sync", s, d]: if s's epoch is higher, d adopts s's epoch and a copy of s's slots; if equal, slots merge by maximum; if lower, nothing changes. Return values (sum of slots) and epochs.
Why this case matters
Reset-wins counters need an epoch so a reset is not undone by increments that were concurrent with it.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events, replicas):
E = {r: 0 for r in replicas}
S = {r: {} for r in replicas}
for ev in events:
if ev[0] == 'inc':
r = ev[1]
S[r][r] = S[r].get(r, 0) + ev[2]
elif ev[0] == 'reset':
r = ev[1]
E[r] += 1
S[r] = {}
else:
s, d = ev[1], ev[2]
if E[s] > E[d]:
E[d] = E[s]
if E[s] >= E[d]:
for k, v in S[s].items():
S[d][k] = max(S[d].get(k, 0), v)
return {'values': [sum(S[r].values()) for r in replicas], 'epochs': [E[r] for r in replicas]}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
1: [('reset wins over concurrent older increments', [[['inc', 'a', 1], ['sync', 'a', 'b'], ['inc', 'b', 2], ['reset', 'a'], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [0, 0, 0], 'epochs': [1, 1, 0]}), ('stale epoch is ignored', [[['reset', 'a'], ['inc', 'a', 3], ['inc', 'b', 6], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 6, 0], 'epochs': [1, 0, 0]}), ('equal epochs merge by maximum', [[['reset', 'a'], ['sync', 'a', 'b'], ['inc', 'a', 1], ['inc', 'b', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 3, 0], 'epochs': [1, 1, 0]}), ('second reset opens a new epoch', [[['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 1], ['reset', 'c'], ['inc', 'c', 1], ['sync', 'c', 'a']], ['a', 'b', 'c']], {'values': [1, 0, 1], 'epochs': [2, 0, 2]}), ('reset clears every slot', [[['inc', 'a', 1], ['inc', 'b', 3], ['sync', 'b', 'a'], ['reset', 'a'], ['inc', 'a', 1]], ['a', 'b', 'c']], {'values': [1, 3, 0], 'epochs': [1, 0, 0]}), ('independent resets reach the same epoch', [[['inc', 'a', 1], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 3, 0], 'epochs': [1, 1, 0]}), ('epoch adoption copies the newer slots', [[['inc', 'b', 1], ['reset', 'a'], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'c']], ['a', 'b', 'c']], {'values': [2, 2, 2], 'epochs': [1, 1, 1]}), ('epoch is local knowledge', [[['reset', 'a'], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1]], ['a', 'b', 'c']], {'values': [0, 1, 0], 'epochs': [2, 1, 0]})],
2: [('reset wins over concurrent older increments', [[['inc', 'a', 2], ['sync', 'a', 'b'], ['inc', 'b', 2], ['reset', 'a'], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [0, 0, 0], 'epochs': [1, 1, 0]}), ('stale epoch is ignored', [[['reset', 'a'], ['inc', 'a', 3], ['inc', 'b', 7], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 7, 0], 'epochs': [1, 0, 0]}), ('equal epochs merge by maximum', [[['reset', 'a'], ['sync', 'a', 'b'], ['inc', 'a', 2], ['inc', 'b', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [4, 4, 0], 'epochs': [1, 1, 0]}), ('second reset opens a new epoch', [[['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 2], ['reset', 'c'], ['inc', 'c', 1], ['sync', 'c', 'a']], ['a', 'b', 'c']], {'values': [1, 0, 1], 'epochs': [2, 0, 2]}), ('reset clears every slot', [[['inc', 'a', 2], ['inc', 'b', 3], ['sync', 'b', 'a'], ['reset', 'a'], ['inc', 'a', 1]], ['a', 'b', 'c']], {'values': [1, 3, 0], 'epochs': [1, 0, 0]}), ('independent resets reach the same epoch', [[['inc', 'a', 1], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 2], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [4, 4, 0], 'epochs': [1, 1, 0]}), ('epoch adoption copies the newer slots', [[['inc', 'b', 2], ['reset', 'a'], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'c']], ['a', 'b', 'c']], {'values': [2, 2, 2], 'epochs': [1, 1, 1]}), ('epoch is local knowledge', [[['reset', 'a'], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1]], ['a', 'b', 'c']], {'values': [0, 1, 0], 'epochs': [2, 1, 0]})],
3: [('reset wins over concurrent older increments', [[['inc', 'a', 3], ['sync', 'a', 'b'], ['inc', 'b', 2], ['reset', 'a'], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [0, 0, 0], 'epochs': [1, 1, 0]}), ('stale epoch is ignored', [[['reset', 'a'], ['inc', 'a', 3], ['inc', 'b', 8], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 8, 0], 'epochs': [1, 0, 0]}), ('equal epochs merge by maximum', [[['reset', 'a'], ['sync', 'a', 'b'], ['inc', 'a', 3], ['inc', 'b', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [5, 5, 0], 'epochs': [1, 1, 0]}), ('second reset opens a new epoch', [[['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 3], ['reset', 'c'], ['inc', 'c', 1], ['sync', 'c', 'a']], ['a', 'b', 'c']], {'values': [1, 0, 1], 'epochs': [2, 0, 2]}), ('reset clears every slot', [[['inc', 'a', 3], ['inc', 'b', 3], ['sync', 'b', 'a'], ['reset', 'a'], ['inc', 'a', 1]], ['a', 'b', 'c']], {'values': [1, 3, 0], 'epochs': [1, 0, 0]}), ('independent resets reach the same epoch', [[['inc', 'a', 1], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 3], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [5, 5, 0], 'epochs': [1, 1, 0]}), ('epoch adoption copies the newer slots', [[['inc', 'b', 3], ['reset', 'a'], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'c']], ['a', 'b', 'c']], {'values': [2, 2, 2], 'epochs': [1, 1, 1]}), ('epoch is local knowledge', [[['reset', 'a'], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1]], ['a', 'b', 'c']], {'values': [0, 1, 0], 'epochs': [2, 1, 0]})],
4: [('reset wins over concurrent older increments', [[['inc', 'a', 4], ['sync', 'a', 'b'], ['inc', 'b', 2], ['reset', 'a'], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [0, 0, 0], 'epochs': [1, 1, 0]}), ('stale epoch is ignored', [[['reset', 'a'], ['inc', 'a', 3], ['inc', 'b', 9], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 9, 0], 'epochs': [1, 0, 0]}), ('equal epochs merge by maximum', [[['reset', 'a'], ['sync', 'a', 'b'], ['inc', 'a', 4], ['inc', 'b', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [6, 6, 0], 'epochs': [1, 1, 0]}), ('second reset opens a new epoch', [[['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 1], ['sync', 'c', 'a']], ['a', 'b', 'c']], {'values': [1, 0, 1], 'epochs': [2, 0, 2]}), ('reset clears every slot', [[['inc', 'a', 4], ['inc', 'b', 3], ['sync', 'b', 'a'], ['reset', 'a'], ['inc', 'a', 1]], ['a', 'b', 'c']], {'values': [1, 3, 0], 'epochs': [1, 0, 0]}), ('independent resets reach the same epoch', [[['inc', 'a', 1], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 4], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [6, 6, 0], 'epochs': [1, 1, 0]}), ('epoch adoption copies the newer slots', [[['inc', 'b', 4], ['reset', 'a'], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'c']], ['a', 'b', 'c']], {'values': [2, 2, 2], 'epochs': [1, 1, 1]}), ('epoch is local knowledge', [[['reset', 'a'], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1]], ['a', 'b', 'c']], {'values': [0, 1, 0], 'epochs': [2, 1, 0]})],
5: [('reset wins over concurrent older increments', [[['inc', 'a', 5], ['sync', 'a', 'b'], ['inc', 'b', 2], ['reset', 'a'], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [0, 0, 0], 'epochs': [1, 1, 0]}), ('stale epoch is ignored', [[['reset', 'a'], ['inc', 'a', 3], ['inc', 'b', 10], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 10, 0], 'epochs': [1, 0, 0]}), ('equal epochs merge by maximum', [[['reset', 'a'], ['sync', 'a', 'b'], ['inc', 'a', 5], ['inc', 'b', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [7, 7, 0], 'epochs': [1, 1, 0]}), ('second reset opens a new epoch', [[['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 5], ['reset', 'c'], ['inc', 'c', 1], ['sync', 'c', 'a']], ['a', 'b', 'c']], {'values': [1, 0, 1], 'epochs': [2, 0, 2]}), ('reset clears every slot', [[['inc', 'a', 5], ['inc', 'b', 3], ['sync', 'b', 'a'], ['reset', 'a'], ['inc', 'a', 1]], ['a', 'b', 'c']], {'values': [1, 3, 0], 'epochs': [1, 0, 0]}), ('independent resets reach the same epoch', [[['inc', 'a', 1], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 5], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [7, 7, 0], 'epochs': [1, 1, 0]}), ('epoch adoption copies the newer slots', [[['inc', 'b', 5], ['reset', 'a'], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'c']], ['a', 'b', 'c']], {'values': [2, 2, 2], 'epochs': [1, 1, 1]}), ('epoch is local knowledge', [[['reset', 'a'], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1]], ['a', 'b', 'c']], {'values': [0, 1, 0], 'epochs': [2, 1, 0]})],
}[N]
for label, args, expected in cases:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| reset wins over concurrent older increments | {'epochs': [1, 1, 0], 'values': [3, 3, 0]} | {'epochs': [1, 1, 0], 'values': [0, 0, 0]} | Failed |
| stale epoch is ignored | {'epochs': [1, 0, 0], 'values': [3, 6, 0]} | {'epochs': [1, 0, 0], 'values': [3, 6, 0]} | Passed |
| equal epochs merge by maximum | {'epochs': [1, 1, 0], 'values': [3, 3, 0]} | {'epochs': [1, 1, 0], 'values': [3, 3, 0]} | Passed |
| second reset opens a new epoch | {'epochs': [2, 0, 2], 'values': [1, 0, 1]} | {'epochs': [2, 0, 2], 'values': [1, 0, 1]} | Passed |
| reset clears every slot | {'epochs': [1, 0, 0], 'values': [1, 3, 0]} | {'epochs': [1, 0, 0], 'values': [1, 3, 0]} | Passed |
| independent resets reach the same epoch | {'epochs': [1, 1, 0], 'values': [3, 3, 0]} | {'epochs': [1, 1, 0], 'values': [3, 3, 0]} | Passed |
| epoch adoption copies the newer slots | {'epochs': [1, 1, 1], 'values': [2, 3, 3]} | {'epochs': [1, 1, 1], 'values': [2, 2, 2]} | Failed |
| epoch is local knowledge | {'epochs': [2, 1, 0], 'values': [0, 1, 0]} | {'epochs': [2, 1, 0], 'values': [0, 1, 0]} | Passed |
SHA-256 / e00262c9cd987440c40e64a4dcc5ada7ebc1aea6aa9e03121c658d481897581d
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events, replicas):
E = {r: 0 for r in replicas}
S = {r: {} for r in replicas}
for ev in events:
if ev[0] == 'inc':
r = ev[1]
S[r][r] = S[r].get(r, 0) + ev[2]
elif ev[0] == 'reset':
r = ev[1]
E[r] += 1
S[r] = {}
else:
s, d = ev[1], ev[2]
if E[s] > E[d]:
S[d] = dict(S[s])
elif E[s] == E[d]:
for k, v in S[s].items():
S[d][k] = max(S[d].get(k, 0), v)
return {'values': [sum(S[r].values()) for r in replicas], 'epochs': [E[r] for r in replicas]}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
1: [('reset wins over concurrent older increments', [[['inc', 'a', 1], ['sync', 'a', 'b'], ['inc', 'b', 2], ['reset', 'a'], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [0, 0, 0], 'epochs': [1, 1, 0]}), ('stale epoch is ignored', [[['reset', 'a'], ['inc', 'a', 3], ['inc', 'b', 6], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 6, 0], 'epochs': [1, 0, 0]}), ('equal epochs merge by maximum', [[['reset', 'a'], ['sync', 'a', 'b'], ['inc', 'a', 1], ['inc', 'b', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 3, 0], 'epochs': [1, 1, 0]}), ('second reset opens a new epoch', [[['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 1], ['reset', 'c'], ['inc', 'c', 1], ['sync', 'c', 'a']], ['a', 'b', 'c']], {'values': [1, 0, 1], 'epochs': [2, 0, 2]}), ('reset clears every slot', [[['inc', 'a', 1], ['inc', 'b', 3], ['sync', 'b', 'a'], ['reset', 'a'], ['inc', 'a', 1]], ['a', 'b', 'c']], {'values': [1, 3, 0], 'epochs': [1, 0, 0]}), ('independent resets reach the same epoch', [[['inc', 'a', 1], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 3, 0], 'epochs': [1, 1, 0]}), ('epoch adoption copies the newer slots', [[['inc', 'b', 1], ['reset', 'a'], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'c']], ['a', 'b', 'c']], {'values': [2, 2, 2], 'epochs': [1, 1, 1]}), ('epoch is local knowledge', [[['reset', 'a'], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1]], ['a', 'b', 'c']], {'values': [0, 1, 0], 'epochs': [2, 1, 0]})],
2: [('reset wins over concurrent older increments', [[['inc', 'a', 2], ['sync', 'a', 'b'], ['inc', 'b', 2], ['reset', 'a'], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [0, 0, 0], 'epochs': [1, 1, 0]}), ('stale epoch is ignored', [[['reset', 'a'], ['inc', 'a', 3], ['inc', 'b', 7], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 7, 0], 'epochs': [1, 0, 0]}), ('equal epochs merge by maximum', [[['reset', 'a'], ['sync', 'a', 'b'], ['inc', 'a', 2], ['inc', 'b', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [4, 4, 0], 'epochs': [1, 1, 0]}), ('second reset opens a new epoch', [[['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 2], ['reset', 'c'], ['inc', 'c', 1], ['sync', 'c', 'a']], ['a', 'b', 'c']], {'values': [1, 0, 1], 'epochs': [2, 0, 2]}), ('reset clears every slot', [[['inc', 'a', 2], ['inc', 'b', 3], ['sync', 'b', 'a'], ['reset', 'a'], ['inc', 'a', 1]], ['a', 'b', 'c']], {'values': [1, 3, 0], 'epochs': [1, 0, 0]}), ('independent resets reach the same epoch', [[['inc', 'a', 1], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 2], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [4, 4, 0], 'epochs': [1, 1, 0]}), ('epoch adoption copies the newer slots', [[['inc', 'b', 2], ['reset', 'a'], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'c']], ['a', 'b', 'c']], {'values': [2, 2, 2], 'epochs': [1, 1, 1]}), ('epoch is local knowledge', [[['reset', 'a'], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1]], ['a', 'b', 'c']], {'values': [0, 1, 0], 'epochs': [2, 1, 0]})],
3: [('reset wins over concurrent older increments', [[['inc', 'a', 3], ['sync', 'a', 'b'], ['inc', 'b', 2], ['reset', 'a'], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [0, 0, 0], 'epochs': [1, 1, 0]}), ('stale epoch is ignored', [[['reset', 'a'], ['inc', 'a', 3], ['inc', 'b', 8], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 8, 0], 'epochs': [1, 0, 0]}), ('equal epochs merge by maximum', [[['reset', 'a'], ['sync', 'a', 'b'], ['inc', 'a', 3], ['inc', 'b', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [5, 5, 0], 'epochs': [1, 1, 0]}), ('second reset opens a new epoch', [[['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 3], ['reset', 'c'], ['inc', 'c', 1], ['sync', 'c', 'a']], ['a', 'b', 'c']], {'values': [1, 0, 1], 'epochs': [2, 0, 2]}), ('reset clears every slot', [[['inc', 'a', 3], ['inc', 'b', 3], ['sync', 'b', 'a'], ['reset', 'a'], ['inc', 'a', 1]], ['a', 'b', 'c']], {'values': [1, 3, 0], 'epochs': [1, 0, 0]}), ('independent resets reach the same epoch', [[['inc', 'a', 1], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 3], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [5, 5, 0], 'epochs': [1, 1, 0]}), ('epoch adoption copies the newer slots', [[['inc', 'b', 3], ['reset', 'a'], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'c']], ['a', 'b', 'c']], {'values': [2, 2, 2], 'epochs': [1, 1, 1]}), ('epoch is local knowledge', [[['reset', 'a'], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1]], ['a', 'b', 'c']], {'values': [0, 1, 0], 'epochs': [2, 1, 0]})],
4: [('reset wins over concurrent older increments', [[['inc', 'a', 4], ['sync', 'a', 'b'], ['inc', 'b', 2], ['reset', 'a'], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [0, 0, 0], 'epochs': [1, 1, 0]}), ('stale epoch is ignored', [[['reset', 'a'], ['inc', 'a', 3], ['inc', 'b', 9], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 9, 0], 'epochs': [1, 0, 0]}), ('equal epochs merge by maximum', [[['reset', 'a'], ['sync', 'a', 'b'], ['inc', 'a', 4], ['inc', 'b', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [6, 6, 0], 'epochs': [1, 1, 0]}), ('second reset opens a new epoch', [[['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 1], ['sync', 'c', 'a']], ['a', 'b', 'c']], {'values': [1, 0, 1], 'epochs': [2, 0, 2]}), ('reset clears every slot', [[['inc', 'a', 4], ['inc', 'b', 3], ['sync', 'b', 'a'], ['reset', 'a'], ['inc', 'a', 1]], ['a', 'b', 'c']], {'values': [1, 3, 0], 'epochs': [1, 0, 0]}), ('independent resets reach the same epoch', [[['inc', 'a', 1], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 4], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [6, 6, 0], 'epochs': [1, 1, 0]}), ('epoch adoption copies the newer slots', [[['inc', 'b', 4], ['reset', 'a'], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'c']], ['a', 'b', 'c']], {'values': [2, 2, 2], 'epochs': [1, 1, 1]}), ('epoch is local knowledge', [[['reset', 'a'], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1]], ['a', 'b', 'c']], {'values': [0, 1, 0], 'epochs': [2, 1, 0]})],
5: [('reset wins over concurrent older increments', [[['inc', 'a', 5], ['sync', 'a', 'b'], ['inc', 'b', 2], ['reset', 'a'], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [0, 0, 0], 'epochs': [1, 1, 0]}), ('stale epoch is ignored', [[['reset', 'a'], ['inc', 'a', 3], ['inc', 'b', 10], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 10, 0], 'epochs': [1, 0, 0]}), ('equal epochs merge by maximum', [[['reset', 'a'], ['sync', 'a', 'b'], ['inc', 'a', 5], ['inc', 'b', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [7, 7, 0], 'epochs': [1, 1, 0]}), ('second reset opens a new epoch', [[['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 5], ['reset', 'c'], ['inc', 'c', 1], ['sync', 'c', 'a']], ['a', 'b', 'c']], {'values': [1, 0, 1], 'epochs': [2, 0, 2]}), ('reset clears every slot', [[['inc', 'a', 5], ['inc', 'b', 3], ['sync', 'b', 'a'], ['reset', 'a'], ['inc', 'a', 1]], ['a', 'b', 'c']], {'values': [1, 3, 0], 'epochs': [1, 0, 0]}), ('independent resets reach the same epoch', [[['inc', 'a', 1], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 5], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [7, 7, 0], 'epochs': [1, 1, 0]}), ('epoch adoption copies the newer slots', [[['inc', 'b', 5], ['reset', 'a'], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'c']], ['a', 'b', 'c']], {'values': [2, 2, 2], 'epochs': [1, 1, 1]}), ('epoch is local knowledge', [[['reset', 'a'], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1]], ['a', 'b', 'c']], {'values': [0, 1, 0], 'epochs': [2, 1, 0]})],
}[N]
for label, args, expected in cases:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| reset wins over concurrent older increments | {'epochs': [1, 0, 0], 'values': [0, 0, 0]} | {'epochs': [1, 1, 0], 'values': [0, 0, 0]} | Failed |
| stale epoch is ignored | {'epochs': [1, 0, 0], 'values': [3, 6, 0]} | {'epochs': [1, 0, 0], 'values': [3, 6, 0]} | Passed |
| equal epochs merge by maximum | {'epochs': [1, 0, 0], 'values': [1, 1, 0]} | {'epochs': [1, 1, 0], 'values': [3, 3, 0]} | Failed |
| second reset opens a new epoch | {'epochs': [0, 0, 2], 'values': [1, 0, 1]} | {'epochs': [2, 0, 2], 'values': [1, 0, 1]} | Failed |
| reset clears every slot | {'epochs': [1, 0, 0], 'values': [1, 3, 0]} | {'epochs': [1, 0, 0], 'values': [1, 3, 0]} | Passed |
| independent resets reach the same epoch | {'epochs': [1, 1, 0], 'values': [3, 3, 0]} | {'epochs': [1, 1, 0], 'values': [3, 3, 0]} | Passed |
| epoch adoption copies the newer slots | {'epochs': [1, 0, 0], 'values': [2, 2, 2]} | {'epochs': [1, 1, 1], 'values': [2, 2, 2]} | Failed |
| epoch is local knowledge | {'epochs': [2, 1, 0], 'values': [0, 1, 0]} | {'epochs': [2, 1, 0], 'values': [0, 1, 0]} | Passed |
SHA-256 / e68f72f0e98479892c5305bebc97de11c9d9b1a18f3940b8be2c13e6372661df
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events, replicas):
E = {r: 0 for r in replicas}
S = {r: {} for r in replicas}
for ev in events:
if ev[0] == 'inc':
r = ev[1]
S[r][r] = S[r].get(r, 0) + ev[2]
elif ev[0] == 'reset':
r = ev[1]
E[r] += 1
S[r] = {}
else:
s, d = ev[1], ev[2]
if E[s] > E[d]:
E[d] = E[s]
S[d] = dict(S[s])
elif E[s] == E[d]:
for k, v in S[s].items():
S[d][k] = max(S[d].get(k, 0), v)
return {'values': [sum(S[r].values()) for r in replicas], 'epochs': [E[r] for r in replicas]}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
1: [('reset wins over concurrent older increments', [[['inc', 'a', 1], ['sync', 'a', 'b'], ['inc', 'b', 2], ['reset', 'a'], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [0, 0, 0], 'epochs': [1, 1, 0]}), ('stale epoch is ignored', [[['reset', 'a'], ['inc', 'a', 3], ['inc', 'b', 6], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 6, 0], 'epochs': [1, 0, 0]}), ('equal epochs merge by maximum', [[['reset', 'a'], ['sync', 'a', 'b'], ['inc', 'a', 1], ['inc', 'b', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 3, 0], 'epochs': [1, 1, 0]}), ('second reset opens a new epoch', [[['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 1], ['reset', 'c'], ['inc', 'c', 1], ['sync', 'c', 'a']], ['a', 'b', 'c']], {'values': [1, 0, 1], 'epochs': [2, 0, 2]}), ('reset clears every slot', [[['inc', 'a', 1], ['inc', 'b', 3], ['sync', 'b', 'a'], ['reset', 'a'], ['inc', 'a', 1]], ['a', 'b', 'c']], {'values': [1, 3, 0], 'epochs': [1, 0, 0]}), ('independent resets reach the same epoch', [[['inc', 'a', 1], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 3, 0], 'epochs': [1, 1, 0]}), ('epoch adoption copies the newer slots', [[['inc', 'b', 1], ['reset', 'a'], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'c']], ['a', 'b', 'c']], {'values': [2, 2, 2], 'epochs': [1, 1, 1]}), ('epoch is local knowledge', [[['reset', 'a'], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1]], ['a', 'b', 'c']], {'values': [0, 1, 0], 'epochs': [2, 1, 0]})],
2: [('reset wins over concurrent older increments', [[['inc', 'a', 2], ['sync', 'a', 'b'], ['inc', 'b', 2], ['reset', 'a'], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [0, 0, 0], 'epochs': [1, 1, 0]}), ('stale epoch is ignored', [[['reset', 'a'], ['inc', 'a', 3], ['inc', 'b', 7], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 7, 0], 'epochs': [1, 0, 0]}), ('equal epochs merge by maximum', [[['reset', 'a'], ['sync', 'a', 'b'], ['inc', 'a', 2], ['inc', 'b', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [4, 4, 0], 'epochs': [1, 1, 0]}), ('second reset opens a new epoch', [[['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 2], ['reset', 'c'], ['inc', 'c', 1], ['sync', 'c', 'a']], ['a', 'b', 'c']], {'values': [1, 0, 1], 'epochs': [2, 0, 2]}), ('reset clears every slot', [[['inc', 'a', 2], ['inc', 'b', 3], ['sync', 'b', 'a'], ['reset', 'a'], ['inc', 'a', 1]], ['a', 'b', 'c']], {'values': [1, 3, 0], 'epochs': [1, 0, 0]}), ('independent resets reach the same epoch', [[['inc', 'a', 1], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 2], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [4, 4, 0], 'epochs': [1, 1, 0]}), ('epoch adoption copies the newer slots', [[['inc', 'b', 2], ['reset', 'a'], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'c']], ['a', 'b', 'c']], {'values': [2, 2, 2], 'epochs': [1, 1, 1]}), ('epoch is local knowledge', [[['reset', 'a'], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1]], ['a', 'b', 'c']], {'values': [0, 1, 0], 'epochs': [2, 1, 0]})],
3: [('reset wins over concurrent older increments', [[['inc', 'a', 3], ['sync', 'a', 'b'], ['inc', 'b', 2], ['reset', 'a'], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [0, 0, 0], 'epochs': [1, 1, 0]}), ('stale epoch is ignored', [[['reset', 'a'], ['inc', 'a', 3], ['inc', 'b', 8], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 8, 0], 'epochs': [1, 0, 0]}), ('equal epochs merge by maximum', [[['reset', 'a'], ['sync', 'a', 'b'], ['inc', 'a', 3], ['inc', 'b', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [5, 5, 0], 'epochs': [1, 1, 0]}), ('second reset opens a new epoch', [[['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 3], ['reset', 'c'], ['inc', 'c', 1], ['sync', 'c', 'a']], ['a', 'b', 'c']], {'values': [1, 0, 1], 'epochs': [2, 0, 2]}), ('reset clears every slot', [[['inc', 'a', 3], ['inc', 'b', 3], ['sync', 'b', 'a'], ['reset', 'a'], ['inc', 'a', 1]], ['a', 'b', 'c']], {'values': [1, 3, 0], 'epochs': [1, 0, 0]}), ('independent resets reach the same epoch', [[['inc', 'a', 1], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 3], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [5, 5, 0], 'epochs': [1, 1, 0]}), ('epoch adoption copies the newer slots', [[['inc', 'b', 3], ['reset', 'a'], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'c']], ['a', 'b', 'c']], {'values': [2, 2, 2], 'epochs': [1, 1, 1]}), ('epoch is local knowledge', [[['reset', 'a'], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1]], ['a', 'b', 'c']], {'values': [0, 1, 0], 'epochs': [2, 1, 0]})],
4: [('reset wins over concurrent older increments', [[['inc', 'a', 4], ['sync', 'a', 'b'], ['inc', 'b', 2], ['reset', 'a'], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [0, 0, 0], 'epochs': [1, 1, 0]}), ('stale epoch is ignored', [[['reset', 'a'], ['inc', 'a', 3], ['inc', 'b', 9], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 9, 0], 'epochs': [1, 0, 0]}), ('equal epochs merge by maximum', [[['reset', 'a'], ['sync', 'a', 'b'], ['inc', 'a', 4], ['inc', 'b', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [6, 6, 0], 'epochs': [1, 1, 0]}), ('second reset opens a new epoch', [[['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 1], ['sync', 'c', 'a']], ['a', 'b', 'c']], {'values': [1, 0, 1], 'epochs': [2, 0, 2]}), ('reset clears every slot', [[['inc', 'a', 4], ['inc', 'b', 3], ['sync', 'b', 'a'], ['reset', 'a'], ['inc', 'a', 1]], ['a', 'b', 'c']], {'values': [1, 3, 0], 'epochs': [1, 0, 0]}), ('independent resets reach the same epoch', [[['inc', 'a', 1], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 4], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [6, 6, 0], 'epochs': [1, 1, 0]}), ('epoch adoption copies the newer slots', [[['inc', 'b', 4], ['reset', 'a'], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'c']], ['a', 'b', 'c']], {'values': [2, 2, 2], 'epochs': [1, 1, 1]}), ('epoch is local knowledge', [[['reset', 'a'], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1]], ['a', 'b', 'c']], {'values': [0, 1, 0], 'epochs': [2, 1, 0]})],
5: [('reset wins over concurrent older increments', [[['inc', 'a', 5], ['sync', 'a', 'b'], ['inc', 'b', 2], ['reset', 'a'], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [0, 0, 0], 'epochs': [1, 1, 0]}), ('stale epoch is ignored', [[['reset', 'a'], ['inc', 'a', 3], ['inc', 'b', 10], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [3, 10, 0], 'epochs': [1, 0, 0]}), ('equal epochs merge by maximum', [[['reset', 'a'], ['sync', 'a', 'b'], ['inc', 'a', 5], ['inc', 'b', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [7, 7, 0], 'epochs': [1, 1, 0]}), ('second reset opens a new epoch', [[['inc', 'c', 4], ['reset', 'c'], ['inc', 'c', 5], ['reset', 'c'], ['inc', 'c', 1], ['sync', 'c', 'a']], ['a', 'b', 'c']], {'values': [1, 0, 1], 'epochs': [2, 0, 2]}), ('reset clears every slot', [[['inc', 'a', 5], ['inc', 'b', 3], ['sync', 'b', 'a'], ['reset', 'a'], ['inc', 'a', 1]], ['a', 'b', 'c']], {'values': [1, 3, 0], 'epochs': [1, 0, 0]}), ('independent resets reach the same epoch', [[['inc', 'a', 1], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 5], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'a']], ['a', 'b', 'c']], {'values': [7, 7, 0], 'epochs': [1, 1, 0]}), ('epoch adoption copies the newer slots', [[['inc', 'b', 5], ['reset', 'a'], ['inc', 'a', 2], ['sync', 'a', 'b'], ['sync', 'b', 'c']], ['a', 'b', 'c']], {'values': [2, 2, 2], 'epochs': [1, 1, 1]}), ('epoch is local knowledge', [[['reset', 'a'], ['reset', 'a'], ['reset', 'b'], ['inc', 'b', 1]], ['a', 'b', 'c']], {'values': [0, 1, 0], 'epochs': [2, 1, 0]})],
}[N]
for label, args, expected in cases:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| reset wins over concurrent older increments | {'epochs': [1, 1, 0], 'values': [0, 0, 0]} | {'epochs': [1, 1, 0], 'values': [0, 0, 0]} | Passed |
| stale epoch is ignored | {'epochs': [1, 0, 0], 'values': [3, 6, 0]} | {'epochs': [1, 0, 0], 'values': [3, 6, 0]} | Passed |
| equal epochs merge by maximum | {'epochs': [1, 1, 0], 'values': [3, 3, 0]} | {'epochs': [1, 1, 0], 'values': [3, 3, 0]} | Passed |
| second reset opens a new epoch | {'epochs': [2, 0, 2], 'values': [1, 0, 1]} | {'epochs': [2, 0, 2], 'values': [1, 0, 1]} | Passed |
| reset clears every slot | {'epochs': [1, 0, 0], 'values': [1, 3, 0]} | {'epochs': [1, 0, 0], 'values': [1, 3, 0]} | Passed |
| independent resets reach the same epoch | {'epochs': [1, 1, 0], 'values': [3, 3, 0]} | {'epochs': [1, 1, 0], 'values': [3, 3, 0]} | Passed |
| epoch adoption copies the newer slots | {'epochs': [1, 1, 1], 'values': [2, 2, 2]} | {'epochs': [1, 1, 1], 'values': [2, 2, 2]} | Passed |
| epoch is local knowledge | {'epochs': [2, 1, 0], 'values': [0, 1, 0]} | {'epochs': [2, 1, 0], 'values': [0, 1, 0]} | Passed |
SHA-256 / ecd333b789518dff63ea8e8295f64877fe9fe6bca5d85ccf5e8c517456034405
Verification & scope
A deterministic, bounded teaching model of one replicated data type with stipulated operation and merge rules; it is not a production CRDT library and makes no claim of conformance to any specific published design. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:49:03.006697+00:00.
Case digest / 02030ab74af9c4132b62b663b587a1c8f973b9d47a7143a1e275d7592fb2c710