529 lines
24 KiB
Markdown
529 lines
24 KiB
Markdown
# D&D NPC Extraction And Registry Implementation Plan
|
|
|
|
Status: Ready for implementation.
|
|
|
|
Implement this plan in order. The feature policy and target state are defined
|
|
in [D&D NPC Extraction And Registry](dnd-npc-extraction.md); this document owns
|
|
implementation sequencing and concrete technical decisions.
|
|
|
|
Do not introduce a DAG, implicit prior-run discovery, an LLM-backed validator,
|
|
or generic semantic deduplication. Preserve the fixed
|
|
`input -> chunk -> extract -> merge -> normalize -> output` architecture and
|
|
the existing framework retry, warning, rejection, checkpoint, debug, and
|
|
output contracts.
|
|
|
|
## Cross-Stage Decisions
|
|
|
|
### Artifact And Module Identities
|
|
|
|
Use these exact production identities:
|
|
|
|
- artifact kind: `dnd/npc-list`;
|
|
- extractor key: `dnd/npcs`;
|
|
- normalizer key: `dnd/npcs`;
|
|
- extractor capability: `dnd.npcs`;
|
|
- prompt ID: `dnd.npcs`, version `v1`;
|
|
- private LLM response-schema key: `dnd_npcs_llm`;
|
|
- private schema ID: `notarius.dnd.npcs.llm`;
|
|
- private schema name: `notarius_dnd_npcs_llm_v1`;
|
|
- durable codec schema ID: `notarius.dnd.npcs`;
|
|
- durable codec schema name: `notarius_dnd_npcs_v1`;
|
|
- durable schema version: `v1`; and
|
|
- durable media type: `application/json`.
|
|
|
|
The private LLM schema omits framework-assigned `id` and `source_id` fields.
|
|
The durable codec schema includes both.
|
|
|
|
### Durable Go And JSON Shape
|
|
|
|
Add the following canonical D&D types in `internal/modules/dnd/types.go`:
|
|
|
|
```go
|
|
type NPCList struct {
|
|
NPCs []NPC `json:"npcs"`
|
|
}
|
|
|
|
type NPC struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Aliases []string `json:"aliases"`
|
|
Description string `json:"description"`
|
|
Relationships []NPCRelationship `json:"relationships"`
|
|
SourceRefs []source.SourceRef `json:"source_refs"`
|
|
}
|
|
|
|
type NPCRelationship struct {
|
|
Target string `json:"target"`
|
|
Relationship string `json:"relationship"`
|
|
}
|
|
```
|
|
|
|
All six NPC fields and both relationship fields are required in durable JSON.
|
|
`npcs`, `aliases`, and `relationships` must be present arrays; the first may be
|
|
empty and the latter two may be empty for an individual record. `source_refs`
|
|
must contain at least one item. Required strings must be non-empty after
|
|
trimming. Unknown JSON fields are rejected.
|
|
|
|
One NPC-level `source_refs` collection collectively supports the canonical
|
|
name, aliases, description, and relationships. Do not add per-alias or
|
|
per-relationship evidence in this version.
|
|
|
|
### Canonical Identity And IDs
|
|
|
|
Create `internal/modules/dnd/npcs/identity` as the sole owner of NPC identity
|
|
comparison and ID derivation. Define comparison keys by applying, in order:
|
|
|
|
1. Unicode NFKC normalization;
|
|
2. replacement of U+2018, U+2019, and U+02BC with ASCII apostrophe;
|
|
3. Unicode whitespace collapsing with `strings.Fields` and one ASCII space;
|
|
4. Unicode case folding with `golang.org/x/text/cases.Fold`.
|
|
|
|
Do not alter display punctuation merely to match a comparison key. Display
|
|
normalization trims and collapses whitespace but otherwise retains the first
|
|
observed spelling.
|
|
|
|
For a non-empty comparison key, derive the ID as:
|
|
|
|
```text
|
|
npc:sha256:<64 lowercase hexadecimal SHA-256 characters>
|
|
```
|
|
|
|
The hash input is the UTF-8 comparison key with no prefix, suffix, separator,
|
|
or salt. An empty identity produces an empty ID and is rejected by shape
|
|
validation. Export a stable identity-policy value
|
|
`dnd.npcs.identity.v1`; components that depend on these rules use it as their
|
|
`identity_policy` checkpoint fingerprint. A future semantic identity change
|
|
must change this policy value.
|
|
|
|
### Deterministic Consolidation
|
|
|
|
Normalizer identity components are built in merged input order. Union two
|
|
records only when:
|
|
|
|
- their canonical-name comparison keys match; or
|
|
- either record's canonical-name key appears in the other record's alias keys.
|
|
|
|
Do not union records merely because their alias sets intersect. This prevents a
|
|
shared title from silently merging otherwise distinct NPCs. After
|
|
consolidation, an alias owned by more than one retained component, or an alias
|
|
matching another retained canonical name, is an identity collision and causes
|
|
normalize-stage validation rejection.
|
|
|
|
The first record in a component supplies the retained canonical display name,
|
|
description, and output position. Add every distinct later canonical display
|
|
name to its aliases, followed by later aliases in encounter order. Union
|
|
relationships by the pair of target and relationship comparison keys, and
|
|
union exact source references. Recompute the retained ID from the retained
|
|
canonical name. Never ask an LLM to choose merged prose.
|
|
|
|
After components are known, rewrite a relationship target to a retained NPC's
|
|
canonical display name when its comparison key matches exactly one retained
|
|
canonical name or alias. Preserve targets that have no NPC match; they may name
|
|
a PC, group, place, or other non-registry entity. An ambiguous target remains
|
|
unchanged and is covered by identity-collision validation when the ambiguity is
|
|
an alias collision.
|
|
|
|
### Validation And Diagnostics
|
|
|
|
All new production validators are deterministic. Use these exact keys and
|
|
reason codes:
|
|
|
|
| Validator key | Rejection/warning reason |
|
|
| --- | --- |
|
|
| `extract/dnd/npcs/shape` | `invalid_npc_shape` |
|
|
| `extract/dnd/npcs/source_refs` | `invalid_npc_source_refs` |
|
|
| `extract/dnd/npcs/source_relatedness` | warning `npc_not_near_source` |
|
|
| `normalize/dnd/npcs/identity` | `invalid_npc_identity` |
|
|
|
|
Shape validation owns required fields and non-empty values. Source-reference
|
|
validation owns document identity, unit existence, and range ordering through
|
|
`source.ValidateRef`. Identity validation owns ID syntax and recomputation,
|
|
duplicate canonical identities, duplicate IDs, duplicate aliases, aliases
|
|
equal to their own canonical name, cross-record alias/canonical collisions, and
|
|
cross-record alias ownership.
|
|
|
|
Relatedness approves the artifact and emits at most one warning per NPC when
|
|
neither its canonical name nor any alias appears in the combined cited source
|
|
text after the same Unicode comparison normalization. Opaque campaign
|
|
references may legitimately explain such a warning; do not treat them as
|
|
source evidence or attempt to parse them deterministically.
|
|
|
|
Bound diagnostics using the established spell-validator policy: display at
|
|
most 20 issues, truncate displayed identity values to 128 Unicode code points
|
|
with an ellipsis, keep encoded rejection messages at or below 4,096 bytes, and
|
|
report the total omitted issue count. Preserve valid UTF-8 and use Go quoting
|
|
for control characters. Warnings must likewise use bounded displayed values.
|
|
|
|
Each new validator implements `CheckpointFingerprintProvider` with one local
|
|
`policy` fingerprint. Use these exact values:
|
|
|
|
- shape: `dnd.npcs.validator.shape.v1`;
|
|
- source references: `dnd.npcs.validator.source_refs.v1`;
|
|
- source relatedness: `dnd.npcs.validator.source_relatedness.v1`; and
|
|
- identity: `dnd.npcs.identity.v1`.
|
|
|
|
Bump only the affected value when validator semantics change.
|
|
|
|
### Testing Rules
|
|
|
|
Follow `docs/policy/testing.md`. Tests must be offline and deterministic. Use a
|
|
fake structured LLM only at the external completion boundary. Protect durable
|
|
artifact contracts, identity and normalization invariants, validation outcomes,
|
|
registration, checkpoint identity, and representative assembled workflows.
|
|
|
|
Do not add tests that require specific words or phrases to remain in prompt
|
|
prose. Prompt-asset tests may verify that assets register, required inputs are
|
|
wired, the selected prompt and schema identities are correct, and raw material
|
|
does not leak into diagnostics. Human review, not exact model-output fixtures,
|
|
owns semantic extraction quality.
|
|
|
|
## Stage 1: NPC Domain Contract, Identity Policy, And Codec
|
|
|
|
### Goal
|
|
|
|
Establish the typed artifact, deterministic identity primitives, and durable
|
|
serialization contract without registering a selectable production module.
|
|
|
|
### Changes
|
|
|
|
- Add `NPCListKind`, `NPCList`, `NPC`, and `NPCRelationship` to the canonical
|
|
D&D model using the exact shape above.
|
|
- Add `internal/modules/dnd/npcs/identity` with defensive, concurrency-safe pure
|
|
functions for display normalization, comparison keys, ID derivation, ID
|
|
syntax checks, and whole-registry identity validation.
|
|
- Identity validation must return structured or otherwise inspectable issues so
|
|
the normalize validator can build bounded aggregate diagnostics. Do not make
|
|
it depend on pipeline validator types.
|
|
- Add `internal/modules/dnd/codec/npcs`, following the spell codec's candidate
|
|
versus approved encode/decode boundary:
|
|
- strict single-value JSON decoding with unknown-field rejection;
|
|
- `EncodeCandidate` and `DecodeCandidate` preserve validator-visible invalid
|
|
values;
|
|
- approved `Encode` and `Decode` enforce structural validity;
|
|
- schema and metadata are defensive copies; and
|
|
- metadata reports `npc_count` only.
|
|
- Add the durable JSON Schema at
|
|
`internal/modules/dnd/codec/npcs/assets/schemas/dnd_npcs.v1.json` with the
|
|
exact required fields, ID pattern, array rules, source-reference shape, and
|
|
`additionalProperties: false` at every object level.
|
|
- Create `docs/integrations/dnd-npc-artifacts.md` as the canonical durable
|
|
contract. At this stage describe the implemented artifact and codec only; do
|
|
not yet claim that production pipelines can select it.
|
|
|
|
### Tests
|
|
|
|
- Test identity equivalence across case, Unicode compatibility forms,
|
|
whitespace, and supported apostrophes; different names must remain distinct.
|
|
- Test the exact ID format, deterministic repeatability, empty-name behavior,
|
|
and registry identity issues for every collision category.
|
|
- Test codec candidate preservation, approved round trips, schema identity and
|
|
defensive copies, nil-versus-empty arrays, malformed/trailing/unknown JSON,
|
|
required strings, relationship shape, ID pattern, and source-reference
|
|
structure.
|
|
- Keep one small intentional durable JSON fixture for round-trip compatibility;
|
|
do not snapshot incidental error text.
|
|
|
|
### Completion Check
|
|
|
|
Run `go test ./internal/modules/dnd/npcs/... ./internal/modules/dnd/codec/npcs` and
|
|
`git diff --check`.
|
|
|
|
## Stage 2: NPC Extractor And Extraction Validators
|
|
|
|
### Goal
|
|
|
|
Add a package-complete LLM-backed NPC extractor and deterministic extraction
|
|
validation, still without composing it into the production D&D registrar.
|
|
|
|
### Changes
|
|
|
|
- Add `internal/modules/dnd/extract/npcs`, mirroring the established spell
|
|
extractor boundaries without sharing spell-specific code.
|
|
- The module spec requires `chunks` and `source.transcript`, provides
|
|
`dnd.npcs`, uses artifact kind `dnd/npc-list`, accepts no options, and declares
|
|
the existing optional `players`, `party`, `glossary`, and deprecated `roster`
|
|
campaign slots with the existing shared media types.
|
|
- Embed and register package-owned prompt assets and a private LLM JSON Schema.
|
|
Reuse the shared D&D system, transcript, and campaign-reference prompt
|
|
fragments through `shared.ModulePromptFS`.
|
|
- The prompt implements the feature-roadmap inclusion and exclusion policy,
|
|
requires canonical in-world names rather than speakers, keeps descriptions
|
|
concise, requires every claim to be supported by transcript citations, and
|
|
treats auxiliary references only as disambiguation.
|
|
- The private response has top-level `npcs`; each item contains `name`,
|
|
`aliases`, `description`, `relationships`, and source ranges without
|
|
`source_id`. Require `aliases` and `relationships` arrays even when empty.
|
|
- Preserve malformed model values for validators. Canonicalize and de-duplicate
|
|
exact source ranges, order response records by earliest valid cited unit, map
|
|
every range to the current source ID, and assign IDs with the identity
|
|
package. Do not merge NPC records in the extractor.
|
|
- Validate constructor dependencies and embedded prompt/schema metadata during
|
|
preparation. Expose manifest-safe prompt and private-schema identities plus
|
|
`identity_policy`; expose `prompt`, `response_schema`, and `identity_policy`
|
|
checkpoint fingerprints.
|
|
- Add typed validators under `internal/modules/dnd/validate/npcs/shape`,
|
|
`source_refs`, and `source_relatedness` using the contracts above. Validators
|
|
defer appropriately after shape failure rather than emitting misleading
|
|
secondary diagnostics.
|
|
- Give each validator a strict empty-options decoder, immutable spec, correct
|
|
execution class, typed builder, policy fingerprint, and nil/dependency error
|
|
behavior consistent with existing production validators.
|
|
|
|
### Tests
|
|
|
|
- Through a fake LLM, test request identity, profile/session propagation,
|
|
chunk-scoped transcript bytes, campaign reference inputs, response mapping,
|
|
deterministic IDs, source-ID assignment, evidence ordering, and preservation
|
|
of invalid candidates for retries.
|
|
- Test cancellation and contextual provider errors without asserting entire
|
|
messages.
|
|
- Test prompt and schema asset registration, input wiring, metadata redaction,
|
|
and checkpoint fingerprints without asserting prompt prose.
|
|
- Test each validator's approval, rejection, warning, malformed-shape deferral,
|
|
strict options, typed registration, diagnostic limits, Unicode truncation,
|
|
and immutability.
|
|
- Test source relatedness using canonical names, aliases, case/whitespace/
|
|
apostrophe variants, invalid ranges, and names resolved only through opaque
|
|
references.
|
|
|
|
### Completion Check
|
|
|
|
Run `go test ./internal/modules/dnd/extract/npcs ./internal/modules/dnd/validate/npcs/...`
|
|
and `git diff --check`.
|
|
|
|
## Stage 3: Deterministic NPC Normalization
|
|
|
|
### Goal
|
|
|
|
Implement conservative cross-chunk identity consolidation and final identity
|
|
validation without changing framework normalization contracts.
|
|
|
|
### Changes
|
|
|
|
- Add `internal/modules/dnd/normalize/npcs` with key `dnd/npcs`, artifact kind
|
|
`dnd/npc-list`, no options, no references, requirements `merged`, and
|
|
capability `normalized`.
|
|
- Deep-clone all nested slices before mutation. A result must never alias the
|
|
merged input or another retained record.
|
|
- Per record, normalize display whitespace, trim description and relationship
|
|
strings, de-duplicate aliases and relationships by comparison keys, remove
|
|
aliases equal to the canonical name, sort and exactly de-duplicate source
|
|
references, and recompute the ID.
|
|
- Build and merge identity components with the exact cross-stage algorithm.
|
|
Preserve component and member encounter order. Add removed canonical names as
|
|
aliases, union provenance, retain only the first description, and
|
|
canonicalize unambiguous relationship targets after all components exist.
|
|
- Use these stable warning reason codes:
|
|
- `npc_fields_normalized`;
|
|
- `npc_id_recomputed`;
|
|
- `source_references_normalized`;
|
|
- `duplicate_npc_collapsed`; and
|
|
- `relationship_target_canonicalized`.
|
|
- Warning scopes use merged input indexes such as `npcs[3]`. A collapsed-group
|
|
warning is scoped to the retained input index and reports bounded removed
|
|
indexes. Accepted-only warning promotion remains framework policy.
|
|
- Expose manifest metadata `identity_policy` and
|
|
`normalization_policy: dnd.npcs.normalize.v1`. Provide those same two local
|
|
checkpoint fingerprints. Bump the normalization value whenever consolidation
|
|
or retained-field semantics change.
|
|
- Add `internal/modules/dnd/validate/npcs/identity`. It delegates identity issue
|
|
detection to the domain identity package, builds bounded diagnostics, and is
|
|
registered only in the normalize default chain during Stage 4.
|
|
|
|
### Tests
|
|
|
|
- Use table-driven domain cases for per-record normalization and alias,
|
|
relationship, source-reference, and ID behavior.
|
|
- Use a compact accepted-output fixture for representative multi-record
|
|
consolidation: exact canonical match, canonical-to-alias match, transitive
|
|
unambiguous match, shared-alias non-merge, first-description retention,
|
|
relationship target rewriting, and stable ordering.
|
|
- Prove ambiguous shared aliases remain separate for identity-validator
|
|
rejection and that invalid evidence is not made valid by normalization.
|
|
- Prove input immutability and independent nested output storage.
|
|
- Test warning scopes/reason codes, normalization and identity fingerprints,
|
|
strict options, registration, cancellation, nil input, and bounded identity
|
|
rejection diagnostics.
|
|
- Do not separately test private union-find or graph helpers when the public
|
|
normalizer cases already protect the behavior.
|
|
|
|
### Completion Check
|
|
|
|
Run `go test ./internal/modules/dnd/normalize/npcs ./internal/modules/dnd/validate/npcs/identity`
|
|
and `git diff --check`.
|
|
|
|
## Stage 4: Production Composition And NPC Pipeline
|
|
|
|
### Goal
|
|
|
|
Make the complete NPC lane selectable and verify the assembled framework path
|
|
before adding it as a reference consumer elsewhere.
|
|
|
|
### Changes
|
|
|
|
- Extend `internal/modules/dnd/register` to register:
|
|
- the NPC codec;
|
|
- NPC extractor and prompt assets;
|
|
- typed `appendorder` merger specialization for `dnd.NPCList`;
|
|
- NPC normalizer and typed `noop` specialization;
|
|
- all four NPC validators;
|
|
- typed always-accept and always-reject validator variants; and
|
|
- default validator-chain mappings.
|
|
- Add a small `appendNPCLists` function that preserves chunk and record order
|
|
and distinguishes nil from present-empty output consistently with the spell
|
|
merger.
|
|
- Register the extract default chain in this order:
|
|
`generic/valid_json`, `generic/valid_json_schema`, NPC shape, NPC source refs,
|
|
NPC source relatedness.
|
|
- Register the normalize default chain in this order:
|
|
`generic/valid_json`, `generic/valid_json_schema`, NPC shape, NPC identity,
|
|
NPC source refs, NPC source relatedness.
|
|
- Do not register an NPC merge default chain and do not change global framework
|
|
defaults.
|
|
- Add a synthetic, non-sensitive Seriatim integration fixture with a PC, a
|
|
repeated named NPC, an alias, an unnamed but distinguishable NPC, and an
|
|
interchangeable group that the fake response omits.
|
|
- Add `examples/dnd-npcs.config.yml` as a complete version-3 configuration. Use
|
|
a generic chunker, an `npcs` artifact lane, `dnd/npcs` extraction with
|
|
`retries: 2`, `dnd/npcs` normalization, explicit checkpoint `enabled: false`,
|
|
and safe relative output/debug paths.
|
|
|
|
### Tests
|
|
|
|
- Extend family registration tests for keys, artifact variants, default chain
|
|
order, prompt/schema assets, nil registry failures, and duplicate
|
|
registration errors. Test the public catalog outcome, not private registrar
|
|
call order.
|
|
- Add config-resolution coverage for the assembled NPC lane, capabilities,
|
|
typed codec/merger/normalizer compatibility, strict options, references, and
|
|
invalid validator placement.
|
|
- Add one runner integration test using a fake LLM that exercises
|
|
Seriatim -> chunks -> NPC extract -> validators -> append merge -> NPC
|
|
normalize -> validators -> JSON output. Assert normalized identities,
|
|
provenance, warnings, manifest metadata, and durable lane schema.
|
|
- Add one representative retry/rejection case at the assembled boundary only
|
|
if existing generic runner tests do not already protect the same mechanism;
|
|
do not duplicate the framework retry matrix.
|
|
- Verify the maintained example through the existing config/example contract
|
|
tests.
|
|
|
|
### Completion Check
|
|
|
|
Run `go test ./internal/modules/dnd/register ./internal/modules/integration ./internal/core/config`
|
|
and `git diff --check`.
|
|
|
|
## Stage 5: NPC Registry Reference For Spell Extraction
|
|
|
|
### Goal
|
|
|
|
Complete the operator-driven sequential workflow by making normalized NPC JSON
|
|
an explicit, validated spell-extractor reference.
|
|
|
|
### Changes
|
|
|
|
- Add an optional `npcs` reference slot to the spell extractor only. Accept
|
|
exactly one `application/json` item with a maximum size of 1,048,576 bytes.
|
|
Do not add it to the shared scene or NPC-extractor campaign slots.
|
|
- During spell-extractor preparation, when `npcs` is bound:
|
|
- require exactly one item;
|
|
- decode it with the approved NPC codec;
|
|
- validate its IDs and alias ownership through the NPC identity package;
|
|
- re-encode canonical durable JSON for the prompt; and
|
|
- compute a semantic SHA-256 digest over those canonical bytes.
|
|
- Permit source references inside the registry to identify another session;
|
|
they are registry provenance, not spell evidence. Do not validate them
|
|
against the current transcript.
|
|
- When the slot is unbound, supply the prompt with exactly `{"npcs":[]}` as the
|
|
empty structured value. Do not create reference manifest provenance or an
|
|
`npc_registry` fingerprint for the absent slot.
|
|
- Declare an optional `application/json` `npcs` prompt input and render it in a
|
|
spell-owned prompt message. Do not modify the shared D&D reference fragment,
|
|
because the scene and NPC prompts do not consume this registry.
|
|
- Instruct the spell model to prefer exact canonical NPC names, recognize
|
|
aliases, and never treat registry content as proof that a spell was cast or
|
|
as source evidence. Preserve the existing party/player policy for PCs.
|
|
- When bound, add manifest metadata `npc_registry_digest` and `npc_count`, and
|
|
add local checkpoint fingerprint `npc_registry` with the semantic digest.
|
|
Never expose names, aliases, reference content, paths, or raw bytes in
|
|
metadata or fingerprints. Existing raw reference provenance continues to
|
|
participate independently in checkpoint identity.
|
|
- Add `examples/dnd-npc-spell-sequential.config.yml` with separate `dnd-npcs`
|
|
and `dnd-spells` pipeline definitions over the same Seriatim input shape. The
|
|
NPC output remains intentionally unbound in the static spell definition
|
|
because its run directory is dynamic; demonstrate the explicit runtime
|
|
binding in documentation.
|
|
- Update current-behavior documentation in canonical locations:
|
|
- `docs/config.md`: module and validator catalogs, NPC reference slot, limits,
|
|
default chains, and maintained examples;
|
|
- `docs/cli.md`: one explicit selector example using
|
|
`spells.extract.npcs=<npc-run>/lanes/npcs.json`;
|
|
- `docs/operations.md`: the two-invocation sequential workflow and state
|
|
sensitivity;
|
|
- `docs/integrations/dnd-npc-artifacts.md`: production identity, final
|
|
normalization, warnings, manifest metadata, and reference-consumer
|
|
semantics;
|
|
- `docs/integrations/dnd-spell-artifacts.md`: optional NPC grounding and its
|
|
non-evidence rule;
|
|
- `docs/integrations/json-output.md`: link the NPC lane payload contract;
|
|
- `docs/internal/overview.md`, `docs/internal/modules.md`, and
|
|
`docs/internal/llm.md`: implemented package inventory and internal prompt,
|
|
preparation, fingerprint, and registration behavior.
|
|
- At feature completion, mark the feature roadmap and this implementation plan
|
|
complete. Remove the now-implemented NPC item from `future.md`; keep combat
|
|
turns as the next future sequential artifact. Do not leave future behavior in
|
|
current-behavior documentation.
|
|
|
|
### Tests
|
|
|
|
- Test spell preparation with an absent registry, a valid normalized registry,
|
|
malformed JSON, unknown fields, invalid IDs, alias collisions, multiple
|
|
items, wrong media type, and the configured byte limit. Materialization-limit
|
|
failures must occur before pipeline execution and checkpoint construction.
|
|
- Through the fake spell client, assert canonical NPC JSON input, input
|
|
metadata, manifest-safe count/digest, and absence of content leakage. Do not
|
|
assert prompt wording.
|
|
- Test that identical semantic registries produce the same component
|
|
fingerprint, semantic changes change it, and returned fingerprints cannot be
|
|
mutated through caller-owned slices. Do not repeat generic checkpoint ordering
|
|
tests already owned by the framework.
|
|
- Add one sequential integration case: run the assembled NPC pipeline with a
|
|
fake NPC response, serialize its normalized lane payload, materialize that
|
|
payload as the spell extractor's `npcs` reference, and run the spell pipeline
|
|
with a fake spell response. Verify reference provenance, prompt input, typed
|
|
output, and that no NPC source reference becomes spell evidence.
|
|
- Validate all new documentation links and maintained example configurations.
|
|
|
|
### Completion Check
|
|
|
|
Run the final verification suite below.
|
|
|
|
## Final Verification
|
|
|
|
Run:
|
|
|
|
```sh
|
|
git diff --check
|
|
go test ./...
|
|
go vet ./...
|
|
go build ./cmd/notarius
|
|
go test -race ./internal/modules/dnd/... ./internal/framework/pipeline \
|
|
./internal/cli ./internal/modules/integration
|
|
```
|
|
|
|
Review the final diff for:
|
|
|
|
- accidental framework or provider-specific D&D behavior;
|
|
- mutation of caller-owned artifacts, schemas, references, metadata, or
|
|
fingerprints;
|
|
- prompt/schema/content leakage into manifests, errors, checkpoint identity,
|
|
or redacted summaries;
|
|
- current documentation claiming behavior before its implementing stage exists;
|
|
- redundant tests or prompt-prose change detectors; and
|
|
- unrelated changes in the worktree.
|
|
|
|
## Open Questions
|
|
|
|
None. The artifact shape, identity algorithm, merge policy, validator placement,
|
|
reference parsing, checkpoint semantics, and documentation ownership are fixed
|
|
by this plan.
|