github-actions[bot] commented on code in PR #66119:
URL: https://github.com/apache/doris/pull/66119#discussion_r3679918127


##########
.github/workflows/code-review-runner.yml:
##########
@@ -708,3 +1303,84 @@ jobs:
           fi
           echo "Codex automated review failed: ${error_msg}"
           exit 1
+
+  publish-terminal-status:
+    needs: code-review
+    if: ${{ always() }}
+    runs-on: ubuntu-latest
+    permissions:
+      statuses: write
+    steps:
+      - name: Publish terminal Code Review status
+        env:
+          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          REPO: ${{ github.repository }}
+          HEAD_SHA: ${{ inputs.head_sha }}
+          REVIEW_CONTEXT_OUTCOME: ${{ 
needs.code-review.outputs.review_context_outcome }}
+          REVIEW_OUTCOME: ${{ needs.code-review.outputs.review_outcome }}
+          CONFIGURED_DEFERRED: ${{ 
needs.code-review.outputs.configured_deferred }}
+          REVIEW_DEFERRED: ${{ needs.code-review.outputs.review_deferred }}
+          RUN_URL: ${{ github.server_url }}/${{ github.repository 
}}/actions/runs/${{ github.run_id }}
+        run: |
+          state='error'
+          description="Automated review failed for ${HEAD_SHA}."
+          if [ "$CONFIGURED_DEFERRED" = 'true' ] || [ "$REVIEW_DEFERRED" = 
'true' ]; then
+            state='pending'
+            description="Automated review is durably queued for a later retry."
+          elif [ "$REVIEW_CONTEXT_OUTCOME" = 'success' ] && [ 
"$REVIEW_OUTCOME" = 'success' ]; then
+            state='success'
+            description="Automated review completed for ${HEAD_SHA}."
+          fi
+          gh api "repos/${REPO}/statuses/${HEAD_SHA}" \
+            -X POST \
+            -f state="$state" \
+            -f context='code-review' \
+            -f description="$description" \
+            -f target_url="$RUN_URL"
+
+  acknowledge-terminal-request:
+    needs:
+      - code-review
+      - publish-terminal-status
+    if: ${{ always() }}
+    runs-on: ubuntu-latest
+    steps:
+      - name: Install ossutil
+        run: |
+          tmp_dir="$(mktemp -d)"
+          trap 'rm -rf "$tmp_dir"' EXIT
+          curl -fsSL -o "$tmp_dir/ossutil.zip" 
https://gosspublic.alicdn.com/ossutil/1.7.19/ossutil-v1.7.19-linux-amd64.zip
+          unzip -q "$tmp_dir/ossutil.zip" -d "$tmp_dir"
+          sudo install -d -o root -g root -m 0755 /opt/doris-ci
+          sudo install -o root -g root -m 0755 
"$tmp_dir/ossutil-v1.7.19-linux-amd64/ossutil" /opt/doris-ci/ossutil
+
+      - name: Acknowledge persisted request
+        env:
+          OSS_AK: ${{ secrets.OSS_AK }}
+          OSS_SK: ${{ secrets.OSS_SK }}
+          OSS_ENDPOINT: oss-cn-hongkong.aliyuncs.com
+          REQUEST_OBJECT: ${{ needs.code-review.outputs.request_object }}
+          SUCCESSOR_REQUEST_OBJECT: ${{ 
needs.code-review.outputs.successor_request_object }}
+          PRESERVE_REQUEST: ${{ needs.code-review.outputs.preserve_request }}
+          CONFIGURED_DEFERRED: ${{ 
needs.code-review.outputs.configured_deferred }}
+          REVIEW_DEFERRED: ${{ needs.code-review.outputs.review_deferred }}
+          STATUS_RESULT: ${{ needs.publish-terminal-status.result }}
+        run: |
+          if [ -z "$REQUEST_OBJECT" ]; then
+            exit 0
+          fi
+          if [ "$STATUS_RESULT" != 'success' ]; then
+            echo 'Terminal status was not persisted; retaining the review 
request.'
+            exit 0
+          fi
+          if [ "$CONFIGURED_DEFERRED" = 'true' ] || [ "$REVIEW_DEFERRED" = 
'true' ]; then
+            if [ -z "$SUCCESSOR_REQUEST_OBJECT" ] \
+              || ! /opt/doris-ci/ossutil -i "$OSS_AK" -k "$OSS_SK" -e 
"$OSS_ENDPOINT" stat "$SUCCESSOR_REQUEST_OBJECT" >/dev/null; then
+              echo 'Deferred successor is not durable; retaining the review 
request.' >&2
+              exit 1
+            fi
+          elif [ "$PRESERVE_REQUEST" = 'true' ]; then
+            echo 'Deferred request persistence was interrupted; retaining the 
review request.'
+            exit 0
+          fi
+          /opt/doris-ci/ossutil -i "$OSS_AK" -k "$OSS_SK" -e "$OSS_ENDPOINT" 
rm -f "$REQUEST_OBJECT"

