198 lines
8.9 KiB
Markdown
198 lines
8.9 KiB
Markdown
# D&D NPC Interactions
|
|
|
|
Status: Accepted
|
|
|
|
## Purpose
|
|
|
|
The normalized NPC registry intentionally answers only who was identified in a
|
|
session. It does not answer whether an NPC was merely mentioned, participated
|
|
in dialogue, or fought alongside or against the party. Add a separate,
|
|
ordered NPC-interaction artifact for that occurrence-level information rather
|
|
than expanding the identity registry.
|
|
|
|
This feature preserves the minimal-extractor policy: the model identifies one
|
|
bounded kind of interaction and its supporting transcript evidence. It does
|
|
not summarize the interaction, infer relationships, or maintain NPC state.
|
|
|
|
## Desired End State
|
|
|
|
A D&D pipeline can run NPC extraction first and supply its accepted normalized
|
|
registry to a later `dnd/npc-interactions` lane. The later lane emits an ordered
|
|
list of evidenced interaction occurrences involving registry NPCs.
|
|
|
|
The production identities should be:
|
|
|
|
- extractor and normalizer key: `dnd/npc-interactions`;
|
|
- artifact kind: `dnd/npc-interaction-list`;
|
|
- durable schema ID: `notarius.dnd.npc_interactions`;
|
|
- durable schema name: `notarius_dnd_npc_interactions_v1`;
|
|
- durable schema version: `v1`; and
|
|
- media type: `application/json`.
|
|
|
|
The lane must use the existing D&D module organization, shared prompt assets,
|
|
typed artifact pipeline, codec boundary, registration pattern, and default
|
|
validator composition.
|
|
|
|
## Artifact Contract
|
|
|
|
The durable payload is an object containing an `interactions` array. The array
|
|
may be empty. Each interaction contains exactly:
|
|
|
|
- `name`: the canonical NPC name from the supplied registry;
|
|
- `kind`: one value from the bounded interaction vocabulary; and
|
|
- `source_refs`: one or more current-transcript ranges supporting both the NPC
|
|
identity and the classified interaction.
|
|
|
|
Every object rejects unknown fields. The model-facing response should contain
|
|
only the corresponding name, kind, and source-unit range candidates. Notarius
|
|
attaches the current source identity deterministically; the model must not
|
|
reproduce it.
|
|
|
|
Do not add a separate interaction ID in the durable contract. Stable ordering,
|
|
the canonical NPC name, the bounded kind, and exact evidence ranges are enough
|
|
to identify and audit an occurrence for the present use cases. Revisit durable
|
|
cross-artifact identity only with a concrete consumer requirement.
|
|
|
|
## Interaction Vocabulary
|
|
|
|
Use this closed vocabulary:
|
|
|
|
| Kind | Meaning |
|
|
| --- | --- |
|
|
| `mentioned` | The NPC is referred to, but is not established as present or communicating in the evidenced passage. |
|
|
| `noncombat_presence` | The NPC is present and relevant to the passage but does not meaningfully participate in dialogue or combat. |
|
|
| `dialogue` | The NPC speaks, responds, or is directly engaged in a meaningful non-combat exchange. |
|
|
| `combat_ally` | The NPC actively participates in combat on the party's side. |
|
|
| `combat_opponent` | The NPC actively participates in combat against the party. |
|
|
| `other` | The transcript clearly establishes a direct NPC occurrence that fits none of the preceding kinds. |
|
|
|
|
`other` is a residual category for positively evidenced activity, not an
|
|
escape hatch for uncertain classification. Omit a candidate when the
|
|
transcript does not support one category.
|
|
|
|
When activities overlap within one occurrence, apply this precedence:
|
|
|
|
1. active combat participation outranks dialogue, presence, and mention;
|
|
2. dialogue outranks non-combat presence and mention;
|
|
3. non-combat presence outranks mention; and
|
|
4. `other` applies only when none of the defined categories describes the
|
|
evidenced activity.
|
|
|
|
Combat alignment is not resolved by precedence. An NPC cannot be both a combat
|
|
ally and combat opponent in one occurrence; split the record when its alignment
|
|
meaningfully changes.
|
|
|
|
## Occurrence Boundaries And Ordering
|
|
|
|
An occurrence represents one NPC, one interaction kind, and one locally
|
|
coherent transcript passage. Combine repeated evidence only while it supports
|
|
the same uninterrupted activity. Create separate occurrences when:
|
|
|
|
- the interaction kind changes;
|
|
- combat alignment changes;
|
|
- a scene or meaningful absence separates repeated activity; or
|
|
- the NPC is first mentioned and later becomes present.
|
|
|
|
Extraction remains chunk-scoped, so an occurrence must not span accepted chunk
|
|
boundaries. Merge and normalization must not semantically combine occurrences
|
|
from different chunks.
|
|
|
|
Order the durable list by the earliest valid source position. Use canonical
|
|
name, interaction kind, and canonical source ranges as deterministic
|
|
tie-breakers. Remove only exact duplicate records; do not use model judgment to
|
|
collapse nearby occurrences.
|
|
|
|
## NPC Grounding And Evidence
|
|
|
|
The extractor declares the existing `npcs` reference slot and requires a bound,
|
|
accepted NPC registry. The normal same-run configuration binds the normalized
|
|
output of an earlier NPC lane through an ordered generated reference. Existing
|
|
framework support for a compatible external registry may remain available, but
|
|
must not weaken the artifact contract.
|
|
|
|
Present the registry's names-only projection to the model. An emitted name must
|
|
match one canonical registry name exactly after the registry's established
|
|
lookup rules are applied, and the durable artifact retains that canonical
|
|
display name. Do not copy NPC IDs or registry source references into an
|
|
interaction.
|
|
|
|
The registry establishes available identity, not occurrence. Every interaction
|
|
must cite current transcript ranges that independently support both the NPC and
|
|
the selected kind. Campaign references and generated artifacts may disambiguate
|
|
a name, but they never become interaction evidence.
|
|
|
|
If no registry NPC has an evidenced interaction, the correct artifact is an
|
|
empty list. A missing, rejected, or incompatible required registry handoff is a
|
|
pipeline dependency failure rather than a request to extract ungrounded names.
|
|
|
|
## Prompt And Model Boundary
|
|
|
|
Follow the established D&D prompt ordering and cache-boundary policy. Stable
|
|
shared instructions, lane instructions, campaign references, and the NPC
|
|
names-only projection precede the variable transcript. Factor wording shared
|
|
with the spell and combat lanes into the existing shared asset pattern rather
|
|
than creating nearly identical package-local messages.
|
|
|
|
The prompt must:
|
|
|
|
- define the closed vocabulary and precedence rules;
|
|
- ask for occurrences involving only supplied registry NPCs;
|
|
- distinguish mention from presence and dialogue;
|
|
- require current-transcript evidence for identity and kind;
|
|
- forbid summaries, relationship inference, sentiment, aliases, and invented
|
|
names; and
|
|
- permit an empty result.
|
|
|
|
Keep the private JSON Schema structural. Deterministic code owns canonical-name
|
|
resolution, enum enforcement at the durable boundary, source-range validation,
|
|
ordering, exact deduplication, and evidence invariants.
|
|
|
|
## Validation And Quality
|
|
|
|
Provide production validators and default chains at extraction and
|
|
normalization boundaries consistent with the existing D&D artifacts. The
|
|
append-only merge does not require a separate default validator chain.
|
|
Deterministic validation must reject:
|
|
|
|
- missing or extra fields;
|
|
- empty or unrecognized NPC names;
|
|
- names absent from the supplied registry;
|
|
- unknown interaction kinds;
|
|
- empty, malformed, out-of-source, or reversed evidence ranges; and
|
|
- records whose evidence comes from a reference rather than the current
|
|
transcript.
|
|
|
|
Any relatedness validator should remain warning-only unless evaluation
|
|
demonstrates a reliable deterministic rejection rule. Diagnostics must be
|
|
bounded and must not leak reference contents.
|
|
|
|
Evaluate the lane on a small human-reviewed transcript set that includes every
|
|
category, transitions between categories, multiple occurrences for one NPC,
|
|
mentions followed by appearances, alignment changes, repeated evidence across
|
|
chunks, and empty output. Review category agreement, evidence sufficiency,
|
|
ordering, duplicate behavior, and reliability on the smaller models the
|
|
application is intended to support. Treat model-output evaluation as a human
|
|
development aid, not a brittle deterministic test oracle.
|
|
|
|
## Documentation Outcomes
|
|
|
|
When implemented, document the durable artifact in `docs/integrations/`, add
|
|
the selectable module and validator contracts to configuration documentation,
|
|
update the current module and pipeline internals, and provide a maintained
|
|
ordered-pipeline example showing NPC extraction followed by interaction
|
|
extraction. Future behavior must remain in this roadmap until it exists.
|
|
|
|
## Non-Goals
|
|
|
|
This scope does not:
|
|
|
|
- add occurrence fields to the normalized NPC registry;
|
|
- summarize dialogue, combat, or NPC behavior;
|
|
- infer disposition, relationships, factions, motives, or persistent state;
|
|
- identify player characters or anonymous groups as NPCs;
|
|
- add scene participants or duplicate scene-description responsibilities;
|
|
- reconcile NPC aliases or perform LLM-assisted semantic deduplication;
|
|
- derive interaction records from registry evidence; or
|
|
- introduce a DAG, concurrent cross-lane reconciliation, or a new reference
|
|
mechanism.
|