Document D&D extractor contract

This commit is contained in:
2026-07-24 14:46:19 +00:00
parent 1aa30a73db
commit a1b76093ce
4 changed files with 48 additions and 8 deletions

View File

@@ -64,12 +64,13 @@ lanes. The canonical ordering and cache-boundary policy is documented in
contracts expose only Notarius structured-completion types, not Scriptorium
public types.
The shared `ChunkPromptMaterial` helper owns common transcript material
preparation for the spell, NPC, combat-turn, and NPC-interaction extractors. It clones supplied
source metadata, falls back to the materialized chunk when content is absent,
checks that content remains chunk-identical, and fills only the common default
fields. Extractors retain their request validation and wrap helper errors with
their module context.
The shared `PrepareChunkExtraction` helper owns common extraction preflight and
transcript material preparation for the spell, NPC, combat-turn,
NPC-interaction, and scene-description extractors. It validates common request
state, clones supplied source metadata, falls back to the materialized chunk
when content is absent, checks that content remains chunk-identical, and fills
only the common default fields. Extractors retain receiver, dependency, and
lane-specific checks locally and wrap helper errors with their module context.
Reference material may inform a module or prompt but must not become source
evidence. The resolver and materializer behavior is described in
@@ -575,6 +576,37 @@ When adding a production module or validator:
Do not add the extension to `docs/development.md`; that file routes by task and
does not inventory implementations.
### D&D Extractor Contract
New D&D extractors preserve these package-owned responsibilities:
- Reject unknown options unless an option namespace is intentionally
extensible, and use shared common preflight while retaining receiver,
dependency, and lane-specific checks locally.
- Return independently owned results and exposed metadata that callers may
safely mutate.
- Keep the private response DTO, structural response schema and its identity,
provider-response mapping, durable artifact conversion, and lane diagnostics
in the owning package.
- Include every stable semantic input that can change durable output in
checkpoint identity. Consider prompt, schema, mapping, canonicalization,
prepared reference projections, identity, normalization, and trimming where
applicable.
- Add focused behavioral coverage where the lane's risks warrant it, including
construction and registration, option rejection, preflight, provider
failures, structured decoding, mapping and ownership, prompt
role/input/cache order, and checkpoint invalidation.
Prompt ordering, shared-asset ownership, cache boundaries, and private-schema
rules are defined in [LLM Runtime](llm.md#dd-extraction-prompt-ordering-and-cache-boundaries).
[Pipeline Internals](pipeline.md#reference-materialization) owns reference
materialization, and its [checkpoint hooks](pipeline.md#checkpoint-and-debug-hooks)
define checkpoint behavior. Follow [Architecture](../policy/architecture.md#source-and-domain-boundaries)
for ownership boundaries and the [Testing Policy](../policy/testing.md) when
selecting durable coverage. This contract intentionally does not prescribe
prompt prose or length, hashes, test counts, filenames, fixture layouts, or
generic implementation builders.
## Tests To Inspect
- Package-local `*_test.go` files under the module or validator being changed.

View File

@@ -14,7 +14,6 @@ import (
const (
Key = "dnd/combat-turns"
ArtifactType = "dnd.combat_turn"
mappingPolicy = "dnd.combat_turns.extract_mapping.v2"
)

View File

@@ -14,7 +14,6 @@ import (
)
const Key = "dnd/spells"
const ArtifactType = "dnd.spell_cast"
const SchemaVersion = "v1"
const mappingPolicy = "dnd.spells.extract_mapping.v2"
@@ -122,6 +121,9 @@ func (e *Extractor) ReferenceSlots() []contracts.ReferenceSlot {
}
func (e *Extractor) ManifestMetadata() map[string]any {
if e == nil {
return nil
}
metadata := map[string]any{
"prompt_id": PromptID,
"prompt_version": SchemaVersion,

View File

@@ -174,6 +174,13 @@ func TestExtractorManifestMetadataIncludesLLMSchemaProvenance(t *testing.T) {
}
}
func TestNilExtractorManifestMetadata(t *testing.T) {
var extractor *Extractor
if metadata := extractor.ManifestMetadata(); metadata != nil {
t.Fatalf("nil extractor metadata = %#v, want nil", metadata)
}
}
func TestExtractPassesReferencesAsPromptInputs(t *testing.T) {
client := &fakeSpellsLLMClient{response: extractionResponse{SpellCasts: []spellCastResponse{}}}
req := extractionRequest()