# Conagent Machine Emulator

## Summary

A host-side Python emulator was added under `analysis/conagent-machine-emulator/`.

The emulator models the backend-facing API surface that `/games/pokemon_pro/conagent` is known to call from static analysis and provides a local browser UI for changing emulated pinball-machine state. It now also includes a small "Extracted Game Calls" runner for representative network/game-session calls found in `/games/pokemon_pro/game` strings.

Generated files:

| Path | Purpose |
| --- | --- |
| `analysis/conagent-machine-emulator/emulator.py` | Dependency-free Python HTTP/HTTPS emulator with web UI. |
| `analysis/conagent-machine-emulator/config.example.json` | Example editable emulator configuration. |
| `analysis/conagent-machine-emulator/README.md` | Usage notes, curl smoke tests, and HTTPS integration notes. |

## Evidence Basis

The emulator endpoints are based on confirmed strings and reconstructed flow in `/games/pokemon_pro/conagent`, documented in [Conagent Reverse Engineering](conagent-re.md):

- `https://%s/api-token-auth/`
- `/api/v1/ping`
- `/api/v1/game/version_upgrades_available`
- `/api/v2/game/heartbeat`
- `/api/v3/game/player_auth`
- `/api/v3/game/game_register`
- `/api/v3/game/game_achievement_descriptors`
- `/api/v3/game/game_auth`
- `http://%s:8345/b8Ag3XU6TH/wibbly_wobbly_timey_wimey/`

The emulator also returns `Message-Number` and `App-Status-Code` headers because the reconstructed HTTP client reads those header fields after requests.

Additional game-call buttons are based on confirmed `/games/pokemon_pro/game` strings:

| Offset | String |
| --- | --- |
| `0x25dd5a8` | `GameSessionBegin` |
| `0x25dd5c0` | `GameSessionUpdate` |
| `0x25dd5d8` | `GameSessionEnd` |
| `0x25de8c0` | `/api/v1/game/high_score_events` |
| `0x25dea50` | `/api/v2/game/machine_audits` |
| `0x25deb88` | `/api/v1/game/game_configuration` |
| `0x25df9d8` | `/api/v2/game/player_achievements` |
| `0x25dfa20` | `/api/v2/game/player_properties` |
| `0x25e03a8` | `/api/v1/game/data_store` |
| `0x25e03f8` | `/api/v1/game/data_retrieve` |
| `0x25e0508` | `/api/v3/game/session_start` |
| `0x25e0568` | `/api/v3/game/session_end` |
| `0x25e05c8` | `/api/v3/game/session_update` |

Score/high-score UI fields are synthetic emulator state, but they are shaped around game strings such as `AD_HIGH_SCORE_1_SCORE`, `AUD_SCORE_HISTO_1`, `AUD_AVERAGE_SCORES`, `PlayerScore`, and `GameScores_Player1`.

## Confirmed Scope

The implementation is host-side support tooling only:

- It does not modify rootfs evidence files.
- It does not execute `/games/pokemon_pro/conagent` or any other target AArch64 binary.
- It emulates backend-facing HTTP behavior, browser-controlled machine state, and synthetic score/session payloads for testing call handling.

## Current Limitations

The emulator does not implement the local `/usr/local/spike/agent.uds` framed game-to-conagent protocol. That protocol remains only partially recovered from static strings, including message IDs, ACK/NACK/reset behavior, and action names.

Scores and sessions produced by this emulator are not recovered from a running game process. They are generated test data intended to exercise the extracted network calls.

Real conagent integration will likely require HTTPS for the API listener because the binary constructs most backend URLs with `https://%s/...`. The special server-time endpoint is plain HTTP on port `8345`.

## Reproducible Commands

Start the emulator:

```sh
cd /Users/jordan/Downloads/pokemon_spike3_rootfs
python3 analysis/conagent-machine-emulator/emulator.py --config analysis/conagent-machine-emulator/config.example.json
```

Smoke-test endpoints:

```sh
curl -s http://127.0.0.1:8088/api/v1/ping
curl -s -X POST http://127.0.0.1:8088/api-token-auth/ \
  -H 'Content-Type: application/json' \
  -d '{"username":"emu","password":"emu"}'
curl -s http://127.0.0.1:8345/b8Ag3XU6TH/wibbly_wobbly_timey_wimey/
```

Run extracted call tests:

```sh
curl -s -X POST http://127.0.0.1:8088/api/game-state/score \
  -H 'Content-Type: application/json' \
  -d '{"player":1,"delta":1234567}'
curl -s -X POST http://127.0.0.1:8088/api/game-calls/run \
  -H 'Content-Type: application/json' \
  -d '{"id":"session_start"}'
curl -s -X POST http://127.0.0.1:8088/api/game-calls/run \
  -H 'Content-Type: application/json' \
  -d '{"id":"session_update"}'
curl -s -X POST http://127.0.0.1:8088/api/game-calls/run \
  -H 'Content-Type: application/json' \
  -d '{"id":"high_score_event"}'
```
