# 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.
