feat(screens): retake the two frames a signed-in character changes
All checks were successful
PR checks / checks (pull_request) Successful in 1m13s

The org lead signed a character into the shard by hand — the step automation
could not reach — so shard-status and app-shard were retaken. The shard page
now reads 1 player online in Britain, and the app's card agrees.

Two things worth noticing in the retake. Presence reaches the public page as
counts and regions rather than names, which is the visibility framework working
unprompted. And the guild board's online column did not move: it refreshes only
when a guild's signature changes, which is the stale-roster defect wearing a
different hat.

A sixth defect, visible in the shipped phone capture: the app interpolates a
count into a fixed plural and says "1 players online". Raised, not fixed —
it wants a plurals resource in the app.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-25 10:08:41 -05:00
committed by Claude
parent ebb3f71786
commit 8b6efd5c0a
5 changed files with 29 additions and 17 deletions

32
PLAN.md
View File

@@ -1076,7 +1076,7 @@ hashed off each object's serial, so a re-run reproduces the same world and a scr
be retaken later and still match.
**What the rig found.** A screenshot rig is an integration test with a human in the loop, and
this one turned up five things nothing else had:
this one turned up six things nothing else had:
- **A fresh `module-uo` install pinned wire protocol 3 while the sidecar speaks 4**, so a new
deployment 409s on every shard read until an admin edits the number by hand. The protocol-4
@@ -1096,6 +1096,9 @@ this one turned up five things nothing else had:
the site connects is therefore invisible — the page said none while the shard had two.
- **The Android news list prints raw ISO timestamps.** Found while choosing the phone
captures; the news screen was dropped from that set rather than shipping a picture of it.
- **The app says "1 players online".** `shard_online_count` and `ShardEventText.kt` both
interpolate a count into a fixed plural. Found in the retake after a character was signed in,
and it is in the shipped phone capture — a `plurals` resource is the fix, in the app.
The first is fixed. The rest are raised as product observations, with the rig working around
them: the guilds are built *after* the rename, and the IDOC staging is two passes with a wait
@@ -1114,15 +1117,24 @@ The shard screen is the one worth having. It shows the two houses entering IDOC
activity feed — the same event that reached `/uo/houses` in the browser, on the same rig, in
the same minute.
**One thing that did not happen: a character logged in.** The org lead asked for it, so the
scaffolding sets a known password on a seeded account and a client was driven as far as its
login screen. ClassicUO stores its password crypted and mangles a plaintext one from
`settings.json`, so auto-login fails; synthetic clicks reach the client but synthetic text
does not; and the remaining route — taking the foreground and typing — was tried once, missed
the client, and typed into the browser window the person at this machine was using. It was
not tried again. **Players online therefore reads 0, and the page is honest about a quiet
realm.** The client is left at its login screen: one manual sign-in and
`npm run screens:capture shard-status app-shard` retakes the two frames that would change.
**The character that had to be logged in by hand.** The org lead asked for a player in the
world, and the scaffolding does its half — it sets a known password on a seeded account,
because `BridgeSeeder` gives every account a random GUID nobody kept. Driving the client is
where automation stopped. ClassicUO stores its password crypted, so a plaintext one in
`settings.json` decrypts to garbage and auto-login fails; posted mouse clicks reach the client
but posted text does not; and the remaining route — taking the foreground and typing — was
tried once, failed to take focus, and typed into the browser window the person at this machine
was using. It was not tried again.
The org lead signed in instead, and the two frames that depended on it were retaken: the shard
page now reads **1 player online, in Britain**, and the app's shard card agrees. Both came from
the same `npm run screens:capture shard-status app-shard`, which is the whole point of D45 —
the thing that changed was the world, not the recipe.
Two things that pass is worth noticing here. Presence reaches the public page as **counts and
regions, not names**, which is the visibility framework doing its job unprompted. And the
**guild board's "online" column did not move**: it is refreshed only when a guild's signature
changes, which is the same defect as the stale roster above wearing a different hat.
**A layout decision worth recording.** The `/features/` figures are one-up at the column's
full width, not a two-column grid. Two-up was built first and is the obvious layout for a set