fix(simulation): address PR #39 review — 3 warnings + 6 suggestions

Warnings fixed:
- contraband.rs: scan event now always emits even when NPC already
  knows (was skipped by early `continue`). Contract matches doc.
- test_world/mod.rs: ScanEventBuffer added to player spawn bundle
  so check_contraband_scan doesn't silently no-op in gauntlet mode.
- npc/mod.rs → simulation/mod.rs: moved check_contraband_scan
  registration to SimulationPlugin (operates on player inventory and
  snapshot pipeline, consistent with process_talk_interaction).

Suggestions addressed:
- cross_room_transitions.rs T1: clarified standalone position vs
  constants.rs observer position in comment.
- dialogue.rs: Vec<&str> dedup replaced with BTreeSet<&str> for
  deterministic iteration (project convention).
- contraband.rs: added test for multiple simultaneous ScanAuthority
  NPCs in range (564 tests total).
- dialogue.rs: doc-comment on relationship_to_trust explaining
  KnowledgeConfidence ordering and Suspects default.
- cross_room_transitions.rs T5: noted direct KG API usage vs full
  perception system.
- sprint_gauntlet.rs: documented intentional Contentment { level: 0 }.
- content_scaling.rs: noted GAUNTLET_NPC_COUNT is manually maintained.
- contraband.rs: doc-comment on cross-plugin registration rationale.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-19 12:23:02 +01:00
co-authored by Claude Opus 4.6
parent bee93963d9
commit 258b266f15
8 changed files with 135 additions and 44 deletions
+3
View File
@@ -47,6 +47,9 @@ const STRESS_TICKS: usize = 100;
/// Fog Theater: 4, Occlusion Corridor: 4, Inventory Warehouse: 1, Pause Chamber: 1,
/// Dialogue Room: 4, Crowd Plaza: 15, Sprint Gauntlet: 1, Eavesdrop Alcove: 2,
/// Confrontation Stage: 2 = 34 total.
///
/// Manually maintained — update when rooms are added/changed. Future: derive
/// from StableId ranges in constants.rs to avoid manual sync.
const GAUNTLET_NPC_COUNT: usize = 34;
/// Extra NPCs to spawn on top of the Gauntlet baseline to reach Active tier ceiling.
+9 -4
View File
@@ -63,8 +63,9 @@ fn run_listening_system(world: &mut World) {
/// T1 — Sprint Exit.
///
/// Player at Sprint Gauntlet observer position (4, 12 absolute) with Walk
/// stance. A Readable sign at (6, 12) is within CLOSE_RANGE (distance 2).
/// Player at (4, 12 absolute) — standalone scenario position south of the
/// Sprint Gauntlet observer (4, 10 per constants.rs). A Readable sign at
/// (6, 12) is within CLOSE_RANGE (distance 2).
///
/// During Walk: sign appears in interaction buffer.
/// During Sprint: buffer is empty (D-055 suppression).
@@ -365,13 +366,17 @@ fn t4_knowledge_graph_survives_room_transition() {
/// T5 — Fog Carry-Over.
///
/// Player observes NPC in Fog Theater at Direct confidence.
/// Player moves to Hub (NPC now out of LOS). Observation system simulates
/// the confidence downgrade: Direct KnowsDetails.
/// Player moves to Hub (NPC now out of LOS). Confidence downgrades
/// from Direct to KnowsDetails.
///
/// Asserts: KG entry persists (entity is remembered, not erased).
/// Server-side "fog carry-over" means previously-seen entities remain in
/// the KG at reduced confidence so the client can render a "last seen"
/// fog state rather than a clean erasure.
///
/// NOTE: Uses direct KG API calls (observe_entity, observe_entity_leaving_los)
/// rather than running the full perception system. This isolates the KG
/// persistence contract from perception scheduling.
#[test]
fn t5_entity_knowledge_downgrades_on_los_exit_not_erased() {
use settled_reach_server::knowledge::types::KnowledgeConfidence;