FA-32476 / Menu interactions / Open access
Completed empty submenu retains a loading control · case 01
Completed empty submenu retains a loading control.
ROOT CAUSE
The lazy-pages model applies `['loading'] if not p['items'] else p['items']` at its empty operation instead of the stipulated transformation.
VERIFIED REPAIR
Apply `[] if p['done'] and not p['items'] else p['items']` at empty.
Unsuccessful approach: The attempted repair `['more'] if not p['items'] else p['items']` still violates the empty oracle.
Case contract
Lazy submenu pages retain provider order, unique IDs and opaque cursors; loading indicators disappear on final empty results.
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 == 'append':
return p['old']+[x for x in p['page'] if x not in p['old']]
if action == 'cursor':
return p['next']
if action == 'done':
return p['next'] is None
if action == 'empty':
return ['loading'] if not p['items'] else p['items']
if action == 'retry':
return p['failed']
if action == 'footer':
return p['rows'][:-1]+p['page']+[p['rows'][-1]]
return {'error': 'unsupported menu operation'}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('append contract', solve('append', {'old':[N],'page':[N,N+1]}), [N,N+1])
check('cursor contract', solve('cursor', {'next':'cursor'+str(N),'previous':'old','items':[1,2]}), 'cursor'+str(N))
check('done contract', solve('done', {'next':'next'+str(N),'items':[],'limit':20}), False)
check('empty contract', solve('empty', {'done':True,'items':[],'request':N}), [])
check('retry contract', solve('retry', {'failed':'failed'+str(N),'next':'next'}), 'failed'+str(N))
check('footer contract', solve('footer', {'rows':['existing','footer'],'page':['new'+str(N)]}), ['existing','new'+str(N),'footer'])
check('unknown operation', solve('unknown', {}), {'error': 'unsupported menu operation'})
check('retain earlier page', solve('append', {'old':[N-1,N], 'page':[N,N+1]}), [N-1,N,N+1])
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 |
|---|---|---|---|
| append contract | [1, 2] | [1, 2] | Passed |
| cursor contract | cursor1 | cursor1 | Passed |
| done contract | False | False | Passed |
| empty contract | ['loading'] | [] | Failed |
| retry contract | failed1 | failed1 | Passed |
| footer contract | ['existing', 'new1', 'footer'] | ['existing', 'new1', 'footer'] | Passed |
| unknown operation | {'error': 'unsupported menu operation'} | {'error': 'unsupported menu operation'} | Passed |
| retain earlier page | [0, 1, 2] | [0, 1, 2] | Passed |
SHA-256 / e9787b8577713bcb0a98107ae69119dec764a80adc4235052f6d70269d55d21c
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 == 'append':
return p['old']+[x for x in p['page'] if x not in p['old']]
if action == 'cursor':
return p['next']
if action == 'done':
return p['next'] is None
if action == 'empty':
return ['more'] if not p['items'] else p['items']
if action == 'retry':
return p['failed']
if action == 'footer':
return p['rows'][:-1]+p['page']+[p['rows'][-1]]
return {'error': 'unsupported menu operation'}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('append contract', solve('append', {'old':[N],'page':[N,N+1]}), [N,N+1])
check('cursor contract', solve('cursor', {'next':'cursor'+str(N),'previous':'old','items':[1,2]}), 'cursor'+str(N))
check('done contract', solve('done', {'next':'next'+str(N),'items':[],'limit':20}), False)
check('empty contract', solve('empty', {'done':True,'items':[],'request':N}), [])
check('retry contract', solve('retry', {'failed':'failed'+str(N),'next':'next'}), 'failed'+str(N))
check('footer contract', solve('footer', {'rows':['existing','footer'],'page':['new'+str(N)]}), ['existing','new'+str(N),'footer'])
check('unknown operation', solve('unknown', {}), {'error': 'unsupported menu operation'})
check('retain earlier page', solve('append', {'old':[N-1,N], 'page':[N,N+1]}), [N-1,N,N+1])
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 |
|---|---|---|---|
| append contract | [1, 2] | [1, 2] | Passed |
| cursor contract | cursor1 | cursor1 | Passed |
| done contract | False | False | Passed |
| empty contract | ['more'] | [] | Failed |
| retry contract | failed1 | failed1 | Passed |
| footer contract | ['existing', 'new1', 'footer'] | ['existing', 'new1', 'footer'] | Passed |
| unknown operation | {'error': 'unsupported menu operation'} | {'error': 'unsupported menu operation'} | Passed |
| retain earlier page | [0, 1, 2] | [0, 1, 2] | Passed |
SHA-256 / 91305b2337f392c0173bf82ff2d1c2f2dc884d66bba276f475d0028d84afd468
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 == 'append':
return p['old']+[x for x in p['page'] if x not in p['old']]
if action == 'cursor':
return p['next']
if action == 'done':
return p['next'] is None
if action == 'empty':
return [] if p['done'] and not p['items'] else p['items']
if action == 'retry':
return p['failed']
if action == 'footer':
return p['rows'][:-1]+p['page']+[p['rows'][-1]]
return {'error': 'unsupported menu operation'}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('append contract', solve('append', {'old':[N],'page':[N,N+1]}), [N,N+1])
check('cursor contract', solve('cursor', {'next':'cursor'+str(N),'previous':'old','items':[1,2]}), 'cursor'+str(N))
check('done contract', solve('done', {'next':'next'+str(N),'items':[],'limit':20}), False)
check('empty contract', solve('empty', {'done':True,'items':[],'request':N}), [])
check('retry contract', solve('retry', {'failed':'failed'+str(N),'next':'next'}), 'failed'+str(N))
check('footer contract', solve('footer', {'rows':['existing','footer'],'page':['new'+str(N)]}), ['existing','new'+str(N),'footer'])
check('unknown operation', solve('unknown', {}), {'error': 'unsupported menu operation'})
check('retain earlier page', solve('append', {'old':[N-1,N], 'page':[N,N+1]}), [N-1,N,N+1])
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 |
|---|---|---|---|
| append contract | [1, 2] | [1, 2] | Passed |
| cursor contract | cursor1 | cursor1 | Passed |
| done contract | False | False | Passed |
| empty contract | [] | [] | Passed |
| retry contract | failed1 | failed1 | Passed |
| footer contract | ['existing', 'new1', 'footer'] | ['existing', 'new1', 'footer'] | Passed |
| unknown operation | {'error': 'unsupported menu operation'} | {'error': 'unsupported menu operation'} | Passed |
| retain earlier page | [0, 1, 2] | [0, 1, 2] | Passed |
SHA-256 / 5bfca9a8ddb800e3b119f9f1ba50be7331836d94de2996ce55181293459161f6
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:12.592516+00:00.
Case digest / f9be7c6d6ceb1ae8d8c8f00624f20eb2bf072bd9299651b08b5917686a5d1f29