Share the D&D NPC registry and prompt grounding

This commit is contained in:
2026-07-21 04:34:56 +00:00
parent d3e171aa82
commit 92acb45775
23 changed files with 628 additions and 436 deletions

View File

@@ -47,7 +47,8 @@ LLM-backed extensions own their prompt definitions and response schemas under
package-local embedded assets. Shared filesystem composition belongs in
`internal/framework/promptfs`; reusable D&D prompt fragments, reference
declarations, prompt-input assembly, and source-unit helpers belong in
`internal/modules/dnd/shared`. Stage contracts expose only Notarius structured-
`internal/modules/dnd/shared`, which also owns bounded D&D diagnostics. Stage
contracts expose only Notarius structured-
completion types, not Scriptorium public types.
Reference material may inform a module or prompt but must not become source
@@ -82,14 +83,18 @@ semantic digest; overlay content remains contextual reference material rather
than source evidence. Its external JSON contract is defined in the
[spell-catalog overlay contract](../integrations/dnd-spell-catalog-overlays.md).
### `internal/modules/dnd/npcs/identity` and `internal/modules/dnd/codec/npcs`
### `internal/modules/dnd/npcs/identity`, `internal/modules/dnd/npcs/registry`, and `internal/modules/dnd/codec/npcs`
The NPC identity package owns Unicode comparison keys, deterministic
`npc:sha256:` IDs, display normalization, and whole-registry collision issues.
The NPC codec owns the strict durable `dnd/npc-list` JSON boundary and exposes
candidate versus approved encode/decode operations. NPC source references are
durable provenance and may later be consumed by another pipeline as registry
context without being treated as evidence for that pipeline.
The registry package resolves one optional normalized artifact through the
strict codec, validates whole-registry identity, canonicalizes its JSON, and
provides immutable records, prompt input, semantic digest, count, and exact
canonical-name/alias lookup. It owns the `npcs` slot and its bounded,
content-safe preparation failures. NPC source references are durable
provenance and are not treated as evidence for a consuming pipeline. The NPC
codec owns the strict durable `dnd/npc-list` JSON boundary and exposes
candidate versus approved encode/decode operations.
## Input Adapter
@@ -196,13 +201,13 @@ stages, using the codec only for checkpoint, debug, and output boundaries.
Shared D&D helpers keep prompt input
names and source-unit reference conversion consistent with the scene chunker.
The extractor also declares the optional `npcs` registry slot. Preparation
requires one approved `application/json` item no larger than 1 MiB, validates
identity without relating registry source references to the current transcript,
and supplies canonical JSON to a spell-owned prompt message. A bound registry
adds only `npc_registry_digest` and `npc_count` to manifest metadata and an
`npc_registry` checkpoint fingerprint. The unbound prompt input is exactly
`{"npcs":[]}` and has no registry provenance or fingerprint.
The extractor also declares the optional `npcs` registry slot and consumes the
prepared immutable registry boundary from `internal/modules/dnd/npcs/registry`.
A bound registry adds only `npc_registry_digest` and `npc_count` to manifest
metadata and an `npc_registry` checkpoint fingerprint. The unbound prompt
input is exactly `{"npcs":[]}` and has no registry provenance or fingerprint.
The shared NPC grounding fragment is placed immediately after the common
campaign reference message and is included in the spell prompt fingerprint.
The durable payload and manifest metadata shapes are defined in the
[D&D spell artifact contract](../integrations/dnd-spell-artifacts.md).
@@ -212,7 +217,7 @@ The durable payload and manifest metadata shapes are defined in the
The NPC extractor maps private model output to the canonical `dnd.NPCList`,
assigns source identity and deterministic NPC IDs, and preserves source
references for deterministic validation. It uses the shared campaign
references only for disambiguation and does not consume the spell-owned NPC
references only for disambiguation and does not consume the optional NPC
registry slot. Its prompt and private response schema are package-owned.
### `internal/modules/dnd/normalize/npcs`