FAILURE MAP
← Case archive

FA-45556 / Data systems / Open access

Membership maintenance matches null keys against right counts · case 01

Membership maintenance matches null keys against right counts.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

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 fixtureActualExpectedOutcome
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 fixtureActualExpectedOutcome
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 fixtureActualExpectedOutcome
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