FAILURE MAP
← Case archive

FA-8696 / Overlay interactions / Open access

Overlay dismissal stack: Clicks on overlay descendants are mistaken for outside clicks · case 01

Clicks on overlay descendants are mistaken for outside clicks.

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

ROOT CAUSE

The inside target operation uses `target != active['id']` where the contract requires `target not in active['inside']`.

VERIFIED REPAIR

Implement the inside target operation as `target not in active['inside']`.

Unsuccessful approach: Reversing membership closes only for internal interactions.

Case contract

Only the topmost overlay handles Escape/outside policy; inside descendants are exempt; explicit unmount removes only its identity.

Why this case matters

A deterministic model of overlay dismissal stack; this isolates one interface invariant without requiring a browser.

1 / The failure

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

N = 1
observations = []
def solve(layers, event, target):
    layers = [dict(x) for x in layers]
    if not layers: return layers
    active = layers[-1]
    if event == 'escape' and active['escape']: return layers[:-1]
    if event == 'outside' and active['outside'] and target != active['id']: return layers[:-1]
    if event == 'remove': return [x for x in layers if x['id'] != target]
    return layers
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('topmost', solve([dict(id='a',escape=False,outside=False,inside=['a']),dict(id='z',escape=True,outside=True,inside=['z'])], 'escape', None), [{'id': 'a', 'escape': False, 'outside': False, 'inside': ['a']}])
check('protected escape', solve([dict(id='a',escape=False,outside=False,inside=['a'])], 'escape', None), [{'id': 'a', 'escape': False, 'outside': False, 'inside': ['a']}])
check('protected outside', solve([dict(id='a',escape=True,outside=False,inside=['a'])], 'outside', 'x'), [{'id': 'a', 'escape': True, 'outside': False, 'inside': ['a']}])
check('inside child', solve([dict(id='a',escape=True,outside=True,inside=['a','child'])], 'outside', 'child'), [{'id': 'a', 'escape': True, 'outside': True, 'inside': ['a', 'child']}])
check('outside', solve([dict(id='a',escape=True,outside=True,inside=['a'])], 'outside', 'x'), [])
check('remove', solve([dict(id='a',escape=True,outside=True,inside=['a']),dict(id='b',escape=True,outside=True,inside=['b'])], 'remove', 'a'), [{'id': 'b', 'escape': True, 'outside': True, 'inside': ['b']}])
check('parameterized stack depth', solve([dict(id=str(i),escape=True,outside=True,inside=[str(i)]) for i in range(N)],'escape',None), [dict(id=str(i),escape=True,outside=True,inside=[str(i)]) for i in range(N-1)])
for repetition in range(N):
    check('repeat remove', solve([dict(id='a',escape=True,outside=True,inside=['a']),dict(id='b',escape=True,outside=True,inside=['b'])], 'remove', 'a'), [{'id': 'b', 'escape': True, 'outside': True, 'inside': ['b']}])
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
topmost[{'escape': False, 'id': 'a', 'inside': ['a'], 'outside': False}][{'escape': False, 'id': 'a', 'inside': ['a'], 'outside': False}]Passed
protected escape[{'escape': False, 'id': 'a', 'inside': ['a'], 'outside': False}][{'escape': False, 'id': 'a', 'inside': ['a'], 'outside': False}]Passed
protected outside[{'escape': True, 'id': 'a', 'inside': ['a'], 'outside': False}][{'escape': True, 'id': 'a', 'inside': ['a'], 'outside': False}]Passed
inside child[][{'escape': True, 'id': 'a', 'inside': ['a', 'child'], 'outside': True}]Failed
outside[][]Passed
remove[{'escape': True, 'id': 'b', 'inside': ['b'], 'outside': True}][{'escape': True, 'id': 'b', 'inside': ['b'], 'outside': True}]Passed
parameterized stack depth[][]Passed
repeat remove[{'escape': True, 'id': 'b', 'inside': ['b'], 'outside': True}][{'escape': True, 'id': 'b', 'inside': ['b'], 'outside': True}]Passed