Review Comment:
   [P1] Do not delete an in-place deferred successor
   
   For a direct `/review`, `REQUEST_OBJECT` is already 
`review-pending/<pr>-<head>-<request>.json`, and both `defer_review` helpers 
write the successor back to that same key. This branch successfully stats that 
key and then the final `rm` deletes it as the "old" request. Whenever the 
direct run has to defer for quota/rate/auth availability, the status stays 
pending but no pending object remains for the scheduler. Treat an equal 
request/successor key as an in-place transition and retain it (with an 
integration test for direct-request deferral).
   
   <!-- doris-codex-review:30511911292:1 -->
   



##########
.github/workflows/code-review-runner.yml:
##########
@@ -708,3 +1303,84 @@ jobs:
           fi
           echo "Codex automated review failed: ${error_msg}"
           exit 1
+
+  publish-terminal-status:
+    needs: code-review
+    if: ${{ always() }}
+    runs-on: ubuntu-latest
+    permissions:
+      statuses: write
+    steps:
+      - name: Publish terminal Code Review status
+        env:
+          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          REPO: ${{ github.repository }}
+          HEAD_SHA: ${{ inputs.head_sha }}
+          REVIEW_CONTEXT_OUTCOME: ${{ 
needs.code-review.outputs.review_context_outcome }}
+          REVIEW_OUTCOME: ${{ needs.code-review.outputs.review_outcome }}
+          CONFIGURED_DEFERRED: ${{ 
needs.code-review.outputs.configured_deferred }}
+          REVIEW_DEFERRED: ${{ needs.code-review.outputs.review_deferred }}
+          RUN_URL: ${{ github.server_url }}/${{ github.repository 
}}/actions/runs/${{ github.run_id }}
+        run: |
+          state='error'
+          description="Automated review failed for ${HEAD_SHA}."
+          if [ "$CONFIGURED_DEFERRED" = 'true' ] || [ "$REVIEW_DEFERRED" = 
'true' ]; then
+            state='pending'
+            description="Automated review is durably queued for a later retry."
+          elif [ "$REVIEW_CONTEXT_OUTCOME" = 'success' ] && [ 
"$REVIEW_OUTCOME" = 'success' ]; then
+            state='success'
+            description="Automated review completed for ${HEAD_SHA}."
+          fi
+          gh api "repos/${REPO}/statuses/${HEAD_SHA}" \

Review Comment:
   [P1] Keep the status owned by the newest review request
   
   Two `/review` commands can target the same unchanged head. The newer caller 
posts `code-review=pending` and then waits behind this workflow's global 
concurrency group, but when the older runner reaches this unconditional status 
write it replaces that pending state with `success`. The newer direct runner 
does not publish pending again when it eventually starts, so the required check 
can remain green for the whole newer review. Bind the aggregate status to a 
persisted per-head request generation (or otherwise compare ownership before 
writing), and test the A-running/B-enqueued/A-finishes ordering.
   
   <!-- doris-codex-review:30511911292:1 -->
   



##########
.github/workflows/code-review-runner.yml:
##########
@@ -488,61 +707,460 @@ jobs:
           HEAD_SHA: ${{ inputs.head_sha }}
           BASE_SHA: ${{ inputs.base_sha }}
 
+      - name: Grant isolated Codex user access to review context
+        run: |
+          sudo chown -R "$CODEX_REVIEW_USER:$CODEX_REVIEW_USER" 
"$REVIEW_CONTEXT_DIR"
+
       - name: Run automated code review
         id: review
         timeout-minutes: 115
         continue-on-error: true
         env:
           GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          OSS_AK: ${{ secrets.OSS_AK }}
