acdream/memory/project_named_decompilation.md
Erik 0a429a980c docs(workflow): align CLAUDE.md + memory + roadmap with named-retail foundation
CLAUDE.md edits (6 surgical ranges):
  - Goal section: introduce named-retail/ as primary; old chunks
    remain as fallback for chunk-by-chunk address-range navigation.
  - Workflow renamed to "grep named -> decompile -> verify -> port"
    with a new STEP 0 GREP NAMED FIRST. Decompile demoted to a
    fallback (Step 1) for the rare obfuscated/packed minority that
    pseudo-C lacks.
  - Function-map citation updated to point at symbols.json + the
    cross-port hand-curated table.
  - "Do not guess" rule strengthened: PDB has the answer for almost
    everything; guessing is now negligence.
  - Phase completion checklist accepts named symbols + addresses.
  - Reference hierarchy table gets a new top row pointing at
    docs/research/named-retail/ as the primary oracle for any
    AC-specific algorithm — beats every other reference.

memory/project_named_decompilation.md (new): evergreen crib-sheet
with file inventory, grep examples, hard rules. Pattern matches
project_ui_architecture.md.

memory/project_retail_research_index.md: updated preamble to point
named-retail/ as first stop; older slices remain useful for
pseudocode + C# port sketches.

memory/project_collision_port.md: rewrote the "Decompiled ground
truth" section to put named-retail/ first, chunks second. The
"DECOMPILE FIRST" mandate becomes "GREP NAMED FIRST, then DECOMPILE
FALLBACK".

docs/architecture/acdream-architecture.md: Guiding Principle text
updated to introduce named-retail as the primary decomp source.

docs/plans/2026-04-11-roadmap.md: new Phase R block — Retail
research infrastructure. R.1 (corpus, shipped a9a01d8), R.2
(pdb-extract, shipped 69d884a), R.3 (actestclient vendored,
shipped a9a01d8). All marked SHIPPED 2026-04-25.

Auto-loaded MEMORY.md index updated with a new entry pointing at
project_named_decompilation.md so post-compaction sessions inherit
the workflow change automatically.

Acceptance verified:
  - grep -c "named-retail" CLAUDE.md = 9 (>= 3 required)
  - grep -c "named-retail" MEMORY.md = 1
  - dotnet build green (docs-only commit, but verified)

Foundation phases A + B + C all landed. Next: Phase D files
ISSUES #8/#9/#11 + closes #10 (KillerNotification orphan parser).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 17:36:53 +02:00

3.6 KiB

Project: named-retail decompilation foundation

Agreed 2026-04-25. Read once per session. Foundation commits: a9a01d8 (corpus), 69d884a (pdb-extract tool).

What changed

The retail-client decompilation has gone from "FUN_xxx Ghidra chunks + 71 hand-mapped functions" to "18,366 named retail functions + 5,371 named struct types + verbatim retail headers", all committed under docs/research/named-retail/. The acclient.pdb (Sept 2013 EoR build, MSVC 7.00) is the source of truth.

Files at docs/research/named-retail/

File What When to use
acclient_2013_pseudo_c.txt (62 MB / 1.44 M lines) Binary Ninja pseudo-C with 99.6% naming. Address-prefixed lines. Primary symbol lookup. Grep by class::method.
acclient.h (1.7 MB / 70K lines) IDA-decompiled retail headers. Every struct verbatim. Struct field names + offsets. Grep by struct name.
acclient.c (46 MB / 1.3 M lines) IDA full-binary export. Mixed FUN_/named, but has named struct fields. Cross-reference when pseudo-C body is corrupt.
symbols.json (3 MB) 18,366 entries: address + name (demangled Class::Method) + mangled (raw MSVC ABI). Programmatic name↔address lookup via jq.
types.json (506 KB) 5,371 named class/struct records with size + kind. Programmatic type-layout queries.

Workflow change — STEP 0 GREP NAMED FIRST

CLAUDE.md workflow now starts with Step 0 before the older DECOMPILE step:

# Find a function body
grep -n "CEnchantmentRegistry::EnchantAttribute" \
     docs/research/named-retail/acclient_2013_pseudo_c.txt

# Find a struct
grep -n "^struct.*CEnchantmentRegistry" \
     docs/research/named-retail/acclient.h

# Programmatic
cat docs/research/named-retail/symbols.json | \
    jq '.[] | select(.name == "CEnchantmentRegistry::EnchantAttribute")'

The older docs/research/decompiled/ Ghidra chunks remain a fallback for the obfuscated/packed minority that pseudo-C lacks. ~5 second grep replaces ~30 minute archaeology for typical lookups.

Hard rules

  1. Grep named-retail/ first. Always. The "Do not guess" rule in CLAUDE.md is upgraded: with the PDB available, guessing is no longer recoverable error — it's negligence.
  2. Match by name, not raw address. The PDB build has a ~0xC00 byte delta vs the binary that produced our older chunks. Address lookups in symbols.json are correct; the older acclient_function_map.md had several mid-body addresses (issue #9 sweep corrected them).
  3. Regenerate JSON sidecars when needed:
    py tools\pdb-extract\pdb_extract.py refs\acclient.pdb
    
  4. refs/ stays gitignored. It's per-developer download cache; the committed extracts at docs/research/named-retail/ are what subagents and post-compaction sessions inherit.

Counts (Sept 2013 EoR build)

  • 18,366 named public function symbols (S_PUB32, code flag set)
  • 5,371 unique named class/struct types (filtered for non-forward-declared)
  • 1,053 .obj compilation units recorded in DBI
  • Build root preserved in PDB: d:\ac1_sep13\

Why this matters

Closes / unblocks issues #6 (enchantment buffs in vital max — uses CEnchantmentRegistry::EnchantAttribute at 0x594570), #7 (PlayerDescription trailer — uses CPlayerSystem::Handle_PlayerDescription at 0x5636A0), plus reduces the cost of every future port from "30 min archaeology" to "5 sec grep".

  • Plan: C:/Users/erikn/.claude/plans/ticklish-conjuring-cake.md (8-phase foundation)
  • Tool: tools/pdb-extract/ (pure Python, no deps)
  • Reference: docs/research/named-retail/README.md