diff --git a/scripts/ci/test_strix_quick_gate.sh b/scripts/ci/test_strix_quick_gate.sh index 938f717363..28cf2e4e36 100755 --- a/scripts/ci/test_strix_quick_gate.sh +++ b/scripts/ci/test_strix_quick_gate.sh @@ -14,6 +14,16 @@ REPO_ROOT="$( GATE_SCRIPT="$REPO_ROOT/scripts/ci/strix_quick_gate.sh" FAILURES=0 + +materialize_trusted_gate_fixture() { + local fixture_script_dir="$1" + + mkdir -p "$fixture_script_dir" + cp "$GATE_SCRIPT" "$fixture_script_dir/strix_quick_gate.sh" + cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$fixture_script_dir/strix_model_utils.sh" + cp "$REPO_ROOT/scripts/ci/strix_evidence_binding.py" "$fixture_script_dir/strix_evidence_binding.py" + chmod +x "$fixture_script_dir/strix_quick_gate.sh" +} TIMEOUT_TEST_PROCESS_SECONDS="${STRIX_TEST_PROCESS_TIMEOUT_SECONDS:-30}" TIMEOUT_TEST_FAKE_SLEEP_SECONDS="${STRIX_TEST_FAKE_SLEEP_SECONDS:-60}" @@ -640,7 +650,7 @@ assert_opencode_review_uses_codegraph_and_contextual_orchestrator() { assert_file_not_contains "$workflow_file" 'ref: ${{ github.workflow_sha }}' "opencode trusted checkout never bypasses the validated ref output" assert_file_contains "$workflow_file" "target_repository:" "opencode repository_dispatch can target a repository whose PR does not inherit required workflows" assert_file_contains "$workflow_file" "Materialize pull request merge tree for coverage measurement" "opencode coverage measures the PR merge tree instead of exposing secrets to untrusted checkout actions" - assert_file_contains "$workflow_file" 'TARGET_REPOSITORY: ${{ needs.validate-pr-metadata.outputs.target_repository }}' "opencode coverage fetches exact validated base/head commits from the target repository" + assert_file_contains "$workflow_file" 'TARGET_REPOSITORY: ${{ steps.validate.outputs.target_repository }}' "opencode coverage fetches exact validated base/head commits from the target repository" assert_file_contains "$workflow_file" "Exchange OpenCode app token for target repository review reads" "opencode review can read private target repositories through the OpenCode app token before materializing review data" assert_file_contains "$workflow_file" 'GH_TOKEN: ${{ steps.review_read_app_token.outputs.token || secrets.OPENCODE_APPROVE_TOKEN || github.token }}' "opencode materialization prefers the OpenCode app token for private target repository reads" assert_file_contains "$workflow_file" '[ "${GH_REPOSITORY:-}" != "${GITHUB_REPOSITORY:-}" ]' "opencode approval uses the app token for target-repository check lookup" @@ -968,13 +978,13 @@ assert_opencode_review_uses_codegraph_and_contextual_orchestrator() { assert_file_contains "$REPO_ROOT/scripts/ci/run_opencode_review_model_pool.sh" "exponential backoff" "opencode model retry paths use exponential backoff instead of fixed sleeps" assert_file_contains "$workflow_file" '"enabled_providers": ["contextual-orchestrator"]' "opencode review keeps the generated provider set gateway-only" assert_file_contains "$workflow_file" '"model": "contextual-orchestrator/orchestrator/free"' "opencode review keeps the generated model on orchestrator/free" - assert_file_contains "$workflow_file" "coverage-source-tree:" "opencode workflow materializes coverage source before running PR-head tests" + assert_file_contains "$workflow_file" "validate-pr-metadata:" "opencode admission job materializes coverage source before running PR-head tests" assert_file_contains "$workflow_file" "coverage-evidence:" "opencode workflow measures coverage before review" assert_file_contains "$workflow_file" "Materialize pull request merge tree for coverage measurement" "required OpenCode reviews measure coverage instead of approving skipped coverage evidence" assert_file_contains "$workflow_file" "Exchange OpenCode app token for target repository coverage reads" "coverage source materialization can read private target repositories during central manual dispatch" assert_file_contains "$workflow_file" "Upload materialized pull request merge tree" "coverage source materialization passes only a prepared merge tree artifact to the PR-head coverage job" assert_file_contains "$workflow_file" "Download materialized pull request merge tree" "coverage evidence consumes the prepared merge tree artifact without target-repository credentials" - assert_file_contains "$workflow_file" "Report coverage source materialization failure" "coverage evidence logs source materialization failures as the coverage blocker" + assert_file_contains "$workflow_file" "needs.validate-pr-metadata.result == 'success'" "coverage evidence requires successful source materialization in the admission job" local coverage_merge_tree_step coverage_merge_tree_step="$( awk ' @@ -3293,10 +3303,14 @@ run_gate_case() { local repo_root_dir="$workspace_dir/smart-crawling-server" mkdir -p "$bin_dir" "$untrusted_bin_dir" "$repo_root_dir/src" mkdir -p "$repo_root_dir/scripts/ci" - local gate_under_test="$repo_root_dir/scripts/ci/strix_quick_gate.sh" - cp "$GATE_SCRIPT" "$gate_under_test" - cp "$REPO_ROOT/scripts/ci/strix_model_utils.sh" "$repo_root_dir/scripts/ci/strix_model_utils.sh" - chmod +x "$gate_under_test" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + local gate_under_test="$trusted_script_dir/strix_quick_gate.sh" + materialize_trusted_gate_fixture "$trusted_script_dir" + if [ "$scenario" = "pr-changed-scope-includes-ci-dependency" ]; then + # Consumer source under scan; execution still uses the separate trusted runtime. + 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" + fi local fake_strix="$bin_dir/strix" local path_hijack_log="$tmp_dir/path-hijack.log" cat >"$untrusted_bin_dir/strix" <<'EOF' @@ -5947,7 +5961,7 @@ PY -u STRIX_OPENAI_FALLBACK_KEY_FILE \ -u STRIX_OPENAI_FALLBACK_API_BASE_FILE \ "${env_cmd[@]}" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$gate_under_test" >"$output_log" 2>&1 ) local rc=$? set -e @@ -7024,9 +7038,8 @@ run_pull_request_target_head_scope_case() { local bin_dir="$tmp_dir/bin" local repo_root_dir="$tmp_dir/repo" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -7152,7 +7165,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ STRIX_TARGET_PATH="$target_path" \ STRIX_REPORTS_DIR="$repo_root_dir/strix_runs" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -7172,9 +7185,8 @@ run_pull_request_target_plaintext_runner_token_fails_closed_case() { local bin_dir="$tmp_dir/bin" local repo_root_dir="$tmp_dir/repo" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -7272,7 +7284,7 @@ EOS LLM_API_KEY_FILE="$llm_api_key_file" \ STRIX_TARGET_PATH="." \ STRIX_REPORTS_DIR="$repo_root_dir/strix_runs" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -7294,9 +7306,8 @@ run_pull_request_target_bounded_head_context_scope_case() { local bin_dir="$tmp_dir/bin" local repo_root_dir="$tmp_dir/repo" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -7382,7 +7393,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ STRIX_TARGET_PATH="." \ STRIX_REPORTS_DIR="$repo_root_dir/strix_runs" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -7399,9 +7410,8 @@ run_pull_request_target_changed_context_scope_uses_pr_head_case() { local bin_dir="$tmp_dir/bin" local repo_root_dir="$tmp_dir/repo" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -7525,7 +7535,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ STRIX_TARGET_PATH="." \ STRIX_REPORTS_DIR="$repo_root_dir/strix_runs" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -7561,7 +7571,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ STRIX_TARGET_PATH="." \ STRIX_REPORTS_DIR="$repo_root_dir/strix_runs" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) rc=$? set -e @@ -7578,9 +7588,8 @@ run_pull_request_target_changed_backend_context_scope_case() { local bin_dir="$tmp_dir/bin" local repo_root_dir="$tmp_dir/repo" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -7812,7 +7821,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ STRIX_TARGET_PATH="." \ STRIX_REPORTS_DIR="$repo_root_dir/strix_runs" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -7837,9 +7846,8 @@ run_pull_request_target_frontend_email_context_scope_case() { local bin_dir="$tmp_dir/bin" local repo_root_dir="$tmp_dir/repo" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -8008,7 +8016,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ STRIX_TARGET_PATH="." \ STRIX_REPORTS_DIR="$repo_root_dir/strix_runs" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -8027,9 +8035,8 @@ run_pull_request_target_shallow_head_merge_base_fallback_case() { local repo_root_dir="$tmp_dir/repo" mkdir -p "$bin_dir" "$origin_repo_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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -8103,7 +8110,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ STRIX_TARGET_PATH="." \ STRIX_REPORTS_DIR="$repo_root_dir/strix_runs" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -8142,9 +8149,8 @@ run_pull_request_target_aborts_on_pr_head_blob_failure_case() { local bin_dir="$tmp_dir/bin" local repo_root_dir="$tmp_dir/repo" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" local real_git real_git="$(command -v git)" @@ -8241,7 +8247,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ STRIX_TARGET_PATH="." \ STRIX_REPORTS_DIR="$repo_root_dir/strix_runs" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -8266,9 +8272,8 @@ run_pull_request_target_rejects_invalid_sha_case() { local bin_dir="$tmp_dir/bin" local repo_root_dir="$tmp_dir/repo" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" local fake_strix="$bin_dir/strix" local call_log="$tmp_dir/calls.log" @@ -8333,7 +8338,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ STRIX_TARGET_PATH="." \ STRIX_REPORTS_DIR="$repo_root_dir/strix_runs" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -8359,9 +8364,8 @@ run_pull_request_target_irregular_head_entry_fails_closed_case() { local bin_dir="$tmp_dir/bin" local repo_root_dir="$tmp_dir/repo" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" local fake_strix="$bin_dir/strix" local call_log="$tmp_dir/calls.log" @@ -8420,7 +8424,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ STRIX_TARGET_PATH="." \ STRIX_REPORTS_DIR="$repo_root_dir/strix_runs" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -8442,9 +8446,8 @@ run_pull_request_target_gitlink_is_explicitly_skipped_case() { local bin_dir="$tmp_dir/bin" local repo_root_dir="$tmp_dir/repo" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" local fake_strix="$bin_dir/strix" local call_log="$tmp_dir/calls.log" @@ -8494,7 +8497,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ STRIX_TARGET_PATH="." \ STRIX_REPORTS_DIR="$repo_root_dir/strix_runs" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -8524,9 +8527,8 @@ run_full_head_scope_skips_gitlink_case() { local bin_dir="$tmp_dir/bin" local repo_root_dir="$tmp_dir/repo" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" @@ -8617,7 +8619,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ STRIX_TARGET_PATH="." \ STRIX_REPORTS_DIR="$repo_root_dir/strix_runs" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -8638,9 +8640,8 @@ run_pull_request_target_rejects_unsafe_changed_path_case() { local bin_dir="$tmp_dir/bin" local repo_root_dir="$tmp_dir/repo" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" local fake_strix="$bin_dir/strix" local call_log="$tmp_dir/calls.log" @@ -8684,7 +8685,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ STRIX_TARGET_PATH="." \ STRIX_REPORTS_DIR="$repo_root_dir/strix_runs" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -8730,9 +8731,8 @@ run_timeout_cleanup_case() { local workspace_dir="$tmp_dir/workspace" local repo_root_dir="$workspace_dir/smart-crawling-server" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" local fake_strix="$bin_dir/strix" local child_pid_file="$tmp_dir/child.pid" local output_log="$tmp_dir/output.log" @@ -8768,7 +8768,7 @@ EOF STRIX_VERTEX_FALLBACK_MODELS="" \ STRIX_REPORTS_DIR="$repo_root_dir/strix_runs" \ STRIX_TARGET_PATH="." \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -8812,9 +8812,8 @@ run_vertex_model_ignores_untrusted_llm_api_base_file_case() { local llm_api_base_file="$outside_dir/llm_api_base.txt" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" cat >"$fake_strix" <<'EOF' #!/usr/bin/env bash @@ -8845,7 +8844,7 @@ EOF STRIX_LLM_FILE="$strix_llm_file" \ LLM_API_KEY_FILE="$llm_api_key_file" \ LLM_API_BASE_FILE="$llm_api_base_file" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -8864,9 +8863,8 @@ run_total_timeout_case() { local workspace_dir="$tmp_dir/workspace" local repo_root_dir="$workspace_dir/smart-crawling-server" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" local fake_strix="$bin_dir/strix" local output_log="$tmp_dir/output.log" local call_count_file="$tmp_dir/calls.log" @@ -8902,7 +8900,7 @@ EOF STRIX_TRANSIENT_RETRY_BACKOFF_SECONDS="0" \ STRIX_REPORTS_DIR="$repo_root_dir/strix_runs" \ STRIX_TARGET_PATH="." \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -9191,9 +9189,8 @@ run_llm_api_base_file_outside_input_root_fails_closed_case() { local llm_api_base_file="$outside_dir/llm_api_base.txt" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" cat >"$fake_strix" <<'EOF' #!/usr/bin/env bash @@ -9218,7 +9215,7 @@ EOF STRIX_LLM_FILE="$strix_llm_file" \ LLM_API_KEY_FILE="$llm_api_key_file" \ LLM_API_BASE_FILE="$llm_api_base_file" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -9246,9 +9243,8 @@ run_pr_scoped_llm_api_base_file_config_failure_exits_2_case() { local llm_api_base_file="$outside_dir/llm_api_base.txt" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" printf '%s\n' 'print("one")' >"$repo_root_dir/src/one.py" printf '%s\n' 'print("two")' >"$repo_root_dir/src/two.py" @@ -9277,7 +9273,7 @@ EOF STRIX_LLM_FILE="$strix_llm_file" \ LLM_API_KEY_FILE="$llm_api_key_file" \ LLM_API_BASE_FILE="$llm_api_base_file" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -9307,9 +9303,8 @@ run_required_input_file_outside_input_root_fails_closed_case() { local outside_file="$outside_dir/${file_env}.txt" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" cat >"$fake_strix" <<'EOF' #!/usr/bin/env bash @@ -9349,7 +9344,7 @@ EOF STRIX_LLM_FILE="$strix_llm_file" \ LLM_API_KEY_FILE="$llm_api_key_file" \ LLM_API_BASE_FILE="$llm_api_base_file" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -9377,9 +9372,8 @@ run_input_file_root_override_takes_precedence_over_runner_temp_case() { local llm_api_base_file="$explicit_input_root/llm_api_base.txt" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" cat >"$fake_strix" <<'EOF' #!/usr/bin/env bash @@ -9405,7 +9399,7 @@ EOF STRIX_LLM_FILE="$strix_llm_file" \ LLM_API_KEY_FILE="$llm_api_key_file" \ LLM_API_BASE_FILE="$llm_api_base_file" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -9431,9 +9425,8 @@ run_stale_report_case() { local llm_api_base_file="$tmp_dir/llm_api_base.txt" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" mkdir -p "$stale_report_dir" cat >"$stale_report_dir/vuln-0001.md" <<'EOF' @@ -9463,7 +9456,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ LLM_API_BASE_FILE="$llm_api_base_file" \ STRIX_REPORTS_DIR="strix_runs" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -9486,9 +9479,8 @@ run_symlink_report_case() { local llm_api_base_file="$tmp_dir/llm_api_base.txt" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" mkdir -p "$external_report_dir" "$repo_root_dir/strix_runs" cat >"$external_report_dir/vuln-0001.md" <<'EOF' @@ -9519,7 +9511,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ LLM_API_BASE_FILE="$llm_api_base_file" \ STRIX_REPORTS_DIR="strix_runs" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -9542,9 +9534,8 @@ run_unsafe_target_path_case() { local llm_api_base_file="$tmp_dir/llm_api_base.txt" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" cat >"$fake_strix" <<'EOF' #!/usr/bin/env bash @@ -9570,7 +9561,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ LLM_API_BASE_FILE="$llm_api_base_file" \ STRIX_TARGET_PATH="../../../../../etc/passwd" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e @@ -9590,9 +9581,8 @@ run_absolute_outside_target_path_case() { local bin_dir="$tmp_dir/bin" local repo_root_dir="$tmp_dir/workspace/smart-crawling-server" 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" + local trusted_script_dir="$tmp_dir/trusted-source/scripts/ci" + materialize_trusted_gate_fixture "$trusted_script_dir" local fake_strix="$bin_dir/strix" local call_log="$tmp_dir/calls.log" local output_log="$tmp_dir/output.log" @@ -9622,7 +9612,7 @@ EOF LLM_API_KEY_FILE="$llm_api_key_file" \ LLM_API_BASE_FILE="$llm_api_base_file" \ STRIX_TARGET_PATH="$tmp_dir/strix-pr-scope.attacker" \ - bash "./scripts/ci/strix_quick_gate.sh" >"$output_log" 2>&1 + STRIX_REPO_ROOT="$repo_root_dir" bash "$trusted_script_dir/strix_quick_gate.sh" >"$output_log" 2>&1 ) local rc=$? set -e diff --git a/tests/test_strix_trusted_fixture_boundary.py b/tests/test_strix_trusted_fixture_boundary.py new file mode 100644 index 0000000000..8e0f158611 --- /dev/null +++ b/tests/test_strix_trusted_fixture_boundary.py @@ -0,0 +1,50 @@ +"""Regression contract for Strix trusted-runtime fixture isolation.""" + +from __future__ import annotations + +from pathlib import Path + + +REPOSITORY_ROOT = Path(__file__).resolve().parents[1] +HARNESS_PATH = REPOSITORY_ROOT / "scripts" / "ci" / "test_strix_quick_gate.sh" +CONSUMER_ROOT_MATERIALIZATION = ( + 'materialize_trusted_gate_fixture "$repo_root_dir/scripts/ci"' +) + + +def _consumer_root_materialization_owners(source: str) -> tuple[str, ...]: + """Return shell-function names that install trusted runtime in the consumer.""" + owners: list[str] = [] + current_function = "" + for raw_line in source.splitlines(): + stripped = raw_line.strip() + if stripped.endswith("() {"): + current_function = stripped.removesuffix("() {").strip() + if (CONSUMER_ROOT_MATERIALIZATION in raw_line + or ('cp "$GATE_SCRIPT" "$repo_root_dir/scripts/ci/strix_quick_gate.sh"' in raw_line + and current_function != "run_gate_case")): + owners.append(current_function) + return tuple(owners) + + +def test_specialized_strix_fixtures_keep_trusted_runtime_outside_consumer() -> None: + """Fail while any fixture can mask consumer-root binder resolution.""" + source = HARNESS_PATH.read_text(encoding="utf-8") + offenders = _consumer_root_materialization_owners(source) + + assert not offenders, ( + "trusted Strix gate/model/binder must be materialized outside " + "repo_root_dir; consumer-root materialization remains in: " + + ", ".join(offenders) + ) + + +def test_base_fixture_executes_trusted_runtime_when_consumer_source_is_retained() -> None: + """A source file under scan must never select the runtime being executed.""" + source = HARNESS_PATH.read_text(encoding="utf-8") + fixture = source.split("\nrun_gate_case() {", 1)[1].split( + "\nrun_gate_case_with_provider_signal_mode() {", 1)[0] + assert 'local gate_under_test="$trusted_script_dir/strix_quick_gate.sh"' in fixture + assert 'materialize_trusted_gate_fixture "$trusted_script_dir"' in fixture + assert 'STRIX_REPO_ROOT="$repo_root_dir" bash "$gate_under_test"' in fixture + assert 'bash "./scripts/ci/strix_quick_gate.sh"' not in fixture