Commit Graph
67 Commits
Author SHA1 Message Date
jpmschweitzerandClaude Opus 4.6 aa79dd97e7 fix(simulation): Clippy cleanup and CI enforcement (#635)
Fix all Clippy warnings across the server codebase (2411 insertions, 1341
deletions). Raise type-complexity-threshold to 750 and too-many-arguments
to 12 in .clippy.toml for idiomatic Bevy ECS system signatures. The server
now passes `cargo clippy -- --deny warnings` cleanly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 10:33:15 +01:00
jpmschweitzerandClaude Opus 4.6 51414b0b63 fix(simulation): address PR #89 review — version comment, settings contract, docs, dead process recovery
Must-fix: protocol version comment now references PROTOCOL_VERSION
(no hardcoded number), settings delete is idempotent no-op.

Suggestions addressed: BehaviorModifier dedup claim dropped, hash
collision safety documented, FK pragma in test store, columns_to_value
consolidated, modifier_hint mismatch logging, OffDuty test coverage,
batching tradeoff documented, unknown value_type warning, occluded
text risk documented, dead child respawn in voice worker, INJECT
block ambiguity documented.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:34:33 +01:00
jpmschweitzerandClaude Opus 4.6 accbe579c9 feat(simulation): SQLite settings storage with IPC protocol v20 (#627)
Per-player settings via rusqlite (bundled, zero runtime dep). Server
owns the settings DB; client sends ChangeSettings commands over IPC.
Extensible key-value with typed columns (String/Int/Float/Bool).
Protocol bumped to v20 with settings_response in ObserverSnapshot.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:11:53 +01:00
jpmschweitzerandClaude Sonnet 4.6 ce0df2f320 refactor(simulation): remove v0.1 content loading system (#655)
Delete the hand-authored YAML content pipeline (server/src/content/) superseded
by the v0.2 generator-first approach (D-122, D-128). Runtime ECS types that were
co-located with content loading have been extracted to dedicated simulation modules:

- simulation/triangle.rs: TriangleState, TriangleCrisisEventQueue, tick/resolve systems
- simulation/line_pool.rs: LinePoolIndex, AccessTier, TrustTier, Mood, LinePoolIndexResource
- simulation/knowledge_grant.rs: KnowledgeGrant, Prerequisites

Monologue systems (trigger_monologue, trigger_recognition_monologue,
trigger_event_monologue) now use hardcoded fallback lines only; the
ContentStoreResource branch and select_pool_line function are removed.

Deleted: content/{loader,types,line_pool,hot_reload,spawn,instantiation,entanglement,mod}.rs
Deleted: tests/{content_loading,content_runtime,content_scaling,template_instantiation,template_schema}.rs
Deleted: bin/line_preview.rs (v0.1 tool)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 09:07:57 +01:00
jpmschweitzerandClaude Opus 4.6 3194a6e491 feat(simulation): character archetype, tell escalation, and news ticker (#587, #589, #591)
- Add character_archetype to StartupMessage with serde default (Detective)
- Bump PROTOCOL_VERSION to 19
- Add escalate_tells_on_activation() and expire_routine_deviations() systems
- RoutineDeviation inserted on triangle NPCs with 300-tick TTL
- Add TickerPool resource with deterministic SimRng rotation (200 ticks)
- Emit current_ticker in ObserverSnapshot when player is in bar zone
- Load ticker YAML from district content directories

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 09:13:03 +01:00
jpmschweitzerandClaude Opus 4.6 ac68ec6eef fix(simulation): address PR #81 review — critical and high-priority issues
Critical fixes:
- storyteller: replace .expect() with guard + log in activation_pass (Hoshe #1)
- content/loader: validate inverted tile_bounds before iteration (Hoshe #C)
- save_io: persist ActivationState on save/load (Tyre #7)

High-priority fixes:
- storyteller: f64 intermediate for observation_time_ticks scoring (Hoshe #A)
- storyteller: deduplicate copresent entities before scoring (Hoshe #B)
- storyteller: skip activation_pass at tick 0 (Hoshe #G)
- storyteller: explicit .before(advance_tick) ordering (Tyre #9)
- save_state: insert EngagementRecord on NPC deserialize (Tyre #10)
- save_io: reset TriangleActivatedQueue + MovementHistoryBuffer on load (Tyre #8)
- debug: validate teleport target walkability (Hoshe #E)
- debug: reject SkipToContamination when tick past delay (Hoshe #F)
- debug: DebugEnabled defaults to cfg!(debug_assertions) (Hoshe #3)
- debug: log when response overwritten (Hoshe #2)
- content/loader: error on tile dimension mismatch (Hoshe #5)
- content/types: DistrictMeta.description optional (Hoshe #D)
- types: version docs updated to v18 (Tyre #1, #2, #3)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 23:40:59 +01:00
jpmschweitzerandClaude Opus 4.6 c30197db0e feat(simulation): add debug console server and LOS boundary wall margin
Debug and LOS tracks for Sprint 23 (#580, #584):

- DebugCommandKind enum with 10 variants (AdvanceTicks,
  SkipToContamination, TeleportToPosition, ForceContaminationActivate,
  InspectNpc, ListTriangles, ListPopulation, GetContaminationStatus,
  TeleportToLocation, ForceTriangleActivation)
- DebugResponsePayload on ObserverSnapshot, handle_debug_commands
  system gated by DebugEnabled resource
- PROTOCOL_VERSION bumped 17 → 18
- VisibilitySector::BoundaryWall variant — 1-tile wall margin beyond
  LOS boundary included in visible_tiles (not exploration/memory)
- compute_boundary_walls() pass in NaturalVision after FOV+cone

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 19:12:08 +01:00
jpmschweitzerandClaude Opus 4.6 d591f44b35 feat(simulation): add world_seed IPC and EntanglementConfig (#175, #178)
Implements the StartupMessage protocol: client generates world_seed in
SessionManager.new_game(), sends it after handshake, server uses it to
seed SimRng and sample EntanglementConfig.

EntanglementConfig samples flat ∈ [25,35]%, intrigue ∈ [15,25]%, mundane
as remainder (D-029). Same seed produces identical config (D-010
determinism). Different seeds produce distinct configs in ≥90% of pairs.

Protocol flow: HandshakeMessage (server→client) → StartupMessage with
world_seed (client→server) → SimRng initialization → tick loop.

10 Rust tests (determinism, variation, bounds, sum invariant).
9 GDScript test stubs + 2 encode tests for client-side pipeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 14:26:31 +01:00
jpmschweitzerandClaude Opus 4.6 d31ac1cc70 feat(simulation): error handling and recovery — panic supervision, state hash, structured errors (#85)
Protocol v17: add state_hash (desync detection) and sim_errors
(structured error reporting) to ObserverSnapshot. Add SimError,
SimErrorKind, SimErrorBuffer types. Wrap main loop app.update() in
catch_unwind — on panic, send a final SimError snapshot before exit.
Report recoverable deserialization errors to client via SimErrorBuffer.
Compute per-tick state hash from player position + NPC count + tick.
Update all test fixtures and golden files for protocol v17.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 17:46:27 +01:00
jpmschweitzerandClaude Opus 4.6 d808d95659 refactor(simulation): address PR #72 review suggestions
- Hoshe #3: replace O(n²) Vec scan in fallback NPC assignment with
  BTreeSet; prevent same NPC assigned to two roles in one triangle
- Hoshe #4: add From impls for RoleId, TriangleId, StableId, and
  TriangleCrisisEventWire — eliminate fragile .0 access on newtypes
- Hoshe #5: consolidate near-identical unit tests with integration
  counterparts — keep only unique tests in #[cfg(test)] module
- Tyre #3: replace O(N*M) scan in apply_resolve_triangle with
  BTreeMap<TriangleId, Entity> index for O(1) per-command lookup
- Tyre #4: document &mut World on generate_intra_template_triangles
- Observer snapshot uses TriangleCrisisEventWire::from instead of
  manual field mapping

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 23:35:23 +01:00
jpmschweitzerandClaude Opus 4.6 c436ae905f feat(simulation): wire triangle escalation and crisis events into protocol
Registers tick_triangle_escalation and apply_resolve_triangle systems
in SimulationPlugin. Adds TriangleCrisisEventWire to ObserverSnapshot
(protocol v16) for future client rendering of triangle crises (#250,
D-087). Observer emits empty vec by default; escalation system will
populate when triangles reach Active phase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 22:33:21 +01:00
jpmschweitzerandClaude Opus 4.6 23fbfdbfc5 fix(simulation): PR #68 review — version bump, tracing warns, test coverage
- Bump PROTOCOL_VERSION 14 → 15 for save_result field addition
- Add tracing::warn on SaveLoadPending command overwrite (double-tap F5)
- Add tracing::warn on KnowledgeGraph::new() fallback during save
- Fix misleading WouldBlock comment in tcp.rs
- Document SimSpacePressure.active_count pre-eviction timing
- Document entity-based eviction tie-breaking non-determinism
- Add ScopePinned eviction survival regression test
- Regenerate msgpack fixtures for protocol v15

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 12:32:35 +01:00
jpmschweitzerandClaude Opus 4.6 6ed8d11502 feat(simulation): Sprint 19 — 7 server systems
Protocol handshake (#555): HandshakeMessage as first IPC frame,
HandshakeState resource, forward-compatible input handling.

State serialization (#96): serialize_npc_to_frozen/deserialize with
full D-024 axis coverage (10 new optional fields on NpcSaveState).

Scope tags (#98): ScopeTagKind enum, ScopePinned marker, automatic
assignment from KnowledgeGraph and RelationshipGraph.

Timestamp eviction (#97): LastInteractionTick, SimSpacePressure,
BinaryHeap LRU eviction respecting ScopePinned entities.

Save/load (#553): save_to_file/load_from_file via MessagePack,
SaveGame/LoadGame IPC commands, SaveLoadResultWire on snapshot.

Test infrastructure (#200): Layer 3 integration test entry point,
three-layer architecture documented per D-030.

Information boundary tests (#272): 4 negative tests proving no
passive KG leakage, LOS fog holds, tier boundary holds, save
isolation per NPC.

1063 tests passing, 0 failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 12:13:03 +01:00
jpmschweitzer f5c5ac635c Merge remote-tracking branch 'origin/server'
# Conflicts:
#	CHANGELOG.md
#	client/tests/fixtures/msgpack/snapshot_boundary_tick_0.msgpack
#	client/tests/fixtures/msgpack/snapshot_boundary_tick_127.msgpack
#	client/tests/fixtures/msgpack/snapshot_boundary_tick_2b31m1.msgpack
#	client/tests/fixtures/msgpack/snapshot_boundary_tick_2b32.msgpack
#	client/tests/fixtures/msgpack/snapshot_boundary_tick_32767.msgpack
#	client/tests/fixtures/msgpack/snapshot_empty.msgpack
#	client/tests/fixtures/msgpack/snapshot_multi_entity.msgpack
#	client/tests/fixtures/msgpack/snapshot_one_npc.msgpack
#	client/tests/fixtures/msgpack/snapshot_player.msgpack
#	client/tests/fixtures/msgpack/snapshot_v2_full.msgpack
#	server/src/bridge/types.rs
2026-02-25 10:09:27 +01:00
jpmschweitzerandClaude Opus 4.6 768a431c38 fix(simulation): PR #66 review — dedup vision, spawn components, doc fixes
- vision.rs: deduplicate own-tile entity iteration, add same-tile test
- spawn.rs: add NpcVisionState, NpcMemory, PlayerAwareness to content-
  spawned NPCs (matching generate_npc)
- pressure.rs: update who_knows_full_scan doc to reflect actual call
  frequency, document O(N) acceptability at call site
- types.rs: fix stale protocol version comment (13→14)
- generate.rs: format!() → .to_string() (clippy)
- vision.rs: hardcoded 10 → TICKS_PER_GAME_MINUTE
- relationships.rs: fix comment "15%" → "20%" to match code
- pressure.rs: document total() floor-truncation
- save_state.rs: document NpcMemory exclusion as intentional

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 10:04:18 +01:00
jpmschweitzerandClaude Opus 4.6 276538cde1 feat(simulation): Sprint 18 — 9 server systems
Background tier state machines (#95), NPC vision (#115), player-
awareness behavior (#244), skill system & combat flag (#91), social
propagation (#249), examine mechanic (#242), character pressure
framework (#248), save state data model (#256), tell state wiring
(#337). Protocol version bumped 13→14 for examine_result and
character_pressure snapshot fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 09:50:37 +01:00
jpmschweitzerandClaude Opus 4.6 a82eb0748a fix(client): address PR #65 review — POI key, ToldBy parsing, KG dirty flag
- minimap.gd: fix "poi_category" → "category" key mismatch so POI
  colors and shapes render correctly
- journal_panel.gd: parse ToldBy(N) source format, resolve entity
  names from player_knowledge; move confidence/source labels to
  UIStrings per D-042
- observer/mod.rs: add Changed<KnowledgeGraph> dirty flag to skip
  per-tick KG serialization when unchanged
- types.rs: fix stale version doc comment (13 → 14)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 02:41:31 +01:00
jpmschweitzerandClaude Opus 4.6 dd3ead7a1b feat(simulation): protocol v14 — POI list, examine result, player knowledge wire types
Add three new ObserverSnapshot fields for client Sprint 18 tickets:
poi_list (Vec<PoiWire>) for minimap #151, examine_result
(Option<ExamineResultWire>) for #174, player_knowledge
(Option<PlayerKnowledgeWire>) for journal #264. POI list populated
live from KG-discovered PointOfInterest components. KG dump
serializes entity/fact knowledge with confidence, source, and state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 02:29:29 +01:00
jpmschweitzerandClaude Opus 4.6 b86e052511 feat(simulation): NPC information boundaries and contradiction monologue (#549, #550)
tell_state reads KG for other-entity relationship state (MVP boundary
per D-082). Contradiction monologue fires with pre-resolved entity names,
shifts ToldBy source to PersonOfInterest. Full THE FRIEND arc event chain.
Implements D-082 step 1, D-083 event chain.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 12:15:11 +01:00
jpmschweitzerandClaude Opus 4.6 efa2dc543f feat(simulation): sprint 16 dialogue server — response handler, trust gossip, variety tracker
Move dialogue system registrations from BridgePlugin to NpcPlugin (#538):
game logic that depends on NPC-layer resources now registers where it
belongs. BridgePlugin retains only wire protocol concerns.

Implement DialogueResponse verb handler (#539): new process_dialogue_response
system runs the full D-028 four-layer pipeline to select follow-up lines
when the player picks a dialogue option. Clears ActiveDialogue when no
candidates remain. Fix latent schedule ambiguity — emit_observation_events
now has explicit .before(advance_tick) constraint.

Verify trust-gated gossip pipeline (#171): confirmed process_talk_interaction
correctly passes KnowledgeConfidence through relationship_to_trust() per
D-075. Added integration tests for Secret-tier access (Friendly+KnowsDetails)
and Surface-only fallback (Friendly+Suspects).

Wire DialogueCooldownTracker into selection (#338): added regression test
confirming no line_id repeats within the 600-tick cooldown window across
10 consecutive Talk interactions.

Closes #538, #539, #171, #338

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 20:01:39 +01:00
jpmschweitzerandClaude Opus 4.6 67cadddaf2 fix(simulation): address PR #55 review — stale comment, range, duplication, docs
- Fix protocol version comment (12 → 13) in ObserverSnapshot doc
- Widen Want intensity range from 3..=9 to 1..=10 to match spec and test
- Replace duplicated pool selection in trigger_recognition_monologue with
  call to select_pool_line helper (~50 lines removed)
- Document NaiveSpatialIndex migration cost for grid/quadtree swap
- Remove misleading Default derive from TellCategory (Nervous is not a
  sensible default for neutral NPCs)
- Add caller invariant doc on generate_npc (no TilePosition spawned)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 14:55:21 +01:00
jpmschweitzerandClaude Opus 4.6 8538f916af feat(simulation): wire Sprint 15 systems + protocol v13
Register all new systems in NpcPlugin and SimulationPlugin with correct
ordering constraints. Protocol bumped to v13: tell_state on VisibleEntity,
follow_state and PostConversationQueue on ObserverSnapshot, Follow verb
on VerbKind. Observer snapshot populates tell state from DerivedTellState
and follow state from FollowTarget. System ordering: tolerance after
mood, deviation after activity, tell after mood+deviation, follow after
visibility geometry, event monologue after conversations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 14:40:09 +01:00
jpmschweitzerandClaude Opus 4.6 28e7e6d9ad feat(simulation): add NPC name masking with role labels and color index
Server-side infrastructure for information asymmetry in dialogue.
NPCs display role labels (Worker, Supervisor, Patron) instead of
real names until the player explicitly learns them via KG lookup.
NpcColorIndex (stable_id % 8) persists across name reveal.

ConversationEvent and DialogueResponseEvent carry display names +
color indices on the wire with serde(default) for compat.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 13:42:59 +01:00
jpmschweitzerandClaude Sonnet 4.6 aa0d8ced37 feat(simulation): NPC-to-NPC conversation system (#247, D-078)
Implements server-authoritative per-word occlusion for NPC conversations.
ConversationEventBuffer drains into ObserverSnapshot each tick so the client
receives only words audible from the player's position. Updates test fixtures
to include the new conversation_events and conversation_ended fields.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 18:41:44 +01:00
jpmschweitzerandClaude Opus 4.6 51abc3e3c1 feat(simulation): #523 add zone_id to ObserverSnapshot (D-077, protocol v11)
Server-tracked zone_id on VisibleTile for D-073 zone crossfade and
D-059 deep fog temperature tint. ZoneMap resource backed by BTreeMap,
observer enrichment in snapshot assembly. Backwards-compatible: v10
payloads deserialize with zone_id: None.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 18:10:06 +01:00
jpmschweitzer 4bdcc8c3fa Merge remote-tracking branch 'origin/ci'
# Conflicts:
#	client/tests/fixtures/msgpack/snapshot_boundary_tick_0.msgpack
#	client/tests/fixtures/msgpack/snapshot_boundary_tick_127.msgpack
#	client/tests/fixtures/msgpack/snapshot_boundary_tick_2b31m1.msgpack
#	client/tests/fixtures/msgpack/snapshot_boundary_tick_2b32.msgpack
#	client/tests/fixtures/msgpack/snapshot_boundary_tick_32767.msgpack
#	client/tests/fixtures/msgpack/snapshot_empty.msgpack
#	client/tests/fixtures/msgpack/snapshot_multi_entity.msgpack
#	client/tests/fixtures/msgpack/snapshot_one_npc.msgpack
#	client/tests/fixtures/msgpack/snapshot_player.msgpack
#	client/tests/fixtures/msgpack/snapshot_v2_full.msgpack
#	server/Cargo.toml
#	server/src/bridge/text_renderer.rs
#	server/src/bridge/types.rs
#	server/src/perception/observer/mod.rs
#	server/src/simulation/path_follow.rs
#	server/tests/bridge_ipc.rs
#	server/tests/bridge_tcp.rs
#	server/tests/gen_fixtures.rs
#	server/tests/serialization.rs
2026-02-19 15:35:56 +01:00
jpmschweitzerandClaude Opus 4.6 03c44bebaf fix(simulation): address PR #42 review — 8 items from Hoshe and Tyre
1. Sound producers: document empty v0.1 pipeline explicitly (critical)
2. Routine tests: add ActiveSim to 3 tests that passed trivially
3. Rename _observer_pos → observer_pos (used at line 191)
4. Add FactionOnly positive test case (matching faction_id)
5. Fix stale doc comment "Current: 9" → 10 in ObserverSnapshot
6. Remove orphaned SimulationTier/LastInteraction/ScopeTag types
7. Add tracing::warn on FactionOnly non-numeric parse failure
8. Document Medium-range occlusion gap as TODO in audible_at
9. Insert SoundEventQueue in observer test setup_world

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:08:32 +01:00
jpmschweitzerandClaude Opus 4.6 3d306b8a2b feat(ci): add tracing::instrument to heavy per-tick systems, fix stale protocol comment (#344, #527)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 14:55:00 +01:00
jpmschweitzerandClaude Opus 4.6 9ea9fd2a74 feat(engine): add rng_seed to ObserverSnapshot for deterministic replay (#527)
Add rng_seed: Option<u64> to ObserverSnapshot (protocol v10). Populated
from SimRng state each tick. Completes the WRONG button capture loop —
seed.txt now writes a valid u64 instead of "unavailable", enabling
deterministic replay from bug reports.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 13:34:14 +01:00
jpmschweitzerandClaude Opus 4.6 066f8031fd feat(simulation): sprint 12 server — tier system, sound events, KG access, line previewer
Implements 4 completed tickets + partial progress on 2 more:

- #93 Tier marker components (ActiveSim, BackgroundSim, StateSaved + TierPlugin)
- #138 Information tag schema (ObserverAccess enum in knowledge/types.rs)
- #124 Sound event system (SoundEventEmitter, SoundEventQueue, bridge wiring)
- #193 Line previewer CLI (line_preview binary with filter/explain/sequence modes)
- #94 Active tier simulation (in progress — With<ActiveSim> filters)
- #139 Component-level access control (in progress — filter_by_access)

Updates snapshot fixtures and test golden files for new sound_events field.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 13:33:23 +01:00
jpmschweitzerandClaude Sonnet 4.6 d103e445e7 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>
2026-02-19 11:12:24 +01:00
jpmschweitzerandClaude Opus 4.6 d92a2e5f50 fix(simulation): address PR #37 review — doc corrections, race fix, marker cleanup
Hoshe review (4 items):
- types.rs: doc comment "Current: 6" → "Current: 9"
- dialogue.rs: walk-away doc duplicated numbering (items 4-5 were 2-3)
- test_world/mod.rs: comment "Reset plates at 49-51" → "49-55"
- content_scaling.rs: magic number 51 → constants::RESET_PLATE_STABLE_IDS.1

Tyre review (3 items):
- knowledge/types.rs: guard comments on decrement() floor at Hostile
- input.rs: TeleportToHub now clears ConfrontationDelivered marker
- content_scaling.rs: same magic number fix (covered above)

Additional:
- content_runtime.rs: barrier-based shutdown handshake fixes TCP RST
  race condition under parallel test execution
- dialogue_room.rs: clippy type_complexity allow on NPCS tuple array

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 17:50:22 +01:00
jpmschweitzerandClaude Opus 4.6 273d29f26f feat(simulation): sprint 10 — hub teleport, confrontation response, walk-away phase 2, gauntlet rooms 4-7, blocked_entities debug field
#491: PlayerAction::TeleportToHub — moves player to hub spawn, clears
dialogue/monologue/interaction buffer, Gauntlet-only with log warning.
#520: ConfrontationDelivered event — Tier 2 animation shift, relationship
state decrement (D-033), monologue spike emission.
#519: Walk-away Phase 2 — NPC animation shift + routine deviation on
dialogue exit (D-064).
#498: Four new Gauntlet rooms — Interaction Gallery, Fog Theater, Crowd
Plaza, Dialogue Room with constants and wiring.
#514: blocked_entities Vec<u64> on ObserverSnapshot, protocol v9.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 12:58:14 +01:00
jpmschweitzerandClaude Opus 4.6 d5a1f6dadb refactor(simulation): apply rustfmt formatting
Formatting-only changes across server source and test files.
No logic changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 01:39:44 +01:00
jpmschweitzerandClaude Opus 4.6 f83815fd9a feat(simulation): add snapshot text renderer library (#481)
format_snapshot_text(&ObserverSnapshot) -> String pub-exported from
server crate. Entity labels as kind:entity_id sorted by distance,
room name stubbed as (unknown) until Gauntlet constants land.
10 unit tests. Consumed by tooling/test-client for --text mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 01:39:28 +01:00
jpmschweitzerandClaude Opus 4.6 12d1fd505e fix(simulation): address PR #26 review comments (13 items)
Warnings fixed:
- Add WalkAway to all_player_action_variants_roundtrip test
- Warn and skip on unresolvable speaker_entity_id (was silent 0)
- Change MonologueState.shown_ids from Vec to HashSet (O(1) lookup)
- Add cross-plugin ordering: trigger_recognition_monologue after
  detect_anomalies (latent determinism bug)
- Add TODO for unreachable Secret trust tier

Suggestions addressed:
- Server-side range check for Talk verb in handle_talk (CLOSE_RANGE)
- Emit IncompleteInteraction before overwriting ActiveDialogue
- Add different_seed_produces_different_replay determinism test
- Replace panic with assert for unknown fixture naming convention
- Fix duplicate "Observe" label: ExamineNpc now uses "Examine NPC"
- Change DialogueCooldownTracker.used from Vec to BTreeMap (D-041)
- Add .after(process_talk_interaction) to process_walk_away ordering
- Collapse dead conditional in main.rs (both branches identical)

468 tests pass, 0 failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 18:12:45 +01:00
jpmschweitzerandClaude Opus 4.6 35f55cfa46 feat(simulation): dialogue pipeline, ContentSlug, and walk-away KG recording
Implement full dialogue selection pipeline (D-028): 4-layer filtering
engine with access tier, situation derivation, trust tier, and weighted
topic+mood scoring via SimRng. Add ContentSlug component for stable
content identity across save/load. Add walk-away KG recording with
IncompleteInteraction events per D-064 three-phase consequences. Bump
protocol to v8 with DialogueResponseEvent. Fixes #305, #427, #452.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 17:41:23 +01:00
jpmschweitzerandClaude Opus 4.6 2b54697278 fix(simulation): discard movement input while paused
process_player_input processed movement commands regardless of tick
rate, causing the camera to drift from the player when the game was
paused and the player held direction keys. Add PlayerAction::is_movement()
helper and a paused guard that skips movement actions while TickRate is
Paused. Pause/Unpause commands still process normally.

Fixes bug #3 (player moves while game is paused).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 23:25:51 +01:00
jpmschweitzerandClaude Opus 4.6 d1aba3d554 fix(simulation): use non-blocking TCP to prevent game loop stall
read_framed() called read_exact() which blocked the entire bevy Update
schedule waiting for client input — no systems ran until a keystroke
arrived. Switch TcpStream to non-blocking mode so receive_inputs()
returns Ok(vec![]) on WouldBlock instead of blocking. Toggle to
blocking for snapshot writes (reliable delivery). Add 50ms frame
throttle (~20 ticks/sec) since the non-blocking loop would otherwise
spin. Downgrade input receive logging to trace, add error logging for
missing bridge resource and failed observer queries.

Fixes bug #1 (server never sends snapshots) and #2 (camera doesn't
center until first keystroke).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 23:25:45 +01:00
jpmschweitzerandClaude Opus 4.6 4d8fe996fc feat(perception): add cognitive delay system for fog recognition (#423)
New CognitiveDelay component buffers perception events before emitting
KnowledgeEvents. Normal delay: 6 ticks (0.6s), urgent: 3 ticks (0.3s).
Drain system runs after emit_observation_events, before process_knowledge_events.

Adds pending_recognitions to ObserverSnapshot (protocol v7) for client
fog entity visualization. Includes cancellation when entity leaves LOS.

Monologue fires during delay (not after) per D-060 — cross-system
wiring deferred to follow-up ticket #451.

Ref: D-060 (cognitive delay), D-031 (10 tps), D-059 (fog layers)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 00:41:08 +01:00
jpmschweitzerandClaude Opus 4.6 d0663c4193 refactor(server): apply rustfmt and clippy suggestions
Formatting pass across simulation, perception, knowledge, NPC, and
test modules. Includes two clippy fixes in monologue.rs (.values()
instead of for (_, v) pattern).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 00:40:43 +01:00
jpmschweitzerandClaude Opus 4.6 df81b24cd1 feat(simulation): sprint anomaly double-take monologue (#428, D-055)
When sprinting past a Contradicted entity, queue a delayed retroactive
monologue that fires after ~1.5s: "Wait — something wasn't right back
there." SprintAnomalyQueue component with first-in-wins semantics.
Detection in observer pipeline, processing in monologue system.
Wire MovementProfile, Stance, and SprintAnomalyQueue into player spawn.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 16:00:20 +01:00
jpmschweitzerandClaude Opus 4.6 98f4cedc03 feat(simulation): Sprint 6 Touch — stance, tile presence, verbs, protocol v6
Implements the core Sprint 6: Touch systems across 5 tickets:

- #449 ObserverSnapshot v6: add player_stance (MovementStance) and
  player_inventory (Vec<InventoryItem>) wire fields with serde defaults
  for backward compatibility. Bump PROTOCOL_VERSION 5→6.

- #417 Stance system: Sprint/Walk/Careful/Crouch movement stance with
  tick-based speed (1/2/3/4 ticks per move), monologue rate multipliers,
  and PlayerMoveCooldown component. ToggleStanceUp/Down player actions.

- #420 TilePresence: posture-layer collision system allowing same-tile
  occupancy for different layers (Standing/Prone/Seated/Fixture).
  Layer-based collision in validate_movement.

- #421 ObjectType component: Readable/Container/Terminal/Door/Pickup/
  Furniture types with Phase 1 verb sets computed from type + proximity.

- #422 Phase 2 verb filter: KG-gated observer-side verb processing —
  POI priority flips, Confront injection at KnowsDetails+, contradiction
  marking, archetype-specific label relabeling (Smuggler/Detective).

217 unit tests + 17 integration tests passing. All MessagePack fixtures
regenerated for v6 wire format.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 15:38:59 +01:00
jpmschweitzerandClaude Opus 4.6 3c106aa2d0 feat(simulation): complete interaction and monologue pipelines (#413, #414, #415)
Three fixes to make the gameplay loop functional end-to-end:

- Add Interactable component to NPC spawn so E-prompt detection works
- Build monologue trigger system (enter_location + time_idle) with
  MonologueBuffer/MonologueState components, wire through ObserverSnapshot
  as current_monologue field, decode on client and display via HUD
- Change PlayerAction::Interact from unit to struct variant carrying
  optional target_entity_id and verb fields

Bumps protocol version from 4 to 5. Regenerates MessagePack fixtures.
All 200 tests pass (170 unit + 30 integration).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:23:47 +01:00
jpmschweitzerandClaude Opus 4.6 c68585e5f2 chore(simulation): add debug logging for received inputs
Log each received player input at DEBUG level with tick and action,
useful for diagnosing input pipeline issues during live testing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 02:07:47 +01:00
jpmschweitzerandClaude Opus 4.6 29c5003403 fix(simulation): add TileKind to VisibleTile wire protocol (#412)
Server was sending visible_tiles without tile type data, so the client
could not distinguish floor from wall in live mode. Add TileKind enum
(Floor/Wall/Door/Object) to VisibleTile, populated from WalkabilityMap
in the NaturalVision perception query. Update test fixtures to include
the new field. Uses #[serde(default)] for backward compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 02:07:19 +01:00
jpmschweitzerandClaude Opus 4.6 18d8253bfe refactor(server): decompose observer pipeline and fix interaction boundary
Extract visibility geometry into a separate system behind a
PerceptionQuery trait, enabling D-017 perception mode swapping.
Two-stage pipeline: compute_visibility_geometry writes to
VisibilityGeometry resource, compute_observer_snapshot reads it.

Remove KnowledgeGraph from compute_nearby_interactions (simulation
phase boundary violation). Verb availability stays in simulation;
POI-based priority adjustment moves to observer via
apply_poi_verb_priority helper.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 23:32:41 +01:00
jpmschweitzerandClaude Opus 4.6 ba867564a8 fix(server): add error logging, protocol version, and architecture docs
- Replace silent Entity::to_bits() fallbacks with tracing::error in
  observer.rs and interaction.rs (makes unregistered entities loud)
- Add PROTOCOL_VERSION constant to types.rs, use in observer snapshot
- Document single-observer assumption on NearbyInteractionBuffer
- Document proximity-only (no LOS) limitation on compute_nearby_interactions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 21:22:34 +01:00
jpmschweitzerandClaude Opus 4.6 e2f2f4e590 refactor(server): remove dead generate_snapshot function
Delete generate_snapshot from bridge/mod.rs — superseded by
perception::observer::compute_observer_snapshot. Not referenced
in any schedule or test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 21:22:28 +01:00
jpmschweitzerandClaude Opus 4.6 9943684f2c refactor(server): address PR #16 review feedback
Hoshe + Tyre review items:
- Use StableId consistently for wire entity_id (H4) across observer,
  observation, interpretation, and interaction systems
- Make NearbyInteractionBuffer.interactions private with take() (H1/H20)
- Add system ordering constraint for compute_nearby_interactions (H5)
- Panic on missing PlayerCharacter in input processing (H2)
- Remove redundant paused field from GameTime (Tyre8)
- Remove #[serde(default)] from nearby_interactions (H3)
- Change NearbyInteraction.distance from f32 to u32 (H8)
- Add sort stability for equal verb priorities (H6)
- Scope constants to pub(crate) (H7)
- Add debug_assert for last_observed_tick ordering (H10)
- Strengthen unregistered entity handling to debug_assert + error (H11)
- Document fractional tick accumulation (Tyre9)
- Extract collect_remembered_entities helper (Tyre2/H17)
- Add half_rate_no_drift_over_10000_frames test (H14)
- Add mid-range and deterministic sort tests (H15)
- Add fixture version assertion (H16)
- Regenerate msgpack fixtures for wire format changes

146 unit + 19 integration tests pass, zero clippy warnings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 20:14:35 +01:00