@@ -32,6 +32,102 @@ The full local verification command is:
3232python scripts/run_all_smoke_tests.py --check-gifs
3333```
3434
35+ ## Handoff Snapshot
36+
37+ This section is written for the next coding agent. It should be enough to
38+ resume without rereading the whole repository first.
39+
40+ Current repository state:
41+
42+ - Branch: ` main `
43+ - Check the latest pushed commit with ` git log --oneline --decorate -1 ` .
44+ - Latest known GitHub Actions run on ` main ` : green on Python 3.10, 3.11, and
45+ 3.12
46+ - Last local verification command run successfully:
47+
48+ ``` bash
49+ python scripts/run_all_smoke_tests.py --check-gifs
50+ ```
51+
52+ Current high-value files to read before changing code:
53+
54+ 1 . ` docs/implementation_gap_audit.md `
55+ 2 . ` docs/trace.md `
56+ 3 . ` docs/example_authoring.md `
57+ 4 . ` pir/adapters/gymnasium_adapter.py `
58+ 5 . ` tests/test_gymnasium_adapter.py `
59+ 6 . ` examples/navigation/09_blocked_path_recovery.py `
60+
61+ Recent completed work:
62+
63+ - Initial repository contents were committed and pushed.
64+ - CI was confirmed green after the initial push.
65+ - ` DynamicObstacleGridWorldGymnasiumAdapter ` was added.
66+ - Trace summaries were added through ` Trace.summary() ` and
67+ ` summarize_trace(trace) ` .
68+ - ` examples/runtime/26_trace_replay.py ` was added.
69+ - ` docs/trace.md ` was added.
70+ - ` docs/implementation_gap_audit.md ` was added.
71+ - Category READMEs were tightened with more "What this teaches" and "Things to
72+ try" sections.
73+
74+ The next agent should not redo those items. If any of them seem missing, first
75+ check the current branch and latest pulled commit.
76+
77+ Recommended next task:
78+
79+ 1 . Add a clean ` BlockedPathWorld ` Gymnasium adapter.
80+ 2 . Do not import ` examples/navigation/09_blocked_path_recovery.py ` from
81+ ` pir/adapters ` ; that would make package code depend on examples.
82+ 3 . First extract the reusable ` BlockedPathWorld ` environment into a package
83+ module, most likely ` pir/worlds/blocked_path.py ` .
84+ 4 . Keep the example's agent and teaching loop in
85+ ` examples/navigation/09_blocked_path_recovery.py ` .
86+ 5 . Update the example to import the extracted world, but keep its behavior and
87+ smoke assertions unchanged.
88+ 6 . Add ` BlockedPathWorldGymnasiumAdapter ` in
89+ ` pir/adapters/gymnasium_adapter.py ` .
90+ 7 . Export it from ` pir/adapters/__init__.py ` .
91+ 8 . Add focused adapter tests covering reset shape, step shape, action decoding,
92+ success termination, timeout truncation, and recoverable ` blocked_path `
93+ failure.
94+ 9 . Update ` README.md ` , ` docs/status.md ` , and this file if adapter counts or
95+ current status change.
96+ 10 . Run the full verification command before committing or pushing.
97+
98+ Suggested acceptance tests for ` BlockedPathWorldGymnasiumAdapter ` :
99+
100+ - ` reset() ` returns encoded observation keys:
101+ ` time ` , ` robot ` , ` goal ` , ` known_map ` , ` dynamic_blocker ` ,
102+ ` last_blocked_cell ` .
103+ - ` info["raw_obs"] ` preserves the original world observation.
104+ - integer action ` GRID_ACTIONS.index("east") ` decodes to ` "east" ` .
105+ - moving into the goal returns ` terminated=True ` , ` truncated=False ` .
106+ - hitting ` max_steps ` returns ` terminated=False ` , ` truncated=True ` with a
107+ nonrecoverable ` timeout ` failure.
108+ - moving into the active blocker returns ` terminated=False ` , ` truncated=False `
109+ with recoverable ` blocked_path ` .
110+
111+ Preferred implementation boundary:
112+
113+ - ` pir/worlds/blocked_path.py ` : world class and small grid helpers needed by
114+ the world.
115+ - ` examples/navigation/09_blocked_path_recovery.py ` : agent, A* policy,
116+ rendering, and example ` run() ` loop.
117+ - ` pir/adapters/gymnasium_adapter.py ` : adapter only, following the existing
118+ ` GridWorldGymnasiumAdapter ` pattern.
119+
120+ Do not start yet:
121+
122+ - Do not add Gymnasium as a core dependency.
123+ - Do not add ROS2, MuJoCo, PyBullet, Torch, JAX, TensorFlow, Docker, or GPU
124+ requirements.
125+ - Do not convert examples into a framework.
126+ - Do not move shared code into ` pir/ ` unless the move makes package boundaries
127+ cleaner or avoids three-or-more-example repetition.
128+ - Do not regenerate GIFs unless a visible README GIF changes or a new major
129+ example is added.
130+
35131## Product Boundary
36132
37133This project is an educational collection of interactive robotics loops. It is
@@ -136,6 +232,15 @@ Next candidates:
1362322 . one continuous-control example such as ` MovingObstacleWorld `
1372333 . a tiny embodied-AI wrapper for controlled language goals
138234
235+ Detailed next step for ` BlockedPathWorld ` :
236+
237+ - Extract only the world/environment portion from
238+ ` examples/navigation/09_blocked_path_recovery.py ` .
239+ - Keep the example readable and local where possible; the agent and teaching
240+ policy should remain in the example.
241+ - Add the adapter after the package boundary is clean.
242+ - Tests should be added before broadening the adapter API further.
243+
139244Rules:
140245
141246- adapters must be importable without Gymnasium installed
@@ -178,7 +283,7 @@ Selection rule:
178283
179284Goal: make the internal loop easier to inspect after a run.
180285
181- Already done :
286+ Done baseline :
182287
183288- lightweight ` Trace.summary() ` and ` summarize_trace(trace) ` helpers
184289- tests for reward, success, failure-count, terminal/recoverable failure, and
@@ -190,6 +295,9 @@ Already done:
190295Tasks:
191296
1922971 . Keep trace tooling small enough that it does not become a logging framework.
298+ 2 . Only add more trace APIs when at least two examples need the same inspection
299+ pattern.
300+ 3 . Prefer small examples and docs over a generalized replay framework.
193301
194302Acceptance criteria:
195303
@@ -211,8 +319,9 @@ Current status:
211319
212320Next:
213321
214- - extend to selected worlds only when the action and observation mapping stays
215- clear
322+ - add ` BlockedPathWorld ` after extracting the world boundary cleanly
323+ - extend to other selected worlds only when the action and observation mapping
324+ stays clear
216325- keep examples independent from Gymnasium
217326
218327### Simulator Bridge
@@ -272,6 +381,20 @@ When a new example is added, update:
2723816 . ` scripts/make_gifs.py ` if it needs a GIF
2733827 . tests
274383
384+ When a new adapter is added, update:
385+
386+ 1 . ` pir/adapters/gymnasium_adapter.py `
387+ 2 . ` pir/adapters/__init__.py `
388+ 3 . ` tests/test_gymnasium_adapter.py `
389+ 4 . ` README.md ` if it changes the public adapter list
390+ 5 . ` docs/status.md `
391+ 6 . ` docs/plan.md `
392+ 7 . ` docs/simulator_integration_strategy.md ` if bridge status changes
393+
394+ When package code is extracted from an example, keep the example's learner-facing
395+ loop visible. The package module should make boundaries cleaner, not hide the
396+ teaching logic.
397+
275398## Testing Plan
276399
277400Keep test types small and explicit:
@@ -302,6 +425,38 @@ A new example is done when:
3024257 . GIF exists if the example is a major teaching example
3034268 . ` python scripts/run_all_smoke_tests.py --check-gifs ` passes
304427
428+ ## Definition Of Done For A New Adapter
429+
430+ A new optional adapter is done when:
431+
432+ 1 . the adapter module imports without Gymnasium installed
433+ 2 . ` pip install -e ".[rl]" ` provides action and observation spaces
434+ 3 . ` reset() ` returns ` (obs, info) `
435+ 4 . ` step() ` returns ` (obs, reward, terminated, truncated, info) `
436+ 5 . ` info["raw_obs"] ` preserves the unencoded toy-world observation
437+ 6 . action decoding is tested
438+ 7 . success is tested as termination
439+ 8 . timeout is tested as truncation
440+ 9 . at least one domain failure path is tested
441+ 10 . examples are not rewritten around Gymnasium
442+ 11 . ` python scripts/run_all_smoke_tests.py --check-gifs ` passes
443+
444+ ## Suggested Claude Work Plan
445+
446+ If Claude is taking over, the most efficient first pass is:
447+
448+ 1 . Run ` git status --short --branch ` .
449+ 2 . Run ` python scripts/run_all_smoke_tests.py --check-gifs ` if local
450+ dependencies are already installed.
451+ 3 . Read ` examples/navigation/09_blocked_path_recovery.py ` .
452+ 4 . Extract ` BlockedPathWorld ` into ` pir/worlds/blocked_path.py ` .
453+ 5 . Update the example import and keep its smoke test green.
454+ 6 . Add ` BlockedPathWorldGymnasiumAdapter ` .
455+ 7 . Add adapter tests.
456+ 8 . Run ` python -m pytest tests/test_gymnasium_adapter.py -q ` .
457+ 9 . Run the full smoke plus GIF check.
458+ 10 . Commit and push only after the worktree is cleanly understood.
459+
305460## Do Not Start Yet
306461
307462These are intentionally deferred:
0 commit comments