diff --git a/docs/re/BACKLOG.md b/docs/re/BACKLOG.md index 4e06f6ee..00cab093 100644 --- a/docs/re/BACKLOG.md +++ b/docs/re/BACKLOG.md @@ -7059,3 +7059,34 @@ is `16,24,25,26,27,28` โ€” **`29` is a `MISSION_ID`, never a requirement**. ๐ŸŸก `RECORD_TYPE`'s two values match the two ranking screens `POINT_RANKING` / `CLEAR_TIME_RANKING` by vocabulary, but no code path selecting one from that field has been shown. + +--- + +## ๐ŸŸก 2026-08-28 โ€” word B's writer: search space closed at 21 functions, field still unwritten + +โœ… **The offset route has power here** (unlike `+184`): `+1956` has **9 stores / 28 +loads** vs `+80`'s **5 403 / 6 923**. Control: the known reader `0x821898C4` is in +the gate's list-builder. + +โŒ **None of the 9 stores is a progress write** โ€” 0 of 8 distinct functions reach +the progress object; the 9th stores through **`r1`** (a stack local). + +โŒโŒ **The singleton-global filter is DEAD โ€” it fails its own control**: applied to +the *known* word-A writer it also reports "no contact", because that path goes +through the copier, not the global. **A filter that rejects the known-good answer +proves nothing.** + +โœ… **The write population is exactly 21.** Every writer must call both the copier +`0x82175110` and the setter `0x8216FF70`: **21 setter callers, 21 copier callers, +21 in both โ€” the same set.** Control: the word-A writer is `0x821C1630` +(`BASE_INFO`+`DIFFICULTY`); ยง5.2's store `0x821C1820` lies inside it. + +โŒ **No member stores to `+1956`** โ€” their big store offsets are all into `this` +(`1004`, `1980`, `2040`, `2100`, `2199`, `2436`). Word B is written through the +stack copy at `localbase + 1876`, invisible to an offset scan. + +โš ๏ธ **False friend:** `0x822A6B00`/`0x822A6EB0` reference `Points` but are the +**arsenal development economy** (`Dependency`, `MissionObjective`, `WEAPON`), with +no `Time`. **Two `Points` vocabularies.** + +๐Ÿ”‘ **Next candidate:** `0x8218EFE0` โ€” the only one of the 21 carrying `BASE_EXTRA`. diff --git a/docs/re/challenge-mission-gate.md b/docs/re/challenge-mission-gate.md index 4cdd9b49..c072b382 100644 --- a/docs/re/challenge-mission-gate.md +++ b/docs/re/challenge-mission-gate.md @@ -508,3 +508,58 @@ screens, `POINT_RANKING` (`sub_8227F6E0`) and `CLEAR_TIME_RANKING` (`sub_82282C2 and `RECORD_TYPE` takes exactly the two values `Points` and `Time`. The pairing is strongly supported by both vocabularies, but no code path has been shown selecting one screen from that field. + +### 5.5 ๐ŸŸก Word B's writer โ€” the search space is now closed at 21 functions + +ยง5.3 left word B (`+1956`) with no known writer. Three routes ran; one produced a +population, two were refuted, and the field itself is still unwritten. + +โœ… **The offset route works here, unlike `+184`.** `+1956` is a large, unusual +offset: **9 stores and 28 loads** image-wide, against `+80`'s **5 403 / 6 923**. +Control: the known reader `0x821898C4` sits in the gate's list-builder +`0x82189870`, exactly where ยง5.1 puts it. + +โŒ **But none of the 9 stores is a progress write.** Filtering them by whether the +storing function reaches the progress object gives 0 of 8 distinct functions โ€” +and the 9th (`0x826AAEA4`) stores through **`r1`, the stack pointer**, so it is a +local. `+1956` is simply an offset several unrelated structures also use. + +โŒโŒ **The obvious filter is dead โ€” it fails its own control.** Testing "does the +function reference the singleton global `0x828F48B0` or call `0x821707C0`?" +against the **known** word-A writer returns *no contact*, because that path +reaches the progress object through the copier, never through the global. **A +filter that rejects the known-good answer proves nothing about the others.** + +#### โœ… What did work: the write population is exactly 21 + +Progress is only ever changed copy-modify-store, so every writer must call **both** +the copier `0x82175110` and the setter `0x8216FF70`. Measured: + +| | | +|---|---:| +| functions calling the setter | **21** | +| functions calling the copier | **21** | +| **calling both** | **21** | + +**21/21 in both directions โ€” the two caller sets are the same set.** That is the +complete progress-write population, and it is small enough to read exhaustively. + +**Control:** the word-A writer is among them as **`0x821C1630`** (976 B, strings +`BASE_INFO` + `DIFFICULTY`) โ€” ยง5.2's store `0x821C1820` lies inside it. The doc's +`0x821C09D8`โ€“`0x821C29F0` is the enclosing method; `0x821C1630` is the function. + +โŒ **No member of the 21 stores to `+1956` directly.** Their only large store +offsets are into `this` (`1004`, `1980`, `2040`, `2100`, `2199`, `2436`) โ€” `1004` +being ยง5.2's own `this+1004 & 0x20000` guard. So word B is written *through the +stack copy*, at `localbase + 1876`, which no offset scan can pick out. + +โš ๏ธ **A false friend, recorded because it cost a query:** two of the 21 +(`0x822A6B00`, `0x822A6EB0`) reference **`Points`**, which looks exactly like the +challenge record-storing path ยง5.3 predicts. It is not โ€” their full string sets +are `Dependency`, `MissionObjective`, `Points`, `WEAPON`, `WEAPONS`, i.e. the +**arsenal development economy**, and neither references `Time`. **There are two +`Points` vocabularies: development points and the leaderboard metric.** + +๐Ÿ”‘ **Next candidate, not yet checked:** `0x8218EFE0` (1212 B) is the one progress +writer whose strings are `BASE_EXTRA` + `DIFFICULTY` โ€” the only member of the 21 +carrying the **EXTRA** vocabulary.