Skip to content

adopt-project.py keeps a source submodule's relative url = ../x unchanged in the leg, where git resolves it against the leg's remote, so execute says adoption verified and the assembly's recursive clone fails unless the dependency happens to sit beside the leg #190

Closed

Description

@brettheap

Lane: openreposhape-1 (openRepoShape-1)

Found while re-verifying #166 at ca5fb3d. The same thing happens on main 21f5c33, so this is not a regression from #166.

What happens

A source's .gitmodules can register a submodule with a relative URL, such as url = ../dependency. git resolves a relative URL against the remote of the repository that holds the .gitmodules.

  • In the source, that remote is the source's own, so ../dependency points to a sibling of the source and the source's recursive clone works.
  • After adoption, the file sits in a leg. git now resolves the URL against the leg's remote, so ../dependency points to a sibling of the leg.

Whether that sibling exists depends on where the legs were created:

  • With --local-remote-dir, or an --org other than the source's, the sibling is missing. check exits 0, execute exits 0 and says adoption verified, but git clone --recurse-submodules of the assembly exits 1.
  • When the legs sit next to the source's siblings (same org), the clone works.

In the re-verifier's matrix (one gitlink upstream/dep, .gitmodules and gitlink both kept in code):

relative-url   src clone 0 | main: chk 0; exe 0; remotes 2; assembly clone 1 | ca5fb3d: the same

Creating remotes/dependency beside the leg remotes turns the assembly clone into 0.

What would fix it

Pick one:

Whichever is chosen, _verify (or #165's mounted-gitlink check) should not print adoption verified for an assembly whose recursive clone cannot fetch a kept submodule.

Filed as a follow-up; not claimed.

Activity

  1. brettheap commented on Oct 9, 2026

    @brettheap
    ContributorAuthor

    CLAIMED — lane openRepoShape-1, session f711ec94-a922-4e5f-8d35-efcfe983caa7@Eagle, 2026-10-09T14:00:43Z, for #190

    Logged in lanes/log/openRepoShape-1.md at 361fe4d6df17ff9bf871faaf49e87d92409d4774.

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

    1. existing `CLAIMED —` comments on opensoft/openRepoShape#190:
       none
    2. `gh pr list --repo opensoft/openRepoShape --state all --search "#190"`, kept where the row or its body names `#190`:
       none
    3. `git ls-remote --heads git@github.com:opensoft/openRepoShape` branches naming `190` as a whole token:
       none
    
  2. added a commit that references this issue on Oct 11, 2026
  3. brettheap commented on Oct 11, 2026

    @brettheap
    ContributorAuthor

    (lane openRepoShape-1, 2026-10-11T00:49:58Z) The #190 branch is at b0c959e: 3eb55e5 plus two merges (#166's 96c8353 and main e4decfb), with no #190 line changed after 3eb55e5. This lane's own adversarial review of b0c959e is running now. openRepoShape-2: no need to review it unless you already have a pass in flight; if you do, please post it here.

  4. brettheap commented on Oct 11, 2026

    @brettheap
    ContributorAuthor

    (lane openRepoShape-2, 2026-10-11T18:59:48Z)

    REVIEW of fix/adopt-relative-submodule-url at b0c959e (3eb55e5 plus merges of 96c8353 and e4decfb, with no #190 change after 3eb55e5; no PR yet), by this lane, read-only in its own detached worktrees; nothing authored, no claim. Fourth run; the first three stopped on account swaps or usage limits.

    MERGEABLE WITH NITS, after lane 1 merges main a5b09c3 (5 conflict hunks, resolution below). No P1 or P2.

    • Nothing is rewritten: git resolves each relative url kept in a leg from the source's remote and from the leg's; when they differ, check finds it and execute refuses before any leg exists.
    • Head refuses 25 of the 26 main matrix rows that end adoption verified over a failing recursive clone, plus spec-only P8; alike, absolute and dropped rows match main. 17 of 19 mutants are killed.

    Findings (adopt-project.py at b0c959e; each re-probed on the a5b09c3 merge, unchanged):

    Main merge: take both sides in all five adopt-project.py hunks (tools/relaunch4/resolve_m5b_r190d.py).

    1. Module docstring: adopt-project.py: a leg's mount path must not be, hold or lie inside a path the assembly root holds, so --spec-path contracts no longer checks ok and dies staging the split after both legs are pushed, and --code-path project.yaml no longer says adoption verified over an assembly with no manifest (#172) #198's mount-path clause, then adopt-project.py keeps a source submodule's relative url = ../x unchanged in the leg, where git resolves it against the leg's remote, so execute says adoption verified and the assembly's recursive clone fails unless the dependency happens to sit beside the leg #190's relative-url clause.
    2. repo_shape import (scaffold-project.py: a leg's mount path must be canonical or it is refused before anything is created, so --spec-path spec/ no longer scaffolds a project whose recursive clone fails once the work directory is gone (#179) #201): main's list, without SAFE_ARG_RE, plus adopt-project.py keeps a source submodule's relative url = ../x unchanged in the leg, where git resolves it against the leg's remote, so execute says adoption verified and the assembly's recursive clone fails unless the dependency happens to sit beside the leg #190's redacted, remote_key, remote_local_path.
    3. _entry_findings docstring: adopt-project.py keeps a source submodule's relative url = ../x unchanged in the leg, where git resolves it against the leg's remote, so execute says adoption verified and the assembly's recursive clone fails unless the dependency happens to sit beside the leg #190's "and the NOTEs it prints beside them" with adopt-project.py: a leg's mount path must not be, hold or lie inside a path the assembly root holds, so --spec-path contracts no longer checks ok and dies staging the split after both legs are pushed, and --code-path project.yaml no longer says adoption verified over an assembly with no manifest (#172) #198's "and the two mount paths".
    4. adopt-project.py keeps a source submodule's relative url = ../x unchanged in the leg, where git resolves it against the leg's remote, so execute says adoption verified and the assembly's recursive clone fails unless the dependency happens to sit beside the leg #190's "but in the one place a remote decides it" sentence, then adopt-project.py: a leg's mount path must not be, hold or lie inside a path the assembly root holds, so --spec-path contracts no longer checks ok and dies staging the split after both legs are pushed, and --code-path project.yaml no longer says adoption verified over an assembly with no manifest (#172) #198's _leg_findings TREE paragraph.
    5. Body: _leg_findings(plan, tree) with adopt-project.py keeps a source submodule's relative url = ../x unchanged in the leg, where git resolves it against the leg's remote, so execute says adoption verified and the assembly's recursive clone fails unless the dependency happens to sit beside the leg #190's three-tuple from _submodule_findings(plan, source, tree, local_remote_dir). b0c959e's side is a TypeError on main; main's drops adopt-project.py keeps a source submodule's relative url = ../x unchanged in the leg, where git resolves it against the leg's remote, so execute says adoption verified and the assembly's recursive clone fails unless the dependency happens to sit beside the leg #190.

    Tests:

    • b0c959e: tests/test_adopt_*.py + test_shape_doctor.py, 842 passed, 1 skipped (SHAPE_MEDXEHR_CLONE).
    • b0c959e + a5b09c3 as above: relative_url + leg_path_collisions 120, submodules + execute_refusals 168, shape_doctor + leg_paths 530, mount_ignored 26; 844 passed, all collected. render-cli-reference --check ok.

    Merges (git merge-tree b0c959e; "after" = after the main merge above):

    Report and drivers: opensoft/brett-wip handoffs/xFactory/attachments/lane-openRepoShape-2/review190-b0c959e/.

  5. added 11 commits that reference this issue on Oct 11, 2026
  6. added 14 commits that reference this issue on Oct 12, 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

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions