Update 2.61
6/9/2026
v2.61.0BETA
Seymour
Native menu STEP 3: native-list row source reverse-engineered + `list-read` (probe) + live selection read
- Continuing the native in-game menu lane (Yojimbo→), step-3 gap #1 ("where do the native list's rows come from?") is closed via IDA: the list INPUT (
FFX_Menu_List_UpdateInput 0x8B4460) is 100% generic — pure field math over the 152-byte object (+40state,+48count,+50top,+52target,+58page,+66slots,+69result,+70scroll,+72selected,+28validator), touches no global, and is reused by 10 distinct builders — but every native draw is item-shaped: the scene3 list (FFX_Menu_CreateScene3ScrollableList 0x8B4FB0→ draw0x8B4A00→ row0x8B4B20) reads rows fromunk_159EC30[64*i](64-byte structs) +byte_1866250[](type), with the item name resolved by0x86C3C0(id→table)and an optional direct label atrowPtr+32(type 1); it loads scene3/33/34 and depends on Customize globals. There is no "free-text list" draw in the binary — so a native list with OUR text (the arena / Aurora Photo-Mode shell) requires a DLL draw callback (step 5, the path foreseen in tick-bible §4), with the hand-rolled recipe documented (generic input0x8B4460+ a DLL draw usingsub_8F5F70window /sub_9016B0string /sub_8C0640cursor, reading+69/+72). Shipped via probe TODAY: new verbffxprobectl list-read [handleHex](READ-only) that scans the menu-object POOL (g_FFX_MenuObjPool 0x18408C0, 32 slots × 152B) — finds ANY active native list/popup and identifies it by its callbacks — plus the shortcut "current list" globals (dword_1866214/186A5DC/23CC120). ✅ RT2 PASS (live, 2026-06-09): with the game in the Customize equipment menu, the pool scan caught the navigated list (slot[3]@0x017A0A88,input=0x8D57E0, a thin wrapper of the generic0x8B4460) and+72/SELECTEDtracked the cursor in real time (35→42) as the operator moved it → step-3 "read the selection of a native navigable list" PROVEN without writing anything. (Bonus: the reset object's+62 = group 0x101matchesFFX_MenuObj_Reset(IDA) — offsets confirmed against memory.) No camera RAM / Aurora /dllmain.cpp/ save touched; IDA read-only (_claude_idacopy, rename-queue in the doc).ffxprobectlbuild 0 errors. Step 5 (blueprint): paste-ready skeleton of the native shell atRuntimeTools/NativeMenuShell/NativeMenuShell.h(+README) — object hand-roll + draw callback (window+rows+cursor) + FFX font encoder + decoupled bridge to Aurora's Photo Mode actions; ABIs/offsets confirmed (IDA verify workflow) and adversarially reviewed (2 lenses FFX-vs-IDA + C++ → no crash/compile blocker); x86 guard + anti-OOB clamp + load-bearing invariants annotated; not wired, does not touchdllmain.cpp. Step 5.1 (wire blueprint, NOT applied): plan + patch draft (docs/ai/HANDOFF_BAHAMUT_NATIVE_MENU_WIRE_BLUEPRINT_2026-06-09.md+docs/patches/BAHAMUT_NATIVE_MENU_WIRE_DRAFT_2026-06-09.patch) wiring the shell intoffx-hooks.dllvia a detour on the menu pumpFFX_Menu_PerFramePump 0x8A9C50(int __cdecl(uint), IDA-verified, main-thread) — OFF by default (FFXHOOKS_ENABLE_NATIVE_MENU+ F7 hotkey), bridge only callsPhotoMode::*; adversarially reviewed (2 lenses) no blocker (compile reviewer applied it to a scratch tree,git apply --recount --checkexit 0);dllmain.cppNOT touched/committed. Doc:docs/reverse/FFX_NATIVE_MENU_LIST_ROW_SOURCE_2026-06-09.md
v2.60.2
v2.61.1BETA
Seymour
Atlas Gear Shop slot value-guard (`proved-candidate`) + item-shop honestly `blocked`
- Second pass of the Shop scout (
HANDOFF_ATLAS_RIKKU_SHOP_SLOT_VALUE_INDEXER): unlock the SAME value-guard for Shop that Treasure already proved. Verified by an 8-agent workflow (5 forensic + 2 adversarial + 1 synthesis): the editor's slotRawValueis the raw on-disk little-endian ushort (ShopTable_File≡ReadBaselineSlotValue), andgear_shop_slots.csv'sslot_value_hex(445/445 populated, theshop_arms.binindex) is that same word — so the guard is a same-space integer compare with no off-by-one (the catalog isMinIndex=0, index 0 = reserved NULL entry, first sellable gear = index 1 =0x01). New read-only accessorSpiraDataAtlasCatalog.TryGetShopGearSlot(bank, slot, currentRawValue)+ lazy_shopGearSlotValues(devwork/only, no compiled fallback, like the Sphere Grid node detail): resolvesatlas:gear:gear-shop-0x{bank}-slot-{n}only while the slot's current value still equals the corpus (and ≠ 0) → editing the slot hides the badge (no stale). The--spiraatlas-rt0gate gained 5 durable asserts (positive lookup Tidus/value 1, value-guard mismatch 999 hides, empty slot raw 0, bank-without-corpus, edge0x2E/427), all PASS. Item-shop =blocked: the corpus does not carry the raw value (item_shop_slots.csv.slot_value_hex100% empty —ItemShopDataObject.toString()prints only the name); a string-guard is NOT fake-safe (Potion/Phoenix Down/Antidote x47 → stale; placeholders + US-vs-JP → false negatives). Unlock = 1-line parser patch + re-run (corpus task, outside this code). Honest tier:proved read-only candidate (parser-corpus + reader-semantics + RT0), neverruntime/byte-grounded(noarms_shop.binwas hexdumped here). No UI, writer, SIN, runtime, orCommonbadge-engine changes (ANIMA). Build 0 errors / 361 warnings;--spiraatlas-rt0+--aicmdmeta-rt0PASS. Doc:docs/ai/ATLAS_RIKKU_SHOP_SLOT_VALUE_INDEXER_RESULT_2026-06-09.md
v2.61.0
v2.61.2BETA
Seymour
Atlas evidence badge in the Shop Explorer (gear-only, value-guarded)
- Read-only UI wiring the
TryGetShopGearSlotaccessor (proved inv2.61.1) intoShopExplorer: each gear-shop slot shows<common:AtlasEvidenceBadgeStrip>with the origin/badges/"where it appears" of that slot's gear reward — only while the slot's currentRawValuestill matches the corpus.ShopEditableSlotRow.Evidence(init) is computed inFrom():source.Kind == Gear && TryGetShopGearSlot(entry.Index, slot.SlotIndex, slot.RawValue). Since the row is rebuilt on EVERY mutation (ComboBox/Set Empty/Undo/Discard/Save/Refresh →RebuildSelectedSlots), editing the slot recomputes the evidence and hides the strip (no stale badge). Item-shop never gets a badge (Kind == Gearguard + double-guard: item has no corpus entry); an empty slot (raw 0) short-circuits. Verified by a 3-lens adversarial workflow (exhaustive lifecycle / item-shop+binding / honesty) → allsound, 0 defects. Reuses ANIMA'sCommoninfra (engine untouched); no new writer, no new parser, no SIN/runtime/Aurora/native-menu. Tierparser-corpus+RT0+read-only, never runtimeproved. Build 0 errors / 361 warnings;--spiraatlas-rt0+--aicmdmeta-rt0PASS (no--shop*gate inProgram.cs). Doc:docs/ai/ATLAS_RIKKU_SHOP_GEAR_BADGE_UI_RESULT_2026-06-09.md
v2.61.1
v2.61.3BETA
Seymour
Atlas provider: normalized `BlitzballPrizeRef` (read-only) replaces the 76-line raw scrape
- The
SpiraDataAtlasCatalogprize section no longer scrapes rawbltz0200/0201; it now reads WAKKA's normalized dataset (work/step0_blitzball_prize_ref_2026-06-09): 164 prize-index rows (101 treasureproved-candidateviaprize+220 -> takara 220..320 -> reward, closed by 3 offline sources — Fahrenheitblitz_prize.cs+bltz0201 obtainTreasure+bltz0200/0201 Treasure-Label— over RT0-proved takara; 60 techpartial; 3 overdrivemetadata-only) + 64blockedscript-sites (the per-event prize is a runtime/save variable). Guardrail rewritten: ruleproved-candidateoffline, the concrete per-league/tournament prizeblocked, never RT2, never a writer. The--spiraatlas-rt0gate went from14739to14891details (BlitzballPrizeRef 76 -> 228) and gained data-grounded asserts (treasure 101 / tech 60 / overdrive 3 / sites 64; prize 0 -> takara 220 Hi-Potion; prize 100 -> takara 320 Phoenix Down; treasureproved-candidate-not-RT2; overdrivemetadata-only; siteblocked). Patch verified by a 4-agent adversarial review before apply. No UI, no writer, no SIN/runtime; does not touch Shop/Treasure/Mix (RIKKU), theCommonbadge engine (ANIMA), or Aurora/native-menu. Build 0 errors / 361 warnings;--spiraatlas-rt0+--aicmdmeta-rt0PASS. Doc:docs/ai/ATLAS_WAKKA_BLITZBALL_PROVIDER_INTEGRATION_RESULT_2026-06-09.md
v2.61.2
v2.61.4BETA
Seymour
Native Menu Shell WIRED into `ffx-hooks.dll` (step 5 applied, OFF by default)
- The step-5.1 patch (adversarially reviewed, no blocker) is now applied to
dllmain.cpp(minimal patch:dllmain.cppONLY, +166 lines, 0 deletions) — it wiresNativeMenuShell.h(native menu with OUR text) to Aurora's bridge (PhotoModeActions.h) via a detour on the menu pumpFFX_Menu_PerFramePump 0x8A9C50(int __cdecl(uint), IDA-verified, MAIN THREAD). OFF by default:FFXHOOKS_ENABLE_NATIVE_MENU=1arms the detour; the menu only opens on the F7 hotkey. Aurora's contract ACCEPTED and followed:PhotoMode::Tick()= Option A (top ofAuroraD3DRender, before the early-return, withFFXHOOKS_ENABLE_AURORA_OVERLAY=1, AURORA-owned hunk); FREEZE single ownerg_pm.frozen;NtSuspendProcessPROHIBITED;PhotoMode::g_base=g_basein init. The wire only callsPhotoMode::*— it does not write camera RAM (0xD378A0) or actor RAM. Build-WithPolyHook -ReleasePASS (dllmain+MusicHook+ElementHook→ffx-hooks.dll). Step 6A/NPC kept OUT of this patch. RT2-pending: F7 inside a menu/field → native "PHOTO MODE" shell should appear (discardable save). Doc:docs/ai/HANDOFF_BAHAMUT_NATIVE_MENU_WIRE_BLUEPRINT_2026-06-09.md
v2.61.3
v2.61.5BETA
Seymour
Atlas evidence badge in the Item Shop (value-guarded) — closes the gear+item pair
- Clones the gear-shop value-guard proved in
v2.61.2to item-shop, now thatv2.61.1+ the corpus unlock gave item a byte-grounded 1:1 raw value. New read-only accessorSpiraDataAtlasCatalog.TryGetShopItemSlot(bank, slot, currentRawValue)+ lazy_shopItemSlotValues(readsitem_shop_slots.csv, devwork/only, no compiled fallback) — an exact mirror ofTryGetShopGearSlot: resolvesatlas:item-shop:item-shop-0x{bank}-slot-{n}only while the slot's currentRawValuestill matches the corpus (the on-disk LE ushort = Items game-index0x2xxx, the editor's space) and is ≠ 0.ShopExplorer_DataModelnow computesEvidenceper shop kind (Gear/Item switch); the<common:AtlasEvidenceBadgeStrip>in the slot card was already shared (v2.61.2), so item slots now show the badge with no XAML change; editing the slot rebuilds the row and hides the strip (no stale). The--spiraatlas-rt0gate gained 4 item asserts (lookup0x2000/Potion, mismatch0x9999hides, empty raw 0, no-corpus slot 3), all PASS (gear still PASS). Regeneratedwork/step0_consolidated_v5/item_shop_slots.csvwithslot_value_hex(404/404, dev-only, not committed). Read-only: no writer, no Treasure/Mix/Common/Aurora/native-menu/runtime changes; ANIMA'sCommonengine only consumed. Build 0 errors / 361 warnings;--spiraatlas-rt0+--aicmdmeta-rt0PASS. Doc:docs/ai/ATLAS_RIKKU_SHOP_ITEM_BADGE_UI_RESULT_2026-06-09.md
v2.61.4