Repository navigation
adopt-project.py: check, given no --local-remote-dir, asks GitHub nothing about the two legs of a plan for another repository and prints no NOTE that execute asks again, as execute refuses plan-not-the-source first and asks nothing; under --local-remote-dir it still asks the disk (#1232) - #1313
brettheap wants to merge 8 commits into
Conversation
… right after its three repository names, so a bad one beside an unanswered entry, a moved source, a refused name or another repository is that one refusal in both, and a `pins:` entry that is no pin is said as `_read_as` says it (#1020) #901 made `check` and `execute` name the same first problem among a plan's options. Outside them, the two still named different problems first (#1020, found by lane 1's writer on #901). 1. **One rule, the refusal before what `check` lists.** `check` refuses a bad `org:` or `id:` outright, exit 2, and lists none of its findings. `execute` refuses at the first of them, but it asked the two only after it had refused four things that `check` lists as findings: a plan for another repository (`plan-not-the-source`), a name the naming policy refuses (`naming-unclassified`), an unanswered entry (`plan-unresolved`) and a source that has moved on (`plan-stale`). And `check` asked the two only where the policy took the plan's names (`_manifest_values`), so an unsafe `org:` beside a refused name was a finding about the name, or about another repository. Both commands now ask the two first of the plan's values, right after the three repository names (`plan.names()`, then `_checked_org_and_id`): `execute` in `cmd_execute`, ahead of `_refuse_a_plan_for_another_repository`, and `check` at its head, after the triad advisory. `_checked_plan_values` no longer asks them, since `cmd_execute` has. 2. **#716's L4-48, decided.** An `org:` that `checked_value` refuses, held to a repository, was `unsafe-value` to `check` and `plan-not-the-source` to `execute`. Such an `org:` names no repository, on GitHub or in the manifest, so it is not compared with the source's. It is `unsafe-value` in both commands now, held to a repository or not. Once it is mended, a plan for another repository is still `plan-not-the-source` in both. This reverses three tests in `tests/test_adopt_check_plan_name.py`, which pinned the old answers on purpose: - `test_an_unsafe_org_is_unsafe_in_check_and_compared_by_execute_if_held` expected `plan-not-the-source` from `execute` in its six held rows. As `test_an_unsafe_org_is_unsafe_in_check_and_in_execute_held_or_not`, all twelve expect `unsafe-value` from both, in the same words. - `test_check_compares_an_unsafe_org_where_no_manifest_is_built` expected `check` to compare `org: acme labs` beside the refused name `bad_name`: `plan-not-the-source` and `naming-unclassified`, exit 1. As `test_an_unsafe_org_is_asked_before_the_plans_refused_names`, it expects `unsafe-value`, exit 2, from `check` and from `execute`. - `test_check_asks_an_unsafe_org_first_where_a_kept_submodule_url_is_relative` expected `plan-not-the-source` from `execute`. It now expects `unsafe-value`, in `check`'s words. 3. **A `pins:` entry that is no pin** was spelled with `repr` (`` `pins:` entry 1 is 7 ``, `True`, `None`). #901 made `pins:` itself read as `_read_as` reads it, and an entry reads the same way now: "the number 7", "the boolean true", "null", "a list of 2 item(s)". Docstrings and comments now say this: `_checked_org_and_id`, `_checked_plan_values`, `_manifest_values`, `_held_findings`, `_not_the_source`, `_refuse_a_plan_for_another_repository`, `_read_pins` and the #499 block comment. No finding is added or removed: only which problem is named first changes, and the spelling of an entry. Measured on main at `6da757cb` and on this branch, with a stub `gh`, a bogus token, an empty `GH_CONFIG_DIR`, `GIT_SSH_COMMAND=false` and `--local-remote-dir`. No run made a leg. | The plan has | `check` on main | `execute` on main | both, here | |---|---|---|---| | a bad id beside an unanswered entry | `plan-bad-id` | `plan-unresolved` | `plan-bad-id` | | a bad id beside a source that has moved on | `plan-bad-id` | `plan-stale` | `plan-bad-id` | | a bad id beside a name the policy refuses | `plan-bad-id` | `naming-unclassified` | `plan-bad-id` | | a bad id beside another organisation, held to a repository | `plan-bad-id` | `plan-not-the-source` | `plan-bad-id` | | no `id:`, and `legs.assembly: north_wind` (a derived id the policy refuses too) | `plan-bad-id` | `naming-unclassified` | `plan-bad-id` | | an unsafe `org:` held to a repository (L4-48) | `unsafe-value` | `plan-not-the-source` | `unsafe-value` | | an unsafe `org:` beside an unanswered entry | `unsafe-value` | `plan-unresolved` | `unsafe-value` | | an unsafe `org:` beside a source that has moved on | `unsafe-value` | `plan-stale` | `unsafe-value` | | an unsafe `org:` beside a refused name | finding `naming-unclassified`, exit 1 | `naming-unclassified` | `unsafe-value` | | the same, held to a repository | finding `plan-not-the-source`, exit 1 | `plan-not-the-source` | `unsafe-value` | Each "here" row is exit 2 from both, word for word. The last two rows agreed on main. They change because `check` now asks the two where the policy refuses the names, as `execute` now does: without that, moving `execute` alone would have made them disagree. Plans with only one of these problems (an unanswered entry, a moved source, a refused name, another repository) are named as on main by both. **Tests.** - `tests/test_adopt_plan_value_order.py` gains 16 rows: - the 10 above, through both commands, comparing the first line; - four `pins:` entries that are no pin: number, boolean, null and list; - two guard rows, `id` and `org`: a leg name `checked_value` refuses (`legs.spec: "-spec"`) beside a bad `id:` or `org:` is that name's `unsafe-value` in both, so the three names are still asked first. - The 14 non-guard rows all fail against `6da757cb`'s `adopt-project.py` and pass here. The two guard rows pass on both, by design. - Existing rows changed for the new behaviour: - `test_adopt_check_plan_name.py`: the three tests above, and its docstring's L4-48 line. - `test_adopt_pins.py`: `a-number`. - `test_adopt_execute_refusals.py`: the three entry rows of `PIN_ENTRIES`. Closes #1020 Lane: openreposhape-4 (openRepoShape-4) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… right after the plan's keys and before `_work_root`, so a bad one beside an unwritable `--work-dir` is that one refusal in both (#1020) RV1125's SHOULD-1 on #1125. A bad `id:` or `org:` beside a `--work-dir` this user cannot write in was `plan-bad-id` (or `unsafe-value`) to `check` and `adopt-work-dir-unwritable` to `execute`: `check` lists the directory as a finding (#524), and `execute` refuses it before it opens the source, ahead of the two asks, which #1125 had placed after `_work_root`. The comments in `cmd_execute` and `_checked_org_and_id` said that cannot happen. - `cmd_check` asks `plan.names()` and `_checked_org_and_id(plan)` right after its mistyped-plan question, before `_work_root`, and `cmd_execute` asks them right after `_refuse_a_mistyped_plan`, before `_work_root`. Both read only the plan. `execute` now asks them before `_require_filter_repo()` too. - A side effect, said in the body: `check` printed the Triad advisory, once it had opened the source, before it refused a bad `org:` or `id:`; it prints nothing now, since the refusal comes before the source is opened. - The comments and docstrings that placed the asks "at its head, after the triad advisory" or "right after the names" say where they are now. - tests/test_adopt_plan_value_order.py: `both_on` takes a `--work-dir` for both commands; one row per bad `id:` and bad `org:` beside an unwritable `--work-dir` (skipped where `chmod` cannot keep this user from writing); and, for NIT-2, one row per value that asks `check` alone and holds stdout empty, the position being told by the Triad advisory the unedited plan prints first. - tests/test_adopt_check_plan_name.py: the docstring of the kept-submodule row says it is a regression row since `check` asks `org:` at its head (NIT-1). Lane: openreposhape-4 (openRepoShape-4) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…blems against its source, in the order a person mends them (another repository, a refused name, a moved source, an unanswered entry), so `check`'s first finding is `execute`'s refusal for each pair (#1113) `check` listed a moved source first, then the plan's entries, then another repository and then the names; `execute` refused another repository, a refused name, an unanswered entry and then a moved source. So for five of the six pairs of the four, `check`'s first finding was not `execute`'s refusal: the four of #1113's table, and a refused name beside a moved source. `_against_its_source` asks the four in one order, and both commands read it: `execute` refuses its first problem, and `check` lists each, in that order and in its own words, before the split branch and the entries. Each of the first three is mended by running `plan` again, which takes back every answer, so an unanswered entry is named last; another repository comes first, before the naming policy or any remote is asked (#499); and a refused name is mended by a `plan` that reads the source as it is now, so it comes before a moved source. `_refuse_an_unrunnable_plan` asks a moved source before an unanswered entry. No refusal's code or wording changes: only which is named first. tests/test_adopt_plan_against_its_source.py runs both commands on one plan per pair, on all four, and on each of the four alone. In tests/test_adopt_relative_submodule_url.py, six rows hand-edit a plan's `org:` to another organisation beside a relative url, and pinned `check`'s old order, the url first. Such a plan is for another repository, which `execute` refuses first (#499), so the rows now expect `plan-not-the-source` first to `check` too. A new row runs `check`, with and without `--local-remote-dir`, and `execute` on one such plan, and asserts that each names it first and that no leg is made. Lane: openreposhape-4 (openRepoShape-4) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…le's problems beside the split branch taken and beside an unsafe `tracking_branch:` pins that `check` lists the rule's problem, and its remediation, first and `execute` refuses it first, so the rule moved after either finding fails a row (#1113) RV1210 measured two placements of the rule that no row pinned, each bringing back a disagreement #1210 fixes: - `check` listing the rule's problems after the split branch: another repository, a refused name and a moved source beside a branch `adopt` in the source, as `test_adopt_split_branch.py` makes it (`another-and-taken`, `name-and-taken`, `moved-and-taken`); - `execute` asking the rule after `_checked_plan_values`, `_repository_urls` and `_refuse_an_unwritable_clone_url`: each of the four beside `tracking_branch: "a b"`, which `BAD_TRACKING_BRANCH` from `test_adopt_plan_value_order.py` edits in (`another-and-tracking`, `name-and-tracking`, `moved-and-tracking`, `unanswered-and-tracking`). Each row asserts that `check` exits 1 and names the rule's problem first, and lists the ordinary finding after it, and that `execute` exits 2 and refuses the rule's problem first. `another-and-taken` also asserts that `check`'s first `Remediation:` line is the rule's (NIT-4), so the remediation lines follow the findings' order. `unanswered-and-taken` stays out: it is #1197's. Test only; adopt-project.py is unchanged. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… nothing about the two legs of a plan for another repository and prints no NOTE that `execute` asks again, as `execute` refuses `plan-not-the-source` first and asks nothing; under `--local-remote-dir` it still asks the disk (#1232) On #1210's head 791106c, `check` on a plan for another repository, given no `--local-remote-dir`, ran `gh repo view <org>/<Project>-spec --json nameWithOwner` and the same for `-code`, under the plan's own `org:`, and where gh could not answer it printed a NOTE that `execute` asks again before it makes either leg. `execute` refuses `plan-not-the-source` first and asks no remote anything (#499). `cmd_check` now skips the leg question (`_leg_remote_findings`) there, as it skips it after a finding in `RENAMES_THE_LEGS`. The source's own plan is asked as before. Under `--local-remote-dir` the disk is still asked beside `plan-not-the-source`: it asks no remote, and a leg's bare repository is `<dir>/<name>.git`, which no `org:` is part of. Measured, the `leg-remote-exists` it lists beside `plan-not-the-source` names the very path the source's own plan, the one the remedy writes, is refused for. Tests: tests/test_adopt_plan_against_its_source.py gains 2 rows that fail on 791106c (a plan for another repository by its `org:` and by its `legs.assembly:`, under a `gh` that logs each call), a row for the choice under `--local-remote-dir`, and a control for the source's own plan. Lane: openreposhape-3 (openRepoShape-3) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The second of the three restack merges: #1210 as it landed on main. Its tree is the final head's (ee6de2a), so this merge changes no file. tests/test_adopt_plan_against_its_source.py, which #1210 added, met as an add/add conflict and was taken ours: the squash holds 791106c's bytes of it, and ours holds those bytes and this branch's own change, nothing else. Lane: openreposhape-3 (openRepoShape-3) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewer's GuideImplementationSkip leg-remote checks for plans refused as
TestsDocument the exception and add coverage for skipping GitHub questions, retaining local-disk checks, and preserving checks for the source repository’s own legs.
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
|
(lane openRepoShape-3, 2026-11-10T14:15:00Z) RV1232: CHECKPOINT at cf65850 LAST STEP reached me during item 4, the gates. Items 1, 2, 3, 5 and 6 are measured. None of item 4 is. Verdict so far: READY AFTER FIXES. The fixes are to the body only, and the verdict holds only if the gates pass. I found no MUST. PR: #1313, #1313. Branch The two choicesChoice 1: under
One of the three reasons the body gives goes too far (SHOULD-1). "The plan the remedy writes is asked of the same two paths" is true only when the plan's
The plan the first remedy writes ( Choice 2: a plan edited only in
The body says why in three plain bullets. I measured what its "Not measured" paragraph leaves open, with a
These are the repositories the remedy's plan names, so the person now meets them one round later. That is acceptable, and the body should say it as measured (SHOULD-2). FindingsSHOULD-1 (body). In "The choice under
SHOULD-2 (body). Replace the paragraph "Not measured. By the code, not by a run: ..." with:
NIT-1 (body, Gates). g2 leaves out NIT-2 (body). After the robot line, the Sourcery bot added a "## Summary by Sourcery" block. Its lines 212 and 218 each hold U+2019. Everything else in the body is ASCII except the robot line, U+1F916 at line 208. NIT-3 (code, optional; the head would change). The test module names NIT-4 (out of scope). The Item 2: before and after (measured)The probe ran
This matches the body's table and its "the same bytes" claims. Item 3: the rows and mutants (measured)
My three mutants were each applied alone. The whole module ran (22 rows), and the file was restored and checked with
Item 5: merges (git 2.43.0, measured)
Item 6: the body (measured)
Not measured
Run these from the clone, one at a time: Paths
Lane 3: g1, g2 and g3 run now from lane 3's main loop with RV1232's own commands, one at a time at |
|
(lane openRepoShape-3, 2026-11-10T14:34:09Z) READY at
The logs are in RV1232-scratch. So RV1232's verdict holds: READY AFTER FIXES, with the fixes to the body only. Lane 3 took SHOULD-1, SHOULD-2 and NIT-1 into the body word for word, and added an "Independent review" section. It did not take two:
|
|
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 days and 6 hours by commenting |



Built on #1210's head
791106c2, then merged with #1210's final head27c8f67band its squash106f92ffafter #1210 landed.What a person sees change
adopt-project.py checkon a plan for another repository (plan-not-the-source), given no--local-remote-dir:gh repo view <org>/<Project>-spec --json nameWithOwnerand the same for-code, under the plan's ownorg:. Where gh could not answer, it printed two NOTEs saying "executeasks again before it makes either leg".executerefusesplan-not-the-sourcefirst and asks no remote anything (adopt-project.pyplannever compares--project(or--org) with the repository it adopts in place, so a source namedbilling-serviceis refused with a remediation that steers to--project BillingService, which plans and checksplan okagainstacme/billing-service, andexecutethen acts onacme/BillingService: a rawgit ls-remotefailure when no such repository exists, and, when a different repository of that name does, both legs, the split branch, the pull request and the topic on that repository #499), so it never asks.checkruns noghand prints neither NOTE. It still listsplan-not-the-sourcefirst, with the same remediation and exit 1, andexecutestill refuses it first, exit 2. So adopt-project.py:checkandexecuteread one list of a plan's problems against its source, in the order a person mends them (another repository, a refused name, a moved source, an unanswered entry), socheck's first finding isexecute's refusal for each pair (#1113) #1210's rule holds.Nothing else changes:
gh repo viewof each leg, and still gets its NOTE where gh cannot answer.--local-remote-direvery output is the same as before.The choice under
--local-remote-dir, and why#1232 left this open. Measured first (the table below):
--local-remote-dir,checkasks the disk, not GitHub: is each leg's bare repository,<dir>/<name>.git, already there, and can the directory hold them?plan-not-the-sourcewith the spec leg's bare repository present,checklistsleg-remote-existsfor<dir>/Northwind-spec.git. That is the very finding, word for word, it lists for the source's own plan under the same directory. The source's own plan is the one the remedy (plan --project Northwind --org testorg) writes.--local-remote-dir, the plan edited toorg: acmeis asked aboutacme/Northwind-spec. The plan the remedy writes is asked abouttestorg/Northwind-spec.So the skip applies only without
--local-remote-dir. Under it, the disk is still asked besideplan-not-the-source, for three reasons:plannever compares--project(or--org) with the repository it adopts in place, so a source namedbilling-serviceis refused with a remediation that steers to--project BillingService, which plans and checksplan okagainstacme/billing-service, andexecutethen acts onacme/BillingService: a rawgit ls-remotefailure when no such repository exists, and, when a different repository of that name does, both legs, the split branch, the pull request and the topic on that repository #499's reason forexecutedoes not apply. And the disk always answers, so there is no NOTE to be wrong.org:is part of a leg's path. The plan the remedy writes is asked of the same two paths wherever the plan keeps the source's own leg names: for anorg:edit, the one adopt-project.py: without--local-remote-dir,checkasksgh repo viewabout the two legs of another repository's plan, and its NOTE saysexecuteasks again, whereexecuterefusesplan-not-the-sourcefirst and asks nothing (follows #1210) #1232, adopt-project.py:checkandexecuteread one list of a plan's problems against its source, in the order a person mends them (another repository, a refused name, a moved source, an unanswered entry), socheck's first finding isexecute's refusal for each pair (#1113) #1210's rows and the relative-url rows measure, and for alegs.assembly:orproject:edit. A plan written for another project, with its ownlegs.spec:andlegs.code:, is asked of that project's paths: measured by RV1232, with<dir>/Thing-spec.gitpresent,checklistsleg-remote-existsfor it besideplan-not-the-sourceon both heads. That is a path the planplan --project <source>writes does not name, and the one the other remedy, a plan from the repository the plan is about, keeps. It is kept: it is true of the disk, and it asks no remote.adopt-folder-cannot-be-madenames the directory, which no mend changes.checkalready applies to the topic finding (family.py, adopt-project.py and the four tools'--org:initasks GitHub's limits on the topic, the--organd the holder's name before any repository exists,checkfinds whatexecuterefuses from one list, and an--orgGitHub gives no organisation (., a trailing hyphen,--) is refused where GitHub is asked (#863) #871's review, S1). Skipped, the finding comes back only after the mend, in a second round.The other way, skipping under both, is mutant M2 below. The row
test_a_local_remote_dir_is_still_asked_beside_another_repositorykills it.One case the skip is blunter than the question. A plan that names another repository only by its
legs.assembly:(orproject:) keeps the source'sorg:and the legs' names. On 791106c,checkasked GitHub abouttestorg/Northwind-specand-code, the legs the plan the remedy writes names (measured: theanother-nameprobe). It is skipped there too:executeasks GitHub nothing about such a plan (adopt-project.pyplannever compares--project(or--org) with the repository it adopts in place, so a source namedbilling-serviceis refused with a remediation that steers to--project BillingService, which plans and checksplan okagainstacme/billing-service, andexecutethen acts onacme/BillingService: a rawgit ls-remotefailure when no such repository exists, and, when a different repository of that name does, both legs, the split branch, the pull request and the topic on that repository #499);Measured by RV1232, with a
ghthat answers{"nameWithOwner": ...}: on thelegs.assembly: Elsewhereplan, main'schecklistedplan-not-the-sourceand aleg-remote-existsfor each oftestorg/Northwind-specand-code(3 findings), and this head listsplan-not-the-sourcealone (1 finding). Those are the legs the remedy's plan names, so a person meets them after the mend, one round later. #1232's first "Done when" asks for noghcall on any plan for another repository, so the skip holds there too.Measured, before and after
The probe is
probe1232.pyin my scratch. It builds each plan with the test suite's own helpers (planned_withwith aheldsource, whoseoriginnamestestorg/Northwind). It runscheckand, for the plans for another repository,execute --yes --work-dir, with:ghfirst on PATH that logs its arguments and exits 97;GH_TOKEN=bogusand an emptyGH_CONFIG_DIR;GIT_SSH_COMMAND=falseand an empty global git config;LANES_LANEunset."Another (org)" is
org: acme. "Another (assembly)" islegs.assembly: Elsewhere. "lrd" is--local-remote-dir: absent (a directory not made yet), "taken" (holdingNorthwind-spec.git), or "a file".checkon 791106ccheckhereexecute(both heads)plan-not-the-source; gh:repo view acme/Northwind-spec,repo view acme/Northwind-code; 2 NOTEsplan-not-the-source; gh: none; no NOTEplan-not-the-source; gh: noneplan-not-the-source; gh:repo view testorg/Northwind-spec,-code; 2 NOTEsplan-not-the-source; gh: none; no NOTEplan-not-the-source; gh: noneplan-not-the-sourceplan-not-the-sourceplan-not-the-source,leg-remote-existsplan-not-the-sourceplan-not-the-source,adopt-folder-cannot-be-madeplan-not-the-sourceplan-not-the-sourcerepo view testorg/Northwind-spec,-code; 2 NOTEsleg-remote-exists(the same line as in "another (org), lrd taken")adopt-folder-cannot-be-madeByte for byte, with paths and hashes masked: 10 of the 12 probe sources are identical, all 20 runs' exits included. The other 2 are the two "no lrd" plans for another repository. In each, only
checkchanged:repo viewcalls to none;Its stderr, its exit and
execute's whole output are the same. No probe made a leg.Where the issue's measurement and mine differ: nowhere. RV1210 measured the
org:edit on90eca414, whoseadopt-project.pyis the same file as 791106c's (sha2564c8c1c9eb0c5). I also measured thelegs.assembly:edit and the three--local-remote-dirmodes, which the issue did not.Why
executewas not run on the source's own plan: without--local-remote-dirit goes on to read the remote, which a probe must not.What changed, in
adopt-project.pycmd_checkonly, the leg question (#798):unmendedis adopt-project.py:checkandexecuteread one list of a plan's problems against its source, in the order a person mends them (another repository, a refused name, a moved source, an unanswered entry), socheck's first finding isexecute's refusal for each pair (#1113) #1210's list of the rule's problems (_against_its_source).RENAMES_THE_LEGS.executeis not touched.checkandexecuteread one list of a plan's problems against its source, in the order a person mends them (another repository, a refused name, a moved source, an unanswered entry), socheck's first finding isexecute's refusal for each pair (#1113) #1210's head the file goes from sha2564c8c1c9eb0c5to81efae25c83b(my commite6f2526e). On main106f92ffand on this head it goes fromf42c0e973c33to7f0a247ffb65.106f92ff..<this head>, without@@andindexlines, is identical to that of791106c2..e6f2526e: 152 changed lines in the same 2 files.Rows
All in
tests/test_adopt_plan_against_its_source.py, #1210's module for the rule betweencheckandexecute, for three reasons:--local-remote-dir,checkasksgh repo viewabout the two legs of another repository's plan, and its NOTE saysexecuteasks again, whereexecuterefusesplan-not-the-sourcefirst and asks nothing (follows #1210) #1232 names it;checkandexecuteread one list of a plan's problems against its source, in the order a person mends them (another repository, a refused name, a moved source, an unanswered entry), socheck's first finding isexecute's refusal for each pair (#1113) #1210's rule (check's first finding isexecute's refusal);planned_with'sheldsource,ANOTHER_ORG,named_first,code_of.A short paragraph is added to the module docstring, because these rows are the exception to its "with the same
--local-remote-dir". Each row runs the tool with aghof its own first on PATH, ahead of the session's guard, that logs each call's arguments and exits 97 (with_a_logging_gh). They skip on Windows, where that#!script cannot run.test_check_asks_github_nothing_about_another_repositorys_legs[org]org: acme: noghcall bycheckorexecute(the row fails if either log holds arepo view, or any call), no NOTE,checkexit 1 andexecuteexit 2, both namingplan-not-the-sourcefirst(['repo view acme/Northwind-spec --json nameWithOwner', 'repo view acme/Northwind-code --json nameWithOwner'], []) != ([], [])test_check_asks_github_nothing_about_another_repositorys_legs[assembly]legs.assembly: Elsewheretestorg/Northwind-spec,-codetest_a_local_remote_dir_is_still_asked_beside_another_repositorychecklistsplan-not-the-sourcethenleg-remote-exists, the very finding it lists for the source's own plan; noghcalltest_check_still_asks_github_about_the_sources_own_legsrepo view testorg/Northwind-specand-code, prints both NOTEs word for word, and passesadopt-project.py(swapped in and restored withcmp): 2 failed, 2 passed.Mutants
Run on my commit
e6f2526e, on #1210's head, before the restack. Each was applied alone toadopt-project.py, the module was run (22 rows), and the file was restored, checked bycmpand sha256 (81efae25c83b, OK each time).asks_github_nothingrowsor another)test_a_local_remote_dir_is_still_asked_beside_another_repositoryor local_remote_dir is None)test_check_still_asks_github_about_the_sources_own_legsplan-staleinstead ofplan-not-the-sourceasks_github_nothingrowsGates
Run on this head
cf658506(treec23c2160, the work tree clean), one pytest at a time and never the whole suite, in the environment the probe used:gh(exit 97) first on PATH;GH_TOKEN=bogusand an emptyGH_CONFIG_DIR;GIT_SSH_COMMAND=falseand an empty global git config;LANES_LANEunset;The groups:
plan-not-the-source,leg-remote-exists,adopt-remote-unreadable,adopt-folder-cannot-be-made, and the NOTE's "could not ask GitHub";checkandexecuteread one list of a plan's problems against its source, in the order a person mends them (another repository, a refused name, a moved source, an unanswered entry), socheck's first finding isexecute's refusal for each pair (#1113) #1210 changed;test_scaffold_leg_path_collisions.py;test_shape_doctor.py, once.Modules that import a fixture from another ran in one pytest with it.
test_adopt_plan_against_its_source.py,test_adopt_plan_value_order.py,test_adopt_root_symlinks.py,test_adopt_pins.pyplan-not-the-sourcetest_adopt_check_plan_name.py,test_adopt_plan_and_remote_paths_spelled.py,test_adopt_project_is_the_source.py,test_adopt_relative_submodule_url.py,test_adopt_split_branch.pytest_adopt_plan_and_remote_paths_spelled.py, which came onto main in8bcdb2c6and onto this branch with the restack, the other four gave 150 passed)test_adopt_execute_refusals.py,test_adopt_branch_names.py,test_adopt_e2e.py,test_adopt_filter_repo_failure.py,test_adopt_gitmodules_values.pytest_adopt_history_gitlinks.py,test_adopt_late_failure.py,test_adopt_mount_ignored.py,test_adopt_root_shape_paths.py,test_ruleset_hint_tracking_branch.pytest_adopt_github_exits.py,test_adopt_source_clone_record.py,test_adopt_temp_work_roots.py,test_adopt_unsearchable_source.pytest_github_limits_init_check_org.py,test_github_name_limits.py,test_scaffold_leg_path_collisions.pytest_repo_hygiene.py,test_cli_reference.py,test_agents_md_codes.py,test_git_output_decoding.py,test_stdout_encoding.py,test_path_guard_hygiene.py,test_no_auto_maintenance.py,test_update_add_codes_documented.pydd699cc2with #1305test_adopt_entry_paths.py2edbfcb5.test_shape_doctor.pytest_shape_doctor.py:10516, "the PowerShell line is printed, and powershell.exe exists, only on a Windows host")The skips are the host's, not this PR's:
test_adopt_root_symlinks.py: "the reftable backend needs git 2.45 or later".test_stdout_encoding.py:292("the default this is about is Windows' own") and 2 attest_no_auto_maintenance.py:222(the run setsGIT_CONFIG_GLOBAL).Before the restack, on my commit
e6f2526ealone, g1 gave 368 passed and g2 150 passed. That chain was stopped when #1210 landed, and everything was run again here.Merges
The restack, as new commits, never a rebase:
e6f2526eon791106c2;8e15daa9, merging adopt-project.py:checkandexecuteread one list of a plan's problems against its source, in the order a person mends them (another repository, a refused name, a moved source, an unanswered entry), socheck's first finding isexecute's refusal for each pair (#1113) #1210's final head27c8f67b(791106c merged with main3add78e1): clean;cf658506, merging adopt-project.py:checkandexecuteread one list of a plan's problems against its source, in the order a person mends them (another repository, a refused name, a moved source, an unanswered entry), socheck's first finding isexecute's refusal for each pair (#1113) #1210's squash106f92ff.27c8f67b's (ee6de2a2, andgit diff 27c8f67b 106f92ffis empty), so this merge changes no file.tests/test_adopt_plan_against_its_source.py, which adopt-project.py:checkandexecuteread one list of a plan's problems against its source, in the order a person mends them (another repository, a refused name, a moved source, an unanswered entry), socheck's first finding isexecute's refusal for each pair (#1113) #1210 added, met as an add/add conflict and was taken ours, after measuring that the squash holds791106c2's bytes of it and ours holds those bytes plus this branch's own change, nothing else.adopt-project.pymerged on its own, to the squash's file plus this change.106f92ff, the squash itself, so merging main again was "Already up to date".git merge-tree --write-tree(git 2.43.0) of this headcf658506:106f92ff: clean, treec23c2160, which is this head's own tree.git diff --name-only 106f92ff cf658506lists only this PR's 2 files.checkandexecuteread one list of a plan's problems against its source, in the order a person mends them (another repository, a refused name, a moved source, an unanswered entry), socheck's first finding isexecute's refusal for each pair (#1113) #1210):origin, asclone.defaultRemoteNamenames it, is read from that remote, soplanreads its organisation, default branch and branches where it refusedadopt-no-org, took HEAD's branch as the default and asked--tracking-branchof the source's own branches, and one with several remotes and nooriginnames them and guesses none (#1276) #1280: not this PR's. Its 3 conflict hunks inadopt-project.py(around lines 3620, 3715 and 5818) are the same, byte for byte, with this head and with main alone. This change sits at about line 14951. It is adopt-project.py: a source whose only remote is not namedorigin, asclone.defaultRemoteNamenames it, is read from that remote, soplanreads its organisation, default branch and branches where it refusedadopt-no-org, took HEAD's branch as the default and asked--tracking-branchof the source's own branches, and one with several remotes and nooriginnames them and guesses none (#1276) #1280's own conflict with main.checklists an unanswered entry with the plan's problems against its source, before the split branch and the entries, so beside an uncovered path, an unsafe path, a bad leg path, the split branch taken or another entry finding its first finding isexecute's refusal,plan-unresolved(#1197) #1305 (lane 3's, for adopt-project.py:checkandexecutestill name different first problems for a plan with an unanswered entry beside an uncovered path,plan-uncoveredandplan-unresolved, a pair #1113's four do not cover (follows #1113) #1197), also built on adopt-project.py:checkandexecuteread one list of a plan's problems against its source, in the order a person mends them (another repository, a refused name, a moved source, an unanswered entry), socheck's first finding isexecute's refusal for each pair (#1113) #1210's head, at2edbfcb5:tests/test_adopt_plan_against_its_source.py, the import block only. adopt-project.py:checklists an unanswered entry with the plan's problems against its source, before the split branch and the entries, so beside an uncovered path, an unsafe path, a bad leg path, the split branch taken or another entry finding its first finding isexecute's refusal,plan-unresolved(#1197) #1305 addsre,make_source_repo,planned,ANSWERSandBAD_LEG_PATH; this PR addsos,ADOPT,run_scriptandPLAN_FILE. The resolution is the union:adopt-project.pymerge on their own: this PR's hunks incmd_checkcome 33 unchanged lines after adopt-project.py:checklists an unanswered entry with the plan's problems against its source, before the split branch and the entries, so beside an uncovered path, an unsafe path, a bad leg path, the split branch taken or another entry finding its first finding isexecute's refusal,plan-unresolved(#1197) #1305's nearest, in791106c2's numbering.dd699cc2(tree98625a93, never pushed), adds over this head exactly adopt-project.py:checklists an unanswered entry with the plan's problems against its source, before the split branch and the entries, so beside an uncovered path, an unsafe path, a bad leg path, the split branch taken or another entry finding its first finding isexecute's refusal,plan-unresolved(#1197) #1305's change: 3 files, +239/-25. Only the import lines differ, as the union.checklists an unanswered entry with the plan's problems against its source, before the split branch and the entries, so beside an uncovered path, an unsafe path, a bad leg path, the split branch taken or another entry finding its first finding isexecute's refusal,plan-unresolved(#1197) #1305's earlier head142ca405gave the same one conflict, and on adopt-project.py:checkandexecuteread one list of a plan's problems against its source, in the order a person mends them (another repository, a refused name, a moved source, an unanswered entry), socheck's first finding isexecute's refusal for each pair (#1113) #1210's head791106c2alone adopt-project.py:checklists an unanswered entry with the plan's problems against its source, before the split branch and the entries, so beside an uncovered path, an unsafe path, a bad leg path, the split branch taken or another entry finding its first finding isexecute's refusal,plan-unresolved(#1197) #1305 merges clean.checklists an unanswered entry with the plan's problems against its source, before the split branch and the entries, so beside an uncovered path, an unsafe path, a bad leg path, the split branch taken or another entry finding its first finding isexecute's refusal,plan-unresolved(#1197) #1305 then moved to28f6f669, its own restack (2edbfcb5merged with27c8f67band106f92ff). Its change over main is line for line2edbfcb5's over791106c2.8f9ded6c).adbf4af2) as with2edbfcb5, and the same union resolves it to the same tree,98625a93, the one m1305 tested.Independent review
RV1232, lane 3's independent opus review (issuecomment-6769621392), reads READY AFTER FIXES at
cf6585063. The fixes are to the body only, and it found no MUST. It judged both choices right:--local-remote-dir, which is what adopt-project.py: without--local-remote-dir,checkasksgh repo viewabout the two legs of another repository's plan, and its NOTE saysexecuteasks again, whereexecuterefusesplan-not-the-sourcefirst and asks nothing (follows #1210) #1232's "To settle" asks, with a row on it;legs.assembly:, which adopt-project.py: without--local-remote-dir,checkasksgh repo viewabout the two legs of another repository's plan, and its NOTE saysexecuteasks again, whereexecuterefusesplan-not-the-sourcefirst and asks nothing (follows #1210) #1232's first "Done when" asks for.Its gates ran from lane 3's main loop at this head with RV1232's own commands, one pytest at a time:
Taken here: SHOULD-1, the bullet on leg paths; SHOULD-2, the paragraph measured by RV1232; and NIT-1, the g2 row.
Not taken:
checkandexecuteread one list of a plan's problems against its source, in the order a person mends them (another repository, a refused name, a moved source, an unanswered entry), socheck's first finding isexecute's refusal for each pair (#1113) #1210's head791106c2), to keep the reviewed head;docs/cli.md:684), which is out of scope. Lane 3 names it to Brett Heap as a follow-up candidate.Closes #1232
Lane: openreposhape-3 (openRepoShape-3)
🤖 Generated with Claude Code
Summary by Sourcery
Align
check’s remote-leg validation withexecuteby skipping unreachable GitHub checks for plans targeting another repository while retaining local and source-plan validation.Bug Fixes:
adopt-project.py checkfrom querying GitHub or emitting misleading notes about remote legs when the plan is for another repository andexecutewill refuse it before any remote access.Enhancements:
--local-remote-dirwhile preserving GitHub checks for the source repository’s own plan.Tests: