FAILURE MAP
← Case archive

FA-45546 / Data systems / Open access

Membership crossings emit one row regardless of left multiplicity · case 01

Membership crossings emit one row regardless of left multiplicity.

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

ROOT CAUSE

right-membership-delta: Membership crossings emit one row regardless of left multiplicity.

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: Capping multiplicity at one still loses duplicate left facts.

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 key is None: continue
            was=before.get(key,0)>0; now=after.get(key,0)>0
            if was!=now: out.append([ident,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, 1]][[10, 2]]Failed

SHA-256 / 30c0c1af3908a0cd708e23e931461d03429be90587150c54fdcf0b58480567dc

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: continue
            was=before.get(key,0)>0; now=after.get(key,0)>0
            if was!=now: out.append([ident,min(multiplicity,1)*(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, 1]][[10, 2]]Failed

SHA-256 / 0c8e45d2cb08374ace7f8aad89381d120bd5a07d97cc2fa8eb5bc0872ec913a0

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.358338+00:00.

Case digest / e93a2c1ed88176bdde537fb34748b57db2b94eb1cdca8417aca49eff0959e274