FAILURE MAP
← Case archive

FA-45651 / Data systems / Open access

Session grouping overwrites the session start on every event · case 01

Session grouping overwrites the session start on every event.

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

ROOT CAUSE

session-bridge-grouping: Session grouping overwrites the session start on every event.

VERIFIED REPAIR

Preserve the stated physical representation and operation order: Group [key,time,id] events into sessions independently by key. Sort each key by (time,id); consecutive gaps <=gap belong to one transitive session. Emit [key,first-time,last-time,ordered-ids] ordered by key and session time. An intervening bridge may join otherwise distant endpoints.

Unsuccessful approach: Allowing the second event to replace the start still shortens the session interval.

Case contract

Group [key,time,id] events into sessions independently by key. Sort each key by (time,id); consecutive gaps <=gap belong to one transitive session. Emit [key,first-time,last-time,ordered-ids] ordered by key and session time. An intervening bridge may join otherwise distant endpoints.

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:
        events,gap=d
        out=[]
        for key in sorted(set(k for k,t,i in events)):
            rows=sorted((t,i) for k,t,i in events if k==key)
            start=last=None; ids=[]
            for time,ident in rows:
                if ids and time-last>gap:
                    out.append([key,start,last,ids]); ids=[]
                start=time
                ids.append(ident); last=time
            if ids: out.append([key,start,last,ids])
        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('bridge chain', solve([[['a', 1, 10], ['a', 3, 11], ['a', 5, 12]], 2]), [['a', 1, 5, [10, 11, 12]]])
    check('arrival order', solve([[['a', 3, 10], ['a', 1, 11]], 2]), [['a', 1, 3, [11, 10]]])
    check('key separation', solve([[['a', 1, 10], ['b', 1, 11]], 2]), [['a', 1, 1, [10]], ['b', 1, 1, [11]]])
    check('separate sessions', solve([[['a', 1, 10], ['a', 6, 11]], 2]), [['a', 1, 1, [10]], ['a', 6, 6, [11]]])
    check('equal timestamp', solve([[['a', 1, 11], ['a', 1, 10]], 0]), [['a', 1, 1, [10, 11]]])
    check('single event', solve([[['a', 1, 10]], 2]), [['a', 1, 1, [10]]])
    check('empty stream', solve([[], 2]), [])
elif N == 2:
    check('bridge chain', solve([[['a', 2, 10], ['a', 4, 11], ['a', 6, 12]], 2]), [['a', 2, 6, [10, 11, 12]]])
    check('arrival order', solve([[['a', 4, 10], ['a', 2, 11]], 2]), [['a', 2, 4, [11, 10]]])
    check('key separation', solve([[['a', 2, 10], ['b', 2, 11]], 2]), [['a', 2, 2, [10]], ['b', 2, 2, [11]]])
    check('separate sessions', solve([[['a', 2, 10], ['a', 7, 11]], 2]), [['a', 2, 2, [10]], ['a', 7, 7, [11]]])
    check('equal timestamp', solve([[['a', 2, 11], ['a', 2, 10]], 0]), [['a', 2, 2, [10, 11]]])
    check('single event', solve([[['a', 2, 10]], 2]), [['a', 2, 2, [10]]])
    check('empty stream', solve([[], 2]), [])
elif N == 3:
    check('bridge chain', solve([[['a', 3, 10], ['a', 5, 11], ['a', 7, 12]], 2]), [['a', 3, 7, [10, 11, 12]]])
    check('arrival order', solve([[['a', 5, 10], ['a', 3, 11]], 2]), [['a', 3, 5, [11, 10]]])
    check('key separation', solve([[['a', 3, 10], ['b', 3, 11]], 2]), [['a', 3, 3, [10]], ['b', 3, 3, [11]]])
    check('separate sessions', solve([[['a', 3, 10], ['a', 8, 11]], 2]), [['a', 3, 3, [10]], ['a', 8, 8, [11]]])
    check('equal timestamp', solve([[['a', 3, 11], ['a', 3, 10]], 0]), [['a', 3, 3, [10, 11]]])
    check('single event', solve([[['a', 3, 10]], 2]), [['a', 3, 3, [10]]])
    check('empty stream', solve([[], 2]), [])
elif N == 4:
    check('bridge chain', solve([[['a', 4, 10], ['a', 6, 11], ['a', 8, 12]], 2]), [['a', 4, 8, [10, 11, 12]]])
    check('arrival order', solve([[['a', 6, 10], ['a', 4, 11]], 2]), [['a', 4, 6, [11, 10]]])
    check('key separation', solve([[['a', 4, 10], ['b', 4, 11]], 2]), [['a', 4, 4, [10]], ['b', 4, 4, [11]]])
    check('separate sessions', solve([[['a', 4, 10], ['a', 9, 11]], 2]), [['a', 4, 4, [10]], ['a', 9, 9, [11]]])
    check('equal timestamp', solve([[['a', 4, 11], ['a', 4, 10]], 0]), [['a', 4, 4, [10, 11]]])
    check('single event', solve([[['a', 4, 10]], 2]), [['a', 4, 4, [10]]])
    check('empty stream', solve([[], 2]), [])
elif N == 5:
    check('bridge chain', solve([[['a', 5, 10], ['a', 7, 11], ['a', 9, 12]], 2]), [['a', 5, 9, [10, 11, 12]]])
    check('arrival order', solve([[['a', 7, 10], ['a', 5, 11]], 2]), [['a', 5, 7, [11, 10]]])
    check('key separation', solve([[['a', 5, 10], ['b', 5, 11]], 2]), [['a', 5, 5, [10]], ['b', 5, 5, [11]]])
    check('separate sessions', solve([[['a', 5, 10], ['a', 10, 11]], 2]), [['a', 5, 5, [10]], ['a', 10, 10, [11]]])
    check('equal timestamp', solve([[['a', 5, 11], ['a', 5, 10]], 0]), [['a', 5, 5, [10, 11]]])
    check('single event', solve([[['a', 5, 10]], 2]), [['a', 5, 5, [10]]])
    check('empty stream', solve([[], 2]), [])
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
bridge chain[['a', 5, 5, [10, 11, 12]]][['a', 1, 5, [10, 11, 12]]]Failed
arrival order[['a', 3, 3, [11, 10]]][['a', 1, 3, [11, 10]]]Failed
key separation[['a', 1, 1, [10]], ['b', 1, 1, [11]]][['a', 1, 1, [10]], ['b', 1, 1, [11]]]Passed
separate sessions[['a', 1, 1, [10]], ['a', 6, 6, [11]]][['a', 1, 1, [10]], ['a', 6, 6, [11]]]Passed
equal timestamp[['a', 1, 1, [10, 11]]][['a', 1, 1, [10, 11]]]Passed
single event[['a', 1, 1, [10]]][['a', 1, 1, [10]]]Passed
empty stream[][]Passed

SHA-256 / ae92454793e933c36e10aa0f865f9ea65dcb27a9e8fd1b9caee59708711b0616

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    try:
        events,gap=d
        out=[]
        for key in sorted(set(k for k,t,i in events)):
            rows=sorted((t,i) for k,t,i in events if k==key)
            start=last=None; ids=[]
            for time,ident in rows:
                if ids and time-last>gap:
                    out.append([key,start,last,ids]); ids=[]
                if len(ids)<=1: start=time
                ids.append(ident); last=time
            if ids: out.append([key,start,last,ids])
        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('bridge chain', solve([[['a', 1, 10], ['a', 3, 11], ['a', 5, 12]], 2]), [['a', 1, 5, [10, 11, 12]]])
    check('arrival order', solve([[['a', 3, 10], ['a', 1, 11]], 2]), [['a', 1, 3, [11, 10]]])
    check('key separation', solve([[['a', 1, 10], ['b', 1, 11]], 2]), [['a', 1, 1, [10]], ['b', 1, 1, [11]]])
    check('separate sessions', solve([[['a', 1, 10], ['a', 6, 11]], 2]), [['a', 1, 1, [10]], ['a', 6, 6, [11]]])
    check('equal timestamp', solve([[['a', 1, 11], ['a', 1, 10]], 0]), [['a', 1, 1, [10, 11]]])
    check('single event', solve([[['a', 1, 10]], 2]), [['a', 1, 1, [10]]])
    check('empty stream', solve([[], 2]), [])
elif N == 2:
    check('bridge chain', solve([[['a', 2, 10], ['a', 4, 11], ['a', 6, 12]], 2]), [['a', 2, 6, [10, 11, 12]]])
    check('arrival order', solve([[['a', 4, 10], ['a', 2, 11]], 2]), [['a', 2, 4, [11, 10]]])
    check('key separation', solve([[['a', 2, 10], ['b', 2, 11]], 2]), [['a', 2, 2, [10]], ['b', 2, 2, [11]]])
    check('separate sessions', solve([[['a', 2, 10], ['a', 7, 11]], 2]), [['a', 2, 2, [10]], ['a', 7, 7, [11]]])
    check('equal timestamp', solve([[['a', 2, 11], ['a', 2, 10]], 0]), [['a', 2, 2, [10, 11]]])
    check('single event', solve([[['a', 2, 10]], 2]), [['a', 2, 2, [10]]])
    check('empty stream', solve([[], 2]), [])
elif N == 3:
    check('bridge chain', solve([[['a', 3, 10], ['a', 5, 11], ['a', 7, 12]], 2]), [['a', 3, 7, [10, 11, 12]]])
    check('arrival order', solve([[['a', 5, 10], ['a', 3, 11]], 2]), [['a', 3, 5, [11, 10]]])
    check('key separation', solve([[['a', 3, 10], ['b', 3, 11]], 2]), [['a', 3, 3, [10]], ['b', 3, 3, [11]]])
    check('separate sessions', solve([[['a', 3, 10], ['a', 8, 11]], 2]), [['a', 3, 3, [10]], ['a', 8, 8, [11]]])
    check('equal timestamp', solve([[['a', 3, 11], ['a', 3, 10]], 0]), [['a', 3, 3, [10, 11]]])
    check('single event', solve([[['a', 3, 10]], 2]), [['a', 3, 3, [10]]])
    check('empty stream', solve([[], 2]), [])
elif N == 4:
    check('bridge chain', solve([[['a', 4, 10], ['a', 6, 11], ['a', 8, 12]], 2]), [['a', 4, 8, [10, 11, 12]]])
    check('arrival order', solve([[['a', 6, 10], ['a', 4, 11]], 2]), [['a', 4, 6, [11, 10]]])
    check('key separation', solve([[['a', 4, 10], ['b', 4, 11]], 2]), [['a', 4, 4, [10]], ['b', 4, 4, [11]]])
    check('separate sessions', solve([[['a', 4, 10], ['a', 9, 11]], 2]), [['a', 4, 4, [10]], ['a', 9, 9, [11]]])
    check('equal timestamp', solve([[['a', 4, 11], ['a', 4, 10]], 0]), [['a', 4, 4, [10, 11]]])
    check('single event', solve([[['a', 4, 10]], 2]), [['a', 4, 4, [10]]])
    check('empty stream', solve([[], 2]), [])
