You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
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
What is wrong.shape-doctor.py's is_this_member (shape-doctor.py:1969)
decides that the directory beside a family holder IS this member on the
strength of project.yaml alone: it is a git repository, its manifest is a project-manifest, and its id (or, with no id in the row, its name)
matches the family's row. It never looks at the clone's origin.
The family's OWN verifier asks two questions, not one. templates/family-root/scripts/siblings.py:405-437
(verify_sibling) refuses a clone whose origin is not the row's repository:/url with WRONG ORIGINbefore it compares the project id,
and refuses a matching origin with a different id as WRONG PROJECT — "ONE
definition of 'is this the right clone', used by the placement half and by the --make dispatch", as its docstring puts it.
So a fork, a stale clone of a renamed repository, or any copy of the same
project from a different origin sitting at ../<Project> is reported by the
doctor as working_clone, and the members row then says a working checkout
is beside the holder when make siblings would call that same directory WRONG ORIGIN and refuse to touch it. The report and the tool disagree about
the same directory, which is the one thing the doctor is written not to do —
"Every row is somebody else's check."
is_this_member's own docstring already claims the two are the same question:
"scripts/siblings.py::verify_sibling asks the same question before it will
touch a directory, and for the same reason". Today that claim is half true.
Found by Copilot on PR #142 (a pure python:S3776 refactor of five other
functions, where is_this_member is byte-identical); left alone there under
that PR's "behaviour byte-identical" law rather than fixed in a refactor.
What would fix it. Ask the origin question too, in the doctor's own
read-only way:
compare the sibling's git remote get-url origin against the member row's repository: (and .gitmodules' url for the mount, which is what siblings.py resolves first), with the same normalization same_repository
uses — .git, a trailing /, and the scp-vs-url spellings must compare
equal, or a family whose rows are spelled one way and whose clones the other
would go from a false positive to a false negative;
keep it a REPORT and never a refusal: the row would say the sibling is a
clone of something else rather than counting it, and the verdict stays
whatever it is today for a member with no working clone (an ok row — the
workstation layout is not a compliance fact);
the normalization lives in the family template today and shape-doctor.py
imports nothing from templates/, so the fix has a shape decision in it:
either a small local normalizer with the rule written down beside it, or
moving same_repository somewhere both may import (it is also wanted by scripts/family.py);
a regression test in tests/test_shape_doctor.py beside test_an_unrelated_repository_beside_the_holder_is_not_the_member: a
sibling carrying the SAME project.yaml id with a DIFFERENT origin, which
passes today and must not.
(lane openreposhape-2 (openRepoShape-2), 2026-09-12T15:52Z) CLAIMED — session 9c6378ea, on Brett Heap's word 'fix 146'. Branch fix/doctor-member-origin-like-siblings, worktree ~/projects/openRepoShape--i146-member-origin on Eagle, from origin/main 57ddeac. Scope: is_this_member asks the origin question too — the sibling's git remote get-url origin against the .gitmodules url for the mount and the row's repository:, through a normaliser that mirrors siblings.py::same_repository (with a parity test over both), so the members row stops calling a fork or a stale clone the working clone; it stays a report, never a refusal.
(lane openreposhape-2 (openRepoShape-2), 2026-09-12T18:33:34Z) MERGED — #147 → 5c63116 (squash), on Brett Heap's word 'go, fan out on all of it, hold the doctor refactor'. shape-doctor.py: the members row asks the origin question the family's own verifier asks — the sibling's git remote get-url origin against the url the holder mounts the member from (.gitmodules first, family.yaml repository: second, a relative ../Repo.git resolved against the holder's remote), so a fork or a stale clone beside the holder is reported as a clone of something else instead of counted as the working clone; a report, never a refusal; credentials redacted from everything stored or printed; the shared rule lives in the non-pinned shape_materialize.py mirroring siblings.py, bound by a parity test over 24 url pairs; four Copilot/Codex rounds, six real findings taken, one (case-folding of filesystem paths) declined and filed as #149; 1147 passed / 1 skipped; no pinned file. Object complete.
Activity
brettheap commentedon Sep 12, 2026
(lane openreposhape-2 (openRepoShape-2), 2026-09-12T15:52Z) CLAIMED — session 9c6378ea, on Brett Heap's word 'fix 146'. Branch fix/doctor-member-origin-like-siblings, worktree ~/projects/openRepoShape--i146-member-origin on Eagle, from origin/main 57ddeac. Scope:
is_this_memberasks the origin question too — the sibling'sgit remote get-url originagainst the.gitmodulesurl for the mount and the row'srepository:, through a normaliser that mirrorssiblings.py::same_repository(with a parity test over both), so the members row stops calling a fork or a stale clone the working clone; it stays a report, never a refusal.brettheap commentedon Sep 12, 2026
(lane openreposhape-2 (openRepoShape-2), 2026-09-12T16:2xZ) PULL REQUEST OPEN: #147 (head ef0e206).
tests/test_shape_doctor.py: the two new members-row assertions compar…
shape-doctor.py: the members row reads the mount url git itself resol…
shape-doctor.py: a relative member url is resolved by git's own arith…
shape-doctor.py: an unresolvable mount url no longer excuses a siblin…
shape-doctor.py: the members row asks the origin question too, so a f…
brettheap commentedon Sep 12, 2026
(lane openreposhape-2 (openRepoShape-2), 2026-09-12T18:33:34Z) MERGED — #147 → 5c63116 (squash), on Brett Heap's word 'go, fan out on all of it, hold the doctor refactor'. shape-doctor.py: the members row asks the origin question the family's own verifier asks — the sibling's git remote get-url origin against the url the holder mounts the member from (.gitmodules first, family.yaml repository: second, a relative ../Repo.git resolved against the holder's remote), so a fork or a stale clone beside the holder is reported as a clone of something else instead of counted as the working clone; a report, never a refusal; credentials redacted from everything stored or printed; the shared rule lives in the non-pinned shape_materialize.py mirroring siblings.py, bound by a parity test over 24 url pairs; four Copilot/Codex rounds, six real findings taken, one (case-folding of filesystem paths) declined and filed as #149; 1147 passed / 1 skipped; no pinned file. Object complete.
siblings.py and shape-doctor.py answer "is this the same repository" …
The two copies of "is this the same repository" become ONE definition…
siblings.py: the printed move runs as typed past a taken staging name…