Audit spell and scene processing
This commit is contained in:
@@ -20,13 +20,12 @@ change only roadmap audit documents do not change that production target.
|
||||
|
||||
Pending final synthesis. The initial baseline is healthy. The architecture,
|
||||
configuration/CLI, pipeline composition, reference/handoff, runtime, state,
|
||||
LLM, generic/Seriatim, shared D&D, registry-family, and occurrence-family
|
||||
reviews have found three High findings, five Medium findings, and twenty-two
|
||||
Low findings, with no production dependency inversion, unbounded framework
|
||||
worker pool, completion-order-dependent result
|
||||
assembly, debug-to-cache coupling, model-visible credential material in the
|
||||
embedded LLM assets, or domain leakage across the Seriatim and generic module
|
||||
boundaries.
|
||||
LLM, generic/Seriatim, shared D&D, registry-family, occurrence-family, and
|
||||
spell/scene-family reviews have found three High findings, six Medium findings,
|
||||
and twenty-three Low findings, with no production dependency inversion,
|
||||
unbounded framework worker pool, completion-order-dependent result assembly,
|
||||
debug-to-cache coupling, model-visible credential material in the embedded LLM
|
||||
assets, or domain leakage across the Seriatim and generic module boundaries.
|
||||
|
||||
## Finding Index
|
||||
|
||||
@@ -58,12 +57,14 @@ Final cross-area ordering is pending synthesis.
|
||||
| MOD-003 | Low | Simplicity | Remove unreachable JSON metadata clone helpers |
|
||||
| DND-CORE-001 | Low | Simplicity | Remove the unused lossy unit-reference constructor |
|
||||
| DND-REG-001 | Low | Correctness | Reject reversed evidence ranges at durable D&D codec boundaries |
|
||||
| DND-REG-002 | Low | Correctness | Keep NPC extraction evidence inside the current chunk |
|
||||
| DND-REG-002 | Low | Correctness | Keep NPC and spell extraction evidence inside the current chunk |
|
||||
| DND-REG-003 | Low | Efficiency | Index item and location duplicate groups |
|
||||
| DND-REG-004 | Low | Efficiency | Select location identity anchors without sorting |
|
||||
| DND-OCC-001 | Medium | Correctness | Align item occurrence evidence fields with the shared prompt |
|
||||
| DND-OCC-002 | Low | Simplicity | Remove unused campaign references from NPC occurrence normalization |
|
||||
| DND-OCC-003 | Low | Efficiency | Reuse canonical item occurrence evidence |
|
||||
| DND-SCENE-001 | Medium | Correctness | Expose catalog aliases to spell extraction |
|
||||
| DND-SCENE-002 | Low | Correctness | Make scene and spell normalization diagnostics complete and bounded |
|
||||
|
||||
## Findings
|
||||
|
||||
@@ -201,7 +202,14 @@ Final cross-area ordering is pending synthesis.
|
||||
`cloneBuildRequest` (`prepare.go:272`–`299` and 325–327). Each request clone
|
||||
deep-copies materialized reference content as well as options, so typed
|
||||
builders receive two reference copies and as many as three option copies;
|
||||
untyped stage and validator builders use fewer copies.
|
||||
untyped stage and validator builders use fewer copies. Spell extractor,
|
||||
normalizer, and catalog-validator construction then call
|
||||
`spells/catalog.ResolveEffectiveCatalog`; that helper clones every slot and
|
||||
every item byte slice in the already owned `ReferenceSet`
|
||||
(`internal/modules/dnd/spells/catalog/effective.go:55`–`62` and 411–426), even
|
||||
though it reads only the `spell_catalog` slot and decodes its content into a
|
||||
new overlay value. On extractor construction this needlessly recopies the
|
||||
optional NPC registry and campaign-context references as well.
|
||||
- **Impact:** Every preparation repeats allocation and byte copying for bounded
|
||||
external references and nested options, with the highest cost and a
|
||||
different ownership path specifically for typed lanes and validators. The
|
||||
@@ -210,7 +218,9 @@ Final cross-area ordering is pending synthesis.
|
||||
- **Recommendation:** Designate one private construction invocation as the
|
||||
ownership boundary and clone the complete `BuildRequest` exactly there.
|
||||
Store raw builders or remove the caller-side clone consistently so all stage
|
||||
and validator registry variants follow the same single-copy rule.
|
||||
and validator registry variants follow the same single-copy rule. Let spell
|
||||
catalog resolution read the owned catalog slot directly instead of cloning
|
||||
unrelated slots.
|
||||
- **Preserve:** Builders must continue to receive independently owned options,
|
||||
reference maps, slot slices, metadata, and content bytes; preparation must
|
||||
retain its own immutable resolved/reference state; nil, key/name, execution
|
||||
@@ -218,8 +228,11 @@ Final cross-area ordering is pending synthesis.
|
||||
- **Validation:** Extend construction hooks to mutate nested options and
|
||||
reference bytes for typed and untyped modules/validators, assert no aliasing
|
||||
with resolved or sibling requests, and use allocation/byte-copy observations
|
||||
or a focused benchmark to confirm a single defensive copy; run
|
||||
`go test ./internal/framework/contracts ./internal/framework/pipeline`.
|
||||
or a focused benchmark to confirm a single defensive copy. Add a spell
|
||||
catalog construction case with large unrelated slots and verify that
|
||||
resolution neither copies nor mutates them; run
|
||||
`go test ./internal/framework/contracts ./internal/framework/pipeline
|
||||
./internal/modules/dnd/spells/catalog`.
|
||||
- **Grouping:** Independent.
|
||||
|
||||
### References And Ordered Handoffs
|
||||
@@ -863,21 +876,26 @@ Final cross-area ordering is pending synthesis.
|
||||
|
||||
- **Severity:** Low
|
||||
- **Category:** Correctness
|
||||
- **Evidence:** The three registry and three occurrence integration contracts
|
||||
require that a source range's start not follow its end
|
||||
- **Evidence:** The three registry, three occurrence, spell, and scene-
|
||||
description integration contracts require that a source range's start not
|
||||
follow its end
|
||||
(`docs/integrations/dnd-npc-registry-artifacts.md:32`–`34`,
|
||||
`dnd-item-registry-artifacts.md:33`–`35`, and
|
||||
`dnd-location-registry-artifacts.md:34`–`36`; and
|
||||
`dnd-npc-occurrence-artifacts.md:33`–`36`,
|
||||
`dnd-item-occurrence-artifacts.md:41`–`43`, and
|
||||
`dnd-location-occurrence-artifacts.md:33`–`35`). All six durable codec
|
||||
validators check only that both endpoints are positive
|
||||
`dnd-item-occurrence-artifacts.md:41`–`43`,
|
||||
`dnd-location-occurrence-artifacts.md:33`–`35`,
|
||||
`dnd-spell-artifacts.md:31`–`35`, and
|
||||
`dnd-scene-description-artifacts.md:33`–`35`). All eight reviewed durable
|
||||
codec validators check only that both endpoints are positive
|
||||
(`internal/modules/dnd/codec/npcregistry/codec.go:96`–`106`,
|
||||
`codec/itemregistry/codec.go:97`–`107`, and
|
||||
`codec/locationregistry/codec.go:97`–`107`; and
|
||||
`codec/npcoccurrences/codec.go:99`–`109`,
|
||||
`codec/itemoccurrences/codec.go:117`–`127`, and
|
||||
`codec/locationoccurrences/codec.go:100`–`110`). Direct registry references are
|
||||
`codec/itemoccurrences/codec.go:117`–`127`,
|
||||
`codec/locationoccurrences/codec.go:100`–`110`,
|
||||
`codec/spells/codec.go:89`–`99`, and
|
||||
`codec/scenedescriptions/codec.go:101`–`109`). Direct registry references are
|
||||
decoded and identity-checked by `npcs/registry.loadRegistry`,
|
||||
`items/registry.loadRegistry`, and `locations/registry.loadRegistry`, but do
|
||||
not pass through the generated-output source-reference validators. A durable
|
||||
@@ -885,17 +903,21 @@ Final cross-area ordering is pending synthesis.
|
||||
`{start_unit_id: 2, end_unit_id: 1}` and otherwise valid fields is therefore
|
||||
accepted; for locations, `validIdentityReference` at
|
||||
`internal/modules/dnd/locations/identity/identity.go:170`–`171` also treats
|
||||
that reversed range as a valid identity anchor.
|
||||
- **Impact:** An externally supplied registry or occurrence list can be
|
||||
accepted as approved even though its evidence cannot denote the documented
|
||||
forward source interval.
|
||||
NPC and item prompt projections then hide the malformed provenance, while a
|
||||
location can derive and retain a durable ID from it; only later consumers
|
||||
that happen to construct contextual grounding against the same source may
|
||||
reject it. Generated pipeline outputs remain protected by their source-
|
||||
reference validator chains, which limits current exposure.
|
||||
that reversed range as a valid identity anchor. The immutable scene-
|
||||
eligibility registry also decodes approved scene artifacts directly before
|
||||
projecting ID, range, and kind
|
||||
(`internal/modules/dnd/scenedescriptions/registry/registry.go:174`–`223`).
|
||||
- **Impact:** An externally supplied D&D artifact can be accepted as approved
|
||||
even though its evidence cannot denote the documented forward source
|
||||
interval.
|
||||
NPC and item prompt projections then hide the malformed provenance, a
|
||||
location can derive and retain a durable ID from it, and scene gating can
|
||||
retain the impossible interval as eligibility metadata; only later consumers
|
||||
with source context may reject it. Generated pipeline outputs remain
|
||||
protected by their source-reference validator chains, which limits current
|
||||
exposure.
|
||||
- **Recommendation:** Add the order-independent structural condition
|
||||
`start_unit_id <= end_unit_id` to all six reviewed codecs' durable
|
||||
`start_unit_id <= end_unit_id` to all eight reviewed codecs' durable
|
||||
validation, and make location identity reject reversed anchors as a defense
|
||||
in depth.
|
||||
Keep document membership and current-chunk coverage in the existing
|
||||
@@ -904,46 +926,49 @@ Final cross-area ordering is pending synthesis.
|
||||
field/trailing-value rejection, location identity's earliest canonical
|
||||
anchor policy, and the separation between source-independent durable shape
|
||||
validation and source-dependent evidence validation.
|
||||
- **Validation:** Add codec encode/decode cases for reversed ranges in all six
|
||||
- **Validation:** Add codec encode/decode cases for reversed ranges in all eight
|
||||
reviewed families, a location identity case that refuses a reversed-only
|
||||
anchor, and direct registry and occurrence reference cases proving malformed
|
||||
referenced JSON is rejected; run the codec, identity, registry, occurrence,
|
||||
and assembled CLI suites.
|
||||
anchor, and direct registry, occurrence, spell, and scene-eligibility
|
||||
reference cases proving malformed referenced JSON is rejected; run the
|
||||
codec, identity, registry, spell, scene, occurrence, and assembled CLI suites.
|
||||
- **Grouping:** Independent.
|
||||
|
||||
### DND-REG-002 — Keep NPC extraction evidence inside the current chunk
|
||||
### DND-REG-002 — Keep NPC and spell extraction evidence inside the current chunk
|
||||
|
||||
- **Severity:** Low
|
||||
- **Category:** Correctness
|
||||
- **Evidence:** The NPC, item, and location extractors receive only the current
|
||||
chunk and all three default extract chains run their family source-reference
|
||||
validator. Item and location validators require a non-nil extraction chunk
|
||||
and reject references whose endpoints are not in it
|
||||
- **Evidence:** The NPC, item, location, and spell extractors receive only the
|
||||
current chunk and all four default extract chains run their family source-
|
||||
reference validator. Item and location validators require a non-nil
|
||||
extraction chunk and reject references whose endpoints are not in it
|
||||
(`internal/modules/dnd/validate/itemregistry/source_refs/validator.go:37`–`55`
|
||||
and `validate/locationregistry/source_refs/validator.go:37`–`55`). The NPC
|
||||
validator at `validate/npcregistry/source_refs/validator.go:36`–`53` checks
|
||||
only that a reference is valid somewhere in the complete source document; it
|
||||
neither requires `req.Chunk` during extraction nor checks chunk membership.
|
||||
Its focused tests include reversed, foreign, and out-of-document ranges but
|
||||
no off-chunk range or missing-chunk case.
|
||||
- **Impact:** If an NPC extraction response supplies a valid unit ID from
|
||||
another chunk, the candidate can pass evidence validation despite the model
|
||||
never receiving that passage. A name that also appears at the off-chunk range
|
||||
can pass advisory relatedness without proving the current candidate, causing
|
||||
duplicated or misattributed registry provenance across chunk results. The
|
||||
model usually copies visible unit IDs, which limits the likelihood.
|
||||
The spell validator has the same document-only behavior
|
||||
(`validate/spells/source_refs/validator.go:35`–`51`). Its tests exercise
|
||||
valid, out-of-document, missing-document, malformed-shape, and bounded-
|
||||
aggregate cases, but supply no stage or chunk and do not cover an existing
|
||||
off-chunk range (`validator_test.go:15`–`73`).
|
||||
- **Impact:** If an NPC or spell extraction response supplies a valid unit ID
|
||||
from another chunk, the candidate can pass evidence validation despite the
|
||||
model never receiving that passage. Relatedness can also succeed when the NPC
|
||||
name or spell appears only at the cited off-chunk range, causing duplicated
|
||||
or misattributed provenance across chunk results. The model usually copies
|
||||
visible unit IDs, which limits the likelihood.
|
||||
- **Recommendation:** Match the item/location extraction contract: require the
|
||||
current chunk when `req.Stage` is extract and reject NPC references outside
|
||||
that chunk. Keep whole-document validation for normalize and other non-
|
||||
extraction validation calls.
|
||||
current chunk when `req.Stage` is extract and reject NPC and spell references
|
||||
outside that chunk. Keep whole-document validation for normalize and other
|
||||
non-extraction validation calls.
|
||||
- **Preserve:** Retain full-document source-ID/range validation, shape deferral,
|
||||
bounded aggregate diagnostics, normalization without a chunk, direct factual
|
||||
third-party mentions, and source-relatedness as an advisory check rather than
|
||||
an identity gate.
|
||||
- **Validation:** Add NPC source-reference cases for an existing off-chunk
|
||||
range, a missing extraction chunk, an accepted in-chunk range, and normalize-
|
||||
stage validation without a chunk; run the NPC registry validator, extractor,
|
||||
and assembled pipeline tests.
|
||||
- **Validation:** Add NPC and spell source-reference cases for an existing off-
|
||||
chunk range, a missing extraction chunk, an accepted in-chunk range, and
|
||||
normalize-stage validation without a chunk; run both source-reference
|
||||
validators, their extractors, and assembled pipeline tests.
|
||||
- **Grouping:** Independent.
|
||||
|
||||
### DND-REG-003 — Index item and location duplicate groups
|
||||
@@ -1113,6 +1138,86 @@ Final cross-area ordering is pending synthesis.
|
||||
per normalized record; run item occurrence normalize/validator tests.
|
||||
- **Grouping:** Independent.
|
||||
|
||||
### Spells, Scene Chunking, And Scene Descriptions
|
||||
|
||||
### DND-SCENE-001 — Expose catalog aliases to spell extraction
|
||||
|
||||
- **Severity:** Medium
|
||||
- **Category:** Correctness
|
||||
- **Evidence:** The overlay contract says optional aliases contribute to spell
|
||||
recognition (`docs/integrations/dnd-spell-catalog-overlays.md:3`–`6` and
|
||||
57–68), and the effective catalog correctly maps each accepted alias to its
|
||||
canonical spell (`internal/modules/dnd/spells/catalog/effective.go:215`–`247`).
|
||||
The extractor's model-visible projection serializes only
|
||||
`EffectiveCatalog.CanonicalNames()` as `spell_names`
|
||||
(`internal/modules/dnd/extract/spells/catalog_prompt_input.go:13`–`28`), while
|
||||
its prompt explicitly says aliases are absent and requires exact canonical
|
||||
spelling (`assets/dnd/spells/prompts/spell-catalog.md:1`–`6`). Focused and
|
||||
assembled tests codify the omission by rejecting `Emberfall Aegis` from the
|
||||
prompt even though the configured overlay maps it to `Aegis of Emberfall`
|
||||
(`internal/modules/dnd/extract/spells/extractor_test.go:88`–`103` and
|
||||
`internal/cli/spell_catalog_identity_contract_test.go:412`–`414`). The
|
||||
downstream catalog validator and normalizer can resolve an alias only if the
|
||||
model already returns it; they cannot teach the model that alias-only
|
||||
transcript language denotes the configured spell.
|
||||
- **Impact:** A real cast expressed only with a campaign alias can be omitted or
|
||||
rejected because the extraction model receives neither the alias nor its
|
||||
canonical mapping. This silently defeats a documented purpose of overlay
|
||||
configuration and can lose durable spell-cast occurrences; canonical names
|
||||
and base-catalog casts remain unaffected.
|
||||
- **Recommendation:** Project a deterministic source-free list of canonical
|
||||
spell names with their recognized aliases into `spell_catalog`, and instruct
|
||||
the model to return the associated canonical spelling. Continue to omit
|
||||
catalog source metadata, paths, licenses, rules text, and provenance. Treat
|
||||
the projection shape and prompt change as semantic fingerprint changes.
|
||||
- **Preserve:** Keep overlays recognition-only rather than evidence, retain
|
||||
strict collision rejection and canonical display names, require current-
|
||||
transcript cast evidence and an in-world caster, preserve NPC provenance
|
||||
separation, and keep the existing prompt order and cache boundaries.
|
||||
- **Validation:** Add base and overlay projection tests for stable canonical-
|
||||
alias mappings, repeated aliases, and metadata exclusion; update the
|
||||
assembled prompt contract to require `Emberfall Aegis` only as an alias of
|
||||
`Aegis of Emberfall`; retain catalog rejection, normalization, checkpoint-
|
||||
invalidation, and retry tests; run the spell extractor, catalog, normalizer,
|
||||
validator, and CLI suites.
|
||||
- **Grouping:** Independent.
|
||||
|
||||
### DND-SCENE-002 — Make scene and spell normalization diagnostics complete and bounded
|
||||
|
||||
- **Severity:** Low
|
||||
- **Category:** Correctness
|
||||
- **Evidence:** The maintained D&D convention says deterministic normalizers
|
||||
issue bounded warnings for changes and collapsed duplicates
|
||||
(`docs/internal/dnd.md:129`–`132`). Spell normalization emits a warning for
|
||||
every canonicalized or unresolved name and changed reference list, then one
|
||||
for every duplicate group, and returns the concatenated slice directly
|
||||
(`internal/modules/dnd/normalize/spells/normalizer.go:89`–`105`, 108–149,
|
||||
and 177–226); unlike the occurrence and registry normalizers, it never calls
|
||||
`diagnostics.LimitWarnings`. Scene-description normalization has the inverse
|
||||
gap: it trims title/summary, reorders records, and removes exact duplicates
|
||||
(`normalize/scenedescriptions/normalizer.go:70`–`124`) but always returns the
|
||||
value without any warnings (lines 53–68). Its primary test performs all three
|
||||
mutations without asserting diagnostic provenance
|
||||
(`normalizer_test.go:15`–`43`).
|
||||
- **Impact:** A large spell list can publish an unbounded number of warnings,
|
||||
inflating manifests, debug artifacts, output files, and checkpoint payloads.
|
||||
Scene normalization silently changes accepted durable content, so operators
|
||||
cannot distinguish an unchanged scene list from repaired whitespace/order or
|
||||
collapsed duplicates. Artifact values remain deterministic and valid.
|
||||
- **Recommendation:** Pass spell warnings through the shared deterministic
|
||||
limiter with a stable omission reason. Add bounded scene warnings that
|
||||
distinguish prose trimming, canonical reordering, and exact duplicate
|
||||
collapse while retaining stable input scopes and order. Emit no warning for
|
||||
an already canonical value.
|
||||
- **Preserve:** Keep current normalized values, source-position ordering,
|
||||
conflict rejection, duplicate identities, input immutability, per-record
|
||||
diagnostic order below the limit, and idempotent warning-free second passes.
|
||||
- **Validation:** Add spell cases beyond `diagnostics.MaxWarnings` that assert
|
||||
the stable omission summary, and scene cases for each mutation, combined
|
||||
overflow, canonical input, and idempotence; run both normalizer suites and
|
||||
assembled output/checkpoint warning tests.
|
||||
- **Grouping:** Independent.
|
||||
|
||||
<!--
|
||||
Finding template for later audit stages:
|
||||
|
||||
@@ -1146,13 +1251,13 @@ evidence projector.
|
||||
|
||||
| Family | Durable kind / Go type | Modules and execution class | Default validator chains (E / N) | Reference dependencies (E / N) | Codec, prompt, and schema ownership | Documented exception and later confirmation |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| Spells | `dnd/spell-list` / `dnd.SpellList` | `dnd/spells` (LLM) → typed `appendorder` (deterministic) → `dnd/spells` (deterministic) | `B + catalog` / `B + catalog` | `C` plus optional `spell_catalog` and `npc_registry` / optional `spell_catalog` | `codec/spells`; extractor owns its prompt and private response schema; normalizer has no prompt | Catalog overlay and NPC caster grounding are optional and never evidence; confirm spell/catalog and scene-family behavior in the spells/scenes review. |
|
||||
| Spells | `dnd/spell-list` / `dnd.SpellList` | `dnd/spells` (LLM) → typed `appendorder` (deterministic) → `dnd/spells` (deterministic) | `B + catalog` / `B + catalog` | `C` plus optional `spell_catalog` and `npc_registry` / optional `spell_catalog` | `codec/spells`; extractor owns its prompt and private response schema; normalizer has no prompt | Confirmed: catalog and NPC grounding remain source-free recognition context; canonicalization, retry, and checkpoint identities are deterministic. DND-REG-001, DND-REG-002, DND-SCENE-001, and DND-SCENE-002 record codec, chunk-evidence, alias-projection, and warning gaps. |
|
||||
| NPC registry | `dnd/npc-registry` / `dnd.NPCRegistry` | `dnd/npc-registry` (LLM) → typed `appendorder` (deterministic) → `dnd/npc-registry` (LLM) | `B` / `B + identity` | `C` / none | `codec/npcregistry`; extractor and normalizer own prompts; extractor owns its response schema, while normalize uses the shared private entity-reconciliation schema | Confirmed: normalized comparison-name identity, deterministic exact duplicate consolidation, proposal-only semantic groups, collision-safe application, retry/fallback, and immutable name/identity projections; DND-REG-001 and DND-REG-002 record evidence-boundary gaps. |
|
||||
| Combat turns | `dnd/combat-turn-list` / `dnd.CombatTurnList` | `dnd/combat-turns` (LLM) → typed `appendorder` (deterministic) → `dnd/combat-turns` (deterministic) | `B` / `B + invariants` | `C`, optional `npc_registry`, required `scene_descriptions` / optional `npc_registry` | `codec/combatturns`; extractor owns its prompt and private response schema; normalizer has no prompt | Scene descriptions gate LLM execution and NPC grounding is not evidence; confirm gate and empty-result semantics in the combat/enemy review. |
|
||||
| Item occurrences | `dnd/item-occurrence-list` / `dnd.ItemOccurrenceList` | `dnd/item-occurrences` (LLM) → typed `appendorder` (deterministic) → `dnd/item-occurrences` (deterministic) | `B + registry` / `B + registry + invariants` | `C` plus required `item_registry` / required `item_registry` | `codec/itemoccurrences`; extractor owns its prompt and private response schema; normalizer has no prompt | Confirmed: exact names-only registry resolution is all-or-nothing, registry provenance never becomes evidence, and quantity/holder rules survive canonical ordering and duplicate collapse. DND-REG-001, DND-OCC-001, and DND-OCC-003 record bounded codec, prompt/schema, and repeated-work gaps. |
|
||||
| Item registry | `dnd/item-registry` / `dnd.ItemRegistry` | `dnd/item-registry` (LLM) → typed `appendorder` (deterministic) → `dnd/item-registry` (LLM) | `B` / `B + identity` | `C` / none | `codec/itemregistry`; extractor and normalizer own prompts; extractor owns its response schema, while normalize uses the shared private entity-reconciliation schema | Confirmed: name identity, exact duplicate evidence union, proposal-only aliases, collision safety, and denomination/type-preserving currency gate; DND-REG-001 and DND-REG-003 record boundary/grouping gaps. |
|
||||
| NPC occurrences | `dnd/npc-occurrence-list` / `dnd.NPCOccurrenceList` | `dnd/npc-occurrences` (LLM) → typed `appendorder` (deterministic) → `dnd/npc-occurrences` (deterministic) | `B + registry` / `B + registry + invariants` | `C` plus required `npc_registry` / `C` plus required `npc_registry` | `codec/npcoccurrences`; extractor owns its prompt and private response schema; normalizer has no prompt | Confirmed: names-only selection resolves to exact registry pairs, registry provenance cannot become occurrence evidence, `mentioned` remains factual, and current-source evidence is canonicalized before exact duplicate collapse. DND-REG-001 and DND-OCC-002 record the codec and unused-normalizer-reference gaps. |
|
||||
| Scene descriptions | `dnd/scene-description-list` / `dnd.SceneDescriptionList` | `dnd/scene-descriptions` (LLM) → typed `appendorder` (deterministic) → `dnd/scene-descriptions` (deterministic) | `B` / `B + invariants` | optional `glossary`, `party`, and `players` / none | `codec/scenedescriptions`; extractor owns its prompt and private response schema; normalizer has no prompt | Each record has one `source_ref` rather than a slice; the separate `dnd/scenes` LLM chunker owns the full-transcript scene prompt. Confirm scene IDs, ordering, and classification in the spells/scenes review. |
|
||||
| Scene descriptions | `dnd/scene-description-list` / `dnd.SceneDescriptionList` | `dnd/scene-descriptions` (LLM) → typed `appendorder` (deterministic) → `dnd/scene-descriptions` (deterministic) | `B` / `B + invariants` | optional `glossary`, `party`, and `players` / none | `codec/scenedescriptions`; extractor owns its prompt and private response schema; normalizer has no prompt | Confirmed: one model classification is mapped onto the current chunk's local ID and exact range, while an immutable source-free ID/range/kind projection alone controls later eligibility. DND-REG-001 and DND-SCENE-002 record codec and warning gaps. |
|
||||
| Enemy events | `dnd/enemy-event-list` / `dnd.EnemyEventList` | `dnd/enemy-events` (LLM) → typed `appendorder` (deterministic) → `dnd/enemy-events` (deterministic) | `B + engagements` / `B + invariants` | `C` plus required `npc_registry`, `scene_descriptions`, `combat_turns`, and `npc_occurrences` / required `npc_registry` | `codec/enemyevents`; extractor owns its prompt and private response schema; normalizer has no prompt | Four generated artifacts ground extraction without becoming event evidence; durable decode separately proves required JSON-field presence. Confirm combat gating, engagement uniqueness, and observation ordering in the combat/enemy review. |
|
||||
| Location registry | `dnd/location-registry` / `dnd.LocationRegistry` | `dnd/location-registry` (LLM) → typed `appendorder` (deterministic) → `dnd/location-registry` (LLM) | `B` / `B + identity` | `C` / none | `codec/locationregistry`; extractor and normalizer own prompts; extractor owns its response schema, while normalize uses the shared private entity-reconciliation schema | Confirmed: comparison name plus earliest canonical evidence identity, same-name/different-anchor preservation, proposal-only aliases, and immutable context-qualified selectors without durable IDs; DND-REG-001, DND-REG-003, and DND-REG-004 record bounded gaps. |
|
||||
| Location occurrences | `dnd/location-occurrence-list` / `dnd.LocationOccurrenceList` | `dnd/location-occurrences` (LLM) → typed `appendorder` (deterministic) → `dnd/location-occurrences` (deterministic) | `B + registry` / `B + registry + invariants` | `C` plus required `location_registry` / required `location_registry` | `codec/locationoccurrences`; extractor owns its prompt and private response schema; normalizer has no prompt | Confirmed: source-free contextual selectors disambiguate same-name locations without exposing durable IDs, unresolved selections reject the whole response, registry evidence remains separate, and explicit kind precedence preserves speculation/mention distinctions. DND-REG-001 records the codec gap. |
|
||||
@@ -1365,6 +1470,22 @@ mechanics that recur without erasing those distinctions.
|
||||
its exhaustion through a provider-neutral sentinel. LLM-002 closes an
|
||||
admission/cancellation race without combining these limits or moving provider
|
||||
capacity policy into the pipeline worker pools.
|
||||
- `internal/modules/dnd/chunk/scenes.planFromResponse` intentionally keeps the
|
||||
whole-source coverage policy explicit in one pass: it resolves opaque unit
|
||||
IDs through the shared document index, compares document positions rather
|
||||
than numeric IDs, rejects reversed ranges, gaps, and overlaps, and requires
|
||||
exact first-to-last coverage before the framework independently canonicalizes,
|
||||
validates, and materializes the plan. Its repeated-looking resolve/position
|
||||
calls are constant-time index lookups that preserve contextual diagnostics;
|
||||
a generic range collector would hide scene-specific full-coverage policy.
|
||||
- `internal/modules/dnd/spells/catalog.composeEffectiveCatalog` intentionally
|
||||
uses separate canonical-name, per-spell alias, and complete lookup maps. The
|
||||
function validates base and overlay collisions while applying overlays in
|
||||
sorted ID order, then produces stable names and a semantic digest. Its nested
|
||||
loops traverse catalog entries and each entry's aliases without a linear scan
|
||||
inside the loop. DND-SCENE-001 concerns the later model-visible projection,
|
||||
not combining catalog composition with prompting or weakening collision
|
||||
checks.
|
||||
|
||||
## Areas Reviewed Without Findings
|
||||
|
||||
@@ -1895,14 +2016,13 @@ mechanics that recur without erasing those distinctions.
|
||||
comparison, diagnostics, resolution, and reconciliation. No additional
|
||||
callback- or reflection-driven helper reduced demonstrated drift.
|
||||
- **Deferred lane questions:** Registry identity, reconciliation, immutable
|
||||
projections, and occurrence-category/grounding policy are now confirmed,
|
||||
projections, occurrence-category/grounding policy, spell catalogs, scene
|
||||
chunking, scene identity, and scene classification are now confirmed,
|
||||
with DND-REG-001 through DND-REG-004 and DND-OCC-001 through DND-OCC-003
|
||||
recording the bounded gaps. Spell catalog, scene chunking, scene IDs, and
|
||||
scene classification remain assigned to the spells/scenes review; combat
|
||||
gates, engagement uniqueness, collective labels, and enemy observation
|
||||
ordering remain assigned to the combat/enemy review. This area therefore
|
||||
remains `Revisit` until those reviews confirm the remaining matrix
|
||||
exceptions.
|
||||
plus DND-SCENE-001 and DND-SCENE-002 recording the bounded gaps. Combat gates,
|
||||
engagement uniqueness, collective labels, and enemy observation ordering
|
||||
remain assigned to the combat/enemy review. This area therefore remains
|
||||
`Revisit` until that review confirms the remaining matrix exceptions.
|
||||
|
||||
### NPC, Item, And Location Registries
|
||||
|
||||
@@ -2012,6 +2132,59 @@ mechanics that recur without erasing those distinctions.
|
||||
order, and ownership; validator tests own pair, source, relatedness, and
|
||||
invariant defenses. The prescribed occurrence and CLI suites pass.
|
||||
|
||||
### Spells, Scene Chunking, And Scene Descriptions
|
||||
|
||||
- **Accepted scene-plan path:** The scene chunker validates the complete source,
|
||||
supplies the whole transcript after optional cached campaign context, and
|
||||
decodes only ordered start/end unit IDs. `planFromResponse` resolves those
|
||||
IDs against document positions and enforces non-empty, contiguous,
|
||||
non-overlapping first-to-last coverage. The framework then canonicalizes,
|
||||
validates, and materializes the plan before storing it. Only an accepted plan
|
||||
is serialized into the distinct chunk-map artifact with exact source,
|
||||
requested-chunker, producer, plan-digest, chunk-ID/range/count, and cloned
|
||||
annotation metadata; lane rejection does not erase that accepted structural
|
||||
artifact, while plan rejection publishes no chunk map. The D&D scene planner
|
||||
deliberately emits empty annotations rather than duplicating classification
|
||||
or source text, and the production contract verifies that separation.
|
||||
- **Scene-description identity and eligibility:** Extraction maps exactly one
|
||||
private kind/title/summary response onto the local current chunk ID and exact
|
||||
range, so the model cannot select or invent durable identity. Extract
|
||||
validation rechecks that exact chunk match; normalization uses source-document
|
||||
positions, rejects ID/range conflicts, and removes only exact duplicates.
|
||||
The immutable registry strictly decodes one approved artifact and projects
|
||||
only ID, complete range, and kind into a semantic eligibility digest. Its
|
||||
exact/missing/mismatched match state prevents title, summary, source prose,
|
||||
or registry provenance from becoming later combat evidence. DND-REG-001 and
|
||||
DND-SCENE-002 record the bounded codec and diagnostic exceptions.
|
||||
- **Spell catalog, grounding, and evidence:** Construction strictly decodes the
|
||||
optional single JSON overlay, composes it with the embedded 2014 SRD catalog
|
||||
in sorted overlay-ID order, rejects cross-spell canonical/alias collisions,
|
||||
and binds a semantic catalog digest to extractor, catalog-validator, and
|
||||
normalizer checkpoints. Optional NPC grounding is resolved independently and
|
||||
projected as source-free names; neither NPC nor catalog provenance becomes
|
||||
cast evidence. The extractor injects the current source ID, canonicalizes
|
||||
references and cast order, and the normalizer canonicalizes catalog names and
|
||||
reference order before collapsing only exact valid-evidence duplicates.
|
||||
DND-SCENE-001 records the missing model-visible alias mapping, DND-REG-002 the
|
||||
extraction chunk gate, and PIPE-002 the redundant construction copy.
|
||||
- **Validation, retries, and cache identity:** Default spell and scene chains
|
||||
preserve shape deferral, strict private and durable schemas, source-aware
|
||||
rejection, advisory relatedness, and normalization invariants. Catalog
|
||||
rejection participates in the framework's bounded retry path, terminal
|
||||
accepted-attempt warnings are retained, and rejected-attempt warnings are
|
||||
suppressed as intended. Raw reference dependencies bind provenance/content,
|
||||
while semantic catalog and NPC/scene projections bind behavior; focused CLI
|
||||
tests prove catalog, mapping-policy, prompt/profile, and generated-reference
|
||||
changes prevent stale checkpoint reuse.
|
||||
- **Prompt and test ownership:** Scene planning follows the intentional D&D
|
||||
prompt order of system, cacheable campaign references, uncached task
|
||||
instructions/schema, and final ephemeral whole transcript. Per-chunk scene
|
||||
descriptions and spells use the shared current-chunk evidence fragments;
|
||||
local response schemas expose no source IDs or chunk IDs. Focused assets,
|
||||
codecs, extractors, normalizers, validators, registries, catalog composition,
|
||||
checkpoint/retry, and production chunk-map tests cover the reviewed contracts,
|
||||
and the prescribed package suite passes.
|
||||
|
||||
## Validation Record
|
||||
|
||||
| Date | Scope | Command or check | Result |
|
||||
@@ -2065,6 +2238,9 @@ mechanics that recur without erasing those distinctions.
|
||||
| 2026-08-08 | Occurrence-family graph/code review | Exact symbol reads, complexity queries, and call traces across NPC, item, and location semantic registry projections/resolution, response adaptation, current-source evidence attachment, canonical ordering/deduplication, normalization, validation, codecs, prompt assets, private schemas, and generated-reference tests | DND-OCC-001 through DND-OCC-003 recorded and DND-REG-001 broadened; all-or-nothing identity attachment, evidence separation, category/holder/quantity/same-name policy, nil/empty ownership, and handoff behavior otherwise confirmed |
|
||||
| 2026-08-08 | Required NPC, item, and location occurrence tests | `go test ./internal/modules/dnd/extract/npcoccurrences ./internal/modules/dnd/extract/itemoccurrences ./internal/modules/dnd/extract/locationoccurrences ./internal/modules/dnd/normalize/npcoccurrences ./internal/modules/dnd/normalize/itemoccurrences ./internal/modules/dnd/normalize/locationoccurrences ./internal/modules/dnd/validate/npcoccurrences/... ./internal/modules/dnd/validate/itemoccurrences/... ./internal/modules/dnd/validate/locationoccurrences/...` | Pass |
|
||||
| 2026-08-08 | Generated occurrence handoff tests | `go test ./internal/cli` | Pass |
|
||||
| 2026-08-08 | Audit target integrity before spell/scene-family review | `git diff --quiet 92e89076a268089e703978fb9d7176200e93344c..HEAD -- . ':(exclude)docs/roadmap/**'` | Pass; production target unchanged |
|
||||
| 2026-08-08 | Spell and scene graph/code review | Scoped architecture, exact symbol reads, complexity inspection, and call traces across whole-source scene planning, framework plan canonicalization/materialization, chunk-map serialization/publication, per-chunk scene extraction, normalization, validation and eligibility projection, effective spell catalog composition, NPC grounding, response canonicalization, normalization, validation, checkpoint identity, retry, codecs, prompt assets, schemas, and focused tests | DND-SCENE-001 and DND-SCENE-002 recorded; DND-REG-001, DND-REG-002, and PIPE-002 broadened; structural/evidence separation, exact scene eligibility, and catalog/checkpoint behavior otherwise confirmed |
|
||||
| 2026-08-08 | Required spell, scene chunking, and scene-description tests | `go test ./internal/modules/dnd/chunk/scenes ./internal/modules/dnd/extract/scenedescriptions ./internal/modules/dnd/normalize/scenedescriptions ./internal/modules/dnd/validate/scenedescriptions/... ./internal/modules/dnd/scenedescriptions/... ./internal/modules/dnd/extract/spells ./internal/modules/dnd/normalize/spells ./internal/modules/dnd/validate/spells/... ./internal/modules/dnd/spells/...` | Pass |
|
||||
|
||||
## Coverage Matrix
|
||||
|
||||
@@ -2081,6 +2257,6 @@ mechanics that recur without erasing those distinctions.
|
||||
| Shared D&D types, codecs, and family mechanics | Revisit | D&D internal/module docs and all D&D integration contracts; root durable types; all ten codec packages and candidate JSON; shared references, ordering, citations, inputs, comparison, diagnostics, registry resolver, entity reconciliation, and assets; typed merger/evidence/default-chain/fallback/family registration; representative module asset declarations and focused tests | Target-integrity check, scoped graph architecture/search/traces, ten-family convention matrix, required codec/shared/register tests | DND-CORE-001 |
|
||||
| NPC, item, and location registries | Reviewed | NPC/item/location registry integration contracts and relevant identity/evidence ADRs; extractors, candidate models and response schemas; identity, immutable registry, prompt/identity projection, location grounding, reconciliation, normalizer, validators, codecs, prompt assets, and focused tests for all three families | Target-integrity check, scoped graph architecture/complexity/search/traces, full family comparison, required extractor/identity/registry/normalizer/validator tests | DND-REG-001, DND-REG-002, DND-REG-003, DND-REG-004 |
|
||||
| NPC, item, and location occurrences | Reviewed | NPC/item/location occurrence integration contracts and deterministic opaque-ID ADR; extractors, private response models/schemas, semantic registry projections and resolvers, canonicalizers, normalizers, validator chains, codecs, prompt assets, and generated/external registry handoff tests for all three families | Target-integrity check, scoped graph architecture/complexity/search/traces, full family comparison, required extractor/normalizer/validator tests, generated CLI handoff tests | DND-REG-001, DND-OCC-001, DND-OCC-002, DND-OCC-003 |
|
||||
| Spells, scene chunking, and scene descriptions | Pending | — | — | — |
|
||||
| Spells, scene chunking, and scene descriptions | Reviewed | Spell, overlay, scene-description, and accepted chunk-map integration contracts; D&D scene chunker and prompt/schema assets; framework plan canonicalization, validation, materialization, accepted chunk-map serialization/publication and production tests; scene-description extractor, normalizer, validators, immutable eligibility registry, codec, prompts, schemas, and tests; spell extractor, effective/base/overlay catalogs, NPC grounding, canonicalizer, normalizer, validators, codec, prompts, schemas, checkpoint/retry/CLI tests | Target-integrity check, scoped graph architecture/complexity/symbol/call review, full family comparison, required chunker/extractor/normalizer/validator/registry/catalog tests | PIPE-002, DND-REG-001, DND-REG-002, DND-SCENE-001, DND-SCENE-002 |
|
||||
| Combat turns and enemy events | Pending | — | — | — |
|
||||
| Test ownership, comments, and final synthesis | Pending | — | — | — |
|
||||
|
||||
Reference in New Issue
Block a user