You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
tests-windows never executes an adoption: git-filter-repo is not installed there, so the eight adopt suites skip and v1.0.0's "adopt works on Windows" is unverified #471
(lane openRepoShape-3, 2026-10-12T21:40Z) Filed by lane 3's v1.0.0 triage. Proposed holder: lane openRepoShape-4, on Brett Heap's word at 21:21Z, "try to assign to lane 4 some tasks". Lane 4 claims it under Rule 1 as usual. Not claimed by lane 3.
What is wrong. v1.0.0 is "core flows, all OSes" (Brett Heap, 2026-10-12): every AGENTS.md procedure, adopt included, must work end to end for ordinary repositories on Linux, macOS and Windows. But no adoption is ever executed on Windows, not in CI and not anywhere else.
.github/workflows/tests.yml's tests-windows job does not install git-filter-repo, on purpose. Its comment says the adoption suites "SKIP without it — which is the honest outcome here: what this job is for is the entry point and the materializer on Windows, not a second platform's worth of history rewriting." That was written before the release aim was set.
Eight suites skip when shutil.which("git-filter-repo") is None, so all of them skip on Windows:
tests/test_adopt_e2e.py;
tests/test_adopt_execute_refusals.py;
tests/test_adopt_mount_ignored.py;
tests/test_adopt_leg_paths.py;
tests/test_adopt_submodules.py;
tests/test_adopt_verify.py (the part that executes);
tests/test_adopt_leg_path_collisions.py;
tests/test_adopt_ignored_shape_files.py.
Between them they hold about 180 test functions before parametrisation.
The rest of Windows' skips are the WINDOWS_SKIP entry-point tests (setup.sh and shebang stubs). Those are covered case for case by tests/test_setup_project_py.py.
What v1.0.0 needs.
Install git-filter-repo in tests-windows at the version the ubuntu job pins (2.47.0), and let the adoption suites run there.
Fix what an ORDINARY repository hits on Windows in adopt-project.py: paths, line endings, how git filter-repo is found and launched, and read-only object files on cleanup. Each fix is a PR on this issue, or on a sub-issue if it is big.
Measure what the suites add to the Windows job's ~48 minutes. If it is too much to pay on every pull request, say so on this issue so Brett can choose: the suites on every PR, or a workflow_dispatch run before the tag.
Related, for the release gate. Both tests-macos and tests-windows are skipped on a push to main (if: github.event_name != 'push'). So "a full run green on all three OSes on the release commit" needs a workflow_dispatch run on that commit before the tag.
Parents: #461 (tests, CI and docs) and #457 (adopt).
CLAIMED — lane openRepoShape-4, session bf1c72df-1c56-4ac9-aace-3ddd139d7ea3@Eagle, 2026-10-12T21:41:40Z, for #471
Logged in lanes/log/openRepoShape-4.md at 72e34cd625b92f04edba86d112c99a61e26f0e77.
The three reads (lane-collision-protocol Rule 1):
1. existing `CLAIMED —` comments on opensoft/openRepoShape#471:
none
2. `gh pr list --repo opensoft/openRepoShape --state all --search "#471"`, kept where the row or its body names `#471`:
none
3. `git ls-remote --heads git@github.com:opensoft/openRepoShape` branches naming `471` as a whole token:
none
(lane openRepoShape-4, 2026-10-12T22:51Z) Probe results, Brett Heap's ruling and the plan.
Probe 1. Run 38312924968 used tests-windows only, with git-filter-repo 2.47.0 installed, over all 23 files that skip without it. #471's body lists 8; two more skip under other spellings.
Result: 1 failed, 1696 passed, 34 skipped in 19m30s.
Adoption works on Windows apart from one ordinary case.
The failure is ordinary, not exotic. The test is test_adopt_ignored_shape_files.py::test_the_assembly_bootstraps_where_it_failed_with_shape_copy_missing[its-own-attributes].
When a source tracks its own root .gitattributes, the shape's * text=auto eol=lf goes beside it, at shape/.gitattributes, and governs only shape/**.
The 9 pinned copies written at root paths get only the source's attributes: Makefile, AGENTS-shape.md, the scripts/ copies, contracts/repository-naming.yaml and the workflow.
Under Git for Windows' default core.autocrlf=true, ANY root .gitattributes without the shape's rule checks them out with CRLF. Even one that only says *.png binary does.
validate-pins.py then reports shape-copy-drift for all 9, and make bootstrap exits 1.
It reproduces on Linux under core.eol=crlf and under core.autocrlf=true, with byte-identical digests.
Ruling (Brett Heap, 2026-10-12T22:48Z): option A. The split appends a marked block to the source's own root .gitattributes, one /<copy> text eol=lf line per pinned copy the root file governs, so a Windows clone works first time with no manual step.
It overrides "never written over" for that one file, and writes only the block.
(D) a follow-up only, which leaves a Windows clone made before the follow-up broken.
Plan: two PRs on this issue.
PR 1, ci/windows-adoption-suites:
tests-windows installs git-filter-repo 2.47.0 and runs the whole suite, as now;
the comments that said Windows lacks it on purpose are corrected;
the one case above is xfail(strict=True) on Windows, naming this issue.
It is Part of #471.
PR 2, fix/adopt-gitattributes-lf-block:
implements A, pinned on Linux under core.eol=crlf;
removes the xfail;
if it is small, makes the 11 tests whose gh or git-filter-repo stub is a #! script runnable on Windows. Today these ordinary failure paths never run there: gh refusing after the push, and git filter-repo failing.
11 use names that cannot exist on NTFS or are not UTF-8: 3 TAB/control, 4 non-UTF-8, 4 newline/TAB/backslash;
9 use tracked symlinks without core.symlinks=true.
3 are test-helper only.
Timing, for Brett's choice (the suites on every PR, or a workflow_dispatch run before the tag):
Only 178 tests are new to Windows. The other 1553 in these files already run there. They add about 8 to 11 minutes: 2.8 s per gated test, which Linux's with/without difference (599.6 s against 349.1 s) confirms.
For scale, the release dry run on main d6df36b (run 38309655530, all green) took this much pytest time per job:
job
pytest time
passed
skipped
tests
11m52s
5171
10
tests-macos
36m51s
5159
22
tests-windows
1h07m56s
4692
489
One note for the release gate.tests.yml's concurrency group is the workflow plus the ref, with cancel-in-progress: true. A workflow_dispatch on main therefore cancels the last landing's Linux push run, and the next landing cancels it. Run the release commit's three-OS check on a throwaway branch at that commit, as the dry run did: ci/v1.0.0-dry-run-d6df36b, since deleted.
Activity
brettheap commentedon Oct 12, 2026
CLAIMED — lane openRepoShape-4, session bf1c72df-1c56-4ac9-aace-3ddd139d7ea3@Eagle, 2026-10-12T21:41:40Z, for #471
Logged in
lanes/log/openRepoShape-4.mdat72e34cd625b92f04edba86d112c99a61e26f0e77.The three reads (lane-collision-protocol Rule 1):
brettheap commentedon Oct 12, 2026
(lane openRepoShape-4, 2026-10-12T22:51Z) Probe results, Brett Heap's ruling and the plan.
Probe 1. Run 38312924968 used
tests-windowsonly, withgit-filter-repo2.47.0 installed, over all 23 files that skip without it. #471's body lists 8; two more skip under other spellings.The failure is ordinary, not exotic. The test is
test_adopt_ignored_shape_files.py::test_the_assembly_bootstraps_where_it_failed_with_shape_copy_missing[its-own-attributes]..gitattributes, the shape's* text=auto eol=lfgoes beside it, atshape/.gitattributes, and governs onlyshape/**.Makefile,AGENTS-shape.md, thescripts/copies,contracts/repository-naming.yamland the workflow.core.autocrlf=true, ANY root.gitattributeswithout the shape's rule checks them out with CRLF. Even one that only says*.png binarydoes.validate-pins.pythen reportsshape-copy-driftfor all 9, andmake bootstrapexits 1.core.eol=crlfand undercore.autocrlf=true, with byte-identical digests.Ruling (Brett Heap, 2026-10-12T22:48Z): option A. The split appends a marked block to the source's own root
.gitattributes, one/<copy> text eol=lfline per pinned copy the root file governs, so a Windows clone works first time with no manual step.update-shape.py --addextends the block.Rejected:
.gitattributes;Plan: two PRs on this issue.
ci/windows-adoption-suites:tests-windowsinstallsgit-filter-repo2.47.0 and runs the whole suite, as now;xfail(strict=True)on Windows, naming this issue.Part of #471.fix/adopt-gitattributes-lf-block:core.eol=crlf;ghorgit-filter-repostub is a#!script runnable on Windows. Today these ordinary failure paths never run there:ghrefusing after the push, andgit filter-repofailing.Closes #471.The 34 skips, apart from those 11:
core.symlinks=true.Timing, for Brett's choice (the suites on every PR, or a
workflow_dispatchrun before the tag):Only 178 tests are new to Windows. The other 1553 in these files already run there. They add about 8 to 11 minutes: 2.8 s per gated test, which Linux's with/without difference (599.6 s against 349.1 s) confirms.
For scale, the release dry run on main d6df36b (run 38309655530, all green) took this much pytest time per job:
teststests-macostests-windowsOne note for the release gate.
tests.yml'sconcurrencygroup is the workflow plus the ref, withcancel-in-progress: true. Aworkflow_dispatchonmaintherefore cancels the last landing's Linux push run, and the next landing cancels it. Run the release commit's three-OS check on a throwaway branch at that commit, as the dry run did:ci/v1.0.0-dry-run-d6df36b, since deleted.docs/release-notes/v1.0.0.md: brought up to main 437a360, so the note…
Merge origin/main (47b1e06) into fix/adopt-gitattributes-lf-block, so #…
README.md, AGENTS.md and the handbook: a root `.gitattributes` the so…
adopt-project.py: a source `.gitattributes` git tracks as a symlink g…
README.md: `update-shape.py apply --add` names the file it adds in a …
Merge #497 (ci/windows-adoption-suites at 6824181) into fix/adopt-git…
tests: the two index-only-link helpers #471's review round added hand…
Merge origin/main (f391e58) into fix/adopt-gitattributes-lf-block, so #…
tests/test_adopt_pins.py: the module fixture deletes its copied repos…
Merge origin/main (d41cc29) into fix/adopt-gitattributes-lf-block: th…
docs/release-notes/v1.0.0.md: brought up to main d41cc29, so section …
5 remaining items
adopt-project.py: #471's four imports, `ATTRIBUTES`, `eol_block_paths…
Merge origin/main (3121945, #494) into fix/adopt-gitattributes-lf-blo…
tests/test_repo_hygiene.py and tests/test_readme_sections.py: a handb…
Merge main (5ed3e5d, #511) into l3-519-handbook-section-hashes: #511'…
Merge main 5ed3e5d (#511's squash for #471) into fix/adopt-plan-quote…
docs/handbook.html: `apply --add` names an added file in an adopted r…
docs/release-notes/v1.0.0.md: brought up to main 8beb3d9, so section …
docs/release-notes/v1.0.0.md: brought up to main 3121945, so section …
docs/release-notes/v1.0.0.md: brought up to main 5ed3e5d, so section …
update-shape.py: `apply` refuses to rewrite a file that has a second,…
adopt-project.py: `check` finds, and `execute` refuses before any leg…
adopt-project.py: `check` finds, and `execute` refuses before any leg…
adopt-project.py: #654's question writes each file of the split in pl…
adopt-project.py and shape_materialize.py: #471's line-ending block n…