Implement physical inventory system per D-065:
- CarriedBy(StableId) component marks items as carried by an entity
- ItemName and InventorySlot components for display and slot assignment
- Take verb: removes TilePosition, adds CarriedBy + InventorySlot
- Place verb: removes CarriedBy + InventorySlot, adds TilePosition
- Observer snapshot populates player_inventory from carried items query
- Info boundary: carried items lack TilePosition, naturally excluded
from all spatial queries (visibility, interactions) for other entities
- 9-slot capacity (3x3 grid per OQ-24), auto-assigns first free slot
- 8 new tests covering take, place, sequential slots, full rejection
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add MovementProfile component with per-archetype default stances (D-053).
Sprint stance now explicitly clears the interaction buffer — no verbs
computed or sent during sprint (D-055). Anomaly monologue pipeline is
unaffected (handled by separate system).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
Well-implemented, comprehensively tested PR. 331 tests covering happy paths, edge cases, and integration scenarios. Clean Phase 1/Phase 2 separation properly enforces D-010 information boundary.
#
File
Severity
Issue
1
input.rs:204
warning
apply_move() uses .expect() which could panic if world state is corrupted. Consider replacing with early-return let Ok(..) = ... else { return }
2
inventory.rs:63
warning
collect_inventory_for() fallback to entity.to_bits() masks bugs. Consider adding debug_assert! in test builds
3
stance.rs:77
suggestion
u32::MAX initialization for first-move-immediate is clever but could be clearer with a named constant
4
monologue.rs:52
suggestion
ANOMALY_DELAY_TICKS=90 hardcoded; consider making configurable for playtesting
5
observer/mod.rs:158
suggestion
archetype_verb_label() will grow; consider extracting to separate module later
6
inventory.rs:28
suggestion
find_next_slot() O(n) scan is fine for n=9, document for future
7
interaction.rs:114
suggestion
Add trace log when sprint suppresses interactions for debugging
Tyre (Architecture): APPROVE
Architecturally sound implementation with excellent adherence to non-negotiable baselines. All features respect D-010 (info boundary), D-012 (chunk-based world), and maintain clean Phase 1/Phase 2 separation. Performance implications are bounded and within budget.
#
File
Severity
Issue
1
monologue.rs:43
warning
No logging when sprint anomaly queue drops subsequent anomalies (first-in-wins). Add trace for debugging
2
types.rs:92
warning
3x3 grid size (9 slots) hardcoded in multiple locations. Consider centralizing the dimension constant
3
stance.rs:72
warning
u32::MAX saturation strategy for first-move is clever but potentially confusing. Consider explicit doc or flag
4
observer/mod.rs:131
suggestion
Phase 2 filter has multiple in-place mutation passes. Document intended execution order
5
inventory.rs:67
suggestion
Soft error on missing EntityRegistry entry is correct per D-020, but add debug assertion for tests
6
interaction.rs
suggestion
File may exceed 800 lines after +717 additions. Consider submodule split in future refactor
Verdict: APPROVED
Both reviewers approve. No critical issues. All warnings are minor (logging, documentation, defensive assertions) and don't block merge.
🤖 Reviewed with Claude Code
## Review: server -> main (type: code)
### Hoshe (Code Quality): APPROVE
Well-implemented, comprehensively tested PR. 331 tests covering happy paths, edge cases, and integration scenarios. Clean Phase 1/Phase 2 separation properly enforces D-010 information boundary.
| # | File | Severity | Issue |
|---|------|----------|-------|
| 1 | `input.rs:204` | warning | `apply_move()` uses `.expect()` which could panic if world state is corrupted. Consider replacing with early-return `let Ok(..) = ... else { return }` |
| 2 | `inventory.rs:63` | warning | `collect_inventory_for()` fallback to `entity.to_bits()` masks bugs. Consider adding `debug_assert!` in test builds |
| 3 | `stance.rs:77` | suggestion | `u32::MAX` initialization for first-move-immediate is clever but could be clearer with a named constant |
| 4 | `monologue.rs:52` | suggestion | `ANOMALY_DELAY_TICKS=90` hardcoded; consider making configurable for playtesting |
| 5 | `observer/mod.rs:158` | suggestion | `archetype_verb_label()` will grow; consider extracting to separate module later |
| 6 | `inventory.rs:28` | suggestion | `find_next_slot()` O(n) scan is fine for n=9, document for future |
| 7 | `interaction.rs:114` | suggestion | Add trace log when sprint suppresses interactions for debugging |
### Tyre (Architecture): APPROVE
Architecturally sound implementation with excellent adherence to non-negotiable baselines. All features respect D-010 (info boundary), D-012 (chunk-based world), and maintain clean Phase 1/Phase 2 separation. Performance implications are bounded and within budget.
| # | File | Severity | Issue |
|---|------|----------|-------|
| 1 | `monologue.rs:43` | warning | No logging when sprint anomaly queue drops subsequent anomalies (first-in-wins). Add trace for debugging |
| 2 | `types.rs:92` | warning | 3x3 grid size (9 slots) hardcoded in multiple locations. Consider centralizing the dimension constant |
| 3 | `stance.rs:72` | warning | `u32::MAX` saturation strategy for first-move is clever but potentially confusing. Consider explicit doc or flag |
| 4 | `observer/mod.rs:131` | suggestion | Phase 2 filter has multiple in-place mutation passes. Document intended execution order |
| 5 | `inventory.rs:67` | suggestion | Soft error on missing EntityRegistry entry is correct per D-020, but add debug assertion for tests |
| 6 | `interaction.rs` | suggestion | File may exceed 800 lines after +717 additions. Consider submodule split in future refactor |
### Verdict: APPROVED
Both reviewers approve. No critical issues. All warnings are minor (logging, documentation, defensive assertions) and don't block merge.
🤖 Reviewed with Claude Code
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Sprint 6 server deliverables: movement stances, tile occupancy, two-phase verb computation, smuggler inventory, and sprint anomaly monologue.
Tickets (9/9 done)
Key decisions implemented
Stats
Unblocks
🤖 Generated with Claude Code
Review: server -> main (type: code)
Hoshe (Code Quality): APPROVE
Well-implemented, comprehensively tested PR. 331 tests covering happy paths, edge cases, and integration scenarios. Clean Phase 1/Phase 2 separation properly enforces D-010 information boundary.
input.rs:204apply_move()uses.expect()which could panic if world state is corrupted. Consider replacing with early-returnlet Ok(..) = ... else { return }inventory.rs:63collect_inventory_for()fallback toentity.to_bits()masks bugs. Consider addingdebug_assert!in test buildsstance.rs:77u32::MAXinitialization for first-move-immediate is clever but could be clearer with a named constantmonologue.rs:52ANOMALY_DELAY_TICKS=90hardcoded; consider making configurable for playtestingobserver/mod.rs:158archetype_verb_label()will grow; consider extracting to separate module laterinventory.rs:28find_next_slot()O(n) scan is fine for n=9, document for futureinteraction.rs:114Tyre (Architecture): APPROVE
Architecturally sound implementation with excellent adherence to non-negotiable baselines. All features respect D-010 (info boundary), D-012 (chunk-based world), and maintain clean Phase 1/Phase 2 separation. Performance implications are bounded and within budget.
monologue.rs:43types.rs:92stance.rs:72u32::MAXsaturation strategy for first-move is clever but potentially confusing. Consider explicit doc or flagobserver/mod.rs:131inventory.rs:67interaction.rsVerdict: APPROVED
Both reviewers approve. No critical issues. All warnings are minor (logging, documentation, defensive assertions) and don't block merge.
🤖 Reviewed with Claude Code
Pull request closed