Skip to content

bump-leg.py --dry-run returns before rewrite_pin runs unless nothing moves, so a leg pin the validators accept and the rewrite refuses (digests: {tree_sha256: …}) gets a dry run that prints old -> new and exits 0, and a real run that exits 2 bump-leg-pin-unrecognised #438

Closed

Description

@brettheap

Lane: openreposhape-3 (openRepoShape-3)

What happens. Measured on main 45e01f4 with a freshly scaffolded project. A new commit was pushed to the spec leg's bare remote. contracts/spec-pin.yaml was committed with its digest as a flow mapping, digests: {tree_sha256: "<digest>"}, and the root was on the branch bump/spec:

scripts/validate-pins.py                                                         exit 0   pins ok
bump-leg.py --root <root> --leg spec --to <new> --local-remote-dir <remotes> --dry-run    exit 0
  commit       <old> -> <new>
  --dry-run: nothing was changed. ...
bump-leg.py --root <root> --leg spec --to <new> --local-remote-dir <remotes>              exit 2
  REFUSED bump-leg-pin-unrecognised: the pin file has 0 `tree_sha256` line(s) where exactly one was expected, so this tool will not rewrite it
  Every byte this command wrote has been rolled back — the pin, the workflow files, the leg's checkout and the index — and the tree is exactly as it was.

Control: the scaffold's layout gives exit 0 on the dry run and exit 0 on the real run, with a commit. Before #380, a digests: child indented four spaces behaved the same way: the #323 writer measured dry run 0 and real run 2 on main. #380 fixed that layout but not the asymmetry. Any refusal rewrite_pin raises (a count that is not one, or a read-back fault) reaches only the real run.

Where. scripts/bump-leg.py on 45e01f4, in cmd_bump (:1096):

  • rewrite_pin is evaluated only inside if was == commit and not plans and rewrite_pin(...) == pin_text (:1125);
  • --dry-run returns at :1133;
  • in a real run, rewrite_pin first runs inside _apply_rewrite (:1028), after the leg has been checked out at :1027.

rewrite_pin itself is at :211, with its refusals at :261 and :272.

Why it matters. AGENTS.md ("Advancing a leg", step 1) makes the dry run the thing the human reads and agrees to. The module's EXIT CODES say exit 0 means the dry run "printed a move it would make". rewrite_pin is a pure function of text that has already been read before the dry-run return, so calling it there writes nothing.

Direction: compute the rewrite once, before the dry-run return, and reuse it in _apply_rewrite. The dry run then refuses what the real run would refuse at that step.

Keep:

  • a dry run that writes nothing;
  • exit 1 "nothing to do", as it is;
  • the digest recomputed from the leg, never edited (AGENTS.md, rule 2).

Open PR #376 (#322) does not bear on this. Its only bump-leg.py change is in commit_once, which now computes the trailers before git add. It does not touch cmd_bump or rewrite_pin, and it merges clean with main.

Source.

Related: #323 (closed), #289, #383 and #423 (other cmd_bump reads before the dry-run return; a different defect).

Activity

  1. brettheap commented on Oct 12, 2026

    @brettheap
    ContributorAuthor

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

    Logged in lanes/log/openRepoShape-3.md at 8e0b3ecfe1a9165921398cd1a9fe5fdca07e8997.

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

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

    @brettheap
    ContributorAuthor

    RELEASED — lane openRepoShape-3, session 43f4ac63-0116-41de-977d-afc23cdf7fdf@Eagle, 2026-10-12T19:31:05Z, for #438

  3. brettheap commented on Oct 14, 2026

    @brettheap
    ContributorAuthor

    CLAIMED — lane openRepoShape-4, session 11c6c0ef-495a-4a05-94cf-811b7b0a1012@Eagle, 2026-10-14T17:52:32Z, for #438

    Logged in lanes/log/openRepoShape-4.md at 86b365c3e8287965fb14cfc4cd4177dd007e1733.

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

    1. existing `CLAIMED —` comments on opensoft/openRepoShape#438:
    6:CLAIMED — lane openRepoShape-3, session 43f4ac63-0116-41de-977d-afc23cdf7fdf@Eagle, 2026-10-12T17:58:05Z, for opensoft/openRepoShape#438
    13:1. existing `CLAIMED —` comments on opensoft/openRepoShape#438:
    26:RELEASED — lane openRepoShape-3, session 43f4ac63-0116-41de-977d-afc23cdf7fdf@Eagle, 2026-10-12T19:31:05Z, for opensoft/openRepoShape#438
    2. `gh pr list --repo opensoft/openRepoShape --state all --search "#438"`, kept where the row or its body names `#438`:
       none
    3. `git ls-remote --heads git@github.com:opensoft/openRepoShape` branches naming `438` 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

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions