Repository navigation
family.py init: --created-by and GIT_AUTHOR_NAME are never asked whether the manifest can hold them, a whitespace-only GIT_AUTHOR_NAME fails after the remote exists, and a --family a Windows disk cannot hold exactly is accepted #688
Description
Goal: init refuses, before any remote or folder exists and under --dry-run alike, every identity or name it cannot write down or lay out, whichever flag or variable supplied it.
Filed by lane openRepoShape-5 on Brett Heap's word of 2026-10-16T12:17:02Z ("#459's family lines (~38)"), from checklist lines on #459 (comment 6214533776, R423 (a) and (b); comment 6192725913, the Windows family-name line). Lane 4 judged the first two OPEN on 95780dd (cluster T9); re-read and probed on d4a7fab.
Lines (line numbers at d4a7fab)
- R423 (a),
initasksunwritable_reasonof the creator only whengit config user.namesupplied it._creator_name(scripts/family.py:1551-1602) calls it only in theif not created_by:branch'selse(:1584);--created-byandGIT_AUTHOR_NAMEgo unasked. Probed on main:init --created-by $'Ada\nLovelace' --dry-runexits 0 and the plan printscreated by Adaand thenLovelace on 2026-10-16on the next line;--created-byholding U+202E exits 0. The scaffold asks its elector whatever the source (_identity, then_refuse_unwritable_values(_elector_named(args), ...)). Direction: ask the creator once, whatever answered, in_creator_nameor besiderefuse_unholdable_manifest(scripts/family.py:2345), with a remedy that names the flag or the variable that supplied it (CREATOR_UNWRITABLE_REMEDIATION,:1538, speaks ofgit config user.namealone). - R423 (b), a whitespace-only
GIT_AUTHOR_NAMEfails after the remote exists._creator_namestrips the variable (:1575) and goes on togit config user.name, so the manifest is written from a good name, butgit commitreads the variable: probed withGIT_AUTHOR_NAME=' ',GIT_COMMITTER_NAME=' 'and a gooduser.name, a realinitexits 2 withfatal: name consists only of disallowed charactersafter<remote>/Orbit.gitand the work directory exist. It predates bump-leg.py, scaffold-project.py and family.py:git status --porcelainandgit config user.nameare read as bytes, so a file name that is not UTF-8 isbump-leg-root-dirtyor the DIRTY warning and auser.namethat is not UTF-8 is refusedfamily-unwritable-valuenaming--created-by, where each ended in a UnicodeDecodeError traceback (#423, #426) #641; scaffold-project.py writes--elected-by,--referenceand--namebetween literal double quotes with no escaping and asks none of them whether a file can hold it, so a line break leaves a project.yaml its own validators refuse, a backslash is recorded as another character (CORP\nickas CORP, a line feed, ick), and a byte that is not UTF-8 dies inwrite_lfafter the legs are pushed #282's body names the scaffold's twin. Direction: refuse it up front, before anything exists, by asking git for the identity the commit will use (GIT_AUTHOR_NAME=' ' GIT_AUTHOR_EMAIL=t@t git var GIT_AUTHOR_IDENTexits 128 with the samefatal: name consists only of disallowed characters, probed) or by naming a blankGIT_AUTHOR_NAME/GIT_COMMITTER_NAMEas the cause, as the creator refusal does. The scaffold's twin is a separate line (scaffold-project.py writes--elected-by,--referenceand--namebetween literal double quotes with no escaping and asks none of them whether a file can hold it, so a line break leaves a project.yaml its own validators refuse, a backslash is recorded as another character (CORP\nickas CORP, a line feed, ick), and a byte that is not UTF-8 dies inwrite_lfafter the legs are pushed #282). - A family name a Windows disk cannot hold exactly is accepted, and then never passes the folder test there.
_checked_family_identity(scripts/family.py:1505-1530) takes--familythroughchecked_value(SAFE_ARG_RE,scripts/repo_shape.py:106, which allows a trailing.) and nothing else asks whether the name is a folder Windows can make: a trailing.or space, which Windows drops, andCON,NULand the other device names.make siblingscomparesfolder.name == family(templates/family-root/scripts/siblings.py:969), and siblings.py and family.py:make siblingsasks about the family folder before it clones, clones each member on its tracking branch, andfamily.py siblingsruns the holder's own copy (#543) #578's stop then repeats on every run.shape_materialize._unmountable_reason(scripts/shape_materialize.py:3677) already holds these rules for a leg's mount path. Reasoned, not run on Windows: this host cannot create such a folder. Direction: refuse the--familyatinit(before anything exists,--dry-runtoo) with the leg path rule's reason, exposing or calling_unmountable_reasonfor a single segment; one test row per rule.
Overlaps: none with an open PR. scripts/family.py is not a pinned copy. The existing family-unwritable-value rows are in tests/test_non_utf8_git_reads.py (#426) and tests/test_clone_url_bytes.py (#433); the new rows go beside them.
Mark the three lines → this issue on #459, and tick them there when this closes.
🤖 Generated with Claude Code
Activity
brettheap commentedon Oct 16, 2026
CLAIMED — lane openRepoShape-4, session 11c6c0ef-495a-4a05-94cf-811b7b0a1012@Eagle, 2026-10-16T13:23:47Z, for #688
Logged in
lanes/log/openRepoShape-4.mdatf66205107ca3d2887cc30f2beb1c312b66e7c5e6.The three reads (lane-collision-protocol Rule 1):
Merge main bf1f099 into fix/688-family-init-values
tests/test_family_init_asks_every_value.py and family.py: the test so…
family.py init: git's words in the commit-identity refusal are spelle…
render-cli-reference.py and tests/: the CLI reference's children writ…
shape_materialize.py, scaffold-project.py and family.py: the folder r…
Merge origin/main (bad05d2) into l3-563-docs
docs/release-notes/v1.1.0.md: entries for #748, #731, #810, #809, #816,
family.py: one import of shown_path, now that #688 has landed beside #…