From f7f596ab0484e80a05280aa450bbe4a4410f737e Mon Sep 17 00:00:00 2001 From: Brett Heap Date: Wed, 21 Oct 2026 10:49:42 +0000 Subject: [PATCH 1/2] templates/assembly-root/project.yaml and templates/family-root/family.yaml: the comment above `visibility:` 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) U039. Brett Heap ruled on 2026-10-21T10:39:44Z ("U039 and U037: take your recommendations") that the words change and no code does: a project's three repositories, or a family's members, can differ, and `visibility:` is one field. project.yaml now says it is the run's `--visibility`, or where none was given `private`, or the visibility of an existing assembly root the run reuses, as GitHub gave it (`_leg_visibility`), and that a reused repository keeps its own. The in-place adoption sentence is unchanged and still true. family.yaml says the same of the holder. tests/test_visibility_field_words.py pins the words, which no test did. Co-Authored-By: Claude Sonnet 5.5 --- templates/assembly-root/project.yaml | 15 ++-- templates/family-root/family.yaml | 8 +- tests/test_visibility_field_words.py | 107 +++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 6 deletions(-) create mode 100644 tests/test_visibility_field_words.py diff --git a/templates/assembly-root/project.yaml b/templates/assembly-root/project.yaml index c4a4b0e0..abb7c202 100644 --- a/templates/assembly-root/project.yaml +++ b/templates/assembly-root/project.yaml @@ -54,11 +54,16 @@ topic: {{TOPIC}} # `private`, `public` or `internal` (an enterprise org-internal repository). # NOT ENFORCED HERE — GitHub is the source of truth for what a repository's # visibility actually is — but recording it is what lets a reader tell, -# without three `gh repo view` calls, why the legs are internal. For a -# scaffolded project this is all three repositories' visibility; for an -# in-place adoption it is the value the two NEW legs were created with — the -# assembly root IS the adopted source and keeps whatever visibility it -# already had on GitHub, unchanged by this tool. +# without three `gh repo view` calls, why the legs are internal. It is the +# visibility the run that wrote this file ASKED FOR, not a reading of any +# repository: for a scaffold, `--visibility`, or where none was given +# `private`, or the visibility of an existing assembly root the run reuses, +# as GitHub gave it. A repository the run REUSES keeps the visibility it +# already has — the run changes no repository's visibility — so this can +# differ from what GitHub says of one of the three. For an in-place adoption +# it is the value the two NEW legs were created with — the assembly root IS +# the adopted source and keeps whatever visibility it already had on GitHub, +# unchanged by this tool. visibility: "{{VISIBILITY}}" # The branch `scripts/bootstrap.py` places each leg on, AT its pinned commit. diff --git a/templates/family-root/family.yaml b/templates/family-root/family.yaml index 27d05c8b..8c73c8cf 100644 --- a/templates/family-root/family.yaml +++ b/templates/family-root/family.yaml @@ -42,7 +42,13 @@ created_on: "{{CREATED_ON}}" # `private`, `public` or `internal`. NOT ENFORCED HERE — GitHub is the source # of truth for what a repository's visibility actually is — but recording it -# is what lets a reader tell why the members need a credential in CI. +# is what lets a reader tell why the members need a credential in CI. It is +# the visibility the `family.py init` run that wrote this file ASKED FOR, not +# a reading of any repository: `--visibility`, which is `private` unless the +# run was given another. It is the HOLDER's alone, since each member has its +# own, and a holder the run REUSES keeps the visibility it already has — the +# run changes no repository's visibility — so this can differ from what +# GitHub says of the holder. visibility: "{{VISIBILITY}}" # The HOLDER's own branch: the one a new holder is created on, and the one diff --git a/tests/test_visibility_field_words.py b/tests/test_visibility_field_words.py new file mode 100644 index 00000000..1a0b7148 --- /dev/null +++ b/tests/test_visibility_field_words.py @@ -0,0 +1,107 @@ +# SPDX-License-Identifier: Apache-2.0 +"""What the comment above `visibility:` says the field records (#913, U039). + +`templates/assembly-root/project.yaml` said "For a scaffolded project this is +all three repositories' visibility". It is not wherever a repository was +reused: the run records the visibility IT asked for (`--visibility`, which is +`private` unless the run was given another, or the reused root's own where it +was given none), and a repository it reuses keeps the visibility it has, +because no run changes one. `family.yaml` is the same for the holder: a reused +PUBLIC holder under the default `--visibility private` records `private`, as +`test_free_plan_hint_reads.py` holds. + +Brett Heap ruled on 2026-10-21T10:39:44Z that the WORDS change and no code +does ("U039 and U037: take your recommendations"): `visibility:` is "the +visibility this run asked for". The behaviour the words describe is pinned +where it is run, by `test_reuse_visibility.py` (the reused root's own is +inherited, and an explicit `--visibility` wins) and by +`test_free_plan_hint_reads.py` (a family keeps the run's); this file pins the +words, which no test did. The comments are copied into every project and +family this tool makes, so a word that goes back says again what a reused +repository does not do. + +NO NETWORK, NO GITHUB, NO PROCESS: the two templates, read as text. +""" + +from __future__ import annotations + +import pytest + +from conftest import REPO + +ASSEMBLY = REPO / "templates" / "assembly-root" / "project.yaml" +FAMILY = REPO / "templates" / "family-root" / "family.yaml" +BOTH = pytest.mark.parametrize("path", [ASSEMBLY, FAMILY], + ids=["project.yaml", "family.yaml"]) + +#: The line the comment sits on. +FIELD = 'visibility: "{{VISIBILITY}}"' + + +def comment_above_visibility(path) -> str: + """The comment block directly above `visibility:`, its `#` and its line + breaks gone, so a phrase is found whichever line it was wrapped on.""" + lines = path.read_text(encoding="utf-8").splitlines() + at = lines.index(FIELD) + block: list[str] = [] + for line in reversed(lines[:at]): + if not line.startswith("#"): + break + block.append(line.lstrip("#").strip()) + return " ".join(reversed(block)) + + +@BOTH +def test_visibility_is_what_the_run_asked_for(path): + """The key claim of #913's ruling, in both manifests: what is recorded + is what the run was asked for, not a reading of any repository, and a + reused repository keeps its own, which no run changes.""" + comment = comment_above_visibility(path) + for phrase in ("ASKED FOR", "not a reading of any repository", + "`--visibility`", "`private`", + "REUSES keeps the visibility it already has", + "changes no repository's visibility"): + assert phrase in comment, (phrase, comment) + + +@BOTH +def test_visibility_is_not_called_the_repositories_visibility(path): + """The sentence the ruling replaced, in the words it used.""" + comment = comment_above_visibility(path) + assert "this is all three repositories' visibility" not in comment + assert "all three repositories" not in comment, comment + + +@BOTH +def test_github_is_still_the_source_of_truth(path): + comment = comment_above_visibility(path) + assert "NOT ENFORCED HERE" in comment, comment + assert "GitHub is the source of truth" in comment, comment + + +def test_the_scaffold_comment_says_a_reused_root_is_inherited(): + """The default is `private` only where there is no reused root GitHub + gave a visibility for, as `_leg_visibility` has it.""" + comment = comment_above_visibility(ASSEMBLY) + assert ("the visibility of an existing assembly root the run reuses, " + "as GitHub gave it") in comment, comment + + +def test_the_in_place_adoption_sentence_holds(): + """Adoption creates the two legs at `plan --visibility` and keeps the + source's root as it is, which is what the sentence says and the ruling + left standing.""" + comment = comment_above_visibility(ASSEMBLY) + for phrase in ("For an in-place adoption it is the value the two NEW " + "legs were created with", + "keeps whatever visibility it already had on GitHub, " + "unchanged by this tool"): + assert phrase in comment, (phrase, comment) + + +def test_the_family_comment_says_it_is_the_holders_alone(): + """`family.yaml` records the HOLDER's, as `family.py init` fills it from + `--visibility`; a member is a project, with a `visibility:` of its own.""" + comment = comment_above_visibility(FAMILY) + assert "It is the HOLDER's alone" in comment, comment + assert "a holder the run REUSES keeps" in comment, comment From 2de07216570c8260cd8137fa9503ddc4a2cb3f96 Mon Sep 17 00:00:00 2001 From: Brett Heap Date: Wed, 21 Oct 2026 12:45:46 +0000 Subject: [PATCH 2/2] templates/assembly-root/project.yaml and tests/test_visibility_field_words.py: the comment above `visibility:` gives the order of what it records, `--visibility`, then the visibility GitHub gave of a reused assembly root, then `private`, and no longer says it is never a reading of a repository (#913) Review RV1102 of #1102, its one MUST. The comment said the field is "ASKED FOR, not a reading of any repository" and then named the reused root's visibility as GitHub gave it, which is a reading (`_leg_visibility`, scaffold-project.py:1660-1673), and it gave no order. It now says the field is what the run asked for, which is not always what a repository is: for a scaffold, `--visibility` where one was given; where none was, the visibility GitHub gave, before the plan, of an existing assembly root the run reuses; and otherwise `private`. It also says "why the legs it created are internal". family.yaml is true as written and is not touched. The test pins "not a reading of any repository" for family.yaml only, pins the order for project.yaml, and pins the adoption sentence from "in-place adoption" so that the old comment fails for its words and not for a capital letter. Co-Authored-By: Claude Sonnet 5.5 --- templates/assembly-root/project.yaml | 21 ++++++------- tests/test_visibility_field_words.py | 44 ++++++++++++++++++---------- 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/templates/assembly-root/project.yaml b/templates/assembly-root/project.yaml index abb7c202..285125f5 100644 --- a/templates/assembly-root/project.yaml +++ b/templates/assembly-root/project.yaml @@ -54,16 +54,17 @@ topic: {{TOPIC}} # `private`, `public` or `internal` (an enterprise org-internal repository). # NOT ENFORCED HERE — GitHub is the source of truth for what a repository's # visibility actually is — but recording it is what lets a reader tell, -# without three `gh repo view` calls, why the legs are internal. It is the -# visibility the run that wrote this file ASKED FOR, not a reading of any -# repository: for a scaffold, `--visibility`, or where none was given -# `private`, or the visibility of an existing assembly root the run reuses, -# as GitHub gave it. A repository the run REUSES keeps the visibility it -# already has — the run changes no repository's visibility — so this can -# differ from what GitHub says of one of the three. For an in-place adoption -# it is the value the two NEW legs were created with — the assembly root IS -# the adopted source and keeps whatever visibility it already had on GitHub, -# unchanged by this tool. +# without three `gh repo view` calls, why the legs it created are internal. +# It is the visibility the run that created this file ASKED FOR, which is not +# always what a repository is: for a scaffold, `--visibility` where one was +# given; where none was, the visibility GitHub gave, before the plan, of an +# existing assembly root the run reuses; and otherwise `private`, a root +# whose read failed included. A repository the run REUSES keeps the +# visibility it already has — the run changes no repository's visibility — +# so this can differ from what GitHub says of one of the three. For an +# in-place adoption it is the value the two NEW legs were created with — the +# assembly root IS the adopted source and keeps whatever visibility it +# already had on GitHub, unchanged by this tool. visibility: "{{VISIBILITY}}" # The branch `scripts/bootstrap.py` places each leg on, AT its pinned commit. diff --git a/tests/test_visibility_field_words.py b/tests/test_visibility_field_words.py index 1a0b7148..53dcf738 100644 --- a/tests/test_visibility_field_words.py +++ b/tests/test_visibility_field_words.py @@ -3,11 +3,13 @@ `templates/assembly-root/project.yaml` said "For a scaffolded project this is all three repositories' visibility". It is not wherever a repository was -reused: the run records the visibility IT asked for (`--visibility`, which is -`private` unless the run was given another, or the reused root's own where it -was given none), and a repository it reuses keeps the visibility it has, -because no run changes one. `family.yaml` is the same for the holder: a reused -PUBLIC holder under the default `--visibility private` records `private`, as +reused: the run records the visibility IT asked for, which is not always what +a repository is, in an order `_leg_visibility` follows (`--visibility` where +one was given; where none was, the reused root's own, as GitHub gave it before +the plan; otherwise `private`), and a repository it reuses keeps the +visibility it has, because no run changes one. `family.yaml` is the same for +the holder, with no root to inherit from: a reused PUBLIC holder under the +default `--visibility private` records `private`, as `test_free_plan_hint_reads.py` holds. Brett Heap ruled on 2026-10-21T10:39:44Z that the WORDS change and no code @@ -54,11 +56,10 @@ def comment_above_visibility(path) -> str: @BOTH def test_visibility_is_what_the_run_asked_for(path): """The key claim of #913's ruling, in both manifests: what is recorded - is what the run was asked for, not a reading of any repository, and a - reused repository keeps its own, which no run changes.""" + is what the run was asked for, and a reused repository keeps its own, + which no run changes.""" comment = comment_above_visibility(path) - for phrase in ("ASKED FOR", "not a reading of any repository", - "`--visibility`", "`private`", + for phrase in ("ASKED FOR", "`--visibility`", "`private`", "REUSES keeps the visibility it already has", "changes no repository's visibility"): assert phrase in comment, (phrase, comment) @@ -79,12 +80,22 @@ def test_github_is_still_the_source_of_truth(path): assert "GitHub is the source of truth" in comment, comment -def test_the_scaffold_comment_says_a_reused_root_is_inherited(): - """The default is `private` only where there is no reused root GitHub - gave a visibility for, as `_leg_visibility` has it.""" +def test_the_scaffold_comment_says_what_is_recorded_in_the_order_it_is(): + """`_leg_visibility`'s order, in the words of the comment: `--visibility` + where one was given, which wins over a reused root; where none was, the + visibility GitHub gave, before the plan, of an existing assembly root the + run reuses; and otherwise `private`. Where the root is the answer the + field IS a reading of a repository, so the comment must not say it is + never one.""" comment = comment_above_visibility(ASSEMBLY) - assert ("the visibility of an existing assembly root the run reuses, " - "as GitHub gave it") in comment, comment + order = ("for a scaffold, `--visibility` where one was given; where none " + "was, the visibility GitHub gave, before the plan, of an " + "existing assembly root the run reuses; and otherwise " + "`private`") + assert order in comment, comment + assert "not a reading of any repository" not in comment, comment + assert "which is not always what a repository is" in comment, comment + assert "why the legs it created are internal" in comment, comment def test_the_in_place_adoption_sentence_holds(): @@ -92,8 +103,8 @@ def test_the_in_place_adoption_sentence_holds(): source's root as it is, which is what the sentence says and the ruling left standing.""" comment = comment_above_visibility(ASSEMBLY) - for phrase in ("For an in-place adoption it is the value the two NEW " - "legs were created with", + for phrase in ("in-place adoption it is the value the two NEW legs were " + "created with", "keeps whatever visibility it already had on GitHub, " "unchanged by this tool"): assert phrase in comment, (phrase, comment) @@ -103,5 +114,6 @@ def test_the_family_comment_says_it_is_the_holders_alone(): """`family.yaml` records the HOLDER's, as `family.py init` fills it from `--visibility`; a member is a project, with a `visibility:` of its own.""" comment = comment_above_visibility(FAMILY) + assert "not a reading of any repository" in comment, comment assert "It is the HOLDER's alone" in comment, comment assert "a holder the run REUSES keeps" in comment, comment