diff --git a/scripts/ci/detect_ci_change_areas.py b/scripts/ci/detect_ci_change_areas.py index 483740854d9d..072e62f3070c 100644 --- a/scripts/ci/detect_ci_change_areas.py +++ b/scripts/ci/detect_ci_change_areas.py @@ -976,6 +976,17 @@ def is_macos_neutral( # executable inputs, so only Markdown outside that folder is neutral. if path.rsplit("/", 1)[-1] in {"CLAUDE.md", "AGENTS.md"}: return True + # Contributor-facing prose. These are read by people, never by a build: + # none is a bundle resource or an Xcode input. Keep this an exact list -- + # THIRD_PARTY_LICENSES.md is also root Markdown, but it ships in + # Resources/ and is read by AboutLicenseContent.swift, so it stays + # macOS-relevant. + if path in { + "STYLE.md", + "CONTRIBUTING.md", + ".github/pull_request_template.md", + }: + return True if ( path.startswith("Packages/iOS/") diff --git a/tests/test_ci_change_areas.py b/tests/test_ci_change_areas.py index defc9d6066ff..e54333b7f16e 100755 --- a/tests/test_ci_change_areas.py +++ b/tests/test_ci_change_areas.py @@ -509,6 +509,24 @@ def test_agent_instructions_and_skill_docs_skip_expensive_areas() -> None: ) +def test_contributor_prose_skips_expensive_areas() -> None: + assert_areas( + ["STYLE.md", "CONTRIBUTING.md", ".github/pull_request_template.md"], + macos=False, + web=False, + ) + # The Release build is the expensive half of the waste: a writing-guidance + # edit used to select a universal app build. + assert module.classify_files(["STYLE.md"]).release_build is False + + +def test_bundled_root_markdown_still_runs_macos() -> None: + # THIRD_PARTY_LICENSES.md is root Markdown like the files above, but it + # ships in Resources/ and AboutLicenseContent.swift reads it, so it is a + # real product input. This is the boundary the prose carveout must not cross. + assert_areas(["THIRD_PARTY_LICENSES.md"], macos=True, web=False) + + def test_bundled_and_executable_skill_files_run_macos() -> None: # The app bundles skills/cmux-cua as a folder resource. assert_areas(["skills/cmux-cua/SKILL.md"], macos=True, web=False)