Repository navigation
make bootstrap, bump-leg.py and update-shape.py apply run the project's own validate-pins.py in the operator's environment, so for a project that pins a neutral product with no local checkout of it each one calls gh api repos/<org>/<product>/git/trees/<sha> with the operator's token, though bump-leg.py says "a project runs its own gate offline" and update-shape.py that "apply is otherwise offline": the three callers #297 named and left #411
Description
Lane: openreposhape-4 (openRepoShape-4)
Named by #297 and left there: "bootstrap.py, bump-leg.py and update-shape.py apply also run the validator with no source (the #272 review's O2); that is documented for the validator and is not claimed here." This lane's planner for the doctor cluster carried it as section 4, item 6. PR #357, which closes #297, starts every validator child of the DOCTOR offline (offline(): the four token variables removed, GH_CONFIG_DIR the null device, a dead proxy). It touches none of these three. Re-verified on main 3ae0109 with local bare remotes, an empty global git config and GIT_ALLOW_PROTOCOL=file. The gh first on PATH writes down its arguments and whether it was handed a token, then exits 97, as an unreachable gh would. Nothing reached the network. Not claimed: what a real, logged-in gh returns (it was never run), macOS and Windows.
What is wrong. A project that pins a neutral product (--pin openGlass@<commit>), with no local checkout of that product, has a validate-pins.py that rechecks the pin's digest through gh api (its docstring, templates/assembly-root/scripts/validate-pins.py:33-38 at 3ae0109). Three tools of the standard run that validator in the operator's own environment, token included:
| caller | where it starts the child | what its own text says |
|---|---|---|
make bootstrap |
scripts/bootstrap.py _run, subprocess.run([sys.executable, *args], cwd=...) (template :83-88) |
"a bootstrap that paused to ask GitHub a question would have made the shape a dependency again" (:67-70, said of its upstream notice) |
bump-leg.py |
run_validator (scripts/bump-leg.py:530) |
"a project runs its own gate offline" (:97-99, over VALIDATORS) |
update-shape.py apply |
run_validator (update-shape.py:1633), env=inherited_child_environment() |
"apply is otherwise offline" (:1730); "this is the one step that needs a network ... everything after it is offline" (:358-360, after the upstream clone) |
U=<openRepoShape checkout> # a clean checkout at 3ae0109
# Runs in bash on Linux (GNU coreutils). Nothing leaves the machine: every repository is a local bare one under $R, git
# reads an empty global config, GIT_ALLOW_PROTOCOL=file makes any accidental https/ssh clone fail, and the `gh` first on
# PATH writes down what it was asked and whether it was handed the operator's token, then exits 97.
R=$(mktemp -d); mkdir $R/bin; touch $R/gitconfig
printf '#!/bin/sh\necho " gh $1 $2 (GH_TOKEN=${GH_TOKEN:-unset})" >> %s/gh.log\nexit 97\n' $R > $R/bin/gh; chmod +x $R/bin/gh
export PATH=$R/bin:$PATH GIT_CONFIG_GLOBAL=$R/gitconfig GIT_CONFIG_NOSYSTEM=1 GIT_ALLOW_PROTOCOL=file \
GIT_AUTHOR_NAME=t GIT_AUTHOR_EMAIL=t@t.invalid GIT_COMMITTER_NAME=t GIT_COMMITTER_EMAIL=t@t.invalid \
GH_TOKEN=the-operators-token
# MedxGlass descends from openGlass and pins it; scaffolded beside a local stand-in, then cloned somewhere else
git init -q -b main $R/src/openGlass && echo '# openGlass' > $R/src/openGlass/README.md
git -C $R/src/openGlass add -A && git -C $R/src/openGlass commit -qm seed; A=$(git -C $R/src/openGlass rev-parse HEAD)
python3 $U/scaffold-project.py --org MedxSoft --project MedxGlass --elected-by 'Test Human' --elected-on 2026-10-12 \
--pin openGlass@$A --pin-source $R/src/openGlass --local-remote-dir $R/remotes --work-dir $R/work >/dev/null
P=$R/away/MedxGlass; git clone -q --recurse-submodules $R/remotes/MedxGlass.git $P
echo "== make bootstrap"; : > $R/gh.log
(cd $P && python3 scripts/bootstrap.py 2>&1 | grep -E '^ skip|^pins ok|^bootstrap ok' | cut -c1-110; echo " exit ${PIPESTATUS[0]}"); cat $R/gh.log
echo "== bump-leg.py, a real bump of the spec leg on a branch"; : > $R/gh.log
(cd $R/work/MedxGlass-spec && echo more >> README.md && git commit -qam more && git push -q origin HEAD:main)
git -C $P checkout -q -b bump-spec
python3 $U/scripts/bump-leg.py --root $P --leg spec --to $(git -C $R/work/MedxGlass-spec rev-parse HEAD) 2>&1 \
| grep -E '^ skip|^pins ok|committed' | cut -c1-110; echo " exit ${PIPESTATUS[0]}"; cat $R/gh.log
echo "== update-shape.py apply, --upstream a local clone that changed one copied file"; : > $R/gh.log
git -C $P checkout -q main; git clone -q $U $R/std
echo '# upstream moved' >> $R/std/templates/assembly-root/scripts/validate-manifest.py && git -C $R/std commit -qam moved
python3 $U/update-shape.py apply --root $P --upstream $R/std --at $(git -C $R/std rev-parse HEAD) --yes --branch shape/update \
2>&1 | grep -E '^ skip|^pins ok|committed' | cut -c1-110; echo " exit ${PIPESTATUS[0]}"; cat $R/gh.logOutput at 3ae0109:
== make bootstrap
skip openGlass: pin commit 11274e5e34da digest NOT rechecked — no local checkout (gh-unreadable: `gh api`
pins ok
bootstrap ok
exit 0
gh api repos/opensoft/openGlass/git/trees/11274e5e34da64610230b42d6bfecd2dd8861d67?recursive=1 (GH_TOKEN=the-operators-token)
== bump-leg.py, a real bump of the spec leg on a branch
skip openGlass: pin commit 11274e5e34da digest NOT rechecked — no local checkout (gh-unreadable: `gh api`
pins ok
committed f55d978c01a7: spec, contracts/spec-pin.yaml
exit 0
gh api repos/opensoft/openGlass/git/trees/11274e5e34da64610230b42d6bfecd2dd8861d67?recursive=1 (GH_TOKEN=the-operators-token)
== update-shape.py apply, --upstream a local clone that changed one copied file
skip openGlass: pin commit 11274e5e34da digest NOT rechecked — no local checkout (gh-unreadable: `gh api`
pins ok
committed on shape/update: contracts/shape-pin.yaml, project.yaml, scripts/validate-manifest.py
exit 0
gh api repos/opensoft/openGlass/git/trees/11274e5e34da64610230b42d6bfecd2dd8861d67?recursive=1 (GH_TOKEN=the-operators-token)
Each run made one gh api repos/opensoft/openGlass/git/trees/<sha>?recursive=1 call carrying the operator's GH_TOKEN. Each printed the validator's skip line and went on, exit 0, because this gh failed. A logged-in gh on a networked machine makes the request for real.
Why.
- The validator's order (a local source, else
gh apiwhenghis authenticated, else askip) is documented and deliberate. shape-doctor.py: thepinsrow says "ok ... the project's own scripts/validate-pins.py passes" for a project that pins a neutral product though that validator SKIPPED the product's digest after a realgh apicall, so the command documented to fetch nothing fetched from GitHub, and a digest nobody rechecked reads asokunder aCOMPLIANTverdict #297 ruled that the doctor's children must not take its second branch, because the doctor promises to fetch nothing. - These three tools say the same kind of thing about themselves in the lines quoted above, and start the child exactly as shape-doctor.py: the
pinsrow says "ok ... the project's own scripts/validate-pins.py passes" for a project that pins a neutral product though that validator SKIPPED the product's digest after a realgh apicall, so the command documented to fetch nothing fetched from GitHub, and a digest nobody rechecked reads asokunder aCOMPLIANTverdict #297 found the doctor doing. - The skip is not hidden here: each tool prints the validator's output. What is out of line with their own words is the network call, and the token it carries.
make bootstrapis the weakest case. It fetches the project's legs by design, so a GitHub read from it is less surprising than one frombump-leg.pyorapply --upstream <local path>.
What it should do. Each tool either keeps its validator child offline, or says plainly that its gate may ask gh api for a neutral-product pin. The decisions are the author's:
- Per tool, offline or documented.
- Starting the child offline (shape-doctor.py: a validator that crashed says it crashed instead of "reports a finding", and is CANNOT ANSWER when it is the standard's template, which a standard whose path holds the
PYTHONPATHseparator no longer runs at all; a neutral product's digestvalidate-pins.pyskipped is anotenaming the product, from a child that can no longer reachghor a proxy; and a root whose manifest does not load and whosescripts/repo_shape.pyis gone is told to restore that file before its gate (#278, #297, #298) #357'soffline()env, moved where these tools can import it, or copied) turns the online recheck into theskipfor an operator whoseghis logged in. - Keeping the call means correcting the quoted docstrings, and AGENTS.md "Advancing a leg" and "Updating a project's shape", to say so.
- Starting the child offline (shape-doctor.py: a validator that crashed says it crashed instead of "reports a finding", and is CANNOT ANSWER when it is the standard's template, which a standard whose path holds the
- A source. Whether a caller that already knows where the product is passes it on (
--pin-source,SHAPE_PIN_SOURCE_<PRODUCT>), so that the recheck runs offline and does not skip. make bootstrap. Whether it keeps the call, since it is networked anyway, and says so.
How to test. For each tool, a descendant that pins a stand-in built by tests/test_scaffold_pin_and_reuse.py's product_repo, cloned with no source beside it. Put a logging gh stub first on PATH, as #357's descendant test does (it is a shell script, so WINDOWS_SKIP), and export a sentinel GH_TOKEN:
- under an offline decision, assert the stub logged no
apicall; - under a documented one, assert the call carried what the tool's text says it does.
Verified at main 3ae0109 (scripts/bump-leg.py sha256 b99c81b3…, update-shape.py 992342a5…, the assembly root's scripts/bootstrap.py ae1426fd…, its scripts/validate-pins.py cc3484bf…).
Related: #297 / PR #357 (the doctor's validator children taken offline), #272 (the tests' same gh api calls, removed with --pin-source), #295 (--pin-source), #296 / PR #349 (the suite's gh guard).
Activity
brettheap commentedon Oct 12, 2026
CLAIMED — lane openRepoShape-3, session 43f4ac63-0116-41de-977d-afc23cdf7fdf@Eagle, 2026-10-12T19:30:15Z, for #411
Logged in
lanes/log/openRepoShape-3.mdat8c2dd12c8270634a4e76b44f9abd32b954c99f8a.The three reads (lane-collision-protocol Rule 1):
brettheap commentedon Oct 12, 2026
(lane openRepoShape-3, 2026-10-12T19:51:23Z) A v1.0.0 scope notice. Brett Heap scoped openRepoShape's first release today: every procedure in AGENTS.md works end to end for ordinary repositories on Linux, macOS and Windows. The tag waits for every in-scope issue to close and a full test run to pass on all three OSes on the release commit. This issue is #411 (P2, parent #458): in scope, in the
v1.0.0milestone. Nothing changes in how it is worked. Known-limit issues stay open, without the milestone, under their area's parent.README.md, docs/handbook.html and `bump-leg.py --local-remote-dir`'s …
Merge origin/main into fix/docs-validate-pins-gh-fallback
Merge origin/main into fix/docs-validate-pins-gh-fallback (#411)
README.md, docs/handbook.html and the comments in bump-leg.py and upd…
Merge origin/main (48585e6: #465 and three others) into docs/v1-accuracy
Merge origin/main (48585e6) into fix/doctor-mid-merge-not-compliant
Merge origin/main (48585e6: #465) into fix/setup-no-terminal-route
Merge origin/main (aa4e1f5) into fix/family-commands-and-branch
Merge origin/main (aa4e1f5) into fix/scaffold-reuse-seeded-legs