FA-76121 / Chat ordering and read receipts / Open access
Aggregate emoji reactions with a per-user limit: limit boundary · case 01
A user can place one more distinct emoji than the configured limit.
ROOT CAUSE
The limit boundary decision evaluates `per_user.get(user, 0) > limit` where the contract requires `per_user.get(user, 0) >= limit`.
VERIFIED REPAIR
Use `per_user.get(user, 0) >= limit` for the limit boundary decision and keep every other rule of the model unchanged.
Unsuccessful approach: Special-casing a limit of one disables the limit entirely for single-reaction rooms. The attempted `per_user.get(user, 0) > limit - 1 if limit > 1 else False` still disagrees with a fixture.
Case contract
events [seq, user, emoji, action] are applied in seq order. A user holds each emoji at most once and at most `limit` distinct emoji per message; an add beyond the limit is ignored. A remove only releases a reaction the user holds. Result rows [emoji, count, mine] for emoji with at least one user, ordered by the seq at which the emoji most recently went from zero to one user.
Why this case matters
Reaction chips reorder and recount live; wrong state handling shows phantom or misordered reactions.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events, viewer, limit):
current = {}
first = {}
per_user = {}
for seq, user, emoji, action in sorted(events):
users = current.get(emoji, set())
if action == 'add':
if user in users or per_user.get(user, 0) > limit:
continue
if not users:
first[emoji] = seq
users.add(user)
current[emoji] = users
per_user[user] = per_user.get(user, 0) + 1
elif user in users:
users.discard(user)
per_user[user] = per_user.get(user, 0) - 1
rows = [[e, len(u), viewer in u] for e, u in current.items() if u]
rows.sort(key=lambda r: first[r[0]])
return rows
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('remove delivered before add', ([[3, 'bo', 'up', 'remove'], [2, 'bo', 'up', 'add']], 'me', 3), []), ('emoji vanishes and returns', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'bo', 'up', 'remove'], [5, 'di', 'up', 'add']], 'me', 3), [['ok', 1, False], ['up', 1, False]]), ('second user joins an emoji', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'di', 'up', 'add']], 'di', 3), [['up', 2, True], ['ok', 1, False]]), ('only reaction removed', ([[1, 'me', 'up', 'add'], [2, 'me', 'up', 'remove']], 'me', 2), []), ('limit reached', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'b', 'add'], [3, 'bo', 'c', 'add']], 'bo', 2), [['a', 1, True], ['b', 1, True]]), ('stray remove does not free a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'z', 'remove'], [3, 'bo', 'b', 'add']], 'me', 1), [['a', 1, False]]), ('removal frees a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'a', 'remove'], [3, 'bo', 'b', 'add']], 'bo', 1), [['b', 1, True]])], 2: [('remove delivered before add', ([[4, 'bo', 'up', 'remove'], [3, 'bo', 'up', 'add']], 'me', 3), []), ('emoji vanishes and returns', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'bo', 'up', 'remove'], [6, 'di', 'up', 'add']], 'me', 3), [['ok', 1, False], ['up', 1, False]]), ('second user joins an emoji', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'di', 'up', 'add']], 'di', 3), [['up', 2, True], ['ok', 1, False]]), ('only reaction removed', ([[1, 'me', 'up', 'add'], [2, 'me', 'up', 'remove']], 'me', 2), []), ('limit reached', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'b', 'add'], [3, 'bo', 'c', 'add']], 'bo', 2), [['a', 1, True], ['b', 1, True]]), ('stray remove does not free a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'z', 'remove'], [3, 'bo', 'b', 'add']], 'me', 1), [['a', 1, False]]), ('removal frees a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'a', 'remove'], [3, 'bo', 'b', 'add']], 'bo', 1), [['b', 1, True]])], 3: [('remove delivered before add', ([[5, 'bo', 'up', 'remove'], [4, 'bo', 'up', 'add']], 'me', 3), []), ('emoji vanishes and returns', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'bo', 'up', 'remove'], [7, 'di', 'up', 'add']], 'me', 3), [['ok', 1, False], ['up', 1, False]]), ('second user joins an emoji', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'di', 'up', 'add']], 'di', 3), [['up', 2, True], ['ok', 1, False]]), ('only reaction removed', ([[1, 'me', 'up', 'add'], [2, 'me', 'up', 'remove']], 'me', 2), []), ('limit reached', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'b', 'add'], [3, 'bo', 'c', 'add']], 'bo', 2), [['a', 1, True], ['b', 1, True]]), ('stray remove does not free a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'z', 'remove'], [3, 'bo', 'b', 'add']], 'me', 1), [['a', 1, False]]), ('removal frees a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'a', 'remove'], [3, 'bo', 'b', 'add']], 'bo', 1), [['b', 1, True]])], 4: [('remove delivered before add', ([[6, 'bo', 'up', 'remove'], [5, 'bo', 'up', 'add']], 'me', 3), []), ('emoji vanishes and returns', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'bo', 'up', 'remove'], [8, 'di', 'up', 'add']], 'me', 3), [['ok', 1, False], ['up', 1, False]]), ('second user joins an emoji', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'di', 'up', 'add']], 'di', 3), [['up', 2, True], ['ok', 1, False]]), ('only reaction removed', ([[1, 'me', 'up', 'add'], [2, 'me', 'up', 'remove']], 'me', 2), []), ('limit reached', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'b', 'add'], [3, 'bo', 'c', 'add']], 'bo', 2), [['a', 1, True], ['b', 1, True]]), ('stray remove does not free a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'z', 'remove'], [3, 'bo', 'b', 'add']], 'me', 1), [['a', 1, False]]), ('removal frees a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'a', 'remove'], [3, 'bo', 'b', 'add']], 'bo', 1), [['b', 1, True]])], 5: [('remove delivered before add', ([[7, 'bo', 'up', 'remove'], [6, 'bo', 'up', 'add']], 'me', 3), []), ('emoji vanishes and returns', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'bo', 'up', 'remove'], [9, 'di', 'up', 'add']], 'me', 3), [['ok', 1, False], ['up', 1, False]]), ('second user joins an emoji', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'di', 'up', 'add']], 'di', 3), [['up', 2, True], ['ok', 1, False]]), ('only reaction removed', ([[1, 'me', 'up', 'add'], [2, 'me', 'up', 'remove']], 'me', 2), []), ('limit reached', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'b', 'add'], [3, 'bo', 'c', 'add']], 'bo', 2), [['a', 1, True], ['b', 1, True]]), ('stray remove does not free a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'z', 'remove'], [3, 'bo', 'b', 'add']], 'me', 1), [['a', 1, False]]), ('removal frees a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'a', 'remove'], [3, 'bo', 'b', 'add']], 'bo', 1), [['b', 1, True]])]}
for _label, _args, _expected in _CASES[N]:
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 |
|---|---|---|---|
| remove delivered before add | [] | [] | Passed |
| emoji vanishes and returns | [['ok', 1, False], ['up', 1, False]] | [['ok', 1, False], ['up', 1, False]] | Passed |
| second user joins an emoji | [['up', 2, True], ['ok', 1, False]] | [['up', 2, True], ['ok', 1, False]] | Passed |
| only reaction removed | [] | [] | Passed |
| limit reached | [['a', 1, True], ['b', 1, True], ['c', 1, True]] | [['a', 1, True], ['b', 1, True]] | Failed |
| stray remove does not free a slot | [['a', 1, False], ['b', 1, False]] | [['a', 1, False]] | Failed |
| removal frees a slot | [['b', 1, True]] | [['b', 1, True]] | Passed |
SHA-256 / c85a3c4c2defd4e920ec64bd5680393adbcc1c48ae1fb2a2eb54670760454a5f
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events, viewer, limit):
current = {}
first = {}
per_user = {}
for seq, user, emoji, action in sorted(events):
users = current.get(emoji, set())
if action == 'add':
if user in users or per_user.get(user, 0) > limit - 1 if limit > 1 else False:
continue
if not users:
first[emoji] = seq
users.add(user)
current[emoji] = users
per_user[user] = per_user.get(user, 0) + 1
elif user in users:
users.discard(user)
per_user[user] = per_user.get(user, 0) - 1
rows = [[e, len(u), viewer in u] for e, u in current.items() if u]
rows.sort(key=lambda r: first[r[0]])
return rows
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('remove delivered before add', ([[3, 'bo', 'up', 'remove'], [2, 'bo', 'up', 'add']], 'me', 3), []), ('emoji vanishes and returns', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'bo', 'up', 'remove'], [5, 'di', 'up', 'add']], 'me', 3), [['ok', 1, False], ['up', 1, False]]), ('second user joins an emoji', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'di', 'up', 'add']], 'di', 3), [['up', 2, True], ['ok', 1, False]]), ('only reaction removed', ([[1, 'me', 'up', 'add'], [2, 'me', 'up', 'remove']], 'me', 2), []), ('limit reached', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'b', 'add'], [3, 'bo', 'c', 'add']], 'bo', 2), [['a', 1, True], ['b', 1, True]]), ('stray remove does not free a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'z', 'remove'], [3, 'bo', 'b', 'add']], 'me', 1), [['a', 1, False]]), ('removal frees a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'a', 'remove'], [3, 'bo', 'b', 'add']], 'bo', 1), [['b', 1, True]])], 2: [('remove delivered before add', ([[4, 'bo', 'up', 'remove'], [3, 'bo', 'up', 'add']], 'me', 3), []), ('emoji vanishes and returns', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'bo', 'up', 'remove'], [6, 'di', 'up', 'add']], 'me', 3), [['ok', 1, False], ['up', 1, False]]), ('second user joins an emoji', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'di', 'up', 'add']], 'di', 3), [['up', 2, True], ['ok', 1, False]]), ('only reaction removed', ([[1, 'me', 'up', 'add'], [2, 'me', 'up', 'remove']], 'me', 2), []), ('limit reached', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'b', 'add'], [3, 'bo', 'c', 'add']], 'bo', 2), [['a', 1, True], ['b', 1, True]]), ('stray remove does not free a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'z', 'remove'], [3, 'bo', 'b', 'add']], 'me', 1), [['a', 1, False]]), ('removal frees a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'a', 'remove'], [3, 'bo', 'b', 'add']], 'bo', 1), [['b', 1, True]])], 3: [('remove delivered before add', ([[5, 'bo', 'up', 'remove'], [4, 'bo', 'up', 'add']], 'me', 3), []), ('emoji vanishes and returns', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'bo', 'up', 'remove'], [7, 'di', 'up', 'add']], 'me', 3), [['ok', 1, False], ['up', 1, False]]), ('second user joins an emoji', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'di', 'up', 'add']], 'di', 3), [['up', 2, True], ['ok', 1, False]]), ('only reaction removed', ([[1, 'me', 'up', 'add'], [2, 'me', 'up', 'remove']], 'me', 2), []), ('limit reached', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'b', 'add'], [3, 'bo', 'c', 'add']], 'bo', 2), [['a', 1, True], ['b', 1, True]]), ('stray remove does not free a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'z', 'remove'], [3, 'bo', 'b', 'add']], 'me', 1), [['a', 1, False]]), ('removal frees a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'a', 'remove'], [3, 'bo', 'b', 'add']], 'bo', 1), [['b', 1, True]])], 4: [('remove delivered before add', ([[6, 'bo', 'up', 'remove'], [5, 'bo', 'up', 'add']], 'me', 3), []), ('emoji vanishes and returns', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'bo', 'up', 'remove'], [8, 'di', 'up', 'add']], 'me', 3), [['ok', 1, False], ['up', 1, False]]), ('second user joins an emoji', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'di', 'up', 'add']], 'di', 3), [['up', 2, True], ['ok', 1, False]]), ('only reaction removed', ([[1, 'me', 'up', 'add'], [2, 'me', 'up', 'remove']], 'me', 2), []), ('limit reached', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'b', 'add'], [3, 'bo', 'c', 'add']], 'bo', 2), [['a', 1, True], ['b', 1, True]]), ('stray remove does not free a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'z', 'remove'], [3, 'bo', 'b', 'add']], 'me', 1), [['a', 1, False]]), ('removal frees a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'a', 'remove'], [3, 'bo', 'b', 'add']], 'bo', 1), [['b', 1, True]])], 5: [('remove delivered before add', ([[7, 'bo', 'up', 'remove'], [6, 'bo', 'up', 'add']], 'me', 3), []), ('emoji vanishes and returns', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'bo', 'up', 'remove'], [9, 'di', 'up', 'add']], 'me', 3), [['ok', 1, False], ['up', 1, False]]), ('second user joins an emoji', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'di', 'up', 'add']], 'di', 3), [['up', 2, True], ['ok', 1, False]]), ('only reaction removed', ([[1, 'me', 'up', 'add'], [2, 'me', 'up', 'remove']], 'me', 2), []), ('limit reached', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'b', 'add'], [3, 'bo', 'c', 'add']], 'bo', 2), [['a', 1, True], ['b', 1, True]]), ('stray remove does not free a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'z', 'remove'], [3, 'bo', 'b', 'add']], 'me', 1), [['a', 1, False]]), ('removal frees a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'a', 'remove'], [3, 'bo', 'b', 'add']], 'bo', 1), [['b', 1, True]])]}
for _label, _args, _expected in _CASES[N]:
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 |
|---|---|---|---|
| remove delivered before add | [] | [] | Passed |
| emoji vanishes and returns | [['ok', 1, False], ['up', 1, False]] | [['ok', 1, False], ['up', 1, False]] | Passed |
| second user joins an emoji | [['up', 2, True], ['ok', 1, False]] | [['up', 2, True], ['ok', 1, False]] | Passed |
| only reaction removed | [] | [] | Passed |
| limit reached | [['a', 1, True], ['b', 1, True]] | [['a', 1, True], ['b', 1, True]] | Passed |
| stray remove does not free a slot | [['a', 1, False], ['b', 1, False]] | [['a', 1, False]] | Failed |
| removal frees a slot | [['b', 1, True]] | [['b', 1, True]] | Passed |
SHA-256 / 318e3ba984d74272a9a45bf07b8544462e2b6979ecb72b57bb5e09a0397afd33
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events, viewer, limit):
current = {}
first = {}
per_user = {}
for seq, user, emoji, action in sorted(events):
users = current.get(emoji, set())
if action == 'add':
if user in users or per_user.get(user, 0) >= limit:
continue
if not users:
first[emoji] = seq
users.add(user)
current[emoji] = users
per_user[user] = per_user.get(user, 0) + 1
elif user in users:
users.discard(user)
per_user[user] = per_user.get(user, 0) - 1
rows = [[e, len(u), viewer in u] for e, u in current.items() if u]
rows.sort(key=lambda r: first[r[0]])
return rows
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('remove delivered before add', ([[3, 'bo', 'up', 'remove'], [2, 'bo', 'up', 'add']], 'me', 3), []), ('emoji vanishes and returns', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'bo', 'up', 'remove'], [5, 'di', 'up', 'add']], 'me', 3), [['ok', 1, False], ['up', 1, False]]), ('second user joins an emoji', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'di', 'up', 'add']], 'di', 3), [['up', 2, True], ['ok', 1, False]]), ('only reaction removed', ([[1, 'me', 'up', 'add'], [2, 'me', 'up', 'remove']], 'me', 2), []), ('limit reached', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'b', 'add'], [3, 'bo', 'c', 'add']], 'bo', 2), [['a', 1, True], ['b', 1, True]]), ('stray remove does not free a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'z', 'remove'], [3, 'bo', 'b', 'add']], 'me', 1), [['a', 1, False]]), ('removal frees a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'a', 'remove'], [3, 'bo', 'b', 'add']], 'bo', 1), [['b', 1, True]])], 2: [('remove delivered before add', ([[4, 'bo', 'up', 'remove'], [3, 'bo', 'up', 'add']], 'me', 3), []), ('emoji vanishes and returns', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'bo', 'up', 'remove'], [6, 'di', 'up', 'add']], 'me', 3), [['ok', 1, False], ['up', 1, False]]), ('second user joins an emoji', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'di', 'up', 'add']], 'di', 3), [['up', 2, True], ['ok', 1, False]]), ('only reaction removed', ([[1, 'me', 'up', 'add'], [2, 'me', 'up', 'remove']], 'me', 2), []), ('limit reached', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'b', 'add'], [3, 'bo', 'c', 'add']], 'bo', 2), [['a', 1, True], ['b', 1, True]]), ('stray remove does not free a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'z', 'remove'], [3, 'bo', 'b', 'add']], 'me', 1), [['a', 1, False]]), ('removal frees a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'a', 'remove'], [3, 'bo', 'b', 'add']], 'bo', 1), [['b', 1, True]])], 3: [('remove delivered before add', ([[5, 'bo', 'up', 'remove'], [4, 'bo', 'up', 'add']], 'me', 3), []), ('emoji vanishes and returns', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'bo', 'up', 'remove'], [7, 'di', 'up', 'add']], 'me', 3), [['ok', 1, False], ['up', 1, False]]), ('second user joins an emoji', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'di', 'up', 'add']], 'di', 3), [['up', 2, True], ['ok', 1, False]]), ('only reaction removed', ([[1, 'me', 'up', 'add'], [2, 'me', 'up', 'remove']], 'me', 2), []), ('limit reached', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'b', 'add'], [3, 'bo', 'c', 'add']], 'bo', 2), [['a', 1, True], ['b', 1, True]]), ('stray remove does not free a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'z', 'remove'], [3, 'bo', 'b', 'add']], 'me', 1), [['a', 1, False]]), ('removal frees a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'a', 'remove'], [3, 'bo', 'b', 'add']], 'bo', 1), [['b', 1, True]])], 4: [('remove delivered before add', ([[6, 'bo', 'up', 'remove'], [5, 'bo', 'up', 'add']], 'me', 3), []), ('emoji vanishes and returns', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'bo', 'up', 'remove'], [8, 'di', 'up', 'add']], 'me', 3), [['ok', 1, False], ['up', 1, False]]), ('second user joins an emoji', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'di', 'up', 'add']], 'di', 3), [['up', 2, True], ['ok', 1, False]]), ('only reaction removed', ([[1, 'me', 'up', 'add'], [2, 'me', 'up', 'remove']], 'me', 2), []), ('limit reached', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'b', 'add'], [3, 'bo', 'c', 'add']], 'bo', 2), [['a', 1, True], ['b', 1, True]]), ('stray remove does not free a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'z', 'remove'], [3, 'bo', 'b', 'add']], 'me', 1), [['a', 1, False]]), ('removal frees a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'a', 'remove'], [3, 'bo', 'b', 'add']], 'bo', 1), [['b', 1, True]])], 5: [('remove delivered before add', ([[7, 'bo', 'up', 'remove'], [6, 'bo', 'up', 'add']], 'me', 3), []), ('emoji vanishes and returns', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'bo', 'up', 'remove'], [9, 'di', 'up', 'add']], 'me', 3), [['ok', 1, False], ['up', 1, False]]), ('second user joins an emoji', ([[1, 'bo', 'up', 'add'], [2, 'cy', 'ok', 'add'], [3, 'di', 'up', 'add']], 'di', 3), [['up', 2, True], ['ok', 1, False]]), ('only reaction removed', ([[1, 'me', 'up', 'add'], [2, 'me', 'up', 'remove']], 'me', 2), []), ('limit reached', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'b', 'add'], [3, 'bo', 'c', 'add']], 'bo', 2), [['a', 1, True], ['b', 1, True]]), ('stray remove does not free a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'z', 'remove'], [3, 'bo', 'b', 'add']], 'me', 1), [['a', 1, False]]), ('removal frees a slot', ([[1, 'bo', 'a', 'add'], [2, 'bo', 'a', 'remove'], [3, 'bo', 'b', 'add']], 'bo', 1), [['b', 1, True]])]}
for _label, _args, _expected in _CASES[N]:
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 |
|---|---|---|---|
| remove delivered before add | [] | [] | Passed |
| emoji vanishes and returns | [['ok', 1, False], ['up', 1, False]] | [['ok', 1, False], ['up', 1, False]] | Passed |
| second user joins an emoji | [['up', 2, True], ['ok', 1, False]] | [['up', 2, True], ['ok', 1, False]] | Passed |
| only reaction removed | [] | [] | Passed |
| limit reached | [['a', 1, True], ['b', 1, True]] | [['a', 1, True], ['b', 1, True]] | Passed |
| stray remove does not free a slot | [['a', 1, False]] | [['a', 1, False]] | Passed |
| removal frees a slot | [['b', 1, True]] | [['b', 1, True]] | Passed |
SHA-256 / f1af2795151369d018dc4012151479af292d981942cd286de3b2dce95869da14
Verification & scope
Stipulated offline chat model; not a complete messaging protocol, client or server implementation. 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:13.391549+00:00.
Case digest / 0129571298123e2ddd3be71132e8008e066e666bbcbc4bdf7ecd981aded129af