elif N == 5:
    check('bridge chain', solve([[['a', 5, 10], ['a', 7, 11], ['a', 9, 12]], 2]), [['a', 5, 9, [10, 11, 12]]])
    check('arrival order', solve([[['a', 7, 10], ['a', 5, 11]], 2]), [['a', 5, 7, [11, 10]]])
    check('key separation', solve([[['a', 5, 10], ['b', 5, 11]], 2]), [['a', 5, 5, [10]], ['b', 5, 5, [11]]])
    check('separate sessions', solve([[['a', 5, 10], ['a', 10, 11]], 2]), [['a', 5, 5, [10]], ['a', 10, 10, [11]]])
    check('equal timestamp', solve([[['a', 5, 11], ['a', 5, 10]], 0]), [['a', 5, 5, [10, 11]]])
    check('single event', solve([[['a', 5, 10]], 2]), [['a', 5, 5, [10]]])
    check('empty stream', solve([[], 2]), [])
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
bridge chain[['a', 3, 5, [10, 11, 12]]][['a', 1, 5, [10, 11, 12]]]Failed
arrival order[['a', 3, 3, [11, 10]]][['a', 1, 3, [11, 10]]]Failed
key separation[['a', 1, 1, [10]], ['b', 1, 1, [11]]][['a', 1, 1, [10]], ['b', 1, 1, [11]]]Passed
separate sessions[['a', 1, 1, [10]], ['a', 6, 6, [11]]][['a', 1, 1, [10]], ['a', 6, 6, [11]]]Passed
equal timestamp[['a', 1, 1, [10, 11]]][['a', 1, 1, [10, 11]]]Passed
single event[['a', 1, 1, [10]]][['a', 1, 1, [10]]]Passed
empty stream[][]Passed

SHA-256 / 21b8e4eb30444755cddf711cbe3d80d6de9e4f2e34674234e4967271397b49c1

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(d):
    try:
        events,gap=d
        out=[]
        for key in sorted(set(k for k,t,i in events)):
            rows=sorted((t,i) for k,t,i in events if k==key)
            start=last=None; ids=[]
            for time,ident in rows:
                if ids and time-last>gap:
                    out.append([key,start,last,ids]); ids=[]
                if not ids: start=time
                ids.append(ident); last=time
            if ids: out.append([key,start,last,ids])
        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('bridge chain', solve([[['a', 1, 10], ['a', 3, 11], ['a', 5, 12]], 2]), [['a', 1, 5, [10, 11, 12]]])
    check('arrival order', solve([[['a', 3, 10], ['a', 1, 11]], 2]), [['a', 1, 3, [11, 10]]])
    check('key separation', solve([[['a', 1, 10], ['b', 1, 11]], 2]), [['a', 1, 1, [10]], ['b', 1, 1, [11]]])
    check('separate sessions', solve([[['a', 1, 10], ['a', 6, 11]], 2]), [['a', 1, 1, [10]], ['a', 6, 6, [11]]])
    check('equal timestamp', solve([[['a', 1, 11], ['a', 1, 10]], 0]), [['a', 1, 1, [10, 11]]])
    check('single event', solve([[['a', 1, 10]], 2]), [['a', 1, 1, [10]]])
    check('empty stream', solve([[], 2]), [])
elif N == 2:
    check('bridge chain', solve([[['a', 2, 10], ['a', 4, 11], ['a', 6, 12]], 2]), [['a', 2, 6, [10, 11, 12]]])
    check('arrival order', solve([[['a', 4, 10], ['a', 2, 11]], 2]), [['a', 2, 4, [11, 10]]])
    check('key separation', solve([[['a', 2, 10], ['b', 2, 11]], 2]), [['a', 2, 2, [10]], ['b', 2, 2, [11]]])
    check('separate sessions', solve([[['a', 2, 10], ['a', 7, 11]], 2]), [['a', 2, 2, [10]], ['a', 7, 7, [11]]])
    check('equal timestamp', solve([[['a', 2, 11], ['a', 2, 10]], 0]), [['a', 2, 2, [10, 11]]])
    check('single event', solve([[['a', 2, 10]], 2]), [['a', 2, 2, [10]]])
    check('empty stream', solve([[], 2]), [])
