From 3c12a7257b93a319405bbdd3eef5c9f87b36f72c Mon Sep 17 00:00:00 2001 From: Heznpc Date: Thu, 13 Aug 2026 18:24:01 +0900 Subject: [PATCH 1/2] Fix build_macos_swift_app.sh silently omitting shipped scripts release_smoke.py's manifest-completeness checks and the app's own RUNTIME_FILES array (which controls what actually gets copied into the signed bundle) were never cross-checked, so a script could pass every existing guard while still being silently absent from the real shipped app. Confirmed for real against this machine's actual installed runtime: modules/macos/idle_cpu.sh, privacy.sh, and devtool_updates.sh were all missing. scanner.sh's sibling-relative `source` failed for each with no `set -e` to stop it, so the scan kept going with three collector functions permanently undefined -- "command not found" on stderr, and the resulting scan_result.json silently reported `collection.complete: true` with all three sections simply absent. Separately, scripts/login_items.sh and modules/approval_token.sh were also missing -- that path fails closed instead (pinnedApprovalTokenModule returns nil when the sealed payload lacks the module), meaning every cleanup preview/execute and login-item removal has failed outright in a real signed build since approval_token.sh was extracted out of cleanup.sh (#67). No test caught it because every existing test runs against the checkout directly, never the installed runtime tree a real user's app uses. Adds a permanent glob-based regression guard, matching the same pattern already used for release_smoke.py's own manifest gaps: any new scripts/**/*.sh file is now required to appear in RUNTIME_FILES unless explicitly build-time-only. --- scripts/build_macos_swift_app.sh | 6 ++++ tests/test_service_contracts.py | 55 ++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/scripts/build_macos_swift_app.sh b/scripts/build_macos_swift_app.sh index 059ff07..826898d 100755 --- a/scripts/build_macos_swift_app.sh +++ b/scripts/build_macos_swift_app.sh @@ -369,12 +369,18 @@ RUNTIME_FILES=( "scripts/report.jxa.js" "scripts/scanner_helper.jxa.js" "scripts/idle_cpu.sh" + "scripts/network_watch.sh" + "scripts/login_items.sh" "scripts/modules/support_dir.sh" + "scripts/modules/approval_token.sh" "scripts/modules/macos/cpu.sh" "scripts/modules/macos/network.sh" "scripts/modules/macos/autoruns.sh" "scripts/modules/macos/security.sh" "scripts/modules/macos/storage.sh" + "scripts/modules/macos/idle_cpu.sh" + "scripts/modules/macos/privacy.sh" + "scripts/modules/macos/devtool_updates.sh" "data/config.example.json" "data/explain.json" "data/whitelist.json" diff --git a/tests/test_service_contracts.py b/tests/test_service_contracts.py index fcf09ff..0123cb7 100644 --- a/tests/test_service_contracts.py +++ b/tests/test_service_contracts.py @@ -5,6 +5,7 @@ import json import os import platform +import re import shutil import subprocess import sys @@ -521,6 +522,60 @@ def test_release_artifacts_exclude_runtime_python(project_root): ) +def test_bundled_app_runtime_includes_every_macos_script(project_root): + """release_smoke.py's MACOS_FILES (checked above) is a manifest- + completeness gate, not what actually ships -- build_macos_swift_app.sh + has its own, completely separate hand-maintained RUNTIME_FILES array + that controls what's actually copied into the signed app bundle. A + script can pass every assertion above while still being silently absent + from RUNTIME_FILES, because the two lists were never cross-checked. + + This happened for real, discovered by running scanner.sh from this + machine's actual installed runtime: modules/macos/idle_cpu.sh, + privacy.sh, and devtool_updates.sh were all missing, so `source` failed + for each (no `set -e`, so the scan kept going with three collector + functions permanently undefined) -- scanner.sh printed "command not + found" for each and the resulting scan_result.json silently reported + `collection.complete: true` with those three sections simply absent. + Separately, scripts/login_items.sh and modules/approval_token.sh were + also missing, which fails closed instead (pinnedApprovalTokenModule() + returns nil when the sealed payload doesn't contain the module) -- but + that means every cleanup preview/execute and login-item removal in a + real signed build failed outright since approval_token.sh was extracted + out of cleanup.sh in PR #67, with no test anywhere catching it because + every test runs against the checkout directly, never the installed + runtime tree a real user's app actually uses. + """ + build_script = (project_root / "scripts" / "build_macos_swift_app.sh").read_text( + encoding="utf-8" + ) + match = re.search(r"RUNTIME_FILES=\((.*?)\n\)", build_script, re.DOTALL) + assert match, "could not find RUNTIME_FILES=(...) in build_macos_swift_app.sh" + runtime_files = set(re.findall(r'"([^"]+)"', match.group(1))) + + # These build/release-time tools are never invoked by the running app, + # so they belong in the repo but not inside the shipped runtime folder. + build_only_scripts = { + "scripts/build_macos_icon.sh", + "scripts/build_macos_swift_app.sh", + "scripts/package_macos_release.sh", + } + expected = { + f"scripts/{path.name}" for path in (project_root / "scripts").glob("*.sh") + } - build_only_scripts + expected |= { + f"scripts/modules/{path.name}" + for path in (project_root / "scripts" / "modules").glob("*.sh") + } + expected |= { + f"scripts/modules/macos/{path.name}" + for path in (project_root / "scripts" / "modules" / "macos").glob("*.sh") + } + + missing = expected - runtime_files + assert not missing, f"scripts missing from the shipped app runtime: {sorted(missing)}" + + @pytest.mark.parametrize( "script,args", [ From 6b5eeb4d2f904356d94eaccaca7224f0ef564ad4 Mon Sep 17 00:00:00 2001 From: Heznpc Date: Thu, 13 Aug 2026 18:30:50 +0900 Subject: [PATCH 2/2] Remove network_watch.sh from this branch's RUNTIME_FILES That file doesn't exist on this branch -- it's part of the separate, not-yet-merged Phase 5-1 work, and CI correctly caught the reference to a nonexistent path. It belongs in that PR instead, alongside the file itself. --- scripts/build_macos_swift_app.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/build_macos_swift_app.sh b/scripts/build_macos_swift_app.sh index 826898d..b0313a8 100755 --- a/scripts/build_macos_swift_app.sh +++ b/scripts/build_macos_swift_app.sh @@ -369,7 +369,6 @@ RUNTIME_FILES=( "scripts/report.jxa.js" "scripts/scanner_helper.jxa.js" "scripts/idle_cpu.sh" - "scripts/network_watch.sh" "scripts/login_items.sh" "scripts/modules/support_dir.sh" "scripts/modules/approval_token.sh"