- Python 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Standing instructions any agent (or /loop) reads to make one reliable, committed unit of progress: the prime directive (evidence-earned confidence, never fabricate), the inputs + evidence-engine status, a machine-checkable ordered backlog (static seeder -> ground the cheat anchors -> tracing harness -> pass-1 -> pass-2), the one-iteration protocol with an adversarial self-check, the confidence rubric, hard don'ts, and how to launch/review the loop. README points to it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
| nodes | ||
| seeders | ||
| sources | ||
| .gitignore | ||
| AGENTS.md | ||
| README.md | ||
| schema.md | ||
psp2i-re — a knowledge graph of Phantasy Star Portable 2 Infinity
Reverse-engineering PSP2i (NPJH50332) by building a living, evidence-grounded
map of the binary — not (yet) a decompiled source. The companion to
psp2i-standalone (the working PPSSPP bundle): that repo
keeps the game playable while this one grows understanding, incrementally and
unattended. "Renovate the house while living in it."
Running the RE loop / pointing agents at this? See AGENTS.md — the per-iteration operating manual (rules, backlog, commit protocol) for
/loopand one-off agents.
Why a graph, and why it doesn't drift into slop
The source of truth is the game itself. Every claim is a node tied to evidence
pulled mechanically from the binary or from running it, with a confidence that
is earned from evidence, never self-graded (see schema.md). A
best-guess pass over every function is fine because the guesses stay quarantined
as guess and carry a falsifiable test — the real output of pass 1 is the
testable assertion, not the guess. A node only reaches confirmed when a test
passes.
Two evidence engines
- Static — the Ghidra allegrex project (
from-231/ghidra/psp-allegrex.rep): function list, call graph, xrefs, constants, strings. - Dynamic (the keystone) — PPSSPP is an instrumentable emulator we control:
- emulator-side tracing via its websocket debugger (
--debugger=PORT) + save-states + scripted input — no toolchain needed; - game-side injected debug logging (recompiled into the EBOOT via the PSP SDK) — richer, semantic, later power-up.
- emulator-side tracing via its websocket debugger (
A hypothesis like "0xXXXX is hit detection" becomes a test: load a battle save, script an attack, see which functions fire and which memory changes.
Seed evidence (free ground truth)
- Cheats (
sources/NPJH50332.ini): each working CWCheat code isaddress -> effect. Seeded intosystemnodes byseeders/seed_cheats.py. - Assets (
from-231/fpb-extracted/psp2i-en, 4941 files): file names/types + string xrefs anchor loaders/handlers. (Seeder TODO — needs CRC32->name via tenora-workslist-*.bin.) - Static skeleton: one
functionnode per Ghidra function. (Seeder TODO — runfrom-231/ghidra/export_functions.pyvia analyzeHeadless.)
Layout
schema.md node schema + confidence rubric + the loop
nodes/ one JSON per node (the graph; diffable git history = audit trail)
seeders/ evidence importers (cheats now; static + assets next)
sources/ reference inputs (cheat DB, later: exported function list)
Status
- Schema + confidence rubric
- Cheat-anchor seeder →
systemnodes (money, EXP, damage, frame-timing, aspect, camera, …) - Static skeleton seeder (Ghidra function list + callgraph)
- Asset-anchor seeder (CRC32→name, string xrefs)
- Emulator-side tracing harness (save-states + scripted input + memwatch)
- Pass-1 coverage loop (best-guess + testable assertion per function)
- Injected debug-logging (PSP SDK) — semantic tests
- Unattended loop (local scheduler): test → refine → commit
Run
python3 seeders/seed_cheats.py # (re)generate system nodes from the cheat DB