Skip to content

update-shape.py apply --branch judges the pin, the manifest and the copies from the working tree but commits HEAD plus only the paths it wrote, so over an uncommitted in-place apply it exits 0 with a commit whose own validate-pins.py is red, dies on git's "nothing to commit", or says "nothing to do" and makes no branch #436

Closed

Description

@brettheap

Lane: openreposhape-3 (openRepoShape-3)

What happens. prepare reads the pin and classifies every copy from the WORKING TREE. _nothing_to_do decides from that reading, and so do the rows _write_copies writes. The validators also run over the working tree. The commit is git commit -- <paths> over only the copies this run wrote, plus the pin and the manifest. Over a tree that is HEAD's, those agree. #379 made the --pr re-run refuse when they do not (update-rerun-uncommitted). Every other path still mixes the two sources.

Measured on main 45e01f4. The project was scaffolded at A into local bare remotes. Upstream commits then changed scripts/validate-manifest.py (B), scripts/validate-pins.py (C) and Makefile (D) under templates/assembly-root/. "In place" means apply --at C --yes with no --branch, left uncommitted. It leaves M on the pin, project.yaml, validate-manifest.py and validate-pins.py.

(a) On main, in place at C, then a first --branch run at D:

apply --root <root> --upstream <upstream> --at <D> --yes --branch shape/d      exit 0
  copied   Makefile
  re-pinned contracts/shape-pin.yaml and project.yaml <C> -> <D>
  ok  contracts/shape-pin.yaml: 11 copied shape file(s) match their digests
  committed on shape/d: Makefile, contracts/shape-pin.yaml, project.yaml
git status --porcelain       M scripts/validate-manifest.py    M scripts/validate-pins.py
scripts/validate-pins.py in a clean worktree of shape/d:      exit 1
  FINDING shape-copy-drift: scripts/validate-pins.py: sha256 cc3484bf…  contracts/shape-pin.yaml records b05c27da…
  FINDING shape-copy-drift: scripts/validate-manifest.py: sha256 e15c4745…  contracts/shape-pin.yaml records cc513d09…

(a′) The same without --branch (in place at C, then in place at D). It prints NEXT git -C <root> checkout -b shape/update-<D> && git -C <root> commit -m 'Re-sync the shape @ <D>' -- Makefile contracts/shape-pin.yaml project.yaml. Run as printed, that line makes the same red commit.

(b) On shape/update, whose HEAD re-pins B (made by apply --at B --branch shape/update --push), in place at C, then back to B. The result is the same with and without --push --pr:

apply --root <root> --upstream <upstream> --at <B> --yes --branch shape/update [--push --pr]    exit 2
  copied   scripts/validate-pins.py
  re-pinned contracts/shape-pin.yaml and project.yaml <C> -> <B>
  ... pins ok / manifest ok
REFUSED committing the re-synced shape on shape/update. THE EXACT COMMAND WAS:
    git commit -q -F - -- contracts/shape-pin.yaml project.yaml scripts/validate-pins.py
nothing to commit, working tree clean
ROLLED BACK: ... restored scripts/validate-pins.py, contracts/shape-pin.yaml, project.yaml

(c) On main, in place at C, then a --branch run at C. The result is the same with and without --push --pr:

apply --root <root> --upstream <upstream> --at <C> --yes --branch shape/c [--push --pr]     exit 0
nothing to do: every copied file matches opensoft/openRepoShape @ <C>, which the pin already names

No shape/c branch is made, and nothing is committed or pushed. _awaits_its_pull_request answers False because --branch is not the current branch, so #379's check is never reached.

Where. On 45e01f4, in update-shape.py:

Why it matters.

  • (a) exits 0 and prints "match their digests" over a commit its own validator rejects, and it leaves two pinned copies modified. Pushed, that commit is a red pull request. AGENTS.md step 6 promises that apply rolls back when the validators go red.
  • (b) names git's "nothing to commit" as the failure where the tool could have named the state.
  • (c) silently skips a branch and pull request that were asked for, with exit 0.

Direction: decide from one source. When a commit will be made (--branch), compare the pin, the manifest and every pinned copy with HEAD before the first write, using #379's _not_what_head_commits. Refuse by name, as the re-run does, saying "commit them or put them back". That covers (a), (b) and (c). The alternative is to build the commit's pathspec from every pinned path that differs from HEAD, not only from what this run wrote. The branchless NEXT line needs the same answer.

Keep:

Source.

Related: #333 (closed by #379), #204, and #202 (closed; it noted that later runs "read those edits as the truth").

Activity

  1. brettheap commented on Oct 12, 2026

    @brettheap
    ContributorAuthor

    CLAIMED — lane openRepoShape-3, session 43f4ac63-0116-41de-977d-afc23cdf7fdf@Eagle, 2026-10-12T17:56:54Z, for #436

    Logged in lanes/log/openRepoShape-3.md at c4fd0f39a7818350bf629b9c3a8344fc3a1207a6.

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

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

    @brettheap
    ContributorAuthor

    (lane openRepoShape-3, 2026-10-12T18:56:22Z) Ruling, Brett Heap 2026-10-12, on this issue's direction: refuse by name. Before the first write, apply --branch compares the pin, the manifest and every pinned copy with HEAD (#379's comparison) and refuses, saying to commit those changes or put them back. It does not widen the commit to every path that differs.

  3. added this to the v1.0.0 milestone on Oct 12, 2026
  4. added a commit that references this issue on Oct 13, 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

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions