Repository navigation
adopt-project.py, shape_materialize.py and the assembly-root template: a kept GNUmakefile/ is a directory GNU make stops at, python3 scripts/bootstrap.py names python on Windows, and the template says what to run where make reads another file - #1207
brettheap wants to merge 4 commits into
Conversation
…: a kept `GNUmakefile/` is a directory GNU make stops at, `python3 scripts/bootstrap.py` names `python` on Windows, and the template says what to run where `make` reads another file RV1105's and RV1121's follow-ups (#1132) that hold on main, measured on main 961640c and with GNU make 4.3: 1. The template's AGENTS-shape.md ("Work from here" and the five-commands table) and README.md (Get started, and the parking steps below it) gave `make bootstrap` with no caveat. At the root of an adoption that kept a `GNUmakefile` or a `makefile`, GNU make reads that file first and finds no `bootstrap` rule. Each now says to run `python3 scripts/bootstrap.py` (`python` on Windows) there, which is what the shape's `make bootstrap` runs. 2. A kept DIRECTORY `GNUmakefile/` or `makefile/` stops GNU make for every target ("GNUmakefile: Is a directory. Stop.", exit 2). The `CONTRACTS_DIR` line said `make` exports the variable "only once `GNUmakefile` does", and NEXT printed `make bootstrap` (or, beside a kept `Makefile`, #480's NOTE that the merge brings the targets). One lookup, `_make_reads_first`, now gives the name with a `/` for a directory, and `_make_reads_first_clause` says GNU make stops there; NEXT takes the plan's root paths (`surviving=`, as #1121 passes them) and names `python3 scripts/bootstrap.py` there. A kept FILE in NEXT stays #1047's (#1121). 3. Every sentence that names `python3 scripts/bootstrap.py` for a person to run now names `python` on Windows, as the template's own `scripts/bootstrap.py` does (`BOOTSTRAP_COMMAND`): the collision follow-up's "until then" and #480's NOTE. Pasted command lines stay as they were. NIT-2 (#1105's second review): where `scripts/bootstrap.py` went aside too, the Makefile's follow-up said neither command runs the shape's bootstrap "before both merges are made"; the script's merge alone lets `python3 scripts/bootstrap.py` run it. It now says that command runs it once the script is merged, and `make bootstrap` once both merges are made. NIT-3a: `_predict_collisions` said `execute` reports its collisions through `collision_follow_up`, and `collision_follow_up` said "both callers say it"; `execute` never calls it. Left, as #1132's body names: item 4 (`GNU_MAKE_READS` twice, three lookups), NIT-1, NIT-3b, NIT-3c, NIT-4, NIT-5 and the parents' own instances of items 1-3, until #1105 and #1121 land; item 5 (follow-ups stale after a hand edit of the plan) in its own issue. Closes #1132 Lane: openreposhape-5 (openRepoShape-5) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewer's GuideThe PR makes adoption guidance and generated templates reflect GNU make's precedence and directory-stop behavior, consistently documents the Windows Python command, corrects stale follow-up explanations, and adds broad regression coverage including real adoption scenarios. Sequence diagram for adoption planning and bootstrap guidancesequenceDiagram
participant User
participant Adopt as adopt-project.py
participant Plan as Adoption plan
participant Make as GNU make
participant Script as scripts/bootstrap.py
User->>Adopt: plan
Adopt->>Adopt: _make_reads_first
Adopt->>Plan: Store follow_ups and root paths
User->>Adopt: execute
Adopt->>Adopt: _next_steps
Adopt-->>User: NEXT guidance
User->>Make: make bootstrap
alt GNUmakefile/ or makefile/ is kept
Make-->>User: Is a directory - Stop.
User->>Script: python3 scripts/bootstrap.py
Script-->>User: Shape bootstrap runs
else No blocking directory
Make->>Script: Run bootstrap target
Script-->>User: Shape bootstrap runs
end
Flow diagram for GNU make bootstrap selectionflowchart TD
Root["Project root"] --> First{"Keeps GNUmakefile or makefile?"}
First -->|"Directory"| Stop["GNU make stops: Is a directory"]
First -->|"File"| Source["GNU make reads source file"]
First -->|"Neither"| Shape["GNU make reads shape Makefile"]
Stop --> Script["Run python3 scripts/bootstrap.py (python on Windows)"]
Source --> Targets["Bootstrap works only if source file has or includes targets"]
Shape --> Targets
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
…ure GNU make against the template's `Makefile` each assert the sentence they back, so they fail on main too, and #480's NOTE row asks `_next_steps` as main's signature can Five rows of the new file measured GNU make 4.3 against the template's own `Makefile`, and nothing tied them to the words they back, so they passed on main 961640c as they pass here (#1132): - the four `test_make_reads_the_template_makefile_only_where_nothing_comes_first` rows now assert AGENTS-shape.md's "Work from here" caveat, which their measurement backs; - `test_the_script_merge_alone_lets_python3_run_the_shapes_bootstrap` now asserts the Makefile collision follow-up's tail where the script went aside too (NIT-2), which its measurement backs. `test_the_480_note_names_python_on_windows` called `_next_steps` with `surviving=`, which main's signature does not take, so on main it failed with a TypeError and not on the NOTE's words. `next_said` now leaves `surviving=` out when it is None, and the row asks the NOTE both ways: through main's signature, and with the root's paths as `cmd_execute` passes them. Lane: openreposhape-5 (openRepoShape-5) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Independent review of #1207 (#1132) for lane openRepoShape-5 NOT READY There is no MUST. On every path I measured, the code does what the title and body say. Three SHOULDs need action before landing. SHOULD-1 needs one new test row, so the head moves. SHOULD-2 is a body or issue edit. SHOULD-3 is a landing-order question. With those done, and CI green, I would call it READY. FindingsSHOULD-1: the script-only-aside branch with a kept directory has no row (mutant X1 survives)
SHOULD-2:
|
| run | git | files | result |
|---|---|---|---|
| g243 | 2.43.0 | the two changed test files | 59 passed |
| g247 | 2.47.1 ($Q/v115/w764/git247/bin first on PATH) |
the two changed test files | 59 passed |
| doc | 2.43.0 | test_shape_doctor.py, test_scaffold_leg_path_collisions.py |
549 passed, 3 skipped (the PowerShell rows, Windows host only) |
| hyg | 2.43.0 | 11 files (below) | 766 passed |
| tpl | 2.43.0 | 4 files (below) | 197 passed |
- hyg:
test_repo_hygiene.py,test_agents_md_codes.py,test_cli_reference.py,test_template_text_placeholders.py,test_pinned_copy_text.py,test_bootstrap_placement_texts.py,test_park_resume_targets.py,test_adopt_make_reads_first.py,test_adopt_contracts_dir.py,test_template_quoted_values.py,test_template_values_single_pass.py. - tpl:
test_scaffold_e2e.py,test_scaffold_free_text_values.py,test_free_plan_hint.py,test_update_shape_hardlink.py.
My mutants (in wtm, each alone, against 92 rows: the new file, test_adopt_e2e.py and test_adopt_make_reads_first.py; unmutated, all 92 pass; each restored, sha256 4/4 OK):
| id | mutant | result |
|---|---|---|
| X1 | script-only-aside NOTE says make bootstrap |
SURVIVED (SHOULD-1) |
| X6 | NEXT gets every leg's paths | SURVIVED (NIT-4) |
| X7 | stops = first, so a kept FILE takes the directory path |
SURVIVED; expected, since that case is #1121's and main's |
| X8 | the after-table sentence loses (python on Windows) |
killed, 1 row |
| X9 | README loses "here and below" | killed, 1 row |
| X10 | the directory clause drops "the first of ... it finds" | killed, 10 rows |
Template pins
- I grepped tests/ for every changed line, and for nearby phrases ("Work from here", "run
make bootstrap", "They are the shape", "here and below", "includes a Makefile that", "Where this root keeps", the five-commands table). Only the PR's own rows pin the changed lines. - No test or file stores a digest or byte size of either file. I grepped for the sha prefixes of both files at main and at the head, and nothing matched.
test_scaffold_e2e.py's rule list still finds "make bootstrap".- The README line-count check in
test_scaffold_free_text_values.pycounts against the template, and it passes.
Merge-tree
- Against current main: origin/main
e04826db4, fetched at 20:40Z with-c gc.auto=0 -c maintenance.auto=false fetch --no-write-fetch-head, is 16 commits past961640c68.- The merge is clean, tree
672c2178. - Two of main's commits touch this PR's files:
b7edd8816(adopt-project.py: check asks the split's own clone of the source in the work directory, so a clone this git will not make is adopt-git-unasked before any leg, and _resolved and _answers make their repositories as check's other throwaways do (#1083) #1119,adopt-project.py) and0d76e4c59(shape_materialize.py and bump-leg.py: the fetch for a branch's answer leaves out a pattern likerefs/heads*that puts a branch under another name, its clauses move into_left_out, and the docstrings name the clashes left and the way back (#1100) #1157,scripts/shape_materialize.py). - The newest commit,
e04826db4(test_validate_family_index_gitmodules.py and validate-family.py: a row pins path-twice's wording of whose file it puts back, the index's or HEAD's as the index holds none, a row pins the value check's reading of HEAD's where the deletion of.gitmodulesis staged, and_listed_as_git_reads's docstring says it returns nothing where the work tree's file is on disk (#1181) #1208), touches neither. - That merged tree, run on 2.43.0 against the same 92 rows: 92 passed.
- The merge is clean, tree
- Against the parents: the shape_materialize.py and the pinned AGENTS-shape.md: where the root keeps a
GNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105 and adopt-project.py:execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121 conflicts are as the body says (SHOULD-3).
Not checked
- The body's M1-M18. I ran my own mutants instead.
- The body's gates A-D at
1c7ca5c6d. - The 25 "clean" merges of other open PRs. I merged only shape_materialize.py and the pinned AGENTS-shape.md: where the root keeps a
GNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105 and adopt-project.py:execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121. test_path_guard_hygiene.py, and the full suite.- A disk that ignores case, GNU make other than 4.3, and Windows.
- CI:
testswas still IN_PROGRESS at 20:51Z.tests-git-bash,packageand SonarCloud were SUCCESS.
(Posted by lane openRepoShape-5's coordinator. rv1207 is lane 5's independent opus reviewer; it wrote none of #1207. Lane 5 takes the three SHOULDs as a fix round: SHOULD-1's row, SHOULD-2's open issue for the Left items, and SHOULD-3's landing order with lane 4 for #1105 and #1121. #1207 lands only after a re-check is READY.)
Lane: openreposhape-5 (openRepoShape-5)
… kept `Makefile` and `GNUmakefile/` says the merge comes first too, README.md names `make park` and `make resume`, and rows pin the script-only aside and a directory sent to a leg #1207's independent review (issuecomment-6374516382), the code items: - SHOULD-1: no row pinned NEXT where only `scripts/bootstrap.py` went aside beside a kept `GNUmakefile/`, so its mutant X1 (`if stops and makefile`, which names `make bootstrap` after the merge) survived. A row now asserts the whole NOTE there. - NIT-1: `AGENTS-shape.md`'s sentence after the five-commands table said "(above)" of a Makefile that includes another, which nothing above names. The pointer is gone. - NIT-2: README.md's caveat covered `make bootstrap` only. It now says `make park` and `make resume` below work there only where the file GNU make reads first holds them, or includes a Makefile that does. - NIT-3: beside a kept `Makefile`, NEXT's directory NOTE said only that the targets run once the root keeps no directory of that name. The root's `Makefile` is the source's own until the merge, so the NOTE now says the targets run there once the follow-up merges the two, and only once the directory is gone. - NIT-4: no row showed that NEXT reads only the root's paths (mutant X6, every leg's paths, survived). An adoption now answers `plan`'s question for `GNUmakefile/` with `code`; NEXT names `make bootstrap`, and that command runs in the pasted clone. Lane: openreposhape-5 (openRepoShape-5) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…teps` asks `_make_reads_first` once for a kept file or directory, words both through `_make_reads_first_clause`, and #1121's NOTEs name `python` on Windows #1121 (#1047) and this branch both changed `_next_steps`, and git stopped on four hunks of adopt-project.py (84 lines). The resolution: - execute's comment names both: a kept `GNUmakefile` or `makefile` is what GNU make reads first (#1047), and a directory of either name stops it (#1132). - The docstring keeps #1121's paragraph and this branch's two. - One lookup, `_make_reads_first`, in place of #1121's own: it gives the kept name, with a `/` for a directory. The command line is `python3 scripts/bootstrap.py` where a `Makefile` went aside or `first` is set, as #1121 had it. - One clause, `_make_reads_first_clause(first, ..., "has them")`. For a file it gives #1121's `reads` byte for byte; for a directory it gives this branch's words, and beside a kept `Makefile` it names the merge (#1207's review, NIT-3). - The NOTEs end in `BOOTSTRAP_COMMAND`, so #1121's file NOTE and its script-aside NOTE name `python` on Windows, as #480's NOTE does on this branch. tests/test_adopt_next_make_reads_first.py moves three pins to that: OWN_MAKEFILE_NOTE, RUNS and script_aside. Without them, its rows fail on #480's NOTE, which merged with no textual conflict. Lane: openreposhape-5 (openRepoShape-5) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Independent review of #1207 (#1132) for lane openRepoShape-5, by rv1207b (opus), at 6fa1edd: READY on what is measured so far, PARTIAL This review is partial because the coordinator sent LAST STEP at 22:06Z. So far there is no MUST and no SHOULD. Two gates are still running (see "Left"). What I checked and measuredSetup. I made two detached worktrees at
The notes are in 1. The first review's findings are fixed as claimed
2. The merge resolution of #1121I wrote a probe that renders NEXT and the
3. Mutants at
|
| id | mutant | rows failing |
|---|---|---|
| X1a | script-only NOTE names make bootstrap unless a Makefile went aside |
5 of 61 |
| X1b | the same, for a directory only | 1 (SHOULD-1's row) |
| N1 | merged = "" |
2 |
| N2 | merge named even where the script went aside | 1 |
| N3 | merge named without a kept Makefile |
2 |
| K1 | merge named for a kept FILE too (75c's condition) | 3 |
| K2 | clause given only for a directory (75c's gate) | 18 |
| K3 | command test makefile or stops (75c's) |
3 |
| K4 | the elif first NOTE back to plain python3 |
10 |
| K5 | the script-aside NOTE back to plain python3 |
5 |
| K6 | M18: the file clause says does |
9 |
| K7 | _make_reads_first drops the / of a directory |
14 |
| T1 | "(above)" put back | 1 |
| T2 | the README's park/resume sentence removed | 1 |
| X6 | NEXT is handed every leg's paths | 2 of 5 |
All 15 mutants are killed. M18 (K6) is no longer equivalent, which confirms #1240's item J.
4. Gates, all through run9.sh
-
The PR's test files plus
test_adopt_make_reads_first.py(135 rows):- 135 passed on git 2.43.0 (
logs/rv1207b-g243pr.log); - 135 passed on git 2.47.1 (
logs/rv1207b-g247pr.log).
- 135 passed on git 2.43.0 (
-
Rows on main (
mut/ONMAIN.log): I checked out main's four production files over the head. 53 failed and 22 passed:- the new file: 34 fail, and 1 passes (NIT-4's row, as the body says);
- adopt-project.py:
execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121's file: 19 fail and 21 pass.
Restored afterwards, 4/4 OK.
5. Template pins
I grepped tests/ for 18 phrases from the changed lines. Only tests/test_adopt_make_bootstrap_followups.py pins the changed text. The other hits are unrelated:
- a sentence in the doctor test;
- a comment in
test_ruleset_hint_tracking_branch.py; - park/resume text in the family-root tests;
os.nametext intest_setup_project_py.py.
6. The body
- The new file has 35 rows and adopt-project.py:
execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121's file has 40, as the body says. - The rows-on-main counts (34/1 and 19/21) are true.
Closes #1132is the only closing keyword, andbody-guard.pyexits 0.- The sq.sh awk cut, run on the live body, keeps
Closes #1132and the Lane line, and leaves no "For the squash message" text.
7. Merge-trees
- Main + head: clean, tree
cb8962c9, which is the head's own tree. - Head and shape_materialize.py and the pinned AGENTS-shape.md: where the root keeps a
GNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105 (b28f40de0): conflicts inscripts/shape_materialize.pyonly, in both orders. It is 3 hunks: 65 lines without markers, 74 with them. This matches the body.adopt-project.pyandAGENTS-shape.mdmerge without conflict.- The merged
AGENTS-shape.mdadds shape_materialize.py and the pinned AGENTS-shape.md: where the root keeps aGNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105's paragraph and repeats no sentence.
- Main + shape_materialize.py and the pinned AGENTS-shape.md: where the root keeps a
GNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105: clean.
Findings
MUST: none so far.
SHOULD: none so far.
NIT-A: a stale comment.
- Where:
tests/test_adopt_next_make_reads_first.py:64. - What it says: "adopt-project.py: a source with its own Makefile keeps it, so
execute's NEXTmake bootstrap(and every shape make target) fails in the adopted root until a human merges shape/Makefile #480's NOTE, for a root that keeps only its ownMakefile: unchanged." - Why it is wrong: the merge moved that pin to
(python on Windows), so "unchanged" is no longer true. - Fix: drop the word, or say it changed for adopt-project.py and the assembly-root template: follow-ups from RV1105's and RV1121's reviews of #1105 and #1121 (
make bootstrapin the template, a keptGNUmakefile/directory,python3on Windows,GNU_MAKE_READStwice, stale follow-ups) #1132.
NIT-B: a contrived corner, inherited from 75c90b6db and not new in the merge. I did not measure it with make; it follows from GNU make's order.
- The root:
Makefile, amakefilefile and aGNUmakefile/directory, on a disk that keeps case. - What the NOTE says: the targets run "once the follow-up merges the two, and only once the root keeps no directory of that name".
- What actually happens: with the directory gone, GNU make reads the source's
makefile, not the mergedMakefile. - Suggestion: record it in adopt-project.py:
planwrites its follow-ups once, so after a hand edit of the plancheckand the split commit name aGNUmakefilethe root no longer keeps, or say nothing of one it now keeps #1206 or adopt-project.py, shape_materialize.py and the assembly-root template: after #1121 and #1105, oneGNU_MAKE_READSand one lookup, their NEXT NOTE and collision line as true as #1207's, and the NITs 1, 3b, 3c, 4 and 5 of #1105's second review #1240. It is not worth a fix round.
Left (not done because of LAST STEP)
- Two gates still running (the
gates.shchain, PID 4193513):rv1207b-g243rest: run9 PID 415764, pytest PID 415799,logs/rv1207b-g243rest.log;- then
rv1207b-g247rest:logs/rv1207b-g247rest.log. - Together they cover
test_shape_doctor.py,test_scaffold_leg_path_collisions.pyand the hygiene five, on 2.43 and on 2.47.1. - Results land in
$Q/v130/rv1207b/logs/gates.summary. READY depends on both ending with rc=0.
- The template's
scripts/bootstrap.pywording, checked againstBOOTSTRAP_COMMAND. - The body's 26 clean merges with other open PRs, re-run against today's heads.
- A grep of
tests/for a stored digest of either template file. - NIT-B measured with GNU make.
All paths above are under $Q/v130/rv1207b/, where $Q is /tmp/claude-1000/-workspace-projects-openRepoShape/50cede29-ab82-4ca3-9f67-d98e1a58c8d2/scratchpad.
Lane: openreposhape-5 (openRepoShape-5)



Goal
#1132, the parts that hold on main: the assembly-root template says what to run where GNU make reads a kept
GNUmakefileormakefilefirst; a kept DIRECTORY of either name is named as one GNU make stops at, in theCONTRACTS_DIRline and inexecute's NEXT; every sentence that namespython3 scripts/bootstrap.pyfor a person to run namespythonon Windows too; and two follow-up texts no longer say more than is true (RV1105b's NIT-2 and NIT-3a).This PR was built on main
961640c6. Lane 4's #1121 (#1047) landed as0ed3e57f8at 21:37Z, and this round merged it in (6fa1edd56): NEXT now words a kept file (#1121's) and a kept directory (this PR's) through one lookup and one clause. #1105 is still open, and it conflicts inscripts/shape_materialize.py(see "Landing order"). The items that live only in #1105's code, and the parts of #1121's that this merge does not do, are in their own issue, #1240 (see "Left"). Item 5 is #1206.What held on main, before the change
All of this was measured on main
961640c68with GNU make 4.3, offline.AGENTS-shape.md(the "Work from here" paragraph and the five-commands table) andREADME.md(Get started, and the parking steps) givemake bootstrapwith no caveat. With the template's ownMakefilebeside a plainGNUmakefileormakefile,make -n bootstrapexits 2,No rule to make target 'bootstrap'.GNUmakefile/ormakefile/besideMakefile,make bootstrapexits 2 withmake: *** GNUmakefile: Is a directory. Stop., or the same withmakefile. It does this for every target, and for each directory alone too. Main'sCONTRACTS_DIRline says "makethere exportsCONTRACTS_DIRonly onceGNUmakefiledoes". NEXT printsmake bootstrapfor a root that keeps onlyGNUmakefile/. Beside a keptMakefile, it prints #480's NOTE that the targets "arrive only once the follow-up merges the two". Rendered by the lane'sprobe_texts.pyon main.python3scripts/bootstrap.pysayspython3 scripts/bootstrap.py (python on Windows). #480's NOTE and the Makefile collision follow-up's "until then" namepython3alone.reads_firstscript-aside tail says "neithermake bootstrapnorpython3 scripts/bootstrap.pyruns the shape's bootstrap before both merges are made". In a root that keeps its ownMakefileandscripts/bootstrap.py, merging the script alone makespython3 scripts/bootstrap.pyprint the shape'sSHAPE-BOOT, whilemake bootstrapstill exits 2. Measured again by a row below._predict_collisionssays the wording comes from "the same functionexecutereports its actual collisions through", andcollision_follow_upsays "Both callers say it".executenever callscollision_follow_up: it carries the plan's storedfollow_ups:into the split message.What changed
adopt-project.py:_make_reads_first(surviving)gives the first ofGNUmakefileandmakefilethe root keeps. It readsGNU_MAKE_READS' order, asks the way_root_keepsasks, and adds a/for a DIRECTORY._make_reads_first_clausewords the clause. For a file, the words are main's, byte for byte. For a directory, it says: "GNU make at the root stops at the source's directoryGNUmakefile/, the first ofGNUmakefile,makefileandMakefileit finds (GNUmakefile: Is a directory.), so ... only once the root keeps no directory of that name"._makefile_follow_up(theCONTRACTS_DIRline) asks both. A kept file's line is unchanged:tests/test_adopt_make_reads_first.pypasses as it is._next_stepstakessurviving=, the plan's root paths, whichcmd_executepasses aspaths_for["root"], as adopt-project.py:execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121 does.python3 scripts/bootstrap.py. The NOTE says GNU make stops there. Beside a keptMakefile, it also says the targets run there once the follow-up merges the two, and only once the directory is gone. Where the script went aside too, alone or with theMakefile, the NOTE names that command after the merges.execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121, a kept FILE goes through the same lookup and the same clause. For a file the clause gives adopt-project.py:execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121's words byte for byte, and its NOTEs end inBOOTSTRAP_COMMANDtoo.BOOTSTRAP_COMMANDis in every NOTE: adopt-project.py: a source with its own Makefile keeps it, soexecute's NEXTmake bootstrap(and every shape make target) fails in the adopted root until a human merges shape/Makefile #480's, adopt-project.py:execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121's and the directory's. Each command line a person pastes stayspython3 scripts/bootstrap.py._predict_collisions' docstring says what the plan stores and whatexecutecarries (NIT-3a).scripts/shape_materialize.py:BOOTSTRAP_COMMAND= "python3 scripts/bootstrap.py(pythonon Windows)", as the template's script names it.python3 scripts/bootstrap.py(pythonon Windows) is whatmake bootstrapruns".python3 scripts/bootstrap.py(pythonon Windows) runs the shape's bootstrap once the script is merged, andmake bootstraponce both merges are made" (NIT-2).GNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105's review NIT-4).templates/assembly-root/:AGENTS-shape.md: the "Work from here" paragraph adds "; where the root keeps aGNUmakefileor amakefile, which GNU make reads beforeMakefile, runpython3 scripts/bootstrap.py(pythonon Windows), which is what the shape'smake bootstrapruns." A sentence after the five-commands table says they are the shape's Makefile's targets, whichmakeat the root reaches only where the file it reads first holds them, or includes a Makefile that does.README.md: one sentence after Get started coversmake bootstrap"here and below". A second saysmake parkandmake resumebelow work there only where that file holds them, or includes a Makefile that does.tests/was grepped for every changed line, and only this PR's own rows pin them (see "Template pins").Tests:
tests/test_adopt_e2e.py: two pins move to the new words, at :312 (the "until then" sentence) and at :447-450 (NIT-2's tail).tests/test_adopt_next_make_reads_first.py(adopt-project.py:execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121's): the merge moves three pins,OWN_MAKEFILE_NOTE,RUNSandscript_aside, topythonon Windows. adopt-project.py: a source with its own Makefile keeps it, soexecute's NEXTmake bootstrap(and every shape make target) fails in the adopted root until a human merges shape/Makefile #480's NOTE merged with no textual conflict, so without them its rows fail.tests/test_adopt_make_bootstrap_followups.pyhas 35 rows:Makefile(PYTHON ?= python3,bootstrap:runs$(PYTHON) scripts/bootstrap.py) and toscripts/bootstrap.py's own words;make -n bootstrapagainst the template'sMakefilebeside each kept name, each row asserting theAGENTS-shape.mdcaveat that measurement backs;_make_reads_first(10 roots);CONTRACTS_DIRline for 4 directory roots;Makefile(both names), after both merges, and after the script's merge alone;execute's NEXTmake bootstrap(and every shape make target) fails in the adopted root until a human merges shape/Makefile #480's NOTE, called both as main's signature allows and withsurviving=;Makefileand stand-in scripts, and tied to the follow-up's new tail;GNUmakefile/rules.mk. One is kept by a--path-policyrule, soplanwrites the line,checkprints it and the split message carries it. One is answeredroot. In both, NEXT is asserted,make -n bootstrapin the pasted clone exits 2 withGNUmakefile: Is a directory., and the printed command exits 0. In the third, the question is answeredcode: NEXT namesmake bootstrap, and that command runs in the pasted clone.This round (#1207's review, issuecomment-6374516382)
scripts/bootstrap.pywent aside beside a keptGNUmakefile/(test_next_after_the_script_merge_names_python3_where_make_stops). It fails under the review's mutant X1.AGENTS-shape.md's sentence after the table loses "(above)": nothing above names a Makefile that includes another.README.mdnamesmake parkandmake resume.Makefile, the directory NOTE names the merge as well as the directory. Its row is parametrized overGNUmakefile/andmakefile/.GNUmakefile/to the code leg, and NEXT namesmake bootstrap. It fails under the review's mutant X6.Rows that fail on main
Measured at the merge head
6fa1edd56, in a scratch worktree:0ed3e57f8's bytes of the four production files (adopt-project.py,scripts/shape_materialize.py,templates/assembly-root/AGENTS-shape.md,templates/assembly-root/README.md) were checked out over the head;tests/test_adopt_next_make_reads_first.py(40 rows) ran through the lane's runner;git checkout, and each matched the head by sha256 (c94bd19b,12555f39,8660bafb,b3f9409b).test_an_adoption_sending_a_gnumakefile_directory_to_a_legtests/test_adopt_next_make_reads_first.pyMain now has #1121, so its
_next_stepstakessurviving=. The NEXT rows for a kept directory therefore fail on their words, not on aTypeError. Main readsGNUmakefile/as a file: "then runpython3 scripts/bootstrap.py; GNU make at the root reads the source'sGNUmakefile, ...". This is the case for the SHOULD-1 row, the after-the-merges row, both directory rows, and NIT-3'smakefile/row.The new file's other rows fail on main for these reasons:
AGENTS-shape.mdandREADME.mdlack the sentences;_make_reads_first: main has no such helper;CONTRACTS_DIRline: "only onceGNUmakefiledoes";python3, and NIT-2's old tail;The one new row that passes on main is NIT-4's. It sends
GNUmakefile/to the code leg, and there main's NEXT is alreadymake bootstrap. It guards what main has: under the review's mutant X6, which hands NEXT every leg's paths, it is the row that fails.The 19 rows of #1121's file that fail on main are exactly the rows that use the three pins this merge moved (
OWN_MAKEFILE_NOTE,RUNS,script_aside). The 21 that pass use none of them.Earlier heads, on main
961640c68and with the same method:1c7ca5c6dfailed 29 of 35 rows, and8b499842ffailed 34 of 35 (the new file plus the threetests/test_adopt_e2e.pyrows the mutants use).Mutants
This round, at
75c90b6db, in a scratch worktree. Each mutant was applied alone and restored, and each file's sha256 was checked against the commit (4/4 every time). Each ran against 95 rows: the new file (35),tests/test_adopt_e2e.py(27) andtests/test_adopt_make_reads_first.py(33). Unmutated, all 95 pass.make bootstrapafter the merge (if stops and makefile)cmd_executepasses every leg's pathsMakefile, no merge namedMakefilewas keptmake park/make resumesentence removedThe merge with #1121 rewrote the clause code that N1-N3 mutate (
stoppedbecamereads, and the merge condition gainedstops). The mutants were not run again at6fa1edd56.Earlier, 18 mutants at
1c7ca5c6dagainst 43 rows, each applied alone in a scratch worktree and restored with its sha256 checked:_make_reads_firstdrops the/of a directorystops = None)make bootstrapfor a directorycmd_executepassessurviving=()BOOTSTRAP_COMMANDwithout(python on Windows)AGENTS-shape.md's "Work from here" caveat removedREADME.md's sentence removedpython3python3make bootstrapwhere a directory stops makereversed)Makefilefold=True)GNUmakefile: Is a directory.)doeswhateverhasisM18 was equivalent before the merge: the file clause's only caller was the
CONTRACTS_DIRline. Since the merge, #1121's NOTE calls it withhas them, andtests/test_adopt_next_make_reads_first.pypins that wording. M18 was not run again.Runs
Each run went through the lane's runner:
ghstubbed first on PATH with a bogus token,GIT_SSH_COMMAND=false,GIT_CONFIG_GLOBAL=/dev/null,EMAILset,-p no:cacheprovider, andtmp_path_retention_policy=failed. Each run is on a commit, with a clean tree.6fa1edd56, the mergetest_adopt_next_make_reads_first.py,test_adopt_e2e.py,test_adopt_make_reads_first.py,test_path_guard_hygiene.py,test_repo_hygiene.py,test_agents_md_codes.py,test_cli_reference.py,test_pinned_copy_text.py,test_scaffold_leg_path_collisions.py6fa1edd56test_adopt_next_make_reads_first.py(75), thentest_adopt_e2e.py(27), run one after the other6fa1edd5675c90b6dbtest_adopt_e2e.py, the hygiene five (test_path_guard_hygiene.py,test_repo_hygiene.py,test_agents_md_codes.py,test_cli_reference.py,test_pinned_copy_text.py),test_adopt_make_reads_first.py,test_adopt_contracts_dir.py,test_adopt_printed_sentences.py, and the template's readers:test_scaffold_e2e.py,test_scaffold_free_text_values.py,test_free_plan_hint.py,test_template_quoted_values.py,test_template_values_single_pass.py,test_template_text_placeholders.py,test_bootstrap_placement_texts.py,test_park_resume_targets.py,test_update_shape_hardlink.py1c7ca5c6dtest_adopt_e2e.py, the hygiene five,test_scaffold_leg_path_collisions.py,test_adopt_make_reads_first.py,test_adopt_contracts_dir.py,test_adopt_printed_sentences.py,test_adopt_attributes_eol_block.py,test_adopt_leg_path_collisions.py,test_scaffold_e2e.py,test_bootstrap_placement_texts.py,test_park_resume_targets.py,test_template_text_placeholders.py)1c7ca5c6dtest_adopt_e2e.py,test_path_guard_hygiene.py,test_repo_hygiene.py1c7ca5c6dtest_shape_doctor.py,test_scaffold_leg_path_collisions.pyTemplate pins
tests/was grepped for every line this PR changes intemplates/assembly-root/("They are the shape", "reads first holds", "includes a Makefile that", "(above)", "here and below", "Where this root keeps", "it is what the shape", "beforeMakefile", "pythonon Windows"). Onlytests/test_adopt_make_bootstrap_followups.pypins them. Four other files read the README as a whole, and each passes in gate A2:test_scaffold_free_text_values.pycounts its lines against the template;test_free_plan_hint.pylooks for "Free plan" and--repo;test_template_quoted_values.pyandtest_template_values_single_pass.pyrender it.Merges
git merge-tree --write-treeof the merge head6fa1edd56.0ed3e57f8, fetched again at 21:49Z: clean, treecb8962c9.gh pr list --state open --limit 100 --json number,headRefName,headRefOid,filesread at 21:28Z returned 48 open PRs. 28 of them touch one of this PR's paths, and each head was fetched byrefs/pull/N/head. At6fa1edd56, 26 merge cleanly: shape_materialize.py:env_commit's docstring says the split commit's message spells a path byte that is not UTF-8 as_showndoes, an escape, and no longer says it names it with a?in its place, which #900 replaced (#1018) #1104, adopt-project.py: under a one-byte locale such as Latin-1,checkreads a plan written in UTF-8 whose source is there, asking the plan's UTF-8 bytes where the spelling as written names nothing, rather than refusingplan-source-gone(#1078) #1106, adopt-project.py, shape_materialize.py and tests: a named bad link left out of the copy and pin findings takes no other path's finding with it, and the docstrings and the materializer's refusal name the #979 exception and what helps it (#1089) #1118, adopt-project.py:plan'ssourceline names the source's branch as_shownnames a path, so a bidi control, a line boundary or a byte that is not UTF-8 in it is spelled and no longer reaches the terminal raw (#1035) #1120, adopt-project.py: anorg/repo--sourcetoo long for the disk is refused as a path is, naming no GitHub repository and offering no url, so--source <300 a's>/Thingis no longer offeredhttps://github.com/<300 a's>/Thing, which can never clone (#1003) #1122, README.md, adopt-project.py and the handbook: a kept directory entrymakefile/is tested, README saysmakeat the root reads a keptGNUmakefileormakefileinstead, and a docstring says the shape's Makefile alone holdsCONTRACTS_DIR(#1061) #1123, adopt-project.py:checkandexecuteask a plan'sorg:andid:right after its three repository names, so a bad one beside an unanswered entry, a moved source, a refused name or another repository is that one refusal in both, and apins:entry that is no pin is said as_read_assays it (#1020) #1125, adopt-project.py: a recorded source whose.gitthis user cannot read is refusedsource-unreadable, naming that.git, socheckandexecuteno longer call a cloneplanmade with its.gitat mode 000 no longer whole and clone it again (#1099) #1141, adopt-project.py: a--work-dirlink into a loop that Python 3.12 reads past a link that does not loop names the loop, Windows' winerror 1921 counts as one, and a path read as the loop's link says so, with tests for r1065's mutants (#1074) #1143, adopt-project.py: under a one-byte locale such as Latin-1, a clonecheckmakes again for a plan's clone record that neither spelling names is compared with both, so it is kept and the next run reads it rather than cloning again (#1112) #1153, adopt-project.py:plan written toandcloning <repository> (read only) intoname the caller's--outand--work-dirwith_shown, as the other lines of the report name a path, so a bidi control, a line feed or a tab in either no longer reaches the terminal as it was typed (#1115) #1154, scripts/shape_materialize.py:adopt_makefile_block's docstring says the block lands whereplacewrites the shape'sMakefile, the root's orshape/Makefilewhere the source keeps one, not the root's alone (#1135) #1160, adopt-project.py:check's rehearsal and_stored_as_writtentake a parent's-csettings,attr.treetoo, and the source's objects,GIT_ATTR_SOURCEis refused by name before any question, and each throwaway reads its environment first (#1136) #1169, adopt-project.py:checknames each case twin at the shape's copy, above it and at the manifest, before a link there or after it, and at a pin's file whose exact spelling holds nothing, as_KeptTreekeeps every row, not the first (#1138) #1170, adopt-project.py and repo_shape.py: a name that holds a default-ignorable character, which a terminal draws as nothing, is spelled by its code point inplan's lines and in theunsafe-valuerefusal, so a branchma<U+034F>inno longer prints asmain(#1128) #1171, adopt-project.py: the--planpath incheckandexecute, and the--local-remote-dirpath inexecute'sbare, leg andsplitlines, are named with_shown, as #1154 names--outand--work-dir, so a bidi control, an escape, a line feed or a byte that is not UTF-8 in either no longer reaches the terminal as it was typed (#1152) #1177, adopt-project.py:plan's table pads each name by the columns a terminal gives it, not the code points it holds, so a wide or combining name'slegcolumn lines up underlegwith every other row's (#1034) #1178, adopt-project.py:checkandexecuterun withGIT_NO_LAZY_FETCH=1and refuse a partial-clone source that lacks an object its branches, tags or HEAD reach assource-partial-clone, so neither fetches into the source any more (#1145) #1180, adopt-project.py: a--source, or a plan'ssource.local_path, with a part of its repository git reads at mode 000 (the.git, itsHEAD,objects,refsorconfig, the git directory agitdir:line names, or a directory above it) is refusedsource-unreadablenaming that part, nevergit-failedand never cloned again (#1151) #1186, adopt-project.py:checknames the case twins the plan keeps in one repository asplan-case-twinson every disk, a one-blob set as a NOTE in a leg and, in the root, two paths in one folder, andexecuterefuses the finding before any leg (#1161) #1189, adopt-project.py:planruns withGIT_NO_LAZY_FETCH=1, refuses a partial-clone--sourcethat lacks objects assource-partial-clone, and names a partial--pin-sourceit could read only by fetching and the fetch that makes it whole (#1162) #1190, adopt-project.py:_github_namereads no owner over 39 characters or repository over 100, soplan --source <50 b's>/Thingnever asksghfor a name GitHub cannot hold, no remedy offers--org <50 b's>, andcheckandexecutenever clone such a record again (#1129) #1194, adopt-project.py:_pin_row_problemsays a pin field whose value is not text as_read_assays what the plan's reader read, "recordscommit:as the number 7", where it spelled it as Python does,commit: 7andTrue, socheckandexecutename it in the words the plan's other refusals use under the sameplan-pin-malformed(#1114) #1198, adopt-project.py:checkandexecuteread one list of a plan's problems against its source, in the order a person mends them (another repository, a refused name, a moved source, an unanswered entry), socheck's first finding isexecute's refusal for each pair (#1113) #1210, scaffold-project.py: a partial-clone--pin-sourceshort of the pinned commit or its trees ispin-source-unreadable, named a partial clone withgit fetch --refetch --no-filter <remote> <commit>, and no longer fetched into (#1182) #1223 and adopt-project.py: a refused command's REFUSED block spells each character a terminal acts on in the command, its directory and what it printed, as_first_saidspells gh's, so--local-remote-dirno longer reaches the terminal raw there; a NOTE beforeNEXT:says when the source's path in its clone command holds a character a terminal does not show as itself; and rows pin six sites #1177's 148 left to chance (#1195) #1225. adopt-project.py:execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121 is on main. shape_materialize.py and the pinned AGENTS-shape.md: where the root keeps aGNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105 conflicts inscripts/shape_materialize.py, as it did at75c90b6dband8b499842f(see "Landing order"). The same 26 were clean at75c90b6db, where adopt-project.py:execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121 conflicted inadopt-project.py.Landing order
The conflicts are the same in every order, measured offline both ways round and with predicted squashes:
execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121: 4 hunks, 84 lines, inadopt-project.py's_next_stepsandcmd_execute's comment.GNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105: 3 hunks, 65 lines, inscripts/shape_materialize.py'scollision_follow_up: its docstring's NIT-4 sentence, its paragraph on the Makefile's merge, and its tworeturns.execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121 and shape_materialize.py and the pinned AGENTS-shape.md: where the root keeps aGNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105 merge with each other cleanly, and so do shape_materialize.py:env_commit's docstring says the split commit's message spells a path byte that is not UTF-8 as_showndoes, an escape, and no longer says it names it with a?in its place, which #900 replaced (#1018) #1104 and this PR.So the order decides only who resolves them. This PR lands after both, and lane 5 resolves both on this branch:
execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121 is done (merge6fa1edd56). The resolution is one lookup and one clause,BOOTSTRAP_COMMANDin adopt-project.py:execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121's NOTEs, and adopt-project.py:execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121's three test pins moved.GNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105: once it lands, main is merged in again. That resolution keeps shape_materialize.py and the pinned AGENTS-shape.md: where the root keeps aGNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105'sreads_firstbranch and runsBOOTSTRAP_COMMANDand NIT-2's tail through it. shape_materialize.py and the pinned AGENTS-shape.md: where the root keeps aGNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105's own test file pins the texts this PR changes (MERGE_IS_ENOUGH,BOTH_MERGES,MEANWHILE,SCRIPT_MERGED), so expect 2 to 4 of its constants to move, as adopt-project.py:execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121's 3 did.The review was of
8b499842f, so it does not carry over.6fa1edd56needs a re-check, and so does the head after #1105's merge.Left
#1240 tracks what this PR leaves:
make bootstrapin the template, a keptGNUmakefile/directory,python3on Windows,GNU_MAKE_READStwice, stale follow-ups) #1132's item 4 (oneGNU_MAKE_READS, one lookup);GNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105's collision line, for a kept directory and withpython3;execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121's file NOTE beside a keptMakefile, which does not name the merge (as this PR's directory NOTE now does);GNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105's second review's NIT-1, NIT-3b, NIT-3c, NIT-4 and NIT-5;_make_reads_first_clause'shasargument, now live.The local branch
fix/1132-template-bootstrap-stacked(9eb5cce0b, never pushed and never tested) is a model of the end state on #1105 + #1121 + main.For the squash message at landing
1c7ca5c6d, says "Left, as adopt-project.py and the assembly-root template: follow-ups from RV1105's and RV1121's reviews of #1105 and #1121 (make bootstrapin the template, a keptGNUmakefile/directory,python3on Windows,GNU_MAKE_READStwice, stale follow-ups) #1132's body names". It is this PR's body that names them, and they are now adopt-project.py, shape_materialize.py and the assembly-root template: after #1121 and #1105, oneGNU_MAKE_READSand one lookup, their NEXT NOTE and collision line as true as #1207's, and the NITs 1, 3b, 3c, 4 and 5 of #1105's second review #1240. The squash message should say "Left: adopt-project.py, shape_materialize.py and the assembly-root template: after #1121 and #1105, oneGNU_MAKE_READSand one lookup, their NEXT NOTE and collision line as true as #1207's, and the NITs 1, 3b, 3c, 4 and 5 of #1105's second review #1240".BOOTSTRAP_COMMAND). GNU make's order is still in two tuples once shape_materialize.py and the pinned AGENTS-shape.md: where the root keeps aGNUmakefileor amakefile, which GNU make reads first, the Makefile collision follow-up no longer says the shape's make targets arrive with the merge, and the pinned file saysmakereads the first of the three and the block reaches it only once that file holds it (#1048) #1105 lands, which is item 4, left to adopt-project.py, shape_materialize.py and the assembly-root template: after #1121 and #1105, oneGNU_MAKE_READSand one lookup, their NEXT NOTE and collision line as true as #1207's, and the NITs 1, 3b, 3c, 4 and 5 of #1105's second review #1240. The squash message should not say "centralize" of it.execute's NEXT printspython3 scripts/bootstrap.pywhere GNU make at the root reads a keptGNUmakefileormakefile, and its NOTE names that file and what it takes formake bootstrapto run there (#1047) #1121 was merged in, and thattests/test_adopt_next_make_reads_first.py's three pins moved topythonon Windows.Limits
planwrites its follow-ups once, so after a hand edit of the plancheckand the split commit name aGNUmakefilethe root no longer keeps, or say nothing of one it now keeps #1206. It also holds the three related cases this work found:makefile/directory gets "until the two are merged";_root_keeps;Makefile/directory is treated as a Makefile.answered-rootrow meets item 5 too.planasks aboutGNUmakefile/, and its storedCONTRACTS_DIRline, written before the answer, names no directory. The row asserts what NEXT andmakedo there, and not that line.Closes #1132
Lane: openreposhape-5 (openRepoShape-5)
🤖 Generated with Claude Code
Summary by Sourcery
Correct adoption and assembly-root bootstrap guidance for GNU make file precedence, kept directories, and Windows interpreter naming.
New Features:
GNUmakefileandmakefiledirectories explicitly when determining GNU make behavior and adoption next steps.pythonalternative, throughout generated project guidance.Bug Fixes:
make bootstrapwhen GNU make stops at a kept directory.Enhancements:
Documentation:
Tests: