Skip to content

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

Closed

Description

@brettheap

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_DIR falls 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:

  1. A pre-scan of the arguments (:142-150) that reads --keep-shape-checkout and --shape-ref and nothing else.
  2. say "(0) self-bootstrap" and git clone --quiet [--depth 1] -- "$SHAPE_REPO" (:179-204). SHAPE_REPO defaults to https://github.com/opensoft/openRepoShape.git (:31).
  3. Only then, setup-project.py from the CLONE with the person's arguments (:221-222). That is where --help is 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 0

So, from anywhere but a checkout:

  1. 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, --help dies with git's exit 128 and prints no help at all.
  2. 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.
  3. The generator inherits both. scripts/render-cli-reference.py's capture_help (:282-307) runs bash <tree>/setup.sh --help with cwd= the tree and the inherited environment, and nothing in it asks whether the tree is a checkout. In a git archive or release extraction, every rendering, --check included, clones the public upstream. It then renders upstream main's setup-project.py usage, preceded by the (0) self-bootstrap lines and a temporary path, as THIS tree's setup.sh section. --check then compares that against the tree's own docs/cli.md.
  4. Nothing documents it.
    • README says that from a checkout "nothing touches the network at all" (README.md:300-302, true), and that "setup.sh --help lists every flag" (:308).
    • Nothing says that --help from a download clones first.
    • tests/test_setup_sh.py's test_no_test_here_depends_on_gh_being_authenticated says --help is answered "before it looks at the machine". That is true only from a checkout, the one place test_help_exits_zero runs.

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:

  1. The shim's answer to -h / --help outside a checkout. Options:
    • (a) A short usage of its own with no clone, naming where the full list lives: docs/cli.md, or setup-project.py --help after 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.py alone and run its --help, the way openRepoShape fetches setup.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.
  2. Whose help. Whichever path prints a usage that is not the bytes beside the script says so: the clone's URL and ref.
  3. The generator. Options:
    • Refuse to render or --check a tree that is not a checkout: git -C <tree> rev-parse --show-toplevel is the tree and the two files is_shape_checkout asks for exist.
    • Or put GIT_ALLOW_PROTOCOL=file in child_env. That changes nothing in a checkout, which clones nothing, and outside one it makes setup.sh --help exit 128, which capture_help already turns into a refusal naming the tool.
    • Or both.
  4. README and the test docstring say what --help does 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:

Activity

  1. brettheap commented on Oct 12, 2026

    @brettheap
    ContributorAuthor

    CLAIMED — lane openRepoShape-5, session 673efb9e-6214-44ee-bde0-987129beed92@Eagle, 2026-10-12T17:30:42Z, for #341

    Logged in lanes/log/openRepoShape-5.md at 0817c6d04bad83e46817c4e434f168435c153d61.

    The three reads (lane-collision-protocol Rule 1):

    1. existing `CLAIMED —` comments on opensoft/openRepoShape#341:
       none
    2. `gh pr list --repo opensoft/openRepoShape --state all --search "#341"`, kept where the row or its body names `#341`:
       none
    3. `git ls-remote --heads git@github.com:opensoft/openRepoShape` branches naming `341` as a whole token:
       none
    
  2. added 2 commits that reference this issue on Oct 12, 2026
  3. added this to the v1.0.0 milestone on Oct 12, 2026
  4. added 2 commits that reference this issue on Oct 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions