A script's `event` value may be a code (a hex byte or a number) or one of the
server's name keywords (location_status, access_tech, network_rejection,
data_connection, ... - events.py's EVENT_NAMES); the API accepts both. The
PWA parsed every value as a hex string: the step list showed
'EVENT 0xaccess_tech' (the unparsed fallback), the editor fell back to event
03 (Location status) with the location field set, and saving then rewrote
the step to that event - silently corrupting name-authored scripts (the two
Alfa2G trigger scripts use access_tech/data_connection).
A mirrored EVENT_ALIASES map plus an eventCode() resolver (number / hex byte
/ name -> code) now feed the step summary, the editor's event block and the
event check; the summary's fallback no longer prefixes a non-numeric value
with 0x, and the editor keeps its canonical hex form on save (the same code).
Drift guard: the aliases live in frontend/tests/event_vectors.json, asserted
by the Node test (the PWA's map + resolver) and the Python test
(events.EVENT_NAMES + resolve_event). Tests: 856 frontend + 839 Python;
sw cache simple-v419.
The four findings from the review of the 3.15-3.18 batch:
- The event step's `_eventFieldsError` flag is cleared at the start of each
collect: fixing malformed JSON used to leave the save refused until the
editor was closed and reopened. Regression test covers invalid -> fixed.
- The script store keeps an entry that no longer validates on load (a
tightened engine rule or a hand edit): it is served, fails at run start with
the validator's message and can be fixed in the editor, instead of being
dropped from memory and erased by the next save. Mutation paths still
refuse it. (The presets store already had this behaviour.)
- Writebacks are serialized per script (`_testWriteChains`): two quick saves
of an unsaved draft no longer create two server-side scripts - the window
could be minutes while a RAM operation holds the card lock. Regression
test asserts one create + one update.
- Deleting a script cancels its pending debounced save and marks it deleted,
so a queued writeback never resurrects it; a create already in flight is
undone with a delete. Regression test covers the pending-save case.
- The event vectors moved to a shared fixture
(frontend/tests/event_vectors.json) asserted by BOTH suites - a one-sided
builder change now fails the other suite instead of drifting silently.
Tests: 816 frontend + 716 Python; sw cache simple-v383.
The other-applet batch: a test script can send the common event downloads
semantically instead of raw hex.
- events.py: server-side mirrors of the PWA's event forms for Location status
(0x03), Access technology change (0x0B), Network rejection (0x12 - the
LA/RA/TA object selected by the registration group, the extended EMM cause
and the extended information object) and Data connection status change
(0x1D - status/type/TI plus the optional cause, host-clock 8.39 date-time,
location information, access technology, APN and PDP/PDN/PDU type). Fields
are validated before the run (a bad value is a script error, not a step
failure); `src` overrides the device-identities source (default terminal,
matching the Phone forms).
- The engine gains the `event` action kind; the runner builds and sends it.
The PWA's action-kind list stays in sync (drift-guarded - the guard itself
caught its own regex bug on the first run).
- Byte parity: the vectors are generated from the PWA's own builders and
pinned in tests/test_events.py; the frontend suites assert the same values.
PLMN and SCTS helpers are mirrored too.
- The Phone tab's event form shows the built "Event data (hex)" (updated as
the fields change), so every event without a builder can be used through
the raw `envelope` action.
- The test-step editor offers the event select + a JSON fields textarea;
malformed JSON refuses the save with a clear message.
- docs/test-scripts.md (the semantic-event table, an event example, the
format stamp), docs/api.md and help EN/RU updated.
Tests: 812 frontend + 717 Python; sw cache simple-v381.