Repository navigation
tests: the bump-leg.py and family.py reachability rows tag a descendant of the commit --to names, so a tag above it reads as one that reaches it and a tag below it keeps the plain words, and --points-at for --contains no longer survives (#1019) - #1107
Conversation
… names, so a tag above it is told as one that reaches it and a tag below it keeps the plain words, and `--points-at` in place of `--contains` no longer survives (#1019) `_remote_tag_reaches` (bump-leg.py) and `_origin_tag_reaches` (family.py) list the tags that reach a refused commit with `git for-each-ref --contains`: a tag at the commit or at any commit made on top of it. Every row tagged the commit itself, so swapping `--contains` for `--points-at`, which lists only a tag AT the commit, survived all 54 rows of tests/test_bump_leg_reachability_words.py and tests/test_family_bump_reachability_words.py (mutant M9 of #988's review). Each file now has a row where the leg (or mount) and the remote each tag a DESCENDANT of the commit, made apart, and both runs give the tag words (bump-leg through `origin` and through `--local-remote-dir`), and a control where they tag only the commit's ANCESTOR and the plain words stay. No production code changes. Closes #1019 Lane: openreposhape-5 (openRepoShape-5) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Reviewer's GuideThis test-only PR closes the reachability coverage gap in bump-leg and family by modeling tags on descendants and ancestors of a local-only commit, validating correct refusal wording and state preservation across execution paths, and killing the surviving --points-at mutation. File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Independent review of #1107 (#1019) at Findings: no MUST, no SHOULD.
Checked and true
Could not verify
Checklist candidates
(Posted by lane openRepoShape-5's coordinator. rv1104-1107 is lane 5's independent opus reviewer; it wrote none of #1107. The PR stays a DRAFT until the v1.2.0 tag; its NITs are taken before it leaves draft.) Lane: openreposhape-5 (openRepoShape-5) |
--to names, so a tag above it is told as one that reaches it and a tag below it keeps the plain words, and --points-at in place of --contains no longer survives (#1019)--to names, so a tag above it reads as one that reaches it and a tag below it keeps the plain words, and --points-at in place of --contains no longer survives (#1019)
--to names, so a tag above it reads as one that reaches it and a tag below it keeps the plain words, and --points-at in place of --contains no longer survives (#1019)--to names, so a tag above it reads as one that reaches it and a tag below it keeps the plain words, and --points-at for --contains no longer survives (#1019)
…_words.py: the descendant rows' docstrings say no earlier row of their file tags a descendant, and no longer count "all 54" rows of both files (#1019) rv1107's NIT 2: "survived all 54 of them" counted the rows of the two files together (34 + 20), several of those rows tag nothing (the no-`origin` and prune rows), and the number goes stale with the next row. Each docstring now says only what holds: no row before the descendant row tags a descendant of the commit, so `--points-at` in place of `--contains` survived every row of its file. Docstrings only. Refs #1019 Lane: openreposhape-5 (openRepoShape-5) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
Re-check of #1107 (#1019) at Findings: one optional NIT. It does not need another round.
What changed and what I checked
Could not verify
(Posted by lane openRepoShape-5's coordinator. rv1104-1107 is lane 5's independent opus reviewer; it wrote none of #1107. The PR stays a DRAFT until the v1.2.0 tag.) Lane: openreposhape-5 (openRepoShape-5) |
|
Sorry @brettheap, you've used your own review budget of 250,000 diff characters for the last 7 days. You can request another review in 4 hours and 42 minutes by commenting |
…s message spells a path byte that is not UTF-8 as `_shown` does, an escape, and no longer says it names it with a `?` in its place, which #900 replaced (#1018) (#1104) `env_commit`'s docstring in `scripts/shape_materialize.py` says what the split commit's message does with a `root` or `drop` path that holds a byte that is not UTF-8, as the code does since #900. It said the message names such a path "with a `?` in place of that byte, a path that does not exist". That was true before #900, and it is not true now. A reader of the docstring is told about a `caf?.md` the tool no longer writes. Found by lane 1's writer on #900 and filed as #1018. Lane 5 took it outside v1.2.0, under Brett Heap's ruling of 2026-10-21T10:32:04Z. Measured on main `2a119f281` and again on `16f9a0e81` (main after #1087), with a small script that calls: `adopt-project.py`'s own `_split_message` and `_shown`, then `env_commit` and a real `git commit`, read back with `cat -A`. - The issue's claim held: the docstring (about line 2103 when filed, line 2268 on `2a119f281`, line 2349 on this branch) still said the message names the byte with a `?`. - The code does not. `_shown("caf\udce9.md")` is `` `caf\udce9.md` ``, and the split message for a `root` and a `drop` entry named that holds no lone surrogate. Through `env_commit` and `git cat-file commit HEAD`, `cat -A`: ``` DROPPED (in no leg and no longer here):$ `caf\udce9.md`$ STAYS IN THE ASSEMBLY ROOT:$ README.md$ `caf\udce9.md`$ ``` - What stays true of `env_commit` itself: a message that holds the lone surrogate, handed to it directly, is still written as `?`. `cat -A` reads `Name: caf?.md$`. So the `errors="replace"` paragraph is kept, and what changes is who it describes. - #1087 (main `16f9a0e81`) changed `scripts/shape_materialize.py` by 128 lines, none of them in `env_commit`, `COMMIT_COMMAND` or the message, and changed nothing in `adopt-project.py` (0 diff lines). The rebase onto it was clean and the docstring needed no other change. One file, `env_commit`'s docstring, in two paragraphs: the `errors="replace"` paragraph (round 1, 11 lines added and 7 removed) and the sentence above it (round 2, below; 3 added and 2 removed). Together 14 added and 9 removed against main `6da757cb`. The `errors="replace"` paragraph now says: - encoding, a character UTF-8 cannot carry is written as `?`, and nothing raises after both legs are pushed, as before; - `adopt-project.py` refuses a lone surrogate in a path it extracts (`entry_path_problem`), and a `root` or `drop` entry that holds one is listed in the split message but never raw: the message names each path as `plan`'s report does (`_shown`, #900), so the byte 0xE9 reads as an escape with no surrogate in it, `` `caf\\udce9.md` ``, the path the source holds; - written raw it would be a `?`, `caf?.md`, a path that does not exist, which is what `env_commit` still writes for a lone surrogate it is handed. The backslash is doubled in the source, as the neighbouring docstrings write `\\udcc3`. A single `\u` in a non-raw docstring would be an escape that makes a lone surrogate. Measured: the docstring holds no character from U+D800 to U+DFFF and holds the six characters `\udce9`. The longest docstring line is 78 characters. **The code is unchanged.** A script compares the AST of `scripts/shape_materialize.py` with every docstring blanked: the branch's file is identical to `origin/main`'s after the rebase onto `16f9a0e81` (round 1), and the merge of this head into `origin/main` `6da757cb` is identical to `6da757cb`'s file (round 2). **No pin moves.** `scripts/shape_materialize.py` is not a pinned copy. `COPIED_VERBATIM`, `COPIED_FROM_SHAPE`, `FAMILY_COPIED_VERBATIM` and `FAMILY_COPIED_FROM_SHAPE` do not list it, and `templates/assembly-root/scripts/validate-pins.py` says of it "which no project carries". So no `upstream-changed` row, no digest, no assembly copy and no `tests/test_pinned_copy_text.py` entry changes. **No other text pins these words.** Searched in `tests/`, `README.md`, `docs/`, `docs/handbook.html`, `AGENTS.md` and `templates/`: no test reads `env_commit`'s docstring (`__doc__`, `getdoc`), and none of them holds "in place of that byte" or "a path that does not exist" for this. The other places that name the `?` are about this function's behaviour or about history, and are still true: `_split_message`'s docstring says `caf\\udce9.md` "was `caf?.md`" (before #900), `_refused_by_policy` already says the message "lists it as `_shown` does (#900)", and `tests/test_adopt_spelled_names.py` quotes the message as it was on `c7a3ff16`. The `?` in `argv_text`, `trailer_line` and the commit-trailer text is about a `--trailer`, not the split message. No rows and no mutants: the change is a docstring, the code is the same AST, and no test pins the docstring. So there is no row to fail on main and nothing to mutate. All with `$Q/v110/run9.sh`, `EMAIL=service@opensoft.dev`, `GIT_SSH_COMMAND=false`, `GIT_CONFIG_GLOBAL=/dev/null`, the stub `gh`, a fake token, git 2.43.0 (`/usr/bin/git`). Two shards, run before the rebase, at the `2a119f281` base with this one-file change in the tree. Together they are every `tests/*.py` that names `shape_materialize` or `env_commit` (86 files, including `tests/test_adopt_spelled_names.py` and `tests/test_adopt_entry_paths.py`, which run `env_commit` and the #900 message) and `tests/test_agents_md_codes.py`: | run | files | result | |---|---|---| | shard A | 43 | 2873 passed, 4 skipped in 1707.51s, rc=0 | | shard B | 44 | 4611 passed, 31 skipped in 2462.01s, rc=0 | After the rebase onto `16f9a0e81`, on the committed head `e32b2703d733f6c60c1b2cba2d62d164d93d7b9a` (`dirty=0`): the trio, `tests/test_repo_hygiene.py`, `tests/test_agents_md_codes.py` and `tests/test_cli_reference.py`, **170 passed in 55.67s**, rc=0. The docstring-only change needed no new shards: the shards' counts are runs at the `2a119f281` base, and #1087 did not touch `env_commit`. Round 2, on the committed head `de89aa81b1533e32f1007f991aeae05cd915b36d` (`dirty=0`): the same trio, **170 passed in 61.77s**, rc=0. The round 2 commit is one docstring sentence, so it needed no new shards either. git 2.47.1: no run. The change adds no test file of its own, so there is none to run on it. `git merge-tree --write-tree HEAD <other>` with HEAD at `de89aa81b1533e32f1007f991aeae05cd915b36d`, after a re-fetch of `origin main` with `-c gc.auto=0 -c maintenance.auto=false` (round 2, about 14:03Z on 2026-10-21): | against | result | |---|---| | `origin/main` `6da757cbe9a4eb66d60c34f38dcc2b332d175e8b` | clean, rc 0, tree `15c11b6c959fc4c7540105d5d62e3f961c8e27fd` | | #1105 `fix/1048-makefile-follow-up-gnu-read-order` `5a4de7f763b5a3c32adce9614a3a539508416eb4`, an open PR that touches `scripts/shape_materialize.py` | clean, rc 0, tree `db05aead67052643942e35a9689d9dd4a0873fda` | | #1118 `fix/1089-named-link-skip-tests` `c60066cbeec18b8b6c926e254ed4bee6b9a486c2`, the other open PR that touches `scripts/shape_materialize.py` | clean, rc 0, tree `a40df3b63c32c2a3d8f4c40587b094940c8d6567` | Read with `gh pr list --state open --json number,headRefName,headRefOid,files`: 16 open PRs, three of them (this one, #1105 and #1118) touch `scripts/shape_materialize.py`, the only file this change touches. The other 13 (#1120, #1119, #1117, #1111, #1109, #1107, #1106, #1102, #1101, #1098, #1097, #1091, #1088) touch no file this change touches. The same command with HEAD at the reviewed head `e32b2703` gives rv1104's trees: `de31d857` against `6da757cb` and `195ffe19` against #1105. The round 1 merge against #1090 is moot: #1090 has landed in `6da757cb`. Held as a draft until the v1.2.0 tag; it is now on the v1.2.1 milestone. - **NIT 1, `scripts/shape_materialize.py` lines 2340-2343, a line round 1 did not change.** The paragraph above the reworded one said the adoption's split message "names each entry path as the source spells it". Since #900 that is true of a printable path alone: `_split_message` lists any other through `_shown`, as the escape the next paragraph describes. It now says "as the source spells it (a printable one; see below)". One new commit on top of `e32b2703`, `de89aa81b1533e32f1007f991aeae05cd915b36d`, 3 lines added and 2 removed, docstring only, pushed as a fast-forward (no rebase, the PR is open). - Measured: the AST with docstrings blanked is identical to `e32b2703`'s and, merged into `6da757cb`, to `6da757cb`'s. The docstring holds no lone surrogate, still holds the six characters `\udce9`, and its longest line is 78 characters. - Searched `tests/`, `README.md`, `docs/`, the handbook mirror, `AGENTS.md`, `templates/` and the scripts for "names each entry path", "as the source spells" and the new words: only `tests/test_adopt_entry_paths.py` line 233 matches, a test's docstring about `execute` handing each path on as the source spells it, which is another sentence and pins nothing here. - **NIT 2, this body.** It named main as `16f9a0e81` and #1090 as the one open PR that touches the file. #1090 has landed. Main is `6da757cb`, and the merge-trees above are redone against it, against #1105 and against #1118, a draft that opened since and also touches the file. Review: rv1104-1107, lane 5's independent opus reviewer, which wrote none of #1104: READY at `de89aa81`, H0 of this landing (issuecomment-6318111413), with no finding; NIT 1 and NIT 2 of the round before are fixed. CI (Brett Heap's ruling 27 and his fast-refresh ruling of 2026-10-15T22:48:35Z): H0 de89aa8 passed tests, tests-git-bash and SonarCloud; the head 92285d4 is a clean update-branch merge of main b66d8f0, with tests-git-bash and SonarCloud green; and the local gate passed on its predicted squash tree 6bd2128 over main b66d8f0: the repo_hygiene, agents_md_codes, cli_reference sets, 171 passed. Landed on Brett Heap's word of 2026-10-23T13:10:26Z, relayed to every lane by lane 3 (#473 issuecomment-6365697123): "merge v1.2.1 PRs once reviewed and green". Closes #1018 Lane: openreposhape-5 (openRepoShape-5) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r through a tag it lacks, is told so, a tag of a tree or a blob it lacks is refused by name, and rows hold `YAML_NOT_TEXT_RE`'s exponents of two digits (#1103) (#1131) The three things rv1090's review of #1090 (#912) left (#1090 issuecomment-6316009648): a row that holds `YAML_NOT_TEXT_RE`'s exponents of two or more digits, a true refusal where a leg with no `origin` holds a tag without its commit, and no `else` that nothing reaches. This is #1103. Brett Heap's ruling of 2026-10-21T10:32:04Z held it until the v1.2.0 tag, and it is now on the v1.2.1 milestone. Three commits: `9d14c29a` on main `6da757cb`, a merge of main `038dafba` (clean), and fix round 1 `a4beec9e`, which answers rv1131's review (#1131 issuecomment-6321276436, READY with two NITs): see `## Fix round 1`. Together they change `scripts/bump-leg.py`, `tests/test_neutral_pin_entry_one_spelling.py` and `tests/test_bump_leg_reachability_words.py`. The sections down to `## Runs` are the first commit's, as rv1131 reviewed them. Each claim was measured on main `6da757cb` by name; the issue's lines are at `d5389eb6`. All three held, at the same names. - **The SHOULD held.** `YAML_NOT_TEXT_RE` (`scripts/shape_materialize.py:538-543`) has two exponent groups, `(?:[eE][-+][0-9]+)?` and `(?:[eE][-+]?[0-9]+)?`, and every exponent in `YAML_FLOATS` (`tests/test_neutral_pin_entry_one_spelling.py:92`) has one digit. - rv1090's R2 changes `[0-9]+` to `[0-9]` in both groups. - Applied to main, R2 passes all 208 rows of the spelling file, `test_scaffold_pin_and_reuse.py` and `test_adopt_pins.py` that `-k "spell or entry or name or rule or stock or every"` selects. - The head before this change quotes `.5e-10`, `.5E+10`, `.5_e-10`, `.5e10` and `.05E-12` correctly, so this is a missing row, not a defect. - **NIT 1 held.** `_unreachable_refusal` (`scripts/bump-leg.py:1239`) was called by the probe on a leg that holds the tag `v1`'s object but not its commit. - With `has_origin=False` and either `fetched`, it said `bump-leg-commit-not-on-remote: <tag> is not in the leg's own object store, and the leg's mount, <leg>, has no remote named `origin` to fetch it from, ...`. That is untrue: `cat-file -t` says `tag`. - With `has_origin=True` it said `opensoft/openGlass has no branch containing <tag>`, which is true. - **NIT 2 held.** A line trace of `peeled_target` (`scripts/bump-leg.py:979`) ran over a commit, a tag, a tag of a tag, a tree, a blob, a tag of either, a tag and a tag of a tag held without their commit, and an id the leg lacks. - `names a {kind}` was reached by the tree and the blob, and `is an annotated tag of a {names}` by the tag of a tree and the tag of a blob. - `else: what = "is an annotated tag that names no commit"` was reached by nothing. - **`YAML_FLOATS`** gains `.5e-10`, `.5E+10`, `.5_e-10` and `.5e10`, as the issue asks. - It also gains `.5.5e-10`. All four of those reach the second pattern (`\.[0-9_]+`), so a cut to the first group's exponent alone still passed them. Only the first pattern, YAML 1.1's as written, takes `.5.5e-10`. Each group is now held on its own (R2a and R2b below). - The list's comment no longer says `--pin` admits every name in it: `.e+5`, `.5e+3` and `.5E+10` hold a `+`, which `PIN_ARG_RE` refuses, so it says a plain scalar can spell them. - Each new name runs through the two rows that take `YAML_FLOATS`: double-quoted and read back, and double-quoted by the rule alone. That is 10 new rows. - **`_unreachable_refusal`**: where the leg has no `origin` and `object_kind(id)` is `tag`, the refusal keeps its code, `bump-leg-commit-not-on-remote`. Its words are now: - `<tag> is an annotated tag the leg's own object store holds without the commit it names, and the leg's mount, <leg>, has no remote named `origin` to fetch that commit from, so whether a branch of <repository> reaches it is not known` - `Remediation: check the tag -- the commit it names belongs to the LEG, not to the assembly root -- and push that commit to a branch of the leg first if it is not pushed yet; give <leg> back a remote named `origin`, ...` (an em dash in the tool, as in the words beside it). - An id the leg does not hold keeps its words, and so does every case with an `origin`. - Fix round 1 gives two rarer held tags this branch caught their own true words: a tag through a tag the leg lacks, and a tag of a tree or a blob. - No other text pins the old sentence. `grep` of `tests/`, `README.md`, `docs/`, the handbook and `AGENTS.md` finds it only in `bump-leg.py`, and `AGENTS.md`'s codes table is unchanged. - **`peeled_target`**: the three-way `if`/`elif`/`else` is now one expression: `is an annotated tag of a {names}` for a tag, `names a {kind}` otherwise, with a comment saying why nothing else is left. The words for a tree, a blob and a tag of either are unchanged, by the same trace on the head. `shape_materialize.not_a_commit`, which `commit_on_forge` uses, still says "an annotated tag that names no commit"; it is not touched. - `tests/test_bump_leg_reachability_words.py`, `test_a_tag_a_leg_with_no_origin_holds_alone_is_told_it_is_held`. - The setup: a tag of a commit pushed nowhere is made in a clone of the leg's remote, and only the tag object goes into the leg (`git hash-object -t tag -w`). The leg's `origin` is renamed to `upstream`, then both runs go through `assert_one_refusal`. - It asserts the note and the two lines exactly, through `told_no_origin`, and that the old sentence is not in stderr. - It reuses the file's `private_remote`, `without_origin`, `runner` and `origin_back`. - **On main's code** (the two test files copied onto `6da757cb`, git 2.43): 1 failed, 159 passed. The one failure is that row, which got main's `REFUSED bump-leg-commit-not-on-remote: <tag> is not in the leg's own object store`. - The 10 float rows pass on main, as they should, because main's rule is right. They are there to kill R2, below. - No assert joins conditions with `and` or `or`. Each mutant was applied alone to a scratch clone holding this commit's files, then restored and compared with the worktree. | Mutant | Rows run | Result | | --- | --- | --- | | R2: `[0-9]+` to `[0-9]` in both exponent groups | the spelling file | killed: 10 failed, 115 passed (all 10 new rows) | | R2 on main's rows | the 208 rows above | survives: 208 passed | | R2a: the first group only | the spelling file | killed: 2 failed (`.5.5e-10`, both rows) | | R2b: the second group only | the spelling file | killed: 4 failed (`.5_e-10` and `.5e10`, both rows) | | N1: the held-tag branch removed, so the old words answer | `-k "no_origin or held"` in the reachability file | killed: 1 failed, 3 passed | All runs go through lane 5's `run9.sh`: a stub `gh` first on PATH, a bogus token, every `LANES_*` variable cleared, `EMAIL=service@opensoft.dev`, `GIT_SSH_COMMAND=false` and `GIT_CONFIG_GLOBAL=/dev/null`. - **The two changed test files on the head:** - git 2.43: 160 passed; - git 2.47.1 (a git 2.47.1 build first on PATH; `git --version` printed `git version 2.47.1`): 160 passed. - **git 2.43, every test file that runs `bump-leg.py`.** The commit changes production code in `scripts/bump-leg.py` only. `scripts/shape_materialize.py` is unchanged: only its test rows were added, and those ran on both gits above. So the related-file runs take the test files that name `bump-leg` or `bump_leg`, and the files that name only `shape_materialize` are not needed. - The set is `grep -rl -E 'bump-leg|bump_leg' tests --include='*.py'`: 56 files, sorted and split into two halves. It holds `tests/test_bump_leg_reachability_words.py` again, and `tests/test_repo_hygiene.py` and `tests/test_agents_md_codes.py`. - shard a, 28 files: 1038 passed, 1 skipped, 0 failed; - shard b, 28 files: 2324 passed, 1 skipped, 0 failed; - together 3362 passed, 2 skipped, 0 failed. Both skips are rows for another host: one needs a disk that ignores case (macOS, Windows), in `tests/test_bump_leg.py`, and one is Windows' own stdout default, in `tests/test_stdout_encoding.py`. - **git 2.43, the trio** `tests/test_repo_hygiene.py`, `tests/test_agents_md_codes.py` and `tests/test_cli_reference.py`: 170 passed. Commit `a4beec9e`, on the merge of main `038dafba` into the branch (`ae830e2b`, clean, tree `10c2372fe578`). It answers rv1131's review (#1131 issuecomment-6321276436). ### What changed - **NIT 1: the no-`origin` words for a held tag were untrue in two rarer cases.** The branch keyed on `object_kind(id) == "tag"` alone, so every held tag `peeled_target` cannot peel was told the leg holds it "without the commit it names". Each case now reads the tag chain from the tags' own headers, `git cat-file tag`'s `type` and `object` lines, one tag at a time while the leg holds the next (`tag_chain_end`, new). The peel (`<id>^{}`) says nothing where the leg lacks an object on the way. - **(a) A tag through a tag the leg lacks**, with the commit at the end held or not: still `bump-leg-commit-not-on-remote`, now in these words: - `<tag> is an annotated tag the leg's own object store holds without a tag it leads through, <inner tag>, and the leg's mount, <leg>, has no remote named `origin` to fetch that tag from, so what that tag names, and whether a branch of <repository> reaches it, are not known` - `Remediation: check the tag -- the tags it leads through, and what they name, belong to the LEG, not to the assembly root -- and push them to the leg first if they are not pushed yet, and any commit they name to a branch of it; give <leg> back a remote named `origin`, ...` (an em dash in the tool, as in the words beside it). - **(b) A tag, or a tag of a tag, of a tree or a blob the leg lacks** names no commit, so `peeled_target` now refuses it `bump-leg-target-not-a-commit`, in the words a tag of a held tree or blob already had: `--to <tag> is an annotated tag of a tree in the leg (<repository>), not a commit`. That is with or without an `origin`, since no fetch makes a tree a commit. - Measured first: for the same tag with its tree or blob held, main and `9d14c29a` both refuse it `bump-leg-target-not-a-commit` in those words. The new refusal is byte for byte the same as main's for the same tag id held with its tree or blob, in all 6 (leg, id) pairs of (b) below. - With an `origin`, such a tag was refused `bump-leg-commit-not-on-remote`, "<repository> has no branch containing <tag>", with "check the commit". That is the one with-`origin` answer this round changes. - **The issue's own case is as it was:** a tag held without its commit, and a tag of a tag with both tags held, keep the head's words, byte for byte. - Neither code is added or removed. Neither code, nor any changed sentence, appears in `README.md`, `docs/`, the handbook or `AGENTS.md`; `tests/test_agents_md_codes.py` and `tests/test_cli_reference.py` pass. - `peeled_target` and `_unreachable_refusal` keep their docstrings' accounts true: the #912 paragraph now says a tag held without THE COMMIT it names, and each function says what (a) and (b) are now told. - A cycle of tags made with `refs/replace/` is never walked: git's own peel never leaves one (measured, git 2.43: `rev-parse <tag>^{}` was still running at a 10 s timeout), and the walk is reached only where the peel failed. - **NIT 2: mutant M5 survived.** `.5.5E-10` is added to `YAML_FLOATS`: only the first exponent group takes it, and only with its `E`. The list's comment says so. ### Words compared with main's and the head's tool The probe called `peeled_target` and `_unreachable_refusal` from main `038dafba`, the head `9d14c29a` and this head on 15 legs x 10 ids x 4 `(has_origin, fetched)`, as rv1131's did, with legs for (a) and (b) added. Each id was asked as typed (`raw`) and, where `peeled_target` returned, as it returned (`flow`). That is 1578 answers from main and the head, and 1554 from this head, where 6 (leg, id) pairs are refused before the verdict. | Pair | The same | Differ | | --- | --- | --- | | `9d14c29a` vs this head | 1532 of 1578 | 46: (a) 16, (b) 30, and nothing else | | main vs this head | 1492 of 1578 | 86: those 46, the issue's case (12) and 28 `raw` asks | - **(a):** 4 legs, `has_origin=False` only. Each holds the outer tag without the inner one: a tag of a tag of a commit, with the commit or without it, and a tag of a tag of a tree, with the tree or without it. - **(b):** 6 (leg, id) pairs, `peeled_target` and the four verdicts each: a tag of a tree and a tag of a blob, each alone and under a held tag of it, and those two tags of a tag, all held without the tree or blob. - **The 28 `raw` asks** ask `_unreachable_refusal` directly about a held tag of a tree or blob, which the flow never does: `peeled_target` refuses it first, with the tree or blob held or not. They keep the head's words. - **Every other answer**, every id with an `origin` but (b)'s, every missing id and every held commit keeps main's words. ### Rows, failing on `9d14c29a` and on main In `tests/test_bump_leg_reachability_words.py`, in the file's style, through `assert_one_refusal` (both runs, exit 2, the same words, nothing written). They reuse `private_remote`, `without_origin`, `runner`, `told_no_origin`, `refusal` and `origin_back`. Two helpers, `pushed_nowhere` and `written_into_the_leg`, are split out of `held_without_its_commit`, which keeps what it did. - `test_a_tag_through_a_tag_the_leg_lacks_is_told_which_tag_it_lacks[commit-held, commit-missing]`: (a). The leg holds only the outer tag; the commit is the leg's own pin, or one pushed nowhere. The note and the two lines are asserted exactly, and "without the commit it names" is not in stderr. - `test_a_tag_of_a_tree_or_a_blob_the_leg_lacks_is_refused_by_name[...]`: (b), 6 rows. The kinds are a tag of a tree, a tag of a blob, and a tag of a tag of a tree with both tags held. Each runs with the leg's `origin` and without it. The tree and the blob are pushed nowhere, so no fetch brings them, and the row checks that afterwards. The two lines are asserted exactly, with the note where there is no `origin`. - **On `9d14c29a`'s `bump-leg.py`:** 8 failed, 59 passed (git 2.43; the rows of `tests/test_bump_leg_reachability_words.py` and `tests/test_bump_leg_dry_run_truth.py`). The 8 are exactly the 8 new rows: the 2 of (a) and the 6 of (b). The old file was put back by sha256 afterwards. - **On main `038dafba`'s `bump-leg.py`:** 9 failed, 58 passed (the same two files, git 2.43). The 9 are those 8 and the issue's row, `test_a_tag_a_leg_with_no_origin_holds_alone_is_told_it_is_held`. The old file was put back by sha256 afterwards. - **`.5.5E-10`** adds 2 rows, one to each test that takes `YAML_FLOATS`. They pass on main and on the head, as they should: the rule is right, and they are there to kill M5. - No assert joins conditions with `and` or `or`. Added lines are at most 79 characters wide. The only non-ASCII character is the em dash in the tool's own words. ### Mutants Each was applied alone in the worktree, at this commit. Its rows were run, then the file was restored and checked against the commit by sha256. For `bump-leg.py` the rows are `tests/test_bump_leg_reachability_words.py` and `tests/test_bump_leg_dry_run_truth.py`; for `shape_materialize.py`, the spelling file. | Mutant | Result | Rows that failed | | --- | --- | --- | | M5: `shape_materialize.py`, the first exponent group's `[eE]` cut to `[e]` | killed: 2 failed, 125 passed | `.5.5E-10`, in `test_a_name_yaml_takes_for_no_text_is_double_quoted` and `test_the_rule_quotes_it_whatever_the_projects_reader_reads` | | NM1: `names = names or tag_chain_end(submodule, target)[0]` cut to `names = names`, so the header is never read where the peel says nothing | killed: 6 failed, 61 passed | the 6 rows of (b) | | NM2: the walk's `tag = named` step replaced by a second `return`, so the chain is never followed past its first tag | killed: 2 failed, 65 passed | the 2 `tag of a tag of a tree` rows of (b) | | NM3: (a)'s branch made dead, `if names == "tag":` to `"tags"` | killed: 2 failed, 65 passed | the 2 rows of (a) | | NM4: a blob not refused, `("tree", "blob")` to `("tree",)` | killed: 4 failed, 63 passed | the 2 `tag of a blob` rows of (b), and `tag of a blob` for `local-remote-dir` and `origin` in `test_a_tree_a_blob_or_a_tag_of_either_is_refused_by_name_in_both_runs` | | NM5: (a)'s note names the outer tag, `{named}` to `{commit}` | killed: 2 failed, 65 passed | the 2 rows of (a) | | NM6: the held-tag words given with an `origin` too, `not has_origin and` cut | killed: 2 failed, 65 passed | `test_a_tag_the_leg_holds_without_its_commit_is_not_on_the_remote`, for `local-remote-dir` and `origin` | | NM7: the header key read is `tag`, not `type` | killed: 8 failed, 59 passed | the 8 new rows | No mutant survived. After each, `scripts/shape_materialize.py` and `scripts/bump-leg.py` were restored from the commit and their sha256 checked: `a37e3d83fbcda475...` and `d6822093b1aa4b0e...` both matched, with the worktree clean. ### Runs All go through lane 5's `run9.sh`, as above, at `a4beec9e`. - **The two changed test files** (`tests/test_neutral_pin_entry_one_spelling.py` and `tests/test_bump_leg_reachability_words.py`): 170 passed, which is the first commit's 160 and this round's 10 new rows. - git 2.43: 170 passed; - git 2.47.1 (a git 2.47.1 build first on PATH; `git --version` printed `git version 2.47.1`): 170 passed. - **git 2.43, the path guard and the trio**: `tests/test_path_guard_hygiene.py`, `tests/test_repo_hygiene.py`, `tests/test_agents_md_codes.py` and `tests/test_cli_reference.py`: 219 passed. - **git 2.43, every test file that runs `bump-leg.py`**, picked as above (`grep -rl -E 'bump-leg|bump_leg' tests --include='*.py'`): 57 files, which are the 56 files of the first commit's set and `tests/test_path_guard_hygiene.py`, which main gained since. Sorted and split in two: - shard a, 29 files: 1094 passed, 1 skipped, 0 failed; - shard b, 28 files: 2325 passed, 1 skipped, 0 failed; - together 3419 passed, 2 skipped, 0 failed. The two skips are the same two rows for another host as before: `tests/test_bump_leg.py` (a disk that ignores case) and `tests/test_stdout_encoding.py` (Windows' own stdout default). - Every run in this section was on `a4beec9e` itself, committed, with the worktree clean (`dirty=0` in each log's START line). Refreshed for fix round 1 (rv1131's body NIT). `git merge-tree --write-tree` of the head `a4beec9e` was run against origin/main, re-fetched (`-c gc.auto=0 -c maintenance.auto=false`), and against each open PR that touches these files: | Against | Head | Result | | --- | --- | --- | | origin/main, re-fetched at 15:16Z on 2026-10-22 | `038dafba9dbe` | clean, tree `f571322318b1`, the head's own tree: the head holds main by its merge | | #1107 `fix/1019-points-at-row` (DRAFT) | `ee48b5fe9693` | clean, tree `7383abd73770` | | #1157 `fix/1100-refspec-followups` (DRAFT) | `a35a97ea52f4` | clean, tree `de32065b7371` | - #1107 touches `tests/test_bump_leg_reachability_words.py`. It gives `made_in_the_leg` an optional `on=` and adds rows after `test_a_tag_of_a_tag_the_two_share_reaches_it`. - The rows here call neither `made_in_the_leg` nor anything #1107 changes. The merged file parses, and no name in it is defined twice. - #1157 touches `scripts/bump-leg.py`, `scripts/shape_materialize.py` and two refspec test files, so it shares only `scripts/bump-leg.py` with this PR. - Its two hunks there are inside `_leg_fetch_refspecs`, at lines 1109 to 1146 of main's file. This PR's hunks in that file are at main's lines 976 to 1043 (`tag_chain_end`, new, and `peeled_target`) and 1250 to 1289 (`_unreachable_refusal`), so the two do not meet and the merge is clean. - None of the other 34 of the 37 open PRs touches these three files. - The branch is no longer behind main: the merge `ae830e2b` brought in every file main gained since `6da757cb` (among them #1111's `tests/test_path_guard_hygiene.py`). None of them is one of these three files, and the runs above stand on the head's own tree. rc1131 re-checked fix round 1 at `a4beec9e` and found it READY with four NITs (#1131, issuecomment-6347256815). The commit `55c30f20f005` mends the first three, in `scripts/bump-leg.py` and `tests/test_bump_leg_reachability_words.py`. NIT 4, the title, is not in a commit. Nothing the tool does changes: the production edit is a comprehension that gives the same dict and a longer docstring. ### What changed - **NIT 1, SonarCloud python:S7494 at `bump-leg.py:999`.** In `tag_chain_end`, `dict(line.split(" ", 1) for line in lines if " " in line)` is now `{key: value for key, sep, value in (line.partition(" ") for line in lines) if sep}`, the form rc1131 gave. - **Same dict:** `tools/equiv2.py` compares the two on every list of up to two lines of up to five characters, and every list of up to three lines of up to three characters, over `a`, `b`, a space and a tab (2478716 distinct lists: the script runs the two ranges one after the other, and the 7311 lists of up to two lines of up to three characters sit in both, so it makes 2486027 comparisons, as rc1131's count of the union shows), and on a real tag header with a continuation line, a line with no space and a `type ` line with a trailing space: equal in all. The commit message says "every list of up to three lines"; the coverage is the one in this sentence (`equiv.py`'s first pass, 3864591 lists, drew its three-line lists from a prefix of the strings). - **The rule:** SonarQube's local analysis of a standalone file holding both forms (project `opensoft_openRepoShape`, python, MAIN) reports one issue, python:S7494 MINOR, at the line of the old `dict(...)` form, and none at the comprehension. - **SonarCloud's own analysis, read through the SonarQube API** (rc1131's reading, issuecomment-6352247887, posted 2026-10-22T22:00:11Z; lane 5 read the same two answers again between 12:05Z and 12:08Z on 2026-10-23): for PR 1131 the API lists exactly one issue, python:S7494 at `scripts/bump-leg.py:999` (MINOR, created 2026-10-22T13:31:04Z), and its status is CLOSED, so there are 0 open issues. The quality gate is OK on all five conditions (new reliability, security and maintainability ratings 1, new duplicated lines density 0.0, new security hotspots reviewed 100.0). The API gives no commit, so it does not say which analysis it read: it shows the issue closed, not that the analysis was of `55c30f20`. - **NIT 2, the walk of two headers.** `TAGS_OF_NO_COMMIT` has a fourth kind, `tag of a tag of a tag of a tree`: three tags, all held, and the tree pushed nowhere, run with and without an `origin` like the other kinds. Its values are now `(what, depth)`, and the row makes `depth - 1` tags over the first one (`outer1-w1131`, `outer2-w1131`) where it made the one `outer-w1131` for the second kind; no other row reads the dict. - **NIT 3, `tag_chain_end`'s docstring.** It now says `("tag", <id>)` is also what it returns "through a tag whose header misstates what it names (`type tag` over an `<id>` the leg holds as something else, which only a malformed tag has)". ### Rows, failing on main Both rows of the new kind (`test_a_tag_of_a_tree_or_a_blob_the_leg_lacks_is_refused_by_name[tag of a tag of a tag of a tree-origin]` and `[...-no-origin]`) fail on main's `bump-leg.py` (`961640c6`) and pass on the head's before this commit (`a4beec9e`'s). The two test files that hold rows for `peeled_target` (`tests/test_bump_leg_reachability_words.py` and `tests/test_bump_leg_dry_run_truth.py`) run 69 rows: | `bump-leg.py` from | Result | Failing rows | | --- | --- | --- | | main `961640c6` | 11 failed, 58 passed | the 9 rows of fix round 1, and the 2 new rows | | `a4beec9e` (this PR before the commit) | 69 passed | none: the new rows hold on the code as it was | | `55c30f20` | 69 passed | none | With main's file the new rows fail on the code of the refusal, as the other rows of the kind do: the row expects `REFUSED bump-leg-target-not-a-commit`, and the run with an `origin` prints `bump-leg-commit-not-on-remote: testorg/Atlas-spec has no branch containing <the tag>` (main's `peeled_target` returns the tag as typed where its peel cannot be read, because the leg lacks the tree, and the run goes on to the reachability verdict), and the run without one prints the `git fetch origin ... has no remote named origin` note and goes the same way. ### Mutants Each was applied alone to `scripts/bump-leg.py`, the 69 rows run on git 2.43.0, and the file restored from `HEAD`; all 11 restores matched (`bl=1a7a69d38f737dce`, `dirty=0`). The mutants are in `tools/mutate.py`. | Mutant | Result | Rows that failed | | --- | --- | --- | | NX1 (rc1131's): the walk reads at most two headers, `while True:` as `for _ in range(2):` | **killed**: 2 failed, 67 passed | the 2 rows of the new kind: the walk stops at `tag`, and the refusal is `bump-leg-commit-not-on-remote`, not `bump-leg-target-not-a-commit` | | NX0: the walk reads one header | killed: 4 failed | the 2 rows of the third kind and the 2 of the new one | | NM2 (fix round 1's): `tag = named` replaced by a return | killed: 4 failed | the same 4 rows | | NX2 (rc1131's): no check that the leg holds the next tag | killed: 2 failed | the 2 rows of `test_a_tag_through_a_tag_the_leg_lacks_is_told_which_tag_it_lacks` | | C3: the comprehension's `key: value` as `value: key` | killed: 10 failed | the rows that read a tag's header | | C6: the comprehension keeps the lines with no space (`if not sep`) | killed: 10 failed | the same 10 rows | | NX3: the walk reads at most three headers | **survives**: 69 passed | none | | C1: the `if sep` filter dropped | survives: 69 passed | none | | C2: `rpartition` for `partition` | survives: 69 passed | none | - **NX3 survives by construction.** A walk bounded at three headers gives the code's answer on every chain of up to three tags, and the longest chain the rows hold is three. Any bound survives a chain of that length, so a row of four tags would only move the survivor to a bound of four. NX1 is the mutant the review named, and it is killed. - **C1 and C2 are equivalent for every header git writes.** The `type` and `object` lines each carry exactly one space and each appears once, and nothing reads another key. C1 keeps a line with no space as a key with an empty value, which `.get("type", "")` and `.get("object", "")` already say of a missing key. C2 splits at the last space, which for a line with one space is the first. Where they could differ is a hand-forged header that repeats a bare `type` line after `type tag`; no row forges one. ### Runs Every run went through `run9.sh` with `EMAIL=service@opensoft.dev`, on `55c30f20` itself, committed, with the worktree clean (`dirty=0` in each log's START line). Logs are in `$Q/v124/n1131/`, where `$Q` is the lane's scratchpad. | Run | git | Result | | --- | --- | --- | | `tests/test_bump_leg_reachability_words.py`, `tests/test_neutral_pin_entry_one_spelling.py`, `tests/test_bump_leg_dry_run_truth.py`, `tests/test_path_guard_hygiene.py`, `tests/test_agents_md_codes.py`, `tests/test_cli_reference.py`, `tests/test_pinned_copy_text.py` (`g243.log`) | 2.43.0 (`/usr/bin/git`) | 402 passed | | the first three of those files (`g247.log`) | 2.47.1 (first on PATH; `git --version` printed `git version 2.47.1`) | 196 passed | - The 57 files that run `bump-leg.py`, which fix round 1 ran in two shards (3419 passed), were not run again: the edit is inside `tag_chain_end`, and the rows that reach it are the two files above, which ran in full. CI's `tests` job on the pushed head is the full-suite run. - `tests/test_path_guard_hygiene.py` passes: the commit adds no `is_file`, `is_dir`, `exists`, `is_symlink` or `os.path` guard. - No added line is wider than 79 characters, none is non-ASCII, and no added assert joins conditions with `and` or `or`. ### Merge-trees at `55c30f20` `git merge-tree --write-tree` of the head against origin/main, re-fetched (`-c gc.auto=0 -c maintenance.auto=false`), and against each open PR that touches one of this PR's three files. Of the 41 open PRs listed at 20:09Z (`gh pr list --json number,headRefName,headRefOid,files`), only #1157 and #1107, besides this one, touch them. | Against | Head | Result | | --- | --- | --- | | origin/main, re-fetched before the push | `961640c681b5` | clean, tree `4d7968be5547`: the head's tree and `docs/release-notes/v1.2.0.md`, the one file main gained since `038dafba` (#1155) | | #1157 `fix/1100-refspec-followups` (DRAFT) | `368b87e9be87` (re-measured at 2026-10-23T12:06:38Z, after #1157's NIT round, which changes only `tests/test_family_bump_fetch_refspecs.py`; `baa19972a271` gave the same clean merge with tree `bd6ebc5cd3af`, and `a35a97ea52f4` when this round began) | clean, tree `e036c02d6a12` | | #1107 `fix/1019-points-at-row` (DRAFT) | `ee48b5fe9693` | clean, tree `a72145c05633` | - This commit's hunks in `scripts/bump-leg.py` are at lines 979 to 1003, in `tag_chain_end`; #1157's against main are in `_leg_fetch_refspecs`, from line 1105. They do not meet. - The other 38 of the 41 touch none of the three files. ### After the second re-check rc1131 found this round READY at `55c30f20f` (#1131, issuecomment-6352247887), with two NITs of its own, both in this body and neither in the code. This body now answers both: the count of lists in NIT 1's equivalence check (2478716 distinct lists, 2486027 comparisons), and SonarCloud's own analysis (python:S7494 CLOSED, 0 open issues, gate OK, no commit named by the API). The one other change is the #1157 row of the merge-trees table, which moved when #1157's NIT round added a commit. The head `55c30f20f` is unchanged. Review: lane 5's independent re-check, by a reviewer that wrote none of #1131: READY at `55c30f20` (issuecomment-6352247887), with rc1131's NITs 1 to 3 fixed. CI (Brett Heap's ruling 27 and his fast-refresh ruling of 2026-10-15T22:48:35Z): H0 55c30f2 passed tests, tests-git-bash and SonarCloud; the head db8533a is a clean update-branch merge of main 0d5704b, with tests-git-bash and SonarCloud green; and the local gate passed on its predicted squash tree 8fe39a5 over main 0d5704b: the bump_leg_reachability_words, neutral_pin_entry_one_spelling, repo_hygiene, agents_md_codes, cli_reference sets, 351 passed. Landed on Brett Heap's word of 2026-10-23T13:10:26Z, relayed to every lane by lane 3 (#473 issuecomment-6365697123): "merge v1.2.1 PRs once reviewed and green". Closes #1103 Lane: openreposhape-5 (openRepoShape-5) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>



Lane: openreposhape-5 (openRepoShape-5)
Claim: #1019 (comment)
Goal
No test held that a tag at a DESCENDANT of the refused commit counts as a tag that reaches it, so
--points-atin place of--containssurvived inbump-leg.pyandfamily.py(mutant M9 of #988's review, filed as #1019). This adds the rows the issue asks for to the two reachability test files, and no production code changes. Opened as a draft with no milestone: Brett Heap's ruling of 2026-10-21T10:32:04Z ("leave the follow-ups out of v1.2.0") held it until the v1.2.0 tag, and it is now on the v1.2.1 milestone.What still held on main
Measured on main
2a119f28before any change, and checked again on16f9a0e81and7e00834c(the tag questions did not change, only their line numbers):scripts/bump-leg.py_remote_tag_reachesandscripts/family.py_origin_tag_reacheslist the tags withgit for-each-ref --contains <commit> --format=%(objectname) refs/tags/. No other copy of either exists (the--containsinon_a_remote_branchand_on_a_remote_branchasks about branches and is not this question).--contains->--points-aton that one line in each script) SURVIVES every row on main:test_bump_leg_reachability_words.py34 passed,test_family_bump_reachability_words.py20 passed, 54 rows, as the issue says.--points-at, that row must fail"). No defect was found.What changed (two test files, 197 insertions, 4 deletions, after round 2)
tests/test_bump_leg_reachability_words.py:made_in_the_leg(project, name, on="HEAD")takes an optionalon, the commit the new commit is made on top of. Every existing call is unchanged.test_a_tag_at_a_descendant_of_the_commit_reaches_it: a commitmadeand a childaboveon top of it, on no branch of the leg's remote. The leg and the remote each tagabove(v1-w1019), made apart, in three kinds: both annotated (the reviewer's case J), leg lightweight and remote annotated, and the reverse. Both runs (dry run and real) refusemadebump-leg-commit-local-onlyin the TAG words, throughoriginand through--local-remote-dir(3 kinds x 2 routes = 6 rows), with nothing moved and the leg's own tag as it was. The premises say the tag names the child, that no tag is ATmade(for-each-ref --points-at), and, through shape_materialize.py: the fetch for a branch's answer leaves out every refspec of the repository's own onto the branches' names, whatever its source, and every one that puts a branch under a name not its own, sofamily.py bumpandbump-leg.pyno longer fail where the remote hasxandrelease/xand the repository's owngit fetch originworks (#1066) #1087'sonly_a_tag_reaches, that a tag of the remote reaches it, no branch does and no remote-tracking ref of the leg does.test_a_tag_at_an_ancestor_of_the_commit_alone_keeps_the_plain_words: the control (x 2 routes). The commit named is the child, and the leg and the remote tag only its parent. The plain words stay, "a pin the rest of the world cannot fetch" included.tests/test_family_bump_reachability_words.py:made_on(holder, env, parent, name): a commit never pushed, made in the mount on top ofparent, throughcommit_in_mount(which checksparentout first), so the holder stays clean.test_a_tag_at_a_descendant_of_the_commit_reaches_it: the same three kinds (3 rows), bothbump --dry-runand the realbumprefusemember-to-local-onlyin the tag words, with nothing moved and the mount's own tag as it was.test_a_tag_at_an_ancestor_of_the_commit_alone_keeps_the_plain_words: the control (1 row).No assert joins conditions with
andoror; each premise is its own assert. No README, docs, AGENTS.md or handbook text names these tests or their row counts (grep), so none changes.The mutants (rebased tree,
7e00834c's line numbers:bump-leg.py1205,family.py8869; each mutant restored, sha256 checked equal to HEAD)--points-atinbump-leg.py--points-atinfamily.py--mergedinbump-leg.py(extra: a check read the other way round)--mergedinfamily.py(extra)The failure is the one the issue names: the plain words ("is reachable from no branch of ...") where the tag words ("and a tag of ... reaches it, but no branch ... does") are expected. Logs:
r-mut-points-at-bump.log,r-mut-points-at-family.log,r-mut-merged-bump.log,r-mut-merged-family.log(andmut-main-*.logfor the 34 and 20 on2a119f28).Runs (through
run9.sh,EMAIL=service@opensoft.dev,GIT_SSH_COMMAND=false,GIT_CONFIG_GLOBAL=/dev/null, gh stubbed, at most two at once, never the full suite)On the pushed head
01fcb259:/usr/bin/git): the two test files, 66 passed (42 + 24; 34 + 20 before).tests/test_repo_hygiene.py,tests/test_agents_md_codes.py,tests/test_cli_reference.pyandtests/test_update_shape_kept_helper.py, 329 passed.On
1201680f(the same two files on top of16f9a0e8, before7e00834c, whose three files no row of mine touches or runs):test_bump_leg_fetch_refspecs.py,test_family_bump_fetch_refspecs.py), 102 passed; the two test files, 42 and 24 passed.$Q/v115/w764/git247/bin/gitfirst on PATH,git --versionprintedgit version 2.47.1): the two test files, 66 passed.No script changed, so no other test runs a changed script.
Merge-trees
git merge-tree --write-tree HEAD origin/mainagainst a re-fetchedorigin/main(7e00834c, which is also the merge base): exit 0, tree3a852e87fcfda41766ece8c1771e47689c622ad6, equal to this head's tree. Against16f9a0e8before the last rebase: exit 0 too.gh pr list --repo opensoft/openRepoShape --state open --json number,headRefName,isDraft,files: 8 (templates/assembly-root/project.yaml and templates/family-root/family.yaml: the comment abovevisibility:says it is the visibility the run asked for, and that a repository the run reuses keeps its own, where it said "this is all three repositories' visibility" (#913) #1102, scaffold-project.py: the--reuse-empty-repohelp, its docs and each remedy that sends a person into that re-run say ssh, a credential helper or askpass can still make it wait, and how to keep it from waiting (#915) #1101, family.py: a failed remove's by-hand lines spell a leg mounted at a path that is not UTF-8 as a printf word of octal escapes ending in a slash, sogit -C <member>/<leg>andsubmodule update -- <leg>typed in any POSIX shell name that leg (#1086) #1098, tests.yml: the full suite keeps its temporary files underrunner.temp, not/tmp, so it runs on Ubuntu 26.04 and thetestsjob goes back toubuntu-latest(#1096) #1097, adopt-project.py:checknames what the clone's.githolds as git keeps refs, and asks a pin's file through the links the root keeps, so a link into.gitor onto a pin's file is refused before any leg or adopted with the copy beside it (#904) #1091, shape_materialize.py, adopt-project.py and bump-leg.py: a tag a clone holds without its commit is one it cannot answer for,checksays a commit it cannot ask was not asked, and a pinned product YAML 1.1 or 1.2 reads as no text is quoted (#912) #1090, the family root's bootstrap.py:credential_adviceandended_onsay a member's failed clone ends git's update with 1 before any checkout but a leg's lets it go on, andkilled_saidsays git's update was itself killed, not that it went on (#1085) #1088, the family root's siblings.py: with a token in use, the clone and the fetch that carry it run in bootstrap.py'suntraced()environment, somake siblingsandfamily.py siblingswrite the token to no trace the caller asks git for (#1055) #1075). None touchestests/test_bump_leg_reachability_words.pyortests/test_family_bump_reachability_words.py, so there is no merge-tree to run against any of them.Round 2 (rv1107, NIT 2; NIT 1, the title, was the coordinator's)
originand prune rows), and a count goes stale with the next row.--points-atin place of--contains, the mutant M9 of bump-leg.py and family.py: the tag check compares the commits tags point to, so a lightweight or another annotated tag at the same commit reaches it (#982) #988's review, survived every row of this file." No row, assert or helper changed. The 54 in "What still held on main" above is the two files together, as it says.01fcb259, a fast-forward push, no rebase: headee48b5fe9693ebda099d1c0aadaca7bdc16b91c1, read back withgit ls-remote. Its tree is615e571bb62fd1cf481e4152278b0e3628bab059.run9.sh,EMAIL=service@opensoft.dev):tests/test_bump_leg_reachability_words.py42 passed,tests/test_family_bump_reachability_words.py24 passed. They ran on7186f3cf, the same tree as the pushed head; only the commit message was shortened after.origin/main(6da757cb, merge base7e00834c): exit 0, tree453566df33c886cf7fc2b1c39af02acbbff365dc. Main moved by nine files, none of mine; itsscripts/bump-leg.pychange (9 lines added) leaves_remote_tag_reachesand its--containsline alone (now line 1214).Closes #1019
🤖 Generated with Claude Code
Summary by Sourcery
Strengthen reachability tests for bump-leg and family so descendant-tag handling is validated and incorrect points-at or reverse-reachability implementations are caught.
Enhancements:
Tests: