Repository navigation
v0.15.8
🚀 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_actionfor 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
- @devin-ai-integration[bot] made their first contribution in #1690
Full Changelog: v0.15.7...v0.15.8
Container image
docker pull ghcr.io/awsomefox/campfire:0.15.8