FA-45556 / Data systems / Open access
Membership maintenance matches null keys against right counts · case 01
Membership maintenance matches null keys against right counts.
ROOT CAUSE
right-membership-delta: Membership maintenance matches null keys against right counts.
VERIFIED REPAIR
Preserve the stated physical representation and operation order: For a fixed left bag [id,key,multiplicity], apply a right-key count delta batch and emit signed left rows only when right membership crosses zero. Null keys never match. Emit [id,signed-left-multiplicity] in left order; duplicate right updates consolidate before crossing detection.
Unsuccessful approach: Right null entries do not make ordinary equality match null left keys.
Case contract
For a fixed left bag [id,key,multiplicity], apply a right-key count delta batch and emit signed left rows only when right membership crosses zero. Null keys never match. Emit [id,signed-left-multiplicity] in left order; duplicate right updates consolidate before crossing detection.
Why this case matters
A bounded deterministic data engine model makes representation and changelog faults reproducible.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(d):
try:
left,old,delta=d
before=dict(old); after=dict(old)
for key,weight in delta: after[key]=after.get(key,0)+weight
out=[]
for ident,key,multiplicity in left:
if False: continue
was=before.get(key,0)>0; now=after.get(key,0)>0
if was!=now: out.append([ident,multiplicity*(1 if now else -1)])
return out
except (IndexError, KeyError, ValueError, StopIteration) as exc:
return {"representation_error": type(exc).__name__}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
check('new right key', solve([[[10, 'a', 1]], [], [['a', 1]]]), [[10, 1]])
check('last right removed', solve([[[10, 'a', 1]], [['a', 1]], [['a', -1]]]), [[10, -1]])
check('right duplicate remains', solve([[[10, 'a', 1]], [['a', 2]], [['a', -1]]]), [])
check('right batch cancellation', solve([[[10, 'a', 1]], [], [['a', 1], ['a', -1]]]), [])
check('other right key', solve([[[10, 'a', 1]], [['b', 1]], [['a', 1]]]), [[10, 1]])
check('null key', solve([[[10, None, 1]], [], [[None, 1]]]), [])
check('two removals cross zero', solve([[[10, 'a', 1]], [['a', 2]], [['a', -1], ['a', -1]]]), [[10, -1]])
check('left multiplicity', solve([[[10, 'a', 2]], [], [['a', 1]]]), [[10, 2]])
elif N == 2:
check('new right key', solve([[[10, 'a', 2]], [], [['a', 1]]]), [[10, 2]])
check('last right removed', solve([[[10, 'a', 2]], [['a', 1]], [['a', -1]]]), [[10, -2]])
check('right duplicate remains', solve([[[10, 'a', 2]], [['a', 2]], [['a', -1]]]), [])
check('right batch cancellation', solve([[[10, 'a', 2]], [], [['a', 1], ['a', -1]]]), [])
check('other right key', solve([[[10, 'a', 2]], [['b', 1]], [['a', 1]]]), [[10, 2]])
check('null key', solve([[[10, None, 2]], [], [[None, 1]]]), [])
check('two removals cross zero', solve([[[10, 'a', 2]], [['a', 2]], [['a', -1], ['a', -1]]]), [[10, -2]])
check('left multiplicity', solve([[[10, 'a', 3]], [], [['a', 1]]]), [[10, 3]])
elif N == 3:
check('new right key', solve([[[10, 'a', 3]], [], [['a', 1]]]), [[10, 3]])
check('last right removed', solve([[[10, 'a', 3]], [['a', 1]], [['a', -1]]]), [[10, -3]])
check('right duplicate remains', solve([[[10, 'a', 3]], [['a', 2]], [['a', -1]]]), [])
check('right batch cancellation', solve([[[10, 'a', 3]], [], [['a', 1], ['a', -1]]]), [])
check('other right key', solve([[[10, 'a', 3]], [['b', 1]], [['a', 1]]]), [[10, 3]])
check('null key', solve([[[10, None, 3]], [], [[None, 1]]]), [])
check('two removals cross zero', solve([[[10, 'a', 3]], [['a', 2]], [['a', -1], ['a', -1]]]), [[10, -3]])
check('left multiplicity', solve([[[10, 'a', 4]], [], [['a', 1]]]), [[10, 4]])
elif N == 4:
check('new right key', solve([[[10, 'a', 4]], [], [['a', 1]]]), [[10, 4]])
check('last right removed', solve([[[10, 'a', 4]], [['a', 1]], [['a', -1]]]), [[10, -4]])
check('right duplicate remains', solve([[[10, 'a', 4]], [['a', 2]], [['a', -1]]]), [])
check('right batch cancellation', solve([[[10, 'a', 4]], [], [['a', 1], ['a', -1]]]), [])
check('other right key', solve([[[10, 'a', 4]], [['b', 1]], [['a', 1]]]), [[10, 4]])
check('null key', solve([[[10, None, 4]], [], [[None, 1]]]), [])
check('two removals cross zero', solve([[[10, 'a', 4]], [['a', 2]], [['a', -1], ['a', -1]]]), [[10, -4]])
check('left multiplicity', solve([[[10, 'a', 5]], [], [['a', 1]]]), [[10, 5]])
elif N == 5:
check('new right key', solve([[[10, 'a', 5]], [], [['a', 1]]]), [[10, 5]])
check('last right removed', solve([[[10, 'a', 5]], [['a', 1]], [['a', -1]]]), [[10, -5]])
check('right duplicate remains', solve([[[10, 'a', 5]], [['a', 2]], [['a', -1]]]), [])
check('right batch cancellation', solve([[[10, 'a', 5]], [], [['a', 1], ['a', -1]]]), [])
check('other right key', solve([[[10, 'a', 5]], [['b', 1]], [['a', 1]]]), [[10, 5]])
check('null key', solve([[[10, None, 5]], [], [[None, 1]]]), [])
check('two removals cross zero', solve([[[10, 'a', 5]], [['a', 2]], [['a', -1], ['a', -1]]]), [[10, -5]])
check('left multiplicity', solve([[[10, 'a', 6]], [], [['a', 1]]]), [[10, 6]])
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 |
|---|---|---|---|
| new right key | [[10, 1]] | [[10, 1]] | Passed |
| last right removed | [[10, -1]] | [[10, -1]] | Passed |
| right duplicate remains | [] | [] | Passed |
| right batch cancellation | [] | [] | Passed |
| other right key | [[10, 1]] | [[10, 1]] | Passed |
| null key | [[10, 1]] | [] | Failed |
| two removals cross zero | [[10, -1]] | [[10, -1]] | Passed |
| left multiplicity | [[10, 2]] | [[10, 2]] | Passed |
SHA-256 / ff63ca8c8ca9f22cb247dfbcbcd2a339ce589fa260c9cdff280f110824af8ee6
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(d):
try:
left,old,delta=d
before=dict(old); after=dict(old)
for key,weight in delta: after[key]=after.get(key,0)+weight
out=[]
for ident,key,multiplicity in left:
if key is None and None not in after: continue
was=before.get(key,0)>0; now=after.get(key,0)>0
if was!=now: out.append([ident,multiplicity*(1 if now else -1)])
return out
except (IndexError, KeyError, ValueError, StopIteration) as exc:
return {"representation_error": type(exc).__name__}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
check('new right key', solve([[[10, 'a', 1]], [], [['a', 1]]]), [[10, 1]])
check('last right removed', solve([[[10, 'a', 1]], [['a', 1]], [['a', -1]]]), [[10, -1]])
check('right duplicate remains', solve([[[10, 'a', 1]], [['a', 2]], [['a', -1]]]), [])
check('right batch cancellation', solve([[[10, 'a', 1]], [], [['a', 1], ['a', -1]]]), [])
check('other right key', solve([[[10, 'a', 1]], [['b', 1]], [['a', 1]]]), [[10, 1]])
check('null key', solve([[[10, None, 1]], [], [[None, 1]]]), [])
check('two removals cross zero', solve([[[10, 'a', 1]], [['a', 2]], [['a', -1], ['a', -1]]]), [[10, -1]])
check('left multiplicity', solve([[[10, 'a', 2]], [], [['a', 1]]]), [[10, 2]])
elif N == 2:
check('new right key', solve([[[10, 'a', 2]], [], [['a', 1]]]), [[10, 2]])
check('last right removed', solve([[[10, 'a', 2]], [['a', 1]], [['a', -1]]]), [[10, -2]])
check('right duplicate remains', solve([[[10, 'a', 2]], [['a', 2]], [['a', -1]]]), [])
check('right batch cancellation', solve([[[10, 'a', 2]], [], [['a', 1], ['a', -1]]]), [])
check('other right key', solve([[[10, 'a', 2]], [['b', 1]], [['a', 1]]]), [[10, 2]])
check('null key', solve([[[10, None, 2]], [], [[None, 1]]]), [])
check('two removals cross zero', solve([[[10, 'a', 2]], [['a', 2]], [['a', -1], ['a', -1]]]), [[10, -2]])
check('left multiplicity', solve([[[10, 'a', 3]], [], [['a', 1]]]), [[10, 3]])
elif N == 3:
check('new right key', solve([[[10, 'a', 3]], [], [['a', 1]]]), [[10, 3]])
check('last right removed', solve([[[10, 'a', 3]], [['a', 1]], [['a', -1]]]), [[10, -3]])
check('right duplicate remains', solve([[[10, 'a', 3]], [['a', 2]], [['a', -1]]]), [])
check('right batch cancellation', solve([[[10, 'a', 3]], [], [['a', 1], ['a', -1]]]), [])
check('other right key', solve([[[10, 'a', 3]], [['b', 1]], [['a', 1]]]), [[10, 3]])
check('null key', solve([[[10, None, 3]], [], [[None, 1]]]), [])
check('two removals cross zero', solve([[[10, 'a', 3]], [['a', 2]], [['a', -1], ['a', -1]]]), [[10, -3]])
check('left multiplicity', solve([[[10, 'a', 4]], [], [['a', 1]]]), [[10, 4]])
elif N == 4:
check('new right key', solve([[[10, 'a', 4]], [], [['a', 1]]]), [[10, 4]])
check('last right removed', solve([[[10, 'a', 4]], [['a', 1]], [['a', -1]]]), [[10, -4]])
check('right duplicate remains', solve([[[10, 'a', 4]], [['a', 2]], [['a', -1]]]), [])
check('right batch cancellation', solve([[[10, 'a', 4]], [], [['a', 1], ['a', -1]]]), [])
check('other right key', solve([[[10, 'a', 4]], [['b', 1]], [['a', 1]]]), [[10, 4]])
check('null key', solve([[[10, None, 4]], [], [[None, 1]]]), [])
check('two removals cross zero', solve([[[10, 'a', 4]], [['a', 2]], [['a', -1], ['a', -1]]]), [[10, -4]])
check('left multiplicity', solve([[[10, 'a', 5]], [], [['a', 1]]]), [[10, 5]])
elif N == 5:
check('new right key', solve([[[10, 'a', 5]], [], [['a', 1]]]), [[10, 5]])
check('last right removed', solve([[[10, 'a', 5]], [['a', 1]], [['a', -1]]]), [[10, -5]])
check('right duplicate remains', solve([[[10, 'a', 5]], [['a', 2]], [['a', -1]]]), [])
check('right batch cancellation', solve([[[10, 'a', 5]], [], [['a', 1], ['a', -1]]]), [])
check('other right key', solve([[[10, 'a', 5]], [['b', 1]], [['a', 1]]]), [[10, 5]])
check('null key', solve([[[10, None, 5]], [], [[None, 1]]]), [])
check('two removals cross zero', solve([[[10, 'a', 5]], [['a', 2]], [['a', -1], ['a', -1]]]), [[10, -5]])
check('left multiplicity', solve([[[10, 'a', 6]], [], [['a', 1]]]), [[10, 6]])
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 |
|---|---|---|---|
| new right key | [[10, 1]] | [[10, 1]] | Passed |
| last right removed | [[10, -1]] | [[10, -1]] | Passed |
| right duplicate remains | [] | [] | Passed |
| right batch cancellation | [] | [] | Passed |
| other right key | [[10, 1]] | [[10, 1]] | Passed |
| null key | [[10, 1]] | [] | Failed |
| two removals cross zero | [[10, -1]] | [[10, -1]] | Passed |
| left multiplicity | [[10, 2]] | [[10, 2]] | Passed |
SHA-256 / 02879f4274c6bf475a7f4f9462447bfef6010e870353a6a2950b12e22ed04e3b
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(d):
try:
left,old,delta=d
before=dict(old); after=dict(old)
for key,weight in delta: after[key]=after.get(key,0)+weight
out=[]
for ident,key,multiplicity in left:
if key is None: continue
was=before.get(key,0)>0; now=after.get(key,0)>0
if was!=now: out.append([ident,multiplicity*(1 if now else -1)])
return out
except (IndexError, KeyError, ValueError, StopIteration) as exc:
return {"representation_error": type(exc).__name__}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
check('new right key', solve([[[10, 'a', 1]], [], [['a', 1]]]), [[10, 1]])
check('last right removed', solve([[[10, 'a', 1]], [['a', 1]], [['a', -1]]]), [[10, -1]])
check('right duplicate remains', solve([[[10, 'a', 1]], [['a', 2]], [['a', -1]]]), [])
check('right batch cancellation', solve([[[10, 'a', 1]], [], [['a', 1], ['a', -1]]]), [])
check('other right key', solve([[[10, 'a', 1]], [['b', 1]], [['a', 1]]]), [[10, 1]])
check('null key', solve([[[10, None, 1]], [], [[None, 1]]]), [])
check('two removals cross zero', solve([[[10, 'a', 1]], [['a', 2]], [['a', -1], ['a', -1]]]), [[10, -1]])
check('left multiplicity', solve([[[10, 'a', 2]], [], [['a', 1]]]), [[10, 2]])
elif N == 2:
check('new right key', solve([[[10, 'a', 2]], [], [['a', 1]]]), [[10, 2]])
check('last right removed', solve([[[10, 'a', 2]], [['a', 1]], [['a', -1]]]), [[10, -2]])
check('right duplicate remains', solve([[[10, 'a', 2]], [['a', 2]], [['a', -1]]]), [])
check('right batch cancellation', solve([[[10, 'a', 2]], [], [['a', 1], ['a', -1]]]), [])
check('other right key', solve([[[10, 'a', 2]], [['b', 1]], [['a', 1]]]), [[10, 2]])
check('null key', solve([[[10, None, 2]], [], [[None, 1]]]), [])
check('two removals cross zero', solve([[[10, 'a', 2]], [['a', 2]], [['a', -1], ['a', -1]]]), [[10, -2]])
check('left multiplicity', solve([[[10, 'a', 3]], [], [['a', 1]]]), [[10, 3]])
elif N == 3:
check('new right key', solve([[[10, 'a', 3]], [], [['a', 1]]]), [[10, 3]])
check('last right removed', solve([[[10, 'a', 3]], [['a', 1]], [['a', -1]]]), [[10, -3]])
check('right duplicate remains', solve([[[10, 'a', 3]], [['a', 2]], [['a', -1]]]), [])
check('right batch cancellation', solve([[[10, 'a', 3]], [], [['a', 1], ['a', -1]]]), [])
check('other right key', solve([[[10, 'a', 3]], [['b', 1]], [['a', 1]]]), [[10, 3]])
check('null key', solve([[[10, None, 3]], [], [[None, 1]]]), [])
check('two removals cross zero', solve([[[10, 'a', 3]], [['a', 2]], [['a', -1], ['a', -1]]]), [[10, -3]])
check('left multiplicity', solve([[[10, 'a', 4]], [], [['a', 1]]]), [[10, 4]])
elif N == 4:
check('new right key', solve([[[10, 'a', 4]], [], [['a', 1]]]), [[10, 4]])
check('last right removed', solve([[[10, 'a', 4]], [['a', 1]], [['a', -1]]]), [[10, -4]])
check('right duplicate remains', solve([[[10, 'a', 4]], [['a', 2]], [['a', -1]]]), [])
check('right batch cancellation', solve([[[10, 'a', 4]], [], [['a', 1], ['a', -1]]]), [])
check('other right key', solve([[[10, 'a', 4]], [['b', 1]], [['a', 1]]]), [[10, 4]])
check('null key', solve([[[10, None, 4]], [], [[None, 1]]]), [])
check('two removals cross zero', solve([[[10, 'a', 4]], [['a', 2]], [['a', -1], ['a', -1]]]), [[10, -4]])
check('left multiplicity', solve([[[10, 'a', 5]], [], [['a', 1]]]), [[10, 5]])
elif N == 5:
check('new right key', solve([[[10, 'a', 5]], [], [['a', 1]]]), [[10, 5]])
check('last right removed', solve([[[10, 'a', 5]], [['a', 1]], [['a', -1]]]), [[10, -5]])
check('right duplicate remains', solve([[[10, 'a', 5]], [['a', 2]], [['a', -1]]]), [])
check('right batch cancellation', solve([[[10, 'a', 5]], [], [['a', 1], ['a', -1]]]), [])
check('other right key', solve([[[10, 'a', 5]], [['b', 1]], [['a', 1]]]), [[10, 5]])
check('null key', solve([[[10, None, 5]], [], [[None, 1]]]), [])
check('two removals cross zero', solve([[[10, 'a', 5]], [['a', 2]], [['a', -1], ['a', -1]]]), [[10, -5]])
check('left multiplicity', solve([[[10, 'a', 6]], [], [['a', 1]]]), [[10, 6]])
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 |
|---|---|---|---|
| new right key | [[10, 1]] | [[10, 1]] | Passed |
| last right removed | [[10, -1]] | [[10, -1]] | Passed |
| right duplicate remains | [] | [] | Passed |
| right batch cancellation | [] | [] | Passed |
| other right key | [[10, 1]] | [[10, 1]] | Passed |
| null key | [] | [] | Passed |
| two removals cross zero | [[10, -1]] | [[10, -1]] | Passed |
| left multiplicity | [[10, 2]] | [[10, 2]] | Passed |
SHA-256 / b9f613338c00dc76110646dfbe23419e79cc5dc101f4bf3b36e0c469ff2ff866
Verification & scope
Offline stipulated semantics over valid small inputs; no performance, concurrency, or production-engine conformance claim. 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:44:23.478286+00:00.
Case digest / 56702d736132c732a072587bf0bb66c65c25e67fb5d5980ac1f5d750795eae13