Skip to content

shape-doctor.py: the pins row says check's apply drops merged-away rows where check says REFUSAL AHEAD (a pinned copy kept as a link), and the shape currency counts leave out five of check's states #676

Closed

Description

@brettheap

Goal: the doctor's pins and shape currency rows say only what update-shape.py check says of the same root, and count every state check counts.

Filed by lane openRepoShape-5 on Brett Heap's word of 2026-10-16T12:17:02Z ("#458's update-shape/bump-leg (~22)"), from two lines on #458: 6158353941 (lane 4's known limits from #512's verification V512m). Lane 4 judged both OPEN on main 95780dd (#473 comment 6215386495); lane 5 re-measured both on main 879d804, with one root.

Lands after: nothing. shape-doctor.py is not a pinned copy, so no project re-pins. No open PR touches it.

The measured root (one adopted-style root, scaffolded with local bare remotes, both lines at once): the pin carries a row shape/Makefile with no file at that path while Makefile is at the root (a merged-away collision copy, #502), and .gitignore is a symlink to .gitignore.real holding the same bytes. validate-pins.py reports one finding, shape-copy-missing for shape/Makefile, and none for the link. The doctor then prints, in pins: ... shape/Makefile (merged into Makefile) is a collision copy the root merged away, so \update-shape.py check` reports it `merged-away`, and the `apply` it prints drops its pin row in the re-pin commit: the step the `shape currency` row names too. update-shape.py checkon the same root printsmerged-away 1 copy-is-link 1 unchanged 10, REFUSAL AHEAD: `apply` will refuse while these are unresolved — .gitignore, and a NEXT line whose apply, pasted, exits 2 update-rewrite-symlink`, writing nothing.

Lines (path:line at main 879d804)

  • The pins row keeps the gate as its NEXT only for a pin or a manifest kept as a link, not for a pinned copy kept as one. with_merged_away_rows (shape-doctor.py:2408-2464) asks us.linked_record(ctx.root, us.root_kind(ctx.root)) (:2446), which looks at contracts/shape-pin.yaml and the manifest only (update-shape.py:1209-1233). A pinned COPY kept as a link beside merged-away rows therefore gets the check NEXT and the clause above, though check calls that copy copy-is-link (a conflict) and its apply is refused. By reading, the same holds for an upstream-removed or an unmapped row beside merged-away ones (all three are in update-shape.CONFLICTS, :327); only the link was run. (Tracking: update-shape.py and bump-leg.py, keeping a project's shape copies and leg pins current #458's 6158353941, first line.)
  • The shape currency reason counts the five original states plus merged-away only. shape-doctor.py:4135-4140 fixes states = (UNCHANGED, UPSTREAM_CHANGED, LOCALLY_MODIFIED, BOTH, UPSTREAM_ADDED) and adds MERGED_AWAY when counted, while update-shape.ORDER (:328-331) also holds ALREADY_AT_TARGET, UPSTREAM_REMOVED, UNMAPPED, COPY_MISSING and COPY_IS_LINK. Measured on the root above: the row prints 10 unchanged / 0 upstream-changed / 0 locally-modified / 0 both / 0 upstream-added / 1 merged-away and names .gitignore, shape/Makefile, eleven rows counted and twelve present, where check prints merged-away 1 copy-is-link 1 unchanged 10. (Tracking: update-shape.py and bump-leg.py, keeping a project's shape copies and leg pins current #458's 6158353941, second line; pre-existing for those states.)

Direction

  • pins: ask check's own question: the rows us.prepare classifies (the shape currency row already calls it), and keep the gate as the NEXT, with the sentence about apply left out, when any row that is not merged-away is a conflict (row.is_conflict), naming it ("check will also say REFUSAL AHEAD over ..."). Or word the clause as conditional on check's verdict. Test with a link (pytest.mark.skipif where symlinks are off, as the file's neighbours).
  • shape currency: count every state in us.ORDER that is non-zero, keeping the five that print even at zero, so a root without these states reads byte-for-byte as it did and the tests that hold today's text stay green; detail["counts"] already carries them all.

Overlaps: none with open PRs; #634 and #639 do not touch shape-doctor.py, and lane 5's other branches do not either. Lane 3 is filing #460's shape-doctor lines into v1.1.0 issues (#473 comment); check them for a shared region before starting.

Mark each line → this issue on #458, and tick it there when this closes.

🤖 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:22:04Z, for #676

    Logged in lanes/log/openRepoShape-3.md at 2a85bf1c54266a64e7564b4255db9c4173919ace.

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

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