acdream/docs/plans/2026-08-25-assess-window-parity-campaign.md
Erik ddbd7e4096
Some checks failed
CI / linux-portable (push) Failing after 3m15s
CI / windows-gate (push) Failing after 6m54s
CI / release (push) Has been skipped
docs+fix(ui): Campaign AS CLOSED — connected gate PASSED; AS-GF1 probes stripped; #443 narrowed
The owner ran the Campaign AS connected gate live and passed it. The two
gate findings resolved in-round: the extras-list "black rectangle" is
retail's own authored scroll-less clipped listbox (no scrollbar authored
on 0x10000335, verified against the live DAT; wheel-scroll/resize reveal
rows — AS-GF1 65f6f584 ruled it not a code defect), and the paperdoll
symptom narrowed from "renders nothing" to an intermittent FIRST-OPEN
DELAY: the probe round proved the private render layer healthy from the
first frames (nonzero handle, 34 MeshRefs, sane bounds/camera) for both
the examination clone and the inventory doll, with mesh residency/upload
latency the leading suspect. #443 stays open with that narrowed shape.

Per the probe-dies-with-its-investigation rule this strips
CreatureAppraisalViewportDiagnostics, its call sites, and the
launch-options row in one commit (recoverable via git show 65f6f584).
App hermetic suite green (6,337/0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 14:15:26 +02:00

157 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Campaign AS — assess/examination window retail parity (player targets)
**Status: CLOSED — CONNECTED GATE PASSED 2026-08-25 ("fixed! gate pass!").**
AS1AS5 review-closed; the gate round harvested two findings, both resolved
in-round: the extras-list "black rectangle" is retail's own authored
scroll-less clipped listbox (no scrollbar authored on 0x10000335 — verified
against the live DAT; wheel-scroll and resize reveal rows; AS-GF1
`65f6f584` ruled it not-a-code-defect), and the paperdoll's absence
narrowed to an intermittent FIRST-OPEN DELAY (#443, kept open) after the
probe round proved the render layer healthy — the render pipeline was
never broken by this campaign. Gate probes deleted at close per the
probe-dies rule (recoverable via `git show 65f6f584`). Branch NOT pushed —
the owner pushes on their word.
Owner report (2026-08-25, side-by-side screenshots, acdream vs retail, both
assessing the player "Dww"): acdream's examination window on a PLAYER target
is missing retail's identity block and body/config sections.
Missing vs retail:
1. **Identity block** under the title bar: gender + heritage ("Female
Aluvian"), current display title ("War Mage"), PK status
("Non-Player Killer") — none of it rendered by acdream.
2. **Per-bodypart armor levels**: retail shows three grouped rows —
"Head/Chest/Groin AL: x/y/z", "Bicep/Wrist/Hand AL: x/y/z",
"Thigh/Shin/Foot AL: x/y/z". Absent in acdream.
3. **Target-configurable extras**: retail only shows what the assessed
player configured to show (date of birth, age, number of deaths, chess
rank, fishing skill, damage/crit ratings, …). acdream shows a
"Dmg/CritDmg Rating:" line but not the rest of the family.
4. **Allegiance/faction lines**: allegiance name/patron/faction shown when
the target has them. Absent in acdream.
Explicit owner rulings:
- **The animated 3D paperdoll is an INTENTIONAL acdream deviation**
(register row AD-114, filed at AS2). Retail's examine preview clone is
NOT a static tinted preview — it is INDEPENDENTLY ANIMATED, just
decoupled from the live target: `BasicCreatureExamineUI::Init
@0x004AB9C0` clones the selected object via `CPhysicsObj::makeObject
@0x005144B0` (which runs `MorphToExistingObject` then
`play_script_internal(setup->default_script_id)`), sets the clone's
heading to 191.367905°, and `CreatureMode::Render @0x004529D0` runs
`update_position` on it every frame. acdream's deviation is that our
preview mirrors the target's LIVE motion instead of playing its own
private, decoupled cycle. Keep ours. (Retail's preview colors are also
buggy on the owner's reference setup, so porting the decoupled clone
would not even be a faithfulness win.)
- Retail comparison is the oracle for text composition; all strings come
from DAT StringTables per the decomp — **never hardcoded English
literals**.
- All UI work goes through the standard GUI classes (UiLabel / UiPanel /
UiScrollablePanel / retail chrome) — no bespoke widgets, no quick fixes.
## Execution model (set by owner)
- **Fable** plans and coordinates (this doc + slice contracts + synthesis).
- **Sonnet** implements each slice against a pinned contract.
- **Opus** runs the dual-lens review per slice — retail-faithfulness lens +
architecture lens — followed by a fix round; slice is REVIEW-CLOSED only
after the re-review accepts the fixes.
- Commit to the worktree branch (`claude/windmill-seam-and-solid-polys`) as
slices land, full hermetic suite green each time
(`Lane!=InstalledDat&Lane!=PreparedPackage&Lane!=Live&Lane!=Manual&Lane!=Timing&Lane!=Windows&Lane!=Linux&Lane!=SystemFont&Purpose!=Diagnostic&Status!=KnownFailure`).
- **Do NOT push to gitea until the owner says so.**
- Campaign stops when all slices are REVIEW-CLOSED and the connected-gate
script is written and waiting on the owner's drive.
## Ground truth sources
- `docs/research/named-retail/acclient_2013_pseudo_c.txt` — the retail
examination window class, line composition, StringTable keys, 0x00C9
client-side parse.
- `references/ACE/` — what our live server actually sends per flag, and the
target-option gating rules.
- `references/Chorizite.ACProtocol/` — field-order cross-check.
- Campaign CT sealed verdicts (`claude-memory/project_character_panel_campaign.md`)
— the heritage/title composition and PK bitfield rules already ported for
the character panel; REUSE, do not re-derive.
- Research synthesis doc (AS1 output):
`docs/research/2026-08-25-campaign-as-ground-truth.md`.
## Slices (FINAL — re-cut at AS1: the 0x00C9 parse is already complete and
the appraisal profile is session-scoped UI presentation state flowing
through the established router seam, so the skeleton's wire and
runtime-owner slices are unnecessary; all work is App-side composition)
**Oracle for every slice:**
`docs/research/2026-08-25-campaign-as-ground-truth.md` (AS1 synthesis) —
its §2 line-composition tables, §3 wire truth, §4 gap ledger G1G10, and
§5 rulings R1R8 are BINDING on implementers and reviewers. Deviating from
a ruling requires a plan-doc amendment, not an implementer judgment call.
- **AS1 — ground truth synthesis (DONE, Fable).** Three research lenses
merged; gap ledger G1G10; rulings R1R8.
- **AS2 — header identity block (Sonnet).** Fix the element mis-mapping in
`AppraisalUiController.ApplyCreature(character: true)` per ground truth
§2a: `0x10000150` ← composed gender+heritage (reuse
`CharacterIdentityText`, including retail's heritage-id overrides and the
creature fallback when heritage==0); `0x10000151` ← current display title
via `CharacterTitleResolver` (Int 261, fallback String 5 Template);
`0x10000152` ← PK line from the assessed `ClientObject`'s PWD bits
(`PlayerKillerStatusBitfield`, ruling R7); `0x1000053A` ← String 47
AllegianceName gated on Int 30 ≥ 1, DELETING the invented
"Assessment incomplete" literal. First-ever `AppraisalView.Character`
controller tests (G10). Register: file the animated-paperdoll AD row
(owner-ruled intentional deviation 2026-08-25) in this commit.
- **AS3 — armor-level rows + extras-list plumbing (Sonnet).** Plumb
`Parsed.ArmorLevels` into the extras composer (signature change from
bare `PropertyBundle`); emit the spacer + three grouped AL rows before
the rating rows per ground truth §2b rows 37, including the `*%d`
≥9999 unenchantable rendering, retail's per-row rating gates
(307|313|314 · 308|315|316 · 350|351), spacer discipline per ruling R4,
and the `* = Unenchantable` legend per ruling R3 (unconditional,
gate-verified). Ordering pinned by tests.
- **AS4 — society/allegiance/fellowship + configurable extras (Sonnet).**
Ground truth §2b rows 12 and 814: the Society row with rank bands and
the local-vs-target faction color rule; the Monarch/Patron/Followers
cascade; Fellowship; Arrived in Dereth; Time in Dereth (locate or port
`ClientUISystem::DeltaTimeToString` — grep for an existing port first);
Chess Rank; Fishing Skill; Deaths ("Has never died" at ≤0); Titles
Earned. Register: narrow AP-110 ("exhaustive character detail regions"
clause retires) in this commit.
- **AS5 — allegiance rank-title table (Sonnet).** Port the 17-function
heritage×gender `AllegianceSystem::GetTitle @0x005B8DD0` table (census
per AP-109's corrected 2026-08-25 text: 11 heritages → 17 functions,
~170 strings; Gearknight/Tumerok male-only reused, Lugian female-only
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 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);
includes the R3 legend retail-side-by-side check and the owner's
configurable-extras toggle matrix.
Slices AS2→AS3→AS4 are SERIAL (all touch `AppraisalUiController` /
`CreatureAppraisalRows` — coupled-file rule); AS5 may run after AS4's
review closes. Each slice: Sonnet implements → full hermetic suite green →
commit → Opus dual-lens review (retail-faithfulness + architecture) → fix
round → narrow re-review → REVIEW-CLOSED.
## Ledger
| Slice | State | Land / fix commits | Notes |
|---|---|---|---|
| AS1 | **DONE 2026-08-25** | (docs commit) | 3-agent research; ground-truth doc committed |
| 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 | **REVIEW-CLOSED 2026-08-25** | `8f8c0c3a` / `9f3e3263` | 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); re-review also flagged + this close fixed the last "retires" phrasing (`AppraisalUiController.cs`) and the CT plan's stale retirement intent |
| AS6 | **GATE PASSED 2026-08-25** | script `87e98395`; gate round `65f6f584` (AS-GF1) + probe-removal close commit | owner ran the gate live; two findings harvested and resolved in-round (extras clip = retail's authored scroll-less listbox, not a defect; paperdoll = #443 first-open delay, render layer proven healthy by probe); identity block, AL rows, allegiance/extras, and the rank-title title bar all owner-verified; probes stripped at close |