Repository navigation
scaffold-project.py: --dry-run's help says its answer about each folder is the mode bits' and that it leaves nothing that stays, a --reuse-empty-repo re-run that takes a seed found only on seed/scaffold names that branch as remaining, and the unused COMMIT_RE import is gone (#921, #923) - #1052
Conversation
…lder is the mode bits' and that it leaves nothing that stays, a `--reuse-empty-repo` re-run that takes a seed found only on `seed/scaffold` names that branch as remaining, and the unused `COMMIT_RE` import is gone (#921, #923) `--dry-run` help (#923 U063, #921 U088): the folder question is `os.access`'s answer, so a quota or a Windows ACL the bits do not show can pass the dry run and be refused by the real run; and where it said "make no folder" it now says it "leaves nothing that stays", since it makes and removes temporary folders. `docs/cli.md` regenerated for the scaffold's section. `only_commit` keeps the ref names `git ls-remote` gave, `_held_seed` returns the branches the seed was found on when the tracking branch is not one of them, and `_reusable_remotes` prints a NOTE after the `reuse` line: the branch remains, and on GitHub it may be the leg's default branch (#921 U006). A dry run says it too. Branch names come from the remote and are spelt as `shown_path` spells a path. The unused `COMMIT_RE` import is dropped (#923 U064): no test reads it off the scaffold module, and pyflakes reports nothing for the file now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewer's GuideThis PR updates scaffold dry-run documentation, removes an unused import, and enhances seeded repository reuse by retaining remote ref names so reruns can explain which non-tracking branches remain untouched; accompanying tests cover the new reporting, edge cases, safe rendering, dry-run semantics, and generated CLI documentation. Sequence diagram for seeded repository reuse with branch preservationsequenceDiagram
participant Scaffold
participant Remote
participant Git
participant User
Scaffold->>Remote: _held_seed(role, url, values, tracking, scratch)
Remote->>Git: only_commit(url, scratch)
Git-->>Remote: commit, tree, refs
Remote->>Remote: _seed_branches(refs, tracking)
Remote-->>Scaffold: seed, unread, found_on
Scaffold->>User: reuse target (one commit, seed)
alt seed found only on another branch
Scaffold->>User: _seed_branch_note(target, found_on, tracking)
User-->>Scaffold: branch remains untouched
else tracking branch also holds seed
User-->>Scaffold: no branch-preservation note
end
Flow diagram for scaffold dry-run behaviorflowchart TD
A[scaffold --dry-run] --> B[Check folders with os.access W_OK and X_OK]
B --> C{Folder appears usable}
C -->|yes| D[May still be refused by quota or Windows ACL]
C -->|no| E[Report refusal]
A --> F[Create and remove temporary folders]
F --> G[No lasting folders, remote, or push]
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
(lane openRepoShape-3, 2026-10-20T10:54:20Z) Independent review (RV1052f, opus) of head 396668b: READY. No MUST. SHOULD-1 scaffold-project.py:376-379 (docs/cli.md:352-354, test at NIT 1 :376-377: "The answer about each folder is its mode bits'" claims Probe, head and main 82fc867, local and stub-gh GitHub modes, cases Lane: openreposhape-3 (openRepoShape-3) |
…ked of `os.access`, which on Windows says yes for every folder, so a read-only drive there passes it as a quota or an ACL does, and the seed NOTE of a `--local-remote-dir` re-run no longer says a bare repository on disk may be the default branch on GitHub (#921, #923) Review round of #1052 (RV1052f, READY, no MUST): - SHOULD-1 and NIT 1: the help's wording, docs/cli.md regenerated, and the assert at tests/test_scaffold_reuse_seeded_legs.py. - NIT 2: `_seed_branch_note` takes `local`; the GitHub wording is unchanged, and rows pin both. - NIT 3: the test that prints no seed note is named for that. - NIT 5: two rows kill the surviving mutant of `_seed_branches`. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
(lane openRepoShape-3, 2026-10-20T11:20:16Z) Independent delta review (RV1052d) of fix round 1, 396668b..dff9aac: READY. No MUST, no SHOULD. All of RV1052f's items are fixed:
Tests at dff9aac, one file at a time under a stub gh:
Mutants:
merge-tree --write-tree of dff9aac is clean with:
The body has no closing keyword (closingIssuesReferences is empty). It ends Part of #921, Part of #923, the Lane line, then the robot line, before the Sourcery block. NITs, neither blocking:
Note: dff9aac carries a Co-Authored-By: Claude Sonnet 5.5 trailer, and 396668b carries the Opus 5.5 one. Lane 3's squash message decides which trailer lands. Lane: openreposhape-3 (openRepoShape-3) |
|
Sorry @brettheap, you've used your own review budget of 250,000 diff characters for the last 7 days. You can request another review in 1 day and 7 hours by commenting |
…cks `<into>/[<Family>/]<Project>`, nothing that stays is created before the typed `yes`, and `passed_values` says which dash words argparse takes as values (#921, #923) (#1051) AGENTS.md and the handbook said step (3) refuses a taken `<into>/<Project>`, but it checks the clone path, and under `--family` that is `<into>/<Family>/<Project>` unless the run already stands in the family's folder. AGENTS.md now writes `<into>/[<Family>/]<Project>`, in the refusal and in the `--family` row, and the handbook says the clone path, `<into>/<Project>` or, where `--family` adds the family's folder, `<into>/<Family>/<Project>`. README.md, the handbook and setup-project.py's docstring said nothing is created before the typed `yes`, but a run makes temporary folders along the way and takes each away again: the write probe above the clone, and the seed and branch folders in the temporary folder. They now say nothing that stays is created before the `yes`, and name such folders. setup-project.py's docstring names the checkout `--keep-shape-checkout` keeps as the one that stays. AGENTS.md and the handbook's list of refusals say "before anything that stays is created", the words the scaffold's `--dry-run` help takes in #1052. The docstring of `passed_values` said a value never starts with `-`. argparse takes `-`, a negative number such as `-5` and a word with a space such as `-x y` (but not one argparse reads as a scaffold flag, such as `-h y`) as a flag's value, where `passed_values` reads none, so step (4) reports from fewer values. The docstring says so now, and so does the docstring of the test that pins it in tests/test_setup_project_py.py. The README grows three lines (tests/readme-cap.d/921.txt), and the seven handbook markers carry the README section's new hash. Part of #921 Part of #923 Lane: openreposhape-3 (openRepoShape-3) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…er answer is `os.access`'s and that it leaves nothing that stays, as the scaffold's help does since #1052, and a test holds the seed NOTE's GitHub clause (#923) (#1063) `family.py init --dry-run`'s help and the module docstring said the run makes no folder, and not where its answer about a folder comes from. They now say what #1052 made the scaffold's help say: whether each folder can be written in is asked of `os.access`, which reads the mode bits and on Windows says yes for every folder, so a quota, a Windows ACL or a read-only drive on Windows can pass the dry run and be refused by the real run; and the dry run leaves nothing that stays: it makes and removes temporary folders, creates no remote or repository and pushes nothing. The docstring names the folders: an `openreposhape-branch-*` every time, and an `openreposhape-ident-*` for the author and for the committer when that role's GIT_AUTHOR_ or GIT_COMMITTER_ variables are set. A test pins the help's words, and docs/cli.md's family section is regenerated. `folder_in_the_way`'s docstring in shape_materialize.py now says that on Windows the real `mkdir` can still be refused where `os.access` said yes. A unit test now holds the scaffold's seed NOTE at its call site: for a GitHub leg it ends ", and on GitHub it may be the leg's default branch.", and under `--local-remote-dir` it says nothing of GitHub. Closes #923 Part of #921 Lane: openreposhape-3 (openRepoShape-3) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>



The scaffold file's share of #921 and #923, v1.2.0 (draft). Four changes in
scaffold-project.py,docs/cli.mdregenerated for the scaffold's section, and rows intests/test_scaffold_reuse_seeded_legs.py. RV1052f's review (READY, no MUST) is answered by one more commit,dff9aacb7, under "Review round" below.What changed, and why
#923 U063, the scaffold half:
--dry-run's help says whatos.accesscan and cannot see (scaffold-project.py:376-384). The dry run asksos.access(W_OK | X_OK)(scripts/shape_materialize.pyfolder_in_the_way,target_in_the_way) and the real run'smkdirand first write can still be refused, so the help now says: "Whether each folder can be written in is asked ofos.access, which reads the mode bits and on Windows says yes for every folder, so a quota, a Windows ACL or a read-only drive on Windows can pass here and be refused by the real run."#921 U088, the scaffold half: "make no folder" is "nothing that stays" (
scaffold-project.py:382-384). The run makes and removesopenreposhape-seed-*andopenreposhape-branch-*in the temporary folder, so the help now says: "It leaves nothing that stays: it makes and removes temporary folders, creates no remote and pushes nothing". "nothing that stays" is the phrase W921a uses in the README and the handbook.docs/cli.md:351-358is regenerated withscripts/render-cli-reference.py;--checksays it is what the generator produces.#921 U006: a
--reuse-empty-repore-run that takes a seed found only onseed/scaffoldsays which branch remains.only_commit(:533,:550) kept only the tips and threw the ref names away. It now keeps the namesgit ls-remotegave and returns them as a third element; its one other reader, a test, readsheld[0]._held_seed(:573) returns(commit, why, found_on),found_onbeing the branches the seed was found on when the tracking branch is not one of them (_seed_branches,:616)._reusable_remotes(:751) prints, after thereuse ... (one commit, ...)line, on GitHub:NOTE the seed in <leg> was found only on its branchseed/scaffold: this run createsmainat it and does not touchseed/scaffold, so that branch remains, and on GitHub it may be the leg's default branch.and under
--local-remote-dir, with no word of GitHub:NOTE the seed in <leg> was found only on its branchseed/scaffold: this run createsmainat it and does not touchseed/scaffold, so that branch remains._seed_branch_note(:631), which takeslocal. The dry run prints it too, since the question is asked before anything is made.#923 U064, the scaffold half: the unused
COMMIT_REimport (scaffold-project.py:95) is dropped.git grep COMMIT_RE -- testsfinds no read of it off the scaffold module (every hit isrepo_shape,adopt-project.py,family.py,bump-leg.pyor a template, each importing it fromrepo_shapeitself).pyflakes scaffold-project.pyprintedscaffold-project.py:94:1: 'repo_shape.COMMIT_RE' imported but unusedatorigin/mainand prints nothing now: 0 left, 0 new.Where the Direction left a choice
seed/scaffold. The code never namedseed/scaffold: it takes any leg whose one commit has the seed's tree. So the NOTE is for any branch the seed was found only on, named as found, and says "branches" and names both when there are two. The issue's words are the NOTE's words for the case it names.--local-remote-dirleg, a bare repository on disk, is not told it.HEADin the listing is not read as proof.mainbesideseed/scaffold): the re-run creates nothing then. A tag, a pull request's ref andHEADare no branch.shown_pathshows a path (as it is, or asreprwhere a character in it is not printable). A branch with U+202E in its name prints inrepr's spelling, never raw (a row builds one withchr(0x202E)).os.access(W_OK)does answer a read-only mount; on Windows it says yes for every folder (scripts/shape_materialize.py:1620-1621,setup-project.py:2611-2612), so a read-only drive there passes the dry run and the help says so (RV1052f SHOULD-1; the first draft left it out).Left out, and why
scripts/family.py:10632-10639, its--dry-runhelp, anddocs/cli.md's family section): another writer ownsfamily.py. The family help says "make no folder" still; a follow-up adds both clauses once that lands.shape_materialize.py,family.py): the same reason, and scripts/shape_materialize.py and scripts/family.py: the helpers that ask a template's own YAML reader and validator about a manifest's values exist twice, once forproject.yamland once forfamily.yaml#925 owns the twin headers.--dry-run: nothing was created.and every refusal'sRemediation: nothing was created. They are not in the issues' lists, and over thirty test files assert on them.passed_values' docstring,setup-project.py), U033 and U088's README, handbook andsetup-project.py:22sentences, the threebumplimits' release notes, and U097, a section headed "Needs a ruling": other files and other writers.Review round
RV1052f at head
396668b2: READY, no MUST. Fixed indff9aacb7, one line per item:--dry-runhelp namesos.access, says it reads the mode bits and on Windows says yes for every folder, so a quota, a Windows ACL or a read-only drive on Windows can pass and be refused by the real run (scaffold-project.py:376-384). That drops "its mode bits'", which claimed the answer about a file in the way and a tree's contents too.docs/cli.md:351-358is regenerated (its scaffold section is the only hunk), and the assert istests/test_scaffold_reuse_seeded_legs.py:381(test_dry_run_help_says_the_mode_bits_and_nothing_that_stays), which now also refuses "its mode bits'".--local-remote-dirthe NOTE no longer says "and on GitHub it may be the leg's default branch"._seed_branch_notetakeslocal(scaffold-project.py:631), passed from_reusable_remotes(:751); the GitHub wording is unchanged.test_the_seed_note_says_github_only_on_github(tests/test_scaffold_reuse_seeded_legs.py:372) has four rows: local with one branch and with two, and GitHub with one and with two, each the whole line. The--local-remote-dirtests'seed_branch_notehelper (:224) holds the local line, andtest_a_seed_pushed_to_a_seed_branch_alone_is_taken_tooasserts no "GitHub" in the run's output.test_a_seed_on_the_tracking_branch_as_well_says_no_branch_remainsis nowtest_a_seed_on_the_tracking_branch_as_well_prints_no_seed_note(:279).test_the_branches_a_seed_was_found_on(:334,:336):("refs/heads/seed/main",) -> ("seed/main",)and("refs/tags/main", "refs/heads/seed/scaffold") -> ("seed/scaffold",). RV1052f's M3 now fails (below).Tests
Each ran alone, under the stub
gh(first onPATH, exit 97),GH_TOKEN=bogus, an emptyGH_CONFIG_DIRandEMAIL=tests@openreposhape.invalid, at headdff9aacb7:scripts/render-cli-reference.py --check:docs/cli.md is what the generator produces.pyflakes scaffold-project.py: no output.tests/test_shape_doctor.pywas not run: this change touches neithershape-doctor.pynor a helper it imports. No pinned copy is touched.Rows in
tests/test_scaffold_reuse_seeded_legs.py:test_a_seed_pushed_to_a_seed_branch_alone_is_taken_too(the NOTE once, after thereuseline, the branch untouched, no word of GitHub),test_a_dry_run_says_the_seed_branch_too_and_makes_nothing,test_a_seed_on_the_tracking_branch_as_well_prints_no_seed_note,test_a_seed_on_two_branches_names_both,test_a_branch_name_is_shown_safe_in_the_seed_note,test_the_seed_note_says_github_only_on_github(4 rows),test_the_branches_a_seed_was_found_on(9 cases),test_dry_run_help_says_the_mode_bits_and_nothing_that_stays, and an added assertion intest_legs_holding_the_seed_are_reused_at_their_commitsthat a seed onmainsays no NOTE. No existing test pinned the old help words ormake no folder.Mutants
Each applied to
scaffold-project.pyalone, the file restored bycpafter and checked withcmp.First draft (at
396668b2):test_a_seed_pushed_to_a_seed_branch_alone_is_taken_too,test_a_dry_run_says_the_seed_branch_too_and_makes_nothing,test_a_seed_on_two_branches_names_both,test_a_branch_name_is_shown_safe_in_the_seed_note(4 failed, 72 passed)_seed_branchesdoes not exclude the tracking branchtest_legs_holding_the_seed_are_reused_at_their_commits, the tracking-branch test, two cases oftest_the_branches_a_seed_was_found_on(4 failed)shown_pathtest_a_branch_name_is_shown_safe_in_the_seed_note(1 failed)--dry-runhelp back to "make no folder"test_dry_run_help_says_the_mode_bits_and_nothing_that_stays(1 failed)docs/cli.mdnot regeneratedtests/test_cli_reference.py, 5 failed (test_the_committed_reference_is_what_the_generator_producesamong them)Review round (at
dff9aacb7):return () if any(ref.endswith("/" + tracking) for ref in refs) else tuple(branches)in_seed_branches. It survived all 76 tests before the two new rowstest_the_branches_a_seed_was_found_on[a-branch-ending-in-the-tracking-name]and[a-tag-named-as-the-tracking-branch](2 failed, 7 passed, run with-k test_the_branches_a_seed_was_found_on)_seed_branch_noteignoreslocal("." if False else ...), so a local NOTE says "on GitHub"test_a_seed_pushed_to_a_seed_branch_alone_is_taken_too,test_a_dry_run_says_the_seed_branch_too_and_makes_nothing,test_a_seed_on_two_branches_names_both, and the two local rows oftest_the_seed_note_says_github_only_on_github(5 failed, 4 passed, run with-k)test_dry_run_help_says_the_mode_bits_and_nothing_that_stays(1 failed)Merges
git merge-tree --write-treeof this headdff9aacb7, after a fresh fetch: withorigin/main(8a0572157): clean. With #1041 (c0ccf755f,scaffold-project.py, a docstring near:1070): clean. With #1051 (93dacf859): clean. The first commit sits on82fc86752(#1044); main has since changed onlyscripts/family.py,templates/family-root/scripts/bootstrap.pyand three tests.Part of #921
Part of #923
Lane: openreposhape-3 (openRepoShape-3)
🤖 Generated with Claude Code
Summary by Sourcery
Improve scaffold dry-run guidance and preserve branch context when reusing seeds found outside the tracking branch.
New Features:
Bug Fixes:
Enhancements:
Documentation:
Tests: