Files

Official app compatibility source witness

Source: https://app.meshcore.nz/main.dart.js
Observed: 2026-10-04
Bytes: 9494192
SHA-256: 84bc39a950735aaffa93d912556852a4c22e235d0cc4e4d04790113207f13a68

Run:
  python3 -B test/test_official_app_compatibility.py -v

Requires Node.js 22 and a native C++17 compiler. Linux native fixtures run
under AddressSanitizer and UndefinedBehaviorSanitizer. No PlatformIO or
hardware is used. The complete web application is not copied into Git.

Default external cache:
  ~/.cache/meshcore-tests/84bc39a950735aaffa93d912556852a4c22e235d0cc4e4d04790113207f13a68/main.dart.js

An optional MESHCORE_OFFICIAL_APP_BUNDLE path selects an existing external
bundle. Its bytes and SHA must match. Without that variable, a cold cache
downloads the public source and verifies its exact size and SHA before saving.
CI should use actions/setup-node with node-version 22 and actions/cache for
~/.cache/meshcore-tests, keyed by the full SHA above. The public URL is mutable:
if it changes and no pinned cache exists, the test fails explicitly. Updating
the source pin and function witnesses requires review; it never silently uses
the new app or replaces its parsers with test implementations.

The JS harness extracts and evaluates unmodified compiled app function bodies:
ACL request builder/decoder, CMD50 builder, binary frame parser, SENT/Binary
listeners, CLI response stripping, and all three radio settings screen parsers.
It also executes the app's byte writer/reader and event emitter. Mocked
boundaries are the Dart runtime/type helpers, timer scheduler, transport,
widget state/localization and RNG. The app's schema/tag matching/decoders are
not reimplemented. The deterministic RNG only makes a synthetic request
repeatable; its random value is not the Companion's replay timestamp.

The exact app-generated CMD50 frame goes through the production Companion
command handler and BaseChat request producer. Its real unique-clock-tagged
11-byte plaintext reaches the production repeater receive/ACL handler, with
actual packet budget/admission/serialization. The server's reflected tag and
full padded plaintext then go through the production Companion response
callback, delayed reply owner and bounded serial transport. Only admitted SENT
and Binary frame bytes reach the stock app frame parser/listener/ACL decoder.
The crypto primitive and radio queue are mocked; zero padding reflects the
production cipher block size, not encryption/authentication validation.
The one-admin direct case asserts 11-byte plaintext, 16-byte padded ciphertext,
20-byte payload and 22-byte zero-path wire size. All 32 decoded cases cover
0/1/22/23/24/25/32/256 entries, direct/flood and zero/maximum return path.
Direct replies are bounded to 22 rows: 23 rows create 176 padded plaintext
bytes, exceeding Companion's 174-byte Binary envelope. An explicit historical
23-row negative uses all 176 bytes and verifies that the real Companion callback
admits no Binary frame. Flood replies include their returned path before cipher
padding; their actual padded extra data also passes through the callback.
Large ACLs retain legacy one-packet truncation, not a complete list guarantee.
Actual Companion and CommonCLI radio replies cover saved automatic/explicit
preambles and an active temporary/secondary profile. A fifth field must invoke
each stock app radio screen's existing error path.

The host listener accepts a matching ACL reply 3s into its estimate-2s/+5s
window. Actual firmware callback/SENT deadline behavior is separately exercised
by test_companion_delayed_reply_delivery.py. The global uncorrelated SENT race
is retained as an expected app-level mechanism witness. Neither this synthetic
race nor the newer firmware deadline regression proves the cause of the user's
intermittent Access Control timeout. The successful pre-fix live retry remains
valid. This public web code is not proof of the installed iOS binary/version,
and these native tests do not exercise RF, BLE fragmentation or app UI lifecycle.