feat(simulation): contraband detection + dialogue confidence gate (D-075) (#425, #524)

Contraband detection (Task #425, D-065):
- New module: simulation/contraband.rs — NPC scan checks carried items
  against the KnowledgeGraph confidence gate. NPCs with Authority access
  can initiate a scan; scan outcome depends on item CarriedBy + KG entry.
- Adds ContrabandScanResult event type and ContrabanEntry component.
- Wired into simulation/mod.rs module list.

Dialogue confidence gate (Task #524, D-075 — OQ-18 resolution):
- relationship_to_trust() gains confidence parameter (KnowledgeConfidence).
- Trust tier mapping: (Friendly, KnowsDetails+)→Secret, (Friendly|Known,
  KnowsOf+)→Real, otherwise Surface. Access tier (Layer 1) unchanged.
- Caller process_talk_interaction passes observer KG confidence_of target.
- Resolves OQ-18: confidence co-gates TrustTier, not AccessTier.

Supporting changes:
- decisions/content.md: add D-075 (16 decisions, dated 2026-02-19)
- knowledge/types.rs: expose KnowledgeConfidence comparison helpers
- knowledge/registry.rs: minor API polish
- bridge/types.rs: ContrabandScanResult wire type
- bridge/text_renderer.rs: render contraband scan status
- perception/observer: include carried item count in snapshot
- npc/mod.rs: NPC scan range constant, authority flag

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-19 11:12:24 +01:00
co-authored by Claude Sonnet 4.6
parent 54754e4080
commit d103e445e7
12 changed files with 670 additions and 46 deletions
+10 -3
View File
@@ -474,7 +474,10 @@ fn handle_confront(
target: target_entity,
});
tracing::debug!(target_id, "Confront: ConfrontationDelivered marker set on player");
tracing::debug!(
target_id,
"Confront: ConfrontationDelivered marker set on player"
);
}
/// Handle Place verb: remove an item from inventory and place it on the ground
@@ -1850,7 +1853,9 @@ mod tests {
schedule.add_systems(process_player_input);
schedule.run(&mut world);
let pos = world.get::<TilePosition>(player).expect("player has position");
let pos = world
.get::<TilePosition>(player)
.expect("player has position");
let hub_spawn = crate::test_world::constants::HUB.spawn;
assert_eq!(pos.x, hub_spawn.x, "player x at hub spawn");
assert_eq!(pos.y, hub_spawn.y, "player y at hub spawn");
@@ -1979,7 +1984,9 @@ mod tests {
schedule.add_systems(process_player_input);
schedule.run(&mut world);
let pos = world.get::<TilePosition>(player).expect("player has position");
let pos = world
.get::<TilePosition>(player)
.expect("player has position");
let hub_spawn = crate::test_world::constants::HUB.spawn;
assert_eq!(pos.x, hub_spawn.x, "teleport works while paused");
}