Repository navigation
adopt-project.py: check and execute ask a plan's org: and id: before its leg paths and branch names, a pins: entry _read_pins names is that one finding, and a digest_source: finding says how the digest was read (#901) - #1015
Conversation
…options execute now asks the plan's org: and id: first of its options (_checked_org_and_id), before the leg paths and branch names, as check asks them in _manifest_values. Docstring reworded. Tests to follow. Lane: openreposhape-1 (openRepoShape-1) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tests/test_adopt_plan_value_order.py runs check and execute on one hand-edited plan: a bad id or org beside a bad leg path, a bad branch name or a bad date is refused for the id or the org by both. Lane: openreposhape-1 (openRepoShape-1) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#255 asks only the pins execute writes (_declared_pins), and the validator's manifest-neutral-product-pins finding is left out wherever _read_pins finds the plan's pins:, so a pin whose product holds a tab is plan-pin-malformed alone. Rows in the new test file. Lane: openreposhape-1 (openRepoShape-1) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A pins: that is no list is said as _read_as says it, and a finding about a pin's digest_source: ends "from the commit and the digest `plan` records, and how it was read, and nothing else". Rows in the new test file. Lane: openreposhape-1 (openRepoShape-1) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test_adopt_pins, test_adopt_execute_refusals: a pins: that is no list is said as _read_as says it. test_adopt_plan_yaml_quoting: a pin holding a line break or a tab is plan-pin-malformed alone. test_adopt_template_ values: a name-only pins: item with a surrogate is plan-pin-unrecorded alone. adopt-project.py: two docstrings reworded. Lane: openreposhape-1 (openRepoShape-1) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… before its leg paths and branch names, so both refuse the same value first, a `pins:` entry `_read_pins` names is that one finding, a `pins:` that is no list is said as its reader read it, and a `digest_source:` finding says `execute` writes how the digest was read (#901) `check` and `execute` now name the same first problem in a hand-edited plan, and name each bad value once, in words that say what `execute` does (#901, which groups #457's L2-6, L2-7, L1-K7, L2-12 and L2-42): 1. **One order:** `_checked_org_and_id` asks the plan's `org:` and `id:`, and both commands ask it first of the plan's options: `check` in `_manifest_values`, where it always asked them, and `execute` at the head of `_checked_plan_values`, before the leg paths and the branch names. On `c7a3ff16` a plan edited to `id: "North Wind"` and `legs.spec_path: "../spec"` was `REFUSED plan-bad-id` to `check` and `REFUSED plan-bad-leg-path` to `execute`, and `org: "-evil"` beside the same path was `REFUSED unsafe-value` about the organisation to `check` and `plan-bad-leg-path` again to `execute`. Both commands now refuse the id, or the organisation, in the same words, exit 2, with no leg made. They come first because they say which project the plan is about, and because `check` builds the manifest it validates from them and refuses either outright, before it lists any finding. 2. **The docstring:** `_manifest_values` says that a bad date beside a bad organisation or id does not make `check` and `execute` name different problems first. 3. **One finding per value:** a `pins:` entry `_read_pins` names is that finding alone. `_plan_values` asks #255 only about the pins `execute` writes (`_declared_pins`), and `_validator_ignores` leaves out the validator's `manifest-neutral-product-pins` wherever `_read_pins` finds the plan's `pins:`. A pin edited to `product: "a\t"` and `repository: "opensoft/a\t"` was `plan-pin-malformed`, `plan-unwritable-value` and `plan-manifest-invalid`; it is `plan-pin-malformed` alone. 4. **`pins:` in its reader's words:** a `pins:` that is no list is said as `_read_as` says it, "the text 'openGlass'", "the boolean true", "the number 5" or "a mapping of 1 key(s)", as each other key a plan is opened by is, and not as Python spells it. 5. **The `digest_source:` finding:** a finding that names a pin's `digest_source:` ends "`execute` writes the pin file from the commit and the digest `plan` records, and how it was read, and nothing else" (`_pin_written_from`), for the pin file says how the digest was read too. Tests: `tests/test_adopt_plan_value_order.py` runs `check` and `execute` on one hand-edited plan with local remotes, and each of its 18 rows fails on `c7a3ff16`'s code. Rows changed for the new behaviour: the `pins:` spellings in `test_adopt_pins.py` (1) and `test_adopt_execute_refusals.py` (9); the two pin rows of `test_adopt_plan_yaml_quoting.py`'s #255 test, moved to a test of their own that expects `plan-pin-malformed` alone; and `test_adopt_template_values.py`'s `pins-surrogate`, now `plan-pin-unrecorded` alone. Lane: openreposhape-1 (openRepoShape-1) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewer's GuideThe PR makes Sequence diagram for aligned plan validation ordersequenceDiagram
participant Plan
participant Check
participant Execute
participant Values as _checked_plan_values
participant OrgId as _checked_org_and_id
Check->>Plan: _manifest_values
Check->>OrgId: _checked_org_and_id
OrgId->>Plan: checked_value(org)
OrgId->>Plan: project_id
Check-->>Check: refuse first org/id problem
Execute->>Values: _checked_plan_values
Values->>OrgId: _checked_org_and_id
OrgId->>Plan: checked_value(org)
OrgId->>Plan: project_id
Values->>Plan: _plan_leg_paths
Values->>Plan: _branch_name_findings
Execute-->>Execute: refuse first actionable problem
Sequence diagram for single pin finding and digest-source diagnosticssequenceDiagram
participant Plan
participant Reader as _read_pins
participant Validator as _validator_ignores
participant Values as _plan_values
participant Execute
Plan->>Reader: read pins
Reader->>Reader: _pin_row_problem
alt malformed or unrecorded pin
Reader-->>Execute: one plan-pin-malformed or plan-pin-unrecorded finding
Reader->>Reader: _pin_written_from
Reader-->>Execute: describe data used by execute
else valid pin
Reader-->>Values: _declared_pins
Values-->>Execute: pin value for validation
end
Reader-->>Validator: pins finding status
Validator-->>Execute: omit duplicate manifest-neutral-product-pins finding
Flow diagram for pin diagnostic wordingflowchart TD
A[_read_pins] --> B{pins is a list?}
B -- No --> C[_read_as]
C --> D[Report parsed boolean or value]
B -- Yes --> E[_pin_row_problem]
E --> F{digest_source is named?}
F -- Yes --> G[_pin_written_from returns commit, digest, and how it was read]
F -- No --> H[_pin_written_from returns commit and digest]
G --> I[Report one pin finding]
H --> I
D --> I
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
(lane openRepoShape-1, 2026-10-19T23:00:33Z) Independent review of #1015 (#901) by r1015, PARTIAL at r1015, checkpoint report. No verdict yet at The gate was stopped partway: the background chain exited with 144 during So far nothing is wrong in behaviour: no first problem is wrong, no bad pin lost its finding, and no test is broken. One wording finding counts as a MUST under the brief's rubric, because it is a false sentence. Findings, most severe first1. MUST (wording only; the behaviour is right): "first of the plan's options" is false.
2. SHOULD: the PR body's "First problems that still differ" list is incomplete.
3. SHOULD (predicted; the mutant was not run): no test pins the "how it was read" clause to
4. NIT: "With a bad id beside them, both now name
5. NIT: "The three docstrings ... now say 6. NIT: a dead clause at 7. NIT (optional). "..., and how it was read, and nothing else" still leaves out that the pin file also records Verified
Test counts at head (stub
|
| File | Result |
|---|---|
test_adopt_plan_value_order.py |
18 passed; all 18 fail against c7a3ff16's adopt-project.py |
test_adopt_pins.py |
146 passed |
test_adopt_execute_refusals.py |
181 passed |
test_adopt_plan_yaml_quoting.py |
518 passed |
test_adopt_template_values.py |
78 passed |
test_scaffold_leg_path_collisions.py |
104 passed |
test_shape_doctor.py shard 00 |
99 passed |
test_shape_doctor.py shard 01 |
113 passed |
Merges
main was fetched; it is at 259743ab, confirmed by ls-remote. Every merge-tree is clean:
Merge of 2b04aec2 with |
Tree |
|---|---|
origin/main (259743ab) |
7fa99899 |
9bf7f4cd (fix/900-spelled-names) |
46cec00c |
996bb0c5 (fix/910-check-throwaway-repos) |
3369aa7a |
| the main merge plus 910 | 275759a6 |
| the main merge plus 900 | 948ccb10 |
The merge with main is built as commit 0f0f2866 (tree 7fa99899), checked out in my --shared clone at /workspace/projects/openRepoShape-worktrees/_lane1-scratch/r1015/merge-main. On it, the order probe and the pin probe give exactly the head's results. Merge commits 818630ab (with 900) and debf05d8 (with 910) are also made in that clone.
Mutant table
Not run. The 14 mutants are prepared in /workspace/projects/openRepoShape-worktrees/_lane1-scratch/r1015/tools/mutate.py (M1, M2, M2b, M3-M9, M7b, M10-M12), and each anchor occurs exactly once in the file.
Left
test_shape_doctor.pyshards 02 and 03:run-one.sh <tree> g08-doctor-0N $(cat logs/doctor-shard-0N).test_agents_md_codes.py,test_repo_hygiene.pyandtest_readme_windows_quoting_sentence.pyat head. My grouped run exited 4 becausetest_neutral_pin_entry_one_spelling.pyis main's (from04923f10d) and is not at the PR head.- On the main merge clone at
0f0f2866: the new file,test_neutral_pin_entry_one_spelling.py, and the four changed test files. - The mutant runs, each restored with
git checkout -- adopt-project.py. - Optionally, the new file on the 900 and 910 merges.
Everything is in /workspace/projects/openRepoShape-worktrees/_lane1-scratch/r1015/: the scripts in tools/, the logs in logs/, and the runners probe.sh, run-one.sh and gate.sh.
Lane: openreposhape-1 (openRepoShape-1)
…fter the three repository names, not first of the plan's options; a short `commit:` row pins "how it was read" to `digest_source:` alone; a dead clause goes Round 1 of review r1015 on #1015, three items; the behaviour is unchanged. MUST: "first of the plan's options" was false. Both commands ask the plan's three repository names first (`plan.names()`, then `_check_names`), and only then `org:` and `id:` (`_checked_org_and_id`), so a bad id beside `legs.spec: "-x"` is `REFUSED unsafe-value: legs.spec is '-x'` to `check` and to `execute` alike. The `_manifest_values` docstring and comment, `_checked_org_and_id` (docstring, and "asked first by both commands"), the `_checked_plan_values` docstring and the test module's docstring and section heading now say `org:` and `id:` are asked before the leg paths and the branch names and after the three repository names. "The most basic problem first" is "the more basic". SHOULD: the rows of `test_adopt_plan_value_order.py` that are not about `digest_source:` asserted only a prefix, so a `_pin_written_from` that always returned the "and how it was read" ending (M7), or a commit finding that did (M7b), passed. Two rows of the new `test_a_finding_about_another_key_does_not_say_how_it_was_read` pin the ending to `digest_source:` alone: `short-commit` (the commit finding's own literal, M7b) and `no-commit` (the ending `_pin_written_from` makes from the keys a finding names, M7). A short `commit:` alone does not reach `_pin_written_from`, so it kills M7b and leaves M7 alive. NIT: the `_plan_fields` comment said a pin is asked "less one no file can hold, which is #255's finding alone". #255 asks only `_declared_pins` now and those hold to `PIN_ARG_RE`'s alphabet, so the clause is gone. Lane: openreposhape-1 (openRepoShape-1) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
(lane openRepoShape-1, 2026-10-20T00:55:31Z) r1015, independent review of #1015 (closes #901), round 2: READY at Round 1 fixed my MUST, my SHOULD 3 and my NIT 6, and the PR body now has my SHOULD 2 and NITs 4 and 5. Nothing blocks. The three NITs below are optional. FindingsNo MUST and no SHOULD. NIT 1: in
NIT 2: mutant M10 survives, in one narrow case.
NIT 3: the PR body's test paragraph could say how the two round-1 rows behave on the base.
Verified1. Delta
2. The new rows.
3. Mutants. All 14 anchors were unchanged by the wording edits. Each mutant was applied in turn and restored with
M9 is equivalent. My round-1 probe tried 27 kinds of bad product in 6 arrangements, on head and on the merge with main. The validator never refused a pin unless 4. Merges.
5. The live PR body. I read it with
6. Style. Doctor shards: skipped. Since Counts
At the end, the worktree Not verified
|
|
|
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 1 day and 15 hours by commenting |
…lict, so #1025 is tested against main as it stands, with #983's change to validate-family.py and #1026's fix of main's two red rows (#936) Main took twelve squashes since e076e3e: #1026, #958, #986, #1002, #1016, #1011, #1021, #1022, #973, #975, #1015 and #983. Only #983 touches validate-family.py, in `_git_runs` and the member checks, apart from this branch's hunks; it touches none of this branch's test files. Lane: openreposhape-4 (openRepoShape-4) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eviews and the Known limits continuation, with lanes 2, 4 and 5's items: eleven sites left to #1110, the doctor's 000 and 444 mount rows, the #1082 upgrade warning and the #891 and #1103 limits said as main's code does, #1112 and lane 2's two doctor limits named, and the shape copies measured (#921) The fix round on RV1155a, RV1155b, RV1155c and RV1155d, the continuations RV1155d2 and RV1155a2, and the comments lanes openRepoShape-4 and openRepoShape-5 left on #1155: - RV1155c's two MUSTs: `spec/` at 000 is `cannot be listed` and at 444 `spec/.git: cannot be read`; `scripts/` at 444 is `INVALID (manifest, pins)` on 3.14 as on 3.12. - Every SHOULD (a 3, b 2, c 3, d 13) and every NIT but RV1155a's NIT 7, RV1155a2's eight among them. - Where lane 5 and a reviewer word one line, one text covers both: #891 (d SHOULD 6, lane 5 SHOULD 7), #1103 (d SHOULD 7, lane 5 SHOULD 4) and #1090 (c's first NIT, lane 5 NIT 14). - KNOWN_OPEN in tests/test_path_guard_hygiene.py holds eleven sites, so both lines say eleven. - #1112 is a known limit; lane 2's two doctor limits (#975) and its test-only gaps (#975, #1050) are listed, and the "INVALID, not DRIFTED" sentence holds for a mount this user cannot list or read. - The shape-copy measurement fills its placeholder; the "Before tagging" pointer is gone. - The pipx claim carries RV1155d's qualifier everywhere it is made. - v1.0.0's tab-in-a-pin line is closed (#1015); its bare number or boolean in a plan's text field is narrowed (#1016). - `update-shape.py check` is named with `--at <release-commit>`, and the measurement says main `038dafb` was the upstream. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>



checkandexecutenow name the same first problem in a hand-edited plan, and name each bad value once, in words that say whatexecutedoes (#901, from lane 3's triage of #457: L2-6, L2-7, L1-K7, L2-12 and L2-42)._checked_org_and_id): both commands ask the plan'sorg:andid:before its leg paths and branch names, after its three repository names, which both commands ask earlier (plan.names()).checkasks them in_manifest_values, where it always did.executenow asks them at the head of_checked_plan_values, before the two leg paths and the two branch names. They come ahead of the leg paths and branch names because they say which project the plan is about: every repository the plan names is<org>/<name>, and the topic and the manifest'sid:are made from the id.checkalso builds the manifest it validates from them, and refuses either outright, exit 2, before it lists any finding._manifest_valuesnow says that a bad date beside a bad organisation or id does not makecheckandexecutename different problems first. The_held_findingsand_not_the_sourcedocstrings, and a#comment in_manifest_values, saidexecuterefuses an unsafeorg:in_repository_urls; they now say_checked_plan_values.pins:entry_read_pinsnames is that finding alone._plan_valuesasks adopt-project.py: since #247 a byte that is not UTF-8 in--elected-by,--referenceor the--sourcedirectory passesplanandcheck, andexecutepushes both legs before it dies withUnicodeEncodeErrorinwrite_lf#255 only about the pinsexecutewrites (_declared_pins)._validator_ignoresleaves out the validator'smanifest-neutral-product-pinswherever_read_pinsfinds the plan'spins:. A pin entry_read_pinsaccepts holds its product toPIN_ARG_RE's alphabet, so every entry the validator refuses is one_read_pinsnames, with theplan --pinthat records the pin whole.pins:in its reader's words: apins:that is no list is said as_read_assays it, as each other key a plan is opened by is.digest_source:finding: a finding that names a pin'sdigest_source:ends "executewrites the pin file from the commit and the digestplanrecords, and how it was read, and nothing else" (_pin_written_from). The pin file says how the digest was read too (_digest_source_written).Measured on
c7a3ff16and on this branch's head2b04aec2, with a stubgh, a bogus token, an emptyGH_CONFIG_DIRand local remotes. No run made a leg.c7a3ff16)2b04aec2)id: "North Wind"andlegs.spec_path: "../spec"check:REFUSED plan-bad-id;execute:REFUSED plan-bad-leg-pathREFUSED plan-bad-id: <plan>: `id:` is 'North Wind' and must match ^[a-z0-9][a-z0-9-]*$org: "-evil"and the same pathcheck:REFUSED unsafe-value(org);execute:REFUSED plan-bad-leg-pathREFUSED unsafe-value: org is '-evil', which is not a value this tool will put on a `git` or `gh` command lineproduct: "a\t",repository: "opensoft/a\t"check: three findings,plan-pin-malformed,plan-unwritable-value,plan-manifest-invalid;execute: refused with all threecheck: one finding,plan-pin-malformed;execute: refused with that onepins: truepins:is True, not a list of pins"pins:is the boolean true, not a list of pins"digest_source: "read by hand"executewrites the pin file from the commit and the digestplanrecords, and nothing else"L2-7's case,
visibility: secretbesideelected_on: someday, is unchanged: both commands nameelection-date-malformed. With a bad id beside them, both nameplan-bad-id, as onc7a3ff16.Tests.
tests/test_adopt_plan_value_order.pyrunscheckandexecuteon one hand-edited plan with local remotes. Its 20 rows pass here. The first round's 18 all fail againstc7a3ff16'sadopt-project.py. Review round 1 added two,short-commitandno-commit: a finding about another key of a pin does not say how the digest was read. Both pass againstc7a3ff16too, where no finding says how the digest was read: they keep that clause from spreading. Existing rows changed for the new behaviour:test_adopt_pins.py: thenot-a-listspelling.test_adopt_execute_refusals.py: the fourpins:rows ofBAD_KEYS, and thepins-textend-to-end assertion.test_adopt_plan_yaml_quoting.py: the two pin rows of the adopt-project.py: since #247 a byte that is not UTF-8 in--elected-by,--referenceor the--sourcedirectory passesplanandcheck, andexecutepushes both legs before it dies withUnicodeEncodeErrorinwrite_lf#255 test, moved to a test of their own that expectsplan-pin-malformedalone.test_adopt_template_values.py:pins-surrogate, nowplan-pin-unrecordedalone.Gate on
2b04aec2, under the stubgh:test_repo_hygiene.py: 100 passed.test_scaffold_leg_path_collisions.py: 104 passed.test_shape_doctor.py: in four shards, 99 + 113 + 91 + 142 passed and 3 skipped, all 448 tests the file collects.Round 1, on
c9652c9e, under the stubgh: the new file, 20 passed;test_adopt_pins.py146,test_adopt_execute_refusals.py181,test_adopt_plan_yaml_quoting.py518,test_adopt_template_values.py78,test_scaffold_leg_path_collisions.py104,test_repo_hygiene.py100,test_agents_md_codes.py47 andtest_readme_windows_quoting_sentence.py44 passed;test_shape_doctor.py, in four shards, 112 + 112 + 112 + 109 passed and 3 skipped.Pre-tested at
2b04aec2on the merge withmainat3864b18c.git merge-treehas no conflicts (tree41815b45), and the tests ran in a checkout of that merge (commit49099409). Eight files, 1047 passed: the new file (18),test_neutral_pin_entry_one_spelling.py(4),test_scaffold_pin_and_reuse.py(75),test_adopt_pins.py(146),test_adopt_execute_refusals.py(181),test_adopt_plan_yaml_quoting.py(518),test_adopt_template_values.py(78) andtest_adopt_unsearchable_source.py(27).Left for follow-up issues, not taken here:
checksaysplan-bad-id,executesaysplan-unresolved;plan-bad-idagainstplan-stale;plan-bad-idagainstnaming-unclassified;org:beside an unanswered entry:unsafe-valueagainstplan-unresolved;org:beside a source that has moved on:unsafe-valueagainstplan-stale;org:in a plan held to a repository:unsafe-valueagainstplan-not-the-source(adopt-project.pycheck: a plan in a name the policy refuses gets no rename-first remedy, and a source that names no repository is never compared with the plan's recordedsource.repository#716's L4-48 pins this one on purpose).visibility: "private\nx"is still two findings, adopt-project.py: since #247 a byte that is not UTF-8 in--elected-by,--referenceor the--sourcedirectory passesplanandcheck, andexecutepushes both legs before it dies withUnicodeEncodeErrorinwrite_lf#255's and adopt-project.py and scaffold-project.py accept values the new project's own validate-manifest.py refuses (a blank--elected-byor--reference,--elected-on 2026-W41-6or20261011on Python 3.11+,--org test+org, a plan'svisibility: secret), soadoption verifiedor a scaffold exit 0 is followed by a failed first bootstrap; andplanadmits a 251-255-character--projectthatcheckrefuses #261's, by that code's own rule that both are listed.COMMIT_REandSHA256_RE(scripts/repo_shape.py:68-69) use$with.match, so a pin'scommit:ortree_sha256:that ends in a line break passes_pin_row_problem.pins:that is no pin is still spelled withrepr(`pins:` entry 1 is 7).Closes #901
Lane: openreposhape-1 (openRepoShape-1)
🤖 Generated with Claude Code
Summary by Sourcery
Make
checkandexecuteagree on validation order and provide consistent, non-duplicated diagnostics for malformed plans and pins.Bug Fixes:
checkandexecuteso they report invalid plan organisation and ID values before leg paths and branch names.pins:values using the plan reader’s human-readable type names.Enhancements:
Tests:
pins:descriptions, and digest-source messaging.