The Simulator view's "STK menu" block already carries the legend, so the
emerald button's hardcoded "STK: " prefix was redundant. It now shows just
the card's menu title (e.g. "Alfa Mobile"), or "Menu"/"Меню" for a
title-less SET UP MENU (`stkMenuLabel`, unchanged).
The help pages (EN/RU) describe the button as the menu title, both AGENTS
files drop the old `STK: Menu` wording, and stk_menu.test.js gains a source
guard against the prefix returning. sw cache simple-v341.
Tests: 743 Node / 619 Python.
The TERMINAL PROFILE chain parsed the SET UP MENU title with 'tag == 0x05'
only, so the live Alfa card's title (CR-set 0x85, 'Alfa Mobile') was
dropped: /api/menu returned items without a title and the PWA showed
'No menu set by the card' - card-specific only because cards pick the tag
variant (this one sends plain 0x8F items and a CR-set title in the same
command).
- _parse_setup_menu_command (pure, tested with the live FETCH bytes)
replaces the inline parse; the PWA shows a title-less menu as 'STK: Menu'
instead of 'No menu set by the card' (stkMenuLabel, pure).
- _cmd_tlv is now the single lookup helper: exact tag, then tag ^ 0x80
(bit 8 is the CR flag, TS 101 220 7.1.1); the old '| 0x80'-only helper and
the duplicate _cmd_tlv_any are gone.
- Remaining single-style checks fixed: _parse_setup_menu_items (0x8F/0x0F),
_parse_select_item title (0x85/0x05), _find_sms_tpdu (0x8B/0x0B - the
plain variant lost the SEND SHORT MESSAGE PoR TPDU), the response
scripting parsers (R-APDU 0x23/0xA3, executed count 0x80/0x00) and the
FF21 resource tags (0x81-0x83/0x01-0x03).
- tests/test_tag_variants.py flips the CR flag on every top-level tag of
real command fixtures and asserts identical parse results for all
parsers (verified to fail when a single-style lookup is reintroduced).
sw cache simple-v313; tests: 524 Python / 675 Node.
The menu chain paused only for DISPLAY TEXT / SELECT ITEM / SET UP MENU,
so a GET INPUT was auto-answered with a bare success TR and no Text
string - the live RemMobileID PIN prompt got an empty answer.
Server: _parse_get_inkey/_parse_get_input read the prompt, qualifier
flags (digits-only, UCS2, Yes/No, immediate, hidden, packed, help),
Response length 91 and Default Text 9D; the fetch handler pauses with
them; _menu_send_response(..., text=) validates the answer (digits set,
min/max, one char for GET INKEY) and builds the Text string TLV 8D in the
requested coding (SMS unpacked 04 / UCS2 08 / packed 00 via _pack_gsm7),
Yes/No as 01/00, empty input as the null text string, help as result 13
and the variable-timeout Duration echoed (6.8.4). /api/menu-respond
takes text; /api/stk-status carries pending_data so a card-initiated
prompt opens the panel; _decode_cmd decodes both commands.
PWA: stkInputHtml/stkInputHint/stkInputValidate render the constrained
panel (password field for hidden entry, numeric keyboard, default text,
Yes/No buttons, help, immediate-digit auto-submit); OK submits through
stkMenuOk; the poll opens the panel for card-initiated prompts.
sw cache simple-v311; tests: 517 Python / 674 Node.
The live log showed the "stuck" state: after the menu watchdog (60 s)
answered a pending command, the PWA kept the panel; the next click got
{'error': 'no pending command'}, 400 and that reply was fed to the dialog
handler as if it were a card answer. A page reload then cancelled in-flight
polls, flooding the log with BrokenPipeError tracebacks.
- stkMenuRespond detects the already-answered reply (stkNoPendingError) and
closes the panel (stkMenuPanelReset) instead of treating it as an answer;
the 5 s status poll drops the panel whenever the server reports
pending: false, even when the Phone tab is hidden.
- /api/terminal-profile (POST) and /api/rescue finish a pending command
with a cancel TR first, so re-sending the TP can never shadow an
unanswered FETCH.
- _send_json and _serve_static swallow BrokenPipe/ConnectionReset/
ConnectionAborted with one "CLIENT GONE" line (a reload cancels polls);
the handlers' state changes still stand.
Tests: stkNoPendingError + the already-answered respond path; version
3.6.35; sw simple-v308; stylesheet rebuilt.
The STK menu overlay's cached top menu showed the card-provided Items Next
Action Indicator (TS 102 223 8.24) as a gray suffix, but the pending
SELECT ITEM list the card returns mid-dialogue did not: the server already
attaches nai_name (via _parse_select_item), the panel just had its own row
markup without the suffix.
Both lists now render through stkMenuItemsHtml(items, handler) - identical
rows (id, text, optional gray suffix) with the per-list click callback
(stkMenuItemClick / stkSubItemClick).
stk_menu.test.js: the shared renderer (suffix only with nai_name, handler
in the row, null list) plus a call-site guard for both lists.
554 frontend / 421 Python green; version 3.5.6; sw cache simple-v259.
SET UP MENU / SELECT ITEM items carry an optional Items Next Action Indicator
(TS 102 223 8.24, tag '18'): one byte per item, in list order, coded with the
Table 9.4 values marked "Used for Next Action Indicator". The decoder ignored
it, so neither the proactive log nor the STK menu showed what the card would
do when an item is selected.
- server: NAI_TYPES whitelist (the ToC-only values - e.g. '26', '27', '47' -
are reserved there and are ignored, as are '00' and unlisted values),
_nai_name(), _attach_nai() (a short NAI list leaves the tail without an
indicator, extra bytes are ignored); _parse_select_item() and
_parse_setup_menu_items() plus the TERMINAL PROFILE SET UP MENU walk attach
nai/nai_name to the items; _decode_cmd() renders '1. Menu -> SET UP MENU'.
- PWA: stkMenuNaiSuffix() adds a small gray '<name>' suffix to STK menu items
that carry an NAI; the proactive log picks the decode up via cmd_decoded.
- tests: SET UP MENU / SELECT ITEM vectors with NAIs, a reserved value that is
ignored, a short NAI list, and the stkMenuNaiSuffix unit test.
- docs: UICC_SPECS 6.5 gained the '18' Items next action indicator row
(8.24/9.4); help EN/RU mention the menu suffix; AGENTS files updated.
548 frontend / 413 Python green; version 3.5.3; sw cache simple-v255.
The stuck-card pattern: after a Back TR the card re-issues the parent menu
as a new SELECT ITEM (91XX -> FETCH, paused, awaiting TR), but the UI's
back/timeout branch ignored that response and showed the cached top menu;
the next item click then sent ENVELOPE(Menu Selection) while the card was
waiting for the TR. The card answers such an ENVELOPE with 9000 (not the
usual 91XX), and menu-select cleared the pending command without a TR,
leaving an unfinished proactive session until reset/equip.
- server: _finish_pending_menu() answers a paused command with a cancel TR
(0x10) before /api/menu-select sends its ENVELOPE and drains a 91XX
follow-up, so a new selection can never shadow an unanswered FETCH
- frontend: stkMenuRespond('back'|'timeout') renders the follow-up command
from the server response (SELECT ITEM / DISPLAY TEXT) and shows the
cached top menu only when the TR answer carries no command (9000)
- tests: finish-pending cancel TR + chain drain (Python); stkMenuRespond
back/timeout/cancel/ok rendering (frontend); help/AGENTS updated;
SW cache v107 -> v108.