docs: group-encounters follow-up backlog + mark helper-tools PRD superseded
- Add follow-up-stories.md (FU-1..FU-11) for the group-encounters feature: deferred items extracted from the PRD non-goals + arch 'Areas for Future Enhancement' + 3-round party-mode decision log (durable timers, ConditionsReader real impl, campaignId enforcement, CAP-17 full refactor, multi-scene passive reveals, spectator views, OQ-8 modifiers, live-E2E gap, plus two verify items). - Mark _bmad-output/specs/spec-encounter-builder/prd.md as superseded (status: final -> superseded) with a pointer to ADR-012: the helper-tools suite is a Claude Code skill, not the local web app + published package (P-1) this PRD described. Closes the drift between the doc and shipped reality. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
---
|
||||
title: "Group Encounters — Follow-up Stories (deferred / ship-and-break items)"
|
||||
status: backlog
|
||||
source_prd: ./prd.md
|
||||
source_arch: ../../arch/arch-mardonar-encounter-engine-2026-06-20/architecture.md
|
||||
created: 2026-06-22
|
||||
updated: 2026-06-22
|
||||
---
|
||||
|
||||
# Group Encounters — Follow-up Stories
|
||||
|
||||
Backlog of items the Group Encounters PRD (`prd.md`) and architecture
|
||||
(`../../arch/arch-mardonar-encounter-engine-2026-06-20/architecture.md`) explicitly
|
||||
deferred, accepted as ship-and-break trade-offs, or left open. The feature set
|
||||
(Features A–E + FR-43) shipped in commit `0028f96`; this file tracks what was
|
||||
*intentionally left for later*.
|
||||
|
||||
> **Confidence note.** These stories are derived from the PRD/arch *design docs*,
|
||||
> not a line-by-line audit of the merged code. Each story is tagged
|
||||
> `confidence: high|medium|verify`. Before pulling one into a sprint, confirm
|
||||
> against the current source that it is still outstanding (some may have landed
|
||||
> post-merge without updating these docs).
|
||||
|
||||
---
|
||||
|
||||
## FU-1 — Durable timed-check timers + multi-instance locking
|
||||
- **status:** deferred · **confidence: high**
|
||||
- **Source:** PRD §3 Non-Goals ("Durable timers… Redis-TTL-backed timers are deferred (NFR-2)"); FR-5 (restart cancels pending timed check as fail); arch line 561 "Areas for Future Enhancement: durable timers / multi-instance locking (if scale lands)"; ADR-006 (in-process mutex with documented Lua swap path).
|
||||
- **Today:** Timed single-player checks use in-memory timers; a bot restart cancels the pending check as a failure. Group-check serialization uses an in-process per-threadId mutex (`sessionManager.atomicMutate`), not Redis Lua/WATCH.
|
||||
- **Acceptance:**
|
||||
- Timed-check timer state persists to Redis with a TTL so a restart rehydrates (not fails) an in-flight timed check.
|
||||
- `atomicMutate` swaps to a cross-process-safe primitive (Redis Lua compare-and-set / `WATCH`) so the engine can run multi-instance without corrupting session/group-check state.
|
||||
- Boot sweep updated for the durable-timer case; no thread hangs on restart.
|
||||
- **Depends on:** a real need to run >1 instance (scale trigger) — the arch scopes this as "if scale lands."
|
||||
|
||||
## FU-2 — ConditionsReader real implementation (E-L2 cutover)
|
||||
- **status:** deferred · **confidence: high**
|
||||
- **Source:** PRD §3 Non-Goal (Foundry write-back for equipment/conditions); FR-31 (read Foundry conditions incl. advantage/disadvantage-granting, feeding FR-43); arch lines 88/118/274 (conditions relay-blocked; `StubConditionsReader` from YAML fixture + `RelayConditionsReader` behind `FOUNDRY_CONDITIONS_ENABLED`; E-L2 sole relay-dependent tier); ADR-008 (ConditionsReader stub).
|
||||
- **Today:** `src/harness/conditionsReader.ts` is a stub returning canned fixture data. D + E-L1 ship independently of the relay. Foundry-granted advantage/disadvantage is not yet wired into FR-43 precedence.
|
||||
- **Acceptance:**
|
||||
- Foundry relay exposes a conditions read RPC against the bot-owned, contract-first schema.
|
||||
- `RelayConditionsReader` implements it; `FOUNDRY_CONDITIONS_ENABLED` flips to true.
|
||||
- Foundry-derived advantage/disadvantage flows into FR-43 precedence (explicit LLM emit arg > Foundry adv/dis > straight roll).
|
||||
- Single Foundry-status→Mardonar-condition mapping seam file in place; build-time version coupling + CI pair-check (no runtime handshake).
|
||||
- **Depends on:** relay maintainer delivering the conditions read RPC to the bot-owned schema.
|
||||
|
||||
## FU-3 — `campaignId` enforcement + campaign-bound encounters
|
||||
- **status:** planned, not enforced · **confidence: high**
|
||||
- **Source:** PRD §3 Non-Goal ("Campaign grouping (`campaignId`). Remains planned, not enforced."); arch lines 256/459 (`campaign:{campaignId}` key in registry; "Campaign-bound encounters: `maxPlayers ≤ party size`").
|
||||
- **Today:** `campaignId` exists in the schema/key registry but is not enforced; encounters are not bound to a campaign party.
|
||||
- **Acceptance:**
|
||||
- Starting an encounter with a `campaignId` binds it to that campaign's party roster.
|
||||
- Lobby `maxPlayers` reconciled against campaign party size (`maxPlayers ≤ party size`).
|
||||
- Latecomer join respects campaign membership.
|
||||
- **Depends on:** CAP-12/13 data-model layer for campaign party.
|
||||
|
||||
## FU-4 — CAP-17 full schema refactor (non-blocking epic)
|
||||
- **status:** deferred (non-blocking) · **confidence: high**
|
||||
- **Source:** arch line 98 ("CAP-17 conditional… scoped minimal… full refactor separate non-blocking epic"); decision-log round 3 ("CAP-17 wizard-reconciliation → non-blocking follow-up").
|
||||
- **Today:** Only the scoped-minimal CAP-17 slice shipped (schema adds the group-encounter fields need + existing-spec migration). The full encounter-spec refactor is deferred.
|
||||
- **Acceptance:**
|
||||
- Full `EncounterSpec` refactor (the part beyond what group encounters required) lands without blocking encounter runtime.
|
||||
- Encounter-wizard reconciliation completed as part of the refactor (named sub-task with its own AC).
|
||||
- **Note:** This is an epic, not a single story — break into stories when prioritized.
|
||||
|
||||
## FU-5 — Multi-scene / staged passive reveals
|
||||
- **status:** deferred (non-goal) · **confidence: high**
|
||||
- **Source:** PRD §3 Non-Goal ("Multi-scene passive reveals… passive reveals apply at encounter start"); FR-7 (passive reveals fire at encounter start); `[ASSUMPTION]` "Passive reveals apply at encounter start only (no scenes/stages today)."
|
||||
- **Today:** Passive reveals fire once at encounter start. The engine has no scenes/stages.
|
||||
- **Acceptance:**
|
||||
- A scene/stage concept exists so passive reveals can fire mid-encounter on stage transitions.
|
||||
- `passiveReveals` can be scoped to a stage, not just encounter start.
|
||||
- **Depends on:** a scenes/stages model (currently absent).
|
||||
|
||||
## FU-6 — Spectator / DM-only private views of group checks
|
||||
- **status:** deferred (non-goal) · **confidence: high**
|
||||
- **Source:** PRD §3 Non-Goal ("Spectator / DM-only private views of group checks").
|
||||
- **Today:** Group checks have the central scoreboard + per-player ephemerals; no DM-only or spectator view.
|
||||
- **Acceptance:** A DM-only (and/or spectator) view of a group check exists without leaking roll state to players.
|
||||
|
||||
## FU-7 — Foundry write-back for equipment/conditions
|
||||
- **status:** deliberate non-goal (listed for completeness) · **confidence: high**
|
||||
- **Source:** PRD §3 Non-Goal ("Foundry write-back for equipment/conditions (Foundry is read-only for these…).")
|
||||
- **Today:** Foundry is read-only for equipment/conditions; only engine-tracked story status is mutable locally.
|
||||
- **Note:** This was a deliberate scope cut, not an oversight. Pull in only if the DM workflow proves it's needed.
|
||||
|
||||
## FU-8 — OQ-8: hidden vs open modifiers on the group scoreboard
|
||||
- **status:** open question · **confidence: high**
|
||||
- **Source:** PRD §8 OQ-8 ("The scoreboard shows each player's modifier (`rolled 16 +3`) to the group. Open rolls (modifiers visible) is the assumed default; confirm or require hidden modifiers."); arch line 474 ("no hide flag for v1 (deferred)").
|
||||
- **Today:** Open rolls — modifiers visible on the scoreboard. No hide flag.
|
||||
- **Acceptance:**
|
||||
- Decision recorded: keep open rolls, **or** add a spec/emit-level hide-modifiers option.
|
||||
- If hidden: scoreboard shows only pass/fail (or the d20 total), not the modifier breakdown.
|
||||
|
||||
## FU-9 — Group-check live E2E gap (release-gate the manual playtest)
|
||||
- **status:** accepted risk → formalize · **confidence: high**
|
||||
- **Source:** arch line 111 ("Group checks = unit + integration coverage only; no live E2E tier… one-token constraint… mitigated by… manual pre-release multi-player playtest checklist item in the release gate"); decision-log round 3 (Murat locks group-check testing = unit+integration-only w/ documented live-E2E gap).
|
||||
- **Today:** Group checks have unit + integration coverage only. Simultaneous multi-player fan-out, successRule N>1, per-user ephemeral delivery, and second-claimant rejection are **not** live-E2E covered. A manual pre-release multi-player playtest checklist is the safety net.
|
||||
- **Acceptance:**
|
||||
- The 7-step manual multi-player playtest checklist is checked into the repo and referenced from the release gate (not just the arch doc).
|
||||
- **Optional (if the one-token constraint ever relaxes):** a second-token live E2E covering the four "unit+integration only" cases.
|
||||
- **Note:** Test debt, not a feature gap.
|
||||
|
||||
## FU-10 — Verify: encounter-wizard reconciliation sub-skills landed
|
||||
- **status:** verify · **confidence: medium**
|
||||
- **Source:** arch line 114 ("Wizard: 2 new sub-skills (Players & Lobby, Passive Reveals) + edits to 2 existing, schema MUST land before wizard reconciliation").
|
||||
- **Today:** The encounter-wizard skill was built 2026-06-20 with 12 nested section skill files (per project memory). Whether the two new sub-skills (Players & Lobby, Passive Reveals) and the two edits actually landed is unconfirmed against this doc.
|
||||
- **Acceptance:** Confirm `.claude/skills/mardonar-encounter-wizard/sections/` contains Players & Lobby + Passive Reveals sub-skills and the two edited existing sections reflect group-encounter fields. If missing → file as a real story.
|
||||
|
||||
## FU-11 — Verify: `src/lib/systemStrings.ts` centralization landed
|
||||
- **status:** verify · **confidence: medium**
|
||||
- **Source:** arch line 114 ("In-world voice: centralize system-string templates in one module (`src/lib/systemStrings.ts`) + named registry + forbidden-word grep on rendered output"); decision-log round 3 (Paige: "systemStrings.voice = 7th harness").
|
||||
- **Today:** The in-world-voice rule is enforced by convention. Whether the centralized `systemStrings.ts` module + the forbidden-word grep on **rendered** output (catches runtime concatenation, not just source literals) landed is unconfirmed.
|
||||
- **Acceptance:** Confirm `src/lib/systemStrings.ts` exists, the named registry is in use, and a CI/hook grep runs on rendered output. If missing → file as a real story (it's a contract-integrity guard for new narrator paths, same family as ADR-005).
|
||||
|
||||
---
|
||||
|
||||
## Not deferred (intentionally closed — do not re-open)
|
||||
- **FR-43 deprecation window / `SKILL_CHECK_SURFACE` flag (FR-49/FR-50):** RETIRED by the round-3 party-mode decision (Mary's trim). Ship-and-break in one release, no flag, plain system notice for old buttons, pinned Discord message. This is *done by design*, not a follow-up.
|
||||
- **Straggler deadline as a spec field:** retracted → became a DM "resolve with current rolls" UX affordance (FR-47), not a spec field.
|
||||
|
||||
---
|
||||
|
||||
## Suggested prioritization
|
||||
1. **FU-2** (ConditionsReader) — unblocks full FR-31/FR-43 fidelity; relay-dependent, so longest lead time → start the contract-first schema now.
|
||||
2. **FU-8** (OQ-8) — a one-decision story; cheap to close and it affects every group-check scoreboard.
|
||||
3. **FU-9** (live E2E gap) — test debt that protects the most residual risk; cheap to formalize the checklist.
|
||||
4. **FU-10 / FU-11** (verify items) — quick confirmations; convert to stories only if missing.
|
||||
5. **FU-1, FU-3, FU-4, FU-5, FU-6** — scope/trigger-gated; pull when the trigger lands (scale, campaign play, scenes, DM demand).
|
||||
6. **FU-7** — only if DM workflow demands it.
|
||||
@@ -1,14 +1,25 @@
|
||||
---
|
||||
title: Mardonar Helper Tools — PRD
|
||||
status: final
|
||||
status: superseded
|
||||
superseded_by: "ADR-012 — helper tools are a Claude Code skill (.claude/skills/mardonar-encounter/ + mardonar-encounter-wizard/), not a web app"
|
||||
created: 2026-06-20
|
||||
updated: 2026-06-20
|
||||
updated: 2026-06-22
|
||||
source_spec: ./SPEC.md
|
||||
target_repo: separate project (TBD — see Open Questions)
|
||||
---
|
||||
|
||||
# Mardonar Helper Tools — PRD
|
||||
|
||||
> **⚠ SUPERSEDED 2026-06-20.** The local-web-app form factor and the published
|
||||
> engine-contract package (P-1) described below were **abandoned** in favor of a
|
||||
> Claude Code skill. The shipped reality is the encounter-authoring skill at
|
||||
> `.claude/skills/mardonar-encounter/` (author + refine) and
|
||||
> `.claude/skills/mardonar-encounter-wizard/` (guided section-by-section
|
||||
> wizard), which validate against the real `EncounterSpecSchema` via an in-process
|
||||
> `loadSpec` round-trip — no published package needed. This document is retained
|
||||
> for history only; do not implement the web-app/package work below. See
|
||||
> `follow-up-stories.md` / ADR-012 in the engine repo.
|
||||
|
||||
> **Re-scoped 2026-06-20** from "encounter builder" to a **helper-tools suite**: a local web app that hosts pluggable DM helper tools, with the **Encounter Builder** as the first tool (plugin #1). The form factor was confirmed as a **local web app** the same day (no longer an assumption). Authored FROM `SPEC.md`, whose 6 capabilities describe the Encounter Builder *tool*; the suite-shell concerns (tool hosting + shared services) are PRD-originated and flagged for spec sync at **OQ-1**.
|
||||
|
||||
## 1. Problem & Vision
|
||||
|
||||
Reference in New Issue
Block a user