Skip to content

README.md (:1081-1084) and docs/handbook.html (:1388) say update-shape.py apply --add refuses a path that is already pinned, one the target's lists do not name and one the root already has a file at, and omit update-add-symlink (#269, on main) and, once #346 lands, update-add-not-a-directory, so a reader meets a refusal no document names; the README is at its line cap and the handbook records its blob, so the clause is a README edit plus a handbook regeneration #429

Closed

Description

@brettheap

(lane openRepoShape-2, 2026-10-12T17:29Z)

Found by this lane's review of PR #346 (the fix for #285) at 818db36, its finding F3 (a nit it called a docs batch): README.md and docs/handbook.html describe what update-shape.py apply --add refuses as they did before #269, and a refusal a reader meets has no sentence. Checked on origin/main 92e29d9 by reading the shipped text against the codes the tool raises. Not claimed.

What is wrong. README.md says of --add (:1081-1084): "--add refuses a path that is already pinned, one the target's lists do not name — and one the root ALREADY has a file at, because two files with one name is a merge and this command copies bytes." The handbook repeats it (docs/handbook.html:1388-1389: "--add refuses a path that is already pinned, one the target's lists do not name, and one the root ALREADY has a file at."). The tool raises four refusals on an --add path at main:

code raised at in README in the handbook in AGENTS.md
update-add-already-pinned update-shape.py:902 yes, in prose ("already pinned") yes no
update-add-not-upstream :911 yes ("the target's lists do not name") yes no
update-add-would-overwrite :923 yes ("ALREADY has a file at") yes no
update-add-symlink (#239, PR #269, landed as c1b6732) :864 no no no

So a root that keeps a symlink at the path, or at a directory above it, is refused with a sentence that no document the person was given mentions, and README's list reads as complete. PR #346 adds a fifth (update-add-not-a-directory, a plain file where a directory goes), which would be omitted the same way. #269 and #346 both left the README alone for the reason below, so each change widened the gap rather than made it.

Why it is not just an edit. The README is capped (tests/test_repo_hygiene.py: 1419 lines, and it is at 1419) and the handbook is "the designed reading of the README" that records the README's blob (docs/handbook.html:1791, README.md blob <sha>) and is held to its outline by test_the_handbook_follows_the_readmes_outline, so any README edit is a handbook regeneration, and a line added is a cap raise with a dated comment as #288's was. A clause that does not add a line (re-wrapping the sentence) needs no cap change.

What it should do. One clause in each of the two sentences that names the refusals: "--add refuses a path that is already pinned, one the target's lists do not name, one the root ALREADY has a file at, and one that has a symlink at it or above it (a link is never written through)" and, once PR #346 lands, "or a file the root keeps where a directory goes". Regenerate the handbook's README pin. If the sentence is kept short, name the codes (update-add-symlink, update-add-not-a-directory) so a person who meets one can search for it; AGENTS.md step 5 ("upstream-added ... --add is per file") may carry one sentence pointing at the README's list.

How to test. tests/test_repo_hygiene.py already pins the README's line cap and the handbook's outline; the change passes them (scripts/render-cli-reference.py --check is unaffected: --help is not touched). A new check that every update-add-* code the tool raises is named in README.md would keep this from drifting again (compare tests/test_agents_md_codes.py, PR #396, which does the same for AGENTS.md's codes).

Not in this issue. A way to decline an addition ("a project that declines an addition has no way to say so yet", the README's own words). The symlink guard for --add is #239/#269; the symlink case for the copies is #286.

Related: #239 and PR #269 (update-add-symlink); #285 and PR #346 (update-add-not-a-directory); #288 and PR #309 (the same kind of omission for the scaffold's two refusals, fixed with a cap raise and a dated comment); #396.

Lane: openreposhape-2 (openRepoShape-2)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions