feat(simulation): knowledge grant schema, events, and contradiction detection (#545, #546, #547)

KnowledgeGrant untagged enum (Fact + Entity variants), ContentEntityRegistry
resource, KnowledgeGranted event processing, ContradictionClaim struct with
600-tick window detection in observe_entity. Wires knowledge_grant field in
dialogue line selection. Implements D-079, D-083. Closes Q-026.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-24 12:14:53 +01:00
co-authored by Claude Opus 4.6
parent 381526ff74
commit 3d636fd4bb
13 changed files with 1121 additions and 12 deletions
+9
View File
@@ -22,6 +22,7 @@ use std::collections::BTreeMap;
use crate::content::loader::{ContentStore, DistrictContent};
use crate::content::types;
use crate::knowledge::content_registry::ContentEntityRegistry;
use crate::knowledge::graph::KnowledgeGraph;
use crate::knowledge::registry::{EntityRegistry, StableEntityId};
use crate::knowledge::types::{
@@ -213,6 +214,12 @@ fn spawn_npc(world: &mut World, profile: &types::NpcProfile, result: &mut SpawnR
ContentSlug(profile.canonical_id.clone()),
));
// Register in ContentEntityRegistry so KnowledgeGrant::Entity can resolve entity_ref strings
// (D-079: ContentEntityRegistry populated at NPC spawn time)
world
.resource_mut::<ContentEntityRegistry>()
.register(profile.canonical_id.clone(), stable_id);
result
.npc_ids
.insert(profile.canonical_id.clone(), stable_id);
@@ -296,6 +303,7 @@ fn resolve_information(
source: KnowledgeSource::Background,
state: KnowledgeState::Active,
acquired_tick: 0,
disclosure_blocked: false,
},
)
})
@@ -648,6 +656,7 @@ mod tests {
fn create_test_world() -> World {
let mut world = World::new();
world.init_resource::<EntityRegistry>();
world.init_resource::<ContentEntityRegistry>();
world
}