+          OSS_SK: ${{ secrets.OSS_SK }}
+          OSS_ENDPOINT: oss-cn-hongkong.aliyuncs.com
+          OSS_CODEX_AUTH_STATUS_OBJECT: 
oss://doris-community-ci/codex/auth-status.json
+          OSS_CODEX_REVIEW_PENDING_PREFIX: 
oss://doris-community-ci/codex/review-pending
+          OSS_CODEX_REVIEW_CLAIMED_PREFIX: 
oss://doris-community-ci/codex/review-claimed
+          AUTH_UNAVAILABLE: ${{ steps.configure_auth.outputs.auth_unavailable 
}}
+          CONFIGURED_ALL_QUOTA_EXHAUSTED: ${{ 
steps.configure_auth.outputs.all_quota_exhausted }}
           REPO: ${{ github.repository }}
           PR_NUMBER: ${{ inputs.pr_number }}
           HEAD_SHA: ${{ inputs.head_sha }}
+          BASE_SHA: ${{ inputs.base_sha }}
+          REVIEW_FOCUS: ${{ inputs.review_focus }}
+          DEFERRED_REQUEST_ID: ${{ inputs.deferred_request_id }}
+          DEFERRED_CLAIM_ID: ${{ inputs.deferred_claim_id }}
         run: |
-          GOAL_PROMPT="$(cat "$REVIEW_CONTEXT_DIR/codex_goal_prompt.txt")"
-          review_started_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
+          write_review_output() {
+            local key="$1"
+            local value="$2"
+            {
+              echo "${key}<<EOF"
+              printf '%s\n' "$value"
+              echo "EOF"
+            } >> "$GITHUB_OUTPUT"
+          }
+
+          OSSUTIL=/opt/doris-ci/ossutil
+
+          defer_review() {
+            local retry_at="$1" request_id request_object
+            request_id="${DEFERRED_REQUEST_ID:-$GITHUB_RUN_ID}"
+            
request_object="$OSS_CODEX_REVIEW_PENDING_PREFIX/${PR_NUMBER}-${HEAD_SHA}-${request_id}.json"
+            local request_file
+            request_file="$(mktemp "$RUNNER_TEMP/codex-review-pending.XXXXXX")"
+            jq -n \
+              --arg pr_number "$PR_NUMBER" \
+              --arg head_sha "$HEAD_SHA" \
+              --arg base_sha "$BASE_SHA" \
+              --arg review_focus "$REVIEW_FOCUS" \
+              --arg not_before "$retry_at" \
+              --arg request_id "$request_id" \
+              --arg lease_id '' \
+              --arg lease_expires_at '' \
+              '{pr_number: $pr_number, head_sha: $head_sha, base_sha: 
$base_sha,
+                review_focus: $review_focus, not_before: $not_before, 
request_id: $request_id,
+                lease_id: $lease_id, lease_expires_at: $lease_expires_at}' > 
"$request_file"
+            write_review_output "preserve_request" "true"
+            "$OSSUTIL" -i "$OSS_AK" -k "$OSS_SK" -e "$OSS_ENDPOINT" cp -f \
+              "$request_file" "$request_object"
+            rm -f "$request_file"
+            write_review_output "deferred_review" "true"
+            write_review_output "successor_request_object" "$request_object"
+          }
+
+          auth_object_args=()
+          known_auth_object_args=()
+          while IFS= read -r auth_object; do
+            auth_object_args+=(--auth-object "$auth_object")
+            known_auth_object_args+=(--known-auth-object "$auth_object")
+          done < "$CODEX_AUTH_OBJECTS_FILE"
+          if [ "${#auth_object_args[@]}" -eq 0 ]; then
+            write_review_output "all_quota_exhausted" "false"
+            write_review_output "failure_reason" "No valid Codex auth account 
is available for review."
+            exit 1
+          fi
 
