fix(ui): Campaign AS AS5 fix round — "retires AP-109" corrected to "narrows" at 6 sites

The AS5 review verified the port exhaustively (170/170 strings, 20
dispatch arms, 17 bounds tests, both call sites) and found one docs-class
defect: five code comments plus the plan slice text claimed AP-109 was
RETIRED while the register correctly keeps the row ACTIVE-narrowed (CT4
FormatXp GetNumberFormatA approximation sliver survives). Comment-only
edits; compile-checked; no behavior change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-08-25 10:30:53 +02:00
parent 8f8c0c3a07
commit 9f3e326374
6 changed files with 11 additions and 8 deletions

View file

@ -118,8 +118,11 @@ a ruling requires a plan-doc amendment, not an implementer judgment call.
reused, Penumbraen aliases Shadowbound, Olthoi excluded by the unsigned
range check) + `AllegianceData::GetFullName @0x005B6950`; wire the
examination title bar (rank from `props.GetInt(0x1E)`, ruling R8) AND
the character panel's name line (closing AP-109's residual). Register:
retire AP-109 in this commit.
the character panel's name line (closing AP-109's rank-prefix residual).
Register: NARROW AP-109 in this commit (CORRECTED at the AS5 review —
retiring would have deleted a live open item: CT4's FormatXp
`GetNumberFormatA` approximation sliver survives as the row's sole
remaining item, so the row stays active-narrowed).
- **AS6 — connected gate script (Fable).** User-driven script
`docs/research/2026-08-25-campaign-as-test-script.md`; two-client where
needed (allegiance/fellowship/PK lines, deception-failure rendering);
@ -140,5 +143,5 @@ round → narrow re-review → REVIEW-CLOSED.
| AS2 | **REVIEW-CLOSED 2026-08-25** | `f8a22589` / `cc5290af` | port exact per dual-lens review; 6 findings (docs/test/refactor) fixed; +AD-114 (animated paperdoll), +AD-115 (title clear-vs-stale), PK bits promoted to `PublicWeenieFlags`; carried follow-up chip: 3 more Core PK-bit copies |
| AS3 | **REVIEW-CLOSED 2026-08-25** | `1616cd3d` (no fix round) | APPROVE first pass — trio/legend/monster-path exact by offset-level decomp verification; R3 flattening theory disproven at source; ratings adjudication: pre-AS3 code already retail-exact. 5 NITs: 12 (legend-order comment), 11 (stronger refresh test) fold into AS4; 14/15 done in the close commit; 13 (geometry-keyed test helper) noted |
| AS4 | **REVIEW-CLOSED 2026-08-25** | `4ade9b04` / `bf8f5b70` (docs-only fix) | port exact per dual-lens review (presence-gate adjudicated FOR the implementer at `InqInt @0x005B3830`; Time-in-Dereth = pre-existing `RetailDurationText @0x00565E10` port, correct reuse); fix round was oracle-doc corrections + records only, NO code change. True full-solution hermetic count 15,528 (the commit's 15,410 was a mis-report). **AS6 carry-note: the Society green/red colorIdx is MODEL-ONLY (ResolveColor no-op pending AP-110 FontInfo residual) — the gate script must NOT gate on row colors.** Pre-existing parallel-load flake surfaced (shadow-caster zero-alloc pin) — #442, unrelated to AS4 |
| AS5 | dispatched 2026-08-25 | — | |
| AS5 | fix round applied, re-review pending | `8f8c0c3a` + comment-fix commit | the campaign's most rigorously verified slice: 170/170 title strings confirmed (164 mechanical diff, 6 PE byte-decoded from the PDB-paired binary), all 20 dispatch arms, all 17 bounds tests, both call sites re-derived; zero behavioral findings. Fix round = "retires AP-109" → "narrows" at 5 comment sites + the plan (the FormatXp sliver keeps the row active) |
| AS6 | pending AS5 review-close | — | |

View file

@ -1,7 +1,7 @@
namespace AcDream.App.UI.Layout;
/// <summary>
/// Campaign AS slice AS5 (2026-08-25, retires register row AP-109): the
/// Campaign AS slice AS5 (2026-08-25, narrows register row AP-109 — its FormatXp sliver survives): the
/// retail allegiance rank-title table and its name-composition wrapper.
///
/// <para><b>Dispatch — <c>AllegianceSystem::GetTitle @0x005B8DD0</c>.</b>

View file

@ -13,7 +13,7 @@ namespace AcDream.App.UI.Layout;
/// </summary>
/// <remarks>
/// <b>Name-line ruling (CT4, 2026-08-24; CLOSED at Campaign AS slice AS5,
/// 2026-08-25 — retires AP-109).</b> Retail's NAME line
/// 2026-08-25 — narrows AP-109; its FormatXp sliver survives).</b> Retail's NAME line
/// (<c>AllegianceData::GetFullName @0x005b6950</c>) prefixes an allegiance
/// RANK title ("&lt;RankTitle&gt; &lt;Name&gt;", same space separator, PE-read
/// @data_794098) when <c>AllegianceSystem::GetTitle(rank, heritage, gender)

View file

@ -164,7 +164,7 @@ public sealed class CharacterSheetProvider
return new CharacterSheet
{
// Campaign AS slice AS5 (retires AP-109): retail's NAME line
// Campaign AS slice AS5 (narrows AP-109 — its FormatXp sliver survives): retail's NAME line
// (gmStatManagementUI::UpdateCharacterInfo @0x004F0770,
// @0x004f0807-@0x004f0895) prefixes AllegianceData::GetFullName
// @0x005B6950's rank title exactly like the examination window's

View file

@ -461,7 +461,7 @@ public sealed class AppraisalUiControllerTests
// ── Campaign AS slice AS5: title-bar allegiance rank-title prefix ─────
// Ground truth: docs/research/2026-08-25-campaign-as-ground-truth.md
// §2a's title-bar row, gap G9, ruling R8. Retires register row AP-109.
// §2a's title-bar row, gap G9, ruling R8. Closes AP-109's rank-prefix residual (the row survives, narrowed to its FormatXp sliver).
[Fact]
public void CharacterResponse_TitleBarPrefixesAllegianceRankTitle()

View file

@ -105,7 +105,7 @@ public sealed class CharacterSheetProviderTests
}
// ── Campaign AS slice AS5: name-line allegiance rank-title prefix ──────
// Retires register row AP-109. Same GetFullName port + rank-property id
// Closes AP-109's rank-prefix residual (row survives, narrowed). Same GetFullName port + rank-property id
// (props.GetInt(0x1E)) as the examination window's title bar
// (AppraisalUiControllerTests.CharacterResponse_TitleBarPrefixes*).