# Next Analysis Targets ## Priority 0: Native playable acceptance and calibration The QEMU/HVF Cocoa game path, loopback `spike3-playfield/v1` bridge, safe pause/restart synchronization, VPX 10.8.1 controller-plugin rebase, generated hardware-contract mapping, clean-room dual-mode VPX table, private controller profile, and native two-window launcher are implemented; see `native-playable-table.md` and `vpx-table-recreation.md`. The default launcher now builds and selects `emulation/vpx-rebuild/dist/PokemonPro_Rebuild.vpx`. The deprecated `emulation/vpx/PokemonPro_Greybox.vpx` is historical evidence that the clean rebuild does not inspect or write; it is not a build input or runtime default. The input transport blockers are now repaired and live-checked. The table uses `VPXActionKey(25..28)`; power-distribution command `0x15` carries active-low Action/Start/door state; CPU-SPI `0-SW-23` is correctly aligned; and service Back/Up/Down/Enter use CPU-SPI `0-SW-8/9/10/11`. Immediate host-event ingestion replaces the broken dependency on node-bus polling. The genuine display accepted service Up/Down/Back, and the guest acknowledged the exact raw states. The final clean table now passes the supervised native startup gate: the 2026-07-20 run reached `Playable cabinet connected`, returned 392 lamp updates, 7 LED frames, and 1 driver pulse, kept both captive optos stable, and delivered QEMU-keyboard coin/Start edges. The launcher now allows 420 seconds because normal game initialization can take about five minutes. The next blocking integration target is a complete normal game and persistence check. If a fresh image enters Guided Setup, complete Save & Exit through the repaired panel, trace any subsequent invalid-machine decision, identify the minimum genuine NVRAM or conagent-backed setup records, persist them across two reboots, and prove the second boot reaches attract mode and accepts Start. The clean table and geometry-free hardware contract pass their static validators. `emulation/vpx-rebuild/qa/runtime-smoke.log` records a bounded VPX 10.8.1 `CaptureAttract` pass on 2026-07-20: it loaded the table and VBS, compiled/started the script, rendered two frames, and closed with exit code 0. The final smoke now matches the current distribution SHA-256 `ddce5d48033ee3c6e67248910a73897293e8b9c36eee29df164160a93572a30e`. It is not interactive play or a substitute for the QEMU-connected acceptance below. After those blockers, continue acceptance and calibration: - Complete and preserve a normal game plus a multiball sequence through the genuine rules on the final clean table, without dashboard ball-motion shortcuts. - Exercise the shooter lane, both orbits, every ramp, both outlanes/returns, pops, QEMU-authoritative slings, Pokedex captive chain, Town VUK, right-ramp hold/Pikachu post, gates, spinner, targets, and Meowth movement with physical VPX balls. Treat contact injection as transport coverage, not shot proof. - Capture exact-address RGB lamp behavior, ordered driver pulses, retained-ball ownership, disconnect fail-safe, and reconnect baselines in one integrated run of the final table. - Record input-to-visible-flipper and bridge-output-to-mechanism p95/p99 from live native traces, plus rendered fps/1% low under simultaneous QEMU load. - Preserve a full 60-minute inventory soak and explicit QEMU, bridge, and VPX restart logs before declaring the long-run acceptance row complete. - Compare `emulation/vpx-rebuild/design/geometry.json` with a physical Pro machine: measure ramp Z/clearance, post and toy footprints, Pikachu post direction/stroke, Meowth crank travel, coil timing, pitch, and ball/rubber behavior. Replace estimated or simulation-tuned values only with recorded evidence. - Acquire a licensed stripped/bare-playfield scan to replace the official registered photograph, whose baked-in hardware and lighting remain visible beneath VPX geometry. Re-run visual and runtime QA after that asset change. - Test QEMU D-Bus shared-memory scanout only after the two-window release is stable. Retain Cocoa rather than adopting a VNC/browser capture fallback if page-flip, 60 fps, or one-frame latency gates fail. The current derived-data inventory and confidence boundaries are summarized in `analysis-evidence-map.md`. This page tracks only the work that remains or still needs stronger validation. ## Priority 1: Main Game Binary Status: first-pass static strings, dependency review, targeted Ghidra decompilation, topper serial-key recovery, a MicroPython emulator artifact, and a Docker/QEMU emulation scaffold are complete; see `main-game-behavior.md`, `topper-serial-key-emulator.md`, and `docker-qemu-emulation.md`. Target: - `/games/pokemon_pro/game` Why: - It is the real machine application started by `game_monitor`. - It interprets hardware state, controls gameplay, and likely talks to SPIKE node hardware. - Exit codes are meaningful and documented in `game_monitor`. Suggested first passes: - Extract strings with offsets. Done: `analysis/static-triage/game.strings`. - Identify linked libraries with an AArch64-aware ELF parser. Done with `objdump -p`; see `analysis/static-triage/game.objdump-p.txt`. - Load into Ghidra/IDA/rizin as AArch64 PIE. Done for targeted paths. - Search for paths from the init scripts: `/connectivity`, `/data`, `/games`, `/dev`, `UPDATE_REQUESTED`, `UPDATE_COMPLETED`, and node firmware filenames. - Search for exit-code constants matching the monitor script: `0` through `6`, plus signal paths. Follow-up passes: - Exercise the new process-level lane documented in `process-level-emulation.md`. Static validation resolves all 51 target runtime libraries and matching `GLIBC_2.39`/`GLIBCXX_3.4.32` nodes; launcher/unit/syntax checks and the Apple Silicon ARM64 container build pass without executing the target. The initial `prepare` run exposed a nested `/games/spike3` alias bug which is now fixed and regression-tested; the post-fix run was blocked by the local Codex Docker approval/usage gate. The next acceptance sequence is `prepare`, `boot-display`, `spike-menu`, then `game`: execute the Mesa FBO smoke test, verify changing noVNC frames on port 6081, nonzero WAV capture, five-minute attract stability, one synthetic-ball Start/flipper/drain cycle from the dashboard, a qemu-user smoke run, and live GDB attachment. Record each failure from the timestamped `emulation/work/runs/` bundle rather than treating source completion as playability. - Continue from `emulation/`: QEMU now boots the generated rootfs, exposes noVNC/dashboard, uses cached rootfs preparation, loads `virtio_gpu`, creates `/dev/dri/card0` plus `/dev/dri/renderD128`, and reaches `boot-display`, `spike-menu`, and `/games/game`. The generated rootfs includes a display probe, `fbdev` fallback interposer, Mesa surfaceless/pbuffer support, synthetic GLES/GBM/EGLImage fallbacks, GPIO sysfs stubs, framebuffer diagnostic renderer, and null ALSA default. Verified captures include nonblank `emulation/work/boot-display-fbo-wrap.ppm`, `emulation/work/spike-menu-gpio-wrap.ppm`, `emulation/work/game-gl-limits.ppm`, `emulation/work/game-fbdev-real-egl.png`, and the earlier diagnostic screen in `emulation/work/game-diagnostic.png`. The prior black-screen, missing-ALSA-default, boot-display framebuffer retry, SPIKE-menu GPIO 25 spam, Mesa loader dependency, and zero-varying shader blockers are cleared. The Docker/VNC softpipe path still encounters the target-created EGLImage/FBO issue and fallback color bands. The native macOS HVF/Cocoa path now has a verified complete 1920x1080 game-frame capture with the opt-in Debian Mesa 22.3.6 llvmpipe stack, although it uses about 5.3 host CPU cores and logs rejected page flips. Other current blockers are TAS/MAX amp register verify reads and bridge/netbridge startup failures (`OpenOCD init failed`, `netbridge image CRC mismatch`, `failed to init bridge thread`). The next display pass should measure llvmpipe frame pacing against softpipe and then investigate an Apple-GPU-backed VirtIO/translation path separately from the working CPU-rendered baseline. - Validate `analysis/topper-emulator/topper_emulator.py` on live hardware or a nodebus capture. - Recover the exact Magikarp topper `IDENTITY_BOARD_PART_ID` expected by command `0xfe`. - Confirm physical UART pins, baud, voltage level, and any netbridge timing/break behavior required for a MicroPython node. ## Priority 2: `image.bin` / Radium Runtime Image Status: first-pass static comparison, whole-rootfs audio search, targeted Ghidra xrefs for the sound path, main-game section 8 PCM table reversal, full main-game section 5 sound command-stream scan, generic section 5 opcode stream decode with payload-field summaries, native opcode length/handler table dumps, section 3 bitmap-record preview extraction, SPIKE menu section 8 PCM parse, SPIKE menu section 5 command-stream scan, Godot `.gdc` string decoding, full main-game WAV export, 54 SPIKE menu WAV exports, 25 Ghidra-confirmed native sound-name aliases, catalog-order offset candidate audit and preview page, 1,137 aligned Pokedex voice aliases, 1,705 draft ASR transcript labels, 169 low-confidence ASR review candidates, complete best-available named alias export, game-asset spoiler/unreleased-feature inventory, and wiki preview pages are complete; see `package-image-firmware.md`, `audio-asset-search.md`, `radium-image-format.md`, `sound-export.md`, `sound-catalog-offset-candidates.md`, `sound-pokedex-voice.md`, `sound-spike-menu.md`, `sound-native-names.md`, `sound-native-sound-test.md`, `sound-asr-draft-labels.md`, `sound-asr-review-candidates.md`, `sound-best-named-export.md`, `asset-previews.md`, `radium-section3-bitmaps.md`, and `game-asset-spoilers-unreleased.md`. Targets: - `/games/pokemon_pro/image.bin` - `/games/pokemon_pro/spike3/spike_menu/image.bin` Why: - `image.bin` is larger than the executable and is probably a resource pack, filesystem image, or application asset bundle used by the game. - The SPIKE menu explicitly copies its `image.bin` to tmpfs because updates may overwrite it while mmap-ed. - `main.pck` has already been extracted into workspace-local `assets/`; see `godot-and-radium-assets.md`. Suggested first passes: - Run `file`, `binwalk`, entropy analysis, and magic-number scans. `file`, `binwalk`, header dump, and first strings completed. - Search for embedded filenames, JSON, SQLite, compression headers, and Godot pack headers. First strings show Stern EULA text; no standard archive signature found by `binwalk`. - Compare structure between game `image.bin` and spike-menu `image.bin`. First 0xb0-byte header shape and early EULA structure are similar, with different size/table values. - Reverse the Radium/cereal mmap image table used by `/games/pokemon_pro/game` strings such as `Flash memory init mmap failed`, `/lcd/demand_loaded`, and `/lcd/auto_loaded`. - Map the remaining Radium sound object IDs and section 8 chunk indices to higher-level script/gameplay names and call sites. Section 8 is decoded as headerless 16-bit PCM chunks, the parser resolves section 5 opcode `0x0b` command-stream references for all chunks, and all chunks are exported as WAVs. A native Godot bridge table confirms names for 25 IDs; Ghidra xrefs to its registration helper are exhausted at those 25 direct calls. Catalog-order comparison now identifies two native anchor offsets, `+69` for EOB Pokedex FX and `+78` for attack-type FX, and writes 199 neighboring unpromoted candidate labels plus one sound-test-candidate disagreement to `analysis/radium-image/catalog_offset_candidate_labels.tsv`. Of those candidates, 196 non-conflicting rows are now used as explicitly marked `catalog_offset_candidate` best-name aliases for sounds that previously had only structural object references. The Pokedex voice stream now maps objects `409` through `1545` to 1,137 semantic Pokemon voice labels. The current ASR pass adds 1,705 draft content labels for bounded voice-like clips, including 220 catalog-matched `SE_PK_VO_*` inferred names across 90 catalog constants, plus 34 low-confidence ASR review aliases for rows that would otherwise remain structural. ASR labels and catalog-offset candidates still need native/script confirmation. - Maintain `analysis/all-sound-best-name-manifest.tsv` as the complete named-export surface. It currently has 2,545 rows: 25 confirmed native names, 1,137 Pokedex voice alignments, 220 catalog-matched ASR aliases, 583 raw ASR draft aliases after stronger-name priority, 196 explicitly marked catalog-offset candidate aliases, 34 low-confidence ASR review aliases, 1 main-image duplicate hash match inheriting a confirmed native name, 295 main structural object fallbacks, 4 SPIKE menu exact-payload matches inheriting stronger main-image names, and 50 SPIKE menu structural fallbacks. The remaining 345 structural rows are also grouped for review in `sound-unresolved-review.md` by bank and duration/channel bucket. Four sound-test-adjacent native label rows are retained for audit, but are not promoted as confirmed best-name labels because their numeric field conflicts with ASR/Pokedex cross-checks. - Continue section 3 image-record recovery. Ghidra xrefs identify section 3 as a 1,477-entry qword pointer table; the current static exporter renders 1,449 raw indexed bitmap records and leaves 28 compact payload records undecoded in `analysis/radium-image/section3_bitmap_manifest.tsv`. Next steps are recovering the compact subtype, confirming palette/alpha semantics, and correlating section 3 records with section 4 or runtime display callers. - Recover SPIKE menu object metadata and higher-level menu names in `/games/pokemon_pro/spike3/spike_menu/game`. The current menu export resolves all 54 section 8 PCM chunks through 300 section 5 opcode `0x0b` references, but only to local object IDs. - Continue decoding compiled GDScript bytecode beyond string recovery if broader script call-site reconstruction is needed. Current static `.gdc` string decoding recovers the 760-name sound catalog and 12 direct Pokedex EOB scene references, but not a general name-to-Radium-object map. - Assign semantics to the non-sound section 5 opcodes now summarized in `analysis/radium-image/command_opcode_payload_summary.tsv`, `analysis/radium-spike-menu-image/command_opcode_payload_summary.tsv`, `analysis/radium-image/opcode_handler_table.tsv`, and `analysis/radium-spike-menu-image/opcode_handler_table.tsv`. The current generic decode confirms clean `0x00`-terminated streams, observed opcodes, fixed payload sizes, common payload values, native handler-address table entries, and that opcode `0x0b` is the sound-reference command, but most non-`0x0b` opcode names still need confirmation from runtime consumers. - Validate the unreleased/deep-feature candidates from `game-asset-spoilers-unreleased.md`: Team Rocket Multiball 3, Pikachu vs. Lucario / Story Wizard 2, Pikachu vs. Magikarp, Eevee Evolution Combos, and Cave/Mountain Top backgrounds. The current evidence is static strings, extracted assets, and candidate sound labels; reachability still needs code-path or runtime confirmation. ## Priority 3: `conagent` Status: first-pass reverse engineering complete in `conagent-re.md`; non-compilable C-like flow export is in `conagent-pseudocode.c`; host-side backend/machine emulator added under `analysis/conagent-machine-emulator/` and documented in `conagent-machine-emulator.md`. Target: - `/games/pokemon_pro/conagent` Why: - It is separately supervised and restarted forever. - Name and `/connectivity` paths suggest Stern Insider Connected or connectivity agent behavior. Suggested first passes: - Strings and URL/domain extraction. - Network syscall/import review. - Trace references to `/connectivity/cache`, `/connectivity/files`, `/connectivity/update`, and hostname handling. Follow-up passes: - Force Ghidra function creation for the stripped text region and rerun decompilation. - Audit `ifup`/`ifdown` command construction and interface-name validation. - Audit direct Game-to-Server endpoint validation. - Audit file-transfer local path validation and update handoff. - Recover enough of the `/usr/local/spike/agent.uds` framed protocol to add a local game-process emulator mode. ## Priority 4: Netbridge Debug Path Status: first-pass strings, ELF program-header review, targeted Ghidra decompilation, host protocol recovery, power-distribution command `0x15` static recovery, a Python host-side emulator scaffold, Docker/QEMU optional serial wiring, and a Pico SDK firmware recreation are complete; see `package-image-firmware.md`, `netbridge-re.md`, and `docker-qemu-emulation.md`. Targets: - `/games/pokemon_pro/spike3/netbridge/netbridge.elf` - `/games/pokemon_pro/spike3/netbridge/spike3-swd.cfg` - `/games/pokemon_pro/spike3/netbridge/rp2040.cfg` Why: - `netbridge.elf` is not stripped and has debug info. - OpenOCD config maps SWD onto Raspberry Pi GPIOs 10 and 11. - This may be the clearest path to understanding lower-level board communication and programming/debug pathways. Findings: - `netbridge.elf` is a 32-bit ARM static executable with code mapped at `0x10000000` and RAM at `0x20000000`/`0x20040000`. - Strings include `uart_node.c`, `NODEBUS_Poll`, `NODEUART_Write`, `UART_NodeRxIrq`, and `WS2812_NodeSetLED`. - Ghidra decompilation identifies the Pi-facing host UART as 2,000,000 baud STX/ETX/ESC framed messages on RP2040 GPIO 16/17, with `0x30` returning firmware CRC `0x357f5327` and `0x41` carrying direct nodebus requests. - Static disassembly of `powerdist_ext.hex` confirms that command `0x15` returns GPIO P0_8/P0_9/P0_11 in bits 0/1/2 and emits an unsolicited sequence-0 report whenever a debounced cabinet input changes. The Python emulator now reproduces both the poll and asynchronous paths. - `analysis/netbridge-emulator/netbridge_emu.py` implements the recovered host frame codec, core bridge commands, CRC response, PTY serving mode, and a stub node at address `0x0a`. - `analysis/netbridge-pico-firmware/` implements the same recovered protocol as a Pico SDK firmware recreation with a portable host-core test. - Docker/QEMU now has an optional `SPIKE3_NETBRIDGE_EMU=1` path that starts the Python emulator on `emulation/work/netbridge.sock`, attaches it as a second PL011 serial, maps guest `/dev/ttyAMA5` to the real serial, and lets the preload shim pass that path through. Follow-up passes: - Run the full Docker path with `SPIKE3_NETBRIDGE_EMU=1` and verify whether the game bridge thread accepts the emulated `/dev/ttyAMA5` device. - Decide whether the OpenOCD programming path should be allowed, replaced with a success stub, or bypassed once CRC command `0x30` is reachable. - Build a Pico UF2 after configuring `PICO_SDK_PATH`, then bench-test it against a host serial harness before connecting it to target hardware. - Validate nodebus timing, break behavior, voltage level, and connector routing on live hardware or a logic-analyzer capture. - Expand the node model beyond the Magikarp/topper-oriented commands once the game requests additional playfield nodes. ## Priority 5: Node Firmware Status: first-pass Intel HEX range parsing is complete for top-level node firmware, and the power-distribution `0x15` input path has been disassembled; see `package-image-firmware.md` and `netbridge-re.md`. Targets: - All `*-LPC*.hex` files under `/games/pokemon_pro`. - `/games/pokemon_pro/spike3/powerdist/powerdist_ext.hex` (input-report path complete; other commands remain open). Why: - These likely define behavior for distributed playfield nodes: coils, LEDs, LCD, magnet sensors, HDMI, TMC drivers, power distribution. - Firmware names expose node families and MCU types. Suggested first passes: - Parse Intel HEX metadata and address ranges. Done for 17 top-level HEX files in `analysis/static-triage/node-firmware-ranges.md`. - Group by MCU family. Initial grouping by filename identifies LPC1112, LPC1113, LPC1124, LPC1313, and LPC812 families. - Disassemble with the correct Cortex-M profile per chip. - Correlate firmware names with harnesses, playfield devices, and game binary strings. ## Priority 6: Update Format Status: first-pass `.sidx` strings/header review complete; see `package-image-firmware.md`. Targets: - `/games/spk/index/pokemon_pro-0_83_0.sidx` - Any available `.spk` update packages outside this rootfs. Why: - `/etc/init.d/update` and `update_monitor` make `.spk` the software update format. - The index file may describe package contents, hashes, versions, or install paths. Suggested first passes: - Inspect `.sidx` with `file`, strings, hexdump, and structured parsers. Done with `file`, `xxd`, and `strings`; 686 package paths were identified. - Compare with any `.spk` available from machine update media or connectivity cache.