elif N == 3:
    check('bridge chain', solve([[['a', 3, 10], ['a', 5, 11], ['a', 7, 12]], 2]), [['a', 3, 7, [10, 11, 12]]])
    check('arrival order', solve([[['a', 5, 10], ['a', 3, 11]], 2]), [['a', 3, 5, [11, 10]]])
    check('key separation', solve([[['a', 3, 10], ['b', 3, 11]], 2]), [['a', 3, 3, [10]], ['b', 3, 3, [11]]])
    check('separate sessions', solve([[['a', 3, 10], ['a', 8, 11]], 2]), [['a', 3, 3, [10]], ['a', 8, 8, [11]]])
    check('equal timestamp', solve([[['a', 3, 11], ['a', 3, 10]], 0]), [['a', 3, 3, [10, 11]]])
    check('single event', solve([[['a', 3, 10]], 2]), [['a', 3, 3, [10]]])
    check('empty stream', solve([[], 2]), [])
elif N == 4:
    check('bridge chain', solve([[['a', 4, 10], ['a', 6, 11], ['a', 8, 12]], 2]), [['a', 4, 8, [10, 11, 12]]])
    check('arrival order', solve([[['a', 6, 10], ['a', 4, 11]], 2]), [['a', 4, 6, [11, 10]]])
    check('key separation', solve([[['a', 4, 10], ['b', 4, 11]], 2]), [['a', 4, 4, [10]], ['b', 4, 4, [11]]])
    check('separate sessions', solve([[['a', 4, 10], ['a', 9, 11]], 2]), [['a', 4, 4, [10]], ['a', 9, 9, [11]]])
    check('equal timestamp', solve([[['a', 4, 11], ['a', 4, 10]], 0]), [['a', 4, 4, [10, 11]]])
    check('single event', solve([[['a', 4, 10]], 2]), [['a', 4, 4, [10]]])
    check('empty stream', solve([[], 2]), [])
elif N == 5:
    check('bridge chain', solve([[['a', 5, 10], ['a', 7, 11], ['a', 9, 12]], 2]), [['a', 5, 9, [10, 11, 12]]])
    check('arrival order', solve([[['a', 7, 10], ['a', 5, 11]], 2]), [['a', 5, 7, [11, 10]]])
    check('key separation', solve([[['a', 5, 10], ['b', 5, 11]], 2]), [['a', 5, 5, [10]], ['b', 5, 5, [11]]])
    check('separate sessions', solve([[['a', 5, 10], ['a', 10, 11]], 2]), [['a', 5, 5, [10]], ['a', 10, 10, [11]]])
    check('equal timestamp', solve([[['a', 5, 11], ['a', 5, 10]], 0]), [['a', 5, 5, [10, 11]]])
    check('single event', solve([[['a', 5, 10]], 2]), [['a', 5, 5, [10]]])
    check('empty stream', solve([[], 2]), [])
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
bridge chain[['a', 1, 5, [10, 11, 12]]][['a', 1, 5, [10, 11, 12]]]Passed
arrival order[['a', 1, 3, [11, 10]]][['a', 1, 3, [11, 10]]]Passed
key separation[['a', 1, 1, [10]], ['b', 1, 1, [11]]][['a', 1, 1, [10]], ['b', 1, 1, [11]]]Passed
separate sessions[['a', 1, 1, [10]], ['a', 6, 6, [11]]][['a', 1, 1, [10]], ['a', 6, 6, [11]]]Passed
equal timestamp[['a', 1, 1, [10, 11]]][['a', 1, 1, [10, 11]]]Passed
single event[['a', 1, 1, [10]]][['a', 1, 1, [10]]]Passed
empty stream[][]Passed

SHA-256 / c79db6c9a57305db34ffc3dfbb50fd8878c3f4ef7daef4c836fda12d08bc304d

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

Case digest / 935624bb8ebff322c0d7af196f675cd7e4d96e8cb4de15d4442f772c38d20602