Skip to content

update-shape.py check's NEXT, and the doctor's shape currency row that sends the reader to it, already carry --accept-local <path> for every locally edited shape copy, so pasting the command AGENTS.md says to run as named re-pins the project's edit as the standard: no refusal, no question to the human, a green validate-pins.py and a COMPLIANT doctor, though AGENTS.md says never to pass --accept-local and that keeping the edit is the human's decision #501

Closed

Description

@brettheap

Lane: openreposhape-4 (openRepoShape-4)

(lane openRepoShape-4, 2026-10-12T23:17Z) Found by lane 4's v1.0.0 README/AGENTS.md audit (finding auU-02), re-verified on main 437a360. Lane 4 claims it.

What is wrong. AGENTS.md says two things about the same command line:

  • The doctor's step 3: "A FINDING names its fix, and you run THAT … Run the one the row names" (AGENTS.md:226-232).
  • The update procedure's step 3: "Never pass --accept-local to make a refusal go away. It re-pins a locally edited file FROM THE PROJECT'S OWN BYTES, which makes the drift validate-pins.py reports today invisible. Whether the project keeps its edit is the human's decision" (:284-288).

Other documents agree with the second. README says a locally-modified file "is named in a refusal unless the human passes --accept-local <path>" (README.md:1054-1058). Every project's own AGENTS-shape.md says "Never update a digest in place. That records this copy as the standard" (templates/assembly-root/AGENTS-shape.md:37-48).

When a project has edited a pinned copy locally, the doctor's row sends the reader to update-shape.py check. check's NEXT is apply … --yes --accept-local <path> --branch …. Pasted, it re-pins the edit. The update-local-drift refusal, which exists to put that question to the human, never fires, so the update step 3's "to make a refusal go away" never applies either. The commit it writes is titled Re-sync the shape copies to opensoft/openRepoShape @ <sha>.

(Not #485, which is about a conflicted merge's NEXT.)

Reproduction. Offline, on Linux. $U is a checkout of main 437a360; a gh that exits 97 stands first on PATH; GIT_ALLOW_PROTOCOL=file is set; git reads an empty global config; identities come from env.

  1. Scaffold Atlas with local remotes (scaffold-project.py --org Northwind --project Atlas --elected-by 'Dana Okafor' --local-remote-dir $R/remotes --work-dir $R/work). Clone it with --recurse-submodules, and run python3 scripts/bootstrap.py.
  2. Edit the pinned .gitignore (append secrets.env) and commit the edit. python3 scripts/validate-pins.py exits 1 with FINDING shape-copy-drift: .gitignore: ….
  3. python3 $U/shape-doctor.py --root $R/Atlas, exit 1:
      FINDING  shape currency   10 unchanged / 0 upstream-changed / 1 locally-modified / 0 both / 0 upstream-added (pinned 437a360a45da, this standard 437a360a45da): .gitignore
               NEXT             python3 <U>/update-shape.py check --root <R>/Atlas --upstream <U>   # then apply --at 437a360a45da26f0e9da0f023a0504cd336aa91e --yes --accept-local .gitignore --branch shape/update-437a360a45da
    DRIFTED (1 locally-modified)   (exit 1)
    
  4. That check, run from $U, exits 1. It reports locally-modified .gitignore and prints:
    NEXT  python3 update-shape.py apply --root <R>/Atlas --upstream <U> --at 437a360a45da26f0e9da0f023a0504cd336aa91e --yes --accept-local .gitignore --branch shape/update-437a360a45da
    
  5. The same apply without --accept-local, which is what the update step 3 means, exits 2:
    REFUSED update-local-drift: these files were edited in this project since the pin:
    …
    Remediation: revert each edit, or carry it upstream, or — having decided the project keeps it — re-run with --accept-local .gitignore
    
    That refusal is the human's question.
  6. Step 4's NEXT, pasted as printed, exits 0:
      kept     .gitignore (local bytes; row recomputed from them because --accept-local named it)
      committed on shape/update-437a360a45da: contracts/shape-pin.yaml, project.yaml
    
    On that branch, validate-pins.py says pins ok (exit 0), and the doctor says COMPLIANT (exit 0).

Why. At 437a360:

  • check pre-fills the flag. cmd_check collects every locally-modified row (update-shape.py:1688) and folds --accept-local <path> for each one into the NEXT it prints, beside --yes (:1705, :1713-1716).
  • The doctor does the same in the shape currency NEXT (shape-doctor.py:2508-2519).
  • The pre-filled flag skips the question. _refuse_local_drift (update-shape.py:2537-2555) is the refusal that asks it, and its remediation already offers --accept-local as one of three exits. The NEXT answers the question before it is asked.
  • A test pins this on purpose. test_an_edited_shape_copy_is_drift_and_names_update_shape asserts the hand-over (tests/test_shape_doctor.py:266-269): "a locally-modified row must hand over the exact flag that re-pins it, which is the one AGENTS.md says never to pass on your own initiative". The design expects the reader not to paste the flag, while AGENTS.md's doctor step 3 tells the reader to paste the row's command.

Proposed fix (for review on the PR). Options for Brett:

  1. The tools stop pre-filling the flag. check's NEXT and the doctor's comment leave out --accept-local for locally-modified rows. A paste then meets update-local-drift, whose remediation names the three exits: revert, carry upstream, or --accept-local on the human's word. check may still name the flag in the row's detail, as it does for both (update-shape.py:1567-1596), where the hand merge has to come first anyway. The test at tests/test_shape_doctor.py:266-269 changes to assert that the flag is absent from the NEXT and present in the refusal.
  2. Keep the NEXT and document the exception. AGENTS.md's doctor step 3 says that a NEXT carrying --accept-local is not run until the human has decided to keep that edit. This is docs only and would go to README.md and AGENTS.md: an accuracy pass for v1.0.0, every command, flag, exit code, refusal code and step they state checked against the tools on main, so the tag's "README and AGENTS.md accurate" criterion holds #483.
  3. The NEXT names the decision, not a command. For a locally-modified row it prints something like # locally-modified: revert it, carry it upstream, or, on the human's word, apply --accept-local <path>, and no runnable apply line until the row is resolved.

The --yes in the same NEXT raises the same question one level up: the update step 2 says "Do not pass --yes on your own initiative". The options above leave it as it is.

How to test.

  • tests/test_update_shape.py: with one edited copy, pasting check's NEXT as printed must not recompute that row from the local bytes. Under option 1 the paste exits 2 with update-local-drift; under option 3 there is no apply line to paste.
  • tests/test_shape_doctor.py: the shape currency NEXT for a locally-modified row matches the chosen option.
  • The both exit stays as it is: --accept-local after a committed hand merge, AGENTS.md:289-292.

Why v1.0.0. The tools' own next command quietly turns a drift finding into the standard, the one outcome the shape pin exists to prevent, and AGENTS.md tells an assistant to run that command. Proposed P1.

Parent: #458 (update-shape and bump-leg).

Related: #485 (a conflicted merge's NEXT, which drops an --accept-local edit), #483 (the docs pass).

Activity

  1. added this to the v1.0.0 milestone on Oct 12, 2026
  2. brettheap commented on Oct 12, 2026

    @brettheap
    ContributorAuthor

    CLAIMED — lane openRepoShape-4, session bf1c72df-1c56-4ac9-aace-3ddd139d7ea3@Eagle, 2026-10-12T23:33:20Z, for #501

    Logged in lanes/log/openRepoShape-4.md at 34cc0ae0b78f5058bf44316c44cc001356a8412b.

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

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