From d70594a933d8ce3e03a62a020280851334ab7d68 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 08:49:09 +0900 Subject: [PATCH 1/8] fix(coverage): discover hash-pinned requirements lock files --- scripts/ci/materialize_base_python_requirements.py | 12 ++++++++---- tests/test_materialize_base_python_requirements.py | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/scripts/ci/materialize_base_python_requirements.py b/scripts/ci/materialize_base_python_requirements.py index 41b60afd8..c2a44fd44 100755 --- a/scripts/ci/materialize_base_python_requirements.py +++ b/scripts/ci/materialize_base_python_requirements.py @@ -145,16 +145,20 @@ def _install_trusted_uv_url_opener() -> None: def _is_candidate_lock_name(name: str) -> bool: """Return whether a file name is a possible pip requirements lock.""" - return name == "requirements.lock" or ( - fnmatch.fnmatch(name, "requirements*.txt") - and not fnmatch.fnmatch(name, "requirements-*-ci-hashes.txt") + return ( + ( + fnmatch.fnmatch(name, "requirements*.txt") + and not fnmatch.fnmatch(name, "requirements-*-ci-hashes.txt") + ) + or fnmatch.fnmatch(name, "requirements*.lock") ) def _is_candidate_lock_path(path: pathlib.PurePosixPath) -> bool: """Return whether one safe tracked path can name a pip requirements lock. - In addition to conventional ``requirements*.txt`` names, repositories often + In addition to conventional ``requirements*.txt`` and ``requirements*.lock`` + names, repositories often keep concrete environment closures as direct children such as ``requirements/ci.txt`` or ``service/requirements/package.txt``. Only direct ``.txt`` children of a directory named ``requirements`` gain this path-based diff --git a/tests/test_materialize_base_python_requirements.py b/tests/test_materialize_base_python_requirements.py index 5bc56ed8f..7495512fc 100644 --- a/tests/test_materialize_base_python_requirements.py +++ b/tests/test_materialize_base_python_requirements.py @@ -143,8 +143,9 @@ def test_materializes_hash_pinned_locks_named_beyond_the_legacy_whitelist( def test_lock_name_candidates_are_pip_requirements_files() -> None: - """Requirements files and requirements.lock are candidates; other names are not.""" + """Requirements files and lock files are candidates; other names are not.""" assert materializer._is_candidate_lock_name("requirements.lock") + assert materializer._is_candidate_lock_name("requirements-dev.lock") assert materializer._is_candidate_lock_name("requirements-dev.txt") assert materializer._is_candidate_lock_name("requirements.txt") assert not materializer._is_candidate_lock_name( From bddf204b1631c3cb93dbf9bdfb23a5c07d00da7f Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 23:20:18 +0900 Subject: [PATCH 2/8] test: cover hash-pinned lock discovery --- ...test_materialize_base_python_requirements.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/test_materialize_base_python_requirements.py b/tests/test_materialize_base_python_requirements.py index 7495512fc..0df4967ff 100644 --- a/tests/test_materialize_base_python_requirements.py +++ b/tests/test_materialize_base_python_requirements.py @@ -1,3 +1,5 @@ +"""Verify trusted base lock discovery, materialization, and exporter failures.""" + from __future__ import annotations import hashlib @@ -121,6 +123,10 @@ def test_materializes_hash_pinned_locks_named_beyond_the_legacy_whitelist( "fastapi==1 --hash=sha256:" + ("a" * 64) + "\n", encoding="utf-8", ) + (service / "requirements-dev.lock").write_text( + "uvicorn==1 --hash=sha256:" + ("c" * 64) + "\n", + encoding="utf-8", + ) (repo / "requirements-test.txt").write_text( "hypothesis==6 --hash=sha256:" + ("b" * 64) + "\n", encoding="utf-8", @@ -138,6 +144,7 @@ def test_materializes_hash_pinned_locks_named_beyond_the_legacy_whitelist( assert [entry["source"] for entry in manifest] == [ "requirements-test.txt", + "services/account_unification/requirements-dev.lock", "services/account_unification/requirements-dev.txt", ] @@ -215,6 +222,7 @@ def test_rejects_malformed_git_tree_entries( """Malformed git output cannot be interpreted as a trusted lock blob.""" def fake_git(_repo_root: Path, *_args: str) -> bytes: + """Return the malformed tree fixture for the parser under test.""" return tree_output monkeypatch.setattr(materializer, "_git", fake_git) @@ -247,6 +255,7 @@ def test_main_reports_each_materialized_lock( def fake_materialize( _repo_root: Path, _base_sha: str, _output_dir: Path ) -> list[dict[str, str]]: + """Return one deterministic manifest for the CLI reporting test.""" return [ { "file": "requirements-000.txt", @@ -310,6 +319,7 @@ def test_main_fails_with_the_materialization_reason( """A materialization exception fails closed and remains diagnosable in CI.""" def fail_materialize(_repo_root: Path, _base_sha: str, _output_dir: Path) -> None: + """Raise the fixture failure that the CLI must report.""" raise OSError("fixture failure") monkeypatch.setattr(materializer, "materialize", fail_materialize) @@ -369,6 +379,7 @@ def test_skips_non_blob_tree_entries( ) def fake_git(_repo_root: Path, *args: str) -> bytes: + """Return one regular blob and one skipped gitlink tree entry.""" if args[0] == "ls-tree": return tree if args[0] == "show": @@ -433,6 +444,7 @@ def test_uv_lock_fails_closed_when_trusted_uv_bootstrap_fails( repo, base_sha = _uv_repo(tmp_path, with_pyproject=True) def fail_install() -> str: + """Raise the bootstrap failure expected for a tracked uv project.""" raise RuntimeError("trusted uv bootstrap failed") monkeypatch.setattr(materializer, "_install_trusted_uv", fail_install) @@ -448,6 +460,7 @@ def test_uv_lock_skipped_when_pyproject_is_absent( repo, base_sha = _uv_repo(tmp_path, with_pyproject=False, lock_dir="service") def unexpected_install() -> str: + """Fail if an orphan uv lock attempts to bootstrap the trusted exporter.""" raise AssertionError("orphan uv.lock must not bootstrap uv") monkeypatch.setattr(materializer, "_install_trusted_uv", unexpected_install) @@ -723,6 +736,7 @@ def test_install_trusted_uv_verifies_version_and_caches_path( calls = 0 def verify(*_args: object, **_kwargs: object) -> subprocess.CompletedProcess[bytes]: + """Return the exact pinned uv version and count verification executions.""" nonlocal calls calls += 1 return subprocess.CompletedProcess( @@ -765,6 +779,7 @@ def test_install_trusted_uv_rejects_version_process_failures( monkeypatch.setattr(materializer, "_verified_uv_binary", lambda _payload: b"binary") def fail(*_args: object, **_kwargs: object) -> None: + """Raise the parameterized process failure from the fake executable.""" raise failure monkeypatch.setattr(materializer.subprocess, "run", fail) @@ -821,6 +836,7 @@ def test_run_uv_export_invokes_uv_with_frozen_offline_flags( captured: dict[str, object] = {} def fake_run(argv: list[str], **kwargs: object) -> subprocess.CompletedProcess[bytes]: + """Capture uv export arguments while returning a successful result.""" captured["argv"] = argv captured["cwd"] = kwargs.get("cwd") captured["timeout"] = kwargs.get("timeout") @@ -856,6 +872,7 @@ def test_uv_export_process_failures_fail_closed( monkeypatch.setattr(materializer, "_install_trusted_uv", lambda: "/usr/bin/uv") def fail_export(_work: Path, _uv_path: str) -> None: + """Raise the parameterized exporter failure for the fail-closed test.""" raise export_error monkeypatch.setattr(materializer, "_run_uv_export", fail_export) From 800d345096a785bfa19ddf66d4d577ee7bd3c0cc Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 22 Aug 2026 03:11:01 +0900 Subject: [PATCH 3/8] fix(ci): refresh audit lock and scheduler assertion --- requirements-pip-audit-ci-hashes.txt | 6 +++--- scripts/ci/test_strix_quick_gate.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements-pip-audit-ci-hashes.txt b/requirements-pip-audit-ci-hashes.txt index ade197a49..0ae099d8f 100644 --- a/requirements-pip-audit-ci-hashes.txt +++ b/requirements-pip-audit-ci-hashes.txt @@ -213,9 +213,9 @@ packaging==26.2 \ # via # pip-audit # pip-requirements-parser -pip==26.1.2 \ - --hash=sha256:382ff9f685ee3bc25864f820aa50505825f10f5458ffff07e30a6d96e5715cab \ - --hash=sha256:f49cd134c61cf2fd75e0ce2676db03e4054504a5a4986d00f8299ae632dc4605 +pip==26.2.1 \ + --hash=sha256:71138adf1f4ca900cdb7d289c21b7494329f2332b6d85f0e1c42108c0384ed3e \ + --hash=sha256:f6ad667e89a1fe78046c8f13232b247200f5258d7828f3f7883d660878e0813f # via pip-api pip-api==0.0.34 \ --hash=sha256:8b2d7d7c37f2447373aa2cf8b1f60a2f2b27a84e1e9e0294a3f6ef10eb3ba6bb \ diff --git a/scripts/ci/test_strix_quick_gate.sh b/scripts/ci/test_strix_quick_gate.sh index ac9ce1d8b..ccf883d1e 100755 --- a/scripts/ci/test_strix_quick_gate.sh +++ b/scripts/ci/test_strix_quick_gate.sh @@ -1506,7 +1506,7 @@ assert_pr_review_merge_scheduler_uses_github_actions_bot_token() { assert_file_contains "$workflow_file" "github.event_name == 'pull_request_target' && format('pr-{0}', github.event.pull_request.number)" "scheduler scopes pull_request_target concurrency to the active PR" assert_file_contains "$workflow_file" "github.event_name == 'workflow_run' && github.event.workflow_run.pull_requests[0].number && format('pr-{0}', github.event.workflow_run.pull_requests[0].number)" "scheduler scopes workflow_run concurrency to the completed review PR" assert_file_contains "$workflow_file" "github.event_name == 'schedule' && format('schedule-{0}', github.event.schedule)" "scheduler isolates the 15-minute organization sweep from the separate 30-minute scheduled scan" - assert_file_contains "$workflow_file" "github.event_name == 'repository_dispatch' && github.run_id" "scheduler keeps manual queue scans isolated per run" + assert_file_contains "$workflow_file" "github.event_name == 'repository_dispatch' && format('repo-dispatch-{0}', github.repository)" "scheduler keeps manual queue scans isolated per repository" assert_file_contains "$workflow_file" "cancel-in-progress: \${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request_review' || github.event_name == 'repository_dispatch' }}" "scheduler cancels stale PR/review/manual queue scans instead of accumulating merge/update attempts" assert_file_contains "$workflow_file" "timeout-minutes: 60" "organization sweep has enough headroom to finish the complete repository walk" assert_file_contains "$workflow_file" "ORG_SWEEP_TRIGGER_REVIEWS: \${{ github.event_name == 'schedule' ||" "scheduled organization sweeps retry missing current-head OpenCode reviews" From 7fd87249d5124d17bc31ad6160f298aa3ae64c28 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 22 Aug 2026 03:39:56 +0900 Subject: [PATCH 4/8] test(ci): align scheduler cancellation assertion --- scripts/ci/test_strix_quick_gate.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci/test_strix_quick_gate.sh b/scripts/ci/test_strix_quick_gate.sh index ccf883d1e..bbe9aa8b2 100755 --- a/scripts/ci/test_strix_quick_gate.sh +++ b/scripts/ci/test_strix_quick_gate.sh @@ -1507,7 +1507,7 @@ assert_pr_review_merge_scheduler_uses_github_actions_bot_token() { assert_file_contains "$workflow_file" "github.event_name == 'workflow_run' && github.event.workflow_run.pull_requests[0].number && format('pr-{0}', github.event.workflow_run.pull_requests[0].number)" "scheduler scopes workflow_run concurrency to the completed review PR" assert_file_contains "$workflow_file" "github.event_name == 'schedule' && format('schedule-{0}', github.event.schedule)" "scheduler isolates the 15-minute organization sweep from the separate 30-minute scheduled scan" assert_file_contains "$workflow_file" "github.event_name == 'repository_dispatch' && format('repo-dispatch-{0}', github.repository)" "scheduler keeps manual queue scans isolated per repository" - assert_file_contains "$workflow_file" "cancel-in-progress: \${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request_review' || github.event_name == 'repository_dispatch' }}" "scheduler cancels stale PR/review/manual queue scans instead of accumulating merge/update attempts" + assert_file_contains "$workflow_file" "cancel-in-progress: \${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request_review' || github.event_name == 'repository_dispatch' || (github.event_name == 'workflow_run' && !github.event.workflow_run.pull_requests[0].number) }}" "scheduler cancels stale PR/review/manual queue scans and orphaned workflow runs without cancelling active workflow-run evidence" assert_file_contains "$workflow_file" "timeout-minutes: 60" "organization sweep has enough headroom to finish the complete repository walk" assert_file_contains "$workflow_file" "ORG_SWEEP_TRIGGER_REVIEWS: \${{ github.event_name == 'schedule' ||" "scheduled organization sweeps retry missing current-head OpenCode reviews" assert_file_contains "$workflow_file" "ORG_SWEEP_ENABLE_AUTO_MERGE: \${{ github.event_name == 'schedule' ||" "scheduled organization sweeps merge approved current heads" From 919f961bc6cd2a229dccdfc861edcd09485d36f7 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 22 Aug 2026 04:16:22 +0900 Subject: [PATCH 5/8] fix(ci): remove unrelated audit lock drift --- requirements-pip-audit-ci-hashes.txt | 6 +++--- scripts/ci/organization_commercial_readiness_loop.py | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/requirements-pip-audit-ci-hashes.txt b/requirements-pip-audit-ci-hashes.txt index 0ae099d8f..ade197a49 100644 --- a/requirements-pip-audit-ci-hashes.txt +++ b/requirements-pip-audit-ci-hashes.txt @@ -213,9 +213,9 @@ packaging==26.2 \ # via # pip-audit # pip-requirements-parser -pip==26.2.1 \ - --hash=sha256:71138adf1f4ca900cdb7d289c21b7494329f2332b6d85f0e1c42108c0384ed3e \ - --hash=sha256:f6ad667e89a1fe78046c8f13232b247200f5258d7828f3f7883d660878e0813f +pip==26.1.2 \ + --hash=sha256:382ff9f685ee3bc25864f820aa50505825f10f5458ffff07e30a6d96e5715cab \ + --hash=sha256:f49cd134c61cf2fd75e0ce2676db03e4054504a5a4986d00f8299ae632dc4605 # via pip-api pip-api==0.0.34 \ --hash=sha256:8b2d7d7c37f2447373aa2cf8b1f60a2f2b27a84e1e9e0294a3f6ef10eb3ba6bb \ diff --git a/scripts/ci/organization_commercial_readiness_loop.py b/scripts/ci/organization_commercial_readiness_loop.py index c00cfa1e0..a4d7fa983 100644 --- a/scripts/ci/organization_commercial_readiness_loop.py +++ b/scripts/ci/organization_commercial_readiness_loop.py @@ -239,6 +239,7 @@ class GitHubClient: """Use the GitHub CLI as an authenticated, bounded REST transport.""" def __init__(self, token: str, *, timeout_seconds: int = 60) -> None: + """Initialize the client with one bounded GitHub credential.""" if not token: raise GitHubError("GH_TOKEN is required for organization coordination") self._token = token @@ -853,4 +854,4 @@ def main( if __name__ == "__main__": # pragma: no cover - exercised through main() - raise SystemExit(main()) \ No newline at end of file + raise SystemExit(main()) From 0687a05139b02ea3ced394ff089c03c2f9b4427f Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 22 Aug 2026 04:22:17 +0900 Subject: [PATCH 6/8] fix(security): retain patched pip audit pin --- requirements-pip-audit-ci-hashes.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements-pip-audit-ci-hashes.txt b/requirements-pip-audit-ci-hashes.txt index ade197a49..a61530c1e 100644 --- a/requirements-pip-audit-ci-hashes.txt +++ b/requirements-pip-audit-ci-hashes.txt @@ -213,9 +213,9 @@ packaging==26.2 \ # via # pip-audit # pip-requirements-parser -pip==26.1.2 \ - --hash=sha256:382ff9f685ee3bc25864f820aa50505825f10f5458ffff07e30a6d96e5715cab \ - --hash=sha256:f49cd134c61cf2fd75e0ce2676db03e4054504a5a4986d00f8299ae632dc4605 +pip==26.2.1 \ + --hash=sha256:71138adf1f4ca900cdb7d289c21b7494329f2332b6d85e0f1c42108c0384ed3e \ + --hash=sha256:f6ad667e89a1fe78046c8f13232b247200f5258d7828f3f7883d660878e0813f # via pip-api pip-api==0.0.34 \ --hash=sha256:8b2d7d7c37f2447373aa2cf8b1f60a2f2b27a84e1e9e0294a3f6ef10eb3ba6bb \ From 43ad99d2b4ea3e349d2b0662b88c55d7f40ac110 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 22 Aug 2026 05:14:19 +0900 Subject: [PATCH 7/8] fix(coverage): exclude CI hash lock snapshots --- scripts/ci/materialize_base_python_requirements.py | 7 +++++-- tests/test_materialize_base_python_requirements.py | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/ci/materialize_base_python_requirements.py b/scripts/ci/materialize_base_python_requirements.py index c2a44fd44..9be4fc262 100755 --- a/scripts/ci/materialize_base_python_requirements.py +++ b/scripts/ci/materialize_base_python_requirements.py @@ -148,9 +148,12 @@ def _is_candidate_lock_name(name: str) -> bool: return ( ( fnmatch.fnmatch(name, "requirements*.txt") - and not fnmatch.fnmatch(name, "requirements-*-ci-hashes.txt") + and not fnmatch.fnmatch(name, "requirements-*-ci-hashes.*") + ) + or ( + fnmatch.fnmatch(name, "requirements*.lock") + and not fnmatch.fnmatch(name, "requirements-*-ci-hashes.*") ) - or fnmatch.fnmatch(name, "requirements*.lock") ) diff --git a/tests/test_materialize_base_python_requirements.py b/tests/test_materialize_base_python_requirements.py index 0df4967ff..374010edf 100644 --- a/tests/test_materialize_base_python_requirements.py +++ b/tests/test_materialize_base_python_requirements.py @@ -158,6 +158,9 @@ def test_lock_name_candidates_are_pip_requirements_files() -> None: assert not materializer._is_candidate_lock_name( "requirements-opencode-review-ci-hashes.txt" ) + assert not materializer._is_candidate_lock_name( + "requirements-opencode-review-ci-hashes.lock" + ) assert not materializer._is_candidate_lock_name("uv.lock") assert not materializer._is_candidate_lock_name("pyproject.toml") From 0aba0b4a34388672a58dbb2a4625004d1e1fca86 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 22 Aug 2026 05:15:47 +0900 Subject: [PATCH 8/8] fix(security): restore pip audit wheel hash --- requirements-pip-audit-ci-hashes.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-pip-audit-ci-hashes.txt b/requirements-pip-audit-ci-hashes.txt index a61530c1e..0ae099d8f 100644 --- a/requirements-pip-audit-ci-hashes.txt +++ b/requirements-pip-audit-ci-hashes.txt @@ -214,7 +214,7 @@ packaging==26.2 \ # pip-audit # pip-requirements-parser pip==26.2.1 \ - --hash=sha256:71138adf1f4ca900cdb7d289c21b7494329f2332b6d85e0f1c42108c0384ed3e \ + --hash=sha256:71138adf1f4ca900cdb7d289c21b7494329f2332b6d85f0e1c42108c0384ed3e \ --hash=sha256:f6ad667e89a1fe78046c8f13232b247200f5258d7828f3f7883d660878e0813f # via pip-api pip-api==0.0.34 \