Repository navigation
openRepoShape: --doctor's shape_checkout runs git clone before checked_ref, so a ref it refuses (a.lock/b, a//b, one over 255 characters) costs a whole clone first, and where the clone fails the ref's refusal is never reached #942
Description
Goal: the launcher's --doctor checks $OPENREPOSHAPE_REF before it clones the standard. A ref checked_ref refuses (a.lock/b, a/.b, a//b, a/b/, a., topic.lock, one over 255 characters) then makes no clone, and the test that names this order pins it.
Filed by lane openRepoShape-2 on Brett Heap's word ("file all", 2026-10-18T14:45:31Z).
- Source: w874, setup.sh, install.sh and the openRepoShape command: each keeps its own copy of the old ref rule (
*..* | *.lock), so a ref git refuses part by part (a.lock/b,a/.b,a//b) clones the standard before it fails #874's writer, found it and left it alone: "openRepoShape:834runsgit cloneinshape_checkoutbeforechecked_refat:839.test_a_ref_the_doctor_would_check_out_is_validatedpins that order in its docstring ... Movingchecked_refabove the clone is a one-line change for a later issue." rv874, lane 2's independent review of setup.sh, install.sh and openRepoShape: a ref git refuses part by part (a.lock/b,a/.b,a//b,a/b/,a.) is refused by each of them before the clone, the fetch or the record, and each refusal states git's rule #875 (setup.sh, install.sh and the openRepoShape command: each keeps its own copy of the old ref rule (*..* | *.lock), so a ref git refuses part by part (a.lock/b,a/.b,a//b) clones the standard before it fails #874), confirmed it by probe (NIT 8): 1git cloneand 0 checkouts, then the refusal. - Why it is not setup.sh, install.sh and the openRepoShape command: each keeps its own copy of the old ref rule (
*..* | *.lock), so a ref git refuses part by part (a.lock/b,a/.b,a//b) clones the standard before it fails #874's: setup.sh, install.sh and the openRepoShape command: each keeps its own copy of the old ref rule (*..* | *.lock), so a ref git refuses part by part (a.lock/b,a/.b,a//b) clones the standard before it fails #874 madesetup.sh,install.shand the launcher refuse a ref git refuses part by part, and kept the order, which the old rule had too (a..bwas refused after the clone as well). - openRepoShape in Git Bash: the
machine:report probespython3alone, a drive-letter$OPENREPOSHAPE_REPOor$OPENREPOSHAPE_BIN_DIRis misread,tests-git-bashskips #598's installer cases, and a doctor test's docstring is stale #649, closed in v1.1.0: lane 5 had filed the stale docstring of that test, which said the refusal "has to arrive before any clone does". The direction was "reword the docstring to say the clone comes first, or check the ref before the clone". openRepoShape in Git Bash: themachine:row findspython, a drive-letter$OPENREPOSHAPE_REPOis a path, a Windows-spelled$OPENREPOSHAPE_BIN_DIRis respelled or refused, andtests-git-bashruns #598's installer cases (#649) #656 (35133f29) took the first: its body says "The docstring now says that. The order is unchanged." This issue takes the second. - Why it is filed: the tracking issues' rule (Tracking: setup, scaffold, family and the shared helpers, creating projects and families #459 and Tracking: the test suite, CI and the docs #461, "Known limits", Brett Heap 2026-10-12) puts a new edge case on a checklist. His word above overrides it for this one.
Lands on: main at 50178305, the v1.1.1 release commit. Every path:line below is read there. None of the six open PRs touches openRepoShape or tests/test_openreposhape_command.py (the coordinator's check, 2026-10-18T14:48Z).
Lines
-
shape_checkoutclones, then checks the ref.- The clone is
openRepoShape:834:git clone --quiet -- "$url" "$SHAPE_DIR" ||(:834-837). The check is:839,checked_ref "$REF", insideif [ "$REF_NAMED" -eq 1 ]; then(:838), andgit checkoutis:845. - Nothing between them needs the clone.
:835-837is the clone's own refusal text and:838is theif.checked_ref(:920-924) callsref_fault(:882-898), which reads only the value and the name it is given. Nothing inref_faultorchecked_reflooks at$SHAPE_DIR. run_doctor(:1010-1024) reachesshape_checkoutonly where no checkout of the standard sits beside the command: the installed copy, or a script arriving on stdin.
- The clone is
- A refused ref costs a whole clone first.
-
Measured with an installed copy of the launcher at
50178305(no checkout beside it),--doctor <an empty directory>,OPENREPOSHAPE_REPOa local bare repository (a copy of this repository's object database: 14,372 loose objects and 48 packs), bash 5.2.21, git 2.43.0,LC_ALL=C.UTF-8, and agitfirst onPATHthat logs its arguments and runs/usr/bin/git. The host's load average was 51, which is why the same clone took 3.6 s in one row and 16.3 s in another:OPENREPOSHAPE_REFexit git clonegit checkoutwhole run left in $TMPDIRa.lock/b2 1 0 15.7 s nothing a/.b2 1 0 17.7 s nothing a//b2 1 0 9.3 s nothing a/b/2 1 0 4.4 s nothing a.2 1 0 5.2 s nothing topic.lock2 1 0 4.5 s nothing a256 times2 1 0 13.7 s nothing main, a ref that is taken2 (the empty directory is no shape root) 1 1 16.1 s the clone, kept by design (openRepoShape --doctor, the form AGENTS.md names first and the one --installgives a person, prints every NEXT command as a path into its temporary clone of the standard, which its EXIT trap deletes before the person can paste the command, so each one fails withcan't open file; and it refuses--jsonand--placement-plan, which AGENTS.md's doctor steps 7 and 4 use #500) -
Each refusal is
ref_fault's sentence for that value, as it is without the clone:REFUSED: $OPENREPOSHAPE_REF is 'a.lock/b', which is not a branch, tag or commit this tool will pass to `git checkout`: a ref starts with an ASCII letter or digit, uses only ASCII letters, digits, '.', '_', '/', '-', has no '..' (git reads it as a revision range), no empty part between slashes ('//', or a '/' at the end), no part that starts with '.' or ends in '.lock' (the name git gives the lock file it writes beside a ref), and does not end in '.'.The 256-character one is$OPENREPOSHAPE_REF is 256 characters long; a branch, tag or commit this tool will pass to `git checkout` is at most 255 characters.(:887). -
The size of the clone (
--doctor's clone has no--depth,:821-825):du -skof the clone is 418,780 KB in 14,910 files. A clone of a local path hardlinksobjects/(404,116 KB of that), so about 14.7 MB is new on disk, the 366 files of the working tree. A URL clone sends a pack instead: the objects reachable from that copy's heads and tags,git rev-list --objects --branches --tags | git pack-objects --stdout, are 9,504,547 bytes (8,087 objects). -
The folder is removed: every refused row leaves
$TMPDIRempty, because the EXIT trap removes the clone. Only a doctor that ran keeps one.
-
- Where the clone fails, the ref's refusal is never reached.
- Measured with
OPENREPOSHAPE_REPO=/nonexistent/openRepoShape.gitandOPENREPOSHAPE_REF=a.lock/b: exit 2 andREFUSED: could not clone /nonexistent/openRepoShape.git into a temporary directory, so there is no standard to check against. `--doctor` needs one: ..., after 1git clone. The ref is not named. With the check first (a scratch copy), the same run is the ref's refusal and nogitcall. - So offline, or with a mirror that is down, a person who typed a bad ref is told to make the clone work, then told the ref is bad once it does.
- Measured with
-
refuse_bad_valueschecks only a ref's characters, so only those are caught before the clone.- Since openRepoShape:
--versionand two fetch refusals print$OPENREPOSHAPE_REPOand$OPENREPOSHAPE_REFwith no check, so an escape or a bidi override in either reaches the terminal as typed, and a scaffold run sends its fetch with them #866 (PR openRepoShape:$OPENREPOSHAPE_REPOand$OPENREPOSHAPE_REFare checked once, before--versionanswers and before any fetch, so a control character or a character a terminal draws as another in either is refused, never printed or sent #872)refuse_bad_values(:996-1002) asksref_character_fault(:908-918) of$OPENREPOSHAPE_REFfor every run: a character a terminal draws as another (install.sh and openRepoShape: a$OPENREPOSHAPE_BIN_DIRholding a bidi override, U+200B, U+2028 or U+FEFF passes #804's control-character check and is echoed as typed, so the PATH note can show a directory as another #837), then a control character. Measured: an escape and U+202E in the ref make 0 clones and end in 0.02 s. checked_ref, after the clone, is the only place that refuses the rest ofref_fault: the length over 255 (:886), and the shape (:894-896): a first character that is no letter or digit,.., a part that starts with.or ends in.lock,//, a trailing/or., and any character outsideA-Za-z0-9._/-, a space andcaféamong them (measured:cafémakes 1 clone attempt, then the shape refusal; git takes it,git check-ref-format --branch caféexits 0).- A ref the record holds does not reach this:
read_recorded_ref(:962-980) holds it to the wholeref_faultas it reads it.--doctorbeside a checkout never uses$OPENREPOSHAPE_REFand never asks (measured:a.lock/bthere runs the doctor, exit 2 as for any empty directory).
- Since openRepoShape:
- The test names this order, and does not pin it.
-
test_a_ref_the_doctor_would_check_out_is_validated(tests/test_openreposhape_command.py:1718-1743), five refs (-x,--upload-pack=touch /tmp/pwned, 256a,refs/heads/..,x.lock). openRepoShape in Git Bash: themachine:row findspython, a drive-letter$OPENREPOSHAPE_REPOis a path, a Windows-spelled$OPENREPOSHAPE_BIN_DIRis respelled or refused, andtests-git-bashruns #598's installer cases (#649) #656 left its docstring,:1721-1729:"$OPENREPOSHAPE_REF reaches
git checkout, so it is checked first. ... Run from STDIN so the clone path is the one taken: the command clones this checkout first, then checks the ref, and refuses beforegit checkoutis ever handed it." -
It asserts exit 2,
OPENREPOSHAPE_REFandgit checkoutin stderr, and that the 256-character value is not echoed. It does not look at what ran, so it passes with the check above or below the clone. Measured, on a clone of the repository at50178305with and without the call moved: this test (5 cases),test_a_checkout_without_the_doctor_refuses_by_nameand the 14 cases oftest_a_clone_is_handed_a_path_or_url_as_it_isare 20 passed on both, unchanged. -
It runs
OPENREPOSHAPE_REPOas this checkout, so each of its five cases makes a real clone of the whole repository: the 20 took 188.4 s as it is and 5.4 s with the call moved (a load average above 100 on both runs).
-
What is checked today
shape_checkout(:829-848) clones, then runschecked_ref "$REF"when a ref was named, thengit checkout. The refusal isdie, so the EXIT trap removes the clone.refuse_bad_valueschecks the characters of$OPENREPOSHAPE_REFfirst (openRepoShape:--versionand two fetch refusals print$OPENREPOSHAPE_REPOand$OPENREPOSHAPE_REFwith no check, so an escape or a bidi override in either reaches the terminal as typed, and a scaffold run sends its fetch with them #866), by design only those:test_a_ref_set_without_the_opt_in_is_never_recordedneeds--installwithbad..refand no opt-in to exit 0, so the length and shape are asked where a ref is used.setup.sh(:239-249) holds the same rule and checks before it clones, andinstall.sh(:163-178) before it fetches the launcher (setup.sh, install.sh and the openRepoShape command: each keeps its own copy of the old ref rule (*..* | *.lock), so a ref git refuses part by part (a.lock/b,a/.b,a//b) clones the standard before it fails #874).
Direction
- Call
checked_ref "$REF"before the clone, inshape_checkout, betweenurl="$(shape_clone_url)"(:831) andworkdir(:832):[ "$REF_NAMED" -eq 0 ] || checked_ref "$REF", and drop the call at:839. The diff is one line added and one removed (measured on a scratch copy).- Keep it in
shape_checkout, not inrefuse_bad_values: the up-front check is characters only on purpose (above), and--doctorbeside a checkout never uses the ref.
- Keep it in
- Make the test pin it: a
gitthat leaves a mark if it is asked to clone, asa_repository_to_clonedoes (tests/test_openreposhape_command.py:1264-1283) or ascloned_fordoes (:2157-2183). Each of the five refs, anda.lock/b,a//b,a.,a/b/andtopic.lock, makes no clone and ends in the refusal with exit 2; a ref that is taken still clones once and checks out once. The test then needs no real clone. - Reword the docstring (
:1721-1729) to say the check comes first and the refusal arrives before any clone, as it said before openRepoShape in Git Bash: themachine:row findspython, a drive-letter$OPENREPOSHAPE_REPOis a path, a Windows-spelled$OPENREPOSHAPE_BIN_DIRis respelled or refused, andtests-git-bashruns #598's installer cases (#649) #656, which is then true. - Nothing else says the order: a search of
docs/,README.md,AGENTS.mdandopenRepoShapefor "clones this checkout", "before any clone", "checks the ref" and "clone comes first" finds no sentence to change.
Verify
tests/test_openreposhape_command.pypasses on Linux.- New cases: a refused ref makes no clone (the fake
gitsees noclone) and nocheckout; a good ref still clones once and checks out once; the refusal's words areref_fault's; andOPENREPOSHAPE_REPO=/nonexistent/...with a bad ref ends in the ref's refusal, not "could not clone". - A stand-in of that test, run in a scratch copy against the launcher as it is and with the call moved (ten refs, a fake
gitwhoseclonefails and logs, plus a good ref): 10 failed, 1 passed as it is (each refused ref asked for a clone), 11 passed with the call moved. - Mutants for the writer to run, each of which the new cases must kill:
- the check moved back below the clone (measured: the stand-in's 10 failures);
- the call dropped;
- the test of
REF_NAMEDinverted, so a named ref is not checked.
Overlaps
- openRepoShape, setup.sh and install.sh: under the
Clocale a$OPENREPOSHAPE_REPOURL or path, or a ref, with a letter past ASCII is refused as "a control character", so--version,--installand--preflightrefuse what v1.1.0 ran #940, filed beside this one forchecked_repoandref_character_fault(the locale's[![:print:]]), editsopenRepoShapeandtests/test_openreposhape_command.pyat other lines (:805-814and:908-918; this one is:829-848and:1718-1743). After that one lands, a refcaféunderCis held as it is underC.UTF-8: it reachesshape_checkout, and is refused after the clone until this lands. - No other open PR touches these files (checked at 2026-10-18T14:48Z).
Parent: #459: the launcher's own items went there, such as #649's machine: block and drive-letter lines, and #649's docstring is this issue's source.
Milestone: v1.2.0. v1.1.1 is released, and lane 3 places issues. A refused ref still exits 2 with the right words wherever the clone works; what is wrong is the wasted clone, and the words where it fails. It needs a ref the person mistyped in $OPENREPOSHAPE_REF, run with --doctor where no checkout sits beside the command.
🤖 Generated with Claude Code
Activity
brettheap commentedon Oct 18, 2026
CLAIMED — lane openRepoShape-2, session 81650e29-c906-4fe8-96c9-55580bfe0c44@Eagle, 2026-10-18T17:39:38Z, for #942
Logged in
lanes/log/openRepoShape-2.mdat99c4e3678a3f94be365c2a5082e108d68c3cee22.The three reads (lane-collision-protocol Rule 1):
tests/test_openreposhape_command.py, openRepoShape and tests.yml: a r…
tests/test_openreposhape_command.py: the good-ref row of the missing-…