cogames-agents 0.0.0.7__cp312-cp312-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. cogames_agents/__init__.py +0 -0
  2. cogames_agents/evals/__init__.py +5 -0
  3. cogames_agents/evals/planky_evals.py +415 -0
  4. cogames_agents/policy/__init__.py +0 -0
  5. cogames_agents/policy/evolution/__init__.py +0 -0
  6. cogames_agents/policy/evolution/cogsguard/__init__.py +0 -0
  7. cogames_agents/policy/evolution/cogsguard/evolution.py +695 -0
  8. cogames_agents/policy/evolution/cogsguard/evolutionary_coordinator.py +540 -0
  9. cogames_agents/policy/nim_agents/__init__.py +20 -0
  10. cogames_agents/policy/nim_agents/agents.py +98 -0
  11. cogames_agents/policy/nim_agents/bindings/generated/libnim_agents.dylib +0 -0
  12. cogames_agents/policy/nim_agents/bindings/generated/nim_agents.py +215 -0
  13. cogames_agents/policy/nim_agents/cogsguard_agents.nim +555 -0
  14. cogames_agents/policy/nim_agents/cogsguard_align_all_agents.nim +569 -0
  15. cogames_agents/policy/nim_agents/common.nim +1054 -0
  16. cogames_agents/policy/nim_agents/install.sh +1 -0
  17. cogames_agents/policy/nim_agents/ladybug_agent.nim +954 -0
  18. cogames_agents/policy/nim_agents/nim_agents.nim +68 -0
  19. cogames_agents/policy/nim_agents/nim_agents.nims +14 -0
  20. cogames_agents/policy/nim_agents/nimby.lock +3 -0
  21. cogames_agents/policy/nim_agents/racecar_agents.nim +844 -0
  22. cogames_agents/policy/nim_agents/random_agents.nim +68 -0
  23. cogames_agents/policy/nim_agents/test_agents.py +53 -0
  24. cogames_agents/policy/nim_agents/thinky_agents.nim +677 -0
  25. cogames_agents/policy/nim_agents/thinky_eval.py +230 -0
  26. cogames_agents/policy/scripted_agent/README.md +360 -0
  27. cogames_agents/policy/scripted_agent/__init__.py +0 -0
  28. cogames_agents/policy/scripted_agent/baseline_agent.py +1031 -0
  29. cogames_agents/policy/scripted_agent/cogas/__init__.py +5 -0
  30. cogames_agents/policy/scripted_agent/cogas/context.py +68 -0
  31. cogames_agents/policy/scripted_agent/cogas/entity_map.py +152 -0
  32. cogames_agents/policy/scripted_agent/cogas/goal.py +115 -0
  33. cogames_agents/policy/scripted_agent/cogas/goals/__init__.py +27 -0
  34. cogames_agents/policy/scripted_agent/cogas/goals/aligner.py +160 -0
  35. cogames_agents/policy/scripted_agent/cogas/goals/gear.py +197 -0
  36. cogames_agents/policy/scripted_agent/cogas/goals/miner.py +441 -0
  37. cogames_agents/policy/scripted_agent/cogas/goals/scout.py +40 -0
  38. cogames_agents/policy/scripted_agent/cogas/goals/scrambler.py +174 -0
  39. cogames_agents/policy/scripted_agent/cogas/goals/shared.py +160 -0
  40. cogames_agents/policy/scripted_agent/cogas/goals/stem.py +60 -0
  41. cogames_agents/policy/scripted_agent/cogas/goals/survive.py +100 -0
  42. cogames_agents/policy/scripted_agent/cogas/navigator.py +401 -0
  43. cogames_agents/policy/scripted_agent/cogas/obs_parser.py +238 -0
  44. cogames_agents/policy/scripted_agent/cogas/policy.py +525 -0
  45. cogames_agents/policy/scripted_agent/cogas/trace.py +69 -0
  46. cogames_agents/policy/scripted_agent/cogsguard/CLAUDE.md +517 -0
  47. cogames_agents/policy/scripted_agent/cogsguard/README.md +252 -0
  48. cogames_agents/policy/scripted_agent/cogsguard/__init__.py +74 -0
  49. cogames_agents/policy/scripted_agent/cogsguard/aligned_junction_held_investigation.md +152 -0
  50. cogames_agents/policy/scripted_agent/cogsguard/aligner.py +333 -0
  51. cogames_agents/policy/scripted_agent/cogsguard/behavior_hooks.py +44 -0
  52. cogames_agents/policy/scripted_agent/cogsguard/control_agent.py +323 -0
  53. cogames_agents/policy/scripted_agent/cogsguard/debug_agent.py +533 -0
  54. cogames_agents/policy/scripted_agent/cogsguard/miner.py +589 -0
  55. cogames_agents/policy/scripted_agent/cogsguard/options.py +67 -0
  56. cogames_agents/policy/scripted_agent/cogsguard/parity_metrics.py +36 -0
  57. cogames_agents/policy/scripted_agent/cogsguard/policy.py +1967 -0
  58. cogames_agents/policy/scripted_agent/cogsguard/prereq_trace.py +33 -0
  59. cogames_agents/policy/scripted_agent/cogsguard/role_trace.py +50 -0
  60. cogames_agents/policy/scripted_agent/cogsguard/roles.py +31 -0
  61. cogames_agents/policy/scripted_agent/cogsguard/rollout_trace.py +40 -0
  62. cogames_agents/policy/scripted_agent/cogsguard/scout.py +69 -0
  63. cogames_agents/policy/scripted_agent/cogsguard/scrambler.py +350 -0
  64. cogames_agents/policy/scripted_agent/cogsguard/targeted_agent.py +418 -0
  65. cogames_agents/policy/scripted_agent/cogsguard/teacher.py +224 -0
  66. cogames_agents/policy/scripted_agent/cogsguard/types.py +381 -0
  67. cogames_agents/policy/scripted_agent/cogsguard/v2_agent.py +49 -0
  68. cogames_agents/policy/scripted_agent/common/__init__.py +0 -0
  69. cogames_agents/policy/scripted_agent/common/geometry.py +24 -0
  70. cogames_agents/policy/scripted_agent/common/roles.py +34 -0
  71. cogames_agents/policy/scripted_agent/common/tag_utils.py +48 -0
  72. cogames_agents/policy/scripted_agent/demo_policy.py +242 -0
  73. cogames_agents/policy/scripted_agent/pathfinding.py +126 -0
  74. cogames_agents/policy/scripted_agent/pinky/DESIGN.md +317 -0
  75. cogames_agents/policy/scripted_agent/pinky/__init__.py +5 -0
  76. cogames_agents/policy/scripted_agent/pinky/behaviors/__init__.py +17 -0
  77. cogames_agents/policy/scripted_agent/pinky/behaviors/aligner.py +400 -0
  78. cogames_agents/policy/scripted_agent/pinky/behaviors/base.py +119 -0
  79. cogames_agents/policy/scripted_agent/pinky/behaviors/miner.py +632 -0
  80. cogames_agents/policy/scripted_agent/pinky/behaviors/scout.py +138 -0
  81. cogames_agents/policy/scripted_agent/pinky/behaviors/scrambler.py +433 -0
  82. cogames_agents/policy/scripted_agent/pinky/policy.py +570 -0
  83. cogames_agents/policy/scripted_agent/pinky/services/__init__.py +7 -0
  84. cogames_agents/policy/scripted_agent/pinky/services/map_tracker.py +808 -0
  85. cogames_agents/policy/scripted_agent/pinky/services/navigator.py +864 -0
  86. cogames_agents/policy/scripted_agent/pinky/services/safety.py +189 -0
  87. cogames_agents/policy/scripted_agent/pinky/state.py +299 -0
  88. cogames_agents/policy/scripted_agent/pinky/types.py +138 -0
  89. cogames_agents/policy/scripted_agent/planky/CLAUDE.md +124 -0
  90. cogames_agents/policy/scripted_agent/planky/IMPROVEMENTS.md +160 -0
  91. cogames_agents/policy/scripted_agent/planky/NOTES.md +153 -0
  92. cogames_agents/policy/scripted_agent/planky/PLAN.md +254 -0
  93. cogames_agents/policy/scripted_agent/planky/README.md +214 -0
  94. cogames_agents/policy/scripted_agent/planky/STRATEGY.md +100 -0
  95. cogames_agents/policy/scripted_agent/planky/__init__.py +5 -0
  96. cogames_agents/policy/scripted_agent/planky/context.py +68 -0
  97. cogames_agents/policy/scripted_agent/planky/entity_map.py +152 -0
  98. cogames_agents/policy/scripted_agent/planky/goal.py +107 -0
  99. cogames_agents/policy/scripted_agent/planky/goals/__init__.py +27 -0
  100. cogames_agents/policy/scripted_agent/planky/goals/aligner.py +168 -0
  101. cogames_agents/policy/scripted_agent/planky/goals/gear.py +179 -0
  102. cogames_agents/policy/scripted_agent/planky/goals/miner.py +416 -0
  103. cogames_agents/policy/scripted_agent/planky/goals/scout.py +40 -0
  104. cogames_agents/policy/scripted_agent/planky/goals/scrambler.py +174 -0
  105. cogames_agents/policy/scripted_agent/planky/goals/shared.py +160 -0
  106. cogames_agents/policy/scripted_agent/planky/goals/stem.py +49 -0
  107. cogames_agents/policy/scripted_agent/planky/goals/survive.py +96 -0
  108. cogames_agents/policy/scripted_agent/planky/navigator.py +388 -0
  109. cogames_agents/policy/scripted_agent/planky/obs_parser.py +238 -0
  110. cogames_agents/policy/scripted_agent/planky/policy.py +485 -0
  111. cogames_agents/policy/scripted_agent/planky/tests/__init__.py +0 -0
  112. cogames_agents/policy/scripted_agent/planky/tests/conftest.py +66 -0
  113. cogames_agents/policy/scripted_agent/planky/tests/helpers.py +152 -0
  114. cogames_agents/policy/scripted_agent/planky/tests/test_aligner.py +24 -0
  115. cogames_agents/policy/scripted_agent/planky/tests/test_miner.py +30 -0
  116. cogames_agents/policy/scripted_agent/planky/tests/test_scout.py +15 -0
  117. cogames_agents/policy/scripted_agent/planky/tests/test_scrambler.py +29 -0
  118. cogames_agents/policy/scripted_agent/planky/tests/test_stem.py +36 -0
  119. cogames_agents/policy/scripted_agent/planky/trace.py +69 -0
  120. cogames_agents/policy/scripted_agent/types.py +239 -0
  121. cogames_agents/policy/scripted_agent/unclipping_agent.py +461 -0
  122. cogames_agents/policy/scripted_agent/utils.py +381 -0
  123. cogames_agents/policy/scripted_registry.py +80 -0
  124. cogames_agents/py.typed +0 -0
  125. cogames_agents-0.0.0.7.dist-info/METADATA +98 -0
  126. cogames_agents-0.0.0.7.dist-info/RECORD +128 -0
  127. cogames_agents-0.0.0.7.dist-info/WHEEL +6 -0
  128. cogames_agents-0.0.0.7.dist-info/top_level.txt +1 -0
@@ -0,0 +1,517 @@
1
+ # CLAUDE.md - Debugging Guide for CoGsGuard Policy
2
+
3
+ Guide for AI assistants debugging this scripted agent policy.
4
+
5
+ ## Python Debug Harness (Recommended)
6
+
7
+ The `debug_agent.py` harness provides programmatic access to simulation state for diagnosing issues.
8
+
9
+ ### Quick Start
10
+
11
+ ```python
12
+ from cogames_agents.policy.scripted_agent.cogsguard.debug_agent import DebugHarness
13
+
14
+ # Create harness from recipe
15
+ harness = DebugHarness.from_recipe(num_agents=10, seed=42)
16
+
17
+ # Step through simulation
18
+ harness.step(50)
19
+
20
+ # Print agent summary
21
+ harness.print_agent_summary()
22
+
23
+ # Find stuck agents and diagnose
24
+ stuck = harness.diagnose_stuck_agents(threshold=10)
25
+
26
+ # Diagnose coordinate issues (common bug)
27
+ harness.diagnose_coordinate_system()
28
+ ```
29
+
30
+ ### Key Methods
31
+
32
+ | Method | Description |
33
+ | --------------------------------------- | ------------------------------------ |
34
+ | `step(n)` | Run n simulation steps |
35
+ | `print_agent_summary(ids)` | Print state summary for agents |
36
+ | `print_simulation_info()` | Print object types and hub locations |
37
+ | `diagnose_stuck_agents(threshold)` | Find and diagnose stuck agents |
38
+ | `diagnose_coordinate_system()` | Check for coordinate mismatches |
39
+ | `run_until_stuck(threshold, max_steps)` | Run until agent stuck |
40
+ | `get_agent_state(id)` | Get internal policy state |
41
+ | `get_grid_objects()` | Get all simulation objects |
42
+ | `find_hubs()` | Get actual hub positions |
43
+
44
+ ### Common Diagnostic Patterns
45
+
46
+ ```python
47
+ # Check if internal positions match simulation
48
+ harness.diagnose_coordinate_system()
49
+
50
+ # Inspect specific agent state
51
+ from cogames_agents.policy.scripted_agent.cogsguard.types import StructureType
52
+ state = harness.get_agent_state(0)
53
+ print(f"Role: {state.role}, Phase: {state.phase}")
54
+ print(f"Position: ({state.row}, {state.col})")
55
+ print(f"Known hub: {state.get_structure_position(StructureType.ASSEMBLER)}")
56
+
57
+ # Check actual vs believed hub positions
58
+ actual = harness.find_hubs()
59
+ for i in range(harness.num_agents):
60
+ info = harness.agent_info[i]
61
+ print(f"Agent {i}: believes hub at {info.hub_pos}, actual: {actual}")
62
+
63
+ # Run until issues appear
64
+ harness.run_until_stuck(threshold=10, max_steps=200)
65
+ ```
66
+
67
+ ### Run from Command Line
68
+
69
+ ```bash
70
+ cd /path/to/metta
71
+ uv run python -c "
72
+ from cogames_agents.policy.scripted_agent.cogsguard.debug_agent import DebugHarness
73
+ h = DebugHarness.from_recipe(num_agents=10)
74
+ h.step(100)
75
+ h.diagnose_stuck_agents()
76
+ h.diagnose_coordinate_system()
77
+ "
78
+ ```
79
+
80
+ ## Coordinate System
81
+
82
+ **IMPORTANT**: Agents track positions **relative to their starting point**, not absolute map coordinates.
83
+
84
+ - Agents start at internal position `(0, 0)` (their origin)
85
+ - All positions are stored relative to this origin
86
+ - The actual map size is irrelevant - only relative offsets matter
87
+ - If you see position mismatches, the coordinate tracking is broken
88
+
89
+ ### Diagnosing Coordinate Issues
90
+
91
+ The most common bug is agents storing wrong object positions. Use the debug harness:
92
+
93
+ ```python
94
+ harness = DebugHarness.from_recipe()
95
+ harness.step(50)
96
+ harness.diagnose_coordinate_system()
97
+
98
+ # Output will show:
99
+ # - Actual hub positions in simulation
100
+ # - What each agent believes the hub position is
101
+ # - Whether there's a mismatch
102
+ ```
103
+
104
+ ## Vibe-Based Role System
105
+
106
+ Agents use **vibes** to determine their behavior:
107
+
108
+ | Vibe | Behavior |
109
+ | ----------- | --------------------------------------------------------------------------- |
110
+ | `default` | Do nothing (noop) |
111
+ | `gear` | Pick a smart role (scout/miner/aligner/scrambler), change vibe to that role |
112
+ | `miner` | Get miner gear if needed, then mine resources |
113
+ | `scout` | Get scout gear if needed, then explore |
114
+ | `aligner` | Get aligner gear if needed, then align junctions to cogs |
115
+ | `scrambler` | Get scrambler gear if needed, then scramble enemy junctions |
116
+ | `heart` | Do nothing (noop) |
117
+
118
+ ## Quick Start
119
+
120
+ ```bash
121
+ # Run with limited steps and log output (no GUI)
122
+ ./tools/run.py recipes.experiment.cogsguard.play policy_uri=metta://policy/role render=log max_steps=100
123
+
124
+ # Custom vibe distribution: 4 miners, 2 scramblers, 1 gear
125
+ ./tools/run.py recipes.experiment.cogsguard.play \
126
+ policy_uri="metta://policy/role?miner=4&scrambler=2&gear=1" render=log max_steps=100
127
+
128
+ # Filter output for specific agent
129
+ ./tools/run.py ... 2>&1 | grep -E "^\[A0\]"
130
+
131
+ # Filter for specific events
132
+ ./tools/run.py ... 2>&1 | grep -E "HAS_GEAR|DISCOVERED|MINER:|GEAR_VIBE"
133
+
134
+ # Filter for initial vibe assignments
135
+ ./tools/run.py ... 2>&1 | grep -E "INITIAL_VIBE"
136
+ ```
137
+
138
+ ### Initial Vibe URI Parameters
139
+
140
+ Control agent role distribution via query parameters:
141
+
142
+ ```
143
+ metta://policy/role?miner=4&scrambler=2&gear=1&aligner=2&scout=1
144
+ ```
145
+
146
+ - `miner`, `scout`, `aligner`, `scrambler`: Count for each role
147
+ - `gear`: Agents that pick a smart role
148
+ - Assignment order: `scrambler → aligner → miner → scout → gear`
149
+ - Default: `scrambler=1, miner=4`
150
+
151
+ ## Enable Debug Mode
152
+
153
+ Set `DEBUG = True` in `policy.py`:
154
+
155
+ ```python
156
+ DEBUG = True # Line ~48
157
+ ```
158
+
159
+ This enables detailed logging for:
160
+
161
+ - Agent step summaries: `[A0] Step 1: vibe=gear role=miner | Phase=get_gear | ...`
162
+ - Vibe transitions: `[A0] GEAR_VIBE: Picking role vibe: scout`
163
+ - Discovery events: `[A0] DISCOVERED miner_station at (105, 100)`
164
+ - Phase transitions and decisions
165
+
166
+ ## Debugging Workflow
167
+
168
+ ### 1. Identify the Problem
169
+
170
+ Run with logging and observe which agents/vibes are misbehaving:
171
+
172
+ ```bash
173
+ ./tools/run.py ... render=log max_steps=100 2>&1 | grep -E "^\[A[0-9]\] Step 50:"
174
+ ```
175
+
176
+ Note: Roles are now dynamic based on vibes. Check what vibe each agent has:
177
+
178
+ ```bash
179
+ ./tools/run.py ... 2>&1 | grep -E "^\[A[0-9]\].*vibe="
180
+ ```
181
+
182
+ ### 2. Trace a Single Agent
183
+
184
+ Focus on one problematic agent:
185
+
186
+ ```bash
187
+ # All output for agent A2
188
+ ./tools/run.py ... 2>&1 | grep -E "^\[A2\]" | head -50
189
+
190
+ # Just step summaries
191
+ ./tools/run.py ... 2>&1 | grep -E "^\[A2\].*Step [0-9]+:" | head -30
192
+ ```
193
+
194
+ ### 3. Check Phase Transitions
195
+
196
+ Verify agents progress through phases:
197
+
198
+ ```bash
199
+ # Find when agent gets gear
200
+ ./tools/run.py ... 2>&1 | grep -E "^\[A2\].*(HAS_GEAR|execute_role)"
201
+
202
+ # Check if stuck in get_gear
203
+ ./tools/run.py ... 2>&1 | grep -E "^\[A2\].*get_gear" | tail -10
204
+ ```
205
+
206
+ ### 4. Debug Discovery
207
+
208
+ Check if agent finds required structures:
209
+
210
+ ```bash
211
+ # What does agent discover?
212
+ ./tools/run.py ... 2>&1 | grep -E "^\[A2\].*DISCOVERED"
213
+
214
+ # Specifically gear stations
215
+ ./tools/run.py ... 2>&1 | grep -E "DISCOVERED.*station"
216
+ ```
217
+
218
+ ### 5. Debug Pathfinding
219
+
220
+ Check if agent navigates correctly:
221
+
222
+ ```bash
223
+ # Track position changes
224
+ ./tools/run.py ... 2>&1 | grep -E "^\[A2\].*Pos=" | head -20
225
+
226
+ # Check if stuck (same position repeated)
227
+ ./tools/run.py ... 2>&1 | grep -E "^\[A2\].*Step" | tail -20
228
+ ```
229
+
230
+ ## Common Issues
231
+
232
+ ### Initial Vibe Not Applied
233
+
234
+ **Symptom**: Agent doesn't switch to expected initial vibe from URI params
235
+
236
+ **Check**:
237
+
238
+ ```bash
239
+ # Look for initial vibe assignment messages
240
+ grep -E "INITIAL_VIBE|CogsguardPolicy.*Initial vibe"
241
+
242
+ # Check what vibe agent actually has
243
+ grep -E "^\[A0\].*vibe="
244
+ ```
245
+
246
+ **Causes**:
247
+
248
+ 1. URI params not parsed correctly (check quoting in shell)
249
+ 2. Agent ID exceeds configured count (only agents 0..N-1 get assigned vibes)
250
+
251
+ **Debug**: The policy logs initial vibe assignment at startup:
252
+
253
+ ```
254
+ [CogsguardPolicy] Initial vibe assignment: ['scrambler', 'miner', 'miner', 'miner', 'miner']
255
+ ```
256
+
257
+ ### Agent Stuck in GET_GEAR Phase
258
+
259
+ **Symptom**: Agent never reaches `execute_role` phase **Check**:
260
+
261
+ ```bash
262
+ grep -E "^\[A2\].*DISCOVERED.*aligner_station"
263
+ ```
264
+
265
+ **Causes**:
266
+
267
+ 1. Exploration not reaching station location
268
+ 2. Station not being discovered (wrong object name pattern)
269
+
270
+ **Fix**: Adjust exploration in `_explore()` or discovery in `_update_occupancy_and_discover()`
271
+
272
+ ### Agent Adjacent but Not Getting Gear
273
+
274
+ **Symptom**: "Adjacent to X_station, bumping it!" repeated but still NO_GEAR **Check**:
275
+
276
+ ```bash
277
+ grep -E "^\[A2\].*GET_GEAR.*adjacent"
278
+ ```
279
+
280
+ **Causes**:
281
+
282
+ 1. Commons out of resources (gear_costs not met)
283
+ 2. Agent not aligned with station's commons
284
+
285
+ **Debug**: Check commons inventory in game state output
286
+
287
+ ### Position Not Updating
288
+
289
+ **Symptom**: Same `Pos=(x,y)` for many steps **Causes**:
290
+
291
+ 1. Movement blocked by obstacle/wall
292
+ 2. `using_object_this_step` flag blocking position update
293
+ 3. Low energy causing action delay (not failure)
294
+
295
+ **Debug**: Check `last_action_executed` vs `last_action` (intended) for mismatches.
296
+
297
+ ### Position Tracking Drift
298
+
299
+ **Symptom**: Agent's internal position diverges from actual simulation position over time.
300
+
301
+ **Key insight**: Position only updates when intended action matches executed action:
302
+
303
+ - Agent intends `move_east`, simulator executes `move_east` → position updates
304
+ - Agent intends `move_east`, simulator executes `noop` (failed) → position stays
305
+ - Human moves cog with `move_north`, agent intended `noop` → position stays frozen
306
+
307
+ **Human takeover behavior**: When a human takes control and moves a cog, the agent's internal position does NOT update.
308
+ This is intentional - it keeps the agent's internal map consistent. When control returns to the agent, it continues from
309
+ where it "thinks" it is.
310
+
311
+ **1-step lag**: Internal position is always 1 step behind simulation because:
312
+
313
+ - At step N, we read `last_action` = step N-1's executed action
314
+ - We update internal position based on step N-1
315
+ - Then sim.step() executes step N's action
316
+
317
+ This lag is expected and correct. To verify position tracking:
318
+
319
+ ```python
320
+ # int_delta[N] should equal act_delta[N-1]
321
+ harness.track_position_drift(num_steps=50)
322
+ ```
323
+
324
+ ### Coordinate Mismatch (Agent Thinks Hub is Elsewhere)
325
+
326
+ **Symptom**: Agent tries to deposit but cargo never decreases. Debug harness shows:
327
+
328
+ ```
329
+ Agent X: believes hub at (100, 102), actual: [(29, 29)]
330
+ ```
331
+
332
+ **Note**: Internal coords are RELATIVE (centered at 100,100), simulation coords are ABSOLUTE. These will NOT match
333
+ directly - compare DELTAS instead.
334
+
335
+ **Causes**:
336
+
337
+ 1. Position drift from second-guessing simulator's `last_action`
338
+ 2. Not updating position when `last_action` is a successful move
339
+ 3. Timing mismatch checking occupancy from wrong timestep
340
+
341
+ **Diagnose with harness**:
342
+
343
+ ```python
344
+ harness = DebugHarness.from_recipe()
345
+ harness.step(100)
346
+ harness.verify_position_tracking() # Check for drift
347
+ harness.diagnose_coordinate_system()
348
+ ```
349
+
350
+ **Fix**: In `_update_agent_position`, trust `last_action_executed` from observation. If it says `move_X`, update
351
+ position unconditionally (simulator already validated the move).
352
+
353
+ ### Role-Specific Debugging
354
+
355
+ #### Miner Issues
356
+
357
+ ```bash
358
+ # Check extractor discovery
359
+ grep "DISCOVERED.*extractor"
360
+
361
+ # Check cargo levels
362
+ grep "MINER: cargo="
363
+ ```
364
+
365
+ #### Aligner Issues
366
+
367
+ ```bash
368
+ # Check influence/heart levels
369
+ grep "ALIGNER_EXEC: influence=.*, heart="
370
+
371
+ # Need both influence >= 1 AND heart >= 1 to align
372
+ ```
373
+
374
+ #### Scrambler Issues
375
+
376
+ ```bash
377
+ # Check heart levels (needs >= 1)
378
+ grep "scrambler.*heart="
379
+
380
+ # Check if finding enemy depots
381
+ grep "DISCOVERED.*junction"
382
+ ```
383
+
384
+ ## Adding Debug Output
385
+
386
+ ### Temporary Debug Print
387
+
388
+ ```python
389
+ # In any method, add:
390
+ if s.step_count <= 50: # Limit output
391
+ print(f"[A{s.agent_id}] DEBUG: var={value}")
392
+ ```
393
+
394
+ ### Using DEBUG Flag
395
+
396
+ ```python
397
+ if DEBUG:
398
+ print(f"[A{s.agent_id}] MESSAGE")
399
+
400
+ # Or with step limit:
401
+ if DEBUG and s.step_count <= 100:
402
+ print(f"[A{s.agent_id}] MESSAGE")
403
+ ```
404
+
405
+ ## Key Files to Modify
406
+
407
+ | Issue | File | Method/Class |
408
+ | ------------------- | -------------- | ----------------------------------------- |
409
+ | Initial vibe counts | URI params | `?scrambler=1&miner=4` in policy URI |
410
+ | Initial vibe switch | `policy.py` | `CogsguardMultiRoleImpl._execute_phase()` |
411
+ | Phase logic | `policy.py` | `_update_phase()` |
412
+ | Gear acquisition | `policy.py` | `_do_get_gear()` |
413
+ | Object discovery | `policy.py` | `_update_occupancy_and_discover()` |
414
+ | Exploration | `policy.py` | `_explore()` |
415
+ | Pathfinding | `policy.py` | `_move_towards()` |
416
+ | Miner behavior | `miner.py` | `execute_role()` |
417
+ | Aligner behavior | `aligner.py` | `execute_role()` |
418
+ | Scrambler behavior | `scrambler.py` | `execute_role()` |
419
+ | Scout behavior | `scout.py` | `execute_role()` |
420
+
421
+ ## Game State Output
422
+
423
+ At episode end, the log shows game state:
424
+
425
+ ```
426
+ {'cogs': {'aligned.hub': 1.0, ...},
427
+ 'clips': {'aligned.junction': 42.0}}
428
+ ```
429
+
430
+ This helps verify:
431
+
432
+ - Did cogs align any depots?
433
+ - Are miners depositing resources?
434
+ - Is the scrambler working (junction alignment decreasing)?
435
+
436
+ ## Action Failure Detection and Retry System
437
+
438
+ Moves require energy. If an agent doesn't have enough energy, the move fails silently (simulator executes `noop`
439
+ instead).
440
+
441
+ **Key insight**: Agents auto-regenerate energy every step, and regenerate full energy when near aligned buildings (like
442
+ the nexus AOE). So we don't need complex "go recharge" logic - just detect failures and retry.
443
+
444
+ ### How It Works
445
+
446
+ 1. **Track intended vs executed actions**: Compare `last_action` (what we wanted) vs `last_action_executed` (from
447
+ observation - what simulator did)
448
+ 2. **Detect action success**: By comparing before/after state (hearts, cargo)
449
+ 3. **Retry failed actions**: Up to MAX_RETRIES (default 3) times - agent will have auto-regened energy
450
+
451
+ ### Action Success Detection
452
+
453
+ - **Scramble/Align**: Success detected when heart count decreases (consumes 1 heart)
454
+ - **Mine**: Success detected when cargo increases
455
+ - **Move**: Success detected when `last_action_executed` matches intended action
456
+
457
+ ### Position Tracking
458
+
459
+ **CRITICAL**: Position is only updated when the agent's intended move matches the executed move:
460
+
461
+ ```python
462
+ # Only update if WE intended this move (not human control)
463
+ if intended_action == executed_action and executed_action.startswith("move_"):
464
+ # Update position
465
+ ```
466
+
467
+ This design ensures:
468
+
469
+ 1. Position doesn't update when moves fail (executed=noop vs intended=move_X)
470
+ 2. Position stays frozen when a human takes over and moves the cog around
471
+ 3. When control returns to the agent, its internal map remains consistent
472
+
473
+ ### Debugging Action Failures
474
+
475
+ ```bash
476
+ # See move failures (action mismatch)
477
+ grep "ACTION_MISMATCH"
478
+
479
+ # Check for retry messages
480
+ grep -E "retrying|failed after.*retries"
481
+
482
+ # Track action success
483
+ grep -E "succeeded|failed"
484
+ ```
485
+
486
+ ## Useful Grep Patterns
487
+
488
+ ```bash
489
+ # Initial vibe assignment (policy startup)
490
+ grep "Initial vibe assignment"
491
+
492
+ # Initial vibe switches (per agent)
493
+ grep "INITIAL_VIBE"
494
+
495
+ # All discoveries
496
+ grep "DISCOVERED"
497
+
498
+ # All role executions
499
+ grep "execute_role"
500
+
501
+ # Energy tracking
502
+ grep "Energy="
503
+
504
+ # Specific action types
505
+ grep "Action=move_"
506
+ grep "Action=noop"
507
+
508
+ # Phase changes
509
+ grep "Phase="
510
+
511
+ # Vibe transitions
512
+ grep "GEAR_VIBE\|change_vibe"
513
+
514
+ # Action retry tracking
515
+ grep -E "SCRAMBLING|ALIGNING|MINING"
516
+ grep -E "retry|failed|succeeded"
517
+ ```