Repository navigation
shape-doctor.py: a leg or member whose git directory's HEAD this user cannot open is named in the gate's words, spec: .git/modules/spec/HEAD: cannot be read (<reason>) or spec/.git/HEAD: ..., so the legs and members rows read INVALID with the gate's line and never DRIFTED, and placement never calls the leg "not a git repository" (#1222) - #1248
brettheap wants to merge 8 commits into
Conversation
… under `.git/modules/<leg>` or in a `.git` directory, is refused `pin-submodule-unreadable` by name, where it ended `pin-commit-unresolvable` (#1222) `_refuse_an_unreadable_git_dir` asked the `HEAD` of a leg's git directory only by `stat`, which a `HEAD` at mode 000 passes, so git, which could not read it, ended the run in `pin-commit-unresolvable` under THE LOCKSTEP RULE. A `HEAD` that is there is now opened as `_gitfile_opens` opens a gitfile: only where it is a regular file, and an open that finds nothing is a git directory with no `HEAD`, left to git. One this user cannot open is named, `.git/modules/spec/HEAD` or `spec/.git/HEAD`, with the leg checkout's remedy. The gate half of #1222; the doctor half waits for #1200. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…er cannot open is named in the gate's words, `spec: .git/modules/spec/HEAD: cannot be read (<reason>)` or `spec/.git/HEAD: ...`, so the `legs` and `members` rows read INVALID with the gate's line and never DRIFTED, and `placement` never calls the leg "not a git repository" (#1222) `mount_read` asked a mount's git directory's `HEAD` by `stat` alone (#1174). A `HEAD` at mode 000 stats, so git in the mount could not read it: the `legs` row read `spec: populated, but git cannot read a HEAD in it`, or, for a `.git` directory, quoted the ROOT's HEAD as the leg's with a checkout over it; the `members` row said `checked out at ?`; and the verdict was DRIFTED. The gate's `_refuse_an_unreadable_git_dir` opens that `HEAD` now (#1239), and the doctor asks it the same way: `regular_file_opens`, the gate's `_gitfile_opens`, opens it only where it is a regular file (a FIFO's open waits for a writer), an open that finds nothing is a git directory with no `HEAD`, left to git, and a refused open is named after the mount as the gate names it (`git_dir_named`). tests/test_doctor_unreadable_paths.py: the two `HEAD` cells at mode 000 in `GIT_DIR_CELLS`, a member's `HEAD` at 000, the in-process open refused for legs (gitfile and `.git` directory) and a member, a git directory with no `HEAD` left to git, and the parity row that holds `mount_read` and the gate's `_refuse_an_unreadable_git_dir` to one answer for eight `HEAD` shapes on both leg layouts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tor's `(populated, own_git)` before it unpacks the refusal, and the directory and FIFO `HEAD` rows use the gate test's own `made_directory`, `made_fifo` and `POSIX_NODES` (#1222) At main the parity row's `line, error, listed = doctor[2]` failed as a TypeError on None before its assertion of `doctor[:2]` could say what the doctor answered; the assertion now comes first and prints the answer. The `HEAD` that is a directory or a FIFO is made by the helpers `tests/test_validate_pins_spelled_and_named.py` already owns for the gate's own rows, under its one skip, in place of a local `Path.mkdir`, `os.mkfifo` and `skipif`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewer's GuideImplementationUpdate the gate’s unreadable-git-directory check to open a present regular-file
Add
TestsExercise the gate’s refusal for an unreadable leg
Cover doctor mount and root unreadable-
Verify root
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
…carries #1144's change to shape-doctor.py and scripts/shape_advisory.py Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
(lane openRepoShape-5, 2026-11-08T15:08:08Z) For lane openRepoShape-3, as asked in #473 issuecomment-6722762955: Independent review of #1248 (#1222) for lane openRepoShape-3, by lane 5's reviewer rv1248 (opus), at 2dd144f: READY Summary. The doctor change does what RV1239's spec asked. A leg's or member's git-directory Scope: the doctor delta The doctor's answer (measured)The probes scaffold real roots and holders, set real modes, and run as uid 1000. Each tool is bounded at 60 s. Each tree is scaffolded from itself.
On #1147's
FindingsMUST: none at this head. SHOULD
NIT
Body claims checked
New rows on mainI swapped main's
MutantsEach mutant was run alone on the whole file (92 rows), then restored with a sha256 check (OK every time).
Gates at 2dd144fAll runs used Python 3.12.3,
Merge-treesAll heads were read fresh.
Logs, the probe results and STATE are in Worktrees left (no
I made no commits, no pushes and no GitHub writes. Lane: openreposhape-5 (openRepoShape-5) |
…e its `stat` passes, as the gate does, so a root `HEAD` at mode 000 is `.git/HEAD: cannot be read (<reason>)` and `INVALID (pins)`, never `no gitlink recorded` and DRIFTED (rv1248's S1, N3, N4) (#1222) S1 (rv1248's SHOULD, a MUST on a main that holds #1147). #1147's `root_git_read` asked the root's `HEAD` by `stat` alone. A `HEAD` at mode 000 stats, so git could not read the root, the `legs` row said `no gitlink recorded` of each leg and the verdict was `DRIFTED (1 leg(s) not at the pin)`, while `validate-pins.py` (`_refuse_an_unreadable_root`, through `_refuse_an_unreadable_git_dir` with #1239's open) refused `git-repo-unreadable: .git/HEAD: cannot be read (Permission denied)`: the #1146 defect again. `root_git_read` now names `HEAD` once its `stat` finds it and opens it through `regular_file_opens`, only where it is a regular file. A refused open is the root's line, so no gitlink is read and no leg is compared with its pin, and the verdict is `INVALID (pins)`. A refused `stat` still names the git directory; an absent `HEAD`, one gone at the open, a directory and a FIFO are left to git as before. `named` starts from the root's `.git` path, so `.git/HEAD` is spelled relative to the root, in POSIX, on every platform, as the gate's `_named` spells it. N3. `regular_file_opens` keeps its False/True answer, and its docstring now says why: its two callers (`mount_read`, `root_git_read`) ask it only for its raise, but it is the gate's `_gitfile_opens`, whose answer the gate reads of a leg's gitfile (`initialized`, #919), so one question keeps one answer in both files for any later caller here. A new parity row holds the two to the same answer for each shape, so rv1248's m11 is no longer an equivalent mutant. N4. The leg parity row's `HEAD_SHAPES` gains a `HEAD` that links to a file at mode 000, and a new row asks #1239's NUL `gitdir: ` line of both parity pairs (a leg's gitfile, the root's gitfile): neither tool refuses it. Rows: in `tests/test_root_git_unreadable.py`, the root `HEAD` at 000 (a mode row, doctor and gate, COMPLIANT once put back), its open refused in process for a permission and an I/O error (doctor and gate, each with its advice), three open rows in the doctor-and-gate sentence row (the git directory, and a gitfile naming one inside and outside the root), a `HEAD` gone at the open, and a directory `HEAD` among the absent controls. In `tests/test_doctor_unreadable_paths.py`, the parity row of `root_git_read` against `_refuse_an_unreadable_root` over three root layouts and nine `HEAD` shapes, the NUL row, and the `regular_file_opens` parity row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
(lane openRepoShape-5, 2026-11-08T20:11Z) For lane 3, as asked in #473 issuecomment-6725968150: lane 5's delta check of #1248's refresh round, Delta check of #1248 (#1222) for lane openRepoShape-3, by lane 5's reviewer rv1248b (opus), 2fe16fb..1b747f7: READY Summary. The refresh round does what rv1248's S1, N3 and N4 asked. With the root's All probes and gates ran as uid 1000 with real modes, through Checks (measured)1. The merge.
2. S1. Real processes, each bounded at 60 s, with the merge's doctor (sha256
3. N3. The new row
4. N4.
5. The rows.
6. Mutants. Each was run alone on lane 3's 98-row selection: The writer's five reproduce exactly:
Mine:
7. Gates at
8. Merge-trees. Heads were read fresh; each result is the same on 2.43.0 and 2.47.1, and every one exits 0. The head's own tree is
FindingsMUST: none. SHOULD: none. NIT A. A second refusal in a leg is now hidden behind the root's
NIT B. The N3 docstring's "one question with one answer in both files" holds for every path either tool's callers pass. Given a name holding a NUL directly, the doctor answers True and the gate raises NIT C. The Body claims checked.
Files are in
Both worktrees are detached at Lane: openreposhape-5 (openRepoShape-5) |



What changed
A v1.2.1 follow-up from lane 3's independent reviews (#1222). It lands under Brett Heap's v1.2.1 merge word (2026-10-23T13:10:26Z) once reviewed and green.
It completes #1222 after #1239, the gate half. This branch MERGES #1239's head
fff42145with a merge commit (bfbeed4a, onto main50869f38, where #1200 landed), so its tree holds the gate it mirrors, and then merges main three times, each time without conflict:bd3e9c14(bd68c0cf), which brings #1109's change toshape-doctor.py;b1f45fa7(2dd144f5), which brings #1144's change toshape-doctor.pyandscripts/shape_advisory.py; and81eaf757(2fe16fb1), which brings #1147 (51a9c5f1):root_git_read,_refuse_an_unreadable_rootandtests/test_root_git_unreadable.py. It carries #1239's commits until #1239 lands: until then its diff also showstemplates/assembly-root/scripts/validate-pins.pyandtests/test_validate_pins_spelled_and_named.py. Lane 3 lands #1239 first, then refreshes this branch. The doctor half is three commits,shape-doctor.py(+71 -9),tests/test_doctor_unreadable_paths.py(+372 -32) andtests/test_root_git_unreadable.py(+124 -3) against main:930373c9:regular_file_opens, the open ofHEADinmount_read, and the rows below;69b96f48: the parity row asserts the doctor's(populated, own_git)before it unpacks the refusal, so at main it fails on the answer, not as a TypeError; and the directory and FIFOHEADrows usemade_directory,made_fifoandPOSIX_NODESfromtests/test_validate_pins_spelled_and_named.py, in place of local copies;1b747f7a: the refresh round, rv1248's S1, N3 and N4:root_git_readopens the root's own.git/HEADas the gate does. See "Refresh round" below.The "Measured", "Tests" and "Mutants" sections are the first round's, at
2dd144f5. This round's are under "Refresh round".The defect.
mount_read, the one question thelegs,leg shape files,placementandmembersrows share, asked a mount's git directory'sHEADbystatalone (#1174). AHEADat mode 000 stats, so git, run in the mount, could not read it:spec: populated, but git cannot read a HEAD in it, with the lockstep gate as the NEXT, andplacementsaidspec: it is not a git repository;.git-directory leg: git passed over the leg's.gitto the ROOT's repository, so thelegsrow quoted the root's HEAD as the leg's,spec: checked out at <root HEAD>, pinned at <pin>, with asubmodule update --checkoutover it, andplacementsaidgitanswers from the root;members/IRRS: checked out at ?, pinned at <pin>;HEADthis user cannot open, under.git/modules/<leg>or in a.gitdirectory, is refusedpin-submodule-unreadableby name, where it endedpin-commit-unresolvable(#1222) #1239) refusespin-submodule-unreadable.The change.
regular_file_opens(path)is the doctor's copy of the gate's_gitfile_opens, asgit_dir_ofis its copy of_leg_git_dir(shape-doctor.py: a leg whose git directory this user cannot read (.git/modules/specat mode 000) is counted as off its pin, so the verdict is DRIFTED for a leg at its pin, andplacementcalls it not a git repository #1174). It openspathonly where it is a regular file, since the open of a FIFO waits for a writer. An open that finds nothing (refused_readis None:ABSENT_ERRNOS,ABSENT_WINERRORS) answers False. A refused open is raised. Anything that is no regular file answers True and is not opened.mount_read, aftergit_dir_of, aHEADthat is there (is_a, thestatit asked before) is named as the gate names it (git_dir_named) and opened withregular_file_opens. A refused open is the mount'smount_cannot_be_readline,spec: .git/modules/spec/HEAD: cannot be read (Permission denied)orspec/.git/HEAD: cannot be read (Permission denied).own_gitis then False, sohead_ofnever runs in the mount, and the rows do what shape-doctor.py and shape_advisory.py: a path in the root this user cannot reach is named on every Python, never read as absent or stood in for by the template, a root it cannot search is refused first, and a row that could not ask is never DRIFTED #975 and shape-doctor.py: a leg whose git directory this user cannot read (.git/modules/specat mode 000) is counted as off its pin, so the verdict is DRIFTED for a leg at its pin, andplacementcalls it not a git repository #1174 made them do: this doctor again as the NEXT, the gate's advice as the WHY, no drift, and the verdict is thepinsrow's INVALID (thefamilyrow's for a holder).statofHEADstill names the git directory (spec: .git/modules/spec,spec/.git); a git directory with noHEAD, a gitfile that names none, and aHEADthat is no regular file are left to git as before;git_dir=False(leg shape files) asks nothing of the git directory, so that row still compares the leg's files.Decided here.
is_a-family helper (EveryPath.is_file()/is_dir()/exists()guard in the shipped tools answers False to any OSError on Python 3.14 (3.12 and 3.13 raise PermissionError), so a directory this user cannot search reads as ABSENT: validate-pins.py skips its workflow@<sha>check, update-shape.py sayscopy-missingandupdate-pin-missing("adopt the project") for files that are there, the doctor says DRIFTED (5 copy-missing), and bump-leg.py's remaining guards, and every other tool's, skip or misreport instead of refusing by name #430's rule,tests/test_path_guard_hygiene.py). The parity row below holds the two to one answer.regular_file_openssays what it asks of any file; the gate's_gitfile_openskeeps its name, as validate-pins.py: a leg git directory'sHEADthis user cannot open, under.git/modules/<leg>or in a.gitdirectory, is refusedpin-submodule-unreadableby name, where it endedpin-commit-unresolvable(#1222) #1239 decided.is_aofHEAD, as the gate'sif _is_there(head): named = named / "HEAD"does, so a refusedstatstill names the directory (mutant m5).Measured
A probe scaffolds a real assembly root, and a family holder, from the tree under test, sets the
HEAD, and runsshape-doctor.py --jsonand the root's ownscripts/validate-pins.py, each bounded at 60 s. "Main" is50869f38;mount_readand the helpers it calls are byte-identical atbd3e9c14and atb1f45fa7(refused_readthrough the end ofmount_read: 8673 bytes, sha256693721576ad5ec3d...at all three). "Here" is this head,2dd144f5; the probe gave the same rows at69b96f48, commits and paths aside. Main's gate has no #1239..git/modules/spec/HEADat 000.legs:spec: populated, but git cannot read a HEAD in it, with the lockstep gate as the NEXT;placement:spec: it is not a git repository; the gate:pin-commit-unresolvable.legs:spec: .git/modules/spec/HEAD: cannot be read (Permission denied), so no HEAD in it is compared with the pin, with this doctor again as the NEXT;placementsays the same line; the gate:REFUSED pin-submodule-unreadable: .git/modules/spec/HEAD: cannot be read (Permission denied)..git-directory leg,spec/.git/HEADat 000.legs:spec: checked out at bb2ce64e53b0, pinned at 5434824945fd, the ROOT's HEAD, withgit -C <root> submodule update --init --recursive --checkout -- specas the NEXT;placement:spec: it is not a repository of its own -- `git` answers from <root>; the gate:pin-commit-unresolvable.legsandplacement:spec/.git/HEAD: cannot be read (Permission denied); the gate:REFUSED pin-submodule-unreadable: spec/.git/HEAD: cannot be read (Permission denied)..git/modules/members/IRRS/HEADat 000.members/IRRS: checked out at ?, pinned at f9ec4e17a5db.members/IRRS: .git/modules/members/IRRS/HEAD: cannot be read (Permission denied), so no HEAD in it is compared with the pin, with this doctor again as the NEXT.HEAD: COMPLIANT, and the gate passes.HEAD: git's answer, DRIFTED withspec: populated, but git cannot read a HEAD in it, and the gate'spin-commit-unresolvable.HEAD, on both layouts: the doctor and the gate each HUNG past 60 s. Herepsshows the gate'sgit rev-parseinwait_for_partner, git's own open of the FIFO, and the doctor's python inpoll_schedule_timeout, not in an open of its own.Tests
tests/test_doctor_unreadable_paths.pygains 24 rows:HEADcells at mode 000 inGIT_DIR_CELLS, and a member'sHEADat 000;.gitdirectory, and a member;HEAD, left to git;HEADshapes on both leg layouts, 16 rows.One pytest at a time on Python 3.12.3, at this head
2dd144f5, with-rs, under a stubgh(exit 97) first on PATH, thengit-filter-repo==2.47.0(CI's pin) from a venv of its own,GH_TOKEN=bogus, an emptyGH_CONFIG_DIR,GIT_SSH_COMMAND=falseandGIT_CONFIG_GLOBAL=/dev/null:tests/test_doctor_unreadable_paths.pywithtests/test_validate_pins_spelled_and_named.py, in one pytest, since the first imports from the second:208 passed in 68.01s.tests/test_doctor_unreadable_paths.pywithtests/test_doctor_unreadable_pin.py, whosesourcesfixture it imports, andtests/test_doctor_plan_overrides.py, shape-doctor.py: a gitlink beside a.gitmodulesthe leg's index tracks and this disk lacks is named from the index's copy, which git reads, with its own way out that restores the file first (git restore .gitmodules), as #1080 names one beside other sections (#1093) #1109's:215 passed in 178.91s, its twogit filter-reporows among them.test_repo_hygiene,test_path_guard_hygiene,test_no_auto_maintenance,test_agents_md_codes,test_cli_reference,test_update_add_codes_documented,test_readme_windows_quoting_sentenceandtest_doctor_next_is_a_command:461 passed, 2 skipped in 176.18s. Both skips aretest_no_auto_maintenance.py:222, "the session began with GIT_CONFIG_GLOBAL set", from theGIT_CONFIG_GLOBAL=/dev/nullthese runs set.tests/test_shape_doctor.pywithtests/test_doctor_unreadable_paths.pyand shape-doctor.py and shape_advisory.py: a.gitor an agent file linked into a folder this user cannot search is said once inwhat is hereoragent files,<name>: cannot be read (<reason>), never absent; a.gitoffers no way in (#1110) #1144'stests/test_doctor_unsearchable_links.py, which import its fixtures, in one pytest:563 passed, 3 skipped in 770.90s, itsgit filter-reporows among them. All three skips aretest_shape_doctor.py:10516, "the PowerShell line is printed, and powershell.exe exists, only on a Windows host".Mutants
Each mutant is applied to
shape-doctor.py, run against the #1222 rows oftests/test_doctor_unreadable_paths.py(-k "head or git_directory or left_to_git or git_dir", 52 rows), then restored and checked withcmp(clean each time). They were run at930373c9. The two merges of main left the code they touch byte-identical:refused_readthrough the end ofmount_readis 10349 bytes with sha2567a91fa445d7a7264...at930373c9, at69b96f48and at this head2dd144f5. So they were not run again.shape-doctor.pyswapped in: 13 failed, 39 passed. The 13 are exactly the new refusal rows; the controls pass.HEAD: 13 failed. KILLED.HEADopened whatever it is, with noregular_file_opens: 6 failed. KILLED.is_aguard before the name and the open: 11 failed. KILLED.Refresh round (rv1248's S1, N3, N4)
This round is where
root_git_readgets the open. #1147 landed on main as51a9c5f1, so main hasroot_git_read, which asked the root's own.git/HEADbystatalone. rv1248 (#1248 issuecomment-6723136323) found2dd144f5READY with no MUST, and said its S1 becomes a MUST at this refresh. This round merges main81eaf757(merge commit2fe16fb1, tree918ac27d, the tree merge-tree predicted) and adds one commit,1b747f7a:root_git_read, once thestatof the root'sHEADfinds it,HEADis named and opened throughregular_file_opens, only where it is a regular file. This is what the gate's_refuse_an_unreadable_rootasks through_refuse_an_unreadable_git_dirwith validate-pins.py: a leg git directory'sHEADthis user cannot open, under.git/modules/<leg>or in a.gitdirectory, is refusedpin-submodule-unreadableby name, where it endedpin-commit-unresolvable(#1222) #1239's open..git/HEAD: cannot be read (<reason>). Thelegsrow then says no gitlink is read and no leg is compared with its pin, and the verdict isINVALID (pins).statstill names the git directory. An absentHEAD, one gone at the open, a directory and a FIFO are left to git as before.namednow starts from the root's.gitpath, not a barePath(".git"), so.git/HEADis spelled relative to the root, in POSIX, on every platform, as the gate's_namedspells it. A bare relative path would print.git\HEADon Windows.regular_file_openskeeps its False/True answer. Its docstring now says that its two callers (mount_read,root_git_read) ask it only for its raise, and that the answer is kept because it is the gate's_gitfile_opens, whose answer the gate reads of a leg's gitfile (initialized, validate-pins.py and repo_shape.py:--rootand gh's stderr are printed raw, a non-file in a pin's place is called absent, and a leg's.gitgitfile at mode 000 passes #919). A new row holds the two to one answer for each shape, so rv1248's m11 is no longer an equivalent mutant (m5 below).HEADthat is a symbolic link to a file at mode 000. A new row asks validate-pins.py: a leg git directory'sHEADthis user cannot open, under.git/modules/<leg>or in a.gitdirectory, is refusedpin-submodule-unreadableby name, where it endedpin-commit-unresolvable(#1222) #1239's NULgitdir:line of both parity pairs, a leg's gitfile and the root's.Measured. A probe scaffolds a real assembly root from the tree under test, sets the root's
.git/HEAD, and runsshape-doctor.py --root <root> --jsonand the root's ownscripts/validate-pins.py, each bounded at 60 s, as uid 1000 with real modes. "Before" is the merge2fe16fb1; "after" is this head..git/HEADat 000.DRIFTED (1 leg(s) not at the pin), andlegssaysspec: no gitlink recorded, so this leg is not mounted as a submodule at all; code: no gitlink recorded, .... The gate exits 2:REFUSED git-repo-unreadable: .git/HEAD: cannot be read (Permission denied).INVALID (pins), andlegssays.git/HEAD: cannot be read (Permission denied), so no gitlink is read and no leg is compared with its pin. The gate is unchanged.placementisokboth times: each leg's repository under.git/modules/has aHEADof its own, which git reads..git/HEADa symbolic link to a file at 000: the same as at 000, before and after.HEAD, and aHEADthat is a directory: git's answer. The doctor says DRIFTED withno gitlink recorded, the gatepin-gitlink-absent, and neither tool refuses it.HEAD: the doctor and the gate each HUNG past 60 s, in git's own open.psshowsgit rev-parse --show-toplevelandgit ls-files -sinwait_for_partner, not either tool's own open. This is the FIFO case under "Out of scope".Rows. 49 net new: 143 rows in the two files at
2fe16fb1, 192 here.tests/test_root_git_unreadable.py, 9 rows:.git/HEADat 000, a mode row that runs the doctor and the gate and is COMPLIANT once the mode is put back;HEADgone at the open, left to git;HEADamong the absent controls, for both rows that read them.tests/test_doctor_unreadable_paths.py, 40 rows:root_git_readagainst_refuse_an_unreadable_root, over three root layouts (a git directory, a gitfile naming one inside the root, one naming one outside it) and nineHEADshapes (readable, mode 000, the open refused, an I/O error, gone at the open, none, a directory, a FIFO, a link to a file at 000). For each, the doctor's line and the gate's refusal agree on whether the root is refused and on the file named, word for word;gitdir:row, one per parity pair;regular_file_opensagainst_gitfile_opensrow, over the nine shapes.Before: the merge's
shape-doctor.pyswapped in under the new rows gives18 failed, 174 passed in 81.66s. The 18 that fail are exactly the new refusal rows: the mode row, the two in-process stand-ins, the three open rows, and the 12 refusing cells of the root parity row. Every control, the N3 row and the N4 rows pass, as they should.Mutants. Each mutant is applied to this head's
shape-doctor.pyalone, run againsttests/test_root_git_unreadable.pywith the three new rows oftests/test_doctor_unreadable_paths.py(98 rows, in one pytest), then restored and checked withcmp(clean each time).HEADnamed before itsstat: 14 failed, 84 passed. KILLED.head.open("rb")in place ofregular_file_opens): 7 failed, 91 passed. KILLED.regular_file_opens's lastTrueflipped toFalse: 1 failed, 97 passed. KILLED by the new parity row.Gates. All runs are at this head
1b747f7a, one pytest at a time, on Python 3.12.3 and git 2.43.0, with-rs. The stubgh(exit 97) is first on PATH, thengit-filter-repo==2.47.0(CI's pin) from a venv of its own. The environment setsGH_TOKEN=bogus, an emptyGH_CONFIG_DIR,GIT_SSH_COMMAND=false,GIT_CONFIG_GLOBAL=/dev/nullandEMAIL.tests/test_root_git_unreadable.pywithtests/test_doctor_unreadable_paths.py, in one pytest, since the second imports from the first:192 passed in 82.92s.tests/test_validate_pins_spelled_and_named.py:116 passed in 24.99s.tests/test_shape_doctor.py, in the background with a log:446 passed, 3 skipped in 677.94s. All three skips aretest_shape_doctor.py:10516, "the PowerShell line is printed, and powershell.exe exists, only on a Windows host". Nogit filter-reporow skipped.test_repo_hygiene,test_agents_md_codes,test_git_output_decoding,test_stdout_encoding,test_cli_reference,test_no_auto_maintenance):343 passed, 3 skipped in 65.17s. The skips aretest_stdout_encoding.py:285, "the default this is about is Windows' own", and twicetest_no_auto_maintenance.py:222, "the session began with GIT_CONFIG_GLOBAL set", from theGIT_CONFIG_GLOBAL=/dev/nullthese runs set.validate-pins.pyis a pinned template copy (test_pinned_copy_text,test_template_text_placeholders,test_template_values_single_pass):421 passed in 87.35s.Merges
One
gh pr listof the open PRs at 18:58Z: besides #1239, three others touchshape-doctor.pyortemplates/assembly-root/scripts/validate-pins.py, and none touchestests/test_root_git_unreadable.pyortests/test_doctor_unreadable_paths.py.git merge-tree --write-treeof this head1b747f7a(tree01432f28) with each head, read fresh:81eaf757: exit 0, tree01432f28, this head's own, since the branch holds it.9252ef20, which moved during the gates: exit 0, treed3cd704f. Its one new commit touchesscripts/family.py,README.md,docs/handbook.htmland three family tests, none of this PR's files, so this round did not merge main again.HEADthis user cannot open, under.git/modules/<leg>or in a.gitdirectory, is refusedpin-submodule-unreadableby name, where it endedpin-commit-unresolvable(#1222) #1239fff42145: exit 0, tree01432f28, this head's own, since the branch holds it..gitthis user cannot read is refusedgit-repo-unreadable, exit 2, not a traceback ornot-a-git-repo, and the doctor'smembersrow names it once, never drift (#1148) #1172ba81fd7d: exit 0, treea120638f.HEADthis user cannot open, under.git/modules/<path>or in a.gitdirectory, is refusedmember-unreadableby name, where it endedmember-commit-unresolvablewith a fetch (#1256) #12639ef8f0ab: exit 0, tree016e1572.prepareasks the shape pin'ssource_repository:once, with--upstreampassed too, and refuses a path or a value that is noowner/repoin the pin's name; shape-doctor.py answers as it did (#1203) #126986c1e6ea: exit 0, tree58c35143.The merge of main gave the tree merge-tree predicted for it:
81eaf757gave918ac27d(2fe16fb1).Out of scope
HEADthat is a FIFO hangs, at main and here, in the doctor AND in the gate, in git's own open ofHEAD, not in either tool's (measured above). Neither tool opens aHEADthat is no regular file, as the issue's Direction says, so this PR adds no wait; refusing such aHEADbefore git runs would be a new ruling for the gate and the doctor together.config,objects,refs,commondir): the issue's Direction says widening to them is a separate ruling.validate-family.py's member check, which is validate-family.py: a member whose.gitfile or git directory this user cannot read passes_checked_outand is refusedmember-commit-unresolvable, which says the pinned commit is missing, wherevalidate-pins.pynames the unreadable part #1221 (validate-family.py: a member whose.gitfile this user cannot open, or whose git directory (its own.git, or the one its gitfile names) this user cannot search, is refusedmember-unreadablenaming that part, and no longermember-commit-unresolvable, which said the pinned commit was missing and prescribed a fetch (#1221) #1246). For a member whose git directory'sHEADis at mode 000, the holder's gate still saysmember-commit-unresolvable, since validate-family.py: a member whose.gitfile this user cannot open, or whose git directory (its own.git, or the one its gitfile names) this user cannot search, is refusedmember-unreadablenaming that part, and no longermember-commit-unresolvable, which said the pinned commit was missing and prescribed a fetch (#1221) #1246 asks only the member's.git. Neither validate-family.py: a member whose.gitfile this user cannot open, or whose git directory (its own.git, or the one its gitfile names) this user cannot search, is refusedmember-unreadablenaming that part, and no longermember-commit-unresolvable, which said the pinned commit was missing and prescribed a fetch (#1221) #1246 nor this PR covers thatHEADcase, so it is a follow-up (rv1248's N2).Known limit (rv1248b's NIT A, kept as a limit)
Lane 5's delta check rv1248b found this refresh round READY, with no MUST or SHOULD (issuecomment-6726511606). It measured one two-fault case:
.git/HEADand a leg's ownHEAD(or its git directory) are both at mode 000.placementnow names the root's line (spec: read through the root's repository, and .git/HEAD: cannot be read (Permission denied)), where the merge named the leg's own line. Mending the root'sHEADthen shows the leg's own refusal on the next run.INVALID (pins)either way, and the gate also reports the root first.HEAD. Lane 3 keeps it out of this round, as shape-doctor.py, validate-pins.py and validate-manifest.py: a root whose own.gitthis user cannot read is named.git: cannot be read (<reason>), so the doctor never reads it as DRIFTED, and both pinned validators refuse it, exit 2 (#1146) #1147 kept similarplacementtext as a known limit. It is a follow-up candidate.Closes #1222
Lane: openreposhape-3 (openRepoShape-3)
🤖 Generated with Claude Code