Audit combat and enemy event processing
This commit is contained in:
@@ -20,9 +20,10 @@ 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, 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,
|
||||
LLM, generic/Seriatim, shared D&D, registry-family, occurrence-family,
|
||||
spell/scene-family, and combat/enemy-family reviews have found three High
|
||||
findings, seven 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.
|
||||
@@ -57,14 +58,15 @@ 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 and spell extraction evidence inside the current chunk |
|
||||
| DND-REG-003 | Low | Efficiency | Index item and location duplicate groups |
|
||||
| DND-REG-002 | Low | Correctness | Keep extraction evidence inside the current chunk |
|
||||
| DND-REG-003 | Low | Efficiency | Index duplicate groups across D&D families |
|
||||
| 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 |
|
||||
| DND-SCENE-002 | Low | Correctness | Make D&D normalization and advisory diagnostics complete and bounded |
|
||||
| DND-COMBAT-001 | Medium | Correctness | Enforce enemy-event semantics at the durable codec boundary |
|
||||
|
||||
## Findings
|
||||
|
||||
@@ -876,26 +878,31 @@ Final cross-area ordering is pending synthesis.
|
||||
|
||||
- **Severity:** Low
|
||||
- **Category:** Correctness
|
||||
- **Evidence:** The three registry, three occurrence, spell, and scene-
|
||||
description integration contracts require that a source range's start not
|
||||
follow its end
|
||||
- **Evidence:** The three registry, three occurrence, spell, scene-description,
|
||||
combat-turn, and enemy-event 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`,
|
||||
`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
|
||||
`dnd-spell-artifacts.md:31`–`35`,
|
||||
`dnd-scene-description-artifacts.md:33`–`35`,
|
||||
`dnd-combat-turn-artifacts.md:31`–`33`, and
|
||||
`dnd-enemy-event-artifacts.md:33`–`35`). Nine of the ten durable codecs check
|
||||
at most 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`,
|
||||
`codec/locationoccurrences/codec.go:100`–`110`,
|
||||
`codec/spells/codec.go:89`–`99`, and
|
||||
`codec/scenedescriptions/codec.go:101`–`109`). Direct registry references are
|
||||
`codec/spells/codec.go:89`–`99`,
|
||||
`codec/scenedescriptions/codec.go:101`–`109`, and
|
||||
`codec/combatturns/codec.go:95`–`106`); the enemy-event codec checks only JSON
|
||||
field presence and accepts even non-positive endpoints
|
||||
(`codec/enemyevents/codec.go:86`–`135`). 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
|
||||
@@ -912,12 +919,14 @@ Final cross-area ordering is pending synthesis.
|
||||
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
|
||||
retain the impossible interval as eligibility metadata. A malformed combat-
|
||||
turn artifact can likewise be accepted for enemy grounding, whose compact
|
||||
projection then strips the malformed provenance; 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 eight reviewed codecs' durable
|
||||
`start_unit_id <= end_unit_id` to all ten 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
|
||||
@@ -926,52 +935,64 @@ 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 eight
|
||||
reviewed families, a location identity case that refuses a reversed-only
|
||||
anchor, and direct registry, occurrence, spell, and scene-eligibility
|
||||
reference cases proving malformed referenced JSON is rejected; run the
|
||||
- **Validation:** Add codec encode/decode cases for reversed ranges in all ten
|
||||
families, a location identity case that refuses a reversed-only
|
||||
anchor, and direct registry, occurrence, spell, scene-eligibility, combat-
|
||||
turn, and enemy-event reference cases proving malformed referenced JSON is
|
||||
rejected; run the
|
||||
codec, identity, registry, spell, scene, occurrence, and assembled CLI suites.
|
||||
- **Grouping:** Independent.
|
||||
- **Grouping:** Coordinate the enemy-event codec change with DND-COMBAT-001;
|
||||
the remaining nine codec changes are otherwise independent.
|
||||
|
||||
### DND-REG-002 — Keep NPC and spell extraction evidence inside the current chunk
|
||||
### DND-REG-002 — Keep extraction evidence inside the current chunk
|
||||
|
||||
- **Severity:** Low
|
||||
- **Category:** Correctness
|
||||
- **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
|
||||
- **Evidence:** The NPC, item, location, spell, combat-turn, and enemy-event
|
||||
extractors receive only the current chunk, and all six 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.
|
||||
The spell validator has the same document-only behavior
|
||||
(`validate/spells/source_refs/validator.go:35`–`51`). Its tests exercise
|
||||
The spell and combat-turn validators have the same document-only behavior
|
||||
(`validate/spells/source_refs/validator.go:35`–`51` and
|
||||
`validate/combatturns/source_refs/validator.go:36`–`60`), while the enemy-
|
||||
event validator correctly requires an extraction chunk and checks every
|
||||
unit in each range (`validate/enemyevents/source_refs/validator.go:37`–`99`).
|
||||
Spell and combat-turn 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
|
||||
off-chunk range (`validate/spells/source_refs/validator_test.go:15`–`73` and
|
||||
`validate/combatturns/source_refs/validator_test.go:15`–`73`).
|
||||
- **Impact:** If an NPC, spell, or combat-turn 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
|
||||
actor, 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 and spell references
|
||||
current chunk when `req.Stage` is extract and reject NPC, spell, and combat-
|
||||
turn 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 and spell source-reference cases for an existing off-
|
||||
- **Validation:** Add NPC, spell, and combat-turn 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.
|
||||
normalize-stage validation without a chunk; run the affected source-reference
|
||||
validators, their extractors, and assembled pipeline tests; retain the enemy-
|
||||
event in-chunk, off-chunk, and missing-chunk cases as the reference behavior.
|
||||
- **Grouping:** Independent.
|
||||
|
||||
### DND-REG-003 — Index item and location duplicate groups
|
||||
### DND-REG-003 — Index duplicate groups across D&D families
|
||||
|
||||
- **Severity:** Low
|
||||
- **Category:** Efficiency
|
||||
@@ -982,25 +1003,38 @@ Final cross-area ordering is pending synthesis.
|
||||
comparison key. `exactDuplicateGroups` in
|
||||
`normalize/locationregistry/normalizer.go:229`–`246` repeats that nested scan
|
||||
and performs `reflect.DeepEqual` over canonical source-reference slices for
|
||||
each candidate group. With distinct records, both paths are quadratic before
|
||||
any LLM reconciliation request is built.
|
||||
- **Impact:** Large merged registries spend avoidable deterministic CPU in
|
||||
each candidate group. Enemy-event normalization likewise scans all retained
|
||||
events for every record and calls exact equality, which recanonicalizes both
|
||||
evidence lists (`normalize/enemyevents/normalizer.go:207`–`227` and
|
||||
`enemyevents/enemyevents.go:42`–`64`); its invariant validator repeats a
|
||||
previous-event scan at `validate/enemyevents/invariants/validator.go:138`–`145`.
|
||||
The knowledge graph reports loop depth two and transitive loop depth four for
|
||||
enemy `collapseDuplicates`. With distinct records, all four paths are
|
||||
quadratic.
|
||||
- **Impact:** Large merged registries or enemy observation lists spend
|
||||
avoidable deterministic CPU in
|
||||
normalization, with the location cost also proportional to citation-list
|
||||
comparisons. Normal registry sizes and the later LLM request dominate today,
|
||||
so the issue is low severity.
|
||||
comparisons. Normal artifact sizes bound the impact, and registry
|
||||
reconciliation's later LLM request dominates its two paths today, so the
|
||||
issue is low severity.
|
||||
- **Recommendation:** Preserve first-seen group order while maintaining a local
|
||||
index from the complete duplicate identity to its group position. Use the
|
||||
existing comparison key for items and an exact, collision-safe key over the
|
||||
comparison name plus canonical source-reference sequence for locations;
|
||||
verify equality on any hash collision rather than using lossy concatenation.
|
||||
apply the same collision-safe complete identity index to enemy events in both
|
||||
normalization and invariant validation. Verify equality on any hash
|
||||
collision rather than using lossy concatenation.
|
||||
- **Preserve:** Item duplicates remain name-identity duplicates regardless of
|
||||
evidence; locations collapse only equal comparison names with exactly equal
|
||||
canonical evidence; group/member order, input-index provenance, warning
|
||||
scopes, and later proposal-only semantic reconciliation remain unchanged.
|
||||
Enemy events continue to collapse only equal normalized subject identity,
|
||||
kind, and complete canonical evidence; different outcomes, evidence, and
|
||||
repeated observations remain distinct.
|
||||
- **Validation:** Add many-distinct and repeated-key cases that compare output
|
||||
groups and warning order with current fixtures, plus a focused benchmark or
|
||||
comparison-count hook demonstrating linear expected grouping work; run the
|
||||
item and location normalizer tests.
|
||||
item and location normalizer tests plus enemy normalizer and invariant tests.
|
||||
- **Grouping:** Independent.
|
||||
|
||||
### DND-REG-004 — Select location identity anchors without sorting
|
||||
@@ -1182,7 +1216,7 @@ Final cross-area ordering is pending synthesis.
|
||||
validator, and CLI suites.
|
||||
- **Grouping:** Independent.
|
||||
|
||||
### DND-SCENE-002 — Make scene and spell normalization diagnostics complete and bounded
|
||||
### DND-SCENE-002 — Make D&D normalization and advisory diagnostics complete and bounded
|
||||
|
||||
- **Severity:** Low
|
||||
- **Category:** Correctness
|
||||
@@ -1198,26 +1232,79 @@ Final cross-area ordering is pending synthesis.
|
||||
(`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`).
|
||||
(`normalizer_test.go:15`–`43`). Combat-turn normalization also emits per-
|
||||
actor, per-reference, per-reorder, and per-duplicate-group warnings without
|
||||
applying the shared limiter (`normalize/combatturns/normalizer.go:131`–`188`
|
||||
and 235–273). Its advisory relatedness validator returns one warning per
|
||||
unrelated turn without a limiter
|
||||
(`validate/combatturns/source_relatedness/validator.go:45`–`67`), whereas
|
||||
both enemy-event equivalents use `diagnostics.LimitWarnings`.
|
||||
- **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
|
||||
Combat lists can have the same warning amplification. 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
|
||||
- **Recommendation:** Pass spell and combat-turn normalization warnings and
|
||||
combat-turn relatedness warnings through the shared deterministic limiter
|
||||
with stable omission reasons. 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.
|
||||
- **Validation:** Add spell, combat-normalizer, and combat-relatedness cases
|
||||
beyond `diagnostics.MaxWarnings` that assert stable omission summaries, and
|
||||
scene cases for each mutation, combined overflow, canonical input, and
|
||||
idempotence; run all affected normalizer/validator suites and assembled
|
||||
output/checkpoint warning tests.
|
||||
- **Grouping:** Independent.
|
||||
|
||||
### Combat Turns And Enemy Events
|
||||
|
||||
### DND-COMBAT-001 — Enforce enemy-event semantics at the durable codec boundary
|
||||
|
||||
- **Severity:** Medium
|
||||
- **Category:** Correctness
|
||||
- **Evidence:** The enemy-event contract and embedded durable schema require a
|
||||
non-empty subject, one of five event kinds, at least one source reference,
|
||||
and a non-empty source ID with positive endpoints
|
||||
(`docs/integrations/dnd-enemy-event-artifacts.md:19`–`35` and
|
||||
`internal/modules/dnd/codec/enemyevents/assets/schemas/dnd_enemy_events.v1.json:4`–`34`).
|
||||
`Codec.Decode` checks strict JSON and literal field presence, but
|
||||
`validateRequiredJSONFields` does not enforce any of those value constraints;
|
||||
`Codec.Encode` checks only that the event and reference slices are non-nil
|
||||
(`codec/enemyevents/codec.go:52`–`95` and 98–160). The focused codec test
|
||||
explicitly proves durable `Decode` accepts a whitespace name, unsupported
|
||||
kind, blank source ID, zero start, and negative end
|
||||
(`codec/enemyevents/codec_test.go:76`–`92`). The combat-turn codec, by
|
||||
contrast, enforces all equivalent value constraints except the separately
|
||||
recorded reversed-range condition (`codec/combatturns/codec.go:80`–`108`).
|
||||
- **Impact:** A direct enemy-event artifact decode can report contract-invalid
|
||||
JSON as approved typed data. More importantly, the supported validator-
|
||||
override surface can replace both family validation chains; a model response
|
||||
with these invalid values can then reach durable output because the final
|
||||
codec encode does not re-establish its published schema. Default chains
|
||||
reject the values, so maintained production configuration is protected.
|
||||
- **Recommendation:** Preserve candidate encode/decode as the permissive retry
|
||||
boundary, but make durable `Encode` and `Decode` apply one shared value
|
||||
validator covering the schema's name, kind, non-empty references, source ID,
|
||||
and positive endpoint constraints. Also apply the forward-range check in
|
||||
DND-REG-001. Keep the raw-object presence pass on decode where omitted versus
|
||||
zero-valued JSON fields must remain distinguishable.
|
||||
- **Preserve:** Retain strict unknown-field and trailing-value rejection,
|
||||
defensive source-reference ownership, empty top-level event lists, candidate
|
||||
preservation before validators, and document/chunk membership checks in the
|
||||
source-aware validator rather than the codec.
|
||||
- **Validation:** Replace the semantic-acceptance durable codec case with
|
||||
paired candidate-preservation and durable-rejection cases for every field,
|
||||
including empty and reversed reference ranges. Add an assembled lane case
|
||||
showing permissive validator overrides still cannot publish schema-invalid
|
||||
enemy events; run the codec, enemy-event, pipeline, and CLI suites.
|
||||
- **Grouping:** Coordinate with DND-REG-001; that finding owns the common
|
||||
forward-range gap, while this finding owns enemy-event schema enforcement.
|
||||
|
||||
<!--
|
||||
Finding template for later audit stages:
|
||||
|
||||
@@ -1249,16 +1336,16 @@ family-owned, uses media type `application/json`, embeds its own v1 durable
|
||||
schema, publishes count metadata, and has a registered direct-source-reference
|
||||
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 |
|
||||
| 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 review result |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| 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. |
|
||||
| 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 | Confirmed: exact combat classification alone enables prompting; exact non-combat and unavailable classifications produce accepted empty lists, with one warning only for unavailable classification. NPC names remain optional source-free grounding. DND-REG-001, DND-REG-002, and DND-SCENE-002 record codec, chunk-evidence, and warning gaps. |
|
||||
| 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 | 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. |
|
||||
| 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 | Confirmed: exact combat gating precedes prompt grounding; compact NPC, combat-turn, and opponent-occurrence projections contain no evidence or opaque IDs; extraction admits one engagement per comparison identity, while normalization preserves later observations and orders them by chronology, subject, kind, and evidence. DND-REG-001, DND-REG-003, and DND-COMBAT-001 record codec and duplicate-work gaps. |
|
||||
| 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. |
|
||||
|
||||
@@ -1344,6 +1431,17 @@ mechanics that recur without erasing those distinctions.
|
||||
production policy. Later D&D stages may evaluate individual shared
|
||||
mechanics, but should not replace these lists with a dynamically typed
|
||||
registration engine.
|
||||
- Combat-turn and enemy-event extractors deliberately own separate explicit
|
||||
scene gates. Both consult the same immutable eligibility registry before any
|
||||
LLM call, but the enemy lane must then resolve three required source-free
|
||||
grounding projections while combat turns have only optional NPC grounding.
|
||||
A callback-driven shared extractor would obscure required-reference and
|
||||
empty-result ownership without removing meaningful policy duplication.
|
||||
- Enemy engagement uniqueness deliberately belongs only to extraction. One
|
||||
chunk represents one classified combat scene, so a comparison-key map can
|
||||
reject repeated `engaged` observations there; the merged/normalized artifact
|
||||
may contain later engagements for the same subject in separate scenes and
|
||||
must preserve them rather than apply a terminal-state model.
|
||||
- `internal/framework/pipeline.RegisterArtifactCodec` and
|
||||
`exactTypedValue` perform apparently repetitive exact-type checks around
|
||||
private erasure. The checks deliberately turn incompatible values into
|
||||
@@ -2015,14 +2113,14 @@ mechanics that recur without erasing those distinctions.
|
||||
helpers already consolidate prompt assets, candidate JSON, reference slots,
|
||||
comparison, diagnostics, resolution, and reconciliation. No additional
|
||||
callback- or reflection-driven helper reduced demonstrated drift.
|
||||
- **Deferred lane questions:** Registry identity, reconciliation, immutable
|
||||
- **Completed lane questions:** Registry identity, reconciliation, immutable
|
||||
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
|
||||
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.
|
||||
chunking, scene identity/classification, combat gates, engagement uniqueness,
|
||||
collective labels, and enemy observation ordering are now confirmed. The
|
||||
convention matrix records every family exception, with DND-CORE-001,
|
||||
DND-REG-001 through DND-REG-004, DND-OCC-001 through DND-OCC-003,
|
||||
DND-SCENE-001, DND-SCENE-002, and DND-COMBAT-001 recording the bounded gaps.
|
||||
No shared D&D question remains deferred to the final synthesis.
|
||||
|
||||
### NPC, Item, And Location Registries
|
||||
|
||||
@@ -2185,6 +2283,51 @@ mechanics that recur without erasing those distinctions.
|
||||
checkpoint/retry, and production chunk-map tests cover the reviewed contracts,
|
||||
and the prescribed package suite passes.
|
||||
|
||||
### Combat Turns And Enemy Events
|
||||
|
||||
- **Eligibility and extraction:** Both extractors prepare the current chunk and
|
||||
consult the immutable scene-description registry before prompt construction.
|
||||
Only an exact `combat` match reaches the model; an exact non-combat match
|
||||
returns an accepted present-empty list, while a missing/mismatched match adds
|
||||
exactly one bounded `scene_classification_unavailable` warning. Scene title,
|
||||
summary, evidence, and provenance never enter either model input or output
|
||||
evidence.
|
||||
- **Grounding and identity:** Combat turns optionally project canonical NPC
|
||||
names without copying registry references. Enemy events require normalized
|
||||
NPCs, scene eligibility, combat turns, and NPC occurrences, but project only
|
||||
NPC names, combat actor/kind pairs, and named `combat_opponent` occurrence
|
||||
pairs. The prompt and maintained CLI test exclude source ranges and opaque
|
||||
IDs from these projections; unmatched transcript-grounded actors and narrow
|
||||
collective enemy labels remain valid durable display subjects.
|
||||
- **Canonicalization and validation:** Extractors inject the current source ID,
|
||||
canonicalize exact reference order/deduplication, and order candidates by
|
||||
valid document chronology while preserving malformed candidates for their
|
||||
validators. Combat normalization uses a collision-safe complete duplicate
|
||||
key; enemy normalization applies explicit chronology, subject identity,
|
||||
display, kind, and evidence ordering and collapses only exact observations.
|
||||
Shape, source, relatedness, normalized-invariant, and extract-only engagement
|
||||
validators retain their documented ownership. DND-REG-002 records combat's
|
||||
missing extraction-chunk check; DND-REG-003 records enemy's pairwise exact-
|
||||
duplicate work; DND-SCENE-002 records combat warning bounds.
|
||||
- **Handoffs, retries, and publication:** The maintained three-step example
|
||||
produces NPC and scene artifacts before combat/NPC occurrences, then binds all
|
||||
four approved generated artifacts into enemy extraction and the NPC registry
|
||||
into normalization. Pipeline reference identities, module prompt/schema/
|
||||
policy fingerprints, bounded extraction retries, rejection suppression, and
|
||||
accepted checkpoint hydration apply unchanged. Focused CLI execution proves
|
||||
only the classified combat chunk prompts for enemy events and publishes typed
|
||||
combat/enemy JSON plus direct evidence context. DND-REG-001 and
|
||||
DND-COMBAT-001 record the remaining durable codec gaps.
|
||||
- **Tests and complexity:** Extractor fixtures cover exact/non-combat/missing/
|
||||
mismatched gates, source-free grounding, generated references, chronology,
|
||||
malformed candidates, and metadata; normalizer/validator fixtures cover
|
||||
canonical names, reference and event order, exact duplicate identity,
|
||||
engagement uniqueness, collective subjects, warning bounds where implemented,
|
||||
and idempotence. Graph traces and complexity inspection found no unbounded
|
||||
family loop; the intentional generated-reference sequencing is linear, while
|
||||
the pairwise enemy duplicate paths are isolated in DND-REG-003. All prescribed
|
||||
family and CLI tests pass.
|
||||
|
||||
## Validation Record
|
||||
|
||||
| Date | Scope | Command or check | Result |
|
||||
@@ -2241,6 +2384,12 @@ mechanics that recur without erasing those distinctions.
|
||||
| 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 |
|
||||
| 2026-08-08 | Audit target integrity before combat/enemy review | `git diff --quiet 92e89076a268089e703978fb9d7176200e93344c..HEAD -- . ':(exclude)docs/roadmap/**'` | Pass; production target unchanged |
|
||||
| 2026-08-08 | Combat and enemy graph/code review | Scoped architecture, exact symbol reads, complexity inspection, and call traces across scene gates, optional NPC grounding, required enemy projections, response mapping, chronology, normalization/deduplication, extract/normalize validator chains, engagement identity, codecs, prompts, private schemas, generated references, retry/checkpoint identity, maintained CLI example, and focused tests | DND-COMBAT-001 recorded; DND-REG-001 through DND-REG-003 and DND-SCENE-002 broadened; exact eligibility, source-free grounding, collective labels, engagement uniqueness, observation preservation/order, and generated handoffs otherwise confirmed |
|
||||
| 2026-08-08 | Required combat-turn and enemy-event tests | `go test ./internal/modules/dnd/extract/combatturns ./internal/modules/dnd/normalize/combatturns ./internal/modules/dnd/validate/combatturns/... ./internal/modules/dnd/extract/enemyevents ./internal/modules/dnd/normalize/enemyevents ./internal/modules/dnd/validate/enemyevents/... ./internal/modules/dnd/enemyevents` | Pass |
|
||||
| 2026-08-08 | Combat and enemy durable codec tests | `go test ./internal/modules/dnd/codec/combatturns ./internal/modules/dnd/codec/enemyevents` | Pass |
|
||||
| 2026-08-08 | Assembled combat and generated-reference integration tests | `go test ./internal/modules/integration/...` | Pass |
|
||||
| 2026-08-08 | Generated combat/enemy handoff and publication tests | `go test ./internal/cli` | Pass |
|
||||
|
||||
## Coverage Matrix
|
||||
|
||||
@@ -2254,9 +2403,9 @@ mechanics that recur without erasing those distinctions.
|
||||
| State, checkpoints, debugging, and file safety | Reviewed | State and operations docs plus architecture state/security policy; CLI output, cache-root, checkpoint identity, recomputation, debug allocation, and terminal owners; core file I/O, debug bundle, and source digest/clone helpers; framework checkpoint, chunk-plan, chunk-map, debug, evidence-context implementations and focused tests | Target-integrity check, graph architecture/complexity/call traces, state collaborator race tests, CLI tests | STATE-001, STATE-002, STATE-003 |
|
||||
| LLM runtime, prompt filesystems, and assets | Reviewed | LLM internal/integration/configuration/operations docs and related ADRs; scheduled client, scheduler, PromptKit adapter/profile inspector, profile/source fingerprints, redaction, debug, asset registry, schema loader, promptfs implementations and focused tests; root assets, fallback profile, all fourteen module manifests and prompt YAML files, shared/model-visible fragments, private response schemas, and representative composed loaders | Target-integrity check, graph architecture/symbol/call review, content scan and exact prompt-order comparison, focused race tests, composed CLI and D&D prompt-cache tests | LLM-001, LLM-002, LLM-003, LLM-004 |
|
||||
| Generic and Seriatim modules | Reviewed | Internal module guide; Seriatim, JSON output, chunk-map, and evidence-context integration contracts; all implementation/tests under `internal/modules/generic/` and `internal/modules/seriatim/`; framework evidence preparation/output paths and focused tests; maintained CLI example and production output contracts | Target-integrity check, graph architecture/symbol/call/caller review, direct import map, required module and codec tests, focused composed evidence/output tests | MOD-001, MOD-002, MOD-003 |
|
||||
| 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 |
|
||||
| Shared D&D types, codecs, and family mechanics | Reviewed | 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; all lane-specific identity, grounding, order, and eligibility exceptions | Target-integrity checks, scoped graph architecture/search/traces, completed ten-family convention matrix, required codec/shared/register and lane-family tests | DND-CORE-001, DND-REG-001, DND-COMBAT-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 | 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 | — | — | — |
|
||||
| Combat turns and enemy events | Reviewed | Combat/enemy integration contracts and D&D internals; extractors, scene/NPC resolvers, compact combat/opponent projections, canonicalizers, normalizers, shared enemy ordering/identity helpers, shape/source/relatedness/engagement/invariant validators, codecs, prompt assets, private schemas, focused and assembled integration tests, generated-reference CLI contracts, and maintained complete example | Target-integrity check, scoped graph architecture/complexity/symbol/call review, full family comparison, required extractor/normalizer/validator/helper tests, codec tests, assembled integration tests, generated CLI handoff/publication tests | DND-REG-001, DND-REG-002, DND-REG-003, DND-SCENE-002, DND-COMBAT-001 |
|
||||
| Test ownership, comments, and final synthesis | Pending | — | — | — |
|
||||
|
||||
Reference in New Issue
Block a user