Skip to content

shape-doctor.py pin_restore: a copy conflicted beside the shape pin that only the side NOT taken has a files: row for is neither taken nor named, so the conflicted pin's why and left_for_a_person say nothing of a file the merge still holds unmerged #687

Closed

Description

@brettheap

Goal: a conflicted shape pin's why names every conflicted copy it does not take, including one that only the other side's pin lists.

Filed by lane openRepoShape-3 on Brett Heap's word of 2026-10-16T12:24:41Z ("give #460 to lane 3").

What happens (measured on main d4a7fab9):

  • The state. It starts from shape-doctor.py pin_restore: a conflicted shape pin sends every copy to a hand merge, and a leg pin broken in its bump commit is restored to the old pin #547's own merge in tests/test_doctor_pin_restore_merges.py (both_pure):
    • update-shape.py apply --at C2 runs on shape/a, and --at C3 on shape/b.
    • shape/b merges shape/a, and Makefile and scripts/bootstrap.py are both conflicted beside the pin.
    • Then the KEPT side's pin is restaged without the Makefile's files: row. That is stage 2 of contracts/shape-pin.yaml, the side the NEXT's checkout --ours takes.
    • This is the mirror of test_a_copy_the_other_sides_pin_has_no_row_for_is_left_to_a_person (:676-699), which removes the row from the OTHER side.
  • What the doctor says (INVALID (merge), exit 1):
    • NEXT: git -C <root> checkout --ours -- contracts/shape-pin.yaml scripts/bootstrap.py.
    • detail.taken_with_the_pin is ["scripts/bootstrap.py"], and detail.left_for_a_person is ["project.yaml"].
    • The why names scripts/bootstrap.py (taken) and project.yaml (a person's merge). It never names the Makefile.
    • Only the merge row mentions it: 4 path(s) unmerged in the index ...: Makefile, contracts/shape-pin.yaml, project.yaml, scripts/bootstrap.py.
  • Why it matters. It is right that the Makefile is not taken, since nothing proves it unedited. But it is not named either, though the other side's pin calls it a copy and its conflict holds that side's apply output. R586's probe P3 found the same on main.
  • How a real flow reaches it: a path one side's standard pins while the other side keeps it as the project's own (an add/add), or a copy whose row the kept side's pin has lost.
  • What it costs. Nothing is lost. The reader is just told less than the doctor knows.

Where it is (main d4a7fab9), in shape-doctor.py:

The change:

  • Read both pins. Read both sides' pins (:2 and :3, where each holds one), and treat as copies the conflicted paths that EITHER pin has a row for.
  • Never take it, but name it. A copy the taken side's pin lacks is never taken (:3765 already refuses to prove it). It goes to left_for_a_person.
  • Say why in the why. The other side's pin calls it a copy and the side taken here does not, so once the merge is finished it is the project's own file. A person merges it, keeping the hunks git merged.
  • Say in the docstring which pin decides. Update the rule at :3395-3399 and :3438-3440, so the next reader does not take this for a contradiction of "a file of the project's own is never named".
  • The manifest kinds row follows. It prints the same NEXT and why, because it reaches the same helper.
  • Pinned shape copies: none. shape-doctor.py is not one.

Tests (tests/test_doctor_pin_restore_merges.py):

  • The mirror of :676-699: the kept side's pin is restaged without the Makefile's row.
    • The Makefile is in left_for_a_person and named in the why, and it is not in the NEXT.
    • scripts/bootstrap.py is still taken.
    • The shape currency and manifest kinds rows say the same.
  • :676-699 still passes unchanged.
  • The NEXT, run pasted, leaves the Makefile unmerged.

From #460, #460 (comment) (L11)

🤖 Generated with Claude Code

Activity

  1. added this to the v1.1.0 milestone on Oct 16, 2026
  2. brettheap commented on Oct 16, 2026

    @brettheap
    ContributorAuthor

    CLAIMED — lane openRepoShape-3, session b30e8b49-f249-4668-adb1-1dbfa93c09e1@Eagle, 2026-10-16T13:07:18Z, for #687

    Logged in lanes/log/openRepoShape-3.md at 0fad3338129107dd059d95164f94f300df6104b0.

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

    1. existing `CLAIMED —` comments on opensoft/openRepoShape#687:
       none
    2. `gh pr list --repo opensoft/openRepoShape --state all --search "#687"`, kept where the row or its body names `#687`:
       none
    3. `git ls-remote --heads git@github.com:opensoft/openRepoShape` branches naming `687` as a whole token:
       none
    
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