[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6JZSEPDQDGTHE3AX1JHASNH":3,"skill-same:01M6JZSEPDQDGTHE3AX1JHASNH":70},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":41,"linkOnly":42,"markdownContent":43,"markdownBody":44,"frontMatter":45,"refName":47,"commitSha":48,"skillDirectory":49,"forksCount":50,"repositoryHtmlUrl":51,"repositoryHomepageUrl":6,"ownerHtmlUrl":52,"ownerBlogUrl":53,"ownerDescription":54,"updatedAt":55,"install":56,"resources":69},"01M6JZSEPDQDGTHE3AX1JHASNH","audit-esm",null,"Deep audit of the ESM\u002FESP plugin parser — GRUP walk, sub-record byte accounting, per-record schemas, FormID remap, CELL\u002FWRLD walkers, ESM→ECS handoff","matiaszanolli\u002FByroRedux","matiaszanolli","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F2379093?v=4","01M6JZJDYMPY01793W4XK157YG","Matias Zanolli","01M6JZJE2KE2BXSDPAYPQC6BSH",39,"MIT","https:\u002F\u002Fgithub.com\u002Fmatiaszanolli\u002FByroRedux\u002Fblob\u002Fmain\u002F.claude\u002Fcommands\u002Faudit-esm\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000040","财务","PROFESSION","适用职业",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40],"audit","esm","audit esm","depth","cell","accounting","name","plugin","record","handoff","ecs","parser","focus","game","dimensions","ESP","deep","2026-11-10 10:12:30",false,"---\ndescription: \"Deep audit of the ESM\u002FESP plugin parser — GRUP walk, sub-record byte accounting, per-record schemas, FormID remap, CELL\u002FWRLD walkers, ESM→ECS handoff\"\nargument-hint: \"--focus \u003Cdimensions> --game \u003Cname> --depth shallow|deep\"\n---\n\n# ESM \u002F Plugin Parser Audit\n\nAudit `crates\u002Fplugin\u002F` (~84k LOC in `src\u002F`) as a parser: GRUP walker, sub-record byte\naccounting, per-record schema dispatch, FormID load-order remap, CELL\u002FWRLD walkers, and\nthe `EsmIndex` → ECS handoff. Per-game audits (`\u002Faudit-fnv`, `\u002Faudit-skyrim`, …) each\nsample one game's slice; this skill owns the parser itself.\n\n**Architecture**: Orchestrator. Each dimension runs as a Task agent (max 3 concurrent).\n\nRead `.claude\u002Fcommands\u002F_audit-common.md` and `.claude\u002Fcommands\u002F_audit-severity.md` for\nshared protocol (dedup, methodology, finding format). Do not duplicate them here.\n\n## Scope\n\n**Crate**: `crates\u002Fplugin\u002Fsrc\u002F` — `esm\u002Freader.rs` (`EsmReader`, `EsmVariant`, `GameKind`,\n`FormIdRemap`, `GlobalSlot`, zlib decompression), `esm\u002Fsub_reader.rs` (`SubReader`),\n`esm\u002Frecords\u002F` (`parse.rs` = the top-level GRUP walker `parse_esm[_with_load_order]`;\n`mod.rs` is a re-export barrel; `index.rs` `EsmIndex`; eight `dispatch_*.rs` routers;\n`grup_walker.rs`; per-type decoders incl. `actor\u002F`, `items.rs`, `items\u002Fconsumable.rs`,\n`container.rs`, `condition.rs`, `weather.rs`, `weather_settings.rs` + `weather_settings_instance.rs`\n(Starfield `WTHS` schema + values), `load_screen.rs`, `pkin.rs`, `misc\u002F*.rs` incl. `story_manager.rs`,\n`location.rs` (`LCTN`), `relationship.rs` (`RELA`), `challenge.rs` (FNV `CHAL`), `music.rs` (`MUSC`; Skyrim `MUST` since `03f9d2158`, #3816 piece 1),\n`lmsw.rs` (Starfield `LMSW`\u002F`MTPT` reflection blobs), `reflection.rs` (the BGS reflection container decoder shared by `WTHS`\u002F`LMSW`\u002F`MTPT`, moved out of `weather_settings.rs` by `ce5796431`, #6272; public paths unchanged via re-exports)),\n`esm\u002Fcell\u002F` (walkers `walkers.rs`, `support.rs`, `wrld.rs`, `helpers.rs`; `mod.rs` is a re-export hub over the\ndata tier `base_objects`\u002F`cell_data`\u002F`index`\u002F`landscape`\u002F`lighting`\u002F`placed_ref`\u002F`worldspace.rs`, `d7c47d741`),\n`esm\u002Fstrings_table.rs`, `equip.rs`, and the Redux-native tier\n(`datastore`\u002F`manifest`\u002F`record`\u002F`resolver`).\n\n**Not in scope**: cell-loader consumption of `CellData` (`\u002Faudit-\u003Cgame>` Dim 1); VMAD\ntranslation (`\u002Faudit-scripting`); NIF (`\u002Faudit-nif`); BSA\u002FBA2\u002FCSG incl. the FO4 previs\nheader → cell-grid recovery (`\u002Faudit-parsers`); `src\u002Fextension.rs` + `crates\u002Fsdk` extension\nmanifests (`\u002Faudit-tooling`); WTHR\u002FCLMT\u002FWATR\u002FLTEX\u002FGRAS *translation* and HNAM sun\nconsumption (`\u002Faudit-exterior` — byte-level decode of those records stays here);\nconsumption semantics of `src\u002Fconsumables.rs` \u002F `expand_leveled_loot` (`equip.rs`) —\ntimed restoratives, container loot, LSCR selection (`\u002Faudit-gameplay`; the decode contract\nstays here, Dim 4); CHARAL formulas (`\u002Faudit-character`).\n\n**Ground truth**: `docs\u002Fengine\u002Fplugin-loading.md`, `docs\u002Fengine\u002Fesm-records.md`,\n`docs\u002Fengine\u002Fpipeline-overview.md`. Every non-obvious decode should cite a\n`wbDefinitions{TES4,FNV,TES5,FO4,FO76,SF1}.pas:line` range (crate docstring in\n`crates\u002Fplugin\u002Fsrc\u002Flib.rs`); a decode with no citation and no test is a guess\n(*feedback_no_guessing*) — flag it.\n\n## Parameters (from $ARGUMENTS)\n\n- `--focus \u003Cdimensions>`: comma-separated dimension numbers. Default: all 8.\n- `--game \u003Cname>`: restrict Dim 8 real-data validation to one game. Default: every game\n  with on-disk data (`_audit-common.md` § Game Data).\n- `--depth shallow|deep`: `shallow` = schema\u002Fcontract check; `deep` = byte-level trace\n  against real masters. Default `deep`.\n\n## Extra Per-Finding Fields\n\n- **Dimension**: Header & GRUP Walk | Sub-Record Byte Accounting | FormID & Load Order |\n  Record Schema Dispatch | CELL \u002F WRLD Walkers | Localized Strings | ESM→ECS Handoff |\n  Real-Data Validation\n- **Record \u002F Sub-record**: 4-char code(s) (e.g. `NPC_` \u002F `ACBS`), or `—`.\n\n## Phase 1: Setup\n\n1. Parse `$ARGUMENTS`. `mkdir -p \u002Ftmp\u002Faudit\u002Fesm`.\n2. `gh issue list --repo matiaszanolli\u002FByroRedux --limit 200 --json number,title,state,labels > \u002Ftmp\u002Faudit\u002Fesm\u002Fissues.json`.\n3. Read the latest `docs\u002Faudits\u002FAUDIT_ESM_*.md` plus the ESM dimensions of the latest\n   `AUDIT_{FNV,SKYRIM,FO4,STARFIELD}_*` reports — this crate's findings historically live\n   there, so **that is where your duplicates are**.\n4. `cargo test -p byroredux-plugin`; record the pass count (a pre-existing failure is\n   context, not a finding). **Never run `--ignored` \u002F `--include-ignored` on this crate**\n   — the real-data tests parse whole masters (Starfield ≈ 4 GB parsed) and have\n   OOM-killed sessions past 20 GB; use Dim 8's single-file probes instead.\n\n**Suggested emphasis**: the 2026-08 → 09-11 reports yielded mostly Localized Strings,\nESM→ECS Handoff, CELL\u002FWRLD and FormID remap; the 2026-09-21 report's MEDIUMs were Byte\nAccounting (Oblivion `LVLO`\u002F`LVLD`, FO4 `TERM`, `LTEX.GNAM`) and Header\u002FGRUP (inflation\nceiling, skip-arm clamp), all found by Dim 8's real-data census — run it, don't skip it.\nThe 2026-09-29 report's MEDIUM\u002FLOWs were again Byte Accounting + FormID: non-FormID `u32`s\nfed to the remap (FO4 `TRDA` `FFFF` sentinel, Oblivion `EFID` char4 codes), fixed in\n`9b099b31f` (#5075\u002F#5076) — see Dim 3 shape (4). The 2026-10-08\u002F10-09 MEDIUMs were decodes that\ncontradict their own `wbDefinitions*.pas` entry (SM `SNAM`\u002F`RNAM`, REGN `WNAM`, PKIN `VNAM`,\nSCOL\u002FPKIN `FLTR`, `PKDD` Dialogue Type offset — all since fixed, #5493 `136048a95` \u002F #5492 `dae08000d`) — open the xEdit definition for every decoder\ntouched since the last report rather than trusting its doc comment.\n\n## Phase 2: Dimensions\n\n### Dimension 1: Header Detection & GRUP Walk (highest blast radius)\nPaths: `crates\u002Fplugin\u002Fsrc\u002Fesm\u002Freader.rs`, `esm\u002Frecords\u002F{parse,grup_walker}.rs`\nFirst step: `grep -rn 'group_content_end(' crates\u002Fplugin\u002Fsrc | grep -v 'tests\u002F\\|\u002F\u002F\u002F'`\n**Why first**: a header-size or GRUP-bounds error desyncs the whole file; everything\ndownstream decodes structurally valid garbage.\n**Guards** (run, confirm live — not `#[ignore]`d, not vacuous):\n`reader::tests::game_kind_from_header_maps_real_master_hedr_values`,\n`grup_walker::tests::every_recursive_grup_walker_honours_the_shared_depth_cap` (table of\nwalkers nested past `MAX_GRUP_NESTING_DEPTH`; a walker missing from the table is invisible\nto it — `EsmReader::for_each_record`, the bounded walk the census\u002Fprobe examples share since\n`0b3ae0d13` (#5819), is not in it and is pinned only by\n`reader::tests::for_each_record_filters_recurses_and_skips_unwanted`), `reader::tests::bounded_group_content_end_clamps_to_parent_end`, and the\n`compressed_record_*` \u002F `inflation_ceiling_clears_every_observed_vanilla_shape` tests.\n**Checklist** (what the guards cannot see):\n- `EsmVariant::detect` (`data[20..24] == b\"HEDR\"` ⇒ 20-byte Oblivion headers) has its\n  length guard before the slice; no caller hardcodes a variant outside tests \u002F\n  `with_variant`.\n- `GameKind::from_header(variant, hedr_version, record_version)` uses **banded** float\n  compares plus the TES4 record version as a second key (Skyrim LE and FO3 GOTY both stamp\n  HEDR 0.94 → record version 40 vs 2; FO4 DLC 0.95 → 131). Vanilla HEDR: FO3 0.94, FO4 1.0,\n  Starfield 0.96, FNV 1.34, Skyrim SE 1.71, **FO76 — a live-service value that drifts with patches** (68.0 → 266.0 → 279.0 → 280.0 \u002F record version 210 as of 2026-11-08, #6779; floor 60.0). A mis-band is not\n  latent: FO4-only arms in `items.rs` (`ARMO DATA` swaps value\u002Fweight\u002Fhealth order at the\n  same 12-byte length, `WEAP DATA` empty, `BOOK` 8-byte) would silently swap armor stats\n  and zero every weapon. Any new per-game schema split widens this blast radius — check.\n- Missing\u002Fshort HEDR falls back to `GameKind::Fallout3NV` (`Default`): confirm each call\n  site is deliberate and no branch treats \"defaulted\" as \"detected FO3\". `character_rules_profile`\n  reads `hedr_version == 0.0` as defaulted, so only a real 0.85\u002F0.94 header picks the FO3 profile (`dc771cf59`, #6780).\n- **Universal GRUP bound** (#3503\u002F#3721\u002F#4076\u002F#4644): every self-recursive walker takes\n  `bounded_group_content_end(header, depth, parent_end, name)` and threads `depth + 1`\n  into its `_inner`; **skip arms** too seek to the parent-clamped end via `seek_to` (the\n  depth-cap arm inside `bounded_group_content_end` included). The raw `group_content_end`\n  may appear only in the non-recursive top-level loop (`records\u002Fparse.rs`, the only\n  `skip_group` caller), `cell\u002Fwrld.rs::parse_wrld_group` and `grup_walker.rs::walk_info_records`'\n  nested-group skip (both `.min(end)` themselves). Regression = a new recursive walker on\n  the raw accessor, a dropped `depth`, or a recurse\u002Fskip site that loses the `parent_end`\n  clamp (guards `overrunning_child_grup_in_a_skip_arm_seeks_to_parent_end`,\n  `bounded_group_content_end_depth_cap_skip_is_parent_clamped` pin fixtures, not every site).\n- `FLAG_COMPRESSED`: `data_size >= 4` checked before the subtraction; declared size is\n  bounded by `record_inflation_ceiling` (`min(64 MiB, max(64 KiB, compressed×2048))`, from a\n  seven-master census — worst real ratio 785.9:1, a Starfield `SFTR`, #4640; 512:1 rejected\n  82 vanilla records and dropped the whole plugin) and the decoder is held to\n  `take(declared + 1)`; mirrors `byroredux_bsa::safety::inflate_bounded` (#3410).\n  Regression = either bound removed or the two implementations diverging.\n**Output**: `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_1.md`\n\n### Dimension 2: Sub-Record Byte Accounting (densest bug class)\nPaths: `crates\u002Fplugin\u002Fsrc\u002Fesm\u002Fsub_reader.rs`, `esm\u002Frecords\u002F**\u002F*.rs`, `esm\u002Fcell\u002Fsupport.rs`\nFirst step: `git log --since=\u003Clast report> --name-only --format= -- crates\u002Fplugin\u002Fsrc\u002Fesm\u002Frecords | sort -u` (decoders touched since the last report), then re-derive their widths from the cited xEdit range.\nESM analogue of `\u002Faudit-nif` Dim 1: a wrong field width shifts every later field and the\nrecord still \"parses\" with wrong numbers.\n**Guard**: `records::test_support::tests::no_module_redeclares_a_local_subrecord_builder`\n(fixture hygiene only — nothing here guards decode widths; since #5454, `29f8fa2ef`, it flags\nany fn returning `SubRecord` built from a parameter 4-CC, not only fixed names).\n**Checklist**:\n- Decoders read through `SubReader`; flag direct raw-slice indexing and any private\n  cursor type. `take` \u002F `wstring` \u002F `counted` (a failed compound read leaves the reader where it\n  started) carry the VMAD (`script_instance.rs`), `weather_settings_instance.rs` and NVNM\n  (`misc\u002Fworld.rs`) shapes since `e04caa7e8` (#6367) — the three per-decoder cursors and the\n  `from_le_bytes(..try_into().unwrap())` sites in `reflection.rs` are gone (a width that disagrees\n  with its type now declines instead of panicking); a new `Option`-returning cursor or\n  `unwrap` on a slice-to-array in a decoder is the regression. FormID arrays read through\n  `SubReader::u32_array`, which declines a ragged body with the cursor unmoved (`f93b3463b`, #6782 — MUSC `TNAM`,\n  MUST `SNAM`, WTHR `HNAM`\u002F`WGDR`); a hand-rolled `chunks_exact(4)` that drops a tail is the regression.\n- The `*_or_default` family swallows short reads: fine for optional tails, a finding\n  mid-fixed-layout (silent zeros). Classify every call site.\n- Fixed-size sub-records check the declared length against the schema; version-gated tails\n  are gated on `GameKind` or remaining length with an xEdit citation. Length gates and field\n  offsets are named constants (`PROJ_DATA_*` \u002F `PROJ_DNAM_*`, `EXPL_*`, `PKDT_*`, `AOR2_LEN`,\n  `COBJ_NAM1_LEN`, `SKYRIM_GLARE_TABLE_LEN`; `004a03fc3`, #6586), and a decoder seeks to a layout\n  offset with the forward-only `SubReader::skip_to_or_eof` rather than hand-summed `skip_or_eof` gaps — a\n  new bare numeric gate or gap chain is the regression.\n- Repeating rows (`CTDA`, `CNTO`, `NVTR`\u002F`NVEX` → `decode_nvtr_row`\u002F`decode_nvex_row`,\n  `LVLO`): `len \u002F stride` with an explicit remainder check; a non-zero remainder is a\n  decode bug.\n- `rgb_color` (3 B) vs `rgba_color` (4 B): swapped pairs shift every later byte. Colours\n  are raw monitor-space floats — never flag a missing sRGB conversion (*feedback_color_space*).\n- Known offset maps — verify against the code, not older reports: `parse_race` TES5\n  `DATA` starting pools at 36\u002F40\u002F44 (new fields land at ≥48; TES4\u002FFO3NV and FO4\u002FFO76 arms\n  differ); the four pre-FO4 WATR decoders share one head, `decode_legacy_head` driven by a\n  per-game `HeadLayout` table (`626be5d12`, #5796; parity test\n  `legacy_head_decodes_every_layout_through_one_pipeline`) — a per-decoder head fix is the\n  regression; WATR `SNAM` is a remapped sound FormID (`sound_form`, `1dd217412`, #6045);\n  WATR `decode_data_fo3nv` shared 0..28 prefix (wind speed\u002Fdirection\u002Famplitude\u002F\n  frequency at 0\u002F4\u002F8\u002F12, direction degrees-on-the-wire converted once), pinned by\n  `parse_watr_186_byte_record_reads_colors_at_40_44_48` and\n  `wind_direction_converts_shipped_degrees_on_the_fo3nv_dnam_arm` (this field moved twice).\n- WTHR (`records\u002Fweather.rs`) sizes are per game *and* form version: `PNAM` cloud colours step\n  `cloud_color_slots(game, len)` TOD slots per layer (FO3\u002FFNV 6 at ≥96 B, Creation-era 8 at\n  1,024 B, else 4; `7f4c25e3e`, #6037); Skyrim `NAM0` is accepted only at the version-prefix\n  sizes `skyrim_nam0_groups` maps (10\u002F13\u002F14\u002F17 groups) and `DALC` also at 24 B (`67433ee3a`,\n  #6038); cloud-layer FourCCs `00TX`..`O0TX` index `byte - '0'` via `skyrim_cloud_layer_index`\n  for Skyrim **and** FO4\u002FFO76\u002FStarfield (`f16741886` #6040, `3ab1b5557` #6039 — FO3\u002FFNV ignore\n  them, `parse_wthr_00tx_fourccs_are_inert`); Oblivion `CNAM` is the lower layer 0 and `DATA`\n  bytes 1-2 the layer speeds (#6041), and its cloud tints are `NAM0` group 2 (Clouds-Lower →\n  `cloud_layer_colors[0]`) and group 9 (Clouds-Upper → `[1]`) — read as FO3\u002FFNV's Unused until\n  `7ed4c7dca` (#6258; `SKY_GROUP_2`\u002F`SKY_GROUP_9`); FO3\u002FFNV 24-byte `FNAM` carries fog power (#6042). The two decoders (`parse_wthr` for Oblivion\u002FFO3\u002FFNV, `parse_wthr_creation` for Skyrim\u002FFO4\u002FFO76\u002FStarfield) share the RGBA unpack\n  `sky_color_at`, the noon\u002Fmidnight synthesis `synthesize_noon_midnight` and the fog head\n  `read_fog_head` \u002F `read_fog_power` (`ac9fa19a8`, #6223); FO4\u002FFO76\u002FStarfield now run the Skyrim-lineage decoder with a per-game NAM0 shape table (`nam0_layout`) and FNAM reader (`read_creation_fnam`), and Skyrim-only reads (DALC, NAM2\u002FNAM3, MNAM\u002FNNAM, the 272-byte side table, the wind flag) are gated on `game`. Starfield's 608-byte NAM0 still takes the FO3-stride read (`Nam0Layout::Fo3Stride`) — no xEdit SF1 layout was on hand to move it; check before touching. A WTHR fix applied to one copy of the shared pieces is the regression. `cargo run --release -p byroredux-plugin --example inspect -- wthr-dump \u003Cgame> \u003CESM>` before\u002Fafter diffs every real master byte-for-byte.\n- Strings: terminator consumed exactly once; a missing terminator cannot read past the\n  sub-record.\n- Leveled lists (`parse_leveled_list_for_game`): FO76 split `LVLO` (4 B ref) + float\n  `LVLV`\u002F`LVIV`\u002F`LVCV` companions only under `GameKind::Fallout76`; the legacy row accepts\n  ≥8 bytes (Oblivion omits Count → default 1) and `LVLD` bit `0x80` becomes `LVLF 0x01`, not\n  chance-none 128 (#4638). A sub-8-byte legacy `LVLO` must never become a valid reference.\n**Output**: `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_2.md`\n\n### Dimension 3: FormID Remap, Load Order & ESL Space\nPaths: `crates\u002Fplugin\u002Fsrc\u002Fesm\u002Freader.rs` (`FormIdRemap`, `GlobalSlot`), `esm\u002Frecords\u002Ftests.rs`, `esm\u002Frecords\u002Fcommon.rs`, `byroredux\u002Fsrc\u002Fcell_loader\u002Fload_order.rs`\nFirst step: `cargo test -p byroredux-plugin -- every_record_parser_takes_a_remap parsers_that_take_a_remap no_parser_with_a_remap remap_fid_has_exactly_one`\n**Guards**: `records::tests::all_record_parsers` walks `records\u002F` at test time and requires\nevery `pub fn parse_*` to take a `remap` parameter or sit in `EXEMPT_NO_U32_READS`\n(mechanically re-verified) \u002F `EXEMPT_JUSTIFIED` (written non-FormID reason);\n`parsers_that_take_a_remap_actually_use_it`; `remap_fid_has_exactly_one_definition`;\n`no_parser_with_a_remap_in_scope_passes_an_identity_remap`. The `cell\u002F` tier is guarded\nstructurally (remap is a required parameter of `read_form_id`). Review **new exemption\nentries** in the diff — each is a human decision, not a proof.\n**What the guards cannot see — the class keeps recurring in three shapes**:\n(1) an unremapped field inside a *shared* decoder several parsers call\n(`CommonNamedFields::from_subs_with_remap`, #4067); (2) a GRUP **label** that encodes a\nFormID (DIAL topic-children label vs remapped DIAL id, #4079 — check every label-dispatch\nsite like a sub-record field); (3) a `HashMap\u003Cu32, _>` in `EsmIndex` keyed by, or compared\nagainst, a raw plugin-local id. **Inverse shape (4)** — a non-FormID `u32` routed *into*\n`remap_fid` (only `0` short-circuits, so every row warns through the out-of-range arm on a\nplugin with masters): xEdit `wbFormIDCk([…, FFFF])` fields go through\n`remap_fid_or_sentinel`, and Oblivion `EFID` (a `wbChar4` effect code resolved via\n`magic_effects_by_code`) through the game-gated `remap_efid` (`records\u002Fcommon.rs`;\n`9b099b31f`, #5075\u002F#5076); PKIN `VNAM` is xEdit's integer *Version*, stored raw as\n`PkinRecord.version` (`0d436e642`, #5422, pinned by `pkin_vnam_version_stays_raw_under_remap`).\nA new sentinel-bearing field, char4 code or plain integer calling `remap_fid` inline is the\nregression. SCOL\u002FPKIN `FLTR` is a `wbString` filter path: both parsers store `filter: String`\nvia `read_zstring` with no `remap_fid` (fixed in `136048a95`, #5493; pinned by\n`pkin_fltr_filter_path_stays_raw_under_remap` + `parse_scol_fltr_decodes_the_filter_path`).\nCTDA `param_1` is remapped only for functions whose first parameter is a FormID:\n`condition.rs::param1_is_form_id` mirrors the scripting catalog by raw function index (rows\nfor fn 56\u002F71\u002F74 were missing until `722c06a76`, #5637; M47.2 added the location\u002Fkeyword\u002F\nrelationship\u002Fquest-variable rows); fn 32\u002F372\u002F382 (GetInSameCell \u002F IsInList \u002F GetHasNote, FO3\u002FFNV) joined in `102e4f5cd`, #6460; `param2_is_form_id` is the second-parameter twin (fn 605\u002F181\u002F\n576\u002F606\u002F608 — everywhere else `param_2` is a literal); the drift guard lives in the scripting\ncrate (`param1_form_id_table_matches_the_condition_catalog`) — a new catalogued\nFormID-param function needs its row.\n**Checklist**:\n- `GlobalSlot::Regular` keeps 24 bits and regular allocation stops at `0xFB` — `0xFC` is the\n  Papyrus VM's synthetic alias-owner byte (`0edc61bbf`, #5988; a regular `0xFC` slot is the\n  regression); `GlobalSlot::Light` (`0xFE` space) packs a 12-bit\n  sub-index and keeps only the low **12** object-id bits (`0x0FFF` masks on both sides);\n  `GlobalSlot::Medium` (`0xFD`, Starfield) packs an 8-bit sub-index + 16-bit object id.\n  The TES4 master bits are per game (#4639, `read_file_header`): Starfield small `0x100` \u002F\n  medium `0x400`, Skyrim SE + FO4 light `0x200`, every other game none — a `0x200` test on\n  Starfield (*Update*) or a pre-ESL game is the regression. `allocate_global_slot`\n  (`load_order.rs`) must keep the three spaces disjoint.\n- `FormIdRemap::remap` arms (`FormIdScheme::Positional`, every game but Starfield): raw `0` → `0`\n  (null sentinel, must not become a live ESL id);\n  self-reference (`mod_index == master_slots.len()`); in-range master; standalone with no\n  masters (pass through, `debug` — the vanilla Oblivion `0x01` artifact, #1308; must NOT be\n  \"fixed\" into a clamp — two forms would collide in `EsmIndex`); out-of-range with masters\n  (pass through, `warn`). Starfield plugins get `FormIdScheme::Starfield` (chosen per plugin\n  from its detected game in `load_order.rs`; `0a2955d33`, #6118): `0xFE` + 12-bit ordinal\n  among the file's **small** masters, `0xFD` + 8-bit ordinal among its **medium** masters, any\n  other top byte an ordinal among its **regular** masters only, ordinal == that kind's count\n  = self, an unlisted master passed through with a `warn` (`remap_starfield`; positional\n  decode had two small masters claiming 61k shared ids). Pinned by the `starfield_*` tests in\n  `reader.rs`; a fixture or new caller building `FormIdRemap` for Starfield with the default\n  scheme is the regression.\n- Master list read in file order; a missing master fails diagnosably, not as a silently\n  shifted slot table.\n- Multi-plugin is live (`--master` repeatable → `parse_esm_with_load_order`); `parse_esm`\n  passes `None`. Verify every embedded FormID in a newly-touched parser goes through\n  `remap_fid`. The guard walk sees only `pub`\u002F`pub(crate)`\u002F`pub(super) fn parse_*` in\n  `records\u002F` (files named `tests.rs` and `#[cfg(test)]` modules excised) — `decode_*` \u002F\n  `from_subs*` helpers and `cell\u002F` are outside it.\n- Parallel walk (#3813, `parse_record_indexes_in_load_order_with_archive`): walks run on\n  the rayon pool, but slot allocation, remap construction, `.STRINGS` loads and the\n  `merge_from` fold stay on the calling thread in load order — fold order, never completion\n  order. Guard: `load_order_parallel_tests::parallel_walk_matches_the_inline_walk_on_a_localized_master_chain`.\n**Output**: `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_3.md`\n\n### Dimension 4: Record Schema Dispatch & Coverage\nPaths: `crates\u002Fplugin\u002Fsrc\u002Fesm\u002Frecords\u002F{parse,index,items,container,actor_value_derive,load_screen}.rs`, `records\u002Fdispatch_*.rs`, `records\u002Fmisc\u002F*.rs`, `crates\u002Fplugin\u002Fsrc\u002Fequip.rs`\nFirst step: `cargo test -p byroredux-plugin -- dispatch_handled_fourccs every_index_map_is_a_category`\n**Guards**: `records::tests::dispatch_handled_fourccs_matches_the_live_dispatch_arms`\n(`DISPATCH_HANDLED_FOURCCS` ↔ the live match in `parse.rs`; era-gated arms count as\nhandled, `PDCL` is deliberately absent; `LCTN`\u002F`LCRT`\u002F`RELA` are routed through `dispatch_misc_stub` into typed maps since M47.2, and `LCTN` is in the list — the stale \"LCTN has no arm\" prose was corrected in `cacdbb955`, #6451; `AORU` is a `dispatch_misc_gameplay_a` arm);\n`index::tests::every_index_map_is_a_category_or_a_recorded_exclusion` (every `EsmIndex`\nmap is a `categories()` row — `map_category!` or a hand-written row recognized by its count\nclosure, like `dialogues` and `game_settings` — or a reasoned exclusion: `record_types`, the derived\n`generic_greeting_form` cache, the derived `game_settings_by_edid` side-table; the non-`HashMap` `deleted_record_metadata` \u002F\n`skipped_unconsumed_groups` sit in its `MANUALLY_MERGED` table); `cell::plugin_loading_doc_pin_tests::the_documented_esm_cell_index_lists_every_field` and\n`…::the_audio_record_split_matches_the_dispatcher` (docs ↔ code).\n**Checklist**:\n- Build the live matrix per record type: typed decode \u002F minimal stub\n  (`parse_minimal_esm_record`, EDID+FULL — `dispatch_misc_stub.rs` also hosts typed\n  decoders: `LSCR`, `CLOT`\u002F`CCRD`\u002F`CMNY` → `items`) \u002F skipped. Report the delta against\n  *record_type_catalog* as coverage, not bugs. A stub must advance the reader correctly;\n  the unknown-record path skips by declared size and never `warn`s per record on a vanilla\n  master.\n- Per-game schema splits within one record (`ARMO\u002FWEAP\u002FAMMO DATA`, `BOD2` vs `BMDT` vs\n  Skyrim's pre-BOD2 `BODT` — 8 or 12 B, same leading biped mask, read in both `ARMO` and\n  `ARMA` since `479414ffe` (#5358; every Skyrim.esm ARMA authors it, so BOD2-only decoding\n  zeroed all 766 masks), `SCOL\u002FPKIN\u002FTXST`, FO76 `LVLO`) switch on `GameKind`. Oblivion's 4-byte\n  `ARMO BMDT` is a u16 Biped Flags + General Flags byte — the mask is the u16 only\n  (`a8e37e5fd`, #5696; a u32 read put General Flags in bits 16-23 on 661 of 996 armors);\n  FO3\u002FFNV keep the u32. **`ACRE` is not Oblivion-only**\n  (FO3 ships 3,349 `ACRE` vs 2,154 `ACHR`) — flag any new per-game gate on it.\n- **Consumables \u002F items decode contract** (decode only; consumption is `\u002Faudit-gameplay`):\n  `ALCH` effect chains via `parse_alch_for_game`; `MgefRecord.instant_restoration_av` via\n  `parse_mgef_for_game`; Oblivion `parse_clot` → `ItemRecord`; `IMOD`\u002F`CCRD`\u002F`CMNY`\n  carried as items; `LVLI` multi-pick (flag `0x04`) vs single-pick highest-eligible,\n  pinned on the shipped FNV master. `expand_leveled_loot` retains unknown terminal ids and\n  saturates counts — check it agrees with the decoder's `LeveledEntry` semantics.\n- **`LSCR`** (`parse_lscr`, header flags via `extract_records_with_flags`): `LNAM` stores\n  grid **Y before X**; malformed known fields land in `malformed_fields` rather than\n  producing an unrestricted screen; truncated fixed fields are safe and visible.\n- **`TPLT` \"Use Stats\"** resolves each absent stat *down the chain* to the deepest record\n  that authors it (`resolve_inherited_field`, #4086; `TPLT_MAX_DEPTH` 6) — the terminal\n  outranks a shallower record and a one-hop chain is unchanged. Check new stat fields join\n  the per-field walk instead of comparing only the chain ends. \"Use Model\u002FAnimation\"\n  (`TEMPLATE_FLAG_USE_MODEL_ANIMATION`, `ResolvedNpc::model`) resolves model-less templated\n  `CREA` shells through their `LVLC` pick (`011ad0c07`, #6075; 63% of FNV fauna placements). A terminal `level` of 0 (30\u002F3,816 FalloutNV.esm `NPC_`) backfills from the authored entry level of the deepest `LVLN` the walk picked through (`last_pick_level`, `ResolvedNpc::level()`), so its owned leveled lists are not expanded at level 0; an authored level or a list-less chain is unchanged (`4fbff2c6c`, #4232 — `effective_actor_level` itself stays unfloored, #3081).\n- `EsmIndex::merge_from`: last-write-wins matches Bethesda override semantics; `game` is\n  only adopted when `other.total() > 0` (a failed-parse `EsmIndex::default()` must not\n  relabel the load order as FO3\u002FFNV, #3403); `character_rules` is first-non-`NONE` wins.\n  **Exception — `dialogues`** (`168b81322`, #5375): an override DIAL replaces only the\n  header fields and folds its INFOs into the master's list by FormID (same id in place, new\n  id after its `PNAM` predecessor), and the prune arm drops Deleted-INFO tombstones from every\n  topic; whole-record `extend` erased 8.5–9.9k FNV INFOs per DLC. An override's `PNAM == 0`\n  run keeps authored file order through one per-override contribution cursor\n  (`fold_infos_into_topic`, `5356c8780`, #5494 — the first contribution goes to the front, later\n  ones follow the previous; the run's position relative to the master's heads is an unsourced\n  engine choice). Since `0c2bd4d6d` (#5644) the fold is one pass over a FormID → node map;\n  `fold_info_into_topic_reference` is the test-only one-at-a-time twin and\n  `batched_info_fold_matches_the_one_at_a_time_fold` pins that the two agree.\n  `game_settings` is also a hand-written category row: GMST resolves by EditorID in load order, not FormID\n  luck — `insert_game_setting` (the only parse-path insert) keeps `game_settings_by_edid`\n  (lower-cased EditorID → winning FormID) coherent, `game_setting_float` reads it first, and the\n  prune arm drops pointers into tombstoned FormIDs (`824bb58c6`, #6350; pinned by\n  `game_setting_duplicate_editor_id_across_distinct_form_ids_resolves_last_loaded`). A parse path\n  inserting into `game_settings` directly leaves the linear-scan fallback (test fixtures only) serving.\n  Top-level maps merge through `categories()`; `EsmCellIndex::merge_from` destructures\n  exhaustively (#4904 — a `..` there is the regression that dropped `landscape_grasses`).\n  A CELL override's record fields come from the override **as parsed** — an omitted\n  sub-record is omitted on purpose (Update.esm drops `XCWT`, a DLC drops `XCRI`); only child\n  records (placements, landscape, navmeshes, pathgrids) and a missing EDID inherit from the\n  base (`merge_cell_override`, exhaustive `CellData` destructure; `2fa227d72`, #6086, pinned by\n  `cell_record_fields_come_from_the_winning_override` \u002F `child_records_still_inherit_from_the_base`).\n  A REFR an override re-authors under another CELL is swept from every other held cell\n  (`765e387a0`, #6084, `a_refr_moved_into_another_cell_leaves_one_copy`).\n- M47.2 added typed maps: `locations` (`LCTN`, `misc\u002Flocation.rs`), `location_ref_types` (`LCRT`),\n  `relationships` (`RELA`, `misc\u002Frelationship.rs`), `condition_forms` (Starfield `CNDF`),\n  `keywords` (`KYWD` EDID only), `SNDR` into the `sounds` map via `parse_sndr` (`soun.rs`),\n  RACE FO4\u002FFO76\u002FStarfield `SRAC`\u002F`SADD`\u002F`SAKD`\u002F`SGNM`\u002F`SAPT`\u002F`STKD`\u002F`SRAF` subgraph data (`SubgraphRole::from_raw(raw, game)`: value 3 is *Linking Only* on FO76\u002FStarfield and *Idle* on FO4, Starfield 5–7 are Mt\u002FWeapon\u002FFurnitureGeneration; `SADD` stays one-per-race, not per entry — a raw scan of all 55 Starfield masters finds 17 races authoring it once, ahead of the first entry; `40cebd21d`, #6621), `KWDA` on\n  `CommonNamedFields`, PERK entry bodies (`PerkEntry`\u002F`PerkEntryBody`, EPFT\u002FEPFD per the\n  xEdit layout), and a \"Use Base Data\" template chain terminal (`ResolvedNpc::base_data`). The\n  `EsmIndex::categories()` count is pinned in `records::tests` (117 on 2026-11-08) — read the live\n  number there; each new map must be a category row or a recorded exclusion. M43 added FO4 `AORU`\n  attraction rules (`attraction_rules`, `parse_aoru` in `misc\u002Fworld.rs`) and the `KWDA` side tables\n  `furniture_keywords` (FURN) \u002F `placed_object_keywords` (FURN, FLOR, ACTI, CONT; `kwda_keywords` in\n  `common.rs`) — all three are category rows; `complex_scene_object` (the `DOBJ` `CMPX` pair, read\n  by `complex_scene_object` in `dispatch_misc_stub.rs`; later plugin wins in `merge_from`) is a scalar\n  and a recorded exclusion. FNV `MSET` is typed (`parse_mset` → `MediaSetRecord`, `misc\u002Fmedia_set.rs`;\n  `media_sets` was a `MinimalEsmRecord` stub, `9ee802d57`). Skyrim `MUSC` (remapped `TNAM`, `parse_musc`, which takes the remap — no remap-free entry point, #6788) and `MUST` (`parse_must` → `music_tracks`, a category row; `MUST` decodes for Skyrim, FO4 and FO76 (one shared layout, #6790); only Starfield lays it out differently) decode in `misc\u002Fmusic.rs`, and `first_playable_track` resolves REGN `RDMO` → `MUSC` → first playable `MUST` (palettes descend, depth-capped; `03f9d2158`). #3816 stays OPEN for its other two pieces (Oblivion `RDMD`; FNV `MSET` consumption) — a typed `music_tracks` map is not a finding.\n- `actor_value_derive.rs` is the CHARAL feed — formulas belong to `\u002Faudit-character`.\n- Settled decodes — verify they hold, do not re-derive: `INAM` is one FormID array (#3356);\n  `CREA CNAM` is not a class (#3383); `FACT` rank ladder (#3338); `ARMO` contributes every\n  race-matching `ARMA` (#3357), `MOD3` is the female mesh (#3414); a `REFR` tombstone\n  removes the placement wherever it lives (#3362); FO76 `HEDR` is patch-dependent — 279.0 on the 2026-09-20 patch, never pin it (#3405, #4643);\n  DIAL quest ownership reads `QSTI` **or** `QNAM` (Skyrim authors `QNAM`; `parse_dial`); FO3\u002FFNV\u002FOblivion INFOs also carry their **own** owning quest in `InfoRecord.quest` (`QSTI`, remapped, 23,247\u002F23,247 FNV INFOs; `dbc07e8f0`, #5271 — Skyrim+\u002FFO4 author none, `0` = use the topic's ownership); INFO `DATA` is typed `InfoDataHeader` (info_type \u002F next_speaker \u002F flags1 \u002F flags2; Goodbye = Flags 1 bit 0) and Skyrim's 8-byte `DATA` lands raw in `skyrim_data` (`25b678106`, #5295); `SMBN`\u002F`SMEN`\u002F`SMQN` decode into `story_manager_nodes` (`misc\u002Fstory_manager.rs`, #5366 closed — the SM dispatches live): `SNAM` is the **previous** sibling (xEdit *Previous Node*; `846e4a6dd`, #5385 — the same-parent census holds in both directions and cannot settle it), `SMQN` `RNAM` is stored hours × 24 and decoded ÷ 24 (xEdit scale `1\u002F24`; `a621d5352`, #5386 — node `HNAM` stays raw), and `XNAM`\u002F`MNAM`\u002F`HNAM`\u002F`QNAM`\u002F`FNAM`\u002F`UNAM` + `DNAM` `0x2`\u002F`0x40000` are named from xEdit (`5489cbe65`, #5420; per-quest `FNAM`\u002F`UNAM` live on `SmQuestLink` beside the `NNAM`\u002F`RNAM` they follow — a node-level field let each later quest overwrite the last, `0edd1dede`, #5515). `FNAM` is xEdit's current `wbUnknown` (the \"24 Hours Till Reset\" reading is withdrawn); its bit 2 is consumed as an **inferred** per-link shares-event (`SM_LINK_FNAM_SHARES_EVENT`, `SmQuestLink::keeps_event`, `af51f6730`) — flag it only if a source contradicts. `DNAM & 0x40000` (`SM_DNAM_NUM_QUESTS_TO_RUN`) gates `MNAM` via `SmNodeRecord::num_quests_to_run`, `XNAM` is `max_concurrent_quests`, and node `HNAM` is the hours-until-reset window (`reset_hours`) — all three are runtime-gated now; INFO Flags 1 bit 5 = Random End (`random_end`, `0436bea5c`, #5397); REGN `WNAM` is the owning **worldspace** (`worldspace_form`, remapped), never a weather, and REGN `CNAM` is xEdit-undefined with zero vanilla occurrences (`bd052048a`, #5421); `NPC_.WNAM` is the per-NPC skin ARMO (`worn_skin`, remapped, no game gate — pre-Skyrim ships none; `edb5fbdfe`, #5359); Oblivion `RACE`'s body-section `ICON` run (INDX restarts at 0 past `NAM1`) lands in `body_part_textures` (`1b45763fa`, #5487); Starfield `WTHS` decodes the REFL\u002FRDIF reflection schema (`weather_settings.rs`, reflection container in `reflection.rs`, #5364; the DIFF walk is depth-capped at `MAX_NESTING_DEPTH` 64, `02187c7f9`, #5687, pinned by `hostile_self_referential_diffs_decline_at_the_depth_cap`) and, since `2c203278f` (#5627), the instance values (`weather_settings_instance.rs`: root `OBJT` value tree + `DIFF` overrides with `LIST`\u002F`MAPC`\u002F`USER`\u002F`USRD` side chunks; grammar grounded from `Starfield.esm` itself — any walk\u002Fschema disagreement declines the whole instance to the census-only state, never guesses); `EsmIndex::synthesize_wths_weathers` runs on the merged index after the load-order fold (`load_order.rs`) and lifts only the grounded fields (day\u002Fnight imagespace, `Colors.Sun`\u002F`Sunlight`\u002F`FogNear`) into a `WeatherRecord` under the WTHS FormID in `weathers` — fog distances, wind and transition floats stay unlifted (real-data 181\u002F181 census in `parse_real_esm.rs`, ignored lane); `DIFF` is (u16 field index, inline value) pairs to the `0xFFFF` terminator and `USRD`\u002F`MAPC` join the instance census (`f0f8dceef`, #5514; real-data pins 163 in-range indices \u002F 47 `USRD`); the CDB builtin ids live in one table (`1f56d5742`, #5615); FO76 `LSCR` decodes on the modern (FO4-shape) arm incl. `BNAM` → icon (`47f927cbf`, #5345); FO3\u002FFNV `PKDD` Dialogue Type is the u32 at offset 16, and Oblivion `PKDT` (4 B) \u002F `PTDT` (12 B) legacy shapes are accepted (`dae08000d`, #5492\u002F#5504); FO3\u002FFNV non-auto-calc NPCs keep their authored `DATA` SPECIAL in `NpcRecord::data_attributes` (`4957536ba`, #5338); FO4 `NPC_` template flags resolve per flag through `template_actors` (`TPTA`, 13 entries in xEdit `wbTemplateFlags` order, `0` = use `TPLT`; `99c22a8db`, #5498); `MSWP` `CNAM` is the Color Remapping Index palette row (`color_remap_index`, `0b2ffed89`, #5497); `MGEF` `DATA` offsets\u002Fflags are named constants in `misc\u002Fmagic.rs`'s `mgef_data` (`abe8d7e96`, #5614); Starfield `NPC_` `ACBS` is 16 B (the FO4 layout minus the trailing words) and shares the FO4 arm under a `>= 16` gate (`78facba89`, #6120 — no arm matched, every Starfield NPC was male with no template flags); ACBS Essential\u002FProtected decode in `parse_npc` (`NpcRecord.essential`\u002F`.protected`; bit 11 is Protected from Skyrim on, No Blood Spray on FO3\u002FFNV; `3162b21b8`, #5921); the ACBS arm is `Fallout4 | Fallout76` at `>= 20` B (FO76 ships the FO4 layout: all 6,551 `SeventySix.esm` NPC_ ACBS are 20 B, `c4884977a`, #6240); the `RACE` `ANAM` skeleton run is read for Skyrim\u002FFO4\u002FFO76\u002FStarfield (`e8e00326d`, #6122; FO76 `4a7963156`, #6297 — 307 runs over 157 RACEs); Oblivion `RACE` body-section tail `MODL` lands in `RaceRecord::tail_models` (male, female; only Argonian\u002FKhajiit author one, `a6ab3625e`, #5753); Starfield bleedout decodes into `RaceRecord::bleedout` (`DAT2` +160) and `NpcRecord::bleedout_override` (`ONA2` flag 5) — decode only, no recovery rule is wired (`a1b72625f`, part of #6259); `PACK` `PSDT` Day-of-Week decodes into `PackDays` (−1 any, 0–6, 7 weekdays, 8 weekends, 9 MWF, 10 TT; `3ce1e1e3a`, #6079 — consumed for FO3\u002FFNV, and Oblivion since `5d7f08e56`, #6257, which also decodes PSDT byte 2 into `PackSchedule::date`); the 12-byte Skyrim+ PSDT duration is **minutes** (`duration_minutes` + `start_minute`; the 8-byte FO3\u002FFNV\u002FOblivion hours are ×60 at decode, `7e2f21482`, #6210 — an hours reading made 1,536 of 1,545 timed Skyrim windows always-on); `PKW3`\u002F`PTD2` (FO3\u002FFNV Use Weapon data and second target, `PackUseWeapon`, `10f8cbb91`; PTD2 is authored by all 82 FNV but only 46 of 56 FO3 Use Weapon packages, the rest declined, #6462); Skyrim+ `PKDT` Interrupt Flags (u16 @ 8, gated on the type byte 18\u002F19; `PackRecord::interrupt_flags`, `allows_random_conversations`); Skyrim\u002FFO4 `FACT` Crime tab (`parse_fact_crime` → `FactionRecord::crime`, `4cfcee4b9`) and `CLAS` `DATA` flags on Oblivion\u002FFO3\u002FFNV (`ClassRecord::class_flags`, Guard bit 1, `1a67c9f30`); `CHAL` decodes only under `Fallout3NV` — Starfield's 8 `CHAL` have no `DATA`\u002F`SNAM` (`f90aea105`, #6298); `MSWP` `FNAM` is the CK *Tree Folder* (`tree_folder`, tooling only), never a path filter (`f81e6e722`, #5756); FO3\u002FFNV `WEAP` `DNAM` offset 28 is Sight FOV (f32, not stored), Base VATS To-Hit is the **u8** at offset 40 (`vats_base_to_hit`) and the regular AP cost is the f32 at offset 68 (`ap_cost`), and the weapon's skill is the `i32` at offset 104 (`ItemKind::Weapon::skill_actor_value`, an actor-value code — 34 Energy, 38 Melee, 41 Guns, 45 Unarmed; `a290c755f`, part of #6657), while the VATS sub-record's offset-12 float is the melee *special attack's* AP, kept as `WeaponVats::special_attack_ap` (`e97707b14`, #6449\u002F#6450; the earlier offset-28 to-hit and *ap_override* readings were mislabels, and the #3324 reading of the VATS float as *the* AP cost before them); `BPTD` decodes the full part run (`BPTN`\u002F`BPNN`\u002F`BPNT`\u002F`BPNI` strings + the 84-byte `BPND`, `BptdRecord::parts`, at xEdit's offsets: flags @4, part type @5, health percent @6, to-hit @8, u16 debris @10; `3bec306a0`, #6448) with short payloads defaulting, and a payload longer than 84 B (FO4's 101-byte `BPND`) keeps the name run and leaves the numeric fields undecoded — it must never reach `remap_fid` (#6465), `CREA` links its record through a standalone `PNAM` (`NpcRecord::body_part_form`; RACE carries none) and humanoids resolve the reserved `PLAYER_BODY_PART_DATA` `0x1C` \u002F `DEFAULT_BODY_PART_DATA` `0x1D` slots (`aebcc99a1`, part of #6350); FO3\u002FFNV `RACE` authors the same body-section `ICON` run under `NAM1` with a three-slot vocabulary (0 upper body, 1\u002F2 hands) — `body_part_textures` is no longer Oblivion-only (`9d1a262ed`, #6090; Skyrim+ authors none); `SOUN` `SNDD`\u002F`SNDX` bytes 0\u002F1 carry min\u002Fmax attenuation (`SounRecord::attenuation_units`; min ×5, max ×100 game units) plus the Menu Sound \u002F 2D bits (`41b53ab41`, #6281); the CRVA, PACK (`PACK_LOCATION_LEN`), ACBS and Oblivion-CTDA length gates are named constants (`64f26db8c`, #6393); FACT `CRVA` decodes at its real 12\u002F16\u002F20-byte cut points (`CRVA_MIN_LEN` 12, `CRVA_STEAL_LEN` 16 for the steal multiplier, `CRVA_TAIL_LEN` 20 for escape\u002Fwerewolf; `3da35c683`, #6516); FACT `XNAM` modifier stays a full `i32` (vanilla Oblivion authors -200; the -100..100 clamp was in the SDK faction catalog, `407730df3`, #6504 — a clamp at the parser is the regression); NPC template flag `0x1000` Use Keywords (Skyrim; FO4's 13th `TPTA` slot) is a `ResolvedNpc::keywords` terminal read by `KeywordTable` (`TEMPLATE_FLAG_USE_KEYWORDS`, `keywords_terminal`, `26850aa5f`, #6515) while Skyrim's `0x0800` Use Attack Data is deliberately unparsed (no `ATKD` reader); `PROJ` alt-trigger proximity\u002Ftimer (`DATA` 28\u002F32 on FO3\u002FFNV\u002FSkyrim; the 93-byte `DNAM` 24\u002F28 on FO4 **and FO76**, `6d70c560c` #6563) and `parse_expl(.., game)` feed `ProjRecord::is_proximity_mine`. `EXPL` `DATA` is picked by game *and length* (`expl_data_layout`, `misc\u002Feffects.rs`; the record walker keeps no form version and `DATA` only grows with it, so the length gives the same answer on every shipped master): force-first damage @4 \u002F radius @8 on FO3\u002FFNV (`0af42d53d`, #6541 — read from 8 until then, storing the radius as damage and the LIGH FormID as a denormal radius) and on Skyrim below 48 B (six oldest `Skyrim.esm` forms); forms-first damage @28 on Skyrim ≥48 B and FO4\u002FFO76, with `Inner Radius` only from 64 B (`6e49cee6f`, #6562); FO76 ≥88 B adds the Damage Curve Table form id at 24 (damage @32; `6d70c560c`). Oblivion has no `EXPL` `DATA` layout and decodes nothing — the old catch-all FO3-offset arm is the regression; Starfield moved the struct to a 164-byte `ENAM` (damage @104, then inner and outer radius; `parse_expl`, `4b28775fd`, #6679) and `PROJ` to `PROD` (flags, alt-trigger proximity\u002Ftimer, explosion, impact force, collision radius, lifetime, and a type byte behind a u32-prefixed string, `decode_starfield_prod`; the sequential type enum is mapped onto the documented bit values and flag bits above 15 ride `ProjRecord::extended_flags`); item `EITM` lands in `CommonItemFields::enchantment`.\n- `equip.rs::main_body_bit` FO76\u002FStarfield arms are a **provisional inference**\n  (`PROVISIONAL (#4074)`, pinned by `fo76_and_starfield_arms_are_marked_provisional`) —\n  known and marked; report only if the marker is removed without an xEdit citation.\n**Output**: `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_4.md`\n\n### Dimension 5: CELL \u002F WRLD Walkers & Placement Data\nPaths: `crates\u002Fplugin\u002Fsrc\u002Fesm\u002Fcell\u002F**\u002F*.rs`, `esm\u002Frecords\u002Fmisc\u002Fworld.rs`, `esm\u002Frecords\u002Fspatial_units.rs`\nFirst step: `git log --since=\u003Clast report> --format='%h %cs %s' -- crates\u002Fplugin\u002Fsrc\u002Fesm\u002Fcell crates\u002Fplugin\u002Fsrc\u002Fesm\u002Frecords\u002Fmisc\u002Fworld.rs`\n**Checklist**:\n- Cell child groups: type 6 is the `Cell Children` *container*; 8 = Persistent, 9 =\n  Temporary, 10 = Visible Distant nest inside it (#4169 — earlier legends said 6\u002F8\u002F9).\n  `PlacedRef.group_type` is re-derived at each nested GRUP in `parse_refr_group_inner`\n  (only the nested position accepts 10; at CELL\u002FWRLD level 10 is Quest Children). No\n  consumer reads it yet — verify it stays populated per-scope, not that a consumer exists.\n- Interior and exterior CELL sub-record walkers share one decode, `CellSubrecordFields::absorb` (`cell\u002Fhelpers.rs`, #5309), and one `CellData` build, `CellSubrecordFields::into_cell` (`d6d216b91`, #5815) — a field added to only one walker, or a hand-built `CellData` literal back in `walkers.rs`\u002F`wrld.rs`, is the regression. All three walkers depth-bounded (see Dim 1): `parse_cell_group`, `parse_wrld_children`,\n  `parse_refr_group`.\n- Placement header flags (`f87490826`, #4813\u002F#4814): `PlacedRef.initially_disabled` =\n  `0x800` on every placement type; `PlacedRef.starts_dead` = `0x200` on `ACHR` gated on\n  `EsmVariant::Tes5Plus`; `starts_unconscious` = `0x2000` on `ACHR`, FO4\u002FFO76\u002FStarfield only\n  (#5017). The placement bit is **not** the corpse marker on every game, and each other game\n  is settled at its own layer: Oblivion = base `NPC_`\u002F`CREA` header `0x80000`\n  (`base_actor_starts_dead`, `dispatch_actor.rs`, Oblivion-gated, #5013); FO3\u002FFNV = base\n  `DATA` health ≤ 0 (`NpcRecord::starts_dead`, #5005 — `0x80000` is not a marker there,\n  and `XRGD` is a ragdoll *pose*, not a death signal) plus the script-killed idiom\n  (`717f39a82`, #5223 — a dismember-family trigger's `XLKR` target; FO3\u002FFNV `XLKR` is **4 B**,\n  the target FormID alone, vs TES5's 8 B keyword+target — a `len >= 8` gate silently dropped\n  every FO3\u002FFNV link). A zero placement `starts_dead` means \"no placement-level marker\",\n  not \"alive\"; the cell loader ORs both\n  (`byroredux\u002Fsrc\u002Fcell_loader\u002Freferences\u002Fmod.rs` → `reference_state.rs::apply_starts_dead`). Flag any per-game gate that reads one of these bits on a game\n  whose xEdit list does not define it.\n- Starfield metric → 70\u002Fm lift (`records\u002Fspatial_units.rs::normalize`, called once at the\n  end of each plugin's walk in `parse.rs`): positions, light radii, XCLL\u002FLGTM fog\u002Ffade +\n  SF height-fog (#5002; the 20-field lighting tail decodes once in\n  `cell::decode_starfield_lighting_tail` and the height-fog lift is the shared\n  `starfield_heights`, `9dbd59b8b`, #5346), WTHR fog distances (only when\n  `fog_distances_authored` — an FNAM-less weather keeps the unlifted 10 000 default, `ec75b1439`,\n  #5301, pinned by `starfield_wthr_without_fnam_keeps_the_unlifted_fog_defaults`) + height-fog tail (#5001\u002F#5134), water heights,\n  WATR `DNAM` lengths ×70 and per-metre absorption ÷70 — only for offsets the record\n  authored (#5151, `24cb577d2`), LAND heights, NAVM vertices, XRGD ragdoll-pose offsets (`5f1a862be`, #5299; Euler stays wire-valued), and Starfield EXPL radii, PROJ speed\u002Frange\u002Fcollision radius\u002Falt-trigger proximity and TXST decal sizes (`af26510e9`, #6777; gravity, lifetime, timer and impact force stay wire-valued, pinned by `starfield_expl_proj_and_decal_distances_lift_once`). FO76 is BU-native except the\n  shared-decoder WATR absorption lane, its only lift (#5169). Three Starfield WATR `DNAM` lane\n  families (noise-UV tiles, displacement simulator, normal falloff) are deliberately **not**\n  lifted — unit unsettled, pinned by `starfield_watr_defers_the_unclassified_dnam_lanes`; the\n  LGTM + cell-XCLL lift is pinned through `parse_esm` by\n  `starfield_index_lifts_lgtm_and_xcll_lighting_distances` (`2dab4ff48`, #5170\u002F#5171,\n  `records\u002Fspatial_units_tests.rs`). Check new Starfield distance\n  fields join it, dimensionless fields (XSCL, Euler) stay out, decoder defaults for an\n  unauthored field are never lifted, and no path normalizes an index twice.\n- M47.2 placement\u002Fbase fields, all remapped: REFR `XAPR` (activate parent + delay, `XAPD`\n  Parent Activate Only), `XMRK`→`FNAM` map-marker flags, per-reference `XEZN`\n  (`PlacedRef.encounter_zone_form`); base-object `DEST`\u002F`DSTD` → `DestructionData`. `ECZN DATA`\n  is per game (`parse_eczn(.., game, ..)`: FO3\u002FFNV 8 B, Skyrim\u002FFO4\u002FStarfield add the `LCTN` and\n  max level; xEdit `wbECZN`). `EsmCellIndex::cell_by_form_id` is a lazily-built O(1) lookup\n  (`cell_form_id_lookup`, #5489), and `locate_refr` \u002F `cell_for_refr_form_id` answer from the\n  twin `refr_lookup` reverse index (`56fc348b8`, #6125; first cell holding a FormID wins, in\n  interior → exterior → persistent order); `merge_from` resets both — a CELL-map edit after\n  the first call leaves them stale. Starfield REFR `XLMS` is a remapped list of `LMSW` FormIDs\n  (`PlacedRef.layered_material_swap_refs`); `layered_material_swap_entries` flattens it\n  (collection members recursively, then own entries; cycle- and depth-capped) over the\n  `layered_material_swaps` \u002F `material_path_forms` maps (`17bd40f4f`, #5757).\n- A placed reference draws the base's **world** model: `ARMO`\u002F`CLOT` `MODL`\u002F`MOD3` are the worn biped meshes (and on Skyrim+ `MODL` is an `ARMA` FormID), so `StaticObject.model_path` takes `MOD2` for them in `cell\u002Fsupport.rs` (a record with no `MOD2` keeps its `MODL` before Skyrim, nothing after; the worn mesh stays on the typed item the equip path reads; `846c36bf0`, #6691 — read as `MODL`, placed armor stood in its bind pose with its gore caps on FO3\u002FFNV and was invisible on Skyrim, 1,683 interior references). Pinned by `placed_armor_and_clothing_take_the_world_model_over_the_biped_mesh`.\n- Lighting-template inheritance is per-field; \"absent\" and \"authored zero\" stay distinct.\n- CELL `XCCM` is per-game (`3b28dca71`, #5463): TES4\u002FFO3\u002FFNV = Climate (CLMT) →\n  `CellData.climate_override`; TES5\u002FFO4\u002FFO76\u002FStarfield = \"Sky\u002FWeather from Region\" (REGN) → `sky_region`\n  (`xccm_targets_region`, `cell\u002Fhelpers.rs`; FO76 and Starfield joined in #6794 — Starfield 36\u002F36 and FO76 41\u002F41 real cells target a REGN). Guards `parse_cell_oblivion_fo3nv_xccm_populates_climate_override`,\n  `parse_cell_tes5_fo4_xccm_is_a_region_not_a_climate`. Regression = a REGN id reaching `climate_override`.\n- **XCLL** is size- and game-validated: `xcll_canonical_sizes(game)`; the ≥92-byte\n  ambient-cube arm fires only for Skyrim\u002FFO4\u002FFO76 (Starfield has its own ≥108 arm) — a non-canonical 92+ XCLL on\n  Oblivion\u002FFO3NV keeps base + per-field reads and warns (guard: the cell test\n  `parse_cell_non_canonical_92plus_xcll_on_pre_skyrim_games_stays_out_of_the_ambient_cube`).\n  Parsed-but-unconsumed tail fields are parked in `docs\u002Fengine\u002Flighting-from-cells.md`.\n- **LIGH** `LightData`: `falloff_exponent` `0.0` is a sentinel resolved per layout\n  generation at the translation boundary (`canonical_light_falloff_exponent`,\n  `byroredux\u002Fsrc\u002Fsystems\u002Flight_anim.rs`) — the parser must store authored values\n  verbatim. Starfield light shape is the `DAT2+56` Light Type enum\n  (`starfield_light_type`: 0 omni, 1 shadow spot, 2 non-shadow spot); `0x200` is *Focus\n  Spotlight Beam*, not a shape bit. `DAT2` is gated on LIGH (an AMMO `DAT2` must not\n  synthesize light data).\n- `XCLW` water height is tri-state: absent → inherit WRLD default; finite → override;\n  `INT_MIN` \u002F `FLT_MAX` sentinel → suppress (`gated_water_height` in `esm\u002Fcell\u002Fhelpers.rs` +\n  `water_height_is_explicit`; `docs\u002Fengine\u002Fwatal.md`).\n- Exterior grid `XCLC`, worldspace parenting and selective-inheritance flags (`wrld.rs`):\n  a child inherits only the flagged categories. Oblivion authors no `PNAM`, so\n  `parse_wrld_group` stamps land\u002FLOD\u002Fwater\u002Fclimate inherit bits on every Oblivion child\n  (`67afa4b95`, #5374 — pre-FO3 \"child ⟹ inherit all\"; the flag-less duplicate fallback was\n  deleted in `65cadde2f`, #5516, so the stamp is the only copy — pinned by\n  `oblivion_child_gets_the_inherit_all_stamp_and_eras_stay_real`); an authored zero `PNAM` on\n  FO3+ must stay zero. After the merge, `EsmCellIndex::inherit_parent_landscapes` (gated to Oblivion,\n  FO3\u002FFNV, Skyrim and FO4 at its caller; FO76 and Starfield are unmeasured — `apply_exterior_processing` \u002F `needs_exterior_processing` in `byroredux\u002Fsrc\u002Fcell_loader\u002Fload_order.rs`, moved\n  into the shared parse by `588c87bc4`, #6123; FO3's four \"Use Land Data\" children measured co-located with the Wasteland's LAND, `a9472103b`, #6089 — the real-data census fills 100–120 LAND-less cells; FO4's NukaWorld Market\u002FAmphitheater and Goodneighbor \"Use Land Data\" children were added, 29 LAND-less content cells, `977936719`, #6464 — pinned by `use_land_data_children_inherit_on_the_measured_games_only`; Skyrim joined with #6594, 308 LAND-less cells over its seven Tamriel children, pinned by the ignored real-data `skyrim_use_land_data_children_inherit_tamriels_landscape`) fills a child's LAND-less cells from the nearest\n  ancestor's LAND (`75b921cf4`, #5505). `XCLC` byte 8 is kept raw as `CellData.land_flags`\n  (Hide Quad bits 0-3, FO4+ No Collision bits 4-7; `79477b4a3`, #6043) — like `grid`, a CELL\n  record field, so an override's value wins as parsed (#6086, Dim 4). An EDID-less `WRLD` clears the current-worldspace binding so its children are not\n  filed under the previous worldspace (`6f803356d`, #6047).\n- `parse_land_record`: quadrant\u002Flayer counts and splat rows are fixed-stride. An `ATXT`\n  with no following `VTXT` must flush with `alpha: None` (`pending_atxt`, #4078;\n  measured 14× on `Oblivion.esm`). `LTEX.GNAM` is an **array** of grasses, kept in\n  authored order into `landscape_grasses` by `parse_ltex_group` (#4642; last-wins was the bug).\n  The `LTEX.TNAM` → `TXST` join is re-run against the merged load order\n  (`landscape_texture_txsts` + `resolve_landscape_texture_sets`, `65add6a2e`, #6036) — a\n  per-plugin-only join loses every DLC LTEX naming a master TXST. LTEX Havok data lands in\n  `landscape_texture_havok` (`LandscapeTextureHavok`; the walk's out-maps are one\n  `cell\u002Fsupport.rs::LtexTables` sink): Oblivion\u002FFO3\u002FFNV `HNAM` = u8 material + friction +\n  restitution, Skyrim\u002FFO4 `MNAM` = remapped `MATT` FormID with `HNAM` friction + restitution\n  only (`c53d87679`, part of #6048; friction\u002Frestitution stored as authored, unapplied). The `MATT` arm in\n  `records\u002Fparse.rs` (`matt_havok_material`, `cell\u002Fsupport.rs`) feeds `EsmCellIndex::material_type_havok`\n  (MATT → Havok material id, merged across the load order): the id is the BSCRC32 of the lowercased `MNAM`\n  string (nif.xml `SkyrimHavokMaterial`; 63 of 78 vanilla MATTs land on a listed id and all 68 vanilla LTEXs\n  name one of them), computed on Skyrim only — FO4\u002FStarfield `MATT`s are routed but stay empty (`4ce5ddf2a`,\n  part of #6048, which stays OPEN for applying friction\u002Frestitution and for FO4 terrain material).\n- FO4 precombine CELL sub-records (`CellSubrecordFields::absorb`): the `XCRI` tail is\n  `ref_count \u002F 2` × (ref FormID, bake hash) pairs → `CellData.absorbed_ref_bakes` (the skip\n  set); `XPRI` is the disjoint previs list, validated and **not** stored (`777351ec1`,\n  #5484 — the two were inverted, double-drawing every baked STAT\u002FSCOL). Guards\n  `parse_cell_xcri_pairs_remap_and_keep_their_bake_hash`,\n  `parse_wrld_exterior_cell_captures_precombined_xcri_xpri`.\n- Starfield `TXST`: an unmodelled slot warns once (#4438), not per record.\n- Navmesh: classic `NVTR`\u002F`NVEX` and packed `NVNM` (`decode_nvnm`, `NVNM_MAX_DIVISOR`)\n  yield the same `NavmRecord` through shared row decoders; the cursor refuses to pass the\n  blob end; retained-raw-on-failure is diagnosable, not a silent success.\n**Output**: `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_5.md`\n\n### Dimension 6: Localized Strings (Skyrim+ `.STRINGS` family)\nPaths: `crates\u002Fplugin\u002Fsrc\u002Fesm\u002Fstrings_table.rs`, `esm\u002Frecords\u002Fcommon.rs` (`StringsTableGuard`, lstring readers), `byroredux\u002Fsrc\u002Fcell_loader\u002Fload_order.rs` (table loading)\nFirst step: `cargo test -p byroredux-plugin strings_table`\n**Checklist**:\n- The TES4 localized flag (`0x80`) — not \"looks like a small integer\" — decides literal vs\n  `u32` string id. lstring id `0` means \"no string\" (empty, never the `\u003Clstring 0x…>`\n  placeholder, #4072); only a genuinely unresolved id yields the placeholder.\n- `.STRINGS` has no length prefix; `.DLSTRINGS`\u002F`.ILSTRINGS` do (`has_length_prefix`). A\n  flag\u002Fdata disagreement warns loudly (declared length vs NUL offset, ±1 band, #4178)\n  instead of yielding shifted strings.\n- Missing string files degrade to \"no string\" without panic or per-form warn spam; a\n  localized plugin that resolves **zero** tables logs a diagnostic (#4073, `load_order.rs`).\n- Tables and the localized flag are thread-locals: since the parallel walk (#3813) the\n  caller only loads tables (`load_string_tables`) and each walk installs its own\n  `StringsTableGuard` on the walking thread. A guard installed on the caller yields\n  `\u003Clstring 0x…>` placeholders under the pool.\n- The language token is not the file-name segment: Skyrim spells it out\n  (`dawnguard_english.strings`), FO4\u002FFO76\u002FStarfield use a short tag\n  (`Fallout4_en.STRINGS`). `language_candidates` expands both; check it exists before\n  reporting the defect (two audits re-derived it before it was filed, #4168).\n- Decode is UTF-8-first with a cp1252 fallback and that order is load-bearing (#4170:\n  English tables carry real cp1252 bytes, localized tables are real UTF-8). A flat cp1252\n  decode is the regression; the fallback is not a bug.\n- Loose files are found case-insensitively before the archive fallback\n  (`load_with_archive`, #4176) — a case-mismatched mod override must beat the archive.\n**Output**: `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_6.md`\n\n### Dimension 7: `EsmIndex` → ECS Handoff & the Redux-Native Tier\nPaths: `crates\u002Fplugin\u002Fsrc\u002F{record,datastore,resolver,manifest,equip}.rs`, `esm\u002Frecords\u002Findex.rs`; consumers `byroredux\u002Fsrc\u002Fcell_loader\u002Freferences\u002F`, `byroredux\u002Fsrc\u002Fnpc_spawn\u002F`\nFirst step: `grep -rn 'resolve_entity_by_global_form_id\\|find_by_form_id' byroredux\u002Fsrc | head -20`\n**Checklist**:\n- `EsmIndex` is a session-long bag of `HashMap\u003Cu32, _>`; nothing evicts it. Check growth on\n  a large load order against `docs\u002Fengine\u002Fmemory-budget.md` (RAM, not VRAM).\n- Sample high-traffic `Option\u003Cu32>` FormID fields (`SCRI`, `RNAM`, `CNAM`, `PKID`, `XEZN`,\n  teleport `XTEL`): the consumer must resolve via `resolve_entity_by_global_form_id`, not a\n  raw `World::find_by_form_id`. That resolver answers from a lazily rebuilt local-id → entity index\n  owned by `FormIdPool` (`FormIdPool::entity_with_local`, keyed on the `FormIdComponent` structural\n  generation plus pool length; first entity in storage order wins on a duplicate id; `ab3a604bf`,\n  #6338) — a per-call scan of every `FormIdComponent` is the regression (per-actor-per-frame Flee\u002FUseWeapon callers).\n- `equip.rs` biped-slot constants: BMDT vs BOD2 vs FO4 bit meanings differ; each block cites\n  its xEdit definition; slot → `addon_index` (`AddonData::addon_index`) matches\n  *equipment_system*. `equip_template_tests.rs` covers template equip resolution.\n- Redux-native tier: audit for **rot** (compiles against the current `Record` shape; docs\n  consistent with `docs\u002Fengine\u002Fplugin-loading.md`) and dead-but-documented API. \"Unused\" is\n  not a bug on its own — `DataStore` + `DependencyResolver` + `PluginManifest` have no\n  production consumer and are kept as design surface: #5609 (`490e76397`) put status banners on\n  `lib.rs`, `plugin-loading.md` and `architecture.md` and a ROADMAP row. A doc presenting them as\n  the live load path again is the regression; the absence of a consumer is not a finding.\n  Likewise seven typed maps (ENCH, REPU, EXPL, CSTY, IPCT, IPDS, COBJ) are parsed with no\n  runtime reader and annotated as such in `index.rs` + `esm-records.md` (`934385de1`, #6180).\n  `body_parts` (BPTD) left that set when the VATS targeting scan began reading it\n  (`byroredux\u002Fsrc\u002Fsystems\u002Fvats.rs`, #6350); its `index.rs` doc was corrected in `cacdbb955`\n  (#6451) and now says only the dismemberment half is unconsumed.\n**Output**: `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_7.md`\n\n### Dimension 8: Real-Data Validation\nPaths: `crates\u002Fplugin\u002Fexamples\u002F`, `crates\u002Fplugin\u002Ftests\u002Fparse_real_esm.rs`, `byroredux\u002Fsrc\u002F{list_cells,sf_smoke}.rs`\nFirst step: `cargo run --release -p byroredux-plugin --example esm_dim8_coverage -- \u003Cmaster.esm>` (one master at a time)\n**Checklist**:\n- Per `--game`: records seen \u002F decoded \u002F stubbed \u002F skipped and *unknown sub-record codes\n  per record type* (`esm_dim8_coverage` emits the TSV; `esm_dim8_bench` gives parse time\n  + `EsmIndex` totals; other probes: `sf_smoke`, `probe_form`, `dump_record_subs`,\n  `weather_coverage_census` — `ls crates\u002Fplugin\u002Fexamples`; one-liner probes are `inspect.rs`\n  subcommands since `b997ea133`, #5856). Unknown-subrecord share is the\n  coverage signal per-game audits never compute across the whole file.\n- A decode rate that drops between games is a schema-split suspect — correlate with Dim 4\n  `GameKind` arms. Compare Starfield against the `sf_smoke --tsv --recurse` baselines (without `--recurse` only the top rows are emitted and the diff is meaningless) in `.claude\u002Faudit-baselines\u002Fsf-esm\u002F`\n  (regenerated `6cbae341c`, #5758; `sf_esm_baseline_handled_column_tracks_the_dispatch_list` pins\n  their handled column to the dispatch list); a drop\n  is a regression, not a new finding.\n- Report parse **time** and peak RSS per master (ESM parse cost is on every session's\n  boot path; door transitions reuse the resident index through `SharedParseCache` in\n  `load_order.rs` unless the plugin set or a file's length\u002Fmtime changed, `588c87bc4`, #6123;\n  NIF parse cost is `\u002Faudit-performance`).\n- Real-data tests resolve installs through `esm\u002Ftest_paths.rs` (`*_data_dir()` + `require_or_skip`);\n  `BYROREDUX_REQUIRE_GAME_DATA` turns an absent install into a failure on the strict lane (`3e4bfab51`, #6184) — a\n  test that re-inlines a Steam root or returns `ok` on a missing master is the regression.\n- No windowed engine launch (*feedback_no_parallel_engine_launch*); example binaries and\n  default `cargo test` only (see Phase 1 step 4 on `--ignored`).\n**Output**: `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_8.md`\n\n## Phase 3: Merge\n\n1. Read all `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_*.md`; combine into `docs\u002Faudits\u002FAUDIT_ESM_\u003CTODAY>.md`:\n   - **Executive Summary** — findings by severity; coverage posture; which games' real\n     data was actually parsed.\n   - **Record Coverage Matrix** — record type × game × {decoded, stubbed, skipped,\n     unknown-subrecords}. The durable artifact; keep it even with no findings.\n   - **Findings** — grouped by severity, deduplicated.\n   - **Cross-Audit Pointers** — `\u002Faudit-\u003Cgame>` Dim 1, `\u002Faudit-scripting` (VMAD),\n     `\u002Faudit-character` (AVIF\u002Fclass), `\u002Faudit-physics` (collision-relevant placement),\n     `\u002Faudit-exterior`, `\u002Faudit-gameplay`, `\u002Faudit-parsers`.\n2. Deduplicate against the per-game reports read in Phase 1 — a finding already filed under\n   an `\u002Faudit-\u003Cgame>` ESM dimension is `Existing: #NNN`, not new.\n\n## Phase 4: Cleanup\n\n`rm -rf \u002Ftmp\u002Faudit\u002Fesm`; tell the user the report is ready; suggest\n`\u002Faudit-publish docs\u002Faudits\u002FAUDIT_ESM_\u003CTODAY>.md` (domain label `esm-plugin`; plus the\nmatching `game:*` when specific to one title's records).\n","# ESM \u002F Plugin Parser Audit\n\nAudit `crates\u002Fplugin\u002F` (~84k LOC in `src\u002F`) as a parser: GRUP walker, sub-record byte\naccounting, per-record schema dispatch, FormID load-order remap, CELL\u002FWRLD walkers, and\nthe `EsmIndex` → ECS handoff. Per-game audits (`\u002Faudit-fnv`, `\u002Faudit-skyrim`, …) each\nsample one game's slice; this skill owns the parser itself.\n\n**Architecture**: Orchestrator. Each dimension runs as a Task agent (max 3 concurrent).\n\nRead `.claude\u002Fcommands\u002F_audit-common.md` and `.claude\u002Fcommands\u002F_audit-severity.md` for\nshared protocol (dedup, methodology, finding format). Do not duplicate them here.\n\n## Scope\n\n**Crate**: `crates\u002Fplugin\u002Fsrc\u002F` — `esm\u002Freader.rs` (`EsmReader`, `EsmVariant`, `GameKind`,\n`FormIdRemap`, `GlobalSlot`, zlib decompression), `esm\u002Fsub_reader.rs` (`SubReader`),\n`esm\u002Frecords\u002F` (`parse.rs` = the top-level GRUP walker `parse_esm[_with_load_order]`;\n`mod.rs` is a re-export barrel; `index.rs` `EsmIndex`; eight `dispatch_*.rs` routers;\n`grup_walker.rs`; per-type decoders incl. `actor\u002F`, `items.rs`, `items\u002Fconsumable.rs`,\n`container.rs`, `condition.rs`, `weather.rs`, `weather_settings.rs` + `weather_settings_instance.rs`\n(Starfield `WTHS` schema + values), `load_screen.rs`, `pkin.rs`, `misc\u002F*.rs` incl. `story_manager.rs`,\n`location.rs` (`LCTN`), `relationship.rs` (`RELA`), `challenge.rs` (FNV `CHAL`), `music.rs` (`MUSC`; Skyrim `MUST` since `03f9d2158`, #3816 piece 1),\n`lmsw.rs` (Starfield `LMSW`\u002F`MTPT` reflection blobs), `reflection.rs` (the BGS reflection container decoder shared by `WTHS`\u002F`LMSW`\u002F`MTPT`, moved out of `weather_settings.rs` by `ce5796431`, #6272; public paths unchanged via re-exports)),\n`esm\u002Fcell\u002F` (walkers `walkers.rs`, `support.rs`, `wrld.rs`, `helpers.rs`; `mod.rs` is a re-export hub over the\ndata tier `base_objects`\u002F`cell_data`\u002F`index`\u002F`landscape`\u002F`lighting`\u002F`placed_ref`\u002F`worldspace.rs`, `d7c47d741`),\n`esm\u002Fstrings_table.rs`, `equip.rs`, and the Redux-native tier\n(`datastore`\u002F`manifest`\u002F`record`\u002F`resolver`).\n\n**Not in scope**: cell-loader consumption of `CellData` (`\u002Faudit-\u003Cgame>` Dim 1); VMAD\ntranslation (`\u002Faudit-scripting`); NIF (`\u002Faudit-nif`); BSA\u002FBA2\u002FCSG incl. the FO4 previs\nheader → cell-grid recovery (`\u002Faudit-parsers`); `src\u002Fextension.rs` + `crates\u002Fsdk` extension\nmanifests (`\u002Faudit-tooling`); WTHR\u002FCLMT\u002FWATR\u002FLTEX\u002FGRAS *translation* and HNAM sun\nconsumption (`\u002Faudit-exterior` — byte-level decode of those records stays here);\nconsumption semantics of `src\u002Fconsumables.rs` \u002F `expand_leveled_loot` (`equip.rs`) —\ntimed restoratives, container loot, LSCR selection (`\u002Faudit-gameplay`; the decode contract\nstays here, Dim 4); CHARAL formulas (`\u002Faudit-character`).\n\n**Ground truth**: `docs\u002Fengine\u002Fplugin-loading.md`, `docs\u002Fengine\u002Fesm-records.md`,\n`docs\u002Fengine\u002Fpipeline-overview.md`. Every non-obvious decode should cite a\n`wbDefinitions{TES4,FNV,TES5,FO4,FO76,SF1}.pas:line` range (crate docstring in\n`crates\u002Fplugin\u002Fsrc\u002Flib.rs`); a decode with no citation and no test is a guess\n(*feedback_no_guessing*) — flag it.\n\n## Parameters (from $ARGUMENTS)\n\n- `--focus \u003Cdimensions>`: comma-separated dimension numbers. Default: all 8.\n- `--game \u003Cname>`: restrict Dim 8 real-data validation to one game. Default: every game\n  with on-disk data (`_audit-common.md` § Game Data).\n- `--depth shallow|deep`: `shallow` = schema\u002Fcontract check; `deep` = byte-level trace\n  against real masters. Default `deep`.\n\n## Extra Per-Finding Fields\n\n- **Dimension**: Header & GRUP Walk | Sub-Record Byte Accounting | FormID & Load Order |\n  Record Schema Dispatch | CELL \u002F WRLD Walkers | Localized Strings | ESM→ECS Handoff |\n  Real-Data Validation\n- **Record \u002F Sub-record**: 4-char code(s) (e.g. `NPC_` \u002F `ACBS`), or `—`.\n\n## Phase 1: Setup\n\n1. Parse `$ARGUMENTS`. `mkdir -p \u002Ftmp\u002Faudit\u002Fesm`.\n2. `gh issue list --repo matiaszanolli\u002FByroRedux --limit 200 --json number,title,state,labels > \u002Ftmp\u002Faudit\u002Fesm\u002Fissues.json`.\n3. Read the latest `docs\u002Faudits\u002FAUDIT_ESM_*.md` plus the ESM dimensions of the latest\n   `AUDIT_{FNV,SKYRIM,FO4,STARFIELD}_*` reports — this crate's findings historically live\n   there, so **that is where your duplicates are**.\n4. `cargo test -p byroredux-plugin`; record the pass count (a pre-existing failure is\n   context, not a finding). **Never run `--ignored` \u002F `--include-ignored` on this crate**\n   — the real-data tests parse whole masters (Starfield ≈ 4 GB parsed) and have\n   OOM-killed sessions past 20 GB; use Dim 8's single-file probes instead.\n\n**Suggested emphasis**: the 2026-08 → 09-11 reports yielded mostly Localized Strings,\nESM→ECS Handoff, CELL\u002FWRLD and FormID remap; the 2026-09-21 report's MEDIUMs were Byte\nAccounting (Oblivion `LVLO`\u002F`LVLD`, FO4 `TERM`, `LTEX.GNAM`) and Header\u002FGRUP (inflation\nceiling, skip-arm clamp), all found by Dim 8's real-data census — run it, don't skip it.\nThe 2026-09-29 report's MEDIUM\u002FLOWs were again Byte Accounting + FormID: non-FormID `u32`s\nfed to the remap (FO4 `TRDA` `FFFF` sentinel, Oblivion `EFID` char4 codes), fixed in\n`9b099b31f` (#5075\u002F#5076) — see Dim 3 shape (4). The 2026-10-08\u002F10-09 MEDIUMs were decodes that\ncontradict their own `wbDefinitions*.pas` entry (SM `SNAM`\u002F`RNAM`, REGN `WNAM`, PKIN `VNAM`,\nSCOL\u002FPKIN `FLTR`, `PKDD` Dialogue Type offset — all since fixed, #5493 `136048a95` \u002F #5492 `dae08000d`) — open the xEdit definition for every decoder\ntouched since the last report rather than trusting its doc comment.\n\n## Phase 2: Dimensions\n\n### Dimension 1: Header Detection & GRUP Walk (highest blast radius)\nPaths: `crates\u002Fplugin\u002Fsrc\u002Fesm\u002Freader.rs`, `esm\u002Frecords\u002F{parse,grup_walker}.rs`\nFirst step: `grep -rn 'group_content_end(' crates\u002Fplugin\u002Fsrc | grep -v 'tests\u002F\\|\u002F\u002F\u002F'`\n**Why first**: a header-size or GRUP-bounds error desyncs the whole file; everything\ndownstream decodes structurally valid garbage.\n**Guards** (run, confirm live — not `#[ignore]`d, not vacuous):\n`reader::tests::game_kind_from_header_maps_real_master_hedr_values`,\n`grup_walker::tests::every_recursive_grup_walker_honours_the_shared_depth_cap` (table of\nwalkers nested past `MAX_GRUP_NESTING_DEPTH`; a walker missing from the table is invisible\nto it — `EsmReader::for_each_record`, the bounded walk the census\u002Fprobe examples share since\n`0b3ae0d13` (#5819), is not in it and is pinned only by\n`reader::tests::for_each_record_filters_recurses_and_skips_unwanted`), `reader::tests::bounded_group_content_end_clamps_to_parent_end`, and the\n`compressed_record_*` \u002F `inflation_ceiling_clears_every_observed_vanilla_shape` tests.\n**Checklist** (what the guards cannot see):\n- `EsmVariant::detect` (`data[20..24] == b\"HEDR\"` ⇒ 20-byte Oblivion headers) has its\n  length guard before the slice; no caller hardcodes a variant outside tests \u002F\n  `with_variant`.\n- `GameKind::from_header(variant, hedr_version, record_version)` uses **banded** float\n  compares plus the TES4 record version as a second key (Skyrim LE and FO3 GOTY both stamp\n  HEDR 0.94 → record version 40 vs 2; FO4 DLC 0.95 → 131). Vanilla HEDR: FO3 0.94, FO4 1.0,\n  Starfield 0.96, FNV 1.34, Skyrim SE 1.71, **FO76 — a live-service value that drifts with patches** (68.0 → 266.0 → 279.0 → 280.0 \u002F record version 210 as of 2026-11-08, #6779; floor 60.0). A mis-band is not\n  latent: FO4-only arms in `items.rs` (`ARMO DATA` swaps value\u002Fweight\u002Fhealth order at the\n  same 12-byte length, `WEAP DATA` empty, `BOOK` 8-byte) would silently swap armor stats\n  and zero every weapon. Any new per-game schema split widens this blast radius — check.\n- Missing\u002Fshort HEDR falls back to `GameKind::Fallout3NV` (`Default`): confirm each call\n  site is deliberate and no branch treats \"defaulted\" as \"detected FO3\". `character_rules_profile`\n  reads `hedr_version == 0.0` as defaulted, so only a real 0.85\u002F0.94 header picks the FO3 profile (`dc771cf59`, #6780).\n- **Universal GRUP bound** (#3503\u002F#3721\u002F#4076\u002F#4644): every self-recursive walker takes\n  `bounded_group_content_end(header, depth, parent_end, name)` and threads `depth + 1`\n  into its `_inner`; **skip arms** too seek to the parent-clamped end via `seek_to` (the\n  depth-cap arm inside `bounded_group_content_end` included). The raw `group_content_end`\n  may appear only in the non-recursive top-level loop (`records\u002Fparse.rs`, the only\n  `skip_group` caller), `cell\u002Fwrld.rs::parse_wrld_group` and `grup_walker.rs::walk_info_records`'\n  nested-group skip (both `.min(end)` themselves). Regression = a new recursive walker on\n  the raw accessor, a dropped `depth`, or a recurse\u002Fskip site that loses the `parent_end`\n  clamp (guards `overrunning_child_grup_in_a_skip_arm_seeks_to_parent_end`,\n  `bounded_group_content_end_depth_cap_skip_is_parent_clamped` pin fixtures, not every site).\n- `FLAG_COMPRESSED`: `data_size >= 4` checked before the subtraction; declared size is\n  bounded by `record_inflation_ceiling` (`min(64 MiB, max(64 KiB, compressed×2048))`, from a\n  seven-master census — worst real ratio 785.9:1, a Starfield `SFTR`, #4640; 512:1 rejected\n  82 vanilla records and dropped the whole plugin) and the decoder is held to\n  `take(declared + 1)`; mirrors `byroredux_bsa::safety::inflate_bounded` (#3410).\n  Regression = either bound removed or the two implementations diverging.\n**Output**: `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_1.md`\n\n### Dimension 2: Sub-Record Byte Accounting (densest bug class)\nPaths: `crates\u002Fplugin\u002Fsrc\u002Fesm\u002Fsub_reader.rs`, `esm\u002Frecords\u002F**\u002F*.rs`, `esm\u002Fcell\u002Fsupport.rs`\nFirst step: `git log --since=\u003Clast report> --name-only --format= -- crates\u002Fplugin\u002Fsrc\u002Fesm\u002Frecords | sort -u` (decoders touched since the last report), then re-derive their widths from the cited xEdit range.\nESM analogue of `\u002Faudit-nif` Dim 1: a wrong field width shifts every later field and the\nrecord still \"parses\" with wrong numbers.\n**Guard**: `records::test_support::tests::no_module_redeclares_a_local_subrecord_builder`\n(fixture hygiene only — nothing here guards decode widths; since #5454, `29f8fa2ef`, it flags\nany fn returning `SubRecord` built from a parameter 4-CC, not only fixed names).\n**Checklist**:\n- Decoders read through `SubReader`; flag direct raw-slice indexing and any private\n  cursor type. `take` \u002F `wstring` \u002F `counted` (a failed compound read leaves the reader where it\n  started) carry the VMAD (`script_instance.rs`), `weather_settings_instance.rs` and NVNM\n  (`misc\u002Fworld.rs`) shapes since `e04caa7e8` (#6367) — the three per-decoder cursors and the\n  `from_le_bytes(..try_into().unwrap())` sites in `reflection.rs` are gone (a width that disagrees\n  with its type now declines instead of panicking); a new `Option`-returning cursor or\n  `unwrap` on a slice-to-array in a decoder is the regression. FormID arrays read through\n  `SubReader::u32_array`, which declines a ragged body with the cursor unmoved (`f93b3463b`, #6782 — MUSC `TNAM`,\n  MUST `SNAM`, WTHR `HNAM`\u002F`WGDR`); a hand-rolled `chunks_exact(4)` that drops a tail is the regression.\n- The `*_or_default` family swallows short reads: fine for optional tails, a finding\n  mid-fixed-layout (silent zeros). Classify every call site.\n- Fixed-size sub-records check the declared length against the schema; version-gated tails\n  are gated on `GameKind` or remaining length with an xEdit citation. Length gates and field\n  offsets are named constants (`PROJ_DATA_*` \u002F `PROJ_DNAM_*`, `EXPL_*`, `PKDT_*`, `AOR2_LEN`,\n  `COBJ_NAM1_LEN`, `SKYRIM_GLARE_TABLE_LEN`; `004a03fc3`, #6586), and a decoder seeks to a layout\n  offset with the forward-only `SubReader::skip_to_or_eof` rather than hand-summed `skip_or_eof` gaps — a\n  new bare numeric gate or gap chain is the regression.\n- Repeating rows (`CTDA`, `CNTO`, `NVTR`\u002F`NVEX` → `decode_nvtr_row`\u002F`decode_nvex_row`,\n  `LVLO`): `len \u002F stride` with an explicit remainder check; a non-zero remainder is a\n  decode bug.\n- `rgb_color` (3 B) vs `rgba_color` (4 B): swapped pairs shift every later byte. Colours\n  are raw monitor-space floats — never flag a missing sRGB conversion (*feedback_color_space*).\n- Known offset maps — verify against the code, not older reports: `parse_race` TES5\n  `DATA` starting pools at 36\u002F40\u002F44 (new fields land at ≥48; TES4\u002FFO3NV and FO4\u002FFO76 arms\n  differ); the four pre-FO4 WATR decoders share one head, `decode_legacy_head` driven by a\n  per-game `HeadLayout` table (`626be5d12`, #5796; parity test\n  `legacy_head_decodes_every_layout_through_one_pipeline`) — a per-decoder head fix is the\n  regression; WATR `SNAM` is a remapped sound FormID (`sound_form`, `1dd217412`, #6045);\n  WATR `decode_data_fo3nv` shared 0..28 prefix (wind speed\u002Fdirection\u002Famplitude\u002F\n  frequency at 0\u002F4\u002F8\u002F12, direction degrees-on-the-wire converted once), pinned by\n  `parse_watr_186_byte_record_reads_colors_at_40_44_48` and\n  `wind_direction_converts_shipped_degrees_on_the_fo3nv_dnam_arm` (this field moved twice).\n- WTHR (`records\u002Fweather.rs`) sizes are per game *and* form version: `PNAM` cloud colours step\n  `cloud_color_slots(game, len)` TOD slots per layer (FO3\u002FFNV 6 at ≥96 B, Creation-era 8 at\n  1,024 B, else 4; `7f4c25e3e`, #6037); Skyrim `NAM0` is accepted only at the version-prefix\n  sizes `skyrim_nam0_groups` maps (10\u002F13\u002F14\u002F17 groups) and `DALC` also at 24 B (`67433ee3a`,\n  #6038); cloud-layer FourCCs `00TX`..`O0TX` index `byte - '0'` via `skyrim_cloud_layer_index`\n  for Skyrim **and** FO4\u002FFO76\u002FStarfield (`f16741886` #6040, `3ab1b5557` #6039 — FO3\u002FFNV ignore\n  them, `parse_wthr_00tx_fourccs_are_inert`); Oblivion `CNAM` is the lower layer 0 and `DATA`\n  bytes 1-2 the layer speeds (#6041), and its cloud tints are `NAM0` group 2 (Clouds-Lower →\n  `cloud_layer_colors[0]`) and group 9 (Clouds-Upper → `[1]`) — read as FO3\u002FFNV's Unused until\n  `7ed4c7dca` (#6258; `SKY_GROUP_2`\u002F`SKY_GROUP_9`); FO3\u002FFNV 24-byte `FNAM` carries fog power (#6042). The two decoders (`parse_wthr` for Oblivion\u002FFO3\u002FFNV, `parse_wthr_creation` for Skyrim\u002FFO4\u002FFO76\u002FStarfield) share the RGBA unpack\n  `sky_color_at`, the noon\u002Fmidnight synthesis `synthesize_noon_midnight` and the fog head\n  `read_fog_head` \u002F `read_fog_power` (`ac9fa19a8`, #6223); FO4\u002FFO76\u002FStarfield now run the Skyrim-lineage decoder with a per-game NAM0 shape table (`nam0_layout`) and FNAM reader (`read_creation_fnam`), and Skyrim-only reads (DALC, NAM2\u002FNAM3, MNAM\u002FNNAM, the 272-byte side table, the wind flag) are gated on `game`. Starfield's 608-byte NAM0 still takes the FO3-stride read (`Nam0Layout::Fo3Stride`) — no xEdit SF1 layout was on hand to move it; check before touching. A WTHR fix applied to one copy of the shared pieces is the regression. `cargo run --release -p byroredux-plugin --example inspect -- wthr-dump \u003Cgame> \u003CESM>` before\u002Fafter diffs every real master byte-for-byte.\n- Strings: terminator consumed exactly once; a missing terminator cannot read past the\n  sub-record.\n- Leveled lists (`parse_leveled_list_for_game`): FO76 split `LVLO` (4 B ref) + float\n  `LVLV`\u002F`LVIV`\u002F`LVCV` companions only under `GameKind::Fallout76`; the legacy row accepts\n  ≥8 bytes (Oblivion omits Count → default 1) and `LVLD` bit `0x80` becomes `LVLF 0x01`, not\n  chance-none 128 (#4638). A sub-8-byte legacy `LVLO` must never become a valid reference.\n**Output**: `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_2.md`\n\n### Dimension 3: FormID Remap, Load Order & ESL Space\nPaths: `crates\u002Fplugin\u002Fsrc\u002Fesm\u002Freader.rs` (`FormIdRemap`, `GlobalSlot`), `esm\u002Frecords\u002Ftests.rs`, `esm\u002Frecords\u002Fcommon.rs`, `byroredux\u002Fsrc\u002Fcell_loader\u002Fload_order.rs`\nFirst step: `cargo test -p byroredux-plugin -- every_record_parser_takes_a_remap parsers_that_take_a_remap no_parser_with_a_remap remap_fid_has_exactly_one`\n**Guards**: `records::tests::all_record_parsers` walks `records\u002F` at test time and requires\nevery `pub fn parse_*` to take a `remap` parameter or sit in `EXEMPT_NO_U32_READS`\n(mechanically re-verified) \u002F `EXEMPT_JUSTIFIED` (written non-FormID reason);\n`parsers_that_take_a_remap_actually_use_it`; `remap_fid_has_exactly_one_definition`;\n`no_parser_with_a_remap_in_scope_passes_an_identity_remap`. The `cell\u002F` tier is guarded\nstructurally (remap is a required parameter of `read_form_id`). Review **new exemption\nentries** in the diff — each is a human decision, not a proof.\n**What the guards cannot see — the class keeps recurring in three shapes**:\n(1) an unremapped field inside a *shared* decoder several parsers call\n(`CommonNamedFields::from_subs_with_remap`, #4067); (2) a GRUP **label** that encodes a\nFormID (DIAL topic-children label vs remapped DIAL id, #4079 — check every label-dispatch\nsite like a sub-record field); (3) a `HashMap\u003Cu32, _>` in `EsmIndex` keyed by, or compared\nagainst, a raw plugin-local id. **Inverse shape (4)** — a non-FormID `u32` routed *into*\n`remap_fid` (only `0` short-circuits, so every row warns through the out-of-range arm on a\nplugin with masters): xEdit `wbFormIDCk([…, FFFF])` fields go through\n`remap_fid_or_sentinel`, and Oblivion `EFID` (a `wbChar4` effect code resolved via\n`magic_effects_by_code`) through the game-gated `remap_efid` (`records\u002Fcommon.rs`;\n`9b099b31f`, #5075\u002F#5076); PKIN `VNAM` is xEdit's integer *Version*, stored raw as\n`PkinRecord.version` (`0d436e642`, #5422, pinned by `pkin_vnam_version_stays_raw_under_remap`).\nA new sentinel-bearing field, char4 code or plain integer calling `remap_fid` inline is the\nregression. SCOL\u002FPKIN `FLTR` is a `wbString` filter path: both parsers store `filter: String`\nvia `read_zstring` with no `remap_fid` (fixed in `136048a95`, #5493; pinned by\n`pkin_fltr_filter_path_stays_raw_under_remap` + `parse_scol_fltr_decodes_the_filter_path`).\nCTDA `param_1` is remapped only for functions whose first parameter is a FormID:\n`condition.rs::param1_is_form_id` mirrors the scripting catalog by raw function index (rows\nfor fn 56\u002F71\u002F74 were missing until `722c06a76`, #5637; M47.2 added the location\u002Fkeyword\u002F\nrelationship\u002Fquest-variable rows); fn 32\u002F372\u002F382 (GetInSameCell \u002F IsInList \u002F GetHasNote, FO3\u002FFNV) joined in `102e4f5cd`, #6460; `param2_is_form_id` is the second-parameter twin (fn 605\u002F181\u002F\n576\u002F606\u002F608 — everywhere else `param_2` is a literal); the drift guard lives in the scripting\ncrate (`param1_form_id_table_matches_the_condition_catalog`) — a new catalogued\nFormID-param function needs its row.\n**Checklist**:\n- `GlobalSlot::Regular` keeps 24 bits and regular allocation stops at `0xFB` — `0xFC` is the\n  Papyrus VM's synthetic alias-owner byte (`0edc61bbf`, #5988; a regular `0xFC` slot is the\n  regression); `GlobalSlot::Light` (`0xFE` space) packs a 12-bit\n  sub-index and keeps only the low **12** object-id bits (`0x0FFF` masks on both sides);\n  `GlobalSlot::Medium` (`0xFD`, Starfield) packs an 8-bit sub-index + 16-bit object id.\n  The TES4 master bits are per game (#4639, `read_file_header`): Starfield small `0x100` \u002F\n  medium `0x400`, Skyrim SE + FO4 light `0x200`, every other game none — a `0x200` test on\n  Starfield (*Update*) or a pre-ESL game is the regression. `allocate_global_slot`\n  (`load_order.rs`) must keep the three spaces disjoint.\n- `FormIdRemap::remap` arms (`FormIdScheme::Positional`, every game but Starfield): raw `0` → `0`\n  (null sentinel, must not become a live ESL id);\n  self-reference (`mod_index == master_slots.len()`); in-range master; standalone with no\n  masters (pass through, `debug` — the vanilla Oblivion `0x01` artifact, #1308; must NOT be\n  \"fixed\" into a clamp — two forms would collide in `EsmIndex`); out-of-range with masters\n  (pass through, `warn`). Starfield plugins get `FormIdScheme::Starfield` (chosen per plugin\n  from its detected game in `load_order.rs`; `0a2955d33`, #6118): `0xFE` + 12-bit ordinal\n  among the file's **small** masters, `0xFD` + 8-bit ordinal among its **medium** masters, any\n  other top byte an ordinal among its **regular** masters only, ordinal == that kind's count\n  = self, an unlisted master passed through with a `warn` (`remap_starfield`; positional\n  decode had two small masters claiming 61k shared ids). Pinned by the `starfield_*` tests in\n  `reader.rs`; a fixture or new caller building `FormIdRemap` for Starfield with the default\n  scheme is the regression.\n- Master list read in file order; a missing master fails diagnosably, not as a silently\n  shifted slot table.\n- Multi-plugin is live (`--master` repeatable → `parse_esm_with_load_order`); `parse_esm`\n  passes `None`. Verify every embedded FormID in a newly-touched parser goes through\n  `remap_fid`. The guard walk sees only `pub`\u002F`pub(crate)`\u002F`pub(super) fn parse_*` in\n  `records\u002F` (files named `tests.rs` and `#[cfg(test)]` modules excised) — `decode_*` \u002F\n  `from_subs*` helpers and `cell\u002F` are outside it.\n- Parallel walk (#3813, `parse_record_indexes_in_load_order_with_archive`): walks run on\n  the rayon pool, but slot allocation, remap construction, `.STRINGS` loads and the\n  `merge_from` fold stay on the calling thread in load order — fold order, never completion\n  order. Guard: `load_order_parallel_tests::parallel_walk_matches_the_inline_walk_on_a_localized_master_chain`.\n**Output**: `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_3.md`\n\n### Dimension 4: Record Schema Dispatch & Coverage\nPaths: `crates\u002Fplugin\u002Fsrc\u002Fesm\u002Frecords\u002F{parse,index,items,container,actor_value_derive,load_screen}.rs`, `records\u002Fdispatch_*.rs`, `records\u002Fmisc\u002F*.rs`, `crates\u002Fplugin\u002Fsrc\u002Fequip.rs`\nFirst step: `cargo test -p byroredux-plugin -- dispatch_handled_fourccs every_index_map_is_a_category`\n**Guards**: `records::tests::dispatch_handled_fourccs_matches_the_live_dispatch_arms`\n(`DISPATCH_HANDLED_FOURCCS` ↔ the live match in `parse.rs`; era-gated arms count as\nhandled, `PDCL` is deliberately absent; `LCTN`\u002F`LCRT`\u002F`RELA` are routed through `dispatch_misc_stub` into typed maps since M47.2, and `LCTN` is in the list — the stale \"LCTN has no arm\" prose was corrected in `cacdbb955`, #6451; `AORU` is a `dispatch_misc_gameplay_a` arm);\n`index::tests::every_index_map_is_a_category_or_a_recorded_exclusion` (every `EsmIndex`\nmap is a `categories()` row — `map_category!` or a hand-written row recognized by its count\nclosure, like `dialogues` and `game_settings` — or a reasoned exclusion: `record_types`, the derived\n`generic_greeting_form` cache, the derived `game_settings_by_edid` side-table; the non-`HashMap` `deleted_record_metadata` \u002F\n`skipped_unconsumed_groups` sit in its `MANUALLY_MERGED` table); `cell::plugin_loading_doc_pin_tests::the_documented_esm_cell_index_lists_every_field` and\n`…::the_audio_record_split_matches_the_dispatcher` (docs ↔ code).\n**Checklist**:\n- Build the live matrix per record type: typed decode \u002F minimal stub\n  (`parse_minimal_esm_record`, EDID+FULL — `dispatch_misc_stub.rs` also hosts typed\n  decoders: `LSCR`, `CLOT`\u002F`CCRD`\u002F`CMNY` → `items`) \u002F skipped. Report the delta against\n  *record_type_catalog* as coverage, not bugs. A stub must advance the reader correctly;\n  the unknown-record path skips by declared size and never `warn`s per record on a vanilla\n  master.\n- Per-game schema splits within one record (`ARMO\u002FWEAP\u002FAMMO DATA`, `BOD2` vs `BMDT` vs\n  Skyrim's pre-BOD2 `BODT` — 8 or 12 B, same leading biped mask, read in both `ARMO` and\n  `ARMA` since `479414ffe` (#5358; every Skyrim.esm ARMA authors it, so BOD2-only decoding\n  zeroed all 766 masks), `SCOL\u002FPKIN\u002FTXST`, FO76 `LVLO`) switch on `GameKind`. Oblivion's 4-byte\n  `ARMO BMDT` is a u16 Biped Flags + General Flags byte — the mask is the u16 only\n  (`a8e37e5fd`, #5696; a u32 read put General Flags in bits 16-23 on 661 of 996 armors);\n  FO3\u002FFNV keep the u32. **`ACRE` is not Oblivion-only**\n  (FO3 ships 3,349 `ACRE` vs 2,154 `ACHR`) — flag any new per-game gate on it.\n- **Consumables \u002F items decode contract** (decode only; consumption is `\u002Faudit-gameplay`):\n  `ALCH` effect chains via `parse_alch_for_game`; `MgefRecord.instant_restoration_av` via\n  `parse_mgef_for_game`; Oblivion `parse_clot` → `ItemRecord`; `IMOD`\u002F`CCRD`\u002F`CMNY`\n  carried as items; `LVLI` multi-pick (flag `0x04`) vs single-pick highest-eligible,\n  pinned on the shipped FNV master. `expand_leveled_loot` retains unknown terminal ids and\n  saturates counts — check it agrees with the decoder's `LeveledEntry` semantics.\n- **`LSCR`** (`parse_lscr`, header flags via `extract_records_with_flags`): `LNAM` stores\n  grid **Y before X**; malformed known fields land in `malformed_fields` rather than\n  producing an unrestricted screen; truncated fixed fields are safe and visible.\n- **`TPLT` \"Use Stats\"** resolves each absent stat *down the chain* to the deepest record\n  that authors it (`resolve_inherited_field`, #4086; `TPLT_MAX_DEPTH` 6) — the terminal\n  outranks a shallower record and a one-hop chain is unchanged. Check new stat fields join\n  the per-field walk instead of comparing only the chain ends. \"Use Model\u002FAnimation\"\n  (`TEMPLATE_FLAG_USE_MODEL_ANIMATION`, `ResolvedNpc::model`) resolves model-less templated\n  `CREA` shells through their `LVLC` pick (`011ad0c07`, #6075; 63% of FNV fauna placements). A terminal `level` of 0 (30\u002F3,816 FalloutNV.esm `NPC_`) backfills from the authored entry level of the deepest `LVLN` the walk picked through (`last_pick_level`, `ResolvedNpc::level()`), so its owned leveled lists are not expanded at level 0; an authored level or a list-less chain is unchanged (`4fbff2c6c`, #4232 — `effective_actor_level` itself stays unfloored, #3081).\n- `EsmIndex::merge_from`: last-write-wins matches Bethesda override semantics; `game` is\n  only adopted when `other.total() > 0` (a failed-parse `EsmIndex::default()` must not\n  relabel the load order as FO3\u002FFNV, #3403); `character_rules` is first-non-`NONE` wins.\n  **Exception — `dialogues`** (`168b81322`, #5375): an override DIAL replaces only the\n  header fields and folds its INFOs into the master's list by FormID (same id in place, new\n  id after its `PNAM` predecessor), and the prune arm drops Deleted-INFO tombstones from every\n  topic; whole-record `extend` erased 8.5–9.9k FNV INFOs per DLC. An override's `PNAM == 0`\n  run keeps authored file order through one per-override contribution cursor\n  (`fold_infos_into_topic`, `5356c8780`, #5494 — the first contribution goes to the front, later\n  ones follow the previous; the run's position relative to the master's heads is an unsourced\n  engine choice). Since `0c2bd4d6d` (#5644) the fold is one pass over a FormID → node map;\n  `fold_info_into_topic_reference` is the test-only one-at-a-time twin and\n  `batched_info_fold_matches_the_one_at_a_time_fold` pins that the two agree.\n  `game_settings` is also a hand-written category row: GMST resolves by EditorID in load order, not FormID\n  luck — `insert_game_setting` (the only parse-path insert) keeps `game_settings_by_edid`\n  (lower-cased EditorID → winning FormID) coherent, `game_setting_float` reads it first, and the\n  prune arm drops pointers into tombstoned FormIDs (`824bb58c6`, #6350; pinned by\n  `game_setting_duplicate_editor_id_across_distinct_form_ids_resolves_last_loaded`). A parse path\n  inserting into `game_settings` directly leaves the linear-scan fallback (test fixtures only) serving.\n  Top-level maps merge through `categories()`; `EsmCellIndex::merge_from` destructures\n  exhaustively (#4904 — a `..` there is the regression that dropped `landscape_grasses`).\n  A CELL override's record fields come from the override **as parsed** — an omitted\n  sub-record is omitted on purpose (Update.esm drops `XCWT`, a DLC drops `XCRI`); only child\n  records (placements, landscape, navmeshes, pathgrids) and a missing EDID inherit from the\n  base (`merge_cell_override`, exhaustive `CellData` destructure; `2fa227d72`, #6086, pinned by\n  `cell_record_fields_come_from_the_winning_override` \u002F `child_records_still_inherit_from_the_base`).\n  A REFR an override re-authors under another CELL is swept from every other held cell\n  (`765e387a0`, #6084, `a_refr_moved_into_another_cell_leaves_one_copy`).\n- M47.2 added typed maps: `locations` (`LCTN`, `misc\u002Flocation.rs`), `location_ref_types` (`LCRT`),\n  `relationships` (`RELA`, `misc\u002Frelationship.rs`), `condition_forms` (Starfield `CNDF`),\n  `keywords` (`KYWD` EDID only), `SNDR` into the `sounds` map via `parse_sndr` (`soun.rs`),\n  RACE FO4\u002FFO76\u002FStarfield `SRAC`\u002F`SADD`\u002F`SAKD`\u002F`SGNM`\u002F`SAPT`\u002F`STKD`\u002F`SRAF` subgraph data (`SubgraphRole::from_raw(raw, game)`: value 3 is *Linking Only* on FO76\u002FStarfield and *Idle* on FO4, Starfield 5–7 are Mt\u002FWeapon\u002FFurnitureGeneration; `SADD` stays one-per-race, not per entry — a raw scan of all 55 Starfield masters finds 17 races authoring it once, ahead of the first entry; `40cebd21d`, #6621), `KWDA` on\n  `CommonNamedFields`, PERK entry bodies (`PerkEntry`\u002F`PerkEntryBody`, EPFT\u002FEPFD per the\n  xEdit layout), and a \"Use Base Data\" template chain terminal (`ResolvedNpc::base_data`). The\n  `EsmIndex::categories()` count is pinned in `records::tests` (117 on 2026-11-08) — read the live\n  number there; each new map must be a category row or a recorded exclusion. M43 added FO4 `AORU`\n  attraction rules (`attraction_rules`, `parse_aoru` in `misc\u002Fworld.rs`) and the `KWDA` side tables\n  `furniture_keywords` (FURN) \u002F `placed_object_keywords` (FURN, FLOR, ACTI, CONT; `kwda_keywords` in\n  `common.rs`) — all three are category rows; `complex_scene_object` (the `DOBJ` `CMPX` pair, read\n  by `complex_scene_object` in `dispatch_misc_stub.rs`; later plugin wins in `merge_from`) is a scalar\n  and a recorded exclusion. FNV `MSET` is typed (`parse_mset` → `MediaSetRecord`, `misc\u002Fmedia_set.rs`;\n  `media_sets` was a `MinimalEsmRecord` stub, `9ee802d57`). Skyrim `MUSC` (remapped `TNAM`, `parse_musc`, which takes the remap — no remap-free entry point, #6788) and `MUST` (`parse_must` → `music_tracks`, a category row; `MUST` decodes for Skyrim, FO4 and FO76 (one shared layout, #6790); only Starfield lays it out differently) decode in `misc\u002Fmusic.rs`, and `first_playable_track` resolves REGN `RDMO` → `MUSC` → first playable `MUST` (palettes descend, depth-capped; `03f9d2158`). #3816 stays OPEN for its other two pieces (Oblivion `RDMD`; FNV `MSET` consumption) — a typed `music_tracks` map is not a finding.\n- `actor_value_derive.rs` is the CHARAL feed — formulas belong to `\u002Faudit-character`.\n- Settled decodes — verify they hold, do not re-derive: `INAM` is one FormID array (#3356);\n  `CREA CNAM` is not a class (#3383); `FACT` rank ladder (#3338); `ARMO` contributes every\n  race-matching `ARMA` (#3357), `MOD3` is the female mesh (#3414); a `REFR` tombstone\n  removes the placement wherever it lives (#3362); FO76 `HEDR` is patch-dependent — 279.0 on the 2026-09-20 patch, never pin it (#3405, #4643);\n  DIAL quest ownership reads `QSTI` **or** `QNAM` (Skyrim authors `QNAM`; `parse_dial`); FO3\u002FFNV\u002FOblivion INFOs also carry their **own** owning quest in `InfoRecord.quest` (`QSTI`, remapped, 23,247\u002F23,247 FNV INFOs; `dbc07e8f0`, #5271 — Skyrim+\u002FFO4 author none, `0` = use the topic's ownership); INFO `DATA` is typed `InfoDataHeader` (info_type \u002F next_speaker \u002F flags1 \u002F flags2; Goodbye = Flags 1 bit 0) and Skyrim's 8-byte `DATA` lands raw in `skyrim_data` (`25b678106`, #5295); `SMBN`\u002F`SMEN`\u002F`SMQN` decode into `story_manager_nodes` (`misc\u002Fstory_manager.rs`, #5366 closed — the SM dispatches live): `SNAM` is the **previous** sibling (xEdit *Previous Node*; `846e4a6dd`, #5385 — the same-parent census holds in both directions and cannot settle it), `SMQN` `RNAM` is stored hours × 24 and decoded ÷ 24 (xEdit scale `1\u002F24`; `a621d5352`, #5386 — node `HNAM` stays raw), and `XNAM`\u002F`MNAM`\u002F`HNAM`\u002F`QNAM`\u002F`FNAM`\u002F`UNAM` + `DNAM` `0x2`\u002F`0x40000` are named from xEdit (`5489cbe65`, #5420; per-quest `FNAM`\u002F`UNAM` live on `SmQuestLink` beside the `NNAM`\u002F`RNAM` they follow — a node-level field let each later quest overwrite the last, `0edd1dede`, #5515). `FNAM` is xEdit's current `wbUnknown` (the \"24 Hours Till Reset\" reading is withdrawn); its bit 2 is consumed as an **inferred** per-link shares-event (`SM_LINK_FNAM_SHARES_EVENT`, `SmQuestLink::keeps_event`, `af51f6730`) — flag it only if a source contradicts. `DNAM & 0x40000` (`SM_DNAM_NUM_QUESTS_TO_RUN`) gates `MNAM` via `SmNodeRecord::num_quests_to_run`, `XNAM` is `max_concurrent_quests`, and node `HNAM` is the hours-until-reset window (`reset_hours`) — all three are runtime-gated now; INFO Flags 1 bit 5 = Random End (`random_end`, `0436bea5c`, #5397); REGN `WNAM` is the owning **worldspace** (`worldspace_form`, remapped), never a weather, and REGN `CNAM` is xEdit-undefined with zero vanilla occurrences (`bd052048a`, #5421); `NPC_.WNAM` is the per-NPC skin ARMO (`worn_skin`, remapped, no game gate — pre-Skyrim ships none; `edb5fbdfe`, #5359); Oblivion `RACE`'s body-section `ICON` run (INDX restarts at 0 past `NAM1`) lands in `body_part_textures` (`1b45763fa`, #5487); Starfield `WTHS` decodes the REFL\u002FRDIF reflection schema (`weather_settings.rs`, reflection container in `reflection.rs`, #5364; the DIFF walk is depth-capped at `MAX_NESTING_DEPTH` 64, `02187c7f9`, #5687, pinned by `hostile_self_referential_diffs_decline_at_the_depth_cap`) and, since `2c203278f` (#5627), the instance values (`weather_settings_instance.rs`: root `OBJT` value tree + `DIFF` overrides with `LIST`\u002F`MAPC`\u002F`USER`\u002F`USRD` side chunks; grammar grounded from `Starfield.esm` itself — any walk\u002Fschema disagreement declines the whole instance to the census-only state, never guesses); `EsmIndex::synthesize_wths_weathers` runs on the merged index after the load-order fold (`load_order.rs`) and lifts only the grounded fields (day\u002Fnight imagespace, `Colors.Sun`\u002F`Sunlight`\u002F`FogNear`) into a `WeatherRecord` under the WTHS FormID in `weathers` — fog distances, wind and transition floats stay unlifted (real-data 181\u002F181 census in `parse_real_esm.rs`, ignored lane); `DIFF` is (u16 field index, inline value) pairs to the `0xFFFF` terminator and `USRD`\u002F`MAPC` join the instance census (`f0f8dceef`, #5514; real-data pins 163 in-range indices \u002F 47 `USRD`); the CDB builtin ids live in one table (`1f56d5742`, #5615); FO76 `LSCR` decodes on the modern (FO4-shape) arm incl. `BNAM` → icon (`47f927cbf`, #5345); FO3\u002FFNV `PKDD` Dialogue Type is the u32 at offset 16, and Oblivion `PKDT` (4 B) \u002F `PTDT` (12 B) legacy shapes are accepted (`dae08000d`, #5492\u002F#5504); FO3\u002FFNV non-auto-calc NPCs keep their authored `DATA` SPECIAL in `NpcRecord::data_attributes` (`4957536ba`, #5338); FO4 `NPC_` template flags resolve per flag through `template_actors` (`TPTA`, 13 entries in xEdit `wbTemplateFlags` order, `0` = use `TPLT`; `99c22a8db`, #5498); `MSWP` `CNAM` is the Color Remapping Index palette row (`color_remap_index`, `0b2ffed89`, #5497); `MGEF` `DATA` offsets\u002Fflags are named constants in `misc\u002Fmagic.rs`'s `mgef_data` (`abe8d7e96`, #5614); Starfield `NPC_` `ACBS` is 16 B (the FO4 layout minus the trailing words) and shares the FO4 arm under a `>= 16` gate (`78facba89`, #6120 — no arm matched, every Starfield NPC was male with no template flags); ACBS Essential\u002FProtected decode in `parse_npc` (`NpcRecord.essential`\u002F`.protected`; bit 11 is Protected from Skyrim on, No Blood Spray on FO3\u002FFNV; `3162b21b8`, #5921); the ACBS arm is `Fallout4 | Fallout76` at `>= 20` B (FO76 ships the FO4 layout: all 6,551 `SeventySix.esm` NPC_ ACBS are 20 B, `c4884977a`, #6240); the `RACE` `ANAM` skeleton run is read for Skyrim\u002FFO4\u002FFO76\u002FStarfield (`e8e00326d`, #6122; FO76 `4a7963156`, #6297 — 307 runs over 157 RACEs); Oblivion `RACE` body-section tail `MODL` lands in `RaceRecord::tail_models` (male, female; only Argonian\u002FKhajiit author one, `a6ab3625e`, #5753); Starfield bleedout decodes into `RaceRecord::bleedout` (`DAT2` +160) and `NpcRecord::bleedout_override` (`ONA2` flag 5) — decode only, no recovery rule is wired (`a1b72625f`, part of #6259); `PACK` `PSDT` Day-of-Week decodes into `PackDays` (−1 any, 0–6, 7 weekdays, 8 weekends, 9 MWF, 10 TT; `3ce1e1e3a`, #6079 — consumed for FO3\u002FFNV, and Oblivion since `5d7f08e56`, #6257, which also decodes PSDT byte 2 into `PackSchedule::date`); the 12-byte Skyrim+ PSDT duration is **minutes** (`duration_minutes` + `start_minute`; the 8-byte FO3\u002FFNV\u002FOblivion hours are ×60 at decode, `7e2f21482`, #6210 — an hours reading made 1,536 of 1,545 timed Skyrim windows always-on); `PKW3`\u002F`PTD2` (FO3\u002FFNV Use Weapon data and second target, `PackUseWeapon`, `10f8cbb91`; PTD2 is authored by all 82 FNV but only 46 of 56 FO3 Use Weapon packages, the rest declined, #6462); Skyrim+ `PKDT` Interrupt Flags (u16 @ 8, gated on the type byte 18\u002F19; `PackRecord::interrupt_flags`, `allows_random_conversations`); Skyrim\u002FFO4 `FACT` Crime tab (`parse_fact_crime` → `FactionRecord::crime`, `4cfcee4b9`) and `CLAS` `DATA` flags on Oblivion\u002FFO3\u002FFNV (`ClassRecord::class_flags`, Guard bit 1, `1a67c9f30`); `CHAL` decodes only under `Fallout3NV` — Starfield's 8 `CHAL` have no `DATA`\u002F`SNAM` (`f90aea105`, #6298); `MSWP` `FNAM` is the CK *Tree Folder* (`tree_folder`, tooling only), never a path filter (`f81e6e722`, #5756); FO3\u002FFNV `WEAP` `DNAM` offset 28 is Sight FOV (f32, not stored), Base VATS To-Hit is the **u8** at offset 40 (`vats_base_to_hit`) and the regular AP cost is the f32 at offset 68 (`ap_cost`), and the weapon's skill is the `i32` at offset 104 (`ItemKind::Weapon::skill_actor_value`, an actor-value code — 34 Energy, 38 Melee, 41 Guns, 45 Unarmed; `a290c755f`, part of #6657), while the VATS sub-record's offset-12 float is the melee *special attack's* AP, kept as `WeaponVats::special_attack_ap` (`e97707b14`, #6449\u002F#6450; the earlier offset-28 to-hit and *ap_override* readings were mislabels, and the #3324 reading of the VATS float as *the* AP cost before them); `BPTD` decodes the full part run (`BPTN`\u002F`BPNN`\u002F`BPNT`\u002F`BPNI` strings + the 84-byte `BPND`, `BptdRecord::parts`, at xEdit's offsets: flags @4, part type @5, health percent @6, to-hit @8, u16 debris @10; `3bec306a0`, #6448) with short payloads defaulting, and a payload longer than 84 B (FO4's 101-byte `BPND`) keeps the name run and leaves the numeric fields undecoded — it must never reach `remap_fid` (#6465), `CREA` links its record through a standalone `PNAM` (`NpcRecord::body_part_form`; RACE carries none) and humanoids resolve the reserved `PLAYER_BODY_PART_DATA` `0x1C` \u002F `DEFAULT_BODY_PART_DATA` `0x1D` slots (`aebcc99a1`, part of #6350); FO3\u002FFNV `RACE` authors the same body-section `ICON` run under `NAM1` with a three-slot vocabulary (0 upper body, 1\u002F2 hands) — `body_part_textures` is no longer Oblivion-only (`9d1a262ed`, #6090; Skyrim+ authors none); `SOUN` `SNDD`\u002F`SNDX` bytes 0\u002F1 carry min\u002Fmax attenuation (`SounRecord::attenuation_units`; min ×5, max ×100 game units) plus the Menu Sound \u002F 2D bits (`41b53ab41`, #6281); the CRVA, PACK (`PACK_LOCATION_LEN`), ACBS and Oblivion-CTDA length gates are named constants (`64f26db8c`, #6393); FACT `CRVA` decodes at its real 12\u002F16\u002F20-byte cut points (`CRVA_MIN_LEN` 12, `CRVA_STEAL_LEN` 16 for the steal multiplier, `CRVA_TAIL_LEN` 20 for escape\u002Fwerewolf; `3da35c683`, #6516); FACT `XNAM` modifier stays a full `i32` (vanilla Oblivion authors -200; the -100..100 clamp was in the SDK faction catalog, `407730df3`, #6504 — a clamp at the parser is the regression); NPC template flag `0x1000` Use Keywords (Skyrim; FO4's 13th `TPTA` slot) is a `ResolvedNpc::keywords` terminal read by `KeywordTable` (`TEMPLATE_FLAG_USE_KEYWORDS`, `keywords_terminal`, `26850aa5f`, #6515) while Skyrim's `0x0800` Use Attack Data is deliberately unparsed (no `ATKD` reader); `PROJ` alt-trigger proximity\u002Ftimer (`DATA` 28\u002F32 on FO3\u002FFNV\u002FSkyrim; the 93-byte `DNAM` 24\u002F28 on FO4 **and FO76**, `6d70c560c` #6563) and `parse_expl(.., game)` feed `ProjRecord::is_proximity_mine`. `EXPL` `DATA` is picked by game *and length* (`expl_data_layout`, `misc\u002Feffects.rs`; the record walker keeps no form version and `DATA` only grows with it, so the length gives the same answer on every shipped master): force-first damage @4 \u002F radius @8 on FO3\u002FFNV (`0af42d53d`, #6541 — read from 8 until then, storing the radius as damage and the LIGH FormID as a denormal radius) and on Skyrim below 48 B (six oldest `Skyrim.esm` forms); forms-first damage @28 on Skyrim ≥48 B and FO4\u002FFO76, with `Inner Radius` only from 64 B (`6e49cee6f`, #6562); FO76 ≥88 B adds the Damage Curve Table form id at 24 (damage @32; `6d70c560c`). Oblivion has no `EXPL` `DATA` layout and decodes nothing — the old catch-all FO3-offset arm is the regression; Starfield moved the struct to a 164-byte `ENAM` (damage @104, then inner and outer radius; `parse_expl`, `4b28775fd`, #6679) and `PROJ` to `PROD` (flags, alt-trigger proximity\u002Ftimer, explosion, impact force, collision radius, lifetime, and a type byte behind a u32-prefixed string, `decode_starfield_prod`; the sequential type enum is mapped onto the documented bit values and flag bits above 15 ride `ProjRecord::extended_flags`); item `EITM` lands in `CommonItemFields::enchantment`.\n- `equip.rs::main_body_bit` FO76\u002FStarfield arms are a **provisional inference**\n  (`PROVISIONAL (#4074)`, pinned by `fo76_and_starfield_arms_are_marked_provisional`) —\n  known and marked; report only if the marker is removed without an xEdit citation.\n**Output**: `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_4.md`\n\n### Dimension 5: CELL \u002F WRLD Walkers & Placement Data\nPaths: `crates\u002Fplugin\u002Fsrc\u002Fesm\u002Fcell\u002F**\u002F*.rs`, `esm\u002Frecords\u002Fmisc\u002Fworld.rs`, `esm\u002Frecords\u002Fspatial_units.rs`\nFirst step: `git log --since=\u003Clast report> --format='%h %cs %s' -- crates\u002Fplugin\u002Fsrc\u002Fesm\u002Fcell crates\u002Fplugin\u002Fsrc\u002Fesm\u002Frecords\u002Fmisc\u002Fworld.rs`\n**Checklist**:\n- Cell child groups: type 6 is the `Cell Children` *container*; 8 = Persistent, 9 =\n  Temporary, 10 = Visible Distant nest inside it (#4169 — earlier legends said 6\u002F8\u002F9).\n  `PlacedRef.group_type` is re-derived at each nested GRUP in `parse_refr_group_inner`\n  (only the nested position accepts 10; at CELL\u002FWRLD level 10 is Quest Children). No\n  consumer reads it yet — verify it stays populated per-scope, not that a consumer exists.\n- Interior and exterior CELL sub-record walkers share one decode, `CellSubrecordFields::absorb` (`cell\u002Fhelpers.rs`, #5309), and one `CellData` build, `CellSubrecordFields::into_cell` (`d6d216b91`, #5815) — a field added to only one walker, or a hand-built `CellData` literal back in `walkers.rs`\u002F`wrld.rs`, is the regression. All three walkers depth-bounded (see Dim 1): `parse_cell_group`, `parse_wrld_children`,\n  `parse_refr_group`.\n- Placement header flags (`f87490826`, #4813\u002F#4814): `PlacedRef.initially_disabled` =\n  `0x800` on every placement type; `PlacedRef.starts_dead` = `0x200` on `ACHR` gated on\n  `EsmVariant::Tes5Plus`; `starts_unconscious` = `0x2000` on `ACHR`, FO4\u002FFO76\u002FStarfield only\n  (#5017). The placement bit is **not** the corpse marker on every game, and each other game\n  is settled at its own layer: Oblivion = base `NPC_`\u002F`CREA` header `0x80000`\n  (`base_actor_starts_dead`, `dispatch_actor.rs`, Oblivion-gated, #5013); FO3\u002FFNV = base\n  `DATA` health ≤ 0 (`NpcRecord::starts_dead`, #5005 — `0x80000` is not a marker there,\n  and `XRGD` is a ragdoll *pose*, not a death signal) plus the script-killed idiom\n  (`717f39a82`, #5223 — a dismember-family trigger's `XLKR` target; FO3\u002FFNV `XLKR` is **4 B**,\n  the target FormID alone, vs TES5's 8 B keyword+target — a `len >= 8` gate silently dropped\n  every FO3\u002FFNV link). A zero placement `starts_dead` means \"no placement-level marker\",\n  not \"alive\"; the cell loader ORs both\n  (`byroredux\u002Fsrc\u002Fcell_loader\u002Freferences\u002Fmod.rs` → `reference_state.rs::apply_starts_dead`). Flag any per-game gate that reads one of these bits on a game\n  whose xEdit list does not define it.\n- Starfield metric → 70\u002Fm lift (`records\u002Fspatial_units.rs::normalize`, called once at the\n  end of each plugin's walk in `parse.rs`): positions, light radii, XCLL\u002FLGTM fog\u002Ffade +\n  SF height-fog (#5002; the 20-field lighting tail decodes once in\n  `cell::decode_starfield_lighting_tail` and the height-fog lift is the shared\n  `starfield_heights`, `9dbd59b8b`, #5346), WTHR fog distances (only when\n  `fog_distances_authored` — an FNAM-less weather keeps the unlifted 10 000 default, `ec75b1439`,\n  #5301, pinned by `starfield_wthr_without_fnam_keeps_the_unlifted_fog_defaults`) + height-fog tail (#5001\u002F#5134), water heights,\n  WATR `DNAM` lengths ×70 and per-metre absorption ÷70 — only for offsets the record\n  authored (#5151, `24cb577d2`), LAND heights, NAVM vertices, XRGD ragdoll-pose offsets (`5f1a862be`, #5299; Euler stays wire-valued), and Starfield EXPL radii, PROJ speed\u002Frange\u002Fcollision radius\u002Falt-trigger proximity and TXST decal sizes (`af26510e9`, #6777; gravity, lifetime, timer and impact force stay wire-valued, pinned by `starfield_expl_proj_and_decal_distances_lift_once`). FO76 is BU-native except the\n  shared-decoder WATR absorption lane, its only lift (#5169). Three Starfield WATR `DNAM` lane\n  families (noise-UV tiles, displacement simulator, normal falloff) are deliberately **not**\n  lifted — unit unsettled, pinned by `starfield_watr_defers_the_unclassified_dnam_lanes`; the\n  LGTM + cell-XCLL lift is pinned through `parse_esm` by\n  `starfield_index_lifts_lgtm_and_xcll_lighting_distances` (`2dab4ff48`, #5170\u002F#5171,\n  `records\u002Fspatial_units_tests.rs`). Check new Starfield distance\n  fields join it, dimensionless fields (XSCL, Euler) stay out, decoder defaults for an\n  unauthored field are never lifted, and no path normalizes an index twice.\n- M47.2 placement\u002Fbase fields, all remapped: REFR `XAPR` (activate parent + delay, `XAPD`\n  Parent Activate Only), `XMRK`→`FNAM` map-marker flags, per-reference `XEZN`\n  (`PlacedRef.encounter_zone_form`); base-object `DEST`\u002F`DSTD` → `DestructionData`. `ECZN DATA`\n  is per game (`parse_eczn(.., game, ..)`: FO3\u002FFNV 8 B, Skyrim\u002FFO4\u002FStarfield add the `LCTN` and\n  max level; xEdit `wbECZN`). `EsmCellIndex::cell_by_form_id` is a lazily-built O(1) lookup\n  (`cell_form_id_lookup`, #5489), and `locate_refr` \u002F `cell_for_refr_form_id` answer from the\n  twin `refr_lookup` reverse index (`56fc348b8`, #6125; first cell holding a FormID wins, in\n  interior → exterior → persistent order); `merge_from` resets both — a CELL-map edit after\n  the first call leaves them stale. Starfield REFR `XLMS` is a remapped list of `LMSW` FormIDs\n  (`PlacedRef.layered_material_swap_refs`); `layered_material_swap_entries` flattens it\n  (collection members recursively, then own entries; cycle- and depth-capped) over the\n  `layered_material_swaps` \u002F `material_path_forms` maps (`17bd40f4f`, #5757).\n- A placed reference draws the base's **world** model: `ARMO`\u002F`CLOT` `MODL`\u002F`MOD3` are the worn biped meshes (and on Skyrim+ `MODL` is an `ARMA` FormID), so `StaticObject.model_path` takes `MOD2` for them in `cell\u002Fsupport.rs` (a record with no `MOD2` keeps its `MODL` before Skyrim, nothing after; the worn mesh stays on the typed item the equip path reads; `846c36bf0`, #6691 — read as `MODL`, placed armor stood in its bind pose with its gore caps on FO3\u002FFNV and was invisible on Skyrim, 1,683 interior references). Pinned by `placed_armor_and_clothing_take_the_world_model_over_the_biped_mesh`.\n- Lighting-template inheritance is per-field; \"absent\" and \"authored zero\" stay distinct.\n- CELL `XCCM` is per-game (`3b28dca71`, #5463): TES4\u002FFO3\u002FFNV = Climate (CLMT) →\n  `CellData.climate_override`; TES5\u002FFO4\u002FFO76\u002FStarfield = \"Sky\u002FWeather from Region\" (REGN) → `sky_region`\n  (`xccm_targets_region`, `cell\u002Fhelpers.rs`; FO76 and Starfield joined in #6794 — Starfield 36\u002F36 and FO76 41\u002F41 real cells target a REGN). Guards `parse_cell_oblivion_fo3nv_xccm_populates_climate_override`,\n  `parse_cell_tes5_fo4_xccm_is_a_region_not_a_climate`. Regression = a REGN id reaching `climate_override`.\n- **XCLL** is size- and game-validated: `xcll_canonical_sizes(game)`; the ≥92-byte\n  ambient-cube arm fires only for Skyrim\u002FFO4\u002FFO76 (Starfield has its own ≥108 arm) — a non-canonical 92+ XCLL on\n  Oblivion\u002FFO3NV keeps base + per-field reads and warns (guard: the cell test\n  `parse_cell_non_canonical_92plus_xcll_on_pre_skyrim_games_stays_out_of_the_ambient_cube`).\n  Parsed-but-unconsumed tail fields are parked in `docs\u002Fengine\u002Flighting-from-cells.md`.\n- **LIGH** `LightData`: `falloff_exponent` `0.0` is a sentinel resolved per layout\n  generation at the translation boundary (`canonical_light_falloff_exponent`,\n  `byroredux\u002Fsrc\u002Fsystems\u002Flight_anim.rs`) — the parser must store authored values\n  verbatim. Starfield light shape is the `DAT2+56` Light Type enum\n  (`starfield_light_type`: 0 omni, 1 shadow spot, 2 non-shadow spot); `0x200` is *Focus\n  Spotlight Beam*, not a shape bit. `DAT2` is gated on LIGH (an AMMO `DAT2` must not\n  synthesize light data).\n- `XCLW` water height is tri-state: absent → inherit WRLD default; finite → override;\n  `INT_MIN` \u002F `FLT_MAX` sentinel → suppress (`gated_water_height` in `esm\u002Fcell\u002Fhelpers.rs` +\n  `water_height_is_explicit`; `docs\u002Fengine\u002Fwatal.md`).\n- Exterior grid `XCLC`, worldspace parenting and selective-inheritance flags (`wrld.rs`):\n  a child inherits only the flagged categories. Oblivion authors no `PNAM`, so\n  `parse_wrld_group` stamps land\u002FLOD\u002Fwater\u002Fclimate inherit bits on every Oblivion child\n  (`67afa4b95`, #5374 — pre-FO3 \"child ⟹ inherit all\"; the flag-less duplicate fallback was\n  deleted in `65cadde2f`, #5516, so the stamp is the only copy — pinned by\n  `oblivion_child_gets_the_inherit_all_stamp_and_eras_stay_real`); an authored zero `PNAM` on\n  FO3+ must stay zero. After the merge, `EsmCellIndex::inherit_parent_landscapes` (gated to Oblivion,\n  FO3\u002FFNV, Skyrim and FO4 at its caller; FO76 and Starfield are unmeasured — `apply_exterior_processing` \u002F `needs_exterior_processing` in `byroredux\u002Fsrc\u002Fcell_loader\u002Fload_order.rs`, moved\n  into the shared parse by `588c87bc4`, #6123; FO3's four \"Use Land Data\" children measured co-located with the Wasteland's LAND, `a9472103b`, #6089 — the real-data census fills 100–120 LAND-less cells; FO4's NukaWorld Market\u002FAmphitheater and Goodneighbor \"Use Land Data\" children were added, 29 LAND-less content cells, `977936719`, #6464 — pinned by `use_land_data_children_inherit_on_the_measured_games_only`; Skyrim joined with #6594, 308 LAND-less cells over its seven Tamriel children, pinned by the ignored real-data `skyrim_use_land_data_children_inherit_tamriels_landscape`) fills a child's LAND-less cells from the nearest\n  ancestor's LAND (`75b921cf4`, #5505). `XCLC` byte 8 is kept raw as `CellData.land_flags`\n  (Hide Quad bits 0-3, FO4+ No Collision bits 4-7; `79477b4a3`, #6043) — like `grid`, a CELL\n  record field, so an override's value wins as parsed (#6086, Dim 4). An EDID-less `WRLD` clears the current-worldspace binding so its children are not\n  filed under the previous worldspace (`6f803356d`, #6047).\n- `parse_land_record`: quadrant\u002Flayer counts and splat rows are fixed-stride. An `ATXT`\n  with no following `VTXT` must flush with `alpha: None` (`pending_atxt`, #4078;\n  measured 14× on `Oblivion.esm`). `LTEX.GNAM` is an **array** of grasses, kept in\n  authored order into `landscape_grasses` by `parse_ltex_group` (#4642; last-wins was the bug).\n  The `LTEX.TNAM` → `TXST` join is re-run against the merged load order\n  (`landscape_texture_txsts` + `resolve_landscape_texture_sets`, `65add6a2e`, #6036) — a\n  per-plugin-only join loses every DLC LTEX naming a master TXST. LTEX Havok data lands in\n  `landscape_texture_havok` (`LandscapeTextureHavok`; the walk's out-maps are one\n  `cell\u002Fsupport.rs::LtexTables` sink): Oblivion\u002FFO3\u002FFNV `HNAM` = u8 material + friction +\n  restitution, Skyrim\u002FFO4 `MNAM` = remapped `MATT` FormID with `HNAM` friction + restitution\n  only (`c53d87679`, part of #6048; friction\u002Frestitution stored as authored, unapplied). The `MATT` arm in\n  `records\u002Fparse.rs` (`matt_havok_material`, `cell\u002Fsupport.rs`) feeds `EsmCellIndex::material_type_havok`\n  (MATT → Havok material id, merged across the load order): the id is the BSCRC32 of the lowercased `MNAM`\n  string (nif.xml `SkyrimHavokMaterial`; 63 of 78 vanilla MATTs land on a listed id and all 68 vanilla LTEXs\n  name one of them), computed on Skyrim only — FO4\u002FStarfield `MATT`s are routed but stay empty (`4ce5ddf2a`,\n  part of #6048, which stays OPEN for applying friction\u002Frestitution and for FO4 terrain material).\n- FO4 precombine CELL sub-records (`CellSubrecordFields::absorb`): the `XCRI` tail is\n  `ref_count \u002F 2` × (ref FormID, bake hash) pairs → `CellData.absorbed_ref_bakes` (the skip\n  set); `XPRI` is the disjoint previs list, validated and **not** stored (`777351ec1`,\n  #5484 — the two were inverted, double-drawing every baked STAT\u002FSCOL). Guards\n  `parse_cell_xcri_pairs_remap_and_keep_their_bake_hash`,\n  `parse_wrld_exterior_cell_captures_precombined_xcri_xpri`.\n- Starfield `TXST`: an unmodelled slot warns once (#4438), not per record.\n- Navmesh: classic `NVTR`\u002F`NVEX` and packed `NVNM` (`decode_nvnm`, `NVNM_MAX_DIVISOR`)\n  yield the same `NavmRecord` through shared row decoders; the cursor refuses to pass the\n  blob end; retained-raw-on-failure is diagnosable, not a silent success.\n**Output**: `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_5.md`\n\n### Dimension 6: Localized Strings (Skyrim+ `.STRINGS` family)\nPaths: `crates\u002Fplugin\u002Fsrc\u002Fesm\u002Fstrings_table.rs`, `esm\u002Frecords\u002Fcommon.rs` (`StringsTableGuard`, lstring readers), `byroredux\u002Fsrc\u002Fcell_loader\u002Fload_order.rs` (table loading)\nFirst step: `cargo test -p byroredux-plugin strings_table`\n**Checklist**:\n- The TES4 localized flag (`0x80`) — not \"looks like a small integer\" — decides literal vs\n  `u32` string id. lstring id `0` means \"no string\" (empty, never the `\u003Clstring 0x…>`\n  placeholder, #4072); only a genuinely unresolved id yields the placeholder.\n- `.STRINGS` has no length prefix; `.DLSTRINGS`\u002F`.ILSTRINGS` do (`has_length_prefix`). A\n  flag\u002Fdata disagreement warns loudly (declared length vs NUL offset, ±1 band, #4178)\n  instead of yielding shifted strings.\n- Missing string files degrade to \"no string\" without panic or per-form warn spam; a\n  localized plugin that resolves **zero** tables logs a diagnostic (#4073, `load_order.rs`).\n- Tables and the localized flag are thread-locals: since the parallel walk (#3813) the\n  caller only loads tables (`load_string_tables`) and each walk installs its own\n  `StringsTableGuard` on the walking thread. A guard installed on the caller yields\n  `\u003Clstring 0x…>` placeholders under the pool.\n- The language token is not the file-name segment: Skyrim spells it out\n  (`dawnguard_english.strings`), FO4\u002FFO76\u002FStarfield use a short tag\n  (`Fallout4_en.STRINGS`). `language_candidates` expands both; check it exists before\n  reporting the defect (two audits re-derived it before it was filed, #4168).\n- Decode is UTF-8-first with a cp1252 fallback and that order is load-bearing (#4170:\n  English tables carry real cp1252 bytes, localized tables are real UTF-8). A flat cp1252\n  decode is the regression; the fallback is not a bug.\n- Loose files are found case-insensitively before the archive fallback\n  (`load_with_archive`, #4176) — a case-mismatched mod override must beat the archive.\n**Output**: `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_6.md`\n\n### Dimension 7: `EsmIndex` → ECS Handoff & the Redux-Native Tier\nPaths: `crates\u002Fplugin\u002Fsrc\u002F{record,datastore,resolver,manifest,equip}.rs`, `esm\u002Frecords\u002Findex.rs`; consumers `byroredux\u002Fsrc\u002Fcell_loader\u002Freferences\u002F`, `byroredux\u002Fsrc\u002Fnpc_spawn\u002F`\nFirst step: `grep -rn 'resolve_entity_by_global_form_id\\|find_by_form_id' byroredux\u002Fsrc | head -20`\n**Checklist**:\n- `EsmIndex` is a session-long bag of `HashMap\u003Cu32, _>`; nothing evicts it. Check growth on\n  a large load order against `docs\u002Fengine\u002Fmemory-budget.md` (RAM, not VRAM).\n- Sample high-traffic `Option\u003Cu32>` FormID fields (`SCRI`, `RNAM`, `CNAM`, `PKID`, `XEZN`,\n  teleport `XTEL`): the consumer must resolve via `resolve_entity_by_global_form_id`, not a\n  raw `World::find_by_form_id`. That resolver answers from a lazily rebuilt local-id → entity index\n  owned by `FormIdPool` (`FormIdPool::entity_with_local`, keyed on the `FormIdComponent` structural\n  generation plus pool length; first entity in storage order wins on a duplicate id; `ab3a604bf`,\n  #6338) — a per-call scan of every `FormIdComponent` is the regression (per-actor-per-frame Flee\u002FUseWeapon callers).\n- `equip.rs` biped-slot constants: BMDT vs BOD2 vs FO4 bit meanings differ; each block cites\n  its xEdit definition; slot → `addon_index` (`AddonData::addon_index`) matches\n  *equipment_system*. `equip_template_tests.rs` covers template equip resolution.\n- Redux-native tier: audit for **rot** (compiles against the current `Record` shape; docs\n  consistent with `docs\u002Fengine\u002Fplugin-loading.md`) and dead-but-documented API. \"Unused\" is\n  not a bug on its own — `DataStore` + `DependencyResolver` + `PluginManifest` have no\n  production consumer and are kept as design surface: #5609 (`490e76397`) put status banners on\n  `lib.rs`, `plugin-loading.md` and `architecture.md` and a ROADMAP row. A doc presenting them as\n  the live load path again is the regression; the absence of a consumer is not a finding.\n  Likewise seven typed maps (ENCH, REPU, EXPL, CSTY, IPCT, IPDS, COBJ) are parsed with no\n  runtime reader and annotated as such in `index.rs` + `esm-records.md` (`934385de1`, #6180).\n  `body_parts` (BPTD) left that set when the VATS targeting scan began reading it\n  (`byroredux\u002Fsrc\u002Fsystems\u002Fvats.rs`, #6350); its `index.rs` doc was corrected in `cacdbb955`\n  (#6451) and now says only the dismemberment half is unconsumed.\n**Output**: `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_7.md`\n\n### Dimension 8: Real-Data Validation\nPaths: `crates\u002Fplugin\u002Fexamples\u002F`, `crates\u002Fplugin\u002Ftests\u002Fparse_real_esm.rs`, `byroredux\u002Fsrc\u002F{list_cells,sf_smoke}.rs`\nFirst step: `cargo run --release -p byroredux-plugin --example esm_dim8_coverage -- \u003Cmaster.esm>` (one master at a time)\n**Checklist**:\n- Per `--game`: records seen \u002F decoded \u002F stubbed \u002F skipped and *unknown sub-record codes\n  per record type* (`esm_dim8_coverage` emits the TSV; `esm_dim8_bench` gives parse time\n  + `EsmIndex` totals; other probes: `sf_smoke`, `probe_form`, `dump_record_subs`,\n  `weather_coverage_census` — `ls crates\u002Fplugin\u002Fexamples`; one-liner probes are `inspect.rs`\n  subcommands since `b997ea133`, #5856). Unknown-subrecord share is the\n  coverage signal per-game audits never compute across the whole file.\n- A decode rate that drops between games is a schema-split suspect — correlate with Dim 4\n  `GameKind` arms. Compare Starfield against the `sf_smoke --tsv --recurse` baselines (without `--recurse` only the top rows are emitted and the diff is meaningless) in `.claude\u002Faudit-baselines\u002Fsf-esm\u002F`\n  (regenerated `6cbae341c`, #5758; `sf_esm_baseline_handled_column_tracks_the_dispatch_list` pins\n  their handled column to the dispatch list); a drop\n  is a regression, not a new finding.\n- Report parse **time** and peak RSS per master (ESM parse cost is on every session's\n  boot path; door transitions reuse the resident index through `SharedParseCache` in\n  `load_order.rs` unless the plugin set or a file's length\u002Fmtime changed, `588c87bc4`, #6123;\n  NIF parse cost is `\u002Faudit-performance`).\n- Real-data tests resolve installs through `esm\u002Ftest_paths.rs` (`*_data_dir()` + `require_or_skip`);\n  `BYROREDUX_REQUIRE_GAME_DATA` turns an absent install into a failure on the strict lane (`3e4bfab51`, #6184) — a\n  test that re-inlines a Steam root or returns `ok` on a missing master is the regression.\n- No windowed engine launch (*feedback_no_parallel_engine_launch*); example binaries and\n  default `cargo test` only (see Phase 1 step 4 on `--ignored`).\n**Output**: `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_8.md`\n\n## Phase 3: Merge\n\n1. Read all `\u002Ftmp\u002Faudit\u002Fesm\u002Fdim_*.md`; combine into `docs\u002Faudits\u002FAUDIT_ESM_\u003CTODAY>.md`:\n   - **Executive Summary** — findings by severity; coverage posture; which games' real\n     data was actually parsed.\n   - **Record Coverage Matrix** — record type × game × {decoded, stubbed, skipped,\n     unknown-subrecords}. The durable artifact; keep it even with no findings.\n   - **Findings** — grouped by severity, deduplicated.\n   - **Cross-Audit Pointers** — `\u002Faudit-\u003Cgame>` Dim 1, `\u002Faudit-scripting` (VMAD),\n     `\u002Faudit-character` (AVIF\u002Fclass), `\u002Faudit-physics` (collision-relevant placement),\n     `\u002Faudit-exterior`, `\u002Faudit-gameplay`, `\u002Faudit-parsers`.\n2. Deduplicate against the per-game reports read in Phase 1 — a finding already filed under\n   an `\u002Faudit-\u003Cgame>` ESM dimension is `Existing: #NNN`, not new.\n\n## Phase 4: Cleanup\n\n`rm -rf \u002Ftmp\u002Faudit\u002Fesm`; tell the user the report is ready; suggest\n`\u002Faudit-publish docs\u002Faudits\u002FAUDIT_ESM_\u003CTODAY>.md` (domain label `esm-plugin`; plus the\nmatching `game:*` when specific to one title's records).\n",{"description":7,"argument-hint":46},"--focus \u003Cdimensions> --game \u003Cname> --depth shallow|deep","main","6afdb791976ed2c24a6c7e61fcbe0cd1f8776061",".claude\u002Fcommands\u002Faudit-esm",6,"https:\u002F\u002Fgithub.com\u002Fmatiaszanolli\u002FByroRedux","https:\u002F\u002Fgithub.com\u002Fmatiaszanolli","matiaszanolli.com","15+ years turning mate into code, and just getting started! All things Python and data lover overall. Music addict, always looking to unite music and tech.","2026-11-12 21:39:17",{"source":8,"skillName":5,"commands":57,"prompt":67,"zipAvailable":68},[58,61,64],{"tool":59,"command":60},"npx","npx skills add matiaszanolli\u002FByroRedux --skill audit-esm",{"tool":62,"command":63},"bunx","bunx skills add matiaszanolli\u002FByroRedux --skill audit-esm",{"tool":65,"command":66},"pnpm","pnpm dlx skills add matiaszanolli\u002FByroRedux --skill audit-esm","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmatiaszanolli\u002FByroRedux\u002Fblob\u002Fmain\u002F.claude\u002Fcommands\u002Faudit-esm\u002FSKILL.md",true,[],[71,80,89,98,107,115],{"skillNo":72,"name":73,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":76,"publishedAt":41},"01M6K028GPYDYZ5441BW6YDFNK","trace-flow","https:\u002F\u002Fgithub.com\u002Fmatiaszanolli\u002FByroRedux\u002Fblob\u002Fmain\u002F.zcode\u002Fcommands\u002Ftrace-flow\u002FSKILL.md",[],[77,78,79],"trace flow","trace","flow",{"skillNo":81,"name":82,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":83,"categories":84,"keywords":85,"publishedAt":41},"01M6K026GTTXBBXXCH09SDRNX6","session-close","https:\u002F\u002Fgithub.com\u002Fmatiaszanolli\u002FByroRedux\u002Fblob\u002Fmain\u002F.zcode\u002Fcommands\u002Fsession-close\u002FSKILL.md",[],[86,87,88],"close","session close","session",{"skillNo":90,"name":91,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":92,"categories":93,"keywords":94,"publishedAt":41},"01M6K024KA1JFTV7BGYFSZV2VV","legacy-lookup","https:\u002F\u002Fgithub.com\u002Fmatiaszanolli\u002FByroRedux\u002Fblob\u002Fmain\u002F.zcode\u002Fcommands\u002Flegacy-lookup\u002FSKILL.md",[],[95,96,97],"lookup","legacy lookup","Legacy",{"skillNo":99,"name":100,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":101,"categories":102,"keywords":103,"publishedAt":41},"01M6K022H36BJ35KB6MT2NHVH6","fix-issue","https:\u002F\u002Fgithub.com\u002Fmatiaszanolli\u002FByroRedux\u002Fblob\u002Fmain\u002F.zcode\u002Fcommands\u002Ffix-issue\u002FSKILL.md",[],[104,105,106],"issue","fix","fix issue",{"skillNo":108,"name":109,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":110,"categories":111,"keywords":112,"publishedAt":41},"01M6K0208JHG4WDJX143YKFF0W","audit-ui","https:\u002F\u002Fgithub.com\u002Fmatiaszanolli\u002FByroRedux\u002Fblob\u002Fmain\u002F.zcode\u002Fcommands\u002Faudit-ui\u002FSKILL.md",[],[113,114,24],"audit ui","ui",{"skillNo":116,"name":117,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":118,"categories":119,"keywords":120,"publishedAt":41},"01M6K01XPHAPHF9BPS4CG5DDWX","audit-tooling","https:\u002F\u002Fgithub.com\u002Fmatiaszanolli\u002FByroRedux\u002Fblob\u002Fmain\u002F.zcode\u002Fcommands\u002Faudit-tooling\u002FSKILL.md",[],[24,121,122],"audit tooling","tooling"]