Put stable D&D prompt content before transcripts

This commit is contained in:
2026-07-21 18:59:59 +00:00
parent ed36f7d7fd
commit 41b52aae74
5 changed files with 77 additions and 44 deletions

View File

@@ -102,19 +102,52 @@ The D&D scene chunker and spell, NPC, and combat-turn extractors each declare an
ordered prompt asset manifest. The manifest lists the package-owned YAML and
Markdown files, then the exact shared fragments rendered by that prompt; the
same ordered list drives both filesystem mounting and the prompt fingerprint.
The three extraction prompts share system, extraction evidence, in-world
identity, transcript, and campaign-reference messages. Spell and combat prompts
then render immediate resolution and the ephemeral NPC registry before their
lane-specific material; the NPC prompt renders its task and instructions
instead. The scene prompt uses system, transcript, and campaign-reference
messages before its task and instructions. Identity, transcript, and
campaign-reference messages are ephemeral in the extraction prompts; the scene
prompt marks transcript and campaign references ephemeral, and the NPC registry
is ephemeral where spell and combat prompts use it. Unused shared assets are
neither mounted nor fingerprinted. Universal extraction-evidence and output
policy lives only in the shared extraction assets; package-owned prompt files
retain artifact-specific rules. The scene prompt keeps its separate output rule
because it does not render the extraction-evidence asset.
Unused shared assets are neither mounted nor fingerprinted. Universal
extraction-evidence and output policy lives only in the shared extraction
assets; package-owned prompt files retain artifact-specific rules. The scene
prompt keeps its separate output rule because it does not render the
extraction-evidence asset.
### D&D Extraction Prompt Ordering And Cache Boundaries
D&D extraction prompts order messages from the most reusable content to the
most variable content. New extraction lanes use these tiers in order:
1. universal shared content, including the system, extraction-evidence, and
in-world identity messages;
2. stable campaign or run context shared across lanes, including campaign
references;
3. stable subset- and lane-specific context and instructions, including an NPC
registry, catalog, task, or extraction instructions when applicable;
4. the chunk transcript as the final user message.
This ordering lets requests reuse the longest identical prefix before the
per-chunk transcript changes. Cache reuse requires the preceding message
sequence and content to be exactly identical; semantic similarity is not
sufficient. Cache boundaries belong at the ends of reusable stable tiers,
subject to the provider's cache-boundary limit. The shared identity and
campaign-reference messages form the first two extraction boundaries. Spell
and combat prompts add a boundary at the shared NPC registry. Each extraction
prompt places its final boundary on its lane-specific instructions, immediately
before the transcript. The transcript does not carry cache control because no
reusable content follows it.
Accordingly, the common prefix of all three extraction prompts is system,
extraction evidence, identity, and campaign references. The NPC prompt then
renders task, instructions, and transcript. Spell renders immediate resolution,
NPC registry, catalog, task, instructions, and transcript. Combat renders
immediate resolution, NPC registry, task, instructions, and transcript. The
scene chunker is not an extraction lane: it retains its separate system,
transcript, campaign-reference, task, and instruction order and marks its
transcript and campaign-reference messages ephemeral.
Shared wording belongs in the canonical assets under
`internal/modules/dnd/shared`; extraction packages reference those assets in
their manifests instead of copying similar text into package-local files.
Package-local assets contain only lane-specific content. An extraction lane may
depart from the tier order only when prompt-quality evidence or a provider
constraint makes the exception necessary; document the exception and rationale
here when it becomes implemented behavior.
Schema helpers load embedded JSON Schema with identity and digest metadata,
return defensive copies, and expose a diagnostics map that omits schema bytes.

View File

