Improve D&D registry caching and retire the completed roadmap
This commit is contained in:
@@ -1,432 +0,0 @@
|
||||
# D&D Location Tracking Implementation Plan
|
||||
|
||||
## Objective
|
||||
|
||||
Complete the target state in [D&D Location Tracking](location.md) by correcting
|
||||
the behavioral and maintainability issues found in the post-implementation
|
||||
audit. The location registry and occurrence lanes are already implemented and
|
||||
production-selectable; the remaining work restores one NPC normalization
|
||||
contract, aligns location-occurrence classification with the roadmap, narrows a
|
||||
module's declared references, and factors demonstrated registry-resolution
|
||||
mechanics into a D&D-shared helper.
|
||||
|
||||
This is an ordered implementation plan for a `gpt-5.6-terra` coding agent.
|
||||
Stages 1 through 14 are complete and must not be reimplemented. Implement one
|
||||
new stage per prompt, beginning with Stage 15, and complete each stage's focused
|
||||
validation before proceeding.
|
||||
|
||||
All remaining stages must follow:
|
||||
|
||||
- [Architecture Policy](../policy/architecture.md);
|
||||
- [Testing Policy](../policy/testing.md);
|
||||
- [Documentation Policy](../policy/documentation.md);
|
||||
- [D&D Module Internals](../internal/dnd.md); and
|
||||
- the durable policy decisions in [the feature roadmap](location.md).
|
||||
|
||||
Use behavior-level tests. Do not add tests that freeze exact prompt wording,
|
||||
message counts, source layout, shared-prefix length, or other incidental
|
||||
implementation details. Prompts and canonical documentation must agree, but
|
||||
that agreement is a review responsibility rather than a reason to add a
|
||||
change-detector test.
|
||||
|
||||
## Completed Work Summary
|
||||
|
||||
Stages 1 through 14 delivered the following production state:
|
||||
|
||||
| Completed stage | Result |
|
||||
| --- | --- |
|
||||
| Stage 1 | Added location and location-occurrence domain types plus evidence-anchored location identity. |
|
||||
| Stage 2 | Added strict `v1` durable codecs and JSON Schemas for both artifact kinds. |
|
||||
| Stage 3 | Added shared, opaque-key D&D entity-reconciliation context and proposal safety infrastructure. |
|
||||
| Stage 4 | Migrated NPC normalization to the shared reconciliation machinery. |
|
||||
| Stage 5 | Added evidence-grounded `dnd/locations` extraction. |
|
||||
| Stage 6 | Added conservative LLM-assisted location normalization. |
|
||||
| Stage 7 | Added immutable location-registry resolution and source-free `{id, name}` projection. |
|
||||
| Stage 8 | Added registry-grounded `dnd/location-occurrences` extraction. |
|
||||
| Stage 9 | Added deterministic location-occurrence normalization. |
|
||||
| Stage 10 | Added location shape, identity, evidence, and advisory validators. |
|
||||
| Stage 11 | Added location-occurrence shape, registry, invariant, evidence, and advisory validators. |
|
||||
| Stage 12 | Registered both lanes, their assets, evidence projectors, default profiles, and validator chains. |
|
||||
| Stage 13 | Added the ordered generated-reference handoff to the complete D&D example and integration coverage. |
|
||||
| Stage 14 | Published the current integration, configuration, internal, output, and top-level documentation and ran final verification. |
|
||||
|
||||
The post-implementation audit confirmed that the feature's durable types,
|
||||
identity derivation, codecs, registration, validators, generated handoff,
|
||||
evidence publication, maintained example, and integration coverage are in
|
||||
place. At the audit baseline, `go test ./...`, focused race tests, `go vet
|
||||
./...`, `go build ./cmd/notarius`, and `git diff --check` all passed.
|
||||
|
||||
## Stage 15: Restore NPC Canonical-Name Selection Semantics
|
||||
|
||||
### Goal
|
||||
|
||||
Restore the NPC-specific canonical display-name policy that was weakened during
|
||||
the shared reconciliation migration, without changing the shared proposal
|
||||
contract or any durable artifact shape.
|
||||
|
||||
### Work
|
||||
|
||||
- Update the NPC normalization task asset under
|
||||
`internal/modules/dnd/normalize/npcs/assets/prompts/` so canonical selection
|
||||
again applies all of these rules:
|
||||
- choose only a supplied candidate from an evidence-supported duplicate
|
||||
group;
|
||||
- prefer a complete, stable proper name over an abbreviation; and
|
||||
- prefer an unadorned proper name over that name plus a contextual class,
|
||||
role, title, or relationship descriptor unless the transcript establishes
|
||||
the descriptor as part of the person's name.
|
||||
- Preserve the opaque-key shared reconciliation instructions, prompt-message
|
||||
ordering, response schema, retry/fallback behavior, and deterministic group
|
||||
application. Do not move NPC-specific naming policy into
|
||||
`shared/entityreconcile`.
|
||||
- Update the canonical NPC artifact contract in
|
||||
`docs/integrations/dnd-npc-artifacts.md` with the observable canonical-name
|
||||
selection rule. Keep `docs/internal/dnd.md` focused on normalization
|
||||
mechanics and link to the integration contract rather than maintaining a
|
||||
competing definition; add or adjust a link only if needed for clarity.
|
||||
- Allow the prompt fingerprint and any derived manifest/checkpoint metadata to
|
||||
change through the existing asset-fingerprint mechanism. Do not manually
|
||||
pin a digest.
|
||||
- Retain existing behavior tests for opaque candidate selection, evidence
|
||||
union, ID derivation, retry/fallback, and non-mutation. Add a test only if it
|
||||
exercises deterministic code behavior; do not assert prompt prose.
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- The rendered NPC normalization prompt contains one unambiguous NPC-owned
|
||||
policy that distinguishes proper names from contextual descriptors.
|
||||
- `Captain Aria` is not preferred over `Aria` solely because it is longer when
|
||||
`Captain` is only a contextual title, while an established full name may
|
||||
still outrank an abbreviation.
|
||||
- No module key, schema, identity policy, response schema, validator chain, or
|
||||
shared reconciliation asset changes.
|
||||
- Canonical current documentation, rather than this implementation plan, owns
|
||||
the restored externally observable rule.
|
||||
- `go test ./internal/modules/dnd/normalize/npcs/... ./internal/modules/dnd/shared/entityreconcile/... ./internal/modules/dnd/register/...`
|
||||
passes offline.
|
||||
- `git diff --check` reports no errors.
|
||||
|
||||
### Prompt Size
|
||||
|
||||
Small and suitable for one implementation prompt.
|
||||
|
||||
## Stage 16: Correct Hypothetical Location-Occurrence Classification
|
||||
|
||||
### Goal
|
||||
|
||||
Make the location-occurrence prompt and durable documentation implement the
|
||||
roadmap's distinction between an explicit speculative mention and an inferred
|
||||
or unsupported occurrence.
|
||||
|
||||
### Work
|
||||
|
||||
- Update the location-occurrence task asset under
|
||||
`internal/modules/dnd/extract/locationoccurrences/assets/prompts/` to encode
|
||||
these exact semantic outcomes:
|
||||
- explicit non-actionable speculation or a mere hypothetical reference to a
|
||||
registry location is `mentioned`;
|
||||
- an explicit proposal, intention, or agreement to travel is `planned`;
|
||||
- a mere hypothetical or speculation is not `planned`; and
|
||||
- an inferred, unstated, uncertain, or unsupported place or occurrence is
|
||||
omitted.
|
||||
- Preserve the documented precedence `visited`, `planned`, `recalled`, then
|
||||
`mentioned`, including the ability to return multiple independently
|
||||
evidenced facts from one passage.
|
||||
- Update the `mentioned` definition in
|
||||
`docs/integrations/dnd-location-occurrence-artifacts.md` to explicitly include
|
||||
non-actionable speculation. Keep durable category semantics in that
|
||||
integration contract and link from internal documentation rather than
|
||||
duplicating the taxonomy elsewhere.
|
||||
- Do not change the occurrence enum, durable schema, normalizer, validators, or
|
||||
generated-reference contract.
|
||||
- Allow existing prompt fingerprinting to record the asset change. Do not add
|
||||
an exact-text or exact-digest test.
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- The prompt no longer instructs the model to omit every hypothetical
|
||||
reference.
|
||||
- An explicit statement such as “What if we went to Moon Gate?” is eligible as
|
||||
`mentioned` when it is supported by a narrow transcript range, but is not a
|
||||
`planned` occurrence without an actual proposal or intention.
|
||||
- An unstated location inferred only from surrounding events remains omitted.
|
||||
- The feature roadmap, prompt, and canonical integration contract agree on all
|
||||
four categories and their precedence.
|
||||
- `go test ./internal/modules/dnd/extract/locationoccurrences/... ./internal/modules/dnd/register/...`
|
||||
passes offline.
|
||||
- `git diff --check` reports no errors.
|
||||
|
||||
### Prompt Size
|
||||
|
||||
Small and suitable for one implementation prompt.
|
||||
|
||||
## Stage 17: Narrow Location-Occurrence Normalizer References
|
||||
|
||||
### Goal
|
||||
|
||||
Make the deterministic normalizer advertise exactly the reference material it
|
||||
uses.
|
||||
|
||||
### Work
|
||||
|
||||
- Change `internal/modules/dnd/normalize/locationoccurrences` so its
|
||||
`ReferenceSlots` and `ModuleSpec` expose only the required `locations` slot.
|
||||
- Keep that slot's existing contract unchanged: exactly one
|
||||
`dnd/location-list` artifact, `application/json`, at most 1,048,576 bytes,
|
||||
required at extraction and normalization.
|
||||
- Remove the normalizer's unused `party`, `roster`, `players`, and `glossary`
|
||||
declarations and any imports or description tables made dead by that change.
|
||||
Do not remove those optional slots from the LLM-backed occurrence extractor,
|
||||
which actually presents campaign material to the model.
|
||||
- Add or revise focused module-contract tests to compare the normalizer's
|
||||
complete declared slot set, including requiredness, media type, artifact kind,
|
||||
and size. This is a stable module contract test, not a source-layout test.
|
||||
- Verify that pipeline-level campaign reference defaults continue to bind only
|
||||
to eligible targets and that the complete example still resolves. Current
|
||||
configuration documentation already states that `locations` is required by
|
||||
both occurrence stages; update it only if repository inspection finds a claim
|
||||
that optional campaign references are consumed by the normalizer.
|
||||
- Do not change normalization output, registry fingerprints, warnings, or
|
||||
checkpoint handling for the required generated registry.
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- Catalog and `ModuleSpec` inspection report exactly one normalizer reference
|
||||
slot: required `locations`.
|
||||
- The extractor continues to accept its existing optional campaign context and
|
||||
required location registry.
|
||||
- Binding optional campaign references no longer implies that deterministic
|
||||
occurrence normalization consumes them.
|
||||
- The complete configuration and generated location handoff still resolve and
|
||||
run through existing tests.
|
||||
- `go test ./internal/modules/dnd/normalize/locationoccurrences/... ./internal/modules/dnd/register/... ./internal/modules/integration/... ./internal/cli/...`
|
||||
passes offline.
|
||||
- `git diff --check` reports no errors.
|
||||
|
||||
### Prompt Size
|
||||
|
||||
Small and suitable for one implementation prompt.
|
||||
|
||||
## Stage 18: Add Shared Registry-Resolution Infrastructure
|
||||
|
||||
### Goal
|
||||
|
||||
Introduce a focused D&D-shared primitive for the demonstrated immutable
|
||||
registry-resolution mechanics, without changing any production consumer in the
|
||||
same prompt.
|
||||
|
||||
### Work
|
||||
|
||||
- Add `internal/modules/dnd/shared/registryresolver` as a domain-shared package;
|
||||
do not put this helper in the generic framework.
|
||||
- Provide an idiomatic generic resolver driven by callbacks or a small adapter
|
||||
so it can operate on immutable domain registry views without importing NPC,
|
||||
location, scene-description, or codec packages.
|
||||
- The resolver core must own the behavior currently duplicated by the NPC and
|
||||
location resolvers:
|
||||
- validate and retain one construction-time seeded view;
|
||||
- treat a declared generated-reference placeholder with zero construction-
|
||||
time items as absent only during construction;
|
||||
- use the seeded view when an operation does not supply the target slot;
|
||||
- resolve an operation-time override when the target slot is present;
|
||||
- memoize valid immutable views by a raw key and by semantic identity;
|
||||
- reuse the seeded view when bound state and semantic identity match;
|
||||
- synchronize concurrent resolution; and
|
||||
- never retain caller-owned reference maps, item content, or mutable values.
|
||||
- Raw cache identity must normalize the media-type spelling and hash the actual
|
||||
item content. Do not trust a caller-supplied digest as proof that different
|
||||
bytes are equal.
|
||||
- Provide a narrow helper for resolving an optional single reference item that
|
||||
validates the configured slot name, exact item count when bound, parsed media
|
||||
type, and maximum size. Return owned bytes or require immediate decode so the
|
||||
helper cannot retain caller-owned content.
|
||||
- Keep artifact decoding, semantic identity validation, canonical encoding,
|
||||
prompt projection, lookup indexes, clone policy, and domain-specific error
|
||||
context in the owning registry packages.
|
||||
- Keep errors bounded and content-free. Do not include raw reference bytes,
|
||||
origin paths, or campaign data in diagnostics.
|
||||
- Add focused tests for absent construction state, zero-item generated
|
||||
placeholders, seeded fallback, operation overrides, malformed cardinality,
|
||||
media types, size limits, raw reuse, semantic reuse, caller-supplied digest
|
||||
mismatch, concurrent access, loader failure, and non-retention/non-mutation.
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- The shared package depends only on generic source/framework contracts and Go
|
||||
standard-library packages, not concrete D&D artifact or codec packages.
|
||||
- The helper owns only demonstrated resolution, validation, caching, and
|
||||
ownership mechanics; it does not become a universal artifact registry.
|
||||
- Invalid values and loader errors are never cached.
|
||||
- Concurrent callers resolving identical bytes receive the same prepared
|
||||
immutable view without races.
|
||||
- Existing production registry packages remain unchanged in this stage.
|
||||
- `go test -race ./internal/modules/dnd/shared/registryresolver/...` passes
|
||||
offline.
|
||||
- `git diff --check` reports no errors.
|
||||
|
||||
### Prompt Size
|
||||
|
||||
Medium and suitable for one implementation prompt. Keep production migrations
|
||||
out of this stage so the generic ownership and concurrency contract can be
|
||||
reviewed independently.
|
||||
|
||||
## Stage 19: Migrate The NPC Registry To The Shared Resolver
|
||||
|
||||
### Goal
|
||||
|
||||
Make the established NPC registry the first production consumer of the shared
|
||||
resolver while preserving all public and operational behavior.
|
||||
|
||||
### Work
|
||||
|
||||
- Refactor `internal/modules/dnd/npcs/registry` to compose the Stage 18 helper
|
||||
for construction/operation selection, single-item validation, raw caching,
|
||||
semantic caching, and synchronization.
|
||||
- Preserve the existing package API used by extractors, normalizers,
|
||||
validators, manifests, and tests, including `NewResolver`, `Resolve`,
|
||||
`Seeded`, `Bound`, `NPCs`, `List`, `CanonicalBytes`, `Digest`,
|
||||
`ProjectionDigest`, `Count`, `PromptInput`, `CanonicalName`, and `Matches`.
|
||||
- Keep NPC-owned behavior in the NPC package:
|
||||
- strict approved NPC codec use;
|
||||
- NPC identity validation;
|
||||
- canonical durable JSON and names-only prompt projection;
|
||||
- comparison-key lookup;
|
||||
- defensive NPC/source-reference cloning; and
|
||||
- NPC-specific redacted error context.
|
||||
- Preserve the exact empty projection, semantic and projection digest behavior,
|
||||
seeded/generated resolution semantics, manifest metadata, checkpoint
|
||||
fingerprints, and source-free prompt input.
|
||||
- Remove superseded NPC-private resolver/cache/media/digest code only after the
|
||||
shared helper supplies the same behavior. Do not migrate locations or scene
|
||||
descriptions in this stage.
|
||||
- Update focused tests as needed to verify behavior through the NPC package,
|
||||
including malformed static and operation-time references, raw/semantic cache
|
||||
reuse, concurrent resolution, defensive copies, prompt projection, and
|
||||
downstream grounding.
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- Existing NPC consumers compile without API changes.
|
||||
- NPC registry output bytes, prompt projection, lookup behavior, digests,
|
||||
reference limits, errors, manifests, and checkpoints retain their established
|
||||
semantics.
|
||||
- The NPC package no longer contains a second implementation of resolver
|
||||
selection, caching, or synchronization.
|
||||
- `go test -race ./internal/modules/dnd/npcs/registry/... ./internal/modules/dnd/extract/npcinteractions/... ./internal/modules/dnd/normalize/npcinteractions/... ./internal/modules/dnd/validate/npcinteractions/...`
|
||||
passes offline.
|
||||
- `go test ./internal/modules/dnd/register/...` passes offline.
|
||||
- `git diff --check` reports no errors.
|
||||
|
||||
### Prompt Size
|
||||
|
||||
Medium and suitable for one implementation prompt.
|
||||
|
||||
## Stage 20: Migrate The Location Registry To The Shared Resolver
|
||||
|
||||
### Goal
|
||||
|
||||
Remove the newly introduced NPC/location resolver duplication while preserving
|
||||
the location identity and generated-handoff contracts.
|
||||
|
||||
### Work
|
||||
|
||||
- Refactor `internal/modules/dnd/locations/registry` to compose the Stage 18
|
||||
helper for the same resolver, reference-item validation, cache, and
|
||||
synchronization responsibilities migrated in Stage 19.
|
||||
- Preserve the existing package API, including `NewResolver`, `Resolve`,
|
||||
`Seeded`, `Bound`, `Locations`, `List`, `CanonicalBytes`, `Digest`,
|
||||
`ProjectionDigest`, `Count`, `PromptInput`, `Lookup`, and `Matches`.
|
||||
- Keep location-owned behavior in the location package:
|
||||
- strict approved location codec use;
|
||||
- evidence-anchored identity validation;
|
||||
- canonical durable JSON and ordered source-free `{id, name}` projection;
|
||||
- exact ID lookup and exact ID/name matching;
|
||||
- defensive location/source-reference cloning; and
|
||||
- location-specific redacted error context.
|
||||
- Preserve absent/empty/bound distinctions, same-name locations with distinct
|
||||
IDs, seeded/generated resolution, semantic and projection digests, manifest
|
||||
metadata, checkpoint fingerprints, and the 1 MiB limit.
|
||||
- Remove superseded location-private resolver/cache/media/digest code only
|
||||
after parity is established.
|
||||
- Do not migrate the scene-description eligibility registry in this stage. It
|
||||
has a different projection and matching contract; including it is not needed
|
||||
to eliminate the exact NPC/location duplication identified by the audit.
|
||||
- Update focused and integration tests as needed for static and generated
|
||||
references, malformed inputs, raw/semantic reuse, concurrency, defensive
|
||||
copies, source-free projections, same-name ID lookup, normalizer grounding,
|
||||
validator grounding, and handoff checkpoint invalidation.
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- Existing location consumers compile without API changes.
|
||||
- Location registry output bytes, projection, identity validation, lookup,
|
||||
digests, reference errors, manifests, and checkpoints retain their
|
||||
established semantics.
|
||||
- NPC and location registries share one implementation of construction/
|
||||
operation resolution, raw and semantic caching, and synchronization.
|
||||
- No registry evidence or provenance appears in the occurrence prompt
|
||||
projection.
|
||||
- `go test -race ./internal/modules/dnd/locations/registry/... ./internal/modules/dnd/extract/locationoccurrences/... ./internal/modules/dnd/normalize/locationoccurrences/... ./internal/modules/dnd/validate/locationoccurrences/... ./internal/modules/integration/...`
|
||||
passes offline.
|
||||
- `git diff --check` reports no errors.
|
||||
|
||||
### Prompt Size
|
||||
|
||||
Medium and suitable for one implementation prompt.
|
||||
|
||||
## Stage 21: Final Regression And Documentation Verification
|
||||
|
||||
### Goal
|
||||
|
||||
Verify the remediations as one coherent production state without expanding the
|
||||
feature or prematurely retiring its roadmap documents.
|
||||
|
||||
### Work
|
||||
|
||||
- Run `gofmt` on all changed Go files and inspect the final diff for unrelated
|
||||
changes, stale private resolver implementations, unused imports, and
|
||||
accidental artifact-contract changes.
|
||||
- Re-read the affected prompt assets and canonical integration documents to
|
||||
verify that:
|
||||
- NPC canonical-name selection retains the proper-name/title distinction;
|
||||
- explicit non-actionable speculation maps to `mentioned`;
|
||||
- inferred, uncertain, and unsupported occurrences remain omitted; and
|
||||
- prompt changes did not reorder or duplicate shared cacheable prompt assets.
|
||||
- Inspect module catalog output or registration tests to confirm the
|
||||
location-occurrence normalizer declares only `locations`, while its extractor
|
||||
retains the intended optional campaign slots.
|
||||
- Confirm the shared resolver has exactly the NPC and location consumers
|
||||
planned here and that domain-specific codecs, identity, projections, lookups,
|
||||
and error context remain in their owning packages.
|
||||
- Run the maintained complete example/configuration loading path and all
|
||||
repository-wide validation.
|
||||
- Leave `docs/roadmap/location.md` and this implementation plan in place for the
|
||||
user's separate roadmap-retirement step. Do not delete them in this stage.
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- `go test ./internal/modules/dnd/...` passes.
|
||||
- `go test ./internal/modules/integration/... ./internal/cli/...` passes.
|
||||
- `go test -race ./internal/modules/dnd/shared/registryresolver/... ./internal/modules/dnd/npcs/registry/... ./internal/modules/dnd/locations/registry/...` passes.
|
||||
- `go test ./...` passes.
|
||||
- `go vet ./...` passes.
|
||||
- `go build ./cmd/notarius` passes.
|
||||
- Maintained configuration/example validation passes through its repository
|
||||
test target.
|
||||
- `git diff --check` reports no errors.
|
||||
- Current documentation contains no stale contradiction about hypothetical
|
||||
location mentions or NPC canonical-name selection.
|
||||
- The worktree contains only the intended remediation changes and the roadmap
|
||||
documents remain available for later retirement.
|
||||
|
||||
### Prompt Size
|
||||
|
||||
Small-to-medium and suitable for one implementation prompt.
|
||||
|
||||
## Open Questions
|
||||
|
||||
None. The feature roadmap and audit findings determine the required behavioral
|
||||
semantics, module reference contract, abstraction boundary, migration order,
|
||||
and validation expectations. The scene-description eligibility registry is
|
||||
explicitly outside this remediation because its projection and matching
|
||||
semantics differ from the duplicated NPC/location grounding registries.
|
||||
Reference in New Issue
Block a user