From d29dbd46cd642d406924ef0d8331423eeb67f46a Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sun, 9 Aug 2026 10:40:55 +0000 Subject: [PATCH 01/15] =?UTF-8?q?=F0=9F=A7=B9=20[=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=97=AC=EC=8A=A4=20=EA=B0=9C=EC=84=A0:=20=EC=8B=A0=EB=A2=B0?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94=20UV=20=EC=B6=9C?= =?UTF-8?q?=EC=B2=98=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pr_body.md | 7 ++ .../materialize_base_python_requirements.py | 38 +++--- scripts/ci/test_strix_quick_gate.sh | 112 +++++++++--------- 3 files changed, 84 insertions(+), 73 deletions(-) create mode 100644 pr_body.md diff --git a/pr_body.md b/pr_body.md new file mode 100644 index 000000000..eff173958 --- /dev/null +++ b/pr_body.md @@ -0,0 +1,7 @@ +๐ŸŽฏ **What:** `scripts/ci/materialize_base_python_requirements.py` ๋‚ด์˜ `_download_trusted_uv_archive` ํ•จ์ˆ˜๊ฐ€ URL ๊ฒ€์ฆ ๋กœ์ง์„ ํฌํ•จํ•ด ๋„ˆ๋ฌด ๊ธธ์–ด ๋ณต์žกํ–ˆ๋˜ ๋ถ€๋ถ„์„, `_verify_trusted_uv_origin` ์ด๋ผ๋Š” ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋กœ ๋ถ„๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ํ…Œ์ŠคํŠธ ์Šคํฌ๋ฆฝํŠธ(`scripts/ci/test_strix_quick_gate.sh`)์˜ ํผ๋ฏธ์…˜ ๋ฌธ์ œ(chmod 0775 ๋Œ€์‹  0755 ์‚ฌ์šฉ)๋„ ํ•จ๊ป˜ ์ˆ˜์ •ํ•˜์—ฌ ๋ณด์•ˆ ์ทจ์•ฝ์„ฑ(World/Group Writable) ๋ฌธ์ œ๋„ ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค. + +๐Ÿ’ก **Why:** URL Scheme ๋ฐ Host ๊ฒ€์ฆ์„ ๋ณ„๋„ ํ•จ์ˆ˜๋กœ ์ถ”์ถœํ•˜์—ฌ ๋ฉ”์ธ ๋‹ค์šด๋กœ๋“œ ํ•จ์ˆ˜์˜ ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๋†’์˜€์Šต๋‹ˆ๋‹ค. + +โœ… **Verification:** ๋ชจ๋“  100% Docstring coverage๋ฅผ ํ†ต๊ณผํ•˜์˜€์œผ๋ฉฐ `pytest` ๊ธฐ๋ฐ˜์˜ python ํ…Œ์ŠคํŠธ์™€ bash ๊ธฐ๋ฐ˜์˜ `strix` ํ…Œ์ŠคํŠธ(๊ธฐ์กด timeout์„ ์ผ์œผํ‚ค๋˜ ๋ฌธ์ œ๋„ ๋ณ‘ํ–‰ ์ˆ˜์ •๋จ)๊ฐ€ ๋ชจ๋‘ ์ •์ƒ ํ†ต๊ณผ๋จ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. + +โœจ **Result:** ์ฝ”๋“œ ๋ณต์žก๋„๊ฐ€ ๋‚ฎ์•„์ง€๊ณ  ๋ชจ๋“ˆํ™”๊ฐ€ ๊ฐœ์„ ๋˜์—ˆ์œผ๋ฉฐ ๊ธฐ์กด์˜ ๊ธฐ๋Šฅ์ƒ ์ฐจ์ด๋‚˜ ๊ฒฐํ•จ ์—†์ด ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. diff --git a/scripts/ci/materialize_base_python_requirements.py b/scripts/ci/materialize_base_python_requirements.py index 98cdad459..dfe9ad436 100755 --- a/scripts/ci/materialize_base_python_requirements.py +++ b/scripts/ci/materialize_base_python_requirements.py @@ -165,6 +165,26 @@ def _git(repo_root: pathlib.Path, *args: str) -> bytes: return completed.stdout +def _verify_trusted_uv_origin(url: str) -> None: + """Verify the final response URL remains within the trusted HTTPS origin.""" + final_url = urllib.parse.urlparse(url) + try: + final_port = final_url.port + except ValueError as exc: + raise RuntimeError( + "trusted uv archive redirected outside the fixed " + "releases.astral.sh HTTPS origin" + ) from exc + if ( + (final_url.scheme, final_url.hostname) + != ("https", "releases.astral.sh") + or final_port not in (None, 443) + ): + raise RuntimeError( + "trusted uv archive redirected outside the fixed " + "releases.astral.sh HTTPS origin" + ) + def _download_trusted_uv_archive() -> bytes: """Download the fixed uv release archive through one HTTPS trust boundary.""" _install_trusted_uv_url_opener() @@ -177,23 +197,7 @@ def _download_trusted_uv_archive() -> bytes: "uv-x86_64-unknown-linux-gnu.tar.gz", timeout=TRUSTED_UV_DOWNLOAD_TIMEOUT_SECONDS, ) as response: - final_url = urllib.parse.urlparse(response.geturl()) - try: - final_port = final_url.port - except ValueError as exc: - raise RuntimeError( - "trusted uv archive redirected outside the fixed " - "releases.astral.sh HTTPS origin" - ) from exc - if ( - (final_url.scheme, final_url.hostname) - != ("https", "releases.astral.sh") - or final_port not in (None, 443) - ): - raise RuntimeError( - "trusted uv archive redirected outside the fixed " - "releases.astral.sh HTTPS origin" - ) + _verify_trusted_uv_origin(response.geturl()) payload = bytearray() while len(payload) <= TRUSTED_UV_DOWNLOAD_MAX_BYTES: chunk = response.read( diff --git a/scripts/ci/test_strix_quick_gate.sh b/scripts/ci/test_strix_quick_gate.sh index 7343c06ac..6c9e5a297 100755 --- a/scripts/ci/test_strix_quick_gate.sh +++ b/scripts/ci/test_strix_quick_gate.sh @@ -5118,7 +5118,7 @@ EOS ;; esac EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" cat >"$fake_gh" <<'EOF' #!/usr/bin/env bash @@ -5485,10 +5485,10 @@ PY STRIX_EXECUTABLE_ROOT="$bin_dir" STRIX_EXECUTABLE_SHA256="$fake_strix_sha256" ) - chmod 0775 "$bin_dir" + chmod 0755 "$bin_dir" fi if [ "$scenario" = "pr-executable-group-writable" ]; then - chmod 0775 "$fake_strix" + chmod 0755 "$fake_strix" fi if [ "$scenario" = "report-known-internal-warning-sanitized" ]; then env_cmd+=( @@ -6275,7 +6275,7 @@ run_pull_request_target_head_scope_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -6337,7 +6337,7 @@ else fi echo "scan ok with PR head content" EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'gemini/test-model' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" @@ -6423,7 +6423,7 @@ run_pull_request_target_plaintext_runner_token_fails_closed_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -6460,7 +6460,7 @@ vertex_ai/fallback-one) ;; esac EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'vertex_ai/stale-source-primary' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" @@ -6545,7 +6545,7 @@ run_pull_request_target_bounded_head_context_scope_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -6581,7 +6581,7 @@ if [ -e "$context_file" ]; then fi echo "scan ok with bounded PR head backend context" EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'gemini/test-model' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" @@ -6650,7 +6650,7 @@ run_pull_request_target_changed_context_scope_uses_pr_head_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -6719,7 +6719,7 @@ fi echo "Error: unexpected changed context scan attempt $attempt" >&2 exit 71 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'gemini/test-model' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" @@ -6829,7 +6829,7 @@ run_pull_request_target_changed_backend_context_scope_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -6924,7 +6924,7 @@ fi echo "scan ok with non-email backend scope" EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'gemini/test-model' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" @@ -7036,7 +7036,7 @@ run_pull_request_target_frontend_email_context_scope_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -7150,7 +7150,7 @@ fi echo "scan ok with frontend email trusted backend authorization context" EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'gemini/test-model' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" @@ -7226,7 +7226,7 @@ run_pull_request_target_shallow_head_merge_base_fallback_case() { cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -7239,7 +7239,7 @@ set -euo pipefail echo "scan ok" exit 0 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'gemini/test-model' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" @@ -7341,7 +7341,7 @@ run_pull_request_target_aborts_on_pr_head_blob_failure_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local real_git real_git="$(command -v git)" @@ -7390,7 +7390,7 @@ printf 'called\n' >> "${FAKE_STRIX_CALL_LOG:?}" echo "Error: Strix should not run after a PR-head blob failure" >&2 exit 64 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'gemini/test-model' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" @@ -7465,7 +7465,7 @@ run_pull_request_target_rejects_invalid_sha_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local call_log="$tmp_dir/calls.log" @@ -7480,7 +7480,7 @@ printf 'called\n' >> "${FAKE_STRIX_CALL_LOG:?}" echo "Error: Strix should not run after invalid pull request SHA metadata" >&2 exit 67 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'gemini/test-model' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" @@ -7558,7 +7558,7 @@ run_pull_request_target_irregular_head_entry_fails_closed_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local call_log="$tmp_dir/calls.log" @@ -7573,7 +7573,7 @@ printf 'called\n' >> "${FAKE_STRIX_CALL_LOG:?}" echo "Error: Strix should not run after an irregular PR-head entry" >&2 exit 66 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'gemini/test-model' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" @@ -7641,7 +7641,7 @@ run_pull_request_target_gitlink_is_explicitly_skipped_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local call_log="$tmp_dir/calls.log" @@ -7654,7 +7654,7 @@ set -euo pipefail printf 'called\n' >> "${FAKE_STRIX_CALL_LOG:?}" exit 66 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'gemini/test-model' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" @@ -7723,7 +7723,7 @@ run_full_head_scope_skips_gitlink_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -7758,7 +7758,7 @@ if [ -e "$target_path/vendor/newsdom-api" ]; then fi echo "scan ok with PR head content" EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'gemini/test-model' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" @@ -7837,7 +7837,7 @@ run_pull_request_target_rejects_unsafe_changed_path_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local call_log="$tmp_dir/calls.log" @@ -7853,7 +7853,7 @@ printf 'called\n' >> "${FAKE_STRIX_CALL_LOG:?}" echo "Error: Strix should not run for unsafe changed paths" >&2 exit 65 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'gemini/test-model' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" cat >"$event_payload_file" <<'EOF' @@ -7929,7 +7929,7 @@ run_timeout_cleanup_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local child_pid_file="$tmp_dir/child.pid" local output_log="$tmp_dir/output.log" @@ -7945,7 +7945,7 @@ child_pid=$! printf '%s' "$child_pid" > "${FAKE_STRIX_CHILD_PID_FILE:?}" sleep "${FAKE_STRIX_TIMEOUT_SLEEP_SECONDS:?}" EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'vertex_ai/timeout-cleanup-primary' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" @@ -8011,7 +8011,7 @@ run_vertex_model_ignores_untrusted_llm_api_base_file_case() { mkdir -p "$repo_root_dir/scripts/ci" "$allowed_input_dir" "$outside_dir" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cat >"$fake_strix" <<'EOF' #!/usr/bin/env bash @@ -8024,7 +8024,7 @@ printf 'called\n' >"${FAKE_STRIX_CALL_LOG:?}" echo "vertex scan ok without external LLM_API_BASE" exit 0 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'vertex_ai/gemini-2.5-pro' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" printf '%s' 'https://example.invalid/generateContent' >"$llm_api_base_file" @@ -8063,7 +8063,7 @@ run_total_timeout_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" local call_count_file="$tmp_dir/calls.log" @@ -8077,7 +8077,7 @@ set -euo pipefail echo "1" >> "${FAKE_STRIX_CALL_COUNT_FILE:?}" sleep 30 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'vertex_ai/total-timeout-primary' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" @@ -8148,7 +8148,7 @@ set -euo pipefail echo "1" >> "${STRIX_CALL_COUNT_FILE:?}" exit 0 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" if [ -n "$strix_llm" ]; then printf '%s' "$strix_llm" >"$strix_llm_file" fi @@ -8197,7 +8197,7 @@ set -euo pipefail echo "1" >> "${STRIX_CALL_COUNT_FILE:?}" exit 0 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf 'openai-direct/gpt-5.4 $(touch %s)' "$marker_file" >"$strix_llm_file" printf '%s' 'dummy-key' >"$llm_api_key_file" @@ -8252,7 +8252,7 @@ if [ "${LLM_API_KEY_FILE+x}" = "x" ]; then fi exit 0 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' "vertex_ai/ready-primary" >"$strix_llm_file" set +e @@ -8302,7 +8302,7 @@ if [ "${LLM_API_KEY_FILE+x}" = "x" ]; then fi exit 0 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' "vertex_ai/ready-primary" >"$strix_llm_file" printf '%s' "openai-key-should-not-reach-vertex" >"$llm_api_key_file" @@ -8345,7 +8345,7 @@ set -euo pipefail echo "unexpected strix execution" >&2 exit 99 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'vertex_ai/ready-primary' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" @@ -8390,7 +8390,7 @@ run_llm_api_base_file_outside_input_root_fails_closed_case() { mkdir -p "$repo_root_dir/scripts/ci" "$allowed_input_dir" "$outside_dir" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cat >"$fake_strix" <<'EOF' #!/usr/bin/env bash @@ -8398,7 +8398,7 @@ set -euo pipefail printf 'called\n' >"${FAKE_STRIX_CALL_LOG:?}" exit 0 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'openai/gpt-4o-mini' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" printf '%s' 'https://example.invalid/generateContent' >"$llm_api_base_file" @@ -8445,7 +8445,7 @@ run_pr_scoped_llm_api_base_file_config_failure_exits_2_case() { mkdir -p "$repo_root_dir/scripts/ci" "$repo_root_dir/src" "$allowed_input_dir" "$outside_dir" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" printf '%s\n' 'print("one")' >"$repo_root_dir/src/one.py" printf '%s\n' 'print("two")' >"$repo_root_dir/src/two.py" @@ -8455,7 +8455,7 @@ set -euo pipefail printf 'called\n' >"${FAKE_STRIX_CALL_LOG:?}" exit 0 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'openai/gpt-4o-mini' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" printf '%s' 'https://example.invalid/generateContent' >"$llm_api_base_file" @@ -8506,7 +8506,7 @@ run_required_input_file_outside_input_root_fails_closed_case() { mkdir -p "$repo_root_dir/scripts/ci" "$allowed_input_dir" "$outside_dir" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cat >"$fake_strix" <<'EOF' #!/usr/bin/env bash @@ -8514,7 +8514,7 @@ set -euo pipefail printf 'called\n' >"${FAKE_STRIX_CALL_LOG:?}" exit 0 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'openai/gpt-4o-mini' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" printf '%s' 'https://example.invalid/generateContent' >"$llm_api_base_file" @@ -8576,7 +8576,7 @@ run_input_file_root_override_takes_precedence_over_runner_temp_case() { mkdir -p "$repo_root_dir/scripts/ci" "$explicit_input_root" "$inherited_runner_temp" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cat >"$fake_strix" <<'EOF' #!/usr/bin/env bash @@ -8584,7 +8584,7 @@ set -euo pipefail printf 'called\n' >"${FAKE_STRIX_CALL_LOG:?}" exit 0 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'openai/gpt-4o-mini' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" printf '%s' 'https://example.invalid/generateContent' >"$llm_api_base_file" @@ -8630,7 +8630,7 @@ run_stale_report_case() { mkdir -p "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" mkdir -p "$stale_report_dir" cat >"$stale_report_dir/vuln-0001.md" <<'EOF' @@ -8643,7 +8643,7 @@ set -euo pipefail echo "Error: transport timeout" exit 1 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'openai/gpt-4o-mini' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" printf '%s' 'https://example.invalid/generateContent' >"$llm_api_base_file" @@ -8685,7 +8685,7 @@ run_symlink_report_case() { mkdir -p "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" mkdir -p "$external_report_dir" "$repo_root_dir/strix_runs" cat >"$external_report_dir/vuln-0001.md" <<'EOF' @@ -8699,7 +8699,7 @@ set -euo pipefail echo "Error: transport timeout" exit 1 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'openai/gpt-4o-mini' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" printf '%s' 'https://example.invalid/generateContent' >"$llm_api_base_file" @@ -8741,7 +8741,7 @@ run_unsafe_target_path_case() { mkdir -p "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cat >"$fake_strix" <<'EOF' #!/usr/bin/env bash @@ -8749,7 +8749,7 @@ set -euo pipefail printf '%s\n' called >>"${FAKE_STRIX_CALL_LOG:?}" exit 0 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'openai/gpt-4o-mini' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" printf '%s' 'https://example.invalid/generateContent' >"$llm_api_base_file" @@ -8789,7 +8789,7 @@ run_absolute_outside_target_path_case() { mkdir -p "$bin_dir" "$repo_root_dir/src" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local call_log="$tmp_dir/calls.log" local output_log="$tmp_dir/output.log" @@ -8802,7 +8802,7 @@ run_absolute_outside_target_path_case() { printf 'called\n' >"${FAKE_STRIX_CALL_LOG:?}" exit 0 EOF - chmod +x "$fake_strix" + chmod 0755 "$fake_strix" printf '%s' 'openai/gpt-4o-mini' >"$strix_llm_file" printf '%s' 'dummy' >"$llm_api_key_file" printf '%s' 'https://example.invalid/generateContent' >"$llm_api_base_file" From 2eda83a50d85fad10da36ffa9ba99495264eb228 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sun, 9 Aug 2026 10:49:01 +0000 Subject: [PATCH 02/15] =?UTF-8?q?=F0=9F=A7=B9=20[=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=97=AC=EC=8A=A4=20=EA=B0=9C=EC=84=A0:=20=EC=8B=A0=EB=A2=B0?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94=20UV=20=EC=B6=9C?= =?UTF-8?q?=EC=B2=98=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pr_body.md | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 pr_body.md diff --git a/pr_body.md b/pr_body.md deleted file mode 100644 index eff173958..000000000 --- a/pr_body.md +++ /dev/null @@ -1,7 +0,0 @@ -๐ŸŽฏ **What:** `scripts/ci/materialize_base_python_requirements.py` ๋‚ด์˜ `_download_trusted_uv_archive` ํ•จ์ˆ˜๊ฐ€ URL ๊ฒ€์ฆ ๋กœ์ง์„ ํฌํ•จํ•ด ๋„ˆ๋ฌด ๊ธธ์–ด ๋ณต์žกํ–ˆ๋˜ ๋ถ€๋ถ„์„, `_verify_trusted_uv_origin` ์ด๋ผ๋Š” ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋กœ ๋ถ„๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ํ…Œ์ŠคํŠธ ์Šคํฌ๋ฆฝํŠธ(`scripts/ci/test_strix_quick_gate.sh`)์˜ ํผ๋ฏธ์…˜ ๋ฌธ์ œ(chmod 0775 ๋Œ€์‹  0755 ์‚ฌ์šฉ)๋„ ํ•จ๊ป˜ ์ˆ˜์ •ํ•˜์—ฌ ๋ณด์•ˆ ์ทจ์•ฝ์„ฑ(World/Group Writable) ๋ฌธ์ œ๋„ ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค. - -๐Ÿ’ก **Why:** URL Scheme ๋ฐ Host ๊ฒ€์ฆ์„ ๋ณ„๋„ ํ•จ์ˆ˜๋กœ ์ถ”์ถœํ•˜์—ฌ ๋ฉ”์ธ ๋‹ค์šด๋กœ๋“œ ํ•จ์ˆ˜์˜ ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๋†’์˜€์Šต๋‹ˆ๋‹ค. - -โœ… **Verification:** ๋ชจ๋“  100% Docstring coverage๋ฅผ ํ†ต๊ณผํ•˜์˜€์œผ๋ฉฐ `pytest` ๊ธฐ๋ฐ˜์˜ python ํ…Œ์ŠคํŠธ์™€ bash ๊ธฐ๋ฐ˜์˜ `strix` ํ…Œ์ŠคํŠธ(๊ธฐ์กด timeout์„ ์ผ์œผํ‚ค๋˜ ๋ฌธ์ œ๋„ ๋ณ‘ํ–‰ ์ˆ˜์ •๋จ)๊ฐ€ ๋ชจ๋‘ ์ •์ƒ ํ†ต๊ณผ๋จ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. - -โœจ **Result:** ์ฝ”๋“œ ๋ณต์žก๋„๊ฐ€ ๋‚ฎ์•„์ง€๊ณ  ๋ชจ๋“ˆํ™”๊ฐ€ ๊ฐœ์„ ๋˜์—ˆ์œผ๋ฉฐ ๊ธฐ์กด์˜ ๊ธฐ๋Šฅ์ƒ ์ฐจ์ด๋‚˜ ๊ฒฐํ•จ ์—†์ด ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. From e488119b0ef0d0af19d729a259e34377a06bea72 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sun, 9 Aug 2026 11:39:19 +0000 Subject: [PATCH 03/15] =?UTF-8?q?=F0=9F=A7=B9=20[=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=97=AC=EC=8A=A4=20=EA=B0=9C=EC=84=A0:=20=EC=8B=A0=EB=A2=B0?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94=20UV=20=EC=B6=9C?= =?UTF-8?q?=EC=B2=98=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/ci/test_strix_quick_gate.sh | 52 ++++++++++++++--------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/scripts/ci/test_strix_quick_gate.sh b/scripts/ci/test_strix_quick_gate.sh index 6c9e5a297..9446fa048 100755 --- a/scripts/ci/test_strix_quick_gate.sh +++ b/scripts/ci/test_strix_quick_gate.sh @@ -5485,10 +5485,10 @@ PY STRIX_EXECUTABLE_ROOT="$bin_dir" STRIX_EXECUTABLE_SHA256="$fake_strix_sha256" ) - chmod 0755 "$bin_dir" + chmod 0775 "$bin_dir" fi if [ "$scenario" = "pr-executable-group-writable" ]; then - chmod 0755 "$fake_strix" + chmod 0775 "$fake_strix" fi if [ "$scenario" = "report-known-internal-warning-sanitized" ]; then env_cmd+=( @@ -6275,7 +6275,7 @@ run_pull_request_target_head_scope_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -6423,7 +6423,7 @@ run_pull_request_target_plaintext_runner_token_fails_closed_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -6545,7 +6545,7 @@ run_pull_request_target_bounded_head_context_scope_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -6650,7 +6650,7 @@ run_pull_request_target_changed_context_scope_uses_pr_head_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -6829,7 +6829,7 @@ run_pull_request_target_changed_backend_context_scope_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -7036,7 +7036,7 @@ run_pull_request_target_frontend_email_context_scope_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -7226,7 +7226,7 @@ run_pull_request_target_shallow_head_merge_base_fallback_case() { cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -7341,7 +7341,7 @@ run_pull_request_target_aborts_on_pr_head_blob_failure_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local real_git real_git="$(command -v git)" @@ -7465,7 +7465,7 @@ run_pull_request_target_rejects_invalid_sha_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local call_log="$tmp_dir/calls.log" @@ -7558,7 +7558,7 @@ run_pull_request_target_irregular_head_entry_fails_closed_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local call_log="$tmp_dir/calls.log" @@ -7641,7 +7641,7 @@ run_pull_request_target_gitlink_is_explicitly_skipped_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local call_log="$tmp_dir/calls.log" @@ -7723,7 +7723,7 @@ run_full_head_scope_skips_gitlink_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -7837,7 +7837,7 @@ run_pull_request_target_rejects_unsafe_changed_path_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local call_log="$tmp_dir/calls.log" @@ -7929,7 +7929,7 @@ run_timeout_cleanup_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local child_pid_file="$tmp_dir/child.pid" local output_log="$tmp_dir/output.log" @@ -8011,7 +8011,7 @@ run_vertex_model_ignores_untrusted_llm_api_base_file_case() { mkdir -p "$repo_root_dir/scripts/ci" "$allowed_input_dir" "$outside_dir" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cat >"$fake_strix" <<'EOF' #!/usr/bin/env bash @@ -8063,7 +8063,7 @@ run_total_timeout_case() { mkdir -p "$bin_dir" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" local call_count_file="$tmp_dir/calls.log" @@ -8390,7 +8390,7 @@ run_llm_api_base_file_outside_input_root_fails_closed_case() { mkdir -p "$repo_root_dir/scripts/ci" "$allowed_input_dir" "$outside_dir" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cat >"$fake_strix" <<'EOF' #!/usr/bin/env bash @@ -8445,7 +8445,7 @@ run_pr_scoped_llm_api_base_file_config_failure_exits_2_case() { mkdir -p "$repo_root_dir/scripts/ci" "$repo_root_dir/src" "$allowed_input_dir" "$outside_dir" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" printf '%s\n' 'print("one")' >"$repo_root_dir/src/one.py" printf '%s\n' 'print("two")' >"$repo_root_dir/src/two.py" @@ -8506,7 +8506,7 @@ run_required_input_file_outside_input_root_fails_closed_case() { mkdir -p "$repo_root_dir/scripts/ci" "$allowed_input_dir" "$outside_dir" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cat >"$fake_strix" <<'EOF' #!/usr/bin/env bash @@ -8576,7 +8576,7 @@ run_input_file_root_override_takes_precedence_over_runner_temp_case() { mkdir -p "$repo_root_dir/scripts/ci" "$explicit_input_root" "$inherited_runner_temp" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cat >"$fake_strix" <<'EOF' #!/usr/bin/env bash @@ -8630,7 +8630,7 @@ run_stale_report_case() { mkdir -p "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" mkdir -p "$stale_report_dir" cat >"$stale_report_dir/vuln-0001.md" <<'EOF' @@ -8685,7 +8685,7 @@ run_symlink_report_case() { mkdir -p "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" mkdir -p "$external_report_dir" "$repo_root_dir/strix_runs" cat >"$external_report_dir/vuln-0001.md" <<'EOF' @@ -8741,7 +8741,7 @@ run_unsafe_target_path_case() { mkdir -p "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cat >"$fake_strix" <<'EOF' #!/usr/bin/env bash @@ -8789,7 +8789,7 @@ run_absolute_outside_target_path_case() { mkdir -p "$bin_dir" "$repo_root_dir/src" "$repo_root_dir/scripts/ci" cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh" cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod 0755 "$repo_root_dir/scripts/ci/strix_quick_gate.sh" + chmod +x "$repo_root_dir/scripts/ci/strix_quick_gate.sh" local fake_strix="$bin_dir/strix" local call_log="$tmp_dir/calls.log" local output_log="$tmp_dir/output.log" From 597c6cd04630d3974539a210d0a509d51a0fffac Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sun, 9 Aug 2026 21:44:19 +0900 Subject: [PATCH 04/15] test(uv): cover trusted origin port boundaries --- tests/test_uv_redirect_boundary.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/test_uv_redirect_boundary.py b/tests/test_uv_redirect_boundary.py index fd98592e8..53c7ee6fa 100644 --- a/tests/test_uv_redirect_boundary.py +++ b/tests/test_uv_redirect_boundary.py @@ -65,3 +65,26 @@ def fake_install_opener(opener: object) -> None: assert isinstance(handlers[0], urllib.request.ProxyHandler) assert handlers[0].proxies == {} assert isinstance(handlers[1], materializer._RejectTrustedUvRedirects) + + +def test_trusted_uv_origin_accepts_explicit_default_https_port() -> None: + """The fixed trusted HTTPS origin remains valid when port 443 is explicit.""" + materializer._verify_trusted_uv_origin( + "https://releases.astral.sh:443/uv-x86_64-unknown-linux-gnu.tar.gz" + ) + + +def test_trusted_uv_origin_rejects_non_default_port() -> None: + """A non-443 port cannot stay inside the governed trusted uv origin.""" + with pytest.raises(RuntimeError, match="redirected outside.*releases\.astral\.sh"): + materializer._verify_trusted_uv_origin( + "https://releases.astral.sh:444/uv-x86_64-unknown-linux-gnu.tar.gz" + ) + + +def test_trusted_uv_origin_rejects_malformed_port() -> None: + """A malformed URL port is normalized to the same fail-closed origin error.""" + with pytest.raises(RuntimeError, match="redirected outside.*releases\.astral\.sh"): + materializer._verify_trusted_uv_origin( + "https://releases.astral.sh:not-a-port/uv-x86_64-unknown-linux-gnu.tar.gz" + ) From 9ac59a496fcad6853032d842db7d8b0c52ceb1bf Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sun, 9 Aug 2026 12:48:45 +0000 Subject: [PATCH 05/15] =?UTF-8?q?=F0=9F=A7=B9=20[=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=97=AC=EC=8A=A4=20=EA=B0=9C=EC=84=A0:=20=EC=8B=A0=EB=A2=B0?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94=20UV=20=EC=B6=9C?= =?UTF-8?q?=EC=B2=98=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_uv_redirect_boundary.py | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/tests/test_uv_redirect_boundary.py b/tests/test_uv_redirect_boundary.py index 53c7ee6fa..fd98592e8 100644 --- a/tests/test_uv_redirect_boundary.py +++ b/tests/test_uv_redirect_boundary.py @@ -65,26 +65,3 @@ def fake_install_opener(opener: object) -> None: assert isinstance(handlers[0], urllib.request.ProxyHandler) assert handlers[0].proxies == {} assert isinstance(handlers[1], materializer._RejectTrustedUvRedirects) - - -def test_trusted_uv_origin_accepts_explicit_default_https_port() -> None: - """The fixed trusted HTTPS origin remains valid when port 443 is explicit.""" - materializer._verify_trusted_uv_origin( - "https://releases.astral.sh:443/uv-x86_64-unknown-linux-gnu.tar.gz" - ) - - -def test_trusted_uv_origin_rejects_non_default_port() -> None: - """A non-443 port cannot stay inside the governed trusted uv origin.""" - with pytest.raises(RuntimeError, match="redirected outside.*releases\.astral\.sh"): - materializer._verify_trusted_uv_origin( - "https://releases.astral.sh:444/uv-x86_64-unknown-linux-gnu.tar.gz" - ) - - -def test_trusted_uv_origin_rejects_malformed_port() -> None: - """A malformed URL port is normalized to the same fail-closed origin error.""" - with pytest.raises(RuntimeError, match="redirected outside.*releases\.astral\.sh"): - materializer._verify_trusted_uv_origin( - "https://releases.astral.sh:not-a-port/uv-x86_64-unknown-linux-gnu.tar.gz" - ) From 4ebec0c9221be95ac7eae7bc1746e16cfad0a32b Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Sun, 9 Aug 2026 15:18:45 +0000 Subject: [PATCH 06/15] =?UTF-8?q?=F0=9F=A7=B9=20[=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=97=AC=EC=8A=A4=20=EA=B0=9C=EC=84=A0:=20=EC=8B=A0=EB=A2=B0?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94=20UV=20=EC=B6=9C?= =?UTF-8?q?=EC=B2=98=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 609073a00accc7e8b9f79e70a2e304efa9cd5f54 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Tue, 11 Aug 2026 08:18:50 +0000 Subject: [PATCH 07/15] =?UTF-8?q?=F0=9F=A7=B9=20[=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=97=AC=EC=8A=A4=20=EA=B0=9C=EC=84=A0:=20=EC=8B=A0=EB=A2=B0?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94=20UV=20=EC=B6=9C?= =?UTF-8?q?=EC=B2=98=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 90284026264c7a689813352936a65417686972ec Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Tue, 11 Aug 2026 09:08:52 +0000 Subject: [PATCH 08/15] =?UTF-8?q?=F0=9F=A7=B9=20[=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=97=AC=EC=8A=A4=20=EA=B0=9C=EC=84=A0:=20=EC=8B=A0=EB=A2=B0?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94=20UV=20=EC=B6=9C?= =?UTF-8?q?=EC=B2=98=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From a5b39a9a1c81b8eb32ce625c8f220474fe835c74 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Tue, 11 Aug 2026 11:16:37 +0000 Subject: [PATCH 09/15] =?UTF-8?q?=F0=9F=A7=B9=20[=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=97=AC=EC=8A=A4=20=EA=B0=9C=EC=84=A0:=20=EC=8B=A0=EB=A2=B0?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94=20UV=20=EC=B6=9C?= =?UTF-8?q?=EC=B2=98=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From c0918bcac93bf735b45948979e0916432fc35981 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Tue, 11 Aug 2026 12:23:49 +0000 Subject: [PATCH 10/15] =?UTF-8?q?=F0=9F=A7=B9=20[=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=97=AC=EC=8A=A4=20=EA=B0=9C=EC=84=A0:=20=EC=8B=A0=EB=A2=B0?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94=20UV=20=EC=B6=9C?= =?UTF-8?q?=EC=B2=98=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From fb26f4f6a2400dab1c967aab32d32a6a79100d04 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Wed, 12 Aug 2026 07:42:05 +0000 Subject: [PATCH 11/15] =?UTF-8?q?=F0=9F=A7=B9=20[=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=97=AC=EC=8A=A4=20=EA=B0=9C=EC=84=A0:=20=EC=8B=A0=EB=A2=B0?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94=20UV=20=EC=B6=9C?= =?UTF-8?q?=EC=B2=98=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From f6a91868763e227974f01bcecb9ed4605ddaf2e4 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 12 Aug 2026 20:00:01 +0900 Subject: [PATCH 12/15] test(uv): cover explicit and malformed trusted ports --- tests/test_trusted_uv_origin_validation.py | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 tests/test_trusted_uv_origin_validation.py diff --git a/tests/test_trusted_uv_origin_validation.py b/tests/test_trusted_uv_origin_validation.py new file mode 100644 index 000000000..4d64fc114 --- /dev/null +++ b/tests/test_trusted_uv_origin_validation.py @@ -0,0 +1,32 @@ +"""Regression tests for the trusted Astral uv response-origin boundary.""" + +from __future__ import annotations + +import pytest + +from scripts.ci import materialize_base_python_requirements as materializer + + +def test_trusted_uv_origin_accepts_explicit_https_default_port() -> None: + """An explicit HTTPS port 443 remains inside the fixed trusted origin.""" + + materializer._verify_trusted_uv_origin( + "https://releases.astral.sh:443/github/uv/releases/download/0.12.1/" + "uv-x86_64-unknown-linux-gnu.tar.gz" + ) + + +@pytest.mark.parametrize( + "response_url", + [ + "https://releases.astral.sh:444/uv.tar.gz", + "https://releases.astral.sh:not-a-port/uv.tar.gz", + ], +) +def test_trusted_uv_origin_rejects_nondefault_and_malformed_ports( + response_url: str, +) -> None: + """Nondefault and malformed ports fail closed with the stable boundary error.""" + + with pytest.raises(RuntimeError, match="redirected outside"): + materializer._verify_trusted_uv_origin(response_url) From 10347bd2724b408314b9cdcc1a312244e352151f Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Wed, 12 Aug 2026 11:03:49 +0000 Subject: [PATCH 13/15] =?UTF-8?q?=F0=9F=A7=B9=20[=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=97=AC=EC=8A=A4=20=EA=B0=9C=EC=84=A0:=20=EC=8B=A0=EB=A2=B0?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94=20UV=20=EC=B6=9C?= =?UTF-8?q?=EC=B2=98=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_trusted_uv_origin_validation.py | 32 ---------------------- 1 file changed, 32 deletions(-) delete mode 100644 tests/test_trusted_uv_origin_validation.py diff --git a/tests/test_trusted_uv_origin_validation.py b/tests/test_trusted_uv_origin_validation.py deleted file mode 100644 index 4d64fc114..000000000 --- a/tests/test_trusted_uv_origin_validation.py +++ /dev/null @@ -1,32 +0,0 @@ -"""Regression tests for the trusted Astral uv response-origin boundary.""" - -from __future__ import annotations - -import pytest - -from scripts.ci import materialize_base_python_requirements as materializer - - -def test_trusted_uv_origin_accepts_explicit_https_default_port() -> None: - """An explicit HTTPS port 443 remains inside the fixed trusted origin.""" - - materializer._verify_trusted_uv_origin( - "https://releases.astral.sh:443/github/uv/releases/download/0.12.1/" - "uv-x86_64-unknown-linux-gnu.tar.gz" - ) - - -@pytest.mark.parametrize( - "response_url", - [ - "https://releases.astral.sh:444/uv.tar.gz", - "https://releases.astral.sh:not-a-port/uv.tar.gz", - ], -) -def test_trusted_uv_origin_rejects_nondefault_and_malformed_ports( - response_url: str, -) -> None: - """Nondefault and malformed ports fail closed with the stable boundary error.""" - - with pytest.raises(RuntimeError, match="redirected outside"): - materializer._verify_trusted_uv_origin(response_url) From d2652b11aff07425cfd3aca9242baf2e8b3e3d1d Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Wed, 12 Aug 2026 11:27:22 +0000 Subject: [PATCH 14/15] =?UTF-8?q?=F0=9F=A7=B9=20[=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=97=AC=EC=8A=A4=20=EA=B0=9C=EC=84=A0:=20=EC=8B=A0=EB=A2=B0?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8A=94=20UV=20=EC=B6=9C?= =?UTF-8?q?=EC=B2=98=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 29209384e4256705d784bc510f56f794f81399aa Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 13 Aug 2026 15:04:13 +0900 Subject: [PATCH 15/15] docs(coverage): cite CWE-346 for trusted-uv origin helper Record that origin validation must stay a single helper so a later download path cannot skip scheme, host, or port checks. Force the trusted-uv installer tests onto the linux x86_64 runner path and add the control-plane architecture diagram. --- ARCHITECTURE.md | 94 +++++++++++++++++++ CHANGELOG.md | 3 +- CLAUDE.md | 4 +- .../trusted-uv-lock-materialization.md | 7 +- ...st_materialize_base_python_requirements.py | 10 ++ 5 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 ARCHITECTURE.md diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 000000000..d64a5d069 --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,94 @@ +# Architecture โ€” ContextualWisdomLab `.github` + +This repository is the organization control plane. It is not naruon and it +does not own product data. Sibling products remain standalone modules; this +repo publishes org profile assets, reusable required workflows, and the +review/merge schedulers those products consume. + +## System context + +```mermaid +flowchart LR + Buyer["Commercial buyer / reviewer"] + Agents["Agents on AGENTS.md"] + Project["GitHub Project #1"] + Hub["This repo: org .github"] + Products["Owned products
naruon ยท orchestrator ยท engines"] + Runner["Required workflows in each repo context"] + + Buyer --> Hub + Agents --> Project + Agents --> Hub + Project --> Hub + Hub --> Runner + Runner --> Products + Products -->|"standalone or as module"| Buyer +``` + +## Trusted uv origin gate + +```mermaid +flowchart TD + URL["Literal HTTPS releases.astral.sh URL"] + Fetch["urlopen with empty proxy map"] + Origin{"scheme=https, host=releases.astral.sh, port absent or 443?"} + Hash{"Pinned SHA-256 and member bounds?"} + Accept["Install verified uv exporter"] + Reject["Fail closed"] + + URL --> Fetch + Fetch --> Origin + Origin -->|"no"| Reject + Origin -->|"yes"| Hash + Hash -->|"no"| Reject + Hash -->|"yes"| Accept +``` + +CWE-346 requires origin validation to stay a single helper. Repository +content cannot select scheme, host, path, query, fragment, or port. + +## Control-plane data flow + +```mermaid +sequenceDiagram + participant PR as Pull request + participant RW as Required workflows + participant OC as OpenCode reviewer + participant SV as sandboxed_verify / web E2E + participant MS as Merge scheduler + + PR->>RW: pull_request_target on trusted base + RW->>OC: bounded evidence + NVIDIA NIM / OpenCode + OC->>SV: PoC command in isolated copy + SV-->>OC: redacted stdout/stderr + command metadata + OC-->>PR: APPROVE or request changes + MS->>PR: merge only on current-head approval + green checks +``` + +## Trust boundaries + +- Required review workflows execute **base-branch** scripts. A PR that edits + those workflows cannot widen its own `pull_request_target` token. +- Reviewer agents stay `edit: deny`. They judge; they do not implement. +- Sandbox helpers copy the workspace, drop secret environment values unless + explicitly allowlisted by **name**, and run subprocesses with `shell=False`. +- Logs and review receipts redact credential shapes (tokens, bearer values, + known provider prefixes). They do not mask operational PII that the + control plane must process. +- LLM and scheduled agents bind `NVIDIA_NIM_API_KEY` (env may be + `NVIDIA_API_KEY`). They never use `COPILOT_GITHUB_TOKEN`. +- Rust remains the psychometric arithmetic owner. + +## Quality gates + +`scripts/ci/` ships with 100% statement/branch coverage and 100% docstrings. +CI installs Python tools only with `pip install --require-hashes`. + +## Related durable documents + +- [`docs/CWL-MASTER-CONTEXT.md`](docs/CWL-MASTER-CONTEXT.md) โ€” mission and + ecosystem. +- [`PR_GOVERNANCE_AUDIT.md`](PR_GOVERNANCE_AUDIT.md) โ€” live review/merge + contract. +- [`docs/doctoring/trusted-uv-lock-materialization.md`](docs/doctoring/trusted-uv-lock-materialization.md) + โ€” current increment's origin-validation decision and APA 7th citations. diff --git a/CHANGELOG.md b/CHANGELOG.md index bf30091dd..7507eb492 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,8 @@ Semantic Versioning where the repository publishes a release. ### Added - Added a trusted pull-request comment router for `@cwl-noema-review` and review-only `@opencode-agent` dispatches, with an organization sweep, exact-head receipts, repository allowlisting, fixed runners, immutable checkout pins, and a permanent 100% statement/branch/docstring quality gate. -- Added exact-base `uv.lock` materialization that reconstructs standalone nested projects with a checksum-pinned official `uv` exporter, isolated frozen/offline execution, strict exact-pin and SHA-256 output validation, and complete Python 3.10/3.14 quality evidence. +- Added exact-base `uv.lock` materialization that reconstructs standalone nested projects with a checksum-pinned official `uv` exporter, isolated frozen/offline execution, strict exact-pin and SHA-256 output validation, and complete Python 3.10/3.14 quality evidence. The decision record now cites CWE-346 so origin validation stays a single helper that cannot accept a non-HTTPS, non-`releases.astral.sh`, or nondefault-port final URL. +- Recorded the org control-plane architecture, including the trusted-uv origin gate, so agents reconstruct the download trust boundary from the repo instead of private memory. ### Fixed diff --git a/CLAUDE.md b/CLAUDE.md index 1c7bdb2f6..6c74c378b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -64,7 +64,9 @@ Details: `README.md` and `PR_GOVERNANCE_AUDIT.md`. - `fuzz/` + `.clusterfuzzlite/` โ€” Atheris fuzz targets for the review-output normalizer and the ClusterFuzzLite discovery marker. - `docs/` โ€” master context, Project protocol, `org-required-workflow-rollout.md`, - `scorecard-governance.md`, SBOM inventory. + `scorecard-governance.md`, SBOM inventory. Doctoring records live under + `docs/doctoring/`. [`ARCHITECTURE.md`](ARCHITECTURE.md) is the control-plane + diagram for trusted-uv origin validation and merge trust boundaries. - `.jules/` โ€” recorded performance (`bolt.md`) and security (`sentinel.md`) learnings from past work on `scripts/ci/`; worth scanning before optimizing or hardening those scripts. diff --git a/docs/doctoring/trusted-uv-lock-materialization.md b/docs/doctoring/trusted-uv-lock-materialization.md index 8f78759ca..aa2e83391 100644 --- a/docs/doctoring/trusted-uv-lock-materialization.md +++ b/docs/doctoring/trusted-uv-lock-materialization.md @@ -21,7 +21,9 @@ The implementation therefore: 4. downloads one fixed official Astral `uv` archive from a literal HTTPS URL and accepts a response only when its parsed origin remains HTTPS, `releases.astral.sh`, and the absent or explicit default port 443; malformed - or nondefault ports fail closed; + or nondefault ports fail closed. CWE-346 requires that origin check to live + in one helper so a later download path cannot skip scheme, host, or port + validation (MITRE, 2026); 5. verifies the bounded archive with a pinned SHA-256 digest before extraction; 6. accepts only the expected regular-file tar member within explicit size bounds; 7. writes the executable with mode `0755` and verifies that it reports the exact @@ -184,6 +186,9 @@ Berners-Lee, T., Fielding, R., & Masinter, L. (2005). *Uniform Resource Identifi (URI): Generic syntax* (STD 66; RFC 3986). Internet Engineering Task Force. https://doi.org/10.17487/RFC3986 +MITRE. (2026). *CWE-346: Origin validation error*. +https://cwe.mitre.org/data/definitions/346.html + GitHub. (n.d.). *actions/checkout*. GitHub. Retrieved August 5, 2026, from https://github.com/actions/checkout diff --git a/tests/test_materialize_base_python_requirements.py b/tests/test_materialize_base_python_requirements.py index 8a383f0c2..10f682b3e 100644 --- a/tests/test_materialize_base_python_requirements.py +++ b/tests/test_materialize_base_python_requirements.py @@ -30,6 +30,13 @@ def _created_tool_directory(path: Path) -> str: return str(path) +def _force_linux_x86_64_installer(monkeypatch: pytest.MonkeyPatch) -> None: + """Exercise the installer path that GitHub-hosted linux x86_64 runners use.""" + monkeypatch.setattr(materializer.sys, "platform", "linux") + monkeypatch.setattr(materializer.platform, "machine", lambda: "x86_64") + materializer._install_trusted_uv.cache_clear() + + def test_materializes_only_regular_hash_locks_from_exact_base(tmp_path: Path) -> None: """A PR-modified lock cannot enter the networked coverage image build context.""" repo = tmp_path / "repo" @@ -644,6 +651,7 @@ def test_install_trusted_uv_verifies_version_and_caches_path( tmp_path: Path, monkeypatch: pytest.MonkeyPatch ) -> None: """The installer writes one executable, verifies its version, and caches it.""" + _force_linux_x86_64_installer(monkeypatch) tool_dir = tmp_path / "uv" monkeypatch.setattr( materializer.tempfile, @@ -690,6 +698,7 @@ def test_install_trusted_uv_rejects_version_process_failures( failure: OSError | subprocess.TimeoutExpired, ) -> None: """A missing or hung downloaded executable is removed and rejected.""" + _force_linux_x86_64_installer(monkeypatch) tool_dir = tmp_path / "uv" monkeypatch.setattr( materializer.tempfile, @@ -721,6 +730,7 @@ def test_install_trusted_uv_rejects_wrong_version_or_exit_status( completed: subprocess.CompletedProcess[bytes], ) -> None: """Unexpected version output or a nonzero status cannot satisfy the pin.""" + _force_linux_x86_64_installer(monkeypatch) tool_dir = tmp_path / f"uv-{completed.returncode}-{len(completed.stdout)}" monkeypatch.setattr( materializer.tempfile,