Commit Graph
120 Commits
Author SHA1 Message Date
jpmschweitzerandClaude Opus 4.6 1920f002a1 docs(workshops): add 5 architecture spike workshop briefs
Workshop briefs for the larger spikes identified by the architecture
review audit: knowledge graph & information boundaries, observer
snapshot pipeline, NPC AI state machines, save/load architecture,
and map authoring pipeline. Each includes participants, key questions,
input documents, and expected outputs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:36:02 +01:00
jpmschweitzerandClaude Opus 4.6 e1a3913060 docs(decisions): add Q-018 through Q-023 from architecture audit
Six new open questions identified by the Tyre/Troblum architecture
review: shadowcasting algorithm selection, entity ID stability,
multi-entity collision resolution, tick budget overflow policy,
pathfinding cache eviction, and debug visualization scope.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:35:56 +01:00
jpmschweitzerandClaude Opus 4.6 af928d74cf chore(meta): update changelog
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:30:15 +01:00
jpmschweitzerandClaude Opus 4.6 33db0caa69 docs(audits): add architecture audit framework and Sprint 1 review
Two-round adversarial review by Tyre + Troblum covering full
architecture decisions and implementation. Status: GREEN architecture,
AMBER implementation plan.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:29:58 +01:00
jpmschweitzerandClaude Opus 4.6 3d872f0d3f chore(db): track ticket status updates (#78, #79, #81-#83 done)
Sprint 1 IPC tickets marked done after client and server PR merges.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:29:54 +01:00
jpmschweitzerandClaude Opus 4.6 b9a3d8efea Merge branch 'server' into main (PR #6)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:26:48 +01:00
jpmschweitzerandClaude Opus 4.6 3f4c663242 fix(bridge): improve accept error reporting with address context
Replace expect() with unwrap_or_else that logs the bind address
and error via tracing before exiting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:16:08 +01:00
jpmschweitzerandClaude Opus 4.6 b9af725b02 fix(simulation): correct tick synchronization in snapshot generation
Snapshot for tick N should show state at END of tick N. Reorder systems
so generate_snapshot runs after validate_movement but before
advance_tick. Previously snapshot.tick was the incremented tick,
not the tick whose inputs were processed. Also fix main.rs accept
error to log address context before exiting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:16:04 +01:00
jpmschweitzerandClaude Opus 4.6 2cd8786036 fix(bridge): add Disconnected error variant, fix test race condition
Replace string-matching disconnect detection with explicit
BridgeError::Disconnected variant. Add TcpBridge::accept_on(listener)
that takes a pre-bound TcpListener, eliminating the 100ms sleep hack
in TCP tests. Send errors now also trigger ServerRunning=false.
Add trace logging to generate_snapshot for entity count visibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:15:56 +01:00
jpmschweitzerandClaude Opus 4.6 3befd2309c fix(client): address PR #5 review — race condition, buffer corruption, input error
Critical fixes from Hoshe review:
1. Race condition: defer TCP connect to _process() with retry logic
   (MAX_CONNECT_RETRIES=20, 100ms interval) so server has time to bind.
2. Buffer corruption: disconnect on oversized message instead of
   clearing valid buffered data (_corrupt flag, fail-safe).
3. Silent input drop: send_input() returns Error so callers can detect
   encode/validation failures.

Warnings addressed:
- ServerProcess validates server_path exists before spawning
- SIGKILL and health check TODOs documented for future work
- Diagonal keybindings documented as intentional deferral
- send_message uses single put_data() call (no partial write risk)
- Static frame helpers documented as D-030 Layer 2 test-only

New tests (36 total, up from 33):
- Partial read scenario (chunked TCP delivery)
- Multi-message sequential decode (exercises buffer corruption fix)
- send_input error return on invalid action

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:14:52 +01:00
jpmschweitzerandClaude Opus 4.6 058d0352ab chore(meta): update changelog
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:02:00 +01:00
jpmschweitzerandClaude Opus 4.6 a5b88cb735 chore(bridge): format gen_fixtures.rs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:01:31 +01:00
jpmschweitzerandClaude Opus 4.6 7864bfdf7d feat(simulation): add input processing, snapshot gen, and game loop
Implements the full server-side tick pipeline:
- process_player_input drains InputQueue, converts PlayerActions to
  MoveIntent components or pause/unpause toggles
- generate_snapshot builds ObserverSnapshot from ECS state with
  render coordinate conversion
- receive_bridge_inputs/send_bridge_snapshot handle bridge I/O with
  graceful disconnect detection via ServerRunning resource
- main.rs now accepts TCP connections and runs a proper game loop
- PlayerCharacter marker, Player EntityKind, SnapshotBuffer resource

Closes server side of #81, #82, #83.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:01:28 +01:00
jpmschweitzerandClaude Opus 4.6 1b0e514560 feat(bridge): add TCP transport for Godot client connection
Godot has no Unix socket API, so TCP localhost is required for
client-server IPC. TcpBridge implements SimBridge with the same
framing protocol as LocalBridge. Includes accept/connect methods
and three integration tests over TCP.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:01:20 +01:00
jpmschweitzerandClaude Opus 4.6 f6ce7d4046 fix(bridge): use named MessagePack format for wire compatibility
Client-side Protocol.gd expects rmp_serde::to_vec_named() (maps with
string keys), but LocalBridge was using to_vec() (compact positional
arrays). Fix send_snapshot and update all test serialization calls to
match actual wire format. Also change EOF from Ok(vec![]) to
BridgeError::Transport so bridge systems can detect disconnects.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:01:15 +01:00
jpmschweitzerandClaude Opus 4.6 c4e1b07346 chore(meta): update changelog
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:00:04 +01:00
jpmschweitzerandClaude Opus 4.6 0f75c3194d feat(client): add LocalBridge framing tests and diagonal fixtures
12 new tests covering framing roundtrips, cross-layer Protocol+framing
integration, and diagonal wire mapping. 4 new diagonal movement
fixtures generated from Rust for D-030 Layer 1 cross-language
verification. 33/33 tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:59:46 +01:00
jpmschweitzerandClaude Opus 4.6 2ecafff2ed feat(client): integrate LocalBridge transport and 8-directional movement
Wire SimBridge to use LocalBridge for TCP transport in non-test mode:
_process() polls for incoming snapshots and flushes outbound inputs.
Add 4 diagonal movement variants (NE, SE, SW, NW) to InputMapper and
wire mapping, ordered clockwise. Register diagonal input actions in
project.godot.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:59:40 +01:00
jpmschweitzerandClaude Opus 4.6 6dfaf2831f feat(client): add LocalBridge TCP transport and ServerProcess manager
LocalBridge wraps StreamPeerTCP with 4-byte big-endian length-prefix
framing matching server/src/bridge/framing.rs. ServerProcess manages
the Rust server as a subprocess via OS.create_process(). Together
they form the D-020 IPC transport layer for ticket #79.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:59:34 +01:00
jpmschweitzerandClaude Opus 4.6 af4d0d3f26 docs(workshops): complete v0.1 content gap analysis workshop
Workshop produced 42 new tickets (#297-#338) + 6 updated, 9 new
decisions (D-032 through D-040), and 53 dependency links. All 18
agent briefings updated to reflect 40 confirmed decisions.

Key outcomes: Sera Venn as detective's FRIEND, Kael Davan as
smuggler's FRIEND, all 6 wow moments in scope, converged 6+3 tag
taxonomy, wiki taxonomy with 14 categories, 8 audio files via
Stable Audio Open, 4 parallel unblocked work tracks identified.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:38:21 +01:00
jpmschweitzerandClaude Opus 4.6 228844fb5d docs(briefings): update Mellanie briefing post-workshop
Workshop outputs unblock content authoring. Updated status,
key decisions, and immediate work items.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:28:58 +01:00
jpmschweitzerandClaude Opus 4.6 96087323d4 chore(db): track ticket database updates
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:28:43 +01:00
jpmschweitzerandClaude Opus 4.6 36ffd3f6fa docs(decisions): add D-040 wiki taxonomy and Q-012 through Q-017
D-040: hierarchical wiki structure with YAML frontmatter.
6 new open questions from content gap analysis workshop
covering generation expansion, line previewer, audio timing,
FRIEND content authoring, knowledge hierarchy, and triangle
pressure thresholds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:28:17 +01:00
jpmschweitzerandClaude Opus 4.6 17ea8a49a1 chore(meta): update changelog
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:28:02 +01:00
jpmschweitzerandClaude Opus 4.6 47585d8107 chore(db): track ticket database updates
Workshop tickets and sprint assignment changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:27:46 +01:00
jpmschweitzerandClaude Opus 4.6 3b6148e56f docs(meta): add PR #4 protocol codec test report
Hoshe's code quality review of client MessagePack codec.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:27:42 +01:00
jpmschweitzerandClaude Opus 4.6 745ce01117 docs(decisions): add D-032 through D-039 from content workshop
D-032: separate monologue pools per character
D-033: entity color = relationship to player
D-034: THE FRIEND production-level NPC pattern
D-035: converged tag taxonomy for line pools
D-036: Sova Transit District / Krenn System setting
D-037: contraband specification (unlicensed lattice components)
D-038: audio in v0.1 scope (8 files via Stable Audio Open)
D-039: v0.1 wow moment scope (all 6 moments)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:27:37 +01:00
jpmschweitzerandClaude Opus 4.6 e96ec80d9c docs(workshops): archive v0.1 content gap analysis workshop
6 agents × 2 rounds examining 9 content layers. Produced D-032
through D-039, THE FRIEND NPC pattern, converged tag taxonomy,
and Sova Transit District setting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:27:31 +01:00
jpmschweitzer 56ee8305ae Merge origin/client into main 2026-02-11 20:26:17 +01:00
jpmschweitzer 2d97fe74da Merge remote-tracking branch 'origin/server' 2026-02-11 20:25:55 +01:00
jpmschweitzerandClaude Opus 4.6 90edf3fabc chore(meta): update changelog
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:15:48 +01:00
jpmschweitzerandClaude Opus 4.6 f87bd2b0e5 feat(simulation): add entity-entity collision
validate_movement now checks both terrain walkability AND tile
occupancy. Builds a spatial index of occupied tiles from stationary
entities, then resolves movers in order — first valid claim wins.

Same spatial pattern needed for D-026 simulation tiers (30-80 active
NPCs) and future pathfinding occupied-tile awareness.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:15:24 +01:00
jpmschweitzerandClaude Opus 4.6 bef4383196 feat(simulation): add 8-directional movement
Add diagonal PlayerAction variants (MoveNortheast, MoveNorthwest,
MoveSoutheast, MoveSouthwest) and TilePosition::all_neighbors()
returning all 8 surrounding tiles. Genre-expected for immersive sim.

Establishes the movement pattern before pathfinding is built on top.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:15:18 +01:00
jpmschweitzerandClaude Opus 4.6 5a539991e4 fix(client): address PR #4 round 2 review feedback
- decode_snapshot() reports dropped entities via push_error and returns
  decode_errors count so callers can detect partial data (D-010
  information boundary compliance)
- receive_bytes() warns when overwriting unconsumed snapshot, documents
  latest-wins semantics
- Rename misleading test to test_encode_produces_nonempty_bytes
- Fix tick rate comment: 10 ticks/game-minute per D-031

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:12:39 +01:00
jpmschweitzerandClaude Opus 4.6 0f5f73a927 chore(meta): update changelog
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:32:56 +01:00
jpmschweitzerandClaude Opus 4.6 bc9a691bc1 fix(client): address PR #4 review feedback
Hoshe critical fixes:
- _action_enum_to_wire uses InputMapper.Action constants instead of
  fragile integer literals; OPEN_MENU explicitly handled as client-only
- Remove int() coercion on tick/entity_id — use direct assignment since
  GDScript int is signed 64-bit (safe for realistic tick values)
- Check encode result before buffering in send_input() — reject empty
  bytes instead of corrupting the outbound stream
- Test snapshot now uses Protocol format {tick, entities} instead of
  legacy schema; GameState updated to derive player position from
  entity data; main.gd and world_renderer.gd updated accordingly

Hoshe warnings:
- 5 negative tests added (truncated bytes, wrong type, missing fields,
  empty bytes, encode validation) — 20/20 tests pass
- receive_bytes signal is emitted at consume time in poll_snapshot by
  design (documented in code)

Tyre suggestions:
- Remove duplicated root-level fixtures — single source of truth in
  client/tests/fixtures/msgpack/
- gen_fixtures.rs writes directly to client/ directory
- Add `make fixtures` target for regeneration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:32:49 +01:00
jpmschweitzerandClaude Opus 4.6 9860fc0857 fix(simulation): address bridge review feedback
Replace .lock().unwrap() with .expect("mutex poisoned") in LocalBridge
for clearer panic messages. Document 16MB MAX_MESSAGE_SIZE rationale
in framing.rs with entity count sizing analysis.

Addresses Hoshe PR review suggestions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:32:35 +01:00
jpmschweitzerandClaude Opus 4.6 78e0c71c6d refactor(simulation): chunk-based walkability map per D-012
Rewrites WalkabilityMap from flat Vec<bool> to HashMap<ChunkCoord, ChunkData>
with 32x32 tile chunks. Supports chunk load/unload for future borderless
generation. Unloaded chunks treated as unwalkable.

Adds TilePosition ↔ f32 render coordinate conversion (to_render_coords,
from_render_coords) bridging i32 simulation coords and f32 wire format.

Addresses Tyre PR review: D-012 chunk architecture compatibility and
VisibleEntity coordinate mismatch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:32:29 +01:00
jpmschweitzerandClaude Opus 4.6 91db2f99de docs(sprints): add PR workflow instructions to sprint briefings
All three sprint briefings now include tea CLI PR creation example
with required --login and --repo flags to avoid TTY prompts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:26:15 +01:00
jpmschweitzerandClaude Opus 4.6 198749f9c1 docs(workshops): add v0.1 content gap analysis workshop brief
Nine-layer analysis from global (art direction) to specific (audio).
Identifies gaps in content tickets for Mellanie, Paula, and Araminta.
Structured as 2-round workshop with 6 participants to produce missing
tickets, dependency chain, and content team work plan.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:18:28 +01:00
jpmschweitzerandClaude Opus 4.6 9af9b3f3aa chore(meta): update changelog
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:17:20 +01:00
jpmschweitzerandClaude Opus 4.6 0041e4453f feat(client): wire SimBridge to Protocol codec
SimBridge now encodes player inputs via Protocol.encode_player_input()
and exposes receive_bytes()/drain_outbound() for the transport layer.
Test mode still works unchanged. Transport (ticket #79) will call
these methods to complete the IPC pipeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:17:05 +01:00
jpmschweitzerandClaude Opus 4.6 b5dd44313e feat(client): add Protocol codec with cross-language tests (#77)
Protocol.gd decodes ObserverSnapshot and PlayerInput from Rust's
rmp_serde wire format, and encodes PlayerInput for sending to server.
Handles rmp_serde enum encoding: unit variants as bare strings,
data variants as single-element maps.

8 fixture-based tests verify decode of Rust-generated fixtures,
GDScript encode/decode roundtrips, and cross-language compatibility.
All 15 tests pass (3 suites).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:16:56 +01:00
jpmschweitzerandClaude Opus 4.6 84e34f61bd feat(client): add MessagePack library and cross-language fixtures
Install Godot4MessagePack (pure GDScript) for MessagePack encode/decode.
Add Rust fixture generator (gen_fixtures.rs) that produces canonical
.msgpack files using rmp_serde::to_vec_named for cross-language testing.

Fixtures cover: snapshots (empty, one NPC, multi-entity with all
EntityKind variants) and player inputs (unit + data enum variants).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:16:43 +01:00
jpmschweitzerandClaude Opus 4.6 e44e90c2cb chore(meta): update changelog
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:08:07 +01:00
jpmschweitzerandClaude Opus 4.6 862ab9099f feat(simulation): add tile collision system (#236)
TilePosition component with discrete grid coordinates, flat-storage
WalkabilityMap resource with O(1) can_move_to() lookup, MoveIntent
component and validate_movement system. Movement validated against
walkability map each tick, blocking all NPC and player movement
through unwalkable tiles. 11 unit tests + 1 integration test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:07:53 +01:00
jpmschweitzerandClaude Opus 4.6 4ed15c1a38 feat(simulation): add LocalBridge IPC over Unix socket (#78)
Length-prefixed MessagePack framing (4-byte BE length + payload),
LocalBridge struct implementing SimBridge trait over Unix domain
sockets, BridgeResource wrapper for ECS integration. Adds Io
error variant to BridgeError. Two integration tests verify
snapshot and input round-trips over real sockets.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:07:47 +01:00
jpmschweitzerandClaude Opus 4.6 0c7d44b265 fix(db): sqlite connector always reads/writes main worktree database
Same fix as the ticket CLI — uses git rev-parse --git-common-dir to
resolve DB path to the main worktree. Prevents WAL/journal pollution
when sqlite-query or sqlite-exec are called from feature branches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:01:26 +01:00
jpmschweitzerandClaude Opus 4.6 70a6f850c6 fix(db): ticket CLI always reads/writes main worktree database
Uses git rev-parse --git-common-dir to find the main worktree root,
then resolves the DB path there. Prevents WAL/journal pollution on
feature branch worktrees that caused merge conflicts on commonwealth.db.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:00:16 +01:00
jpmschweitzerandClaude Opus 4.6 039eac608d chore(skills): start-sprint uses current branch as team
No argument needed — the current branch determines the team.
Only asks if on main.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 18:53:16 +01:00