• v4.8.0-rc1 1124bbfc0a

    v4.8.0-rc1
    All checks were successful
    CI / Does this change touch the recording path? (push) Successful in 34s
    CI / Backend lint (ruff) (push) Successful in 36s
    CI / Which journeys does this change need? (push) Successful in 35s
    CI / Bot/backend version sync (push) Successful in 58s
    CI / Summarisation accuracy eval harness (stub provider) (push) Successful in 59s
    Release / Create Forgejo release (push) Successful in 25s
    CI / Bot tests and audit (push) Successful in 2m18s
    CI / Feedback site tests (push) Successful in 4m7s
    Release / Build and push versioned images (push) Successful in 6m6s
    CI / Frontend (shard 2/2) (push) Successful in 9m31s
    CI / Docker image build (push) Successful in 10m40s
    CI / Synthetic session harness (no GPU, no LLM) (push) Successful in 8m15s
    CI / Frontend (shard 1/2) (push) Successful in 11m54s
    CI / End-to-end journeys (phone) (push) Successful in 26m33s
    CI / Backend migration, tests, and audit (push) Successful in 39m1s
    CI / End-to-end journeys (desktop) (push) Successful in 28m38s
    CI / End-to-end journeys (keyboard) (push) Successful in 29m5s
    Pre-release

    claude-bot released this 2026-11-07 16:32:38 +00:00 | 10 commits to main since this release

    Prerelease of 4.8.0 for testing on the dev server; not for production.

    Added

    • [webapp] The weekly email digest. Turn on "Weekly digest" in Settings → Notifications (it appears wherever the instance can send mail, and starts off), pick the day of the week, and once a week, at 8am in your own time zone on that day, you get one email across all your live campaigns: the sessions coming up in the next seven days with your answer, the sessions played in the last seven days, and the time votes still waiting for you. It lists titles and links only, never a summary or transcript, skips archived, deleted and muted campaigns, and is not sent in a week with nothing to say. Every digest ends with a "Stop these emails" link, and carries the one-click unsubscribe headers so a mail app's own Unsubscribe button turns it off (#11).
    • [repo] The feedback site has a company-rating page at /companies. It rolls a
      whole business offline from reviewed recipes (23 trades, about 140 jobs, with the
      names from the name generator); testers mark each trade up or down and leave notes,
      and the admin readout tallies them. Slice 1 of "Fill it in" (#1328): the recipes only,
      nothing in Quest Board changes yet.
    • [webapp] Convert a sheet saved for another game into the campaign's, as a draft (#958, IS-424, D5).
      A sheet whose system is not the campaign's says so (to the GM and the
      character's player) and offers "Convert into , as a draft" or "Keep it
      as it is"; with no AI set up the button says AI is needed. The campaign's own
      AI reads the old sheet and the new definition and proposes values and
      feats, spells and items, each with how sure it was and why, which the person
      reviews, edits or leaves out before one confirm. Every value is held to the
      new definition (type, range, choices); what does not fit, and what nothing
      took, is listed as not converted with the reason; entries are matched by name
      to the new system's rules or kept as text. Nothing is saved until the
      confirm, and the model is not asked again then. Converting moves the page's
      sheet to the new definition in place and keeps the old sheet in its history
      (versions now carry their game system, and one written for the old game can't
      be put back onto the new). A GM's locks hold: a player can't convert a sheet
      whose locks the new sheet can't keep, and a GM's original locks are recorded.
      Migration d958c0a1b2c3 adds character_sheet_versions.system_id
      (backfilled). BOT_CONTRACT_VERSION is unchanged.
    • [webapp] Import a Pathfinder 2e character from Pathbuilder. "Import from Pathbuilder…" is in a character sheet's More menu, and beside "Make a sheet" on a player character's page that has none. Give the six-digit code from Pathbuilder (Menu, Export, Export JSON), paste its JSON or choose a .json file, or upload the character sheet PDF it fills in. A preview comes first and saves nothing: what will happen, what was not read and why, which feats, items and spells matched the loaded content, and where Pathbuilder's numbers differ from Quest Board's. Replacing a sheet that came from somewhere else asks first. Your browser fetches the code from pathbuilder2e.com, so the web server's connect-src now allows that one origin (#958).
    • [webapp] Pathbuilder import, the backend: a Pathfinder 2e character comes in from Pathbuilder's build JSON or its filled character-sheet PDF (#958, D82).
      A preview first, with a report of what was read and what was not (and the
      numbers Pathbuilder worked out held against Quest Board's); then one confirm
      makes the page's sheet or, when the provenance matches, updates the same one.
      The mapping is the pack's imports.pathbuilder map in the Pathfinder 2e
      definition. Feats, items and spells are matched to the campaign's rules by
      name and kept as text when not found. The server never calls Pathbuilder
      (its site blocks servers): the browser fetches the JSON and posts it. The
      PDF's form fields are read, never rendered, off the event loop, with size,
      page and field limits. The page that uses it follows.
    • [webapp] Character sheets: Update to version n, with what changes (#958, D83). A sheet made under an older version of its system's definition keeps reading as it is; when a newer version exists and ships a migration, the GM sees "Saved against version 1 of the Pathfinder 2e sheet" with Update to version 2 and What changes (what is renamed, moved, filled in, dropped or worked out, from and to). Nothing happens until the GM confirms, and it is the GM's alone. The sheet as it was is kept as a version first, so a dropped value is recoverable and the update can be put back from Versions (which also puts the old definition back). A definition's migrations are now typed and checked when a pack is uploaded: rename, move, default, drop and compute (the formula language, no dice), with paths checked against the version they start from and the one they arrive at; chains (v1 to v2 to v3) run in order. Every built-in definition is still version 1, so nothing offers an update yet.

    Changed

    • [webapp] The recording panel and Table mode now share one live recording stream per session in a tab, instead of each opening its own; it closes when the last view of the session goes away (#1247).
    • [repo] The secret scanner no longer reports 34 known-false findings (#132): rules-pack record keys, model names beside a provider host, and the invented Discord ids and dummy key in tests are allowlisted by exact value shape in .gitleaks.toml, each with its reason, so a real finding stands out.
    • [webapp] A new version is picked up without pressing Reload, at a safe moment. When one is waiting, Quest Board applies it on your next move to another page, when the tab is hidden, or after two minutes with no input, but never with anything unsaved, while offline, on the table or on the page of a session being played. Afterwards a short notice says "Quest Board was updated." The Reload banner now appears only if the update has waited half an hour (#1341).
    • [webapp] Suggested wiki fact changes also ask about pages the transcript names, not only pages linked to the session (#1342): every live, non-proposed page of the campaign whose title or alias is spoken in the session (and whose type has facts to suggest) is now asked about, after the linked ones and the most-named first, up to 12 a session; the rest are counted as skipped_cap. Titles shorter than three characters and small words are never used to find a page. The backfill task takes force_zero_asked to re-run sessions that asked about nothing before.
    • [repo] The backend image no longer downloads the PostgreSQL apt signing key at build time. The PGDG key is committed at docker/keys/pgdg.asc (fingerprint recorded in the Dockerfile and checked by a test) and copied in, so a build no longer depends on postgresql.org being reachable. apt still verifies the repository against it. (#1346)
    • [docs] D341 records where a sheet conversion is reviewed: in the dialog, not Suggested wiki updates (#958).

    Removed

    • [webapp] Cleanup after the built-in name generator: the old AI names code is gone, and names runs nothing used are kept for a day, not 30 days. The model-written names function and its prompts were no longer reached by any route; they are removed (Describe, the one line a model writes under a name, is unchanged). The daily sweep now deletes a names run older than 24 hours unless it is in a prep sheet or For later, or one of its names is now a page in the wiki. The campaign's memory of names already offered is untouched, so a name is still never offered twice.

    Fixed

    • [webapp] Settings → Notifications no longer skips a heading level (#1360): "Per campaign" is now a second-level heading under the page title, so screen readers navigate the page in order. It looks the same.
    Downloads