An unidentified item's true name can reach players through title reads outside the wiki #877

Closed
opened 2026-09-27 03:49:37 +00:00 by claude-bot · 2 comments
Collaborator

Lane 8 PR 3 (#734) adds unidentified items (IS-122). A page carries player_title, and players see that title instead of the true one. The swap is done on every wiki read, in the AI and transcriber feeds and in export, and test_wiki_crawl covers all of those.

The gap: roughly 150 other LoreEntry.title reads in app/ weren't audited. Notifications (bell lines, emails and Discord posts that name a page), session and shelf text outside the card faces, search elsewhere, and similar paths could show a player an item's true name.

Fix: an AST allowlist, like test_body_readers.py, for reads of LoreEntry.title. Each read either goes through a title-for-reader helper or is allowlisted as GM-only or unseen, and any new read fails CI. Then convert or justify each existing read.

Lane 8 PR 3 (#734) adds unidentified items (IS-122). A page carries `player_title`, and players see that title instead of the true one. The swap is done on every wiki read, in the AI and transcriber feeds and in export, and `test_wiki_crawl` covers all of those. **The gap:** roughly 150 other `LoreEntry.title` reads in `app/` weren't audited. Notifications (bell lines, emails and Discord posts that name a page), session and shelf text outside the card faces, search elsewhere, and similar paths could show a player an item's true name. **Fix:** an AST allowlist, like `test_body_readers.py`, for reads of `LoreEntry.title`. Each read either goes through a title-for-reader helper or is allowlisted as GM-only or unseen, and any new read fails CI. Then convert or justify each existing read.
Author
Collaborator

Picking this up (1 Oct), on fix/877-title-reads. Plan as the issue says: enumerate every read of a lore page's title under app/, classify each (through the title-for-reader helper; GM-only by construction; never shown; or a leak), fix each leak with a test that a player sees player_title, and add an AST allowlist test beside test_body_readers.py so a new unclassified read fails CI. Lane 11's sheet code (sheets named after their page) is in scope.

Picking this up (1 Oct), on `fix/877-title-reads`. Plan as the issue says: enumerate every read of a lore page's title under `app/`, classify each (through the title-for-reader helper; GM-only by construction; never shown; or a leak), fix each leak with a test that a player sees `player_title`, and add an AST allowlist test beside `test_body_readers.py` so a new unclassified read fails CI. Lane 11's sheet code (sheets named after their page) is in scope.
Author
Collaborator

Done in #994, merged 1 Oct (main 566185fe).

Found: PUT /lore/{id}/identity accepts any kind of page, so quests, characters and NPCs can be unidentified too, not only items. Of about 250 .title reads under app/, 103 were a page's title, and sixteen leaked the true name to someone who should read the party's:

History; a name-clash oracle on create and rename; the bell, email and Discord DM for a shown handout; the reveal's stored row; the Discord handout post; a session's cold open; the quest log; the pre-session reminder's open threads; the bot's /quests; a timeline row with no words of its own; "Add to a sheet"; a new sheet's starting name; a level-up's milestone; a rest's refusal; the proposal-merge prompt (its output is not GM-reviewed); and the wiki list's sort order.

Each is fixed with a test that fails on the old code (tests/wiki/test_unidentified_titles.py).

The guard: tests/wiki/test_title_readers.py lists every .title read by module, function and expression, with a count and a reason for each page title. A new read fails CI. It already caught two in #830's export module on the next merge, which were then classified. Its docstring lists what it cannot see (rows read by key, a title copied into another column, aliases, the bot and the frontend).

Decisions and follow-ups

  • Words written once for everyone (a reveal's row, the Discord handout post, a level-up milestone, a new sheet's name) use the party's name for GMs too: question W18 on the Questions page.
  • No data fix for rows written before this: unidentified items arrived in lane 8 and have never been released, so no production data holds a true name in a reveal row.
  • #993: GM-reviewed prompts still get the true name; a proposal about an unidentified item doesn't match its page.
  • The audit log's descriptions keep true titles; it is administrators-only.
Done in #994, merged 1 Oct (main 566185fe). **Found:** `PUT /lore/{id}/identity` accepts any kind of page, so quests, characters and NPCs can be unidentified too, not only items. Of about 250 `.title` reads under `app/`, 103 were a page's title, and **sixteen leaked** the true name to someone who should read the party's: History; a name-clash oracle on create and rename; the bell, email and Discord DM for a shown handout; the reveal's stored row; the Discord handout post; a session's cold open; the quest log; the pre-session reminder's open threads; the bot's `/quests`; a timeline row with no words of its own; "Add to a sheet"; a new sheet's starting name; a level-up's milestone; a rest's refusal; the proposal-merge prompt (its output is not GM-reviewed); and the wiki list's sort order. Each is fixed with a test that fails on the old code (`tests/wiki/test_unidentified_titles.py`). **The guard:** `tests/wiki/test_title_readers.py` lists every `.title` read by module, function and expression, with a count and a reason for each page title. A new read fails CI. It already caught two in #830's export module on the next merge, which were then classified. Its docstring lists what it cannot see (rows read by key, a title copied into another column, aliases, the bot and the frontend). **Decisions and follow-ups** - Words written once for everyone (a reveal's row, the Discord handout post, a level-up milestone, a new sheet's name) use the party's name for GMs too: question W18 on the Questions page. - No data fix for rows written before this: unidentified items arrived in lane 8 and have never been released, so no production data holds a true name in a reveal row. - #993: GM-reviewed prompts still get the true name; a proposal about an unidentified item doesn't match its page. - The audit log's descriptions keep true titles; it is administrators-only.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/Quest-Board#877
No description provided.