865 lines
44 KiB
Markdown
865 lines
44 KiB
Markdown
# Canonical D&D Entity Registries And Occurrences Implementation Plan
|
|
|
|
## Objective
|
|
|
|
Implement the target state defined in
|
|
[Canonical D&D Entity Registries And Occurrences](entity-registries.md). NPCs,
|
|
locations, and items will each have one canonical registry lane and one
|
|
registry-backed occurrence lane, with consistent module, artifact, schema,
|
|
prompt, reference, validation, package, asset, example, and documentation
|
|
vocabulary.
|
|
|
|
This is a breaking pre-release migration. The completed implementation must not
|
|
retain compatibility aliases for old module keys, artifact kinds, types,
|
|
schemas, prompts, validators, reference slots, or asset paths. The stages below
|
|
deliberately change durable contracts before moving the corresponding module
|
|
namespace so that each prompt remains bounded for gpt-5.6-terra and the
|
|
repository can compile and pass focused tests after every stage.
|
|
|
|
Complete the stages in numerical order. Each stage is sized for one
|
|
implementation prompt. Do not combine stages unless a later review explicitly
|
|
revises this plan.
|
|
|
|
## Final Contract Matrix
|
|
|
|
Use these exact final identities. Do not invent variants during implementation.
|
|
|
|
| Entity role | Module key | Go artifact type | Artifact kind | Durable schema ID | Durable root |
|
|
| --- | --- | --- | --- | --- | --- |
|
|
| NPC registry | `dnd/npc-registry` | `dnd.NPCRegistry` | `dnd/npc-registry` | `notarius.dnd.npc_registry` | `npcs` |
|
|
| NPC occurrences | `dnd/npc-occurrences` | `dnd.NPCOccurrenceList` | `dnd/npc-occurrence-list` | `notarius.dnd.npc_occurrences` | `occurrences` |
|
|
| Location registry | `dnd/location-registry` | `dnd.LocationRegistry` | `dnd/location-registry` | `notarius.dnd.location_registry` | `locations` |
|
|
| Location occurrences | `dnd/location-occurrences` | `dnd.LocationOccurrenceList` | `dnd/location-occurrence-list` | `notarius.dnd.location_occurrences` | `occurrences` |
|
|
| Item registry | `dnd/item-registry` | `dnd.ItemRegistry` | `dnd/item-registry` | `notarius.dnd.item_registry` | `items` |
|
|
| Item occurrences | `dnd/item-occurrences` | `dnd.ItemOccurrenceList` | `dnd/item-occurrence-list` | `notarius.dnd.item_occurrences` | `occurrences` |
|
|
|
|
All durable contracts use schema version `v1` and media type
|
|
`application/json`. Registry records have required `id`, `name`, and
|
|
`source_refs`. NPC, location, and item occurrences have required `npc_id`,
|
|
`location_id`, or `item_id` respectively, plus required `name`, `kind`, and
|
|
`source_refs`. Item occurrence `quantity`, `from`, and `to` remain semantically
|
|
conditional durable fields.
|
|
|
|
Use these exact identity policies and digest inputs:
|
|
|
|
- NPC: `dnd.npc_registry.identity.v1`, SHA-256 of compact JSON
|
|
`[policy, comparison_name]`, prefix `npc:sha256:`;
|
|
- location: `dnd.location_registry.identity.v1`, SHA-256 of compact JSON
|
|
`[policy, comparison_name, source_id, start_unit_id, end_unit_id]` using the
|
|
earliest canonical evidence anchor, prefix `location:sha256:`; and
|
|
- item: `dnd.item_registry.identity.v1`, SHA-256 of compact JSON
|
|
`[policy, comparison_name]`, prefix `item:sha256:`.
|
|
|
|
Registry reference slots and corresponding PromptKit inputs are exactly
|
|
`npc_registry`, `location_registry`, and `item_registry`. Enemy-event grounding
|
|
uses `npc_occurrences` for the renamed NPC occurrence artifact.
|
|
|
|
## Rules For Every Stage
|
|
|
|
- Read and follow `docs/policy/architecture.md`,
|
|
`docs/policy/documentation.md`, and `docs/policy/testing.md` before editing.
|
|
- Preserve the fixed pipeline architecture, typed artifact zone, ordered-step
|
|
barrier, generated-reference provenance, whole-run failure behavior,
|
|
scheduler, checkpoint, and output boundaries. This feature requires no new
|
|
framework workflow primitive and no new ADR.
|
|
- Keep `assets/assets.go` as the root assets package's only Go file. It remains
|
|
a read-only content boundary with no business logic, PromptKit dependency,
|
|
registry behavior, or module registration.
|
|
- Keep D&D semantics inside `internal/modules/dnd` and `assets/dnd`. Do not
|
|
implement the future generic LLM-assisted deduplicator in this work set.
|
|
- Do not create compatibility type aliases, duplicate module registrations,
|
|
legacy schema decoders, fallback reference-slot names, copied prompt assets,
|
|
or deprecated-key shims. Intermediate stages may retain a current module key
|
|
until its explicit namespace-migration stage, but must not register both old
|
|
and new keys.
|
|
- Preserve minimal evidence-grounded contracts. Registry references are
|
|
source-free grounding and never occurrence evidence. Every occurrence must
|
|
cite current-transcript ranges independently.
|
|
- Private structured-response schemas must reject unknown fields and include
|
|
every declared property in `required`. Use nullable private fields for
|
|
semantically absent item values and map them deterministically to omitted
|
|
durable fields.
|
|
- Preserve prompt-cache construction: extraction prompts share the byte-identical
|
|
system/identity/reference/chunk prefix; evidence and registry projections
|
|
follow that prefix; module instructions remain final. Registry normalizers
|
|
retain system, instructions, shared reconciliation policy, candidates, and
|
|
transcript-window order.
|
|
- Update current-behavior documentation when a stage changes an implemented
|
|
contract. Do not describe a not-yet-registered item module outside
|
|
`docs/roadmap/` before its production-registration stage.
|
|
- Keep default tests offline, deterministic, and credential-free. Use package
|
|
behavior tests for codecs, identity, registry resolution, normalization, and
|
|
validators; integration tests for generated handoffs; and CLI tests for
|
|
assembled examples. Do not add live-LLM tests, exact prompt snapshots, private
|
|
asset inventories, or duplicate change-detector tests.
|
|
- Preserve unrelated user changes. Use `gofmt`, `git diff --check`, and focused
|
|
tests in every stage. Do not retire this roadmap or the feature roadmap as
|
|
part of implementation.
|
|
|
|
## Stage 1: Migrate The NPC Registry Durable Contract And Identity
|
|
|
|
### Goal
|
|
|
|
Adopt the final NPC registry type, artifact kind, schema identity, and identity
|
|
algorithm while the selectable module temporarily remains `dnd/npcs`.
|
|
|
|
### Required changes
|
|
|
|
1. In `internal/modules/dnd/types.go`, replace `NPCListKind` and `NPCList` with
|
|
`NPCRegistryKind` and `NPCRegistry`. Retain `NPC` with required `ID`, `Name`,
|
|
and `SourceRefs`, and retain the durable root field `npcs`.
|
|
2. Update every typed consumer, merger, evidence projection, validator,
|
|
normalizer, extractor, test fixture, integration helper, and registry
|
|
registration to use `dnd.NPCRegistry` and `dnd.NPCRegistryKind`. Do not leave
|
|
a Go alias for the retired names.
|
|
3. In the existing NPC codec package, replace the durable schema with
|
|
`dnd_npc_registry.v1.json`, schema ID `notarius.dnd.npc_registry`, schema name
|
|
`notarius_dnd_npc_registry_v1`, and version `v1`. Keep the strict `npcs`
|
|
envelope and `application/json` media type.
|
|
4. Change the NPC identity policy to `dnd.npc_registry.identity.v1`. Derive IDs
|
|
from compact JSON `[policy, comparison_name]`, not the current bare comparison
|
|
string. Preserve Unicode NFKC, apostrophe normalization, whitespace collapse,
|
|
case folding, empty-input rejection, lowercase SHA-256, and the existing ID
|
|
prefix.
|
|
5. Update registry validation and tests to prove the documented bytes, policy
|
|
namespace, deterministic IDs, uniqueness, concurrency safety, malformed-ID
|
|
rejection, and non-mutation. Update dependent fixtures to use newly derived
|
|
IDs rather than copied old digests.
|
|
6. Update the current `docs/integrations/dnd-npc-artifacts.md` in place so its
|
|
artifact kind, schema identity, Go-independent ID algorithm, and wire example
|
|
match this stage. It must continue to name `dnd/npcs` as the current producer
|
|
until Stage 2.
|
|
|
|
### Acceptance criteria
|
|
|
|
- No production Go code refers to `NPCList` or `NPCListKind`.
|
|
- The registered codec round-trips the strict `NPCRegistry` `v1` contract and
|
|
reports the target kind and schema identity.
|
|
- All current NPC-grounded consumers compile against `NPCRegistry` without
|
|
changing their reference-slot names yet.
|
|
- There is no compatibility alias or decoder for `dnd/npc-list` or
|
|
`notarius.dnd.npcs`.
|
|
|
|
### Validation
|
|
|
|
Run `gofmt` on every Go file changed in this stage, then run:
|
|
|
|
```sh
|
|
go test ./internal/modules/dnd/... ./internal/modules/integration/...
|
|
git diff --check
|
|
```
|
|
|
|
## Stage 2: Move The NPC Registry Module Into Its Canonical Namespace
|
|
|
|
### Goal
|
|
|
|
Rename the NPC registry's selectable modules, packages, prompts, assets,
|
|
validators, capabilities, and reference slots without changing the durable
|
|
record shape completed in Stage 1.
|
|
|
|
### Required changes
|
|
|
|
1. Move the stage packages to Go-compatible canonical paths:
|
|
`codec/npcregistry`, `extract/npcregistry`, `normalize/npcregistry`, and
|
|
`validate/npcregistry/...`. Domain helpers under `internal/modules/dnd/npcs`
|
|
may remain because they own NPC identity rather than a selectable module.
|
|
2. Set extract and normalize module keys to `dnd/npc-registry`. Rename all NPC
|
|
validator keys from `.../dnd/npcs/...` to `.../dnd/npc-registry/...`, and
|
|
rename the provided capability to `dnd.npc_registry`.
|
|
3. Move `assets/dnd/npcs/{extract,normalize}` to
|
|
`assets/dnd/npc-registry/{extract,normalize}`. Use prompt IDs
|
|
`dnd.npc_registry` and `dnd.npc_registry.normalize`; use private schema ID
|
|
`notarius.dnd.npc_registry.llm`, schema name
|
|
`notarius_dnd_npc_registry_llm_v1`, and filename
|
|
`dnd_npc_registry_llm.v1.json`.
|
|
4. Rename `common-dnd-npcs.md` to `common-dnd-npc-registry.md`. Change the
|
|
rendered PromptKit input and every module-facing reference slot from `npcs`
|
|
to `npc_registry` in spells, combat turns, the still-current NPC-interaction
|
|
modules, and enemy events. Preserve requiredness: optional for spell and
|
|
combat grounding, required where the current consumer already requires an
|
|
NPC registry.
|
|
5. Update immutable NPC registry projections to render ordered `{id, name}`
|
|
pairs where identity is required and the narrowest source-free name
|
|
projection where a consumer intentionally needs names only. Do not expose
|
|
registry source references to prompts.
|
|
6. Update central module, codec, merger, evidence, validator, default-chain,
|
|
prompt, and profile registration. Update the cross-lane prompt composition
|
|
test for the new prompt ID and `npc_registry` input without duplicating its
|
|
ordering assertions in module-local tests.
|
|
7. Rename the integration contract to
|
|
`docs/integrations/dnd-npc-registry-artifacts.md`, update inbound links, and
|
|
update the implemented module catalog, configuration reference, current
|
|
internal D&D guide, and maintained examples for the new key and slot.
|
|
8. Remove the old package trees, asset tree, prompt IDs, module/validator keys,
|
|
capability, shared filename, and reference-slot name. The durable JSON field
|
|
`npcs`, the record type `NPC`, and domain helper package name `npcs` are not
|
|
legacy module identifiers and should remain.
|
|
|
|
### Acceptance criteria
|
|
|
|
- `dnd/npc-registry` is the only selectable NPC registry extract/normalize key.
|
|
- All NPC-registry consumers expose `npc_registry` and accept only
|
|
`dnd/npc-registry` artifacts.
|
|
- Prompt and schema assets load only from `assets/dnd/npc-registry` and retain
|
|
the documented cache order.
|
|
- Current docs and examples contain no claim that `dnd/npcs` is selectable.
|
|
|
|
### Validation
|
|
|
|
```sh
|
|
go test ./internal/modules/dnd/... ./internal/modules/integration/... ./internal/cli/...
|
|
go run ./cmd/notarius config validate --config examples/dnd-minimal.config.yml --pipeline dnd-session
|
|
git diff --check
|
|
```
|
|
|
|
## Stage 3: Redesign The NPC Occurrence Durable Contract
|
|
|
|
### Goal
|
|
|
|
Replace the NPC-interaction value contract with the final registry-ID-backed
|
|
NPC occurrence contract while the selectable module temporarily remains
|
|
`dnd/npc-interactions`.
|
|
|
|
### Required changes
|
|
|
|
1. Replace `NPCInteractionListKind`, `NPCInteractionList`,
|
|
`NPCInteractionKind`, and `NPCInteraction` with `NPCOccurrenceListKind`,
|
|
`NPCOccurrenceList`, `NPCOccurrenceKind`, and `NPCOccurrence`. The envelope
|
|
field is `occurrences`; each record has required `npc_id`, `name`, `kind`,
|
|
and `source_refs`.
|
|
2. Retain the six existing category values and their precedence and splitting
|
|
semantics. Change only the contract vocabulary and registry identity link;
|
|
do not add relationship, sentiment, biography, or persistent-state fields.
|
|
3. In the current codec package, adopt `dnd/npc-occurrence-list`, durable schema
|
|
ID `notarius.dnd.npc_occurrences`, schema name
|
|
`notarius_dnd_npc_occurrences_v1`, and strict file
|
|
`dnd_npc_occurrences.v1.json`.
|
|
4. Change the current NPC-interaction private response contract to require
|
|
`npc_id` as well as `name`, `kind`, and `source_refs`. Use private schema ID
|
|
`notarius.dnd.npc_occurrences.llm`, schema name
|
|
`notarius_dnd_npc_occurrences_llm_v1`, and a renamed schema file even though
|
|
the prompt ID moves in Stage 4.
|
|
5. Project ordered `{id, name}` NPC registry entries into extraction. Require
|
|
the model to return an exact supplied pair. Extraction, normalization, and
|
|
registry validators must reject unknown IDs and mismatched ID/name pairs
|
|
rather than repairing by name similarity.
|
|
6. Update deterministic ordering, exact-duplicate identity, clone/evidence
|
|
helpers, merge functions, normalizers, validators, and diagnostics to include
|
|
`npc_id`. Preserve source chronology and distinct kinds/evidence.
|
|
7. Update enemy-event grounding to consume `NPCOccurrenceList`, filtering
|
|
`combat_opponent` occurrences while carrying only source-free grounding
|
|
values. Do not add NPC IDs to the enemy-event durable contract.
|
|
8. Update `docs/integrations/dnd-npc-interaction-artifacts.md` in place to the
|
|
new durable schema, root, and fields while accurately retaining the current
|
|
producer key until Stage 4.
|
|
|
|
### Acceptance criteria
|
|
|
|
- No production Go code refers to an `NPCInteraction*` artifact type.
|
|
- The durable artifact uses `occurrences` and validates exact NPC ID/name pairs.
|
|
- Unknown IDs and mismatches are detected independently at extraction,
|
|
normalization, and validation boundaries without mutation.
|
|
- Enemy-event grounding behavior remains source-free and category-filtered.
|
|
|
|
### Validation
|
|
|
|
```sh
|
|
go test ./internal/modules/dnd/codec/npcinteractions ./internal/modules/dnd/extract/npcinteractions ./internal/modules/dnd/normalize/npcinteractions ./internal/modules/dnd/validate/npcinteractions/... ./internal/modules/dnd/extract/enemyevents ./internal/modules/dnd/normalize/enemyevents
|
|
go test ./internal/modules/dnd/... ./internal/modules/integration/...
|
|
git diff --check
|
|
```
|
|
|
|
## Stage 4: Move NPC Occurrences Into Their Canonical Namespace
|
|
|
|
### Goal
|
|
|
|
Complete the NPC migration by replacing interaction module/package vocabulary
|
|
and updating the enemy-event dependency.
|
|
|
|
### Required changes
|
|
|
|
1. Move the codec, extract, normalize, validate, and D&D helper packages from
|
|
`npcinteractions` to `npcoccurrences` where they own the occurrence artifact.
|
|
2. Set extract and normalize keys to `dnd/npc-occurrences`; rename validator
|
|
keys and the provided capability to the `npc-occurrences`/
|
|
`dnd.npc_occurrences` vocabulary.
|
|
3. Move `assets/dnd/npc-interactions` to `assets/dnd/npc-occurrences`. Change the
|
|
extraction prompt ID to `dnd.npc_occurrences`, update instructions from
|
|
“interactions” to “occurrences” without changing category semantics, and
|
|
keep the target private schema identity established in Stage 3.
|
|
4. Rename the generated reference and PromptKit grounding input consumed by
|
|
enemy events from `npc_interactions` to `npc_occurrences`. Update combat
|
|
grounding assets, reference specs, fingerprint metadata, checkpoint inputs,
|
|
and tests consistently.
|
|
5. Update central registration, default validator chains, artifact evidence and
|
|
merge registration, prompt-cache tests, configuration keys, examples, and
|
|
current documentation.
|
|
6. Rename the integration contract to
|
|
`docs/integrations/dnd-npc-occurrence-artifacts.md` and update every link from
|
|
NPC registry, enemy event, combat, internal D&D, configuration, and JSON
|
|
output documentation.
|
|
7. Delete every old package, key, schema, prompt, capability, asset, and current-
|
|
behavior reference for `dnd/npc-interactions` and `npc_interactions`. Do not
|
|
retain a module alias.
|
|
|
|
### Acceptance criteria
|
|
|
|
- `dnd/npc-occurrences` is the only selectable NPC occurrence key.
|
|
- Enemy events require `npc_occurrences` of kind
|
|
`dnd/npc-occurrence-list`.
|
|
- Current catalogs, examples, and documentation use occurrence vocabulary.
|
|
- No production package or asset directory named `npcinteractions` or
|
|
`npc-interactions` remains.
|
|
|
|
### Validation
|
|
|
|
```sh
|
|
go test ./internal/modules/dnd/... ./internal/modules/integration/... ./internal/cli/...
|
|
OPENROUTER_API_KEY=validation-placeholder go run ./cmd/notarius config validate --config examples/dnd-complete.config.yml --pipeline dnd-session
|
|
git diff --check
|
|
```
|
|
|
|
## Stage 5: Migrate The Location Registry Durable Contract And Identity
|
|
|
|
### Goal
|
|
|
|
Adopt the final location registry type, artifact kind, schema identity, and
|
|
identity-policy namespace while the selectable module remains `dnd/locations`.
|
|
|
|
### Required changes
|
|
|
|
1. Replace `LocationListKind` and `LocationList` with `LocationRegistryKind` and
|
|
`LocationRegistry`. Retain `Location` and the durable `locations` root.
|
|
2. Update all typed location-registry consumers, especially location-occurrence
|
|
extraction, normalization, validation, reference resolution, merge, evidence,
|
|
registration, and tests. Do not leave aliases.
|
|
3. In the current location codec package, use kind `dnd/location-registry`,
|
|
schema ID `notarius.dnd.location_registry`, schema name
|
|
`notarius_dnd_location_registry_v1`, and strict file
|
|
`dnd_location_registry.v1.json`.
|
|
4. Change the identity policy to `dnd.location_registry.identity.v1` and retain
|
|
the exact compact JSON input `[policy, comparison_name, source_id,
|
|
start_unit_id, end_unit_id]`. Continue to select the earliest canonical
|
|
evidence anchor without mutating caller data. Accept the resulting pre-release
|
|
ID invalidation.
|
|
5. Update identity, registry, codec, same-name-location, normalization, and
|
|
dependent occurrence fixtures. Tests must prove same-name distinct anchors,
|
|
deterministic ordering, invalid component rejection, and exact documented
|
|
bytes.
|
|
6. Update `docs/integrations/dnd-location-artifacts.md` in place for the target
|
|
kind, schema, and identity policy while retaining `dnd/locations` as the
|
|
current module key until Stage 6.
|
|
|
|
### Acceptance criteria
|
|
|
|
- No production Go code refers to `LocationList` or `LocationListKind`.
|
|
- Same-name locations with distinct evidence anchors remain distinguishable.
|
|
- The codec and generated-reference compatibility use
|
|
`dnd/location-registry`.
|
|
- No old kind, schema identity, or identity-policy compatibility path remains.
|
|
|
|
### Validation
|
|
|
|
```sh
|
|
go test ./internal/modules/dnd/locations/... ./internal/modules/dnd/codec/locations ./internal/modules/dnd/extract/locations ./internal/modules/dnd/normalize/locations ./internal/modules/dnd/extract/locationoccurrences ./internal/modules/dnd/normalize/locationoccurrences ./internal/modules/dnd/validate/locations/... ./internal/modules/dnd/validate/locationoccurrences/...
|
|
go test ./internal/modules/dnd/... ./internal/modules/integration/...
|
|
git diff --check
|
|
```
|
|
|
|
## Stage 6: Move And Tighten The Location Registry Module
|
|
|
|
### Goal
|
|
|
|
Move location registry code and assets into the canonical namespace and enforce
|
|
the roadmap's named-or-uniquely-designated eligibility policy.
|
|
|
|
### Required changes
|
|
|
|
1. Move the stage packages to `codec/locationregistry`,
|
|
`extract/locationregistry`, `normalize/locationregistry`, and
|
|
`validate/locationregistry/...`. Entity identity and immutable registry
|
|
helpers may remain under `internal/modules/dnd/locations`.
|
|
2. Set extract and normalize keys to `dnd/location-registry`; rename validator
|
|
keys and the provided capability to `dnd.location_registry`.
|
|
3. Move `assets/dnd/locations/{extract,normalize}` to
|
|
`assets/dnd/location-registry/{extract,normalize}`. Use prompt IDs
|
|
`dnd.location_registry` and `dnd.location_registry.normalize`; use private
|
|
schema ID `notarius.dnd.location_registry.llm`, schema name
|
|
`notarius_dnd_location_registry_llm_v1`, and filename
|
|
`dnd_location_registry_llm.v1.json`.
|
|
4. Change the location-registry extraction instructions to accept only a stable
|
|
proper name or unique in-world designation. Explicitly exclude generic,
|
|
temporary, relative, and descriptive phrases such as `the room`, `the bar`,
|
|
`the hallway`, `outside`, and `upstairs`. Do not use capitalization as the
|
|
eligibility test and do not add a brittle deterministic word blacklist.
|
|
5. Rename the required location-occurrence reference slot and PromptKit input
|
|
from `locations` to `location_registry`. Preserve the ordered source-free
|
|
`{id, name}` projection and exact ID/name validation at extraction and
|
|
normalization.
|
|
6. Update location-occurrence instructions so a generic current-chunk phrase
|
|
may resolve to an existing named registry location only when context supports
|
|
that coreference; it may not create a registry entity or substitute registry
|
|
provenance for evidence.
|
|
7. Update central registration, prompt composition, validator chains,
|
|
configuration, examples, and current docs. Rename the integration contract
|
|
to `docs/integrations/dnd-location-registry-artifacts.md` and update links.
|
|
8. Remove old module/package/asset/prompt/validator/capability identities and
|
|
old reference-slot names. The durable `locations` field and domain helper
|
|
package remain valid.
|
|
|
|
### Acceptance criteria
|
|
|
|
- `dnd/location-registry` is the only selectable location registry key.
|
|
- Registry prompts exclude generic locations, while occurrence prompts permit
|
|
supported coreference to an existing registry entity.
|
|
- Location occurrences require `location_registry` of kind
|
|
`dnd/location-registry` at extract and normalize stages.
|
|
- No production compatibility alias for `dnd/locations` remains.
|
|
|
|
### Validation
|
|
|
|
```sh
|
|
go test ./internal/modules/dnd/... ./internal/modules/integration/... ./internal/cli/...
|
|
OPENROUTER_API_KEY=validation-placeholder go run ./cmd/notarius config validate --config examples/dnd-complete.config.yml --pipeline dnd-session
|
|
git diff --check
|
|
```
|
|
|
|
## Stage 7: Add The Item Registry Domain Foundation
|
|
|
|
### Goal
|
|
|
|
Implement the item registry's typed durable contract, deterministic identity,
|
|
codec, and immutable reference projection without registering a selectable
|
|
pipeline module yet.
|
|
|
|
### Required changes
|
|
|
|
1. Add `ItemRegistryKind`, `ItemRegistry`, and `Item` to the D&D domain types.
|
|
The strict envelope is `{"items":[...]}`; each item has required `id`,
|
|
`name`, and `source_refs`.
|
|
2. Add an item identity package under `internal/modules/dnd/items/identity`.
|
|
Implement comparison normalization consistent with the NPC identity text
|
|
family, policy `dnd.item_registry.identity.v1`, compact JSON
|
|
`[policy, comparison_name]`, prefix `item:sha256:`, syntax checks, registry
|
|
uniqueness validation, and deterministic errors.
|
|
3. Add immutable item registry resolution under
|
|
`internal/modules/dnd/items/registry`. It must decode through the canonical
|
|
codec, validate IDs, preserve same-name/type policy, return defensive copies,
|
|
and produce an ordered source-free `{id, name}` projection suitable for a
|
|
later reference slot.
|
|
4. Add `internal/modules/dnd/codec/itemregistry` with strict durable schema
|
|
`dnd_item_registry.v1.json`, ID `notarius.dnd.item_registry`, name
|
|
`notarius_dnd_item_registry_v1`, version `v1`, and media type
|
|
`application/json`.
|
|
5. Test codec round trips, strict unknown-field rejection, candidate encoding,
|
|
metadata, identity bytes, empty/malformed identities, duplicate IDs,
|
|
defensive copies, projection order, and non-mutation.
|
|
6. Do not register the codec or describe the item registry as selectable in
|
|
current configuration or integration docs yet. The feature roadmap remains
|
|
the canonical description until Stage 9.
|
|
|
|
### Acceptance criteria
|
|
|
|
- The new type, identity, codec, and registry packages pass independently.
|
|
- Item IDs are name/type identities rather than per-instance identities.
|
|
- The projection exposes IDs and names but no source references.
|
|
- No generic framework package depends on D&D item types.
|
|
|
|
### Validation
|
|
|
|
Run `gofmt` on every Go file changed in this stage, then run:
|
|
|
|
```sh
|
|
go test ./internal/modules/dnd/items/... ./internal/modules/dnd/codec/itemregistry
|
|
go test ./internal/modules/dnd/...
|
|
git diff --check
|
|
```
|
|
|
|
## Stage 8: Implement Item Registry Extraction And Validation
|
|
|
|
### Goal
|
|
|
|
Add the item-registry extraction module, private response contract, prompt
|
|
assets, canonical mapping, and extraction validators without production
|
|
registration.
|
|
|
|
### Required changes
|
|
|
|
1. Add `internal/modules/dnd/extract/itemregistry` with key
|
|
`dnd/item-registry`, artifact kind `dnd/item-registry`, LLM-backed execution,
|
|
the ordinary campaign reference slots, and prompt ID `dnd.item_registry`.
|
|
2. Add `assets/dnd/item-registry/extract` containing `prompt.yaml`, one coherent
|
|
`instructions.md`, and strict private schema `dnd_item_registry_llm.v1.json`
|
|
with ID `notarius.dnd.item_registry.llm` and name
|
|
`notarius_dnd_item_registry_llm_v1`. The private response contains required
|
|
item `name` and `source_refs`; deterministic code supplies source identity
|
|
and derives the durable item ID.
|
|
3. Encode the roadmap eligibility policy precisely: accept named unique items,
|
|
concrete reusable item types, stable unique designations, and separate
|
|
currency denominations; reject vague `loot`, `treasure`, `some gear`,
|
|
generic weapons, inferred properties, quantities, and uniqueness.
|
|
4. Reuse the shared extraction prompt prefix and evidence policy. Keep the item
|
|
registry instructions final and ephemeral. Do not add item occurrence,
|
|
holder, inventory, or ledger rules to this prompt.
|
|
5. Canonicalize display whitespace and evidence, derive IDs through the item
|
|
identity package, preserve candidate evidence for validation, and order
|
|
candidates deterministically. Do not semantically collapse aliases in the
|
|
extractor.
|
|
6. Add `validate/itemregistry/shape`, `source_refs`, and
|
|
`source_relatedness` packages and keys using the final module vocabulary.
|
|
Keep relatedness advisory according to existing D&D conventions.
|
|
7. Add focused behavior, schema, prompt preparation, metadata-redaction,
|
|
cancellation/error, and validator tests. Do not call a live model and do not
|
|
snapshot full prompt text.
|
|
8. Do not add the module to the production D&D registrar until its normalizer
|
|
and complete default chains exist in Stage 9.
|
|
|
|
### Acceptance criteria
|
|
|
|
- Direct module construction prepares and maps a strict item-registry response.
|
|
- Currency denominations and reusable item types are eligible; vague categories
|
|
are excluded by prompt policy without a capitalization heuristic.
|
|
- Extracted records contain deterministic IDs and owned evidence slices.
|
|
- No current module catalog advertises an incomplete lane.
|
|
|
|
### Validation
|
|
|
|
```sh
|
|
go test ./internal/modules/dnd/extract/itemregistry ./internal/modules/dnd/validate/itemregistry/...
|
|
go test ./internal/modules/dnd/...
|
|
git diff --check
|
|
```
|
|
|
|
## Stage 9: Implement Item Registry Normalization And Production Registration
|
|
|
|
### Goal
|
|
|
|
Complete and register the item registry as the third production registry
|
|
family.
|
|
|
|
### Required changes
|
|
|
|
1. Add `internal/modules/dnd/normalize/itemregistry` with key
|
|
`dnd/item-registry`, LLM-backed execution, prompt ID
|
|
`dnd.item_registry.normalize`, and the same retry/fallback contract used by
|
|
NPC and location registry normalization.
|
|
2. Deterministically preprocess candidate names, evidence, IDs, and exact
|
|
duplicates. Then use the existing shared D&D entity-reconciliation proposal
|
|
mechanics with item-specific candidates and selected transcript windows.
|
|
Validated groups may choose one supplied canonical display name and union
|
|
evidence; unsafe, overlapping, unknown, or uncertain groups preserve the
|
|
deterministic result with bounded diagnostics.
|
|
3. Add `assets/dnd/item-registry/normalize` with `prompt.yaml`,
|
|
`instructions.md`, and `candidates.md`. Item instructions own only same-item-
|
|
kind/designation judgment and canonical display preference. The shared
|
|
reconciliation fragment alone owns opaque keys and safe group mechanics.
|
|
4. Explicitly prevent reconciliation across currency denominations, materially
|
|
different item types, or merely nearby objects. Do not create per-instance
|
|
identities or infer properties.
|
|
5. Add `validate/itemregistry/identity` and its default normalize-chain position.
|
|
Test retry, invalid structured output, operational error, warning bounds,
|
|
idempotence, order, non-mutation, and content-safe diagnostics.
|
|
6. Register the item registry codec, evidence projection, append-order merger,
|
|
extractor, normalizer, validators, default chains, prompt assets, and module
|
|
metadata in the D&D registrar. Add it to the centralized extraction prompt
|
|
composition test.
|
|
7. Create the current durable contract at
|
|
`docs/integrations/dnd-item-registry-artifacts.md`. Update configuration and
|
|
internal module catalogs enough to describe the now-selectable registry,
|
|
but defer the complete multi-step example until item occurrences consume it.
|
|
|
|
### Acceptance criteria
|
|
|
|
- `dnd/item-registry` is selectable for extraction and normalization with
|
|
complete production validator chains.
|
|
- The normalizer uses proposal-only LLM semantics and deterministic application.
|
|
- Codec, merge, evidence, prompt, metadata, and registry registrations are all
|
|
type-compatible.
|
|
- The current docs accurately describe the implemented item registry without
|
|
claiming that item occurrences consume it yet.
|
|
|
|
### Validation
|
|
|
|
```sh
|
|
go test ./internal/modules/dnd/items/... ./internal/modules/dnd/codec/itemregistry ./internal/modules/dnd/extract/itemregistry ./internal/modules/dnd/normalize/itemregistry ./internal/modules/dnd/validate/itemregistry/... ./internal/modules/dnd/register
|
|
go test ./internal/modules/dnd/... ./internal/cli/...
|
|
git diff --check
|
|
```
|
|
|
|
## Stage 10: Redesign Item Events As Registry-Backed Item Occurrences
|
|
|
|
### Goal
|
|
|
|
Adopt the final item occurrence durable contract and required item-registry
|
|
grounding while the selectable module temporarily remains `dnd/item-events`.
|
|
|
|
### Required changes
|
|
|
|
1. Replace `ItemEventListKind`, `ItemEventList`, `ItemEventKind`, and `ItemEvent`
|
|
with `ItemOccurrenceListKind`, `ItemOccurrenceList`, `ItemOccurrenceKind`,
|
|
and `ItemOccurrence`. Use durable root `occurrences`; each record has required
|
|
`item_id`, `name`, `kind`, and `source_refs`, plus conditional `quantity`,
|
|
`from`, and `to`.
|
|
2. Preserve the five existing kinds and all holder, quantity, currency,
|
|
ordering, and exact-duplicate semantics. Rename the D&D helper behavior to
|
|
occurrence vocabulary in code, but defer physical package moves to Stage 11.
|
|
3. In the current codec package, adopt kind `dnd/item-occurrence-list`, schema
|
|
ID `notarius.dnd.item_occurrences`, schema name
|
|
`notarius_dnd_item_occurrences_v1`, and strict file
|
|
`dnd_item_occurrences.v1.json`.
|
|
4. Change the private response schema to
|
|
`notarius.dnd.item_occurrences.llm`/
|
|
`notarius_dnd_item_occurrences_llm_v1` in
|
|
`dnd_item_occurrences_llm.v1.json`. Require every property. Represent absent
|
|
`quantity`, `from`, and `to` as nullable private fields and map them to the
|
|
durable conditional fields without fabricating values.
|
|
5. Add required `item_registry` reference slots to both extraction and
|
|
normalization, accepting only `dnd/item-registry`, `application/json`, and an
|
|
explicit size bound. Resolve one immutable registry per operation and render
|
|
ordered source-free `{id, name}` entries after the shared evidence message.
|
|
6. Require the model to return an exact registry ID/name pair. Extraction must
|
|
reject or omit unknown/mismatched pairs without creating an item. The
|
|
deterministic normalizer must canonicalize recognized names by ID and retain
|
|
unknown values for the registry validator to reject according to the current
|
|
validation architecture.
|
|
7. Add a registry membership validator to the item occurrence extract and
|
|
normalize chains. Update shape, invariant, source-reference, relatedness,
|
|
merge, evidence, clone, metadata, warning, and ordering behavior for
|
|
`item_id` and the new envelope.
|
|
8. Update the maintained complete example immediately: produce
|
|
`dnd/item-registry` in the earlier registry step and bind its generated
|
|
artifact as `item_registry` to the still-current `dnd/item-events` extract
|
|
and normalize stages. Keep the example valid at the end of this stage.
|
|
9. Update `docs/integrations/dnd-item-event-artifacts.md` in place to the target
|
|
durable shape and required registry behavior while retaining the current
|
|
producer key until Stage 11.
|
|
|
|
### Acceptance criteria
|
|
|
|
- No production Go code uses an `ItemEvent*` artifact type.
|
|
- Every item occurrence carries an exact item-registry ID/name pair.
|
|
- Extraction and normalization both declare the identical required registry
|
|
slot; validation detects unknown and mismatched identities.
|
|
- The complete example resolves with an earlier item registry and no same-step
|
|
dependency.
|
|
|
|
### Validation
|
|
|
|
```sh
|
|
go test ./internal/modules/dnd/itemevents ./internal/modules/dnd/codec/itemevents ./internal/modules/dnd/extract/itemevents ./internal/modules/dnd/normalize/itemevents ./internal/modules/dnd/validate/itemevents/... ./internal/modules/dnd/register ./internal/modules/integration/...
|
|
OPENROUTER_API_KEY=validation-placeholder go run ./cmd/notarius config validate --config examples/dnd-complete.config.yml --pipeline dnd-session
|
|
git diff --check
|
|
```
|
|
|
|
## Stage 11: Move Item Occurrences Into Their Canonical Namespace
|
|
|
|
### Goal
|
|
|
|
Complete the item migration by replacing item-event module, package, prompt,
|
|
validator, asset, and documentation vocabulary.
|
|
|
|
### Required changes
|
|
|
|
1. Move `internal/modules/dnd/itemevents` to `itemoccurrences` and move codec,
|
|
extract, normalize, and validate packages to the corresponding
|
|
`itemoccurrences` paths.
|
|
2. Set extract and normalize keys to `dnd/item-occurrences`; rename validator
|
|
keys and the provided capability to `dnd.item_occurrences`.
|
|
3. Move `assets/dnd/item-events` to `assets/dnd/item-occurrences`. Use prompt ID
|
|
`dnd.item_occurrences`, the target private schema identity from Stage 10, and
|
|
occurrence terminology throughout module instructions.
|
|
4. Update all imports, central registrations, default chains, metadata,
|
|
fingerprints, prompt composition cases, configuration keys, example lanes,
|
|
generated references, output expectations, and tests.
|
|
5. Rename the integration contract to
|
|
`docs/integrations/dnd-item-occurrence-artifacts.md` and update links from
|
|
item registry, configuration, internal D&D, and JSON output documentation.
|
|
6. Delete every old `itemevents`, `item-events`, `dnd/item-events`,
|
|
`dnd.item_events`, `notarius.dnd.item_events`, `events`-envelope fixture, and
|
|
old schema/asset path that represented the retired artifact. Do not remove
|
|
unrelated uses of the ordinary word “event” in other D&D lanes.
|
|
|
|
### Acceptance criteria
|
|
|
|
- `dnd/item-occurrences` is the only selectable item occurrence key.
|
|
- All item occurrence packages, prompts, validators, schemas, and docs use the
|
|
canonical vocabulary.
|
|
- The complete example binds `item_registry` into both stages of the renamed
|
|
lane.
|
|
- No compatibility alias for item events remains.
|
|
|
|
### Validation
|
|
|
|
```sh
|
|
go test ./internal/modules/dnd/... ./internal/modules/integration/... ./internal/cli/...
|
|
OPENROUTER_API_KEY=validation-placeholder go run ./cmd/notarius config validate --config examples/dnd-complete.config.yml --pipeline dnd-session
|
|
git diff --check
|
|
```
|
|
|
|
## Stage 12: Verify The Complete Ordered Entity Pipeline
|
|
|
|
### Goal
|
|
|
|
Make the maintained complete configuration and representative integration tests
|
|
prove the final three-registry/three-occurrence architecture.
|
|
|
|
### Required changes
|
|
|
|
1. Finalize `examples/dnd-complete.config.yml` with an earlier registry step
|
|
containing `npc-registry`, `location-registry`, and `item-registry` lanes
|
|
alongside scene descriptions. The next step contains NPC, location, and item
|
|
occurrences plus spell and combat lanes. The derived enemy step consumes
|
|
`npc_registry`, `npc_occurrences`, combat turns, and scene descriptions.
|
|
2. Use generated-reference aliases `npc_registry`, `location_registry`,
|
|
`item_registry`, and `npc_occurrences`. Preserve explicit step-and-lane
|
|
selectors and stage-local spell-catalog bindings. Do not infer dependencies
|
|
from matching names.
|
|
3. Update scene-plan eligibility configuration for all renamed lane labels while
|
|
preserving the shared chunk plan and exact combat-scene routing semantics.
|
|
4. Add or revise one representative integration workflow that executes the
|
|
ordered handoffs with deterministic fake LLM responses and proves exact
|
|
artifact-kind compatibility, registry projection, independent occurrence
|
|
evidence, and final publication for all three entity families.
|
|
5. Test compatible external path references for each registry through existing
|
|
reference preparation. Do not duplicate the framework's exhaustive topology
|
|
and failure-propagation cases; add only D&D-specific compatibility coverage.
|
|
6. Test rejection of a wrong registry artifact kind and invalid same-step or
|
|
forward binding at the existing resolver/integration boundary if those risks
|
|
are not already credibly covered with the new kinds.
|
|
7. Update CLI maintained-example contract tests and production catalog tests so
|
|
both D&D examples load, validate, resolve, and list only implemented module
|
|
and validator identities.
|
|
|
|
### Acceptance criteria
|
|
|
|
- The complete example validates offline and resolves all generated handoffs.
|
|
- A representative assembled run proves all three registry-to-occurrence paths.
|
|
- External compatible registry artifacts remain supported.
|
|
- Cross-family integration tests protect compatibility without repeating
|
|
package-level identity and validator cases.
|
|
|
|
### Validation
|
|
|
|
```sh
|
|
go test ./internal/modules/integration/... ./internal/cli/... ./internal/modules/dnd/register
|
|
go run ./cmd/notarius config validate --config examples/dnd-minimal.config.yml --pipeline dnd-session
|
|
OPENROUTER_API_KEY=validation-placeholder go run ./cmd/notarius config validate --config examples/dnd-complete.config.yml --pipeline dnd-session
|
|
git diff --check
|
|
```
|
|
|
|
## Stage 13: Consolidate Current Documentation And Examples
|
|
|
|
### Goal
|
|
|
|
Bring every canonical current-behavior document into alignment with the final
|
|
implemented entity family without duplicating contracts across documents.
|
|
|
|
### Required changes
|
|
|
|
1. Update `docs/config.md` as the canonical owner of selectable module keys,
|
|
validator keys, default chains, reference slots, requiredness, size limits,
|
|
execution classes, profile behavior, and ordered binding examples.
|
|
2. Update `docs/internal/dnd.md` for ten final D&D artifact lanes, the three
|
|
registry normalizers, source-free ID/name projections, occurrence grounding,
|
|
package/asset ownership, and lane-specific differences. Link to integration
|
|
contracts instead of repeating their schemas or categories.
|
|
3. Update `docs/internal/modules.md`, `docs/internal/overview.md`, README, CLI,
|
|
operations, JSON output, and other current documents only where they actually
|
|
name affected modules, artifacts, examples, or links. Preserve each
|
|
document's canonical scope under the documentation policy.
|
|
4. Ensure the six target integration contracts are the only canonical durable
|
|
entity contracts:
|
|
`dnd-npc-registry-artifacts.md`, `dnd-npc-occurrence-artifacts.md`,
|
|
`dnd-location-registry-artifacts.md`,
|
|
`dnd-location-occurrence-artifacts.md`,
|
|
`dnd-item-registry-artifacts.md`, and
|
|
`dnd-item-occurrence-artifacts.md`.
|
|
5. Each integration contract must define its exact kind, schema ID/name/version,
|
|
media type, strict wire shape, identity or occurrence policy, evidence
|
|
boundary, normalization behavior, consumers, and compatibility statement.
|
|
Cross-link rather than copying common reference or output semantics.
|
|
6. Verify that only `examples/dnd-minimal.config.yml` and
|
|
`examples/dnd-complete.config.yml` remain as maintained D&D configurations,
|
|
that both are secret-free, and that documentation links to rather than
|
|
reproduces them.
|
|
7. Keep future or historical discussion in `docs/roadmap/` and ADRs. Do not
|
|
rewrite accepted ADRs as current reference documentation, add a changelog,
|
|
or delete the active roadmap files.
|
|
|
|
### Acceptance criteria
|
|
|
|
- Current docs contain only implemented final names and contracts.
|
|
- Each volatile fact has one canonical owner and all links resolve.
|
|
- Maintained examples are valid, copyable, and tested.
|
|
- No documentation claims compatibility with the retired pre-release names.
|
|
|
|
### Validation
|
|
|
|
```sh
|
|
go test ./internal/cli/... ./internal/modules/integration/...
|
|
go run ./cmd/notarius config validate --config examples/dnd-minimal.config.yml --pipeline dnd-session
|
|
OPENROUTER_API_KEY=validation-placeholder go run ./cmd/notarius config validate --config examples/dnd-complete.config.yml --pipeline dnd-session
|
|
git diff --check
|
|
```
|
|
|
|
## Stage 14: Final Contract Audit And Repository Verification
|
|
|
|
### Goal
|
|
|
|
Perform a final gap audit, remove stale implementation remnants, and prove the
|
|
completed feature at repository scope.
|
|
|
|
### Required changes
|
|
|
|
1. Search production code, assets, tests, examples, and current documentation
|
|
for retired exact identities, including:
|
|
`dnd/npcs`, `dnd/npc-interactions`, `dnd/locations`, `dnd/item-events`,
|
|
`dnd/npc-list`, `dnd/npc-interaction-list`, `dnd/location-list`,
|
|
`dnd/item-event-list`, old schema IDs/names, old prompt IDs, old capability
|
|
names, `common-dnd-npcs.md`, and old reference-slot names. Exclude
|
|
`docs/roadmap/`, where migration context intentionally names the old values.
|
|
2. Search for retired Go artifact identifiers `NPCList`, `NPCInteraction`,
|
|
`LocationList`, and `ItemEvent`. Distinguish legitimate words or unrelated
|
|
concepts from compatibility remnants; remove every actual old contract or
|
|
alias.
|
|
3. Verify the final package and asset trees contain only canonical registry and
|
|
occurrence stage packages. Confirm every D&D prompt subtree has
|
|
`prompt.yaml` and `instructions.md`, manifests select only existing assets,
|
|
and all prompt/schema fingerprints are content-safe.
|
|
4. Verify every private D&D response schema has `additionalProperties: false`,
|
|
includes every declared property in `required`, and uses the exact final
|
|
private identity. Verify durable schemas independently through their codecs;
|
|
do not conflate private and durable contracts.
|
|
5. Review default validator chains for all six entity modules. Each registry
|
|
must have shape, identity, source-reference, schema, and relatedness coverage;
|
|
each occurrence must additionally enforce exact registry membership and
|
|
domain invariants at the appropriate stages.
|
|
6. Review tests against `docs/policy/testing.md`. Consolidate redundant
|
|
cross-layer assertions, retain regression coverage for identities and
|
|
handoffs, and do not add asset inventories or exact prefix-length detectors.
|
|
7. Run repository-wide tests, vet, build, example validation, and whitespace
|
|
checks. Fix any defect discovered; do not merely document it as follow-up if
|
|
it is within this roadmap's scope.
|
|
8. Report any optional live-model observations separately. Live model quality
|
|
is useful human evaluation but is not a credentialed automated acceptance
|
|
gate and must not block deterministic completion.
|
|
|
|
### Acceptance criteria
|
|
|
|
- The target end state in `entity-registries.md` is fully implemented.
|
|
- No production compatibility alias or stale current-behavior name remains.
|
|
- All six entity modules register with exact typed contracts and default chains.
|
|
- Both maintained configurations validate offline.
|
|
- The full repository test, vet, and build checks pass with a clean diff check.
|
|
|
|
### Validation
|
|
|
|
```sh
|
|
go test -count=1 ./...
|
|
go vet ./...
|
|
go build ./cmd/notarius
|
|
go run ./cmd/notarius config validate --config examples/dnd-minimal.config.yml --pipeline dnd-session
|
|
OPENROUTER_API_KEY=validation-placeholder go run ./cmd/notarius config validate --config examples/dnd-complete.config.yml --pipeline dnd-session
|
|
git diff --check
|
|
```
|