-          set +e
-          # GitHub-hosted runners are ephemeral. Avoid workspace-write here 
because
-          # Codex uses bubblewrap for that mode and uid maps can be 
unavailable.
-          codex exec --goal "$GOAL_PROMPT" \
-            --cd "$GITHUB_WORKSPACE" \
-            --model "gpt-5.6-sol" \
-            --config "model_reasoning_effort=xhigh" \
-            --sandbox danger-full-access \
-            --color never \
-            --json \
-            --output-last-message 
"$REVIEW_CONTEXT_DIR/codex-final-message.txt" \
-            > "$REVIEW_CONTEXT_DIR/codex-events.jsonl" \
-            2> >(tee "$REVIEW_CONTEXT_DIR/codex-stderr.log" >&2)
-          status=$?
-          set -e
+          sync_auth_state() {
+            "$OSSUTIL" -i "$OSS_AK" -k "$OSS_SK" -e "$OSS_ENDPOINT" cp -f \
+              "$CODEX_AUTH_STATE_FILE" "$OSS_CODEX_AUTH_STATUS_OBJECT"
+          }
+
+          record_auth_result() {
+            local result="$1"
+            local http_status="$2"
+            local retry_after="$3"
+            local record_args=(
+              record
+              --state "$CODEX_AUTH_STATE_FILE"
+              --auth-object "$CODEX_AUTH_STATE_KEY"
+              "${known_auth_object_args[@]}"
+              --result "$result"
+            )
+            if [ -n "$http_status" ]; then
+              record_args+=(--http-status "$http_status")
+            fi
+            if [ -n "$retry_after" ]; then
+              record_args+=(--retry-after "$retry_after")
+            fi
+            "$CODEX_AUTH_STATE_HELPER" "${record_args[@]}"
+          }
+
+          install_selected_auth() {
+            local candidate_auth_file
+            candidate_auth_file="$(mktemp "$RUNNER_TEMP/codex-auth.XXXXXX")"
+            "$OSSUTIL" -i "$OSS_AK" -k "$OSS_SK" -e "$OSS_ENDPOINT" cp -f \
+              "$CODEX_AUTH_OSS_OBJECT" "$candidate_auth_file"
+            "$CODEX_AUTH_STATE_HELPER" validate --auth "$candidate_auth_file"
+            sudo install -o "$CODEX_REVIEW_USER" -g "$CODEX_REVIEW_USER" -m 
600 \
+              "$candidate_auth_file" "$CODEX_HOME/auth.json"
+            install -m 600 "$candidate_auth_file" "$CODEX_AUTH_SNAPSHOT"
+            rm -f "$candidate_auth_file"
+          }
+
+          sync_refreshed_auth() {
+            local auth_dir refreshed_auth_file promoted_auth_file 
refreshed_digest cmp_status
+            if ! auth_dir="$(mktemp -d 
"$RUNNER_TEMP/codex-refreshed-auth.XXXXXX")"; then
+              return 1
+            fi
+            refreshed_auth_file="$auth_dir/refreshed-auth.json"
+            promoted_auth_file="$auth_dir/promoted-auth.json"
+            if ! sudo -u "$CODEX_REVIEW_USER" cat "$CODEX_HOME/auth.json" > 
"$refreshed_auth_file"; then
+              rm -rf "$auth_dir"
+              return 1
+            fi
+            if ! "$CODEX_AUTH_STATE_HELPER" promote \
+              --baseline "$CODEX_AUTH_SNAPSHOT" \
+              --candidate "$refreshed_auth_file" \
+              --output "$promoted_auth_file"; then
+              rm -rf "$auth_dir"
+              return 1
+            fi
+            if [ ! -s "$promoted_auth_file" ]; then
+              rm -rf "$auth_dir"
+              return 1
+            fi
+            cmp -s "$promoted_auth_file" "$CODEX_AUTH_SNAPSHOT"
+            cmp_status=$?
+            if [ "$cmp_status" -gt 1 ]; then
+              rm -rf "$auth_dir"
+              return 1
+            fi
+            if [ "$cmp_status" -eq 1 ]; then
+              if ! "$OSSUTIL" -i "$OSS_AK" -k "$OSS_SK" -e "$OSS_ENDPOINT" cp 
-f \

Review Comment:
   [P1] Keep OSS secrets out of post-agent argv
   
   The sanitized child environment and absolute binary path do not close the 
