The tab ran real firmware
The esp32sim project is a Rust emulator for ESP32, ESP32-S3, ESP32-C3, and ESP32-C6 chips. Its browser build runs the emulator in a Web Worker. The page reads firmware from hosted files or the visitor's disk.
We opened the hosted hello_world demo. The live console showed the ESP32-S3 mask ROM, the ESP-IDF 5.5.4 second-stage bootloader, the application image, and Hello world!. The page reported WebAssembly execution and an emulated-time counter. That proves the hosted demo completed this path in our browser. We did not build the local command-line tool or attach a board.
A boot log proves a boot path. It does not prove every peripheral, clock edge, or fault.
The repository names its cut lines
At revision 142805d5399e0c3cf25995fe21ba524e75a2b3cb, the peripheral table labels blocks as full, partial, stubbed, or absent. UART, timers, flash, crypto blocks, GPIO, display buses, Wi-Fi paths, and board models have different coverage. Bluetooth and the Wi-Fi radio frequency path are not modeled.
The WebAssembly documentation states that the browser build has no direct network address translation because the tab has no host sockets. Firmware can use the virtual access point and subnet. Traffic beyond the emulated gateway is refused unless a separate relay is used. The same document says the execution timing does not establish cycle accuracy.
Good tests have several witnesses
The project does more than compare one boot log. Its test guide lists decoder fixtures, core semantics, peripheral tests, machine tests, golden firmware runs, WebAssembly smoke tests, and selected comparisons against physical boards. The continuous integration workflow builds the workspace, runs Clippy, executes hermetic and golden tests, builds the WebAssembly module, and runs named firmware manifests under Node.
Those layers support different claims. A decoder fixture checks instruction translation. A golden console checks a known run. A hardware trace checks one board, image, state, and observation path. None of them turns every untested device or physical effect into a match.
Keep six contracts
- Pin the firmware, ROM, bootloader, partition table, emulator revision, and browser build.
- List the CPU, memory map, interrupt path, and every device the test touches.
- State whether time means wall time, emulated time, instructions, cycles, or event steps.
- Record the virtual network, external relay, refused routes, and packet observations.
- Put radio frequency behavior, analog timing, thermal effects, wear, and board-specific faults on the hardware lane.
- Inject one failure. Record the expected output, cleanup, and residue check.
Use the browser as the first lane
A browser emulator can give a coding agent a quick, repeatable firmware loop without a board on every desk. Keep the same image and scripted input for the hardware run. Compare the output that matters to the change, not every line that happens to be printable.
If the change touches a stubbed or absent block, stop treating the browser run as release evidence for that behavior. Move the test to a board. Save both receipts so the next person knows where the emulator ended and the hardware check began.