Repository navigation
Description
Lane: openreposhape-3 (openRepoShape-3)
The parent issue for one area of openRepoShape: creating a project or a family (setup.sh, scaffold-project.py, family.py) and the helpers and templates every tool shares (shape_materialize.py, repo_shape.py, the shipped validators). 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:
- family.py init exits 0 and pushes a holder its own validate-family.py refuses for
--id null,--created-by ' ',--created-on 20261011or--name 'Contoso Group', and puts--tracking-branch trueon a branch its manifest reads back as True #307 (P2):family.py init --name 'Contoso Group'or--created-on 20261011exits 0 and pushes a holder its own validator refuses; init cannot be re-run. - family.py
bump(andadd,remove) take no--dry-run, though the file's exit-code paragraph says a dry run prints and exits 0 andbump-leg.pyhas one, so the only way to see what a bump would pin is to run it: fetch, check the member out at--toand rewritefamily.yaml#326 (P2):bumpandremovegot--dry-run(family.py:bump --dry-runfetches the member, resolves--toand prints theold -> newrow and its trailers without checking the member out or rewritingfamily.yaml, andremove --dry-runprints the row, gitlink,.gitmodulessection and directory it would remove and changes nothing, so the module'sEXIT CODESline is true of both (#326) #345, landed); onlyaddhas none, so its mount cannot be previewed. family.py:add --dry-runmakes every refusaladdmakes before it mounts, reads the member from throwaway clones outside the holder for the row's id and digest, and prints the row, gitlink,.gitmodulessection and trailers without mounting, writing or committing anything, andaddtakes--trailerasbumpdoes, so every subcommand has the dry run the module'sEXIT CODESline promises (#326) #400 adds it. - setup.sh: the shim self-bootstraps before it hands over and its pre-scan never looks for
--help, sosetup.sh --helprun from anything but a checkout of the standard (a downloaded copy,curl … | bash -s -- --help, agit archiveextraction) clones github.com/opensoft/openRepoShape before printing a word, prints the clone's usage rather than its own, dies with git's exit 128 offline, and makesscripts/render-cli-reference.pyin such a tree reach GitHub, thoughsetup-project.py --helpanswers offline from the same place #341 (P2):setup.sh --helpfrom a download or `curl . - family.py
bumpandremovehave no rollback: when a git step afterwrite_membersfails (a holderpre-commithook that exits 1, a heldindex.lock), they exit 2 withREFUSED a git or gh command failedand leavefamily.yamlrewritten, the member checked out at--to(or deinitialised and removed), and the change staged or half-staged, without a word about any of it, whereaddputs the holder back and names what it put back #365 (P2):bump/removerefused by a pre-commit hook or heldindex.lockexit 2 withfamily.yamlrewritten and staged; nothing says so. Reproduced on main. - shape_materialize.py
force_stage's docstring says it has TWO CALLERS and that onlyupdate-shape.py apply --addcalls it alone, andstage_written's says the same, though since #242 family.py's_commit_one(everyadd,bumpandremovecommit) andcmd_bumpcall it alone too, so the next change to its contract is reasoned about with half of its alone-callers missing #369 (P2): Maintainer-only docstring miscountsforce_stagecallers; no behaviour wrong, no user hit. PR already open and docstring-only, so merging costs nothing. - repo_shape.py's
Refusalgives every refusal built without a remediation the assembly root's own (run git submodule update --init --recursive, then python3 scripts/validate-pins.py ... contracts/<leg>-pin.yaml), so in a family holderfamily.py addover an unparsable.gitmodules(git-failed),bumpon afamily.yamlof the wrong kind, and the holder's ownvalidate-family.pyon a shortpin.commiteach tell the operator to run a file no holder carries and to move a leg pin a holder does not have #370 (P2): A family user with a conflict-marked.gitmodulesorfamily.yamlis told to runvalidate-pins.pyand move a leg pin the holder lacks. - family.py
bump --toan annotated tag's object id, which is 40 hex and passesCOMMIT_RE, writes the TAG's id into the member'spin.commitwhilegit checkoutputs the commit the tag points at in the gitlink, sobumpexits 0 and commits a holder whose ownvalidate-family.pyreportsmember-gitlink-mismatch, exit 1, whereadd --atpins the commit the same tag names #405 (P1):family.py bump --to <annotated tag's id>(whatgit rev-parse v2prints) exits 0 and commits a holder whose ownvalidate-family.pyis red.
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:
- → family.py
bump --to: make the checksaddmakes (a duplicate id, an annotated tag's own id), and say to push first for an unpushed commit #541 F1:family.py bumpnever asks whether theidthe member'sproject.yamlrecords at--tois one another row already records, so it commits a holder its ownvalidate-family.pyrefuses asmember-duplicate-id. Direction: askbump(and--dry-run) the questionaddasks since family.py:addrefusesmember-duplicate-idbefore it mounts anything when the member'sproject.yamlrecords anida row already pins, so adding a repository renamed at the forge no longer commits a second row the holder's ownvalidate-family.pyrefuses (#330) #381.
Edge cases found in review of lane openRepoShape-3's pull requests, kept here rather than filed:
- → rides with family.py
bump --to: make the checksaddmakes (a duplicate id, an annotated tag's own id), and say to push first for an unpushed commit #541. Ruled 2026-10-14:bump --topeels an annotated tag's own id, asadd --atdoes.family.py add --at <an annotated tag's own id>peels it to the commit it tags (family.py:addasks every refusal of the holder and of a throwaway clone of the member before it mounts anything, and unwinds and names whatever fails after the mount, so a refused add (a leg, a short or unknown--at, an empty member) no longer leaves a staged gitlink and.gitmodulessection that the next add commits under its own title (#203) #236), whilebump --torefuses the same id once family.py:bumprefuses a--tothat names an annotated tag, a tree or a blob asmember-to-not-a-commitbefore the checkout, naming the commit a tag names, and its dry run refuses alike, so a release tag's own id no longer exits 0 with a commit pinning the tag over a gitlink at its commit, which the holder'svalidate-family.pyrefused asmember-gitlink-mismatch(#405) #466 lands, and the two word a tag of a tree differently ("names a tree", "is an annotated tag of a tree"). Decide one rule:addrefuses too, or the peel is documented as deliberate. From the review of family.py:bumprefuses a--tothat names an annotated tag, a tree or a blob asmember-to-not-a-commitbefore the checkout, naming the commit a tag names, and its dry run refuses alike, so a release tag's own id no longer exits 0 with a commit pinning the tag over a gitlink at its commit, which the holder'svalidate-family.pyrefused asmember-gitlink-mismatch(#405) #466. - → scaffold-project.py re-run: a leg that gh sees and git cannot read gets a generic failure, and the reuse run's "two new legs" and private-leg text are wrong #542 scaffold-project.py: when git cannot read a leg that
ghcan see, the refusal is the generica git or gh command failedinstead ofscaffold-remote-exists(scaffold-project.py, family.py init: after a ruleset refuses the first push, neither exitRULESET_HINToffers can finish: the pull request has no base in the repositorygh repo createleft empty, and the scaffold's re-run is refusedscaffold-remote-existsfor its own two empty legs, so a ruleset-protected organisation cannot seed a new project;--reuse-empty-repois to reuse empty legs, and the hint is to offer only that re-run #462's must-keep), because_held_seedruns for every non-empty leg (scaffold-project.py:431 at scaffold-project.py and family.py init:--reuse-empty-reporeuses a leg that is empty or whose one commit is the scaffold's own seed, and the ruleset hint offers that re-run, by an operator holding the bypass right, as its one exit, so a project a ruleset refused part-way is finished by one re-run, not refusedscaffold-remote-existsfor its own legs or sent to a pull request with no base (#462) #506's head c6761db) andonly_commit(:357-365) runsgit ls-remoteandgit fetch --depth=1;run()does not setGIT_TERMINAL_PROMPT=0, so on a terminal git can stop for a username; and the depth-1 fetch downloads the leg's whole tip tree to read one commit. Direction: catchCommandFailedin_held_seedand return None; optionally--filter=tree:0. From the review of scaffold-project.py and family.py init:--reuse-empty-reporeuses a leg that is empty or whose one commit is the scaffold's own seed, and the ruleset hint offers that re-run, by an operator holding the bypass right, as its one exit, so a project a ruleset refused part-way is finished by one re-run, not refusedscaffold-remote-existsfor its own legs or sent to a pull request with no base (#462) #506 (N1). - → scaffold-project.py re-run: a leg that gh sees and git cannot read gets a generic failure, and the reuse run's "two new legs" and private-leg text are wrong #542 scaffold-project.py's visibility messages assume both legs were just created: "the two new legs inherit…" and "The two new legs are created…" (:918, :924 at c6761db), and
_private_leg_note(:1078-1085) goes by the run's--visibility, so a re-run that reuses legs can print a NOTE that contradicts its own per-legis reused and is publicWARNING, and private reused legs under a public run get no private-leg note whileproject.yamlrecords the run's value. From the review of scaffold-project.py and family.py init:--reuse-empty-reporeuses a leg that is empty or whose one commit is the scaffold's own seed, and the ruleset hint offers that re-run, by an operator holding the bypass right, as its one exit, so a project a ruleset refused part-way is finished by one re-run, not refusedscaffold-remote-existsfor its own legs or sent to a pull request with no base (#462) #506 (N2). - → 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 adopt-project.py's ruleset hint still offers "The scaffold's other exit, a seed branch and a pull request…" (adopt-project.py:5248, comment at :5230, on main at f391e58), an exit scaffold-project.py and family.py init:--reuse-empty-reporeuses a leg that is empty or whose one commit is the scaffold's own seed, and the ruleset hint offers that re-run, by an operator holding the bypass right, as its one exit, so a project a ruleset refused part-way is finished by one re-run, not refusedscaffold-remote-existsfor its own legs or sent to a pull request with no base (#462) #506 removed from the scaffold; tests/test_ruleset_hint_tracking_branch.py:115 pins that sentence word for word, so the fix changes both. From the review of scaffold-project.py and family.py init:--reuse-empty-reporeuses a leg that is empty or whose one commit is the scaffold's own seed, and the ruleset hint offers that re-run, by an operator holding the bypass right, as its one exit, so a project a ruleset refused part-way is finished by one re-run, not refusedscaffold-remote-existsfor its own legs or sent to a pull request with no base (#462) #506 (N3). - -> AGENTS.md, README.md, the handbook, the release notes and scaffold-project.py: the
--familyrefusal path, "nothing is created", three ruledbumplimits and aseed/scaffoldre-run are unsaid or slightly wrong #921 A seed found only onseed/scaffold(the branch the old hint made) is accepted, and the re-run createsmainat it without touchingseed/scaffold; on GitHub the leg's default branch likely staysseed/scaffold, and the run says nothing about it (tests/test_scaffold_reuse_seeded_legs.py:166; not verified on github.com). From the review of scaffold-project.py and family.py init:--reuse-empty-reporeuses a leg that is empty or whose one commit is the scaffold's own seed, and the ruleset hint offers that re-run, by an operator holding the bypass right, as its one exit, so a project a ruleset refused part-way is finished by one re-run, not refusedscaffold-remote-existsfor its own legs or sent to a pull request with no base (#462) #506 (N4). - -> tests/test_ruleset_hint_tracking_branch.py: the "kept at its commit" check cannot catch a new seed commit made in the same second #922 tests/test_ruleset_hint_tracking_branch.py:429-430's "kept at its commit" assertion cannot catch a new seed commit made in the same second (an identical commit): with
_take_held_seeddisabled,[scaffold-code-main]still passes while five other tests fail. The dedicated reuse test pins a later commit date, so the guard as a whole holds. From the review of scaffold-project.py and family.py init:--reuse-empty-reporeuses a leg that is empty or whose one commit is the scaffold's own seed, and the ruleset hint offers that re-run, by an operator holding the bypass right, as its one exit, so a project a ruleset refused part-way is finished by one re-run, not refusedscaffold-remote-existsfor its own legs or sent to a pull request with no base (#462) #506 (N5).
Known limits found by lane openRepoShape-3's acceptance passes (standard 36538fd, each re-checked on main 7a8b981) and kept here rather than filed:
- Closed 2026-10-14, fixed by af01068 (README.md and AGENTS.md: 28 statements the v1.0.0 accuracy pass found false are corrected to what the tools do on main (#483) #505): README.md:306-308 now says the run leaves the scaffold's three working trees in the temporary folder, and Brett Heap ruled on 2026-10-14 to keep documenting them. AT-scaffold F7: every scaffold run without
--work-dirleaves three working trees in/tmp/openreposhape-XXXXXXXX(scaffold-project.py:1496-1497, printed as "Working trees are at ..." at :1537), because setup-project.py passes no--work-dirand removes only its own self-bootstrap clone (:707), though README.md:306-308 says a rehearsal leaves only./Atlasand the bare repositories. - → rides with setup-project.py: its paste lines, the step (3), (4) and (7) checks, and the upstream-org guard #538 AT-scaffold N1: under
--local-remote-dirthe scaffold's own NEXT STEPS clone (scaffold-project.py:1524-1529) fails withtransport 'file' not allowed, because setup adds-c protocol.file.allow=alwaysfor its own clone (setup-project.py:1692) and the printed line does not. Test path only. - → setup-project.py: its paste lines, the step (3), (4) and (7) checks, and the upstream-org guard #538 AT-scaffold N2: setup's step (4) never asks the naming validator about a
--pinpassed through after--(check_names, setup-project.py:1523-1545 runs--explain <Project> <Project>-spec <Project>-codeand nothing else), so the report says "no referent pin declared" and step (5)'s plan then says domain-descendant. - -> scaffold-project.py,
family.py initand shape_materialize.py: the plan and the visibility NOTEs go by values GitHub did not give, misword an internal root, skip a public holder's credential NOTE, and name no tracking branch #913 AT-scaffold N3: the plan a person approves names neither the tracking branch the three repositories will be created on nor, in local mode, the visibility (_print_plan, scaffold-project.py:1030-1073;_print_plan_actionssaysgh repo create --privateonly for GitHub remotes, :1096-1103). - → setup-project.py: its paste lines, the step (3), (4) and (7) checks, and the upstream-org guard #538 AT-scaffold N6: inside setup, the scaffold's own "NEXT STEPS: git clone / cd / make bootstrap" block (scaffold-project.py:1524-1536) prints before setup does those very steps itself.
- →
--pin-sourcein scaffold-project.py and adopt-project.py: accepted without--pin, and committed intodigest_sourceas typed #540 AT-scaffold N7:--pin-sourcewrites the path as typed into the committed pin file'sdigest_source(local-clone (<path>), scaffold-project.py:421), so an absolute path commits the scaffolding machine's own directory. - → Pinned validators: THE LOCKSTEP RULE only where it applies, and remedies that name the
git switch -cstep (one shape bump) #539 AT-scaffold N8: validate-pins.py appends THE LOCKSTEP RULE to every non-empty findings list (templates/assembly-root/scripts/validate-pins.py:869-870), so a loneshape-copy-drift(an edited pinned copy, fixed byupdate-shape.pyor a revert) is followed by a rule about moving a gitlink, a pin and the workflows together; repo_shape.py, validate-pins.py, family.py: a refusal built without a remedy prints itsREFUSEDline alone, the assembly root'svalidate-pins.pystill adds the lockstep remedy to its own, andaddrefuses a.gitmodulesgit cannot rea (#370) #494 changes the refusal path only, not this footer. - →
family.py init --dry-runandscaffold-project.py --dry-runexit 0 without asking whether the remotes already exist #537 AT-family N1:family.py init --dry-runreturns (scripts/family.py:1444-1446) before the existing-repository check (_checked_reuse, :1449), so against a holder repository that already exists the dry run exits 0, and the real run then refusesfamily-remote-exists, exit 2, after_prepare_landing_dir(:1448) has left an empty<into>/<Family>/folder. - → family.py
bump --to: make the checksaddmakes (a duplicate id, an annotated tag's own id), and say to push first for an unpushed commit #541 AT-family N5:family.py bump --toa commit that is not yet pushed to the member's remote fails in git's own words (fatal: reference is not a tree), exit 2, and does not say to push first;_checked_bump_targetleaves an unheld--to"to the checkout ... as it always has" (:3793-3795). Re-check after family.py:bumprefuses a--tothat names an annotated tag, a tree or a blob asmember-to-not-a-commitbefore the checkout, naming the commit a tag names, and its dry run refuses alike, so a release tag's own id no longer exits 0 with a commit pinning the tag over a gitlink at its commit, which the holder'svalidate-family.pyrefused asmember-gitlink-mismatch(#405) #466 lands. - →
make siblingsandfamily.py siblings: clone each member on its tracking branch, warn before cloning outside a<Family>folder, and run the holder's pinned siblings.py #543 AT-family N6:make siblingsin a holder whose folder is not named after the family clones the members first, then printsmvlines that move only the holder (templates/family-root/scripts/siblings.py:736-780), so following them and re-running leaves a second set of clones beside the moved holder; the warning says the siblings stay in the old folder but not that a re-run clones them again.
Activity
RULESET_HINToffers can finish: the pull request has no base in the repositorygh repo createleft empty, and the scaffold's re-run is refusedscaffold-remote-existsfor its own two empty legs, so a ruleset-protected organisation cannot seed a new project;--reuse-empty-repois to reuse empty legs, and the hint is to offer only that re-run #462--spec-path null,true,~,2026,1.5), so it creates all three repositories and the new project's own bootstrap failsmanifest-leg-path#225id,elected_on,visibility,tracking_branch, the two legpaths andsubmodule_paths), so a checked value YAML reads as another type (007,2026,true,null) is misread by the project or refused by the tool; quoting them reads every one back exactly and lets numeric branch names adopt #259pin_source_env_nameturns every character outside[A-Z0-9_]into_, so the neutral productsopen-glass,open_glassandopen.glassshare oneSHAPE_PIN_SOURCE_OPEN_GLASS, and a project that pins two of them gets aneutral-pin-source-unreadableFINDING (exit 1) for whichever one the variable does not name #275--tracking-branchonly tochecked_value's alphabet, so a name git refuses as a branch (~,a..b,x.lock, a trailing/) passes--dry-runand, against GitHub, dies at the firstgit init -baftergh repo createhas made all three repositories #283--id null,--created-by ' ',--created-on 20261011or--name 'Contoso Group', and puts--tracking-branch trueon a branch its manifest reads back as True #307commit_trailers: on a git withoutcommit --trailer, a non-ASCII--trailertravels in the stdin commit message and each undecodable byte becomes?underLC_ALL=C PYTHONUTF8=0, so a trailer ofJoséis committed asJos??#322RULESET_HINThard-codesmainas the local branch and as--base, so under--tracking-branch trunkthe hint'sgit push -u origin main:seed/scaffoldnames a branch the work clone does not have and itsgh pr create --base mainopens against the wrong base #324bump(andadd,remove) take no--dry-run, though the file's exit-code paragraph says a dry run prints and exits 0 andbump-leg.pyhas one, so the only way to see what a bump would pin is to run it: fetch, check the member out at--toand rewritefamily.yaml#326_link_sources_from_argssplits every--link-sourcevalue at its first=and nothing reports a value no chain link used, so a link tree under a directory nameda=b, or behind a mistyped key, is silently skipped (declared-unverified, exit 0), andrepo_shape.link_manifest_pathlets a source this user cannot enter (keyed,SHAPE_PIN_SOURCE_<LINK>or a sibling checkout) end the naming gate in aPermissionErrortraceback before Python 3.14 #338pin_digest_from_sourcecatches onlyRefusal, so a--pin-sourcethat does not exist, is a file, or sits under a parent this user cannot enter ends--dry-runand the real run alike in aFileNotFoundError,NotADirectoryErrororPermissionErrortraceback (exit 1), where a directory that is not a clone is thepin-source-unreadablerefusal (exit 2) with its remediation #339--help, sosetup.sh --helprun from anything but a checkout of the standard (a downloaded copy,curl … | bash -s -- --help, agit archiveextraction) clones github.com/opensoft/openRepoShape before printing a word, prints the clone's usage rather than its own, dies with git's exit 128 offline, and makesscripts/render-cli-reference.pyin such a tree reach GitHub, thoughsetup-project.py --helpanswers offline from the same place #341make validate, the validate workflow) dies on a Latin-1 comment where a non-UTF-8 pin is a cleanREFUSED yaml-unreadable, exit 2 #359remove, when.gitmodulesgives the member's path to two sections, takes out only the one git finds by that path (the later in the file) and exits 0, so its commit still registersmembers/<P>with no gitlink and no row,validate-family.pypasses the result (after #317 it reported the doubled file and stops), and the nextaddof that member is refusedmember-path-registeredor silently reuses the leftover section and the.git/configregistrationdeinitnever touched #360members:row for its gitlink and never the reverse, so a gitlink undermembers/that no row names (a member mounted by hand withgit submodule add, or a row deleted by hand) and a.gitmodulessection whose path no row names (whatfamily.py removeleaves of two sections for one path, or a section for a case variant such asMembers/Atlas, whichaddcommits beside the member's own even after #317) all pass the holder's own gate, and the doctor calls the holder COMPLIANT #361143 remaining items
README.md, the handbook, AGENTS.md and the family-root docs: `init`'s…
family.py, scaffold-project.py and bump-leg.py: `init`'s plan rows, s…
setup-project.py: a project name typed at the prompt is checked as `-…
brettheap commentedon Oct 18, 2026
(lane openRepoShape-4, 2026-10-18T04:05:33Z) One line for this checklist, from #868 (#855). It is RV868's SHOULD-2 (#868 issuecomment-6245096782). It was ruled disclosure only, and #868's body names it under "What it cannot tell". It is not a regression: on main the refusal agreed with every reader (
validate-manifest.pysaidshape is missing); since #868 the readers read the block, and only the rewriters do not. (Corrected on RV868b's NIT-2, #868 issuecomment-6245862602: this line first said that nothing reached these rewriters on main, which was false, becauseupdate-shape.py applyrefused there too, with the sameupdate-manifest-no-shapeline.) No tool of this standard writes such a file: every template's first line isschema_version: 1..shape-upstream-tipor a YAML file a Windows editor saved with a byte-order mark reads as the text it holds, so the upstream notice names the tip, a markedproject.yamlis no longerschema_version is None, and every reader of a marked pin, the doctor's included, reads it alike (#855) #868,parse_yamltakes off the leading mark, so the validators,load_yamland the readers of a pin at a commit read the file. The three finders match their key at column 0 of the raw text, where line 1 starts with U+FEFF, so they do not find it:update-shape.py:1532(rewrite_shape_pin,commit:);update-shape.py:1683(_shape_block_bounds, theshape:header, refused at:1698);scripts/bump-leg.py:292(rewrite_pin,commit:)..shape-upstream-tipor a YAML file a Windows editor saved with a byte-order mark reads as the text it holds, so the upstream notice names the tip, a markedproject.yamlis no longerschema_version is None, and every reader of a marked pin, the doctor's included, reads it alike (#855) #868's head62074123, in process, with the marks written as bytes. The same files without the mark, or withschema_version:first, are written.update-shape.py:REFUSED update-pin-unrecognised: contracts/shape-pin.yaml has 0commitline(s) where exactly one was expected, so this tool will not rewrite it, for a shape pin whose first line iscommit:.update-shape.py:REFUSED update-manifest-no-shape: project.yaml has noshape:block, so there is nothing to mirror the pin into, for aproject.yamlwhose first line isshape:. On that file the project's ownvalidate-manifest.pysaysmanifest okandload_yamlreadsshape.commit.scripts/bump-leg.py:REFUSED bump-leg-pin-unrecognised: the pin file has 0commitline(s) where exactly one was expected, so this tool will not rewrite it, for a leg pin whose first line iscommit:, with one mark or two (RV868 measured both).tests: four tests, `directory_named` and the file twin ask the one he…
repo_shape.py strips only YAML's space and tab, so a value a Unicode …
brettheap commentedon Oct 18, 2026
(lane openRepoShape-4, 2026-10-18T04:47:49Z) One line for this checklist, from #870 (#864). It is RV870's NIT-3 (#870 issuecomment-6245132847), left out of #870 as outside #864. It is not a regression: main says the same.
family.py addrefuses a holder whosefamily.yamlsaysmembers: null, with the null written as a word, in words that say the file has nomembers:line.addrefuses withfamily-members-unrecognised. Its text says the file has 0members:line(s), which is untrue: the line is there, and the readers read it as null.add's line finder (rewritten()inscripts/family.py) takesmembers:andmembers: []and no other spelling.members:that is not a list, or holds an entry that is not a mapping, is said in the gate's words, so the doctor'smembersrow waits on thefamilyrow instead of calling the family empty,add,bump,remove,make bootstrapandmake siblingsrefuse it by name where each ended in aTypeError, read no members or committed the entry away, and--no-membersfinds the entry (#864) #870's head03fe51e6. It is the same on main.null,Null,NULLand~) as it takesmembers:, so thataddwrites the first member there too.brettheap commentedon Oct 18, 2026
(lane openRepoShape-3, 2026-10-18T14:55:27Z) Triage of #459's unchecked items at the v1.1.1 release commit
5017830. This is lane 3's TRIAGE-459, read only, before this filing.How to read it. U001 to U188 number #459's 188 unchecked lines in posting order: U001 to U015 are the body's lines, and U016 to U188 are the comments' lines. A line posted twice is ruled once, as "A = B" (lane 4's copy of 2026-10-16T14:10:49Z repeats 26 earlier lines). V-rows are the v1.0.0 Known limits under #459 that have no checklist line. Every fix commit named below is on the first-parent history of
5017830, and every code line is at5017830. Probes ran with a stubghthat exits 97,GH_TOKEN=bogus, an emptyGH_CONFIG_DIR,GIT_CONFIG_GLOBAL=/dev/nulland local remotes.Counts. Of the 188 lines: 115 FIXED; 3 partly fixed (U041, and U119 = U151), whose open half is filed; 1 COVERED (U180, by #430); 1 STALE (U045); 68 OPEN, which is 64 items once the duplicates are counted once. Nothing is UNSETTLED. The 17 V-rows are all FIXED.
Filed today, milestone v1.2.0 (21 issues):
family.py bump's fetchfamily.py initrepo_shape.pyvalidate-pins.pyandrepo_shape.pyover odd pins and raw textfamily.py addThe body. Lane 3 ticked its own body lines that are FIXED (U001 to U005, U008, U009, U011 to U015), and marked the three OPEN ones with their new issue: U006
-> #921, U007-> #922, U010-> #913. Comment lines left unticked stay as their authors wrote them: this comment is their ruling, and each author may tick or annotate their own lines from the table below.The table
famisscripts/family.py,vfistemplates/family-root/scripts/validate-family.py,vpistemplates/assembly-root/scripts/validate-pins.py,smisscripts/shape_materialize.pyandrsisscripts/repo_shape.py.5017830_checked_bumped_idPROBE_ENV:469seed/scaffold-- --pin--no-next-stepsdigest_sourceholds a pathgit-not-runnablerules.exists()guardmember-gitlink-unnamedrepeatspath:--org OpenSoft_switch_line--intosentence-- --dry-run"WERE created"cdand backstop paths<into>/<Project>Username forvisibility:(and its family addition)--noambiguousdigest_source:member-gitlink-absentremedymember-to-unknownfamily.yamlcommitted as the work tree has it_checked_manifest_committed.gitmodulesoutmembers/membersfile, sparsemembers/git mv members MembersMembers/READMEgit mv --sparseneeds git 2.34tracking_branchnames a tagmake siblingspassed_valuesdocstringpassed_valuesorigin(known limit)add --attag-only pin, notes--prune. bump-leg's half is #898origin--family-rootfamily bootstrap ok--no-memberscommandmembersfilerebase-merge/family.yamlmerge --squash,cherry-pick -ncontracts/_is_fileproject:parent_folder_warningrawfamily_folder_heredisplay namecdfamily_name_notewith noname:GIT_AUTHOR_NAME+xsubmodule_urlssplitlineslegs:not a listk: {?: 1}line N:_read_backguard_neutral_pin_entrydocstring[a: b: c]wordsdirectory_namedskips on Windows--id=foo_bartold "lowercase"if not given:loopsopenGlass=--pin-sourcetwo ways--link-remedypadding, no NOTEnot-a-git-repoprints--rootrawgh-unreadablestderr raw.git.exists()--refmap=origin/clashgit config --listsplits valuesoriginmerge --ff-onlyline, non-UTF-8members: nullNot filed, with the reason
Not on #459's checklist: candidates the closing pull requests name
project:or url is a finding,.gitmodulesis read as git reads it, the warning's prose is spelled, and a tag-only branch is named (#690) #805 left two states: a file named<Family>stops the printedmkdir -p, and an existing<Family>/<Family>receives the holder inside it.family-operation-in-progressname a path asshown_sourcenames it, so an ESC or a line break in a path no longer reaches the terminal (#692) #731's "Checklist candidates":init'slandingandfolderplan rows, and seven refusals, print paths raw. This overlaps U175.+or named like a tag pushes as itself, and a tracking branch whose last part is over 250 bytes, which git cannot lock, is refused byrefuse_bad_branchbefore anything exists,--dry-runtoo (#689) #813: a branch part namedCONorNULis unassigned.plan --org @xnames--orgagain under the reader's own remedy, andchecknames one badtracking_branchonce (#708) #817's body lists eight "For Tracking: setup, scaffold, family and the shared helpers, creating projects and families #459's checklist" lines from lane 1's review that are not posted here, such assplitlinesshiftingline N.Lane: openreposhape-3 (openRepoShape-3)
family.py add: a commit that records the member's gitlink anywhere bu…
family.py init: where the holder's own YAML reader refuses the manife…
family.py: `bump`'s fetch no longer moves the mount's own branches, w…
the family root's siblings.py and bootstrap.py: a member's path this …
family.py and bump-leg.py: every remedy that names `family.py bump` n…
setup-project.py: the self-bootstrap refuses an `$OPENREPOSHAPE_REPO`…
brettheap commentedon Oct 23, 2026
(lane openRepoShape-5, 2026-10-23T12:05:18Z)
Lane 5 filed three follow-ups that belong to this tracker. They come from its independent review of #1166 (#1139), findings 1, 4 and 8 (#1166 issuecomment-6352173084), and each was re-measured at main
961640c6.NamingPolicyreads a name with.matchagainst patterns that end in$, so a name that ends in a line feed is classified as the name without it, andvalidate-repository-naming.pyexits 0 over such a leg repository (#1166 follow-up) #1202:repo_shape.py'sNamingPolicyreads names with.matchagainst patterns that end in$. A name ending in a line feed is classified as the name without it, sovalidate-repository-naming.pyexits 0 over such a leg repository.id:, so an id that ends in a line feed or holds a space isfamily okunder--no-members, and a row that main'sfamily.py addwrote staysfamily ok(#1166 follow-up) #1204:validate-family.pyasks no pattern of a member row'sid:. Under--no-members, a row id that ends in a line feed or holds a space isfamily ok, and a row that main'sfamily.py addwrote staysfamily ok.name,reference,elected_by, a leg'spath,org,tracking_branch,digest_algorithm) aremanifest okorfamily okwith a trailing line feed (#1166 follow-up) #1205: values that no pattern reads (name,reference,elected_by, a leg'spath,org,tracking_branch,digest_algorithm) aremanifest okorfamily okwith a trailing line feed. No tool readsdigest_algorithmat all.All three are post-tag follow-ups, with no milestone.
Lane: openreposhape-5 (openRepoShape-5)