Repository navigation
setup.sh: the shim self-bootstraps before it hands over and its pre-scan never looks for --help, so setup.sh --help run from anything but a checkout of the standard (a downloaded copy, curl … | bash -s -- --help, a git archive extraction) clones github.com/opensoft/openRepoShape before printing a word, prints the clone's usage rather than its own, dies with git's exit 128 offline, and makes scripts/render-cli-reference.py in such a tree reach GitHub, though setup-project.py --help answers offline from the same place #341
Description
Lane: openreposhape-4 (openRepoShape-4)
Found by this lane's adversarial review of #295 (PR #312, head eb0658f; its "Process note (disclosure)"). That reviewer ran scripts/render-cli-reference.py --check inside git archive extractions of merged trees, which are not checkouts. ./setup.sh --help then took setup.sh's self-bootstrap path, and the report counts up to ten anonymous, read-only, shallow clones of the public upstream, with nothing written. Since then every probe in this lane runs under GIT_ALLOW_PROTOCOL=file, and none runs a tool's --help, the generator or setup.sh outside a git work tree.
Re-verified on main c7c02fa by reading setup.sh, setup-project.py, openRepoShape and the generator, and by three runs inside a git work tree that is not a checkout of the standard. In each run the clone either named a local path or was refused by git under GIT_ALLOW_PROTOCOL=file, so nothing reached the network. One correction to the review's note: openRepoShape --help does NOT clone. It prints its own usage and exits at its argument loop (openRepoShape:411) before anything is fetched, and setup-project.py --help answers at the top of _main. Only the bash shim takes this path. No open pull request touches these files. Not claimed:
- Windows, where the shim does not run.
- The generator run in a non-checkout tree, which is read and not run here; the review's disclosure is the observed instance.
curl … | bash -s -- --help, which takes the same branch by reading:$SCRIPT_DIRfalls back to the working directory.
What is wrong. setup.sh execs setup-project.py directly only when is_shape_checkout passes (setup.sh:86-92, :109-114 at c7c02fa). Otherwise its section 0 runs:
- A pre-scan of the arguments (
:142-150) that reads--keep-shape-checkoutand--shape-refand nothing else. say "(0) self-bootstrap"andgit clone --quiet [--depth 1] -- "$SHAPE_REPO"(:179-204).SHAPE_REPOdefaults tohttps://github.com/opensoft/openRepoShape.git(:31).- Only then,
setup-project.pyfrom the CLONE with the person's arguments (:221-222). That is where--helpis finally read.
setup-project.py's own _main answers --help first (setup-project.py:1808-1810), before its checkout probe and its own self_bootstrap (:1835-1836). So the two entry points #50 made one flow disagree about whether asking for help is a network act:
# $U: a clean checkout at c7c02fa. D stands for a download: a git work tree that is not a checkout of the standard
# (setup.sh's `is_shape_checkout` wants `scaffold-project.py` at git's top level); a directory with no `.git` takes the same branch.
D=$(mktemp -d) && git init -q "$D" && cp "$U/setup.sh" "$U/setup-project.py" "$D/" && cd "$D"
sed -i.bak 's/^USAGE = """usage: setup-project.py /&(THE COPY BESIDE setup.sh) /' setup-project.py # mark this copy's usage line
python3 setup-project.py --help | head -n 1; echo "exit ${PIPESTATUS[0]}"
# usage: setup-project.py (THE COPY BESIDE setup.sh) [<Project>] [options] [-- <extra scaffold flags>]
# exit 0
GIT_ALLOW_PROTOCOL=file bash setup.sh --help; echo "exit $?" # the clone of github.com fails closed
# openRepoShape setup
#
# (0) self-bootstrap
# git clone --quiet --depth 1 -- https://github.com/opensoft/openRepoShape.git $TMPDIR/openreposhape-shape-XXXXXX
# fatal: transport 'https' not allowed
# exit 128
OPENREPOSHAPE_REPO="$U" bash setup.sh --help 2>/dev/null | sed -n '1,4p;/^usage:/p'; echo "exit ${PIPESTATUS[0]}" # the same path, cloning the local checkout
# openRepoShape setup
#
# (0) self-bootstrap
# git clone --quiet -- $U $TMPDIR/openreposhape-shape-XXXXXX
# usage: setup-project.py [<Project>] [options] [-- <extra scaffold flags>]
# exit 0So, from anywhere but a checkout:
- A request for help is a clone. It is a shallow, anonymous clone of the public upstream, made before a word of help is printed. Offline, or where policy refuses it,
--helpdies with git's exit 128 and prints no help at all. - The help is the clone's. It is upstream main's (or
$OPENREPOSHAPE_REPO's, or--shape-ref's), not the copy beside the script: the marked usage line above never appears. - The generator inherits both.
scripts/render-cli-reference.py'scapture_help(:282-307) runsbash <tree>/setup.sh --helpwithcwd=the tree and the inherited environment, and nothing in it asks whether the tree is a checkout. In agit archiveor release extraction, every rendering,--checkincluded, clones the public upstream. It then renders upstream main'ssetup-project.pyusage, preceded by the(0) self-bootstraplines and a temporary path, as THIS tree'ssetup.shsection.--checkthen compares that against the tree's owndocs/cli.md. - Nothing documents it.
- README says that from a checkout "nothing touches the network at all" (
README.md:300-302, true), and that "setup.sh --helplists every flag" (:308). - Nothing says that
--helpfrom a download clones first. tests/test_setup_sh.py'stest_no_test_here_depends_on_gh_being_authenticatedsays--helpis answered "before it looks at the machine". That is true only from a checkout, the one placetest_help_exits_zeroruns.
- README says that from a checkout "nothing touches the network at all" (
Why. The shim's header says it "parses nothing" and owns four things Python cannot do before it is running, a checkout among them. --help was left to the one parser, setup-project.py, which is only reachable after the checkout exists. Section 0's own scan already breaks "parses nothing" for two flags that are about the checkout. --help is the one other argument whose answer needs no checkout of the standard at all: setup-project.py gives it before asking for one.
What it should do. Asking a front door for help is never a network act it does not announce, and the generator never renders a tree it did not check out. The decisions are the author's:
- The shim's answer to
-h/--helpoutside a checkout. Options:- (a) A short usage of its own with no clone, naming where the full list lives:
docs/cli.md, orsetup-project.py --helpafter downloading that one file. This is a second usage text, against One definition for the two entry points: setup.sh becomes a shim over setup-project.py (follow-up of #49) #50's "one--help". - (b) Fetch
setup-project.pyalone and run its--help, the wayopenRepoShapefetchessetup.sh. Still network and still upstream's text, but not a clone. - (c) Keep the clone and document it in README, the shim's header and the test docstring above.
- (d) Refuse, naming the two offline ways.
- (a) A short usage of its own with no clone, naming where the full list lives:
- Whose help. Whichever path prints a usage that is not the bytes beside the script says so: the clone's URL and ref.
- The generator. Options:
- Refuse to render or
--checka tree that is not a checkout:git -C <tree> rev-parse --show-toplevelis the tree and the two filesis_shape_checkoutasks for exist. - Or put
GIT_ALLOW_PROTOCOL=fileinchild_env. That changes nothing in a checkout, which clones nothing, and outside one it makessetup.sh --helpexit 128, whichcapture_helpalready turns into a refusal naming the tool. - Or both.
- Refuse to render or
- README and the test docstring say what
--helpdoes from a download, whatever decision 1 is.
How to test. In tests/test_setup_sh.py's self-bootstrap section, which already runs a lone copy of setup.sh with $OPENREPOSHAPE_REPO pointed at this checkout so the clone is local: --help from there asserts decision 1. For (a) or (d) that means no (0) self-bootstrap line and no temporary checkout made; for (c) it means the documented clone line. The test carries WINDOWS_SKIP like the rest of that file. For the generator, a test that copies the tree without .git (or uses git archive) and runs render-cli-reference.py --check there, with GIT_ALLOW_PROTOCOL=file set so that a regression fails closed instead of reaching GitHub, asserts the refusal of decision 3.
Verified at main c7c02fa (setup.sh sha256 ef80934a…, setup-project.py 80ac584e…, scripts/render-cli-reference.py 41037205…); no open PR touches these files.
Related:
- One definition for the two entry points: setup.sh becomes a shim over setup-project.py (follow-up of #49) #50 (setup.sh became a shim over
setup-project.py, "one--help"). - setup.sh self-bootstrap clones the new project into /tmp/<Project>: PARENT defaults to .. of the TEMPORARY checkout #39 (the self-bootstrap's landing directory).
- docs/cli.md: a flag-level CLI reference for an agent, GENERATED from every shipped tool's --help, with a hygiene test that fails when the committed file drifts from what the generator produces #97 (
docs/cli.mdand its generator). - tests: 149 tests in four files run the operator's real
gh(407 calls togh --versionandgh auth status, andgh api userbesides with a login) through the doctor'smachinerow and the installed command's machine block, so a suite whose conftest says "NO NETWORK AND NO GITHUB" reaches the host on a logged-in machine, and the oneghstub the doctor tests have is called by that row without the test seeing it #296 (the tests' own reach to the operator'sgh, the same no-network rule from the suite's side).
Activity
brettheap commentedon Oct 12, 2026
CLAIMED — lane openRepoShape-5, session 673efb9e-6214-44ee-bde0-987129beed92@Eagle, 2026-10-12T17:30:42Z, for #341
Logged in
lanes/log/openRepoShape-5.mdat0817c6d04bad83e46817c4e434f168435c153d61.The three reads (lane-collision-protocol Rule 1):
setup.sh: the #50 guard holds every `--help` in the shim to its help …
Merge origin/main (53bee5b) into fix/setup-help-offline, so the handb…
Merge remote-tracking branch 'origin/main' into fix/setup-help-offline
Merge origin/main into fix/docs-validate-pins-gh-fallback
Merge origin/main (48585e6) into fix/doctor-mid-merge-not-compliant