feat(webapp): names without the AI, the built-in generator in Prep → Names (#1257) #1331

Merged
claude-bot merged 17 commits from feat/1257-names-in-prep into main 2026-11-04 00:45:42 +00:00
Collaborator

Closes #1257 (D330, D331; lane 6l). It also carries #1330 (the rating fixes and lanes 6k and 6l) and the D327–D331 decision rows.

The engine is app/names/, a faithful port of the 44 styles the owner rated on the names page.

  • The lists and the style catalogue were generated by script from names.html and name-styles.js, so no word is hand-typed. The same patterns, probabilities, join and flow rules, and filters (famous names and places, published names, offensive words across joins) are ported.
  • Python and the page agree on acceptance rate and name length over 60,000 draws per style.
  • Place slot (D330): every pattern with a place in it takes an optional real place. With none, it generates one.

Never twice in a campaign: a name_offers table, from migration a1257b0c1d2e (revises f1280a0b1c2d, real downgrade). A draw excludes every name offered before in the campaign and every live page title and alias. Each set is varied, so no two names share a first letter or an ending where avoidable.

No AI for names.

  • A set is still a names run, so Insert, the shelf and History work as before.
  • Describe is a new GM-only route that asks the campaign's AI for one line. Without an AI it answers 409, and the drawer hides the button.
  • The ready-made prefetch pool and its routes are removed.

The drawer follows lane 6l:

  • Kind of name, then a Style that follows it, with the campaign's own system's peoples first.
  • Ten names a set; Save to the wiki; Describe; Another set.
  • The "feel" field and the Ready-made chip are gone.
  • Button names start with their visible words (WCAG 2.5.3).

Checked

  • Backend, on the dev host: 589 passed in a wide run (every migration test, sessions, planning, prep, workbench, generation, history, and the guards). Its one failure, a .title read the title guard flagged, was fixed and the affected set re-run (131 passed). ruff format and check are clean; the version and changelog checks are OK.
  • Frontend: src/pages/prep, 148 passed. eslint has 0 errors.
  • Not yet: the full backend suite (CI), and the render check, which is running.

Left for a follow-up: audio_service.generate_name_options and its prompts are now unused, but were left in place.

New wording goes on the Wording Review page before merge.

🤖 Generated with Claude Code

Closes #1257 (D330, D331; lane 6l). It also carries #1330 (the rating fixes and lanes 6k and 6l) and the D327–D331 decision rows. **The engine** is `app/names/`, a faithful port of the 44 styles the owner rated on the names page. - The lists and the style catalogue were generated by script from `names.html` and `name-styles.js`, so no word is hand-typed. The same patterns, probabilities, join and flow rules, and filters (famous names and places, published names, offensive words across joins) are ported. - Python and the page agree on acceptance rate and name length over 60,000 draws per style. - **Place slot (D330):** every pattern with a place in it takes an optional real place. With none, it generates one. **Never twice in a campaign:** a `name_offers` table, from migration `a1257b0c1d2e` (revises `f1280a0b1c2d`, real downgrade). A draw excludes every name offered before in the campaign and every live page title and alias. Each set is varied, so no two names share a first letter or an ending where avoidable. **No AI for names.** - A set is still a `names` run, so Insert, the shelf and History work as before. - **Describe** is a new GM-only route that asks the campaign's AI for one line. Without an AI it answers 409, and the drawer hides the button. - The ready-made prefetch pool and its routes are removed. **The drawer** follows lane 6l: - Kind of name, then a Style that follows it, with the campaign's own system's peoples first. - Ten names a set; Save to the wiki; Describe; Another set. - The "feel" field and the Ready-made chip are gone. - Button names start with their visible words (WCAG 2.5.3). **Checked** - **Backend,** on the dev host: 589 passed in a wide run (every migration test, sessions, planning, prep, workbench, generation, history, and the guards). Its one failure, a `.title` read the title guard flagged, was fixed and the affected set re-run (131 passed). ruff format and check are clean; the version and changelog checks are OK. - **Frontend:** `src/pages/prep`, 148 passed. eslint has 0 errors. - **Not yet:** the full backend suite (CI), and the render check, which is running. **Left for a follow-up:** `audio_service.generate_name_options` and its prompts are now unused, but were left in place. New wording goes on the Wording Review page before merge. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Roll a page's empty facts offline, and the people and places they
point to: dice in the editor, Roll the rest, the list of pages a roll
would make before saving (one level deep), a whole company from size
and trade, Make it a page from the names page, a quick NPC at the
table, and the fact tables for review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The owner's note: three compact rows (the fact's name; the value with
its die or Roll again; Who sees it with Remove) instead of five, with
no overlap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Measured: the die sat 6-10 px above the field and 3 px shorter. It now
starts level with the field and is as tall, on a phone and on a wide
screen; Roll again centres in the same space.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Forests: no Chase, Hanger, Holt, Brake, Weald, Thicket, Copse or
  Wilds, and no bare tree-and-feature names; mostly a place's forest
  or wood, sometimes the Wood of a river, about 18% "The ...".
- Rivers and lakes: Falls, never Force, Foss, Leap or Spout; Heron
  Lake, never "The Heron Lake"; Loch and River forms; about 20% "The".
- Coasts: about 20% "The", bare forms like Heron Bay, no Ness.
- Realms: mostly the name alone (about 25% "The"), no Reach, Marches
  or Old Empire, a rare New realm; sayable, and not a real first name.
- Every landscape: "The <adj> <noun>" about a fifth; a place-name
  helper retries failed joins so they don't tilt the mix.
- Hearthland: no Cyn-, Leod-, Bald-, Mild-, Hild- given parts, no
  -swith, -thryth, -gyth, -den, -er or -ley endings.
- Elvish: no "of the ..." titles; a sound rule against vowel pile-ups
  and four-syllable names.
- Taverns: no Snug. Mountains: no Heights after a made place name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Kind of name and a Style that follows it (the system's peoples first),
ten names from the generator, Save to the wiki and Describe (only with
an AI), Another set; the no-AI, described and nothing-to-offer states,
a phone, and the table of styles per kind. Three questions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two left over from the rating fixes: Westside Pike, and an adjective
that echoes the Prancing Pony.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge remote-tracking branch 'origin/design/1328-fill-it-in' into feat/1257-rating-fixes
Some checks failed
CI / Does this change touch the recording path? (pull_request) Successful in 34s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Bot/backend version sync (pull_request) Successful in 49s
CI / Backend lint (ruff) (pull_request) Successful in 59s
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 1m5s
CI / Which journeys does this change need? (pull_request) Successful in 32s
CI / Feedback site tests (pull_request) Successful in 1m46s
CI / Bot tests and audit (pull_request) Successful in 2m13s
CI / Docker image build (pull_request) Successful in 6m35s
CI / End-to-end journeys (desktop) (pull_request) Has been skipped
CI / Frontend (shard 2/2) (pull_request) Successful in 9m39s
CI / Frontend (shard 1/2) (pull_request) Failing after 10m43s
CI / Backend migration, tests, and audit (pull_request) Successful in 36m0s
9af7781191
# Conflicts:
#	tools/feedback-site/app.py
#	tools/feedback-site/tests/test_app.py
The owner's answers to Q220–Q231.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
WCAG 2.5.3: "Save to the wiki: Wenna Stroud", "Describe: …",
"Another description: …"; and "no names for concepts yet" in the
plural, as drawn.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Forty-four styles ported from the names page, drawn with no model; a campaign is
never offered a name twice or one its wiki holds; styles per kind and game
system; Describe asks the campaign's AI only when it has one. The ready-made
names prefetch and cache are removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge remote-tracking branch 'origin/feat/1257-fe' into feat/1257-names-in-prep
Some checks failed
CI / Does this change touch the recording path? (pull_request) Successful in 17s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Bot/backend version sync (pull_request) Successful in 26s
CI / Docker image build (pull_request) Successful in 32s
CI / Which journeys does this change need? (pull_request) Successful in 16s
CI / Feedback site tests (pull_request) Successful in 45s
CI / Backend lint (ruff) (pull_request) Successful in 1m20s
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 2m20s
CI / Bot tests and audit (pull_request) Successful in 3m50s
CI / End-to-end journeys (desktop) (pull_request) Successful in 10m28s
CI / Frontend (shard 2/2) (pull_request) Successful in 12m38s
CI / Frontend (shard 1/2) (pull_request) Successful in 14m42s
CI / Backend migration, tests, and audit (pull_request) Has been cancelled
b32df95177
fix(webapp): Names in History say the page type, and the drawer's choices stack (#1257)
Some checks failed
CI / Which journeys does this change need? (pull_request) Successful in 24s
CI / Does this change touch the recording path? (pull_request) Successful in 25s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Bot/backend version sync (pull_request) Successful in 29s
CI / Backend lint (ruff) (pull_request) Successful in 46s
CI / Feedback site tests (pull_request) Successful in 51s
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 59s
CI / Bot tests and audit (pull_request) Successful in 2m1s
CI / Docker image build (pull_request) Successful in 5m56s
CI / Frontend (shard 2/2) (pull_request) Successful in 8m0s
CI / Frontend (shard 1/2) (pull_request) Failing after 9m11s
CI / End-to-end journeys (desktop) (pull_request) Successful in 10m28s
CI / Backend migration, tests, and audit (pull_request) Failing after 25m16s
be5b72a561
From the render check: History read "Npc names"; it now uses the page
type's label ("NPC names"). In the Prep margin the Style choice was
cut off side by side ("Human: Hearthla…"); Kind and Style now stack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
Collaborator

Render check of b32df951 on the seeded journeys stack built from this branch: prep sheet and Planning, light and dark, 1280 and 390, 57 shots. The migration reached a1257b0c1d2e.

  • Every page returned HTTP 200, with 0 console errors, 0 axe violations (WCAG 2.2 AA), and no sideways scroll at 390.
  • Without an AI: ten names a set, each with only Save to the wiki. Describe answers 409 with the sentence. A player gets 403 on both routes.
  • With the seed's AI on: Describe shows and returns a line.
  • Never twice: 46 NPC sets, 460 names, all unique. A saved name ("Kenward Chandler") never came back across five more sets. Cities and Companies gave 160 names each, all unique.
  • Style order:
    • NPC: the three human styles, then elf, dwarf, halfling, gnome, orc, goblin, then the PF2e and 5e ancestries.
    • Settlement: Hamlets & villages, Towns, Cities, Streets, Temples.
    • Business: Companies, Taverns, Inns.
    • Concept says "Quest Board has no names for concepts yet."
  • Integration: Insert put all ten names on the sheet (201). History lists the runs on the sheet and on Planning. Save to the wiki made the page on both.
  • Long noble-house names at 390: they wrap with no overlap.

Fixed after the check (be5b72a5): History said "Npc names" and now says "NPC names"; and in the Prep margin the Style choice was cut off ("Human: Hearthla…"), so Kind and Style now stack. Checked: the prep-history, names-routes and title-reader tests (44 passed), the drawer tests (36 passed), and ruff, all clean.

Noted, not changed: every draw is a run, so the sheet's History grows quickly with "Another set". Runs already worked this way, but names now cost nothing to draw. A follow-up could keep only runs that are inserted, shelved or saved.

**Render check** of b32df951 on the seeded journeys stack built from this branch: prep sheet and Planning, light and dark, 1280 and 390, 57 shots. The migration reached `a1257b0c1d2e`. - Every page returned HTTP 200, with 0 console errors, 0 axe violations (WCAG 2.2 AA), and no sideways scroll at 390. - **Without an AI:** ten names a set, each with only Save to the wiki. Describe answers 409 with the sentence. A player gets 403 on both routes. - **With the seed's AI on:** Describe shows and returns a line. - **Never twice:** 46 NPC sets, 460 names, all unique. A saved name ("Kenward Chandler") never came back across five more sets. Cities and Companies gave 160 names each, all unique. - **Style order:** - NPC: the three human styles, then elf, dwarf, halfling, gnome, orc, goblin, then the PF2e and 5e ancestries. - Settlement: Hamlets & villages, Towns, Cities, Streets, Temples. - Business: Companies, Taverns, Inns. - Concept says "Quest Board has no names for concepts yet." - **Integration:** Insert put all ten names on the sheet (201). History lists the runs on the sheet and on Planning. Save to the wiki made the page on both. - **Long noble-house names at 390:** they wrap with no overlap. **Fixed after the check** (be5b72a5): History said "Npc names" and now says "NPC names"; and in the Prep margin the Style choice was cut off ("Human: Hearthla…"), so Kind and Style now stack. Checked: the prep-history, names-routes and title-reader tests (44 passed), the drawer tests (36 passed), and ruff, all clean. **Noted, not changed:** every draw is a run, so the sheet's History grows quickly with "Another set". Runs already worked this way, but names now cost nothing to draw. A follow-up could keep only runs that are inserted, shelved or saved.
claude-bot scheduled this pull request to auto merge when all checks succeed 2026-11-03 22:56:56 +00:00
test: the infobox editor's tests wait for the facts panel itself (#1331)
Some checks failed
CI / Bot/backend version sync (pull_request) Successful in 26s
CI / Docker image build (pull_request) Successful in 30s
CI / Backend lint (ruff) (pull_request) Successful in 30s
CI / Does this change touch the recording path? (pull_request) Successful in 12s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Which journeys does this change need? (pull_request) Successful in 20s
CI / Feedback site tests (pull_request) Successful in 48s
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 52s
CI / Bot tests and audit (pull_request) Successful in 1m59s
CI / Frontend (shard 2/2) (pull_request) Successful in 7m34s
CI / End-to-end journeys (desktop) (pull_request) Successful in 10m23s
CI / Frontend (shard 1/2) (pull_request) Successful in 14m10s
CI / Backend migration, tests, and audit (pull_request) Failing after 24m47s
abd61ba65f
CI's frontend shard found the heading a moment before its section on a
slow runner and got null. Passes locally on main and the branch; the
helper now waits for the section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
Collaborator

CI: Frontend shard 1 failed on src/pages/wiki/EditorFacts.test.jsx › "starts a new page with its kind's facts, empty" with Expected container to be an Element … but got null. The test's facts() helper found the heading a moment before its section on a slow runner.

The test passes locally on this branch and on main (9/9), so this PR didn't break it. The helper now waits for the section itself (abd61ba6). Both infobox editor test files pass (15).

The owner approved wording v-001 to v-006. The PR is set to merge when CI passes.

**CI:** Frontend shard 1 failed on `src/pages/wiki/EditorFacts.test.jsx` › "starts a new page with its kind's facts, empty" with `Expected container to be an Element … but got null`. The test's `facts()` helper found the heading a moment before its section on a slow runner. The test passes locally on this branch and on main (9/9), so this PR didn't break it. The helper now waits for the section itself (abd61ba6). Both infobox editor test files pass (15). The owner approved wording v-001 to v-006. The PR is set to merge when CI passes.
Author
Collaborator

CI: tests/wiki/test_body_readers.py (the page-text guard) flagged names/engine.py make_order reading SOCIETY.body. That was a word list (Circle, Lodge, Covenant…), not a page's text, so it's renamed to SOCIETY.group. No other guarded attribute names (.title, .body, .transcript, .summary, .text, .aliases) are used in app/names/.

CI stops at the first failure, so before pushing I ran the full backend suite on the dev host: 10,721 passed, 0 failed. ruff format and check are clean. The PR is re-scheduled to merge when CI passes.

**CI:** `tests/wiki/test_body_readers.py` (the page-text guard) flagged `names/engine.py` `make_order` reading `SOCIETY.body`. That was a word list (Circle, Lodge, Covenant…), not a page's text, so it's renamed to `SOCIETY.group`. No other guarded attribute names (`.title`, `.body`, `.transcript`, `.summary`, `.text`, `.aliases`) are used in `app/names/`. CI stops at the first failure, so before pushing I ran the **full backend suite** on the dev host: **10,721 passed, 0 failed**. ruff format and check are clean. The PR is re-scheduled to merge when CI passes.
fix(webapp): the order style's word list isn't called body (#1257)
All checks were successful
CI / Bot/backend version sync (pull_request) Successful in 25s
CI / Backend lint (ruff) (pull_request) Successful in 29s
CI / Does this change touch the recording path? (pull_request) Successful in 13s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Which journeys does this change need? (pull_request) Successful in 13s
CI / Feedback site tests (pull_request) Successful in 49s
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 55s
CI / Bot tests and audit (pull_request) Successful in 2m4s
CI / Docker image build (pull_request) Successful in 7m43s
CI / Frontend (shard 2/2) (pull_request) Successful in 8m18s
CI / Frontend (shard 1/2) (pull_request) Successful in 9m55s
CI / End-to-end journeys (desktop) (pull_request) Successful in 11m25s
CI / Backend migration, tests, and audit (pull_request) Successful in 38m58s
9a03da6f15
CI's page-text guard flags every .body read; SOCIETY.body was a list of
words (Circle, Lodge, Covenant…), now SOCIETY.group.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign in to join this conversation.
No description provided.