# Original selected-commodity balance cache Pinned source SHA256: `6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93`. All functions are read from the saved image; no game setter, request, lookup or reference-counting method is invoked by the adapter. ## Source and current-version bindings Original registration `1E2A720` exposes interface object+58 by dynamic type `5F7E844`. Constructor `1DD2B60` finally installs main/secondary/interface tables `5241FB0/5241FF0/52420F0`. Independent full-body and bound-slot comparison with the current ED5A image gives `5241F80/5241FC0/52420C0`; the type global remains `5F7E844`. The sidecar `commodity-tree/compatibility.json` now includes twenty-four complete functions, seventeen bound virtual slots and two name/category leaves. This extends the commodity options source evidence; it does not relax the client hash or runtime table/owner checks. ## Exact cached inputs All following offsets are relative to the registered interface, not the base. | Field | Evidence | Meaning | | --- | --- | --- | | +E8 pointer | selected-definition setter `1E4D5E0` | Original actual definition instance | | +F0 int | same setter, original enum lookup +28 | Zero clears the selected definition; a valid bound source has nonzero value | | +F8 hash | getter +78 is `EBDF50`, `lea rax,[rcx+F8]` | SystemAddress → signed float balance | | +E0 bool, +2C0 count | ready getter +30 `1DF3590` | Ready only when bool is true and pending count is zero | | +140 bool | setters `1E4D5E0/1E59760`, original tick | Cache dirty after selection/config changes | | +144 uint | rebuilder `1E6BC80` | Local cache revision, incremented before synchronous rebuild | The selected definition is bound to a UID by exact instance identity in the actual ready definition map (node+10 equals the selected pointer). Its real map key supplies the UID. No Market ID, row number or fallback name hash supplies it. The original `1B390F0` does compute an ASCII lowercase DJB2 name key for its own lookup, but the read-only adapter still requires the actual definition entry. `1E6BC80` clears base+150/interface+F8, increments base+19C/interface+144 and rebuilds the float map on the original owning thread. The copy publishes rows only when the original ready predicate is true **and** dirty is false, preventing an old selection's rows from being attached to a newly selected UID. Pending sources retain the known UID/revision but return no publishable rows. Every copied field, map bucket, node, name and source binding is rechecked for byte stability. Current account registry, entity, owner, thread and 500ms snapshot guards apply to the runtime entry point. The system hash is the original 64-bit multiply/xor sequence used in `3B27B00`. Each positive address, bucket assignment, uniqueness, count and chain is checked. A stored float zero is real data; a missing row stays unknown. Nonfinite values, malformed chains and counts are rejected. No absent address is converted to zero balance or a negative availability fact. ## Complete context-bound original classification `3B27B00` additionally requires the original filter's position/range, pending flag and actual ready generic system descriptor. `3AF45E0` clears its pending flag only after the source's +30 ready getter succeeds. The +58 method `1E31A90` forwards its caller's RDX address to the original neighbourhood provider +38, then enumerates actual nearby rows and submits them through +18; it is not a simple address field setter. These mutating routines are never called by the tool. `Navigation.GalaxyCommodityFilter.cs` now independently binds the real Main/filter context before classifying a requested original UID. The raw cache reader remains separate and cannot by itself prove an original result. Original registry type `5F05DB4` supplies Main interface base+80. The paired current-version Main constructor proves filter instance base+3E0; its current vtable is `552D9C8`, its config+10 must equal Main base+50, selected UID+D0 must equal both request and the actual balance definition UID, and pending+138 must be zero. The filter's native centre floats are +78/+7C/+80 and its actual config range +1D8 is40. Catalogue XYZ is relative to the galaxy origin; the classifier adds `GalaxyServices` origin/32 before the original strict `distance<40` test. The original generic lookup returns hash-node+10; this predicate requires returned+30, **node+40**, to be non-null. Trade's metadata status at node+30 is a different field and is not reused as commodity readiness. Verified classifier rules: positive balance → Import, negative → Export; PriceMode1 excludes Export, mode2 excludes Import, modes0/3 allow both signs. Stored zero selects ImportNothing, or ExportNothing for mode2. Actual config minimum/midpoint/maximum opacity is .25/.5/1, interpolated over absolute balance0..0.5..1 and clamped at the upper endpoint. Final RGBA multiplies the original row alpha by this opacity once. Inside a ready valid scope, a missing cache row takes original None with size .5; ordinary and Nothing size are1. Outside the strict range or with a known null descriptor, opacity and size are0. Missing/invalid metadata, unavailable source, mismatched UID and pending state remain unknown, not None. Exact original palette rows supply raw HDR RGBA and sprite12/11/12/11/13 for categories0..4. The adapter uses the existing `GalaxyServices` and `GalaxyFilterContext`, checks the original registry/account/entity, owner thread and500ms freshness, and rechecks every source pointer, pending flag, selected UID and balance revision. It only reads the existing original caches. It does not change CommodityIndex or call the original neighbourhood subscriber to make another source available. ### Read-only rebuild for another actual UID `Navigation.GalaxyCommodityRebuild.cs` ports the actual `1E6BC80` synchronous calculation over its copied all-commodity inputs. Original raw JSON parser `1E369C0` proves a systems→markets vector and each market's full `commodities` dictionary, rather than a response containing only the currently selected item. The ready enumeration row provides both **float32** `cost_mean` at node+C and integer JSON `id` at+10. Getter `1E102E0` returns MOVSS→XMM0; interpreting its Ghidra `undefined4` as uint would be incorrect. Getter+28 supplies the actual market id. No Market.json ID, name hash or UID-as-index guess supplies either. The existing registered source must have a valid selected definition, matching original filter selection, ready=true, pending count0, dirty=false, and a stable revision. For a different requested actual UID, the pure reader verifies its real enumeration/definition identity, then replays the original calculation: - Raw source base+118 holds system nodes, whose actual32-byte market rows are at node+48/count+40. Base+F8 holds market nodes with the original sparse commodity table. `B1F390` proves occupancy bitmap, aligned row base and linear probing. - The real enumeration `id` addresses16-byte quote records `{id,buy,sell,flags}`. Original surface, large-pad and maximum-distance conditions are retained. - Per-system best buy/min and sell/max, global min/max and float mean determine the original signed normalized balance. Each denominator is at least1, ties select buy/negative, and a selected nonzero branch has magnitude at least.01. - The original creates a system temporary for an allowed actual market even if that commodity is missing or the quote is ignored/illegal. Such a temporary can produce actual zero/Nothing. A missing market or all stations excluded can instead leave no balance row. This rule applies only within the ready original cache, never to an absent public station report. Source ready/dirty/pending/revision and enum/definition identity are rechecked; the private copied result does not change the game's selected UID or balance map. The original centre/40ly/descriptor/classification/style gates still apply. This removes the earlier requirement that the tool's chosen UID equal the game's current UID, while making no claim about uncached neighbourhoods or complete world market coverage. The runtime facts/wire/Core contract stays unchanged. `XFENavigationGalaxyCommodityRebuildSelfTest` expects255 across eight independent groups: per-system and global normalization, multiple markets, readonly copies, surface/pad/distance gates, real collision+wrap probing, missing/illegal/zero quotes, malformed bitmap/NaN/id, source identity changes and exact0/high-bit UID bindings. Parent's isolated Native release passed480 unified invocations after adding this adapter. The compatibility sidecar additionally binds full raw parser and sparse lookup functions. Duplicate enum getters are tied to their already proven vtable+20/+28, comparing **both** return branches through the first INT3, rather than accepting an ambiguous global signature or truncating at first RET. ## Core and application boundary Capability `galaxyCommodityFilterFacts` gates the existing owning-thread facts queue. Request fields are `includeCommodity`, numeric uint `commodityUid`, and `commodityPriceMode`0..3. Every requested row echoes UID/mode even when unknown; unknown revision/category/opacity/size/sprite/rgba are allnull. Core rejects wrong UID/mode, partial styles, invalid values and mixed revisions across pages, then releases the queue. The current PID/FID/origin/generation guards apply before VM publication; the whole runtime source is excluded from disk persistence. `GalaxyMapFilter` resolves one selected actual UID only through the live original options. A matching native category0..3 is a target; category4 None is a known non-target even when unknown display is enabled. Unknown original facts cannot be replaced by public station presence or saved query proofs. Modes0 and3 retain distinct requests and QueryKeys despite both allowing both directions. Original commodity size is independently selectable through saved commodity selection. Actual original RGBA preserves HDR and source alpha through `GetOriginalRgba`; opacity is applied exactly once. Tool multi-selection/public supply-demand queries remain separately identified and do not pretend to be the original regional filter. An unresolved saved `CommodityIndex` is itself a pending original selection. It does not run a previous public value or a different UID with the same displayed name. Its pending UID/mode is part of QueryKey; it stays unknown until actual definitions resolve it or a manual selection clears the pending original UID. ### Actual published price choices Original `3A3D910` publishes **three**, rather than four, radio rows. Its explicit UID setters are0,1,2, paired respectively with the pinned-image strings at `5523748`, `5523788`, `55237C8`: | UID | Exact original key | Observed original Chinese text | | --- | --- | --- | | 0 | GALAXY_MAP_COMMODITY_PRICE_MODE_IMPORT_EXPORT | 进口/出口价格 | | 1 | GALAXY_MAP_COMMODITY_PRICE_MODE_IMPORT | 进口价格 | | 2 | GALAXY_MAP_COMMODITY_PRICE_MODE_EXPORT | 出口价格 | `GMCommodityFiltersComponent.validate` selects a matching published row, otherwise the first. Saved mode3 is accepted by the original classifier as both directions but is not a fourth published radio choice. The Panel follows the three actual rows in their original order. Importing3 retains that raw mode/request and shows the first row without mutating it; a later user selection supplies actual0/1/2. No invented additional semantic label is exposed for3. Text provenance is the previously recorded `all-text-private.json` localisation resource. ## Tests and status `XFENavigationGalaxyCommodityBalanceSelfTest` expects255 across eight independent fixture groups: exact UID and >2^53 system address, positive/negative/zero values, no writes, loaded/dirty/pending source transitions, mismatched definition/owner, cycle and nonfinite rejection, UID0/high-bit identity, a real empty cache, and immutable revision snapshots. Native unified compilation/check results are reported by the parent integration task. `XFENavigationGalaxyCommodityFilterSelfTest` also expects255: real context/UID binding, nonzero galaxy origin, all four modes, Nothing/None, descriptor versus Trade status, exact40ly boundary, signed zero, pending/dirty transitions, immutable revision and no-write checks. Parent unified Native checks initially passed472 invocations with the corresponding wire fixture; the read-only arbitrary-UID rebuild subsequently passed the480-invocation release. Core named-pipe and filter regressions in `NativeGalaxyCommodityFilterFactsTests` and `GalaxyOriginalCommodityFilterTests` cover exact0/high-bit UIDs, >2^53 addresses, bound unknown, wrong echo/partial style cleanup, mixed revisions, strict matching, HDR/alpha/sprite/independent-size, PID/FID/origin clearing, disk exclusion and reuse of unchanged instances. Galaxy217/217 passed; the Test project compiled with zero errors (nine existing warnings). The pending-UID regression subsequently brought the Galaxy total to218/218; see `commodity-pending-uid-build.txt` and `commodity-pending-uid-tests.txt`. Initial logs are `artifacts/galaxy-query-research/commodity-filter-core-build.txt` and `commodity-filter-galaxy-tests.txt`. These fixtures are not a live original-game or final visual acceptance claim.