Repository navigation
shape-doctor.py members row: its green note says make siblings places every member with no working clone, a directory make siblings refuses included, so one row says both that it places IRRS and that it leaves IRRS exactly as it is #669
Description
Goal: the members row says, member by member, what make siblings would do with the directory beside the holder, as the holder's scripts/siblings.py decides it. It never says make siblings places a member it will refuse.
Filed by lane openRepoShape-3 on Brett Heap's word of 2026-10-16T12:24:41Z ("give #460 to lane 3").
What happens:
-
check_membersputs every member whose sibling is not counted as its working clone intowithout_working_clone(shape-doctor.py:7574-7575). On the green path one note covers them all: "no working clone beside the holder for (make siblingsplaces them when the holder is in a folder named after its repository, …)" (:7509-7518). -
working_cloneturns a sibling down for several reasons, andmake siblingsrefuses most of them (placeandverify_siblingintemplates/family-root/scripts/siblings.py):at ../<Project>the doctor make siblingsthe note today nothing, or an empty folder not counted clones it true a clone of the member from another remote (shape-doctor.py: the members row calls a beside-the-holder repository the working clone on its project id alone, where the family's own verifier also requires the origin #146) other_originset, stranger sentenceWRONG ORIGIN, left as it is (:484)says both a non-empty folder with no .git(None, None):is_this_memberneeds.git(:6929)NOT A CLONE(:559)false a repository that is not this member (None, None)WRONG ORIGIN(origin asked first) orWRONG PROJECT(:494)false the holder itself (a member named after its family) (None, None)IS THE HOLDER(:548)false a clone at the right origin with no readable project.yaml(read from the code, not run)(None, None)fetched as the member: project_idis None, soverify_siblingpasses itfalse a clone that fails at run time cannot be known beforehand CLONE FAILED(:585)conditional; acceptable -
The contradiction is pinned by a test. R605 measured WRONG ORIGIN and NOT A CLONE on real holders.
test_the_stranger_note_says_from_which_folder_make_siblings_calls_it(tests/test_shape_doctor.py:3703-3723) asserts that one row, for one WRONG ORIGIN member, holds bothSTRANGER_NOTEandPLACES_NOTE(:3720). This predates shape-doctor.py: the members row saysmake siblingsplaces the working clones from a holder in a folder named after its repository, and that from anywhere else it clones nothing and prints the mv, as it does since #578 (#605) #624 (shape-doctor.pymembersrow: once #578 lands, its note saysmake siblingsplaces the clones, which it does only from a folder named after the family #605), which fixed the note's folder condition and left alone what the note is attached to. -
Neither the note nor the stranger sentence says the folder name must match EXACTLY.
parent_folder_warningcomparesfolder.name == family(siblings.py:969), so on macOS and Windows a folderinkrouteris refused forInkRouter.make siblingsprints the rename itself. -
The verdict and exit code are right and must not move.
Where it is (d4a7fab):
shape-doctor.py:members_verdict, :7289-7521 (the stranger sentence at :7323-7329, the note at :7497-7518);check_members, :7551-7578;working_clone, :7128-7186;member_state, :7189-7231;is_this_member, :6913-6938.
- The rules it must agree with, in
templates/family-root/scripts/siblings.py:placeat :529-600,verify_siblingat :460-502,project_idat :449, andparent_folder_warning's exact compare at :969.
The change:
-
Record what stands at
../<Project>.member_statetakes the slot's state inplace's order:- the holder itself;
- a non-empty folder with no
.git; - absent or empty;
- a repository whose origin is not the member's;
- one at the right origin with another id;
- one at the right origin with no readable manifest;
- the working clone.
The
--jsonentry carries this state as a new key, so a caller need not parse prose. -
Say per member what
make siblingsdoes.- The "places them" note names only the absent and empty slots, and keeps its folder condition.
- Every other member gets one sentence in
make siblings's own word (WRONG ORIGIN,NOT A CLONE,WRONG PROJECT,IS THE HOLDER, or "fetched as the member") saying what it does. This holds on the green and the red path alike, as the stranger sentence does today. CLONE FAILEDis not predicted.
-
Say "exactly". The folder condition reads "named exactly after its repository (case included)", in the note and in the stranger sentence.
-
Document what the doctor restates. The doctor restates
place's slot order but not the folder rule, asworking_clonerestatesverify_sibling's questions (shape-doctor.py: the members row calls a beside-the-holder repository the working clone on its project id alone, where the family's own verifier also requires the origin #146). Say so in the docstring. -
Nothing else moves.
without_working_clonekeeps its meaning, and no verdict, exit code or NEXT changes.
Tests (tests/test_shape_doctor.py, the #146 and #605 sections, :3610-3725):
- Invert
test_the_stranger_note_says_from_which_folder_make_siblings_calls_it: the stranger is not in the "places them" note. - One row per slot state, each asserting the sentence, the
--jsonkey,okandCOMPLIANT. - An agreement test: for each state, the holder's own
scripts/siblings.py --dry-run, run from its family folder, gives the doctor's word for that member. PLACES_NOTEandSTRANGER_NOTEgain "exactly".
From #460, #460 (comment) (L16, and the doctor's half of L21)
🤖 Generated with Claude Code
Activity
brettheap commentedon Oct 16, 2026
CLAIMED — lane openRepoShape-3, session b30e8b49-f249-4668-adb1-1dbfa93c09e1@Eagle, 2026-10-16T12:57:19Z, for #669
Logged in
lanes/log/openRepoShape-3.mdat7d3a5e7e7fd4d3ae5c9d3450344b92ed042488d5.The three reads (lane-collision-protocol Rule 1):
shape-doctor.py: the `members` row reads a folder beside the holder i…