SHA-256 / 0e196e7661df2986d321372e122b3c006fca700e0d4de749ebd33eceae1a9bbf

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(layers, event, target):
    layers = [dict(x) for x in layers]
    if not layers: return layers
    active = layers[-1]
    if event == 'escape' and active['escape']: return layers[:-1]
    if event == 'outside' and active['outside'] and target in active['inside']: return layers[:-1]
    if event == 'remove': return [x for x in layers if x['id'] != target]
    return layers
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('topmost', solve([dict(id='a',escape=False,outside=False,inside=['a']),dict(id='z',escape=True,outside=True,inside=['z'])], 'escape', None), [{'id': 'a', 'escape': False, 'outside': False, 'inside': ['a']}])
check('protected escape', solve([dict(id='a',escape=False,outside=False,inside=['a'])], 'escape', None), [{'id': 'a', 'escape': False, 'outside': False, 'inside': ['a']}])
check('protected outside', solve([dict(id='a',escape=True,outside=False,inside=['a'])], 'outside', 'x'), [{'id': 'a', 'escape': True, 'outside': False, 'inside': ['a']}])
check('inside child', solve([dict(id='a',escape=True,outside=True,inside=['a','child'])], 'outside', 'child'), [{'id': 'a', 'escape': True, 'outside': True, 'inside': ['a', 'child']}])
check('outside', solve([dict(id='a',escape=True,outside=True,inside=['a'])], 'outside', 'x'), [])
check('remove', solve([dict(id='a',escape=True,outside=True,inside=['a']),dict(id='b',escape=True,outside=True,inside=['b'])], 'remove', 'a'), [{'id': 'b', 'escape': True, 'outside': True, 'inside': ['b']}])
check('parameterized stack depth', solve([dict(id=str(i),escape=True,outside=True,inside=[str(i)]) for i in range(N)],'escape',None), [dict(id=str(i),escape=True,outside=True,inside=[str(i)]) for i in range(N-1)])
for repetition in range(N):
    check('repeat remove', solve([dict(id='a',escape=True,outside=True,inside=['a']),dict(id='b',escape=True,outside=True,inside=['b'])], 'remove', 'a'), [{'id': 'b', 'escape': True, 'outside': True, 'inside': ['b']}])
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
topmost[{'escape': False, 'id': 'a', 'inside': ['a'], 'outside': False}][{'escape': False, 'id': 'a', 'inside': ['a'], 'outside': False}]Passed
protected escape[{'escape': False, 'id': 'a', 'inside': ['a'], 'outside': False}][{'escape': False, 'id': 'a', 'inside': ['a'], 'outside': False}]Passed
protected outside[{'escape': True, 'id': 'a', 'inside': ['a'], 'outside': False}][{'escape': True, 'id': 'a', 'inside': ['a'], 'outside': False}]Passed
inside child[][{'escape': True, 'id': 'a', 'inside': ['a', 'child'], 'outside': True}]Failed
outside[{'escape': True, 'id': 'a', 'inside': ['a'], 'outside': True}][]Failed
remove[{'escape': True, 'id': 'b', 'inside': ['b'], 'outside': True}][{'escape': True, 'id': 'b', 'inside': ['b'], 'outside': True}]Passed
parameterized stack depth[][]Passed
repeat remove[{'escape': True, 'id': 'b', 'inside': ['b'], 'outside': True}][{'escape': True, 'id': 'b', 'inside': ['b'], 'outside': True}]Passed

SHA-256 / 6052ade380cb3beeedcc4e14a3c18cd54e5ba436f2c29bbeaf33450c4d3f46c0

3 / The verified repair

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

N = 1
observations = []
def solve(layers, event, target):
    layers = [dict(x) for x in layers]
    if not layers: return layers
    active = layers[-1]
    if event == 'escape' and active['escape']: return layers[:-1]
    if event == 'outside' and active['outside'] and target not in active['inside']: return layers[:-1]
    if event == 'remove': return [x for x in layers if x['id'] != target]
    return layers
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('topmost', solve([dict(id='a',escape=False,outside=False,inside=['a']),dict(id='z',escape=True,outside=True,inside=['z'])], 'escape', None), [{'id': 'a', 'escape': False, 'outside': False, 'inside': ['a']}])
check('protected escape', solve([dict(id='a',escape=False,outside=False,inside=['a'])], 'escape', None), [{'id': 'a', 'escape': False, 'outside': False, 'inside': ['a']}])
check('protected outside', solve([dict(id='a',escape=True,outside=False,inside=['a'])], 'outside', 'x'), [{'id': 'a', 'escape': True, 'outside': False, 'inside': ['a']}])
check('inside child', solve([dict(id='a',escape=True,outside=True,inside=['a','child'])], 'outside', 'child'), [{'id': 'a', 'escape': True, 'outside': True, 'inside': ['a', 'child']}])
check('outside', solve([dict(id='a',escape=True,outside=True,inside=['a'])], 'outside', 'x'), [])
check('remove', solve([dict(id='a',escape=True,outside=True,inside=['a']),dict(id='b',escape=True,outside=True,inside=['b'])], 'remove', 'a'), [{'id': 'b', 'escape': True, 'outside': True, 'inside': ['b']}])
check('parameterized stack depth', solve([dict(id=str(i),escape=True,outside=True,inside=[str(i)]) for i in range(N)],'escape',None), [dict(id=str(i),escape=True,outside=True,inside=[str(i)]) for i in range(N-1)])
for repetition in range(N):
    check('repeat remove', solve([dict(id='a',escape=True,outside=True,inside=['a']),dict(id='b',escape=True,outside=True,inside=['b'])], 'remove', 'a'), [{'id': 'b', 'escape': True, 'outside': True, 'inside': ['b']}])
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
topmost[{'escape': False, 'id': 'a', 'inside': ['a'], 'outside': False}][{'escape': False, 'id': 'a', 'inside': ['a'], 'outside': False}]Passed
protected escape[{'escape': False, 'id': 'a', 'inside': ['a'], 'outside': False}][{'escape': False, 'id': 'a', 'inside': ['a'], 'outside': False}]Passed
protected outside[{'escape': True, 'id': 'a', 'inside': ['a'], 'outside': False}][{'escape': True, 'id': 'a', 'inside': ['a'], 'outside': False}]Passed
inside child[{'escape': True, 'id': 'a', 'inside': ['a', 'child'], 'outside': True}][{'escape': True, 'id': 'a', 'inside': ['a', 'child'], 'outside': True}]Passed
outside[][]Passed
remove[{'escape': True, 'id': 'b', 'inside': ['b'], 'outside': True}][{'escape': True, 'id': 'b', 'inside': ['b'], 'outside': True}]Passed
parameterized stack depth[][]Passed
repeat remove[{'escape': True, 'id': 'b', 'inside': ['b'], 'outside': True}][{'escape': True, 'id': 'b', 'inside': ['b'], 'outside': True}]Passed

SHA-256 / 15ba81ce96041653330d7722eb8d4b4ef5e335c8b061eb8bdf21fd3f701eb989

Verification & scope

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

Case digest / b93a7c679163ce3b3a9e1affc391dd9ee8ef4c428172b433d9c69248378e84ae