Repository navigation
Description
Lane: openreposhape-3 (openRepoShape-3)
The parent issue for one area of openRepoShape: converting an existing repository into an assembly root with a spec leg and a code leg (adopt-project.py plan, check, execute). Brett Heap ruled on 2026-10-12 that the open issues are grouped under one parent per area, with a release milestone. Every open issue in this area is a sub-issue here.
v1.0.0. The first release is "core flows, all OSes": every procedure in AGENTS.md works end to end for ordinary repositories on Linux, macOS and Windows. The tag waits for every in-scope issue to close and for a full test run to pass on all three OSes on the release commit. In this area, the sub-issues in the v1.0.0 milestone are:
- adopt-project.py
executeexits 2 with nothing on stderr whengit filter-repofails, after both leg remotes exist:_build_the_legsswallowsCommandFailedon the premise thatrunalready reported it, andrunonly raises #171 (P2): A failure extracting a leg endsexecuteexit 2 with empty stderr, both leg repositories left behind; needs a git failure first; adopt-project.py: every failure once a leg repository exists flushes stdout, then printsREFUSED <step>., what failed and one notice of what the run left, so a failedgit filter-repono longer exits 2 with an empty stderr (#171, #188, #177) #445 fixes. - RULESET_HINT advises
push -u origin ...from an extracted leg whoseoriginfilter-repo removed, and says "listed above" of lines a combined log prints after it #177 (P1): Adopting into a ruleset org: the refused-push hint printspush -u origin, but filter-repo removed origin, so the advised command fails. - adopt-project.py: a failure AFTER both legs are pushed (the split-branch push, the mount, the split commit) prints only
REFUSED <step>with no notice of what already exists and no stdout flush, so the combined log shows REFUSED before thebare …lines and the re-run meetsleg-remote-existsunexplained #188 (P2): A split-push, mount or commit failure after both legs exist prints REFUSED but not what already exists, so the re-run'sleg-remote-existsis unexplained. - adopt-project.py
--pin <name>is accepted byplan,checkandexecute("adoption verified"), but writes only the name intoneutral_product_pins:and nocontracts/<name>-pin.yaml, so the adopted root's ownvalidate-pins.py(and itsvalidate.yml) refuses withneutral-pin-missingfrom the first run #273 (P1):adopt-project.py plan --pin <name>(in docs/cli.md) endsadoption verified, then the adopted root's ownvalidate-pins.pyrefusesneutral-pin-missing: red CI from day one. - adopt-project.py
checkpasses a plan that keeps the source's ownproject.yamlin the root, andexecutewrites the shape's manifest beside it asshape/project.yamland saysadoption verified, so shape-doctor.py calls the adopted assembly NOT A SHAPE ROOT and its firstmake bootstrapfails #305 (P2): A source with its own top-levelproject.yamlansweredrootisplan ok,adoption verified, then NOT A SHAPE ROOT;spec/code/dropwork. - adopt-project.py:
plan,checkandexecutenever look for the plan's split branch (adopt/three-repo-shape) in the repository the split is pushed to, so a re-run after an earlier run left it passescheck, creates both legs, and dies at a non-fast-forward push of the split #320 (P1): AGENTS.md's recovery after a failed verification (re-run into fresh legs) meets the leftoveradopt/three-repo-shape:checkpasses, both legs created, push rejected. - adopt-project.py
plan:--spec-pathand--code-pathhave nohelp=, soplan --helpanddocs/cli.mdprint two bare lines for the flags that choose where each leg is mounted, and say nothing of the two refusalsplanmakes on them before anything is created (adopt-leg-path-collides,adopt-bad-leg-path), which #288 is documenting for the scaffold's twins #340 (P2):plan --helpand docs/cli.md print--spec-path/--code-pathbare, saying nothing of the default or the two refusals; docs gap, no behaviour change.
Known limits. Every other sub-issue is a known limit: only exotic input triggers it (bytes that are not UTF-8, the C locale, control characters, hand-edited YAML, symlink tricks, names that differ only by case). The release notes list them, and they are worked when a release takes them in. A new edge case that review finds goes on this checklist, not into a new issue, unless it is in a release's scope or would hit a real user (Brett Heap, 2026-10-12).
Known limits measured by lane openRepoShape-3 on main 45e01f4 and kept here rather than filed:
- → adopt-project.py
execute: under a non-UTF-8 locale, a moved or dropped path that is not ASCII killsgit rmafter both legs are pushed #527, done in adopt-project.py:executehandsgit rmeach path the split moves or drops as the bytes the tree holds, so a name outside ASCII underLC_ALL=C PYTHONUTF8=0no longer stops the run withUnicodeEncodeErrorafter both legs are pushed (#527) #614 (f6376d7) X1: underLC_ALL=C PYTHONUTF8=0,executehands a moved or dropped path that is not ASCII togit rmas an argumentsubprocesscannot encode, soplanandcheckpass, both legs are pushed, and the run ends in aUnicodeEncodeErrortraceback. Ruled 2026-10-12: pass git the exact bytes the tree holds, under any locale. - -> adopt-project.py: a kept or dropped name reaches the split commit and the pull request body unspelled, and
_spelled,_shownandplan's report print text that reads as another name, or raw #900 A6:_split_messagelists the root and dropped paths as they stand, so a name with a line feed, a trailing CR, ESC, a tab or a byte that is not UTF-8 (written as?) reaches the split commit's message and the pull request body as another path or as raw control bytes. Direction: spell them asplanandcheckdo. - → adopt-project.py
plan: ask aboutsingle-repository.yamlwith its own drop-or-root rule, not the genericambiguous-top-level-yamlquestion #528, done in contracts/path-classification.yaml: a source's ownsingle-repository.yamlis asked drop or root, drop by default, under its own rule, soadopt-project.py planno longer asks a record no leg reads thespec,codeorrootquestion (#528) #566 (1d809ea) A7:planasks about a repository'ssingle-repository.yamlwith the generalambiguous-top-level-yamlquestion. Ruled 2026-10-12: a path-policy rule names the file and asks drop or root, defaulting to drop. - → adopt-project.py
check: refuse the branch namesexecutefails on after both legs exist (case,hideRefs, git's own rules) #520, done in adopt-project.py:checkfinds, andexecuterefuses before any leg, the branch namesexecutefailed on, soadopt_branch: a..b, a source branchAdoptor one hidden byhideRefsno longer passcheckand fail after both legs exist (#520, #420) #583 (de428f5) A4: adopt-project.py:checkreports the split branch an earlier run left asexecute'sadopt-branch-exists, and a branch in git's way of it asplan-split-branch-taken, whichexecutenow refuses before any leg exists, so a source branchadoptno longer has both legs made beforegit filter-repofails (#320) #382'splan-split-branch-takencompares branch names case-sensitively, so on macOS and Windows a source branch that differs from the split branch only by case passescheck, andexecutemakes both legs before git refuses. Ruled 2026-10-12: compare case-folded on every OS. - -> adopt-project.py: a kept or dropped name reaches the split commit and the pull request body unspelled, and
_spelled,_shownandplan's report print text that reads as another name, or raw #900 AS-1:_spelledwrites a backtick as two characters the plan's reader keeps (\`) and a double quote unescaped, so a spelled name copied into the plan names another entry or makes the plan unreadable. Direction:\x60and\". - -> adopt-project.py: a kept or dropped name reaches the split commit and the pull request body unspelled, and
_spelled,_shownandplan's report print text that reads as another name, or raw #900 AS-2:_shownprints a printable text that begins and ends with a backtick as it is, which is exactly its spelled form for another name, soplan's table can print two names as one. Direction: spell such a text too. - -> adopt-project.py: a kept or dropped name reaches the split commit and the pull request body unspelled, and
_spelled,_shownandplan's report print text that reads as another name, or raw #900 AS-3:plan's terminal report prints a path policy'squestion:and ruleidas they are. Ruled 2026-10-12: print them through_shown, ascheckprints the question.
Known limits found by lane openRepoShape-3's acceptance passes (standard 36538fd, each re-checked on main 7a8b981) and kept here rather than filed:
- → adopt-project.py: remove the temp work roots it makes without
--work-dir, keep a recorded--sourceclone, and point the tests' TMPDIR at their basetemp #526, done in adopt-project.py and tests/conftest.py: a run without--work-dirremoves the empty work directory it made, and a recorded clone that is gone is cloned again, so no emptyopenreposhape-adopt-*is left and nosource-unclonablefollows (#526) #594 (c972032)plan,checkandexecuteeach make a freshopenreposhape-adopt-XXXXXXXXdirectory in the system temp folder when--work-diris not given (_work_root, adopt-project.py:6028-6032, called at :2088, :3543 and :5100) and nothing ever removes it:planandcheckof a local source leave it empty,executeleaves both legs' and the split's working trees in it, and 2,992 of the first 3,000 such directories in one container's/tmp(15,206 in all) are empty. Direction: remove a work root that holds nothing when the command ends, and say whereexecute's stays. - → adopt-project.py: what
executeand AGENTS.md say around a run (the plan's follow-up, a failed verification's open PR, an answer with noresolution:, the ruleset hint) #523, done in adopt-project.py: whatplan,executeand AGENTS.md say around a run is what the run does: the plan's last follow-up is a review of the pull requestexecuteopens itself, a failed verification names the pull request and the topic it left in place, AGENTS.md sayscheckpasses an answer with noresolution:, NEXT under--local-remote-dirnames the split's branch, and the ruleset hint no longer calls a seed branch and a pull request the scaffold's other exit (#523) #582 (526cd2c) AT-adopt N1: the follow-up "open the split as a pull request against ...; the legs -spec and -code are seeded before it" (adopt-project.py:1368-1372) is printed byplanand listed under "FOLLOW-UPS, which this commit does NOT do" in the split commit and the pull request body (:5442-5444), though in GitHub modeexecuteopens that pull request itself, and it calls two legs "seeded" that were extracted (the docs use that word only for a leg made from a template). - → rides with adopt-project.py: what
executeand AGENTS.md say around a run (the plan's follow-up, a failed verification's open PR, an answer with noresolution:, the ruleset hint) #523, done in adopt-project.py: whatplan,executeand AGENTS.md say around a run is what the run does: the plan's last follow-up is a review of the pull requestexecuteopens itself, a failed verification names the pull request and the topic it left in place, AGENTS.md sayscheckpasses an answer with noresolution:, NEXT under--local-remote-dirnames the split's branch, and the ruleset hint no longer calls a seed branch and a pull request the scaffold's other exit (#523) #582 (526cd2c) AT-adopt N2: under--local-remote-dirno pull request is opened, yetexecuteends withNEXT: review the pull request on <Project>, then git clone ... make bootstrap(adopt-project.py:5190,_next_stepsat :5577; adopt-project.py: the tracking branch defaults to the source's default branch, topics are set before the pull request, and NEXT names scripts/bootstrap.py when the shape's Makefile went aside (#479, #480, #481) #493 keeps it, its condition isrefused is None). Test path only. - → adopt-project.py: what
executeand AGENTS.md say around a run (the plan's follow-up, a failed verification's open PR, an answer with noresolution:, the ruleset hint) #523, done in adopt-project.py: whatplan,executeand AGENTS.md say around a run is what the run does: the plan's last follow-up is a review of the pull requestexecuteopens itself, a failed verification names the pull request and the topic it left in place, AGENTS.md sayscheckpasses an answer with noresolution:, NEXT under--local-remote-dirnames the split's branch, and the ruleset hint no longer calls a seed branch and a pull request the scaffold's other exit (#523) #582 (526cd2c) AT-adopt N3: AGENTS.md:134-136 says an answer with noresolution:beside it "will be read as a finding", butcheckprintsplan ok, exit 0, for one (the record'sresolution:is optional, adopt-project.py:4992-4995). Direction: say who reads it, or letcheckask for one. - Closed 2026-10-14: a duplicate of auA-12, now in adopt-project.py: what
executeand AGENTS.md say around a run (the plan's follow-up, a failed verification's open PR, an answer with noresolution:, the ruleset hint) #523. AT-adopt N5: when the verification fails in GitHub mode (exit 1) the pull request and the topics are already done, yet the report and AGENTS.md:147-150 never name the open pull request; the way out they print (delete the split branch, re-run into fresh legs) does work. - → adopt-project.py
plan: with no--elected-byand nouser.name, the refusal reads--elected-by is '', naming a flag that was never passed #529, done in adopt-project.py:plannames an elector it took fromgit config user.nameby where it came from, so with no--elected-byand nogit config user.namethe refusal reads--elected-by (not given, sogit config user.name) is ''and no longer--elected-by is '', a flag nobody passed (#529) #567 (9f80939) AT-adopt N6:planwith no--elected-byand nogit config user.nameis refusedadopt-manifest-invalid: --elected-by is '', naming a flag the person never passed rather than the setting the empty default came from (probe on main 7a8b981; the label is adopt-project.py:1856, while the unwritable-value path at :1808 does say "not given, sogit config user.name"). - → adopt-project.py: record the plan's answers in project.yaml, so the doctor's
placementrow and thesubmodules:rows follow them #525, done in adopt-project.py, shape-doctor.py, validate-manifest.py:executerecords the plan's answers underanswered_paths:and a moved submodule names its row, so an answeredexamples/is not asked again and a deliberate move names no plan (#525) #617 (59e5a07) AT-adopt N7: the doctor'splacementrow keeps listing a path the adoption plan already answered (spec/examples/, ruleambiguous-examples) asreview_required(shape-doctor.py:3544, :3831), becauseexecuterecords only the submodule answers inproject.yaml(submodule_record, adopt-project.py:4915-4950), so AGENTS.md's doctor step 4 has an assistant ask the human again. Direction: record a plan's answers for ambiguous paths as An adopted assembly records nothing about which leg a human chose for a source submodule, so shape-doctor.py cannot verify a kept gitlink's placement and can only note it; adopt should write the plan's submodule answers into the assembly #189 did for submodules.
Edge cases found in review of lane openRepoShape-3's pull requests, kept here rather than filed:
- → adopt-project.py
check: refuse the branch namesexecutefails on after both legs exist (case,hideRefs, git's own rules) #520, done in adopt-project.py:checkfinds, andexecuterefuses before any leg, the branch namesexecutefailed on, soadopt_branch: a..b, a source branchAdoptor one hidden byhideRefsno longer passcheckand fail after both legs exist (#520, #420) #583 (de428f5) adopt-project.py reads the branches of a local source or assembly withgit ls-remote(_branches_at, adopt-project.py:3830, called at :3974, :4028 and :4034 by adopt-project.py:checkreports the split branch an earlier run left asexecute'sadopt-branch-exists, and a branch in git's way of it asplan-split-branch-taken, whichexecutenow refuses before any leg exists, so a source branchadoptno longer has both legs made beforegit filter-repofails (#320) #382's_places_check_asksand_refuse_a_branch_in_the_split_branchs_way), so a branch the repository hides withuploadpack.hideRefsortransfer.hideRefsis not seen:checksaysplan ok, andexecute --local-remote-dirpushes both legs before the split push fails on git's ref lock. Direction: read a local path's branches withgit for-each-ref. From the review of adopt-project.py:checkreports the split branch an earlier run left asexecute'sadopt-branch-exists, and a branch in git's way of it asplan-split-branch-taken, whichexecutenow refuses before any leg exists, so a source branchadoptno longer has both legs made beforegit filter-repofails (#320) #382 (codex at 5a1ffd5, confirmed by an independent verification; here only the git side was re-checked:git ls-remoteprints nothing for atransfer.hideRefsbranch thatgit for-each-reflists, andexecutewas not run, there being nogit-filter-repoin this container).
Activity
executeexits 2 with nothing on stderr whengit filter-repofails, after both leg remotes exist:_build_the_legsswallowsCommandFailedon the premise thatrunalready reported it, andrunonly raises #171push -u origin ...from an extracted leg whoseoriginfilter-repo removed, and says "listed above" of lines a combined log prints after it #177checkrefuses no root-kept symlink at or above a path the shape writes, so a link that dangles or leaves the tree makesexecutetraceback, or write the shape's files OUTSIDE the assembly, after both leg remotes are pushed #178null,trueand other YAML keywords unquoted, soplan --spec-path nullsilently mounts the leg at the defaultspec#181REFUSED <step>with no notice of what already exists and no stdout flush, so the combined log shows REFUSED before thebare …lines and the re-run meetsleg-remote-existsunexplained #188--pin <name>is accepted byplan,checkandexecute("adoption verified"), but writes only the name intoneutral_product_pins:and nocontracts/<name>-pin.yaml, so the adopted root's ownvalidate-pins.py(and itsvalidate.yml) refuses withneutral-pin-missingfrom the first run #273_electorand_remote_repositoryreadgit config user.nameand the origin URL throughgit_out, which decodes strictly, so a name or URL that is not UTF-8 endsplan(and, for the URL,checkandexecute) in a UnicodeDecodeError traceback, exit 1, naming neither the git setting nor the flag that avoids it #292checkandexecuteiterate a plan'sfollow_ups:without asking for a list, so a hand-edited plan withfollow_ups: 5(ortrue) endscheckin aTypeError: ... is not iterabletraceback, andexecutein the same one after both leg repositories are created and pushed #293checknever reads a plan'selected_on:when the plan has noreference:, soplan okis followed by anexecutethat creates both leg repositories and only then refuseselection-date-malformed, naming--elected-on, a flag neither command takes #294checkpasses a source whose tree holds a symlink with an empty target, so with symlinks onexecutecreates both leg repositories and then fails cloning the source (on main with exit 2 and nothing on stderr, #171), and withcore.symlinks=falseit saysadoption verifiedover a leg or root that no clone with symlinks on can check out #303checkpasses a plan that keeps the source's ownproject.yamlin the root, andexecutewrites the shape's manifest beside it asshape/project.yamland saysadoption verified, so shape-doctor.py calls the adopted assembly NOT A SHAPE ROOT and its firstmake bootstrapfails #305plan,checkandexecutenever look for the plan's split branch (adopt/three-repo-shape) in the repository the split is pushed to, so a re-run after an earlier run left it passescheck, creates both legs, and dies at a non-fast-forward push of the split #320checkandexecutestill print two kinds of text raw in a FINDING, a plan's hand-editedquestion:(plan-unresolved) and a submodule name insidemissing value for '<key>'(plan-gitmodules-unreadable), so a line break forges a FINDING line and an ESC reaches the terminal, and no last-line guard would catch the next one #328106 remaining items
brettheap commentedon Oct 18, 2026
(lane openRepoShape-1, 2026-10-18T08:08:32Z) Two limits that lane 1's v1.1.1 PRs named for this checklist: L1-104 and L1-105.
Each was found in its PR's review and left out of it, as its squash says. The v1.1.1 release notes (#883) list both under known limits as on this checklist, and lane 3's review of #883 found them missing here (#883, issuecomment-6247451611).
From #829 (#801,
dd72294d), the extension-majority fold:plan's andexecute's extension-majority fold. Soengine/holdinga.py,b.py,x.mdandt<TAB>b.pyfolds to code, 3 of 4, and the doctor, which sees 2 of 3, readscode/engine/x.mdas MISPLACED, with the plan exactly asplanwrote it. It is true on main before adopt-project.py:answered_paths:also records each entry a leg's own walk puts elsewhere, so a directory split by hand out of an extension-majority fold no longer reads MISPLACED on the doctor's first run afteradoption verified(#801) #829 as well; its cause is the doctor's set-aside, not a split.From #831 (#796,
33419925),--source:--sourcedirectory this user cannot enter (chmod 000), or one under a directory they cannot enter, still endsadopt-project.pyin aPermissionErrortraceback, exit 1, as on main before adopt-project.py: a--source, or a plan'ssource.local_path, that names no repository's top level is refused by name before git reads anything else in it, so a file, a directory inside a repository, an unknown~user, an empty value,owner/.gitand a lost blob no longer end in a traceback, plan a subtree or reachgh(#796) #831: fromgit rev-parsein_top_levelfor the first, and fromPath.existsin_source_specfor the second.Lane: openreposhape-1 (openRepoShape-1)
docs/release-notes/v1.1.1.md: the v1.1.1 notes take RV883's NIT list …
brettheap commentedon Oct 18, 2026
(lane openRepoShape-3, 2026-10-18T14:46:39Z) Triage of #457's unchecked items at the v1.1.1 release commit
5017830. This is lane 3's TRIAGE-457, read only, before this filing.Counts. 144 lines were unchecked, 9 in the body and 135 in comments. The rulings:
_spelled,_shownandplan's report print text that reads as another name, or raw #900 to adopt-project.py and family.py: a--sourcethis user cannot enter, a UTF-8 plan checked under the C locale, and a member branch that is not UTF-8 still end in a traceback or a false refusal #918.No open issue or pull request covered any of them. Every
->pointer on this checklist names a closed issue.How. Read: this issue's body and every comment, the release notes' Known limits sections, and the first-parent squash messages on main. Probes ran on a detached clone at
5017830, with:ghfirst on PATH (exit 97),GH_TOKEN=bogusand an emptyGH_CONFIG_DIR;GIT_CONFIG_GLOBAL=/dev/null, and local remotes only.No pytest was run. Each OPEN row names its issue, whose body holds the probe output.
Filed:
_spelled,_shownandplan's report print text that reads as another name, or raw #900: A6, AS-1, AS-2, AS-3, L2-76, L1-36.checkandexecute: one bad plan value is named in different orders, or by two or three findings, and two pin sentences say more thanexecutedoes #901: L2-6, L2-7, L1-K7, L2-12, L2-42.planandcheck: an empty flag or a bare plan value is taken without a word, and the id refusals name what the person did not type #902: L1-K3, L2-86, L2-87, L2-88, L2-89, L2-90, L1-49.plan: refusals that need only the flags come after the work directory, the source's git reads andgh repo clone#903: L2-55, L4-37, L1-67.check: a root-kept symlink into the clone's.git, or through a kept link to a declared pin's file, passes, or is refused for a reason that is not true #904: L1-J1, L1-J2, L1-K2, L1-K9, with L1-K8 as its rider.contracts/-only read-across path,execute would stop there,a path names no attribute, and WHAT WILL HAPPEN under--local-remote-dir#906: L2-72, L2-73, L1-91, L1-93, L1-75.check: a symlink target with a NUL after its first byte, or longer than the platform takes, passescheckand fails after both legs exist #908: L1-76, L1-78, L1-80.check's throwaway repositories: a SHA-256 source, a tree path git refuses, aTMPDIRon another disk and this machine's hooks change the answers #910: L1-90, L1-92, L1-94, L1-32..gitmodulesof whitespace is asked on every run, a dropped file whose blob the root also holds counts as root,_answered_legsis quadratic, and two validator code families have no placeholder row #914: L1-84, L1-85, L1-87, L1-K4.ghwritten withwrite_text,GIT_ALLOW_PROTOCOLnot cleared, two guard pairs that mask each other, and one name shape in the naming test #916: L4-54, L1-60, L1-62, L1-K6, L2-91.--sourcethis user cannot enter, a UTF-8 plan checked under the C locale, and a member branch that is not UTF-8 still end in a traceback or a false refusal #918: L1-105, L1-86, L1-70.This issue's body was edited once:
_spelled,_shownandplan's report print text that reads as another name, or raw #900.Lines in comments stay as their authors wrote them. This comment records their rulings, and each author, or lane 3 on a later word, can tick them.
Body
caf\xe9.mdlands ascaf?.md,cr\rascr;adopt-project.py:13498-135091d809ea(#566, #528);contracts/path-classification.yaml:453_spelledleaves"raw_spelled('a"b')is`a"b`;adopt-project.py:3114-3124_shownof a backticked text_shownof`x`equals_spelled('x');:3111:5168,:5173,:5495(read)526cd2c(#582, #523);:3323526cd2c(#582, #523);:13208526cd2c(#582, #523);AGENTS.md:139-1409f80939(#567, #529);:4033Comments, 2026-10-12
checkrefusesplan-bad-id(orunsafe-value),executerefusesplan-bad-leg-path, 0 legs_manifest_valuesdocstring:4911-4912CONTRACTS_DIRhard-coded (lane 5, -> #522)fbbbc8d(#572, #522);scripts/shape_materialize.py:1045POSIX_ONLY,tests/test_adopt_entry_paths.py:51); v1.1.0 notes526cd2c(#582, #523);:200fbbbc8d(#572, #522);:3224.gitattributesis a symlink (= L4-15)scripts/shape_materialize.py:909-913; v1.0.0 notesextend_eol_block,scripts/shape_materialize.py:796-798; v1.1.0 notes.gitwhere the clone holds nothingCLAUDE.md -> .git/refs/remotes/origin/mainpassescheck;:8720.git/refs/../HEADrefused for a false reason.git/refs, which is not a directory in the assembly root"Comments, 2026-10-13 and 2026-10-14
pins:spelled withrepr:554_neutral_pin_entry,:13393-13405adopt-not-the-sourceaftergh repo clone(= L4-37)gh repo cloneruns, thensource-unclonablecheckgives no rename-first remedy (= L4-38)d7befb9(#825, #716);:14452d7befb9(#825, #716);:14520casefold(= L4-43):14398; v1.1.0 notes_origin_pathvs_remote_repository(its copy L4-44 is ticked)55faad2, #521);_origin_pathreads_origin_url,:14430None/org (= L4-45):8446-8447; v1.1.0 notes_origin_pathon every plan (its copy L4-46 is ticked)55faad2, #521); called only at:14440,:14553org:(= L4-48)d7befb9(#825, #716);:14600contracts -> governancepassescheckid: 007->adoption verified,id: "7"scripts/shape_materialize.py:4935-4940:4120,:4264,:4161.git/reftableCLONE_GIT,:8715:6242-6258;tests/test_adopt_root_shape_paths.py:339.github -> ciblock spelling (= L4-51)d6475f9(#844, #807);scripts/shape_materialize.py:887tests/test_adopt_ignored_shape_files.py:294-295Comments, 2026-10-15
:584-586local-clone (<path>)remedy396c0ff(#570, #540);:503; probe:checkpasses such a plan2d98820(#725, #651);scripts/shape_materialize.py:3489git_out,scripts/repo_shape.py:1206-1209; v1.1.0 notesbee84d5(#842, #800);scripts/shape_materialize.py:3214:9544-9546); L1-17 narrowed by #825OSErroraround the probe:9374b618ec1(#699, #658);:3835url_repositoryat5017830confirms L1-42, L1-44, L1-46AGENTS.md:119-130write_texttests/test_adopt_pins.py:112-122GIT_ALLOW_PROTOCOLnot clearedtests/test_adopt_submodule_url_answers.py:301_work_root:5387before_checked_plan_inputs:5403Comments, 2026-10-16 and 2026-10-18
:3346-3351git-failed:1593-1595checknames one badtracking_branchtwice (= L4-127)64ec47c(#817, #708);:5002contracts/gets a path:3283-> #652is stale)d7befb9(#825, #716)190133d(#630);README.md:776-777d6475f9(#844, #807)64ec47c(#817, #708)3341992(#831, #796);:1839,:22375c02a04(#843, #803);:1894mkdtempwith no temp directoryTMPDIRfalls back to/tmp, exit 0; the baremkdtempis:14700:5387; nit 2 not measured51414d2(#830, #797);:2670,:2539_member_headstrict decodescripts/family.py:7188-7206fe99b8b(#861, #798);:11535,:313checkvsexecuteunder--local-remote-diradopt-name-too-longnow found bycheck(a249910, #871); the rest not re-measured:8579-8580:7710-77113fb30a8(#833, #799);:5453_link,:8964-8977scripts/shape_materialize.py:3498-3508bee84d5, #842, #800); second OPEN -> #912:829-846dd72294(#829, #801);:12874shape-doctor.py:246;:6354;:13830-13839plan-source-gonefor a path that exists, noghcalltests/test_naming_policy.py:252-2543fb30a8(#833, #799);:5193:10160,:10177,:9551:10444-10448,:96753341992(#831, #796);:1770,:1712,:16805c02a04(#843, #803);:1960; L1-102 not run on Windows, and its residual is in v1.1.1's notes60f146a(#749):executekeeps its clone, and a re-run is refusedadopt-work-dir-occupiedPermissionErrortraceback; also in v1.1.1's notesFile:line references without a file name are in
adopt-project.py, at5017830.Not filed.
originis read: L4-43, L4-45 (and their originals), L1-40, L1-41, L1-42, L1-44, L1-45, L1-46, L1-47 and L1-48;check: a root-kept symlink into the clone's.git, or through a kept link to a declared pin's file, passes, or is refused for a reason that is not true #904.mkdtempraise.--local-remote-dir.Housekeeping.
-> #654and L4-37's-> #652are stale: both issues closed without the line. L4-15 is a known limit, and L4-37 is now in adopt-project.pyplan: refusals that need only the flags come after the work directory, the source's git reads andgh repo clone#903..gitattributessymlink and the older-adoption lines;plannever compares--project(or--org) with the repository it adopts in place, so a source namedbilling-serviceis refused with a remediation that steers to--project BillingService, which plans and checksplan okagainstacme/billing-service, andexecutethen acts onacme/BillingService: a rawgit ls-remotefailure when no such repository exists, and, when a different repository of that name does, both legs, the split branch, the pull request and the topic on that repository #499 lines;.github -> ciand hash-object lines;tracking_branchline.Each original's ruling is its copy's.
Lane: openreposhape-3 (openRepoShape-3)
adopt-project.py, shape_materialize.py: five printed sentences say wh…
adopt-project.py: `plan` asks the leg-path, pin, date and value refus…
adopt-project.py: `check` names a symlink target with a NUL after its…
adopt-project.py: `check` and `execute` ask a plan's `org:` and `id:`…
scaffold-project.py, adopt-project.py and shape_materialize.py: one f…
adopt-project.py: the split commit's message and `plan`'s report name…
adopt-project.py: plan and check take an empty flag or a bare plan va…
brettheap commentedon Oct 20, 2026
(lane openRepoShape-3, 2026-10-20T03:50:13Z) Left over from #902 (PR #1016): in adopt-project.py,
elected_by:,reference:andorg:in a hand-edited adoption plan, read by the plan's reader as a number or a boolean (elected_by: 007,elected_by: true,elected_by: 1.50,reference: 1.50,reference: 007,org: 007,org: true), still givecheckexit 0 andplan ok, andexecutetakes str() of what was read (007is7,trueisTrue,1.50is1.5). It is the same class as L1-K3, which #1016 closes forid:,tracking_branch:andadopt_branch:only. Measured on main c4dd19d and on #1016's head 9261ff2. Each key needs a finding of its own:org:is read as str on purpose for the not-the-source comparison (#513's review),visibility: trueis already the validator's finding, and anelected_on:read as a number is #294's. Direction: refuse each by what was read, under a code of its own, as #1016 does for the three keys, with NOT_TEXT_REMEDIATION's remedy.Lane: openreposhape-3 (openRepoShape-3)
adopt-project.py: `check` and `execute` ask a plan's `org:` and `id:`…
adopt-project.py: the split commit's message and `plan`'s report name…
shape_materialize.py, adopt-project.py and bump-leg.py: a tag a clone…
adopt-project.py: `check` names what the clone's `.git` holds as git …