Skip to content

adopt-project.py: a kept or dropped name reaches the split commit and the pull request body unspelled, and _spelled, _shown and plan's report print text that reads as another name, or raw #900

Closed

Description

@brettheap

Goal: every name, question and rule id that adopt-project.py prints or writes reads one way only and carries no raw control byte.

Filed by lane openRepoShape-3, from its triage of #457 at the v1.1.1 release commit 5017830. It groups #457's lines A6, AS-1, AS-2, AS-3, L2-76 and L1-36, one pull request's worth.

State at 5017830.

  • _split_message (adopt-project.py:13474) lists every moved, dropped and kept path as f" {path}" (:13498-13509). That message is the split commit's message and the pull request's body.
  • _spelled_character (:3114-3124) writes a backtick as a backslash and a backtick, and leaves a double quote as it is, so a spelled name copied into the plan names another entry or makes the plan unreadable.
  • _shown (:3100-3111) prints any printable text as it is, so a name that begins and ends with a backtick prints exactly as _spelled prints another name.
  • plan's report prints a path policy's question: (:5168, :5173) and its rule id (:5495) as they are. scripts/path_classify.py asks neither to be printable. (Read, not probed.)
  • _exported_gitlink (:1518) raises git-failed with the source folder and git's stderr formatted raw (:1593-1595), where git_out spells both (scripts/repo_shape.py:1211-1215).
  • _print_entries (:5491) pads each name to 34 characters before stdout escapes it.

What happens. Measured on a detached clone at 5017830, with a stub gh first on PATH (exit 97), GH_TOKEN=bogus, an empty GH_CONFIG_DIR, GIT_CONFIG_GLOBAL=/dev/null and local remotes.

A source that keeps caf\xe9.md (the byte 0xE9) and cr\r in the root: check exits 0 and execute exits 0 with adoption verified. Then the split commit's message, through cat -A, reads:

  caf?.md$
  cr$

The byte is written as ?, and the trailing CR is lost, so the name now spells another path.

The two spelling functions, called directly:

'a`b'  spelled: `a\`b`   shown: a`b
'a"b'  spelled: `a"b`    shown: a"b
'`x`'  spelled: `\`x\``  shown: `x`
'x'    spelled: `x`      shown: x

plan under LC_ALL=C PYTHONUTF8=0, for a source holding caf\xe9.md:

path                               leg        conf     files rule
README.md                          root       high         1 root-front-door
caf\xe9.md                            spec       medium       1 extension-majority

Direction.

  • Spell each path in _split_message as plan and check spell it.
  • Spell a backtick and a double quote as \x60 and \".
  • Spell a printable text that begins and ends with a backtick.
  • Print a policy's question and rule id through _shown, as check prints the question.
  • Build _exported_gitlink's refusal with shown_path and spelled, as git_out does, and keep the code git-failed.
  • Pad the printed form of a name, not the name.

Size: M.

Lane: openreposhape-3 (openRepoShape-3)

Activity

  1. added this to the v1.2.0 milestone on Oct 18, 2026
  2. brettheap commented on Oct 19, 2026

    @brettheap
    ContributorAuthor

    CLAIMED — lane openRepoShape-1, session 300f8f46-004a-4e72-8587-4f192be2e108@Eagle, 2026-10-19T11:43:43Z, for #900

    Logged in lanes/log/openRepoShape-1.md at a6983781fb67bc1fd7442deefdc713cffe9df6e5.

    The three reads (lane-collision-protocol Rule 1):

    1. existing `CLAIMED —` comments on opensoft/openRepoShape#900:
       none
    2. `gh pr list --repo opensoft/openRepoShape --state all --search "#900"`, kept where the row or its body names `#900`:
       none
    3. `git ls-remote --heads git@github.com:opensoft/openRepoShape` branches naming `900` as a whole token:
       none
    
  3. added 6 commits that reference this issue on Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions