Add a feature roadmap and staged implementation plan to refactor shared D&D module assets

This commit is contained in:
2026-07-06 12:03:49 -05:00
parent 47cf7e76ec
commit 7861d040df
4 changed files with 445 additions and 74 deletions

157
docs/roadmap/dnd.md Normal file
View File

@@ -0,0 +1,157 @@
# D&D Shared Module Helper Roadmap
This roadmap defines the target state for consolidating Dungeons & Dragons
helper code that is currently duplicated across the implemented D&D modules.
The refactor should preserve runtime behavior: module keys, prompt IDs, prompt
versions, Scriptorium-visible prompt files, message order, response schemas,
reference slot compatibility, manifests, diagnostics policy, and CLI/config
semantics should not change.
## Motivation
The `dnd/scenes` chunker and `dnd/spells` extractor now share several D&D prompt
and reference conventions:
- prompt inputs named `transcript`, `players`, `party`, and `glossary`;
- deprecated `roster` reference bindings mapped to the `party` prompt input;
- D&D reference media-type declarations;
- deterministic rendering of one or more reference files into prompt input
materials;
- shared D&D prompt fragments currently under `internal/modules/sharedassets`;
- prompt hash inclusion for shared D&D prompt fragments.
Keeping this logic duplicated makes future D&D modules more likely to drift. It
also makes small prompt-contract changes expensive because each module must
update the same reference-slot, prompt-input, and test helper behavior.
## Target Package Boundary
D&D-specific shared helpers should live under:
```text
internal/modules/sharedassets/dnd
```
The package name should be `dnd`. This keeps generic shared asset plumbing in
`internal/modules/sharedassets` while giving D&D-specific prompt and reference
policy a clear home.
`internal/modules/sharedassets` should continue to own:
- generic shared prompt asset registration;
- `ModulePromptFS` and related prompt filesystem layout helpers;
- non-domain-specific embedded asset plumbing;
- future prompt assets only when they are truly domain-neutral.
`internal/modules/sharedassets/dnd` should own D&D-specific reusable helpers:
- D&D shared prompt fragments;
- accepted reference media types for D&D reference slots;
- reference slot definitions for `players`, `party`, `glossary`, and the
deprecated `roster` alias;
- prompt input assembly for D&D modules that use the shared prompt fragments;
- deterministic reference material rendering;
- shared D&D prompt hash parts.
Concrete D&D modules should continue to own:
- stage contracts and module registration;
- module keys and provided/required capabilities;
- prompt IDs and prompt versions;
- module-local prompt definitions, task prompts, and instruction prompts;
- response schema definitions and schema metadata;
- artifact interpretation, scene interpretation, validators, and output
conversion.
Framework, core, and CLI packages must not import
`internal/modules/sharedassets/dnd`.
The intended asset layout is:
```text
internal/modules/sharedassets/
assets.go
prompt_fs.go
internal/modules/sharedassets/dnd/
assets.go
prompt_inputs.go
references.go
assets/
prompts/
common-dnd-system.md
common-dnd-transcript.md
common-dnd-references.md
```
The parent `sharedassets` package should have no hard-coded knowledge of
`common-dnd-*` files. It should provide generic composition primitives that a
domain package such as `sharedassets/dnd` can use.
## Desired End State
The `dnd/scenes` and `dnd/spells` modules should remain small owners of their
stage-specific behavior. Shared D&D helpers should remove duplicated mechanics
without hiding module semantics.
After the refactor:
- both modules should call one shared helper to build the D&D prompt input set
from source input and resolved references;
- both modules should use one shared source of truth for D&D reference slots and
accepted media types;
- D&D shared prompt files should live in `internal/modules/sharedassets/dnd`
beside the code that owns the D&D prompt contract;
- generic shared asset plumbing should compose caller-provided shared prompt
files without knowing which domain owns them;
- deprecated `roster` bindings should continue to work as an alias for `party`;
- reference rendering behavior should remain deterministic and covered by tests
in the shared D&D helper package;
- real prompt asset tests should remain decoupled from exact embedded prompt
prose;
- D&D module tests should focus on module contracts, request construction,
response interpretation, validators, diagnostics, and manifest metadata rather
than duplicate reference rendering details.
## Documentation Outcome
Current-behavior docs should describe the D&D shared helper package only where
it helps future maintainers understand ownership:
- [Internal Modules](../internal/modules.md) should mention that common D&D
prompt/reference helper behavior lives under
`internal/modules/sharedassets/dnd`.
- [Internal Overview](../internal/overview.md) may mention the package if it
lists shared module-support packages.
User-facing docs should not describe internal helper placement unless behavior
visible to users changes. This refactor should not change visible behavior.
## Resolved Decisions
### Should generic reference-slot cloning move to `contracts`?
Decision: move generic cloning to `internal/framework/contracts`, for example
as `CloneReferenceSlots`. The operation is not D&D-specific and exists because
`contracts.ReferenceSlot` contains mutable slices. Keeping the clone helper with
the contract type makes defensive copying easier to reuse in future modules
without introducing domain imports.
### Should shared D&D prompt hash parts move into `sharedassets/dnd`?
Decision: move D&D shared prompt hash helpers into
`internal/modules/sharedassets/dnd`. The hash parts are D&D-specific prompt
provenance, and placing them beside the D&D prompt contract reduces drift.
### Should D&D shared prompt assets move into `sharedassets/dnd`?
Decision: move D&D shared prompt assets into
`internal/modules/sharedassets/dnd/assets/prompts`. The current
`common-dnd-system.md`, `common-dnd-transcript.md`, and
`common-dnd-references.md` files are not truly generic; they are part of the
D&D prompt contract. Keeping the files beside D&D reference slots, prompt input
assembly, reference rendering, and prompt hash helpers gives the package clear
ownership of reusable D&D prompt behavior.
The parent `internal/modules/sharedassets` package may still contain prompt
assets in the future, but only when they are genuinely domain-neutral.