Skip to content

Commit ec36fe5

Browse files
committed
expand project handoff plan
1 parent d38fdd7 commit ec36fe5

1 file changed

Lines changed: 158 additions & 3 deletions

File tree

docs/plan.md

Lines changed: 158 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,102 @@ The full local verification command is:
3232
python 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

37133
This project is an educational collection of interactive robotics loops. It is
@@ -136,6 +232,15 @@ Next candidates:
136232
2. one continuous-control example such as `MovingObstacleWorld`
137233
3. 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+
139244
Rules:
140245

141246
- adapters must be importable without Gymnasium installed
@@ -178,7 +283,7 @@ Selection rule:
178283

179284
Goal: 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:
190295
Tasks:
191296

192297
1. 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

194302
Acceptance criteria:
195303

@@ -211,8 +319,9 @@ Current status:
211319

212320
Next:
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:
272381
6. `scripts/make_gifs.py` if it needs a GIF
273382
7. 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

277400
Keep test types small and explicit:
@@ -302,6 +425,38 @@ A new example is done when:
302425
7. GIF exists if the example is a major teaching example
303426
8. `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

307462
These are intentionally deferred:

0 commit comments

Comments
 (0)