@@ -51,15 +51,12 @@ declarations, prompt-input assembly, and source-unit/citation helpers belong in
D&D scene chunker and spell, NPC, and combat-turn extractors use ordered
package-local prompt manifests for both rendering and prompt fingerprinting, so
only the shared fragments each prompt actually renders participate in either
operation. The three extraction prompts share the order system, extraction
evidence, in-world identity, transcript, and campaign references, with
ephemeral cache control on identity, transcript, and references. Spell and
combat prompts append immediate resolution and an ephemeral NPC registry before
lane-specific material; the NPC prompt appends its task and instructions. The
scene prompt uses system, transcript, and campaign references before its
lane-specific task and instructions, with ephemeral cache control on transcript
and references. Stage contracts expose only Notarius structured-completion
types, not Scriptorium public types.
operation. Extraction prompts place stable shared and lane-specific context
before the variable transcript and use shared assets for wording common across
lanes. The canonical ordering and cache-boundary policy is documented in
[LLM Runtime](llm.md#dd-extraction-prompt-ordering-and-cache-boundaries). Stage
contracts expose only Notarius structured-completion types, not Scriptorium
public types.
The shared `ChunkPromptMaterial` helper owns common transcript material
preparation for the spell, NPC, and combat-turn extractors. It clones supplied
@@ -240,15 +237,14 @@ 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 optional NPC
registry slot. Its prompt and private response schema are package-owned. The
prompt uses the common evidence, identity, transcript, and campaign-reference
messages, then the NPC-specific task and instructions; only the identity,
transcript, and campaign-reference messages carry ephemeral cache control.
prompt follows the shared D&D extraction ordering and cache policy documented
in [LLM Runtime](llm.md#dd-extraction-prompt-ordering-and-cache-boundaries).
### `internal/modules/dnd/extract/combatturns`
The combat extractor prepares one structured request per supplied chunk using
the shared extraction-evidence, identity, transcript, campaign-reference,
immediate-resolution, and NPC-grounding prompt inputs. It
the shared extraction-evidence, identity, campaign-reference,
immediate-resolution, NPC-grounding, and transcript prompt inputs. It
maps the private response to `dnd.CombatTurnList`, assigns the current source
identity, removes exact duplicate source ranges, and orders turns by valid
source-document position while preserving malformed candidate fields for
@@ -256,11 +252,11 @@ deterministic validators. Its package-owned private response schema enforces
only the structural JSON envelope; semantic artifact constraints remain with
the validator chain. Its prepared metadata and checkpoint fingerprints contain
only prompt/schema/mapping identities plus an optional NPC registry digest.
The prompt renders immediate resolution and the NPC registry before the
combat-specific task and instructions; identity, transcript, campaign
references, and the NPC registry use ephemeral cache control. The package
exposes typed registration and is included in the production D&D registrar with
the default combat extraction chain.
The prompt follows the shared D&D extraction ordering and cache policy
documented in
[LLM Runtime](llm.md#dd-extraction-prompt-ordering-and-cache-boundaries). The
package exposes typed registration and is included in the production D&D
registrar with the default combat extraction chain.
The combat normalizer accepts only the optional structured NPC registry.
Campaign references remain extractor-only LLM context and are not materialized
@@ -448,6 +444,10 @@ When adding a production module or validator:
2. expose and test its spec, constructor, and registration function;
3. keep format or domain parsing inside the concrete package;
4. add package-owned prompt/schema assets when the extension is LLM-backed;
new LLM-backed D&D extraction modules must follow the stable-to-variable
prompt ordering, shared-asset ownership, and cache-boundary policy in
[LLM Runtime](llm.md#dd-extraction-prompt-ordering-and-cache-boundaries), or
document the implemented exception and its evidence there;
5. register it through its package-family registrar and add a default chain
there only when production policy requires one;
6. add resolution and composition coverage for capabilities, options,

View File

@@ -26,10 +26,6 @@ messages:
content_file: ./sharedassets/common-dnd-identity.md
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-references.md
cache_control:
@@ -44,6 +40,10 @@ messages:
content_file: ./task.md
- role: user
content_file: ./instructions.md
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
output:
format: json
validation_mode: json_schema

View File

@@ -23,10 +23,6 @@ messages:
content_file: ./sharedassets/common-dnd-identity.md
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-references.md
cache_control:
@@ -35,6 +31,10 @@ messages:
content_file: ./task.md
- role: user
content_file: ./instructions.md
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
output:
format: json
validation_mode: json_schema

View File

@@ -29,10 +29,6 @@ messages:
content_file: ./sharedassets/common-dnd-identity.md
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-references.md
cache_control:
@@ -49,6 +45,10 @@ messages:
content_file: ./task.md
- role: user
content_file: ./instructions.md
cache_control:
type: ephemeral
- role: user
content_file: ./sharedassets/common-dnd-transcript.md
output:
format: json
validation_mode: json_schema