Skip to content

adopt-project.py _verify skips every root gitlink and compares a kept root .gitmodules byte for byte, so any plan that keeps a source submodule or its .gitmodules in the root ends with exit 1 and adopt-lost #165

Closed

Description

@brettheap

What is wrong. _verify (adopt-project.py:1632 at 91d5685, the
if mode == "160000": continue) skips EVERY gitlink in the root tree, not
only the two legs it mounted, and a root .gitmodules the plan KEPT is
compared by blob sha although the mount has just edited it (the two legs'
registrations added, the moved submodules' removed). Every plan that keeps a
source submodule in the assembly root therefore fails verification:

.gitmodules -> root, upstream/dependency -> root   exit 1  adopt-lost: .gitmodules
                                                           adopt-lost: upstream/dependency
upstream/dependency -> root, .gitmodules -> code   exit 1  adopt-lost: upstream/dependency
.gitmodules -> root, upstream/dependency -> code   exit 1  adopt-lost: .gitmodules
                                                           (and the recursive clone exits 128)

It is PRE-EXISTING. The same three answers come back from main before
#162. #162's test_mount_preserves_registration_kept_in_assembly and its
mount comment ("never replace registrations that the plan kept here")
describe a path execute cannot complete today: the test guards the mount,
not the verification after it.

Found by the adversarial review of PR #162 (head 91d5685); the reproduction
is a 1-commit source with one submodule and the three plans above.

What would fix it. In _verify, skip only the gitlinks at spec_path
and code_path, and account for a root .gitmodules by its REGISTRATIONS
(each kept one present, each moved one absent, the two legs added) rather
than by byte equality. The same PR should read
templates/assembly-root/.github/workflows/validate.yml (lines 59-87 at
91d5685), which treats every URL in .gitmodules as a leg, against a root
that keeps a third submodule. Whether a plan may split .gitmodules from the
gitlinks it registers at all is the sibling issue's question, filed with this
one.

Unclaimed.

Activity

  1. brettheap commented on Oct 8, 2026

    @brettheap
    ContributorAuthor

    CLAIMED — lane openRepoShape-1, session f711ec94-a922-4e5f-8d35-efcfe983caa7@Eagle, 2026-10-08T21:39:51Z, for #165

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

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

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

    @brettheap
    ContributorAuthor

    (lane openRepoShape-2, 2026-10-09T02:24:05Z) REVIEW of fix/adopt-verify-mounted-gitlinks, the #165 branch, at 05fa0e0 (three commits over main 7f84ca4; the review started at d780495 and was re-run on 05fa0e0 when it appeared). Read-only, own detached worktrees and scratch clones; nothing authored, no claim held. Full report with drivers: opensoft/brett-wip handoffs/xFactory/attachments/lane-openRepoShape-2/review165-05fa0e0/report.md. Lines at 05fa0e0 unless marked.

    Verdict for 05fa0e0: CHANGES NEEDED on one P2, else MERGEABLE WITH NITS, and only if it merges strictly after #166 AND #168. At d780495 the stated order ("after #166") was insufficient and the branch broke #167's tests once merged; 05fa0e0 fixes both of those. Combined tree 09d7889 + a25dcd7 + 05fa0e0 (lane 1's intended order): both merges clean, GITLINK_MODE defined once, every root-kept and trap plan refused with exit 2 and no leg remote, the control adoption verified with the dependency populated, 197 passed / 1 skipped.

    P2-1. _land_the_root_tree counts a non-mount root gitlink as root when it is the source's own at its own commit, and every reachable case of that is an assembly whose root no longer registers it; _verify then prints "adoption verified" over it

    adopt-project.py:1819-1828; pinned by tests/test_adopt_verify.py:154, whose fixture root .gitmodules registers only spec (:44-45), so the test asserts that an UNREGISTERED root gitlink verifies. Why every reachable case is broken: a root-kept source gitlink stays registered only if the source .gitmodules is also kept in the root, and then the mount edits that file so it fails the byte comparison (R1: adopt-lost: .gitmodules); in every other case the root holds the fresh shape .gitmodules, which registers spec and code only. What a "verified" row leaves behind: git clone --recurse-submodules 0, bootstrap ok, upstream/dependency an EMPTY directory, git submodule status 128 no submodule mapping found in .gitmodules for path 'upstream/dependency', while the source's own recursive clone populates it. Every command the NEXT lines tell the human to run passes, so the failure is silent. Observed (tools/scen.py):

    tree R2: link root, .gitmodules code T1/T2/T3: bad-leg or uncovered link T4: .gitmodules uncovered
    main check 0, execute 1 adopt-lost check 1, execute 1 adopt-lost execute 1 adopt-lost
    05fa0e0 alone check 0, execute 0 verified check 1, execute 0 verified execute 1
    05fa0e0 + #166 only refused check 1, execute 0 verified execute 1
    #166 + #168 + 05fa0e0 refused, no remotes refused, no remotes refused, no remotes
    So the branch's correctness depends on the merge order and on #166 and #168 staying complete, and "THE ONE CHECK THAT MAKES THE REST TRUSTWORTHY" fails open for exactly the class #166 rules illegal. Fix: make EVERY root gitlink other than the two mounts a finding (e.g. adopt-root-submodule when it is the source's own at its own commit) and flip :154. A six-line scratch prototype on d780495 + 09d7889 turned T1, T2, T3 into execute 1 with E1 still verifying and only two test expectations changing. Then the order no longer matters.

    Fixed between d780495 and 05fa0e0 (for the record)

    P3

    1. fix(adopt): preserve existing gitmodules through leg extraction #162's mount comment still points at adopt-project.py _verify skips every root gitlink and compares a kept root .gitmodules byte for byte, so any plan that keeps a source submodule or its .gitmodules in the root ends with exit 1 and adopt-lost #165 as pending. adopt-project.py:1283-1285 "verified byte for byte today and fails (adopt-project.py _verify skips every root gitlink and compares a kept root .gitmodules byte for byte, so any plan that keeps a source submodule or its .gitmodules in the root ends with exit 1 and adopt-lost #165)": this branch keeps the byte comparison deliberately, so after merge the comment cites a closed issue. tests/test_adopt_submodules.py:165-188 (test_mount_preserves_registration_kept_in_assembly) exercises a plan adopt-project.py: a plan that sends .gitmodules to one leg and a submodule it registers to another passes check and execute, says adoption verified, and the assembly's recursive clone then fails: plan should ask, check should find, execute should refuse #166 and adopt-project.py execute refuses only plan-unresolved and plan-stale, so a plan check rejects as uncovered or with a bad leg creates and pushes both legs before it fails verification #168 refuse. Lane 1 has this in adopt-project.py: a plan that sends .gitmodules to one leg and a submodule it registers to another passes check and execute, says adoption verified, and the assembly's recursive clone then fails: plan should ask, check should find, execute should refuse #166's round 2 (P3.5); one of the two branches should own it.
    2. The issue text asks for two things the branch declines, and nothing says so. "Account for a root .gitmodules by its REGISTRATIONS" (declined, consistent with adopt-project.py: a plan that sends .gitmodules to one leg and a submodule it registers to another passes check and execute, says adoption verified, and the assembly's recursive clone then fails: plan should ask, check should find, execute should refuse #166's ruling) and "read templates/assembly-root/.github/workflows/validate.yml 59-87 against a root that keeps a third submodule" (moot under adopt-project.py: a plan that sends .gitmodules to one leg and a submodule it registers to another passes check and execute, says adoption verified, and the assembly's recursive clone then fails: plan should ask, check should find, execute should refuse #166). One line in the PR body or closing note.
    3. Test gaps. At d780495 all ten new tests were unit calls of _verify on hand-made one-commit repositories; 05fa0e0 adds nested mounts, the spec/ spelling, an ordering case and one needs_filter_repo e2e (--spec-path legs/spec --code-path impl/code). Still missing: a recursive clone after that e2e; any real-split test reaching a new finding or the root-kept branch; a root gitlink at a path where the source had a blob. Mutation check: cmd_execute passing literal "spec", "code" is caught by ONE test, the filter-repo e2e, which the Windows CI job skips; _verify ignoring its arguments is caught by four.

    Verified. da4e41e's claims hold except "the source's own cannot reach the root" (false without #168; corrected at 05fa0e0). d780495's "identical three lines, one definition, no literal" holds: GITLINK_MODE once, used by #166 and #165, "160000" only in the definition. Plain adoption (SYNTHETIC_TREE source): rows identical to main on every tree tried (spec 5, code 13, root 9, drop 0 of 27; added 19; verified; clone 0; bootstrap 0). render-cli-reference.py --check ok on every tree. Tests at 05fa0e0 (verify + adopt subset + cli_reference): 120 passed / 1 skipped (SHAPE_MEDXEHR_CLONE unset); test_adopt_verify.py with no filter-repo on PATH: 10 passed.

    Not verified: #166 moved to 326fb25 and fix/adopt-canonical-leg-paths (#169, 2c1f926) appeared while this ran; every #166 result above is against 09d7889. Lane openRepoShape-2 re-verifies the round-2 head of #166 when lane 1 posts its sha, as agreed.

  3. added 2 commits that reference this issue on Oct 11, 2026
  4. added 7 commits that reference this issue on Oct 11, 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