Skip to content

v0.15.8

Choose a tag to compare

@AwsomeFox AwsomeFox released this 30 Jul 02:00
· 289 commits to main since this release
07d7358

🚀 Key Highlights

  • Major focus on AI Driver, campaign management, and gameplay reliability improvements.
  • Added stronger safety, consent, moderation, and audit workflows across sessions and AI-assisted play.
  • Expanded support for encounters, maps, character sheets, and print-friendly outputs.

✨ New Features & Improvements

  • Introduced server-wide AI seat defaults, AI session lifecycle phases, and step-level retry/fallback for the AI Driver.
  • Added collaborative handoff mode, DM-facing tool confirmation queue, and bounded conversation history for AI play.
  • Improved campaign and session workflows with organized-play scheduling, admin campaign catalog controls, and guest DM handoff protections.
  • Enhanced content and rules handling with campaign module lineage/rollback, linked compendium inventory acquisition, and structured condition/resource support.
  • Added print-ready reference sheets, print-friendly character sheets and recaps, and encounter activity rail updates.

🐛 Bug Fixes & Maintenance

  • Fixed issues in combat, conditions, damage resolution, concentration checks, and rest/recovery flows.
  • Resolved AI state and security bugs, including transcript caching, consent controls, grant revocation, SSE frame leakage, and race conditions.
  • Improved backups, exports, search, audits, diagnostics, and storage reliability.
  • Addressed multiple test, CI, and e2e flakiness issues to improve release confidence and stability.

Full Changelog

What's Changed

  • fix: One-shot campaign onboarding checklist for new DMs (#507) by @AwsomeFox in #1427
  • fix: Audit retention — no silent history deletion (#502) by @AwsomeFox in #1429
  • fix: Open Legend native character sheets and attribute preservation (#540) by @AwsomeFox in #1433
  • fix: Open Legend exploding action dice in roller, log, MCP, AI (#541) by @AwsomeFox in #1435
  • fix: Guest DM handoff with protected ownership and scoped grants (#545) by @AwsomeFox in #1439
  • fix: FTS5-backed campaign search for scalable queries (#533) by @AwsomeFox in #1430
  • fix: Backup scheduler retention, free-space protection, alerts (#505) by @AwsomeFox in #1425
  • fix: Explain None/homebrew ruleset consequences before create (#508) by @AwsomeFox in #1428
  • fix: Maps onboarding for world, handout, and encounter maps (#520) by @AwsomeFox in #1434
  • fix: 13th Age level initiative and escalation die in combat (#542) by @AwsomeFox in #1436
  • fix: Structured encounter conditions with duration and concentration (#423) by @AwsomeFox in #1440
  • test(web): add missing Linux snapshot baseline for ui-icons unit spec by @AwsomeFox in #1467
  • fix: Compendium facets from active ruleset with Rules/Reference (#544) by @AwsomeFox in #1437
  • fix: Atomically reserve AI token budget before provider calls (#563) by @AwsomeFox in #1444
  • fix: Explain Campfire jargon at first use (#518) by @AwsomeFox in #1431
  • fix: Server-redacted cast sessions for Player Display (#547) by @AwsomeFox in #1438
  • feat: Durable responsive map derivatives instead of decoding originals (#604) by @AwsomeFox in #1515
  • test: nightly live rule-source smoke covering every importer (#568) by @AwsomeFox in #1517
  • test(web): PWA install/offline e2e coverage and CI wiring (#569) by @AwsomeFox in #1519
  • fix: AI readiness prerequisites before promoting AI actions (#519) by @AwsomeFox in #1432
  • fix: Rule pack updates apply upstream corrections to existing slugs (#500) by @AwsomeFox in #1441
  • fix: Cancel scheduled sessions without deleting RSVP history (#504) by @AwsomeFox in #1426
  • fix: Idempotent combat mutations so a lost response cannot double-apply (#580) by @AwsomeFox in #1525
  • fix: Persist AI Driver control state across restarts (#559) by @AwsomeFox in #1442
  • feat: Preserve abuse evidence and add a protected incident workflow (#601) by @AwsomeFox in #1514
  • feat: Authoritative multi-player AI Table transcript (#572) by @AwsomeFox in #1524
  • fix: AI consent controls and durable generation provenance (#501) by @AwsomeFox in #1443
  • feat: Separate backups from redacted adventure distribution packages (#586) by @AwsomeFox in #1536
  • feat: Ground AI Driver rules and canon claims in authorized retrieval (#577) by @AwsomeFox in #1537
  • feat: Campaign module identity, lineage, updates, overlays, and rollback (#585) by @AwsomeFox in #1523
  • ci: type-check the server test tree and the web e2e tree in lint (#1535) by @AwsomeFox in #1542
  • test: assert documented success statuses match what routes actually return (#1538) by @AwsomeFox in #1540
  • fix: Player damage on own character no longer 403s off-turn; fix two e2e flake root causes (#1478) by @AwsomeFox in #1544
  • fix: Namespace AI transcript cache by user and purge it on identity changes (#573) by @AwsomeFox in #1543
  • feat: Read-only Viewer, interactive-guest capability, block, mute, and direct silence (#597) by @AwsomeFox in #1549
  • perf: replace count-by-loading with SQL aggregates in the campaign summary (#602) by @AwsomeFox in #1550
  • fix: audit and revoke AI Driver grants that cannot survive a restart (#1042) by @AwsomeFox in #1551
  • feat: give the AI Driver bounded conversation history (#1038) by @AwsomeFox in #1553
  • fix: moderation-blocked AI map prompts no longer consume the rate-limit slot by @AwsomeFox in #1554
  • test: stop the pseudonymizer test failing when its random tail contains the id by @AwsomeFox in #1564
  • test: scope getByRole('status') queries so they cannot match a loading skeleton by @AwsomeFox in #1565
  • test: wait for the transcript mount tail-pin before scrolling away (#590) by @AwsomeFox in #1563
  • test: scope the combatant Remove locator so it cannot match the map's remove control by @AwsomeFox in #1559
  • feat: let the AI Driver reshape encounters, with visibility and ownership contained (#1022) by @AwsomeFox in #1557
  • test: dismiss the AI-disclosure popover by viewport point, not by a page element by @AwsomeFox in #1569
  • feat: server-wide AI seat defaults that campaigns inherit live (#1070) by @AwsomeFox in #1568
  • fix: role-project every AI driver SSE frame so a new frame type cannot leak by default (#1552) by @AwsomeFox in #1572
  • feat: DM-facing tool confirmation queue on the AI Table (#1558) by @AwsomeFox in #1573
  • fix: make spell-slot overspend an error and give the AI Driver the tool to spend them (#1039) by @AwsomeFox in #1570
  • fix: stop a cleared condition coming back on its own, via one owner of both condition columns by @AwsomeFox in #1575
  • feat: declare inspiration and hero points as rule-system resources, and fix a lost-update race in resource spending (#1073) by @AwsomeFox in #1577
  • feat: structured condition instances on the character sheet, with an explicit combat boundary (#1047) by @AwsomeFox in #1582
  • fix: actually run the 157 web unit specs, and fix the 10 failures that had accumulated (#1574) by @AwsomeFox in #1583
  • feat: collaborative handoff mode for the AI Driver — narrate freely, defer mechanics (#1051) by @AwsomeFox in #1567
  • feat: atomic short rest and long rest, reconciling two divergent recovery paths (#1041) by @AwsomeFox in #1566
  • feat: Participant X-Card — an immediate safety hold across encounters and AI play (#599) by @AwsomeFox in #1547
  • feat: structured tone, pacing and play-style presets for the AI seat (#1049) by @AwsomeFox in #1560
  • feat: Organized-play scheduling — rooms, series, assigned DMs, and cross-campaign conflicts (#588) by @AwsomeFox in #1539
  • fix: Encounters: damage application ignores damage type, resistances, vulnerability, immunity, save-for-half, and crit doubling (#605) by @AwsomeFox in #1596
  • feat: Admin campaign catalog with per-campaign privacy and DM-approved export requests (#587) by @AwsomeFox in #1546
  • feat: AI Driver session lifecycle phases — greeting, active, wrap-up, ended (#1043) by @AwsomeFox in #1561
  • fix: point the AI Driver at resolve_action for attacks — gated on the systems whose maths the resolver actually implements (#1053) by @AwsomeFox in #1576
  • fix: Backup/export scale: stream archives instead of buffering up to gigabytes in memory (#603) by @AwsomeFox in #1541
  • feat: Withhold AI narration that the provider ends with a safety finish reason (#598) by @AwsomeFox in #1545
  • feat: step-level retry and optional fallback provider for the AI Driver (#1052) by @AwsomeFox in #1556
  • feat: token cost estimates for the AI seat, with unknown as the structural default (#1065) by @AwsomeFox in #1580
  • fix: Print-friendly character sheets and recaps (#667) by @AwsomeFox in #1606
  • feat: Session Zero consent — pre-join boundaries and versioned acknowledgments (#600) by @AwsomeFox in #1562
  • test: remove the grid-calibration harness race (#1595) by @AwsomeFox in #1607
  • test: repair the PNG_16_9 fixture and remove the grid-default-normalization route race (#1609, #1608) by @AwsomeFox in #1613
  • feat: Add encounter activity rail (#669) by @AwsomeFox in #1615
  • fix: Persist concentration damage checks (#606) by @AwsomeFox in #1616
  • feat: Add print-ready reference sheets (#670) by @AwsomeFox in #1617
  • fix: classify JSON body reads so no native parse error escapes an adapter (#1602) by @AwsomeFox in #1611
  • fix: Safe persistent data repair diagnostics (#729) by @AwsomeFox in #1619
  • fix: Attachment attribution and accessibility metadata (#735) by @AwsomeFox in #1622
  • fix: Health and diagnostics storage failures (#724) by @AwsomeFox in #1618
  • feat: Linked compendium inventory acquisition (#738) by @AwsomeFox in #1625
  • test(ai-driver): pin grounding redaction on nudge and flag (#1591) by @AwsomeFox in #1632
  • fix(ai-driver): close the read-await-write race that dropped a queued action (#1586) by @AwsomeFox in #1626
  • fix: account-wide /me refresh when a member's role changes (#1590) by @AwsomeFox in #1634
  • feat(audit): transaction-aware audit write path, and consolidate best-effort logging (#1581) by @AwsomeFox in #1630
  • test(e2e): block the PWA service worker in ai-transcript-privacy.spec.ts by @AwsomeFox in #1629
  • feat(characters): expose the #422 resource system via REST + MCP (#1578) by @AwsomeFox in #1633
  • fix(encounters): validate spell-slot spend before consequences in apply_action by @AwsomeFox in #1620
  • fix(ai-dm): rehydrate proactive watchers on boot (#1587) by @AwsomeFox in #1627
  • fix(ai-dm): clamp tokenBudget to its own schema bounds on import (#1593) by @AwsomeFox in #1623
  • feat(admin): add the export-request queue UI to /admin/campaigns by @AwsomeFox in #1631
  • fix(encounters): retry a deduped grid-default write once the owning request settles by @AwsomeFox in #1628
  • fix(security): viewer could resolve/apply/undo combat actions (#1450) by @AwsomeFox in #1621
  • feat(action-resolver): make attack resolution adapter-owned (#1598) by @AwsomeFox in #1635
  • fix(security): require a role floor before ownership checks on three more write sites (#1636) by @AwsomeFox in #1648
  • fix: close createRoom/updateRoom sibling-name check-then-write race (#1638) by @AwsomeFox in #1650
  • fix: password recovery UX (#757) by @AwsomeFox in #1657
  • feat(ai-driver): brand grounding verdicts at the HTTP response boundary (#1639) by @AwsomeFox in #1652
  • fix: campaign-scoped homebrew compendium (#741) by @AwsomeFox in #1656
  • feat(characters): surface inspiration / hero points on the character sheet (#1642) by @AwsomeFox in #1654
  • fix(action-resolver): route save/check proficiency through the rule-system adapter (#1599) by @AwsomeFox in #1660
  • fix: stop a completed session from releasing its room/DM (#1555) by @AwsomeFox in #1663
  • fix(rest): a long rest drops 5e exhaustion by one level, not to zero (#1641) by @AwsomeFox in #1665
  • fix(action-resolver): wire double-total critical damage to save/check failures (#1600) by @AwsomeFox in #1661
  • feat(membership): account-wide signal + redirect on revocation (#1640) by @AwsomeFox in #1653
  • feat: standardize save feedback (#756) by @AwsomeFox in #1659
  • feat(characters): exhaustion as an adjustable, visible level (#1643) by @AwsomeFox in #1662
  • fix(export): stop exporting organized-play scheduling decoration import never restores (#1548) by @AwsomeFox in #1651
  • feat: Inbox sweep — server orchestration + REST endpoint (#1644) by @AwsomeFox in #1649
  • test(conditions): mechanically enforce the single-writer invariant (#1666) by @AwsomeFox in #1668
  • fix: bound every turn-state slot against the adapter action-economy model by @AwsomeFox in #1676
  • fix(action-resolver): bound-check action-economy spend before it is written (#1637) by @AwsomeFox in #1673
  • fix(export): make character conditionInstances exportable and importable (#1667 half B) by @AwsomeFox in #1669
  • feat: campaign library management (#742) by @AwsomeFox in #1655
  • fix(organized-play): cancelSeries releases resources held by future-completed occurrences (#1671) by @AwsomeFox in #1672
  • i18n: localize the AI DM settings card and AI console card by @AwsomeFox in #1624
  • fix(conditions): reconcile the leveled-condition cap and sync between sheet and combatant (#1670) by @AwsomeFox in #1675
  • fix(auth): distinguish non-JSON OIDC discovery responses from unreachable endpoints (#1612) by @devin-ai-integration[bot] in #1690
  • feat(web): add a narrow Tailwind v4 @theme bridge (#1682, #1533 §1) by @AwsomeFox in #1687
  • fix(sessions): avoid 409 on idempotent reschedule retry in forced overlap (#1603) by @devin-ai-integration[bot] in #1691
  • fix(build): remove duplicate ConditionInstance import breaking main by @AwsomeFox in #1702
  • test: pin buildMemberExport's field policy and document why it bypasses fieldsFor/pickFields (#1680) by @AwsomeFox in #1681
  • fix(web): give .seg-opt its own 24px WCAG floor (#1693) by @AwsomeFox in #1696
  • fix(build): restore ConditionInstance import dropped by #1681's merge by @AwsomeFox in #1705
  • fix(a11y): make focus distinguishable from hover on the page-header menu and status picker by @AwsomeFox in #1686
  • fix(a11y): scope PlayerDisplayPage's injected CSS and stop the HP-colour drift by @AwsomeFox in #1689
  • perf(ci): consolidate faster tests and reliable CI monitoring by @AwsomeFox in #1730
  • feat: add a DM-facing Sweep control to the scribe inbox (#1646) by @AwsomeFox in #1679
  • feat(web): add xs density step and retire the !min-h-0/!py-* height-shrink idiom (#1683, #1533 step 2) by @AwsomeFox in #1692
  • feat: expose inbox sweep as MCP tool (#1645) — re-land off main by @AwsomeFox in #1704
  • fix(a11y,web): migrate raw ✕/× close glyphs to (#1715 Part 2) by @AwsomeFox in #1719
  • fix(web): collapse chrome-context GameIcon sizes onto the 4-value UI_ICON_SIZE scale (#1715 Part 1) by @AwsomeFox in #1721
  • feat(membership): account-wide signal + immediate redirect on campaign trash (#1707) by @AwsomeFox in #1710
  • fix(a11y): give the Dashboard, quest detail, and AI Table routes a real h1 (#1711) by @AwsomeFox in #1720
  • docs: point the inbox-sweep promise at the real control by @AwsomeFox in #1701
  • test(inbox-sweep): pin the per-item body regression for #1718 by @AwsomeFox in #1725
  • fix(inbox-sweep): distinguish new vs recovered ledger rows in sweep counts by @AwsomeFox in #1723
  • test(web): add golden coverage for interactive control surfaces (#1694) by @AwsomeFox in #1699
  • feat: add atomic battle-map token batches (#761) by @AwsomeFox in #1726
  • refactor(web): migrate raw cf-btn sites to (#1713 Part A) by @AwsomeFox in #1729
  • feat: manage a separate player display window (#762) by @AwsomeFox in #1728
  • feat: add atomic party recovery workflows (#759) by @AwsomeFox in #1727
  • Add coordinated multi-agent backlog delivery by @AwsomeFox in #1733
  • Fix comment visibility on hidden encounters by @AwsomeFox in #1735
  • fix(characters): redact dmSecret on xp/level-up/spell-slots by @AwsomeFox in #1736
  • fix(characters): require dm-or-owner to roll a check/save for a character by @AwsomeFox in #1739
  • Security: enforce characterId ownership, DM-only scene, role-aware step/token caps by @AwsomeFox in #1740
  • Fix rule-pack lifecycle consistency by @AwsomeFox in #1734
  • Fix: /actions/undo trusts a persisted chain snapshot, not the client token by @AwsomeFox in #1741
  • fix(scheduling): project series detail through the derived schedule status (#1601) by @AwsomeFox in #1748
  • fix(web): fail-fast offline mutations and wire the Large text-size preference (#1534) by @AwsomeFox in #1749
  • fix: serialize encounter lifecycle writes by @AwsomeFox in #1737
  • Fix persistent stuck states by @AwsomeFox in #1738
  • Fence untrusted AI driver prompt context by @AwsomeFox in #1747
  • Add GLM-powered Copilot backlog agents by @AwsomeFox in #1755
  • fix(secrecy): audit and guard dmSecret redaction across all dmSecret-bearing services (#1745) by @AwsomeFox in #1751
  • test(web): guard e2e-spec/config coverage and remove the orphaned unit config by @AwsomeFox in #1742
  • fix(characters): persist deathState/hpTemp/death-saves/resources on PATCH and resolve the level-cap conflict (#1492) by @AwsomeFox in #1752
  • Security: /actions/apply trusts only a chainId, never client resolution by @AwsomeFox in #1750
  • fix(encounters): scope character sheets and turn actions by @AwsomeFox in #1743
  • fix(encounters): allow overriding the stale-sync gate instead of blocking forever by @AwsomeFox in #1744

New Contributors

Full Changelog: v0.15.7...v0.15.8


Container image

docker pull ghcr.io/awsomefox/campfire:0.15.8