FA-33211 / Menu interactions / Open access
Tearing off a menu discards its invocation context · case 01
Tearing off a menu discards its invocation context.
ROOT CAUSE
The tearoff-menus model applies `{}` at its copy-context operation instead of the stipulated transformation.
VERIFIED REPAIR
Apply `dict(p['context'])` at copy-context.
Unsuccessful approach: The attempted repair `dict(p['ambient'])` still violates the copy-context oracle.
Case contract
A tear-off menu retains a frozen command context while acquiring an independent surface lifetime; its geometry and closure no longer follow the source popup.
Why this case matters
Cascading and context menus require coherent command and session state as content changes.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
import unicodedata
N = 1
observations = []
def solve(action, p):
if action == 'copy-context':
return {}
if action == 'lifetime':
return None
if action == 'translate':
return [p['popup'][0]+p['offset'][0],p['popup'][1]+p['offset'][1]]
if action == 'source-close':
return p['torn'] if p['independent'] else []
if action == 'reattach':
return {'parent':p['destination'],'independent':False,'context':p['context']}
if action == 'closed-record':
return [x for x in p['windows'] if x['id']!=p['id']]
return {'error': 'unsupported menu operation'}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('copy-context contract', solve('copy-context', {'context':{'document':N},'ambient':{'document':N+1}}), {'document':N})
check('lifetime contract', solve('lifetime', {'parent_session':N,'root_session':N+1}), None)
check('translate contract', solve('translate', {'popup':[N,2*N],'offset':[10,20]}), [N+10,2*N+20])
check('source-close contract', solve('source-close', {'torn':[N],'independent':True,'source':['old']}), [N])
check('reattach contract', solve('reattach', {'destination':'menu'+str(N),'context':'doc'}), {'parent':'menu'+str(N),'independent':False,'context':'doc'})
check('closed-record contract', solve('closed-record', {'windows':[{'id':N},{'id':N+1}],'id':N}), [{'id':N+1}])
check('unknown operation', solve('unknown', {}), {'error': 'unsupported menu operation'})
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 |
|---|---|---|---|
| copy-context contract | {} | {'document': 1} | Failed |
| lifetime contract | None | None | Passed |
| translate contract | [11, 22] | [11, 22] | Passed |
| source-close contract | [1] | [1] | Passed |
| reattach contract | {'context': 'doc', 'independent': False, 'parent': 'menu1'} | {'context': 'doc', 'independent': False, 'parent': 'menu1'} | Passed |
| closed-record contract | [{'id': 2}] | [{'id': 2}] | Passed |
| unknown operation | {'error': 'unsupported menu operation'} | {'error': 'unsupported menu operation'} | Passed |
SHA-256 / 7a471724603e493f1d202804cc9b17ff4c11e5a68ba237d4472465c0be7003d9
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
import unicodedata
N = 1
observations = []
def solve(action, p):
if action == 'copy-context':
return dict(p['ambient'])
if action == 'lifetime':
return None
if action == 'translate':
return [p['popup'][0]+p['offset'][0],p['popup'][1]+p['offset'][1]]
if action == 'source-close':
return p['torn'] if p['independent'] else []
if action == 'reattach':
return {'parent':p['destination'],'independent':False,'context':p['context']}
if action == 'closed-record':
return [x for x in p['windows'] if x['id']!=p['id']]
return {'error': 'unsupported menu operation'}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('copy-context contract', solve('copy-context', {'context':{'document':N},'ambient':{'document':N+1}}), {'document':N})
check('lifetime contract', solve('lifetime', {'parent_session':N,'root_session':N+1}), None)
check('translate contract', solve('translate', {'popup':[N,2*N],'offset':[10,20]}), [N+10,2*N+20])
check('source-close contract', solve('source-close', {'torn':[N],'independent':True,'source':['old']}), [N])
check('reattach contract', solve('reattach', {'destination':'menu'+str(N),'context':'doc'}), {'parent':'menu'+str(N),'independent':False,'context':'doc'})
check('closed-record contract', solve('closed-record', {'windows':[{'id':N},{'id':N+1}],'id':N}), [{'id':N+1}])
check('unknown operation', solve('unknown', {}), {'error': 'unsupported menu operation'})
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 |
|---|---|---|---|
| copy-context contract | {'document': 2} | {'document': 1} | Failed |
| lifetime contract | None | None | Passed |
| translate contract | [11, 22] | [11, 22] | Passed |
| source-close contract | [1] | [1] | Passed |
| reattach contract | {'context': 'doc', 'independent': False, 'parent': 'menu1'} | {'context': 'doc', 'independent': False, 'parent': 'menu1'} | Passed |
| closed-record contract | [{'id': 2}] | [{'id': 2}] | Passed |
| unknown operation | {'error': 'unsupported menu operation'} | {'error': 'unsupported menu operation'} | Passed |
SHA-256 / 76a706db351f93ee7dfcf02ec8c490057703c976a38aed50a9e654b6282a303a
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
import unicodedata
N = 1
observations = []
def solve(action, p):
if action == 'copy-context':
return dict(p['context'])
if action == 'lifetime':
return None
if action == 'translate':
return [p['popup'][0]+p['offset'][0],p['popup'][1]+p['offset'][1]]
if action == 'source-close':
return p['torn'] if p['independent'] else []
if action == 'reattach':
return {'parent':p['destination'],'independent':False,'context':p['context']}
if action == 'closed-record':
return [x for x in p['windows'] if x['id']!=p['id']]
return {'error': 'unsupported menu operation'}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('copy-context contract', solve('copy-context', {'context':{'document':N},'ambient':{'document':N+1}}), {'document':N})
check('lifetime contract', solve('lifetime', {'parent_session':N,'root_session':N+1}), None)
check('translate contract', solve('translate', {'popup':[N,2*N],'offset':[10,20]}), [N+10,2*N+20])
check('source-close contract', solve('source-close', {'torn':[N],'independent':True,'source':['old']}), [N])
check('reattach contract', solve('reattach', {'destination':'menu'+str(N),'context':'doc'}), {'parent':'menu'+str(N),'independent':False,'context':'doc'})
check('closed-record contract', solve('closed-record', {'windows':[{'id':N},{'id':N+1}],'id':N}), [{'id':N+1}])
check('unknown operation', solve('unknown', {}), {'error': 'unsupported menu operation'})
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 |
|---|---|---|---|
| copy-context contract | {'document': 1} | {'document': 1} | Passed |
| lifetime contract | None | None | Passed |
| translate contract | [11, 22] | [11, 22] | Passed |
| source-close contract | [1] | [1] | Passed |
| reattach contract | {'context': 'doc', 'independent': False, 'parent': 'menu1'} | {'context': 'doc', 'independent': False, 'parent': 'menu1'} | Passed |
| closed-record contract | [{'id': 2}] | [{'id': 2}] | Passed |
| unknown operation | {'error': 'unsupported menu operation'} | {'error': 'unsupported menu operation'} | Passed |
SHA-256 / f3cd11b16d33b43cf5acd923ee1d2149e5d462947de6a2aec1ae4673003f357a
Verification & scope
Offline supplied-valid-payload model; excludes DOM, keyboard, focus, selection, announcements and browser conformance. 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:42:20.065442+00:00.
Case digest / 845922cf6d94181c2c9d29e9438288e42d324114b973c3e3ccfb6b4ad1c059ce