secret boundary. A prompt-injected Codex process can leave a detached low-UID 
process polling the shared process table; after `codex exec` returns, this 
privileged invocation puts both repository-wide OSS keys in `ossutil`'s argv, 
where that process can read and exfiltrate them. This is distinct from 
inheriting the keys or replacing `ossutil`. Run the secret-bearing work after 
the entire agent process tree is gone (ideally in a fresh job/container) and 
pass credentials through a root-only channel that never exposes them in argv.
   
   <!-- doris-codex-review:30511911292:1 -->
   



##########
.github/scripts/codex_auth_state.py:
##########
@@ -0,0 +1,582 @@
+#!/usr/bin/env python3
+"""Persist and select the rotating credentials used by code review jobs."""
+
+from __future__ import annotations
+
+import argparse
+import base64
+import copy
+import json
+import re
+import tempfile
+from dataclasses import dataclass
+from datetime import datetime, timedelta, timezone
+from pathlib import Path
+from typing import Any
+
+
+STATE_VERSION = 1
+AVAILABLE = "available"
+QUOTA_EXHAUSTED = "quota_exhausted"
+RATE_LIMITED = "rate_limited"
+AUTHENTICATION_FAILED = "authentication_failed"
+TRANSIENT_FAILURE = "transient_failure"
+STATUS_VALUES = {AVAILABLE, QUOTA_EXHAUSTED, RATE_LIMITED, 
AUTHENTICATION_FAILED}
+QUOTA_RETRY_DELAY = timedelta(hours=12)
+RATE_LIMIT_RETRY_DELAY = timedelta(hours=1)
+PERMANENT_AUTH_FAILURE_PATTERN = re.compile(
+    r"refresh[\s_-]*token.*(?:revoked|expired|already\s+used)|"
+    r"(?:revoked|expired).*refresh[\s_-]*token",
+    re.IGNORECASE,
+)
+USAGE_LIMIT_MESSAGE_PATTERN = re.compile(
+    r"you(?:'|\u2019)ve hit your usage limit|usage limit",
+    re.IGNORECASE,
+)
+USAGE_LIMIT_RETRY_PATTERN = re.compile(
+    r"try again 
at\s+(?:(?P<date>[A-Za-z]{3,9}\s+\d{1,2}(?:st|nd|rd|th)?,\s+\d{4}\s+"
+    r"\d{1,2}:\d{2}\s+(?:AM|PM))|(?P<time>\d{1,2}:\d{2}\s+(?:AM|PM)))",
+    re.IGNORECASE | re.DOTALL,
+)
+CONTENT_DIGEST_PATTERN = re.compile(r"[0-9a-f]{64}")
+
+
+@dataclass(frozen=True)
+class Selection:
+    auth_object: str | None
+    all_quota_exhausted: bool
+    next_retry_at: str | None
+
+
+@dataclass(frozen=True)
+class FailureClassification:
+    kind: str
+    http_status: int | None
+    retry_after: str | None
+
+
+def utc_now() -> datetime:
+    return datetime.now(timezone.utc).replace(microsecond=0)
+
+
+def parse_timestamp(value: str) -> datetime:
+    parsed = datetime.fromisoformat(value.replace("Z", "+00:00"))
+    if parsed.tzinfo is None:
+        raise ValueError(f"Timestamp must include a timezone: {value!r}")
+    return parsed.astimezone(timezone.utc).replace(microsecond=0)
+
+
+def format_timestamp(value: datetime) -> str:
+    return 
value.astimezone(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00",
 "Z")
+
+
+def default_account_state() -> dict[str, Any]:
+    return {
+        "content_digest": None,
+        "status": AVAILABLE,
+        "last_failure_at": None,
+        "last_http_status": None,
+        "last_success_at": None,
+        "last_recovered_at": None,
+        "retry_after": None,
+    }
+
+
+def default_state() -> dict[str, Any]:
+    return {"version": STATE_VERSION, "next_account": 0, "accounts": {}}
+
+
+def load_state(path: Path) -> dict[str, Any]:
+    if not path.exists():
+        return default_state()
+
+    state = json.loads(path.read_text())
+    if not isinstance(state, dict):
+        raise ValueError("Authentication state must be a JSON object")
+    if state.get("version") != STATE_VERSION:
+        raise ValueError(f"Unsupported authentication state version: 
{state.get('version')!r}")
+    if not isinstance(state.get("next_account"), int):
+        raise ValueError("Authentication state next_account must be an 
integer")
+    if not isinstance(state.get("accounts"), dict):
+        raise ValueError("Authentication state accounts must be an object")
+    return state
+
+
+def save_state(path: Path, state: dict[str, Any]) -> None:
+    with tempfile.NamedTemporaryFile("w", encoding="utf-8", dir=path.parent, 
delete=False) as temporary:
+        json.dump(state, temporary, indent=2, sort_keys=True)
+        temporary.write("\n")
+        temporary_path = Path(temporary.name)
+    temporary_path.replace(path)
+
+
+def parse_id_token(id_token: str) -> dict[str, Any]:
+    parts = id_token.split(".")
+    if len(parts) < 3 or any(not part for part in parts[:3]):
+        raise ValueError("Codex id_token must be a parseable JWT")
+    payload = parts[1]
+    try:
+        decoded = base64.b64decode(payload + "=" * (-len(payload) % 4), 
altchars=b"-_", validate=True)
+        claims = json.loads(decoded)
+    except (ValueError, json.JSONDecodeError) as exc:
+        raise ValueError("Codex id_token must be a parseable JWT") from exc
+    if not isinstance(claims, dict):
+        raise ValueError("Codex id_token JWT payload must be an object")
+    return claims
+
+
+def string_claim(value: object, name: str) -> str | None:
+    if value is None:
+        return None
+    if not isinstance(value, str):
+        raise ValueError(f"Codex id_token {name} claim must be a string")
+    return value
+
+
+def auth_identity(credentials: dict[str, Any]) -> dict[str, Any]:
+    if credentials.get("auth_mode") != "chatgpt":
+        raise ValueError("Codex credentials must use ChatGPT authentication")
+
+    tokens = credentials.get("tokens")
+    if not isinstance(tokens, dict):
+        raise ValueError("Codex credentials must contain a tokens object")
+    for token_name in ("access_token", "refresh_token", "id_token"):
+        if not isinstance(tokens.get(token_name), str) or not 
tokens[token_name]:
+            raise ValueError(f"Codex {token_name} must be a non-empty string")
+
+    claims = parse_id_token(tokens["id_token"])
+    profile = claims.get("https://api.openai.com/profile";)
+    if profile is not None and not isinstance(profile, dict):
+        raise ValueError("Codex id_token profile claim must be an object")
+    auth_claims = claims.get("https://api.openai.com/auth";)
+    if auth_claims is not None and not isinstance(auth_claims, dict):
+        raise ValueError("Codex id_token auth claim must be an object")
+    profile = profile or {}
+    auth_claims = auth_claims or {}
+    fedramp = auth_claims.get("chatgpt_account_is_fedramp", False)
+    if not isinstance(fedramp, bool):
+        raise ValueError("Codex id_token chatgpt_account_is_fedramp claim must 
be a boolean")
+
+    email = claims.get("email")
+    if email is None:
+        email = profile.get("email")
+    return {
+        "email": string_claim(email, "email"),
+        "chatgpt_user_id": string_claim(
+            auth_claims.get("chatgpt_user_id", auth_claims.get("user_id")), 
"chatgpt_user_id"
+        ),
+        "chatgpt_account_id": 
string_claim(auth_claims.get("chatgpt_account_id"), "chatgpt_account_id"),
+        "chatgpt_account_is_fedramp": fedramp,
+        "account_id": string_claim(tokens.get("account_id"), "account_id"),
+    }
+
+
+def validate_auth(credentials: dict[str, Any]) -> None:
+    auth_identity(credentials)
+    last_refresh = credentials.get("last_refresh")
+    if last_refresh is not None:
+        if not isinstance(last_refresh, str) or not last_refresh:
+            raise ValueError("Codex last_refresh must be a non-empty 
timestamp")
+        parse_timestamp(last_refresh)
+
+
+def promote_auth(baseline: dict[str, Any], candidate: dict[str, Any]) -> 
dict[str, Any]:
+    validate_auth(baseline)
+    validate_auth(candidate)
+    if auth_identity(baseline) != auth_identity(candidate):
+        raise ValueError("Refreshed credentials changed an immutable account 
or workspace claim")
+    if not isinstance(candidate.get("last_refresh"), str) or not 
candidate["last_refresh"]:
+        raise ValueError("Refreshed credentials must include last_refresh")
+
+    promoted = copy.deepcopy(baseline)
+    for token_name in ("access_token", "refresh_token", "id_token"):

Review Comment:
   [P1] Do not trust the agent-owned token bundle for promotion
   
   Protecting the helper and state file does not protect this input: Codex owns 
`auth.json`, can keep the baseline `id_token` unchanged, replace `access_token` 
and `refresh_token` with any non-empty strings, and advance `last_refresh`. 
`auth_identity` still matches, so this loop copies the attacker-controlled 
values and the privileged parent uploads them to the shared OSS object. This is 
a distinct remaining channel across the new UID boundary. Refresh/promote the 
credential in a trusted broker (or validate the replacement with the provider), 
rather than treating self-asserted JWT claims and non-empty token strings as 
proof.
   
   <!-- doris-codex-review:30511911292:1 -->
   



##########
.github/workflows/code-review-runner.yml:
##########
@@ -488,61 +707,460 @@ jobs:
           HEAD_SHA: ${{ inputs.head_sha }}
           BASE_SHA: ${{ inputs.base_sha }}
 
+      - name: Grant isolated Codex user access to review context
+        run: |
+          sudo chown -R "$CODEX_REVIEW_USER:$CODEX_REVIEW_USER" 
"$REVIEW_CONTEXT_DIR"
+
       - name: Run automated code review
         id: review
         timeout-minutes: 115
         continue-on-error: true
         env:
           GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          OSS_AK: ${{ secrets.OSS_AK }}
+          OSS_SK: ${{ secrets.OSS_SK }}
+          OSS_ENDPOINT: oss-cn-hongkong.aliyuncs.com
+          OSS_CODEX_AUTH_STATUS_OBJECT: 
oss://doris-community-ci/codex/auth-status.json
+          OSS_CODEX_REVIEW_PENDING_PREFIX: 
oss://doris-community-ci/codex/review-pending
+          OSS_CODEX_REVIEW_CLAIMED_PREFIX: 
oss://doris-community-ci/codex/review-claimed
+          AUTH_UNAVAILABLE: ${{ steps.configure_auth.outputs.auth_unavailable 
}}
+          CONFIGURED_ALL_QUOTA_EXHAUSTED: ${{ 
steps.configure_auth.outputs.all_quota_exhausted }}
           REPO: ${{ github.repository }}
           PR_NUMBER: ${{ inputs.pr_number }}
           HEAD_SHA: ${{ inputs.head_sha }}
+          BASE_SHA: ${{ inputs.base_sha }}
+          REVIEW_FOCUS: ${{ inputs.review_focus }}
+          DEFERRED_REQUEST_ID: ${{ inputs.deferred_request_id }}
+          DEFERRED_CLAIM_ID: ${{ inputs.deferred_claim_id }}
         run: |
-          GOAL_PROMPT="$(cat "$REVIEW_CONTEXT_DIR/codex_goal_prompt.txt")"
-          review_started_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
+          write_review_output() {
+            local key="$1"
+            local value="$2"
+            {
+              echo "${key}<<EOF"
+              printf '%s\n' "$value"
+              echo "EOF"
+            } >> "$GITHUB_OUTPUT"
+          }
+
+          OSSUTIL=/opt/doris-ci/ossutil
+
+          defer_review() {
+            local retry_at="$1" request_id request_object
+            request_id="${DEFERRED_REQUEST_ID:-$GITHUB_RUN_ID}"
+            
request_object="$OSS_CODEX_REVIEW_PENDING_PREFIX/${PR_NUMBER}-${HEAD_SHA}-${request_id}.json"
+            local request_file
+            request_file="$(mktemp "$RUNNER_TEMP/codex-review-pending.XXXXXX")"
+            jq -n \
+              --arg pr_number "$PR_NUMBER" \
+              --arg head_sha "$HEAD_SHA" \
+              --arg base_sha "$BASE_SHA" \
+              --arg review_focus "$REVIEW_FOCUS" \
+              --arg not_before "$retry_at" \
+              --arg request_id "$request_id" \
+              --arg lease_id '' \
+              --arg lease_expires_at '' \
+              '{pr_number: $pr_number, head_sha: $head_sha, base_sha: 
$base_sha,
+                review_focus: $review_focus, not_before: $not_before, 
request_id: $request_id,
+                lease_id: $lease_id, lease_expires_at: $lease_expires_at}' > 
"$request_file"
+            write_review_output "preserve_request" "true"
+            "$OSSUTIL" -i "$OSS_AK" -k "$OSS_SK" -e "$OSS_ENDPOINT" cp -f \
+              "$request_file" "$request_object"
+            rm -f "$request_file"
+            write_review_output "deferred_review" "true"
+            write_review_output "successor_request_object" "$request_object"
+          }
+
+          auth_object_args=()
+          known_auth_object_args=()
+          while IFS= read -r auth_object; do
+            auth_object_args+=(--auth-object "$auth_object")
+            known_auth_object_args+=(--known-auth-object "$auth_object")
+          done < "$CODEX_AUTH_OBJECTS_FILE"
+          if [ "${#auth_object_args[@]}" -eq 0 ]; then
+            write_review_output "all_quota_exhausted" "false"
+            write_review_output "failure_reason" "No valid Codex auth account 
is available for review."
+            exit 1
+          fi
 
-          set +e
-          # GitHub-hosted runners are ephemeral. Avoid workspace-write here 
because
-          # Codex uses bubblewrap for that mode and uid maps can be 
unavailable.
-          codex exec --goal "$GOAL_PROMPT" \
-            --cd "$GITHUB_WORKSPACE" \
-            --model "gpt-5.6-sol" \
-            --config "model_reasoning_effort=xhigh" \
-            --sandbox danger-full-access \
-            --color never \
-            --json \
-            --output-last-message 
"$REVIEW_CONTEXT_DIR/codex-final-message.txt" \
-            > "$REVIEW_CONTEXT_DIR/codex-events.jsonl" \
-            2> >(tee "$REVIEW_CONTEXT_DIR/codex-stderr.log" >&2)
-          status=$?
-          set -e
+          sync_auth_state() {
+            "$OSSUTIL" -i "$OSS_AK" -k "$OSS_SK" -e "$OSS_ENDPOINT" cp -f \
+              "$CODEX_AUTH_STATE_FILE" "$OSS_CODEX_AUTH_STATUS_OBJECT"
+          }
+
+          record_auth_result() {
+            local result="$1"
+            local http_status="$2"
+            local retry_after="$3"
+            local record_args=(
+              record
+              --state "$CODEX_AUTH_STATE_FILE"
+              --auth-object "$CODEX_AUTH_STATE_KEY"
+              "${known_auth_object_args[@]}"
+              --result "$result"
+            )
+            if [ -n "$http_status" ]; then
+              record_args+=(--http-status "$http_status")
+            fi
+            if [ -n "$retry_after" ]; then
+              record_args+=(--retry-after "$retry_after")
+            fi
+            "$CODEX_AUTH_STATE_HELPER" "${record_args[@]}"
+          }
+
+          install_selected_auth() {
+            local candidate_auth_file
+            candidate_auth_file="$(mktemp "$RUNNER_TEMP/codex-auth.XXXXXX")"
+            "$OSSUTIL" -i "$OSS_AK" -k "$OSS_SK" -e "$OSS_ENDPOINT" cp -f \

Review Comment:
   [P2] Reconcile the bytes that are actually installed
   
   Discovery hashes A-old, but this function downloads the selected object 
again without updating its digest. If an operator replaces that credential in 
between, Codex runs with A-new while state still records A-old; a quota/auth 
failure is then persisted against the old digest, and the next job sees A-new 
as another replacement and resets the failure to `available`. Install the 
already validated bytes, or hash and reconcile every installation before Codex 
starts, and cover replacement-between-discovery-and-install.
   
   <!-- doris-codex-review:30511911292:1 -->
   



##########
.github/scripts/test_codex_auth_state.py:
##########
@@ -0,0 +1,292 @@
+from __future__ import annotations

Review Comment:
   [P2] Run the auth-state suite in CI
   
   These 18 tests pass locally, but no repository workflow or test harness 
invokes this file, so the rotation, promotion, and failure-classification 
behavior can regress while CI remains green. Add a non-secret job (or an early 
helper self-test) that runs this suite; the shell/workflow ordering still needs 
separate integration coverage.
   
   <!-- doris-codex-review:30511911292:1 -->
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to