Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 66 additions & 12 deletions scripts/ci/strix_quick_gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
# automatic model fallback, transient-error retry, and severity-based
# pass/fail decisions.
#
# STRIX_LOG is a per-attempt temp file consumed only by
# is_transient_same_model_retry_error(); cumulative report dirs in
# STRIX_REPORTS_DIR are never overwritten. Refer to ARCHITECTURE.md
# for the 3-tier timeout classification hierarchy.
# RAW_STRIX_LOG is the immutable per-attempt console evidence. STRIX_LOG points
# to it while the scanner runs, then to a private sanitized classification copy.
# Cumulative report dirs in STRIX_REPORTS_DIR are never overwritten. Refer to
# ARCHITECTURE.md for the 3-tier timeout classification hierarchy.
set -euo pipefail

SCRIPT_DIR="$({ CDPATH='' && cd -P -- "$(dirname -- "$0")" && pwd -P; })"
Expand All @@ -25,7 +25,9 @@ RAW_SCAN_MODE="${STRIX_SCAN_MODE:-quick}"
SCAN_MODE=""
ARTIFACT_REPORTS_DIR="$REPO_ROOT/strix_runs"
STRIX_RUNTIME_DIR="$(mktemp -d /tmp/strix-runtime.XXXXXX)"
STRIX_LOG="$STRIX_RUNTIME_DIR/strix.log"
RAW_STRIX_LOG="$STRIX_RUNTIME_DIR/strix.log"
STRIX_CLASSIFICATION_LOG="$STRIX_RUNTIME_DIR/strix-classification.log"
STRIX_LOG="$RAW_STRIX_LOG"
ACTIVE_REPORTS_DIR="$STRIX_RUNTIME_DIR/reports"
ATTEMPT_LOGS_DIR="$STRIX_RUNTIME_DIR/gate-attempts"
STRIX_SCAN_WORKING_DIR="$STRIX_RUNTIME_DIR/scan-cwd"
Expand Down Expand Up @@ -128,8 +130,8 @@ publish_artifact_reports() {
if [ -d "$ATTEMPT_LOGS_DIR" ] && [ ! -L "$ATTEMPT_LOGS_DIR" ]; then
cp -R -- "$ATTEMPT_LOGS_DIR" "$ARTIFACT_REPORTS_DIR/gate-attempts"
fi
if [ -f "$STRIX_LOG" ] && [ ! -L "$STRIX_LOG" ]; then
cp -- "$STRIX_LOG" "$ARTIFACT_REPORTS_DIR/gate-last-attempt.log"
if [ -f "$RAW_STRIX_LOG" ] && [ ! -L "$RAW_STRIX_LOG" ]; then
cp -- "$RAW_STRIX_LOG" "$ARTIFACT_REPORTS_DIR/gate-last-attempt.log"
fi
# Relative scanner output is copied into ACTIVE_REPORTS_DIR immediately
# after each attempt and sanitized before this publication trap runs.
Expand Down Expand Up @@ -172,6 +174,12 @@ known_internal_warning = re.compile(
r"|ended a turn without a lifecycle tool call \(interactive=False\)"
r"); forcing tool continuation \(\d+/\d+\): "
)
# Strix prints this exact box-content heading at startup whenever the
# configured model is not on its own hardcoded "recommended frontier
# model" list. Remove only that one cosmetic line: deleting the whole box
# could hide a real provider failure emitted beside the heading.
model_quality_heading = re.compile(r"│[ \t]*MODEL QUALITY WARNING[ \t]*│")
Comment thread
seonghobae marked this conversation as resolved.
ansi_csi = re.compile(r"\x1b\[[0-?]*[ -/]*[@-~]")


def iter_report_logs(root: Path):
Expand All @@ -191,16 +199,55 @@ def iter_report_logs(root: Path):

for log_path in iter_report_logs(root):
try:
lines = log_path.read_text(encoding="utf-8").splitlines(keepends=True)
text = log_path.read_text(encoding="utf-8")
except UnicodeDecodeError:
continue
filtered = [line for line in lines if not known_internal_warning.match(line)]
if filtered != lines:
log_path.write_text("".join(filtered), encoding="utf-8")
original = text
lines = text.splitlines(keepends=True)
filtered = [
line
for line in lines
if not model_quality_heading.fullmatch(ansi_csi.sub("", line.rstrip("\r\n")))
and not known_internal_warning.match(line)
]
text = "".join(filtered)
if text != original:
log_path.write_text(text, encoding="utf-8")
PY
done
}

# Strips the same benign MODEL QUALITY WARNING startup heading (see above)
# from the private classification copy so has_detected_infrastructure_error
# does not mistake it for a real provider/infrastructure failure signal.
sanitize_strix_console_log() {
local log_path="$1"
if [ -z "$log_path" ] || [ ! -f "$log_path" ] || [ -L "$log_path" ]; then
return 0
fi
python3 - "$log_path" <<'PY'
from pathlib import Path
import re
import sys

log_path = Path(sys.argv[1])
model_quality_heading = re.compile(r"│[ \t]*MODEL QUALITY WARNING[ \t]*│")
ansi_csi = re.compile(r"\x1b\[[0-?]*[ -/]*[@-~]")

try:
text = log_path.read_text(encoding="utf-8")
except UnicodeDecodeError:
raise SystemExit(0)
sanitized = "".join(
line
for line in text.splitlines(keepends=True)
if not model_quality_heading.fullmatch(ansi_csi.sub("", line.rstrip("\r\n")))
)
if sanitized != text:
log_path.write_text(sanitized, encoding="utf-8")
Comment thread
coderabbitai[bot] marked this conversation as resolved.
PY
}

has_strix_report_failure_signal() {
local report_root
local report_log
Expand Down Expand Up @@ -256,7 +303,7 @@ has_strix_report_provider_failure_signal() {
# shellcheck disable=SC2317,SC2329 # invoked from EXIT/INT/TERM trap
cleanup_runtime() {
publish_artifact_reports || true
rm -f "$STRIX_LOG"
rm -f "$RAW_STRIX_LOG" "$STRIX_CLASSIFICATION_LOG"
rm -rf "$STRIX_RUNTIME_DIR"
local scope_dir
for scope_dir in "${PULL_REQUEST_SCOPE_DIRS[@]}"; do
Expand Down Expand Up @@ -2512,6 +2559,10 @@ run_strix_once() {
local resolved_target_path
local timeout_seconds="$STRIX_PROCESS_TIMEOUT_SECONDS"
local total_budget_limited_timeout=0
# Every invocation writes an untouched raw console transcript. Classifiers
# switch to a sanitized private copy only after the raw attempt is archived.
STRIX_LOG="$RAW_STRIX_LOG"
rm -f -- "$STRIX_CLASSIFICATION_LOG"
if [ "$RUN_START_EPOCH" -le 0 ]; then
RUN_START_EPOCH="$(date +%s)"
fi
Expand Down Expand Up @@ -2790,6 +2841,9 @@ PY
fi
fi
preserve_attempt_log "$model" "$rc"
cp -- "$RAW_STRIX_LOG" "$STRIX_CLASSIFICATION_LOG"
STRIX_LOG="$STRIX_CLASSIFICATION_LOG"
sanitize_strix_console_log "$STRIX_LOG"
Comment thread
seonghobae marked this conversation as resolved.
Comment thread
seonghobae marked this conversation as resolved.

sanitize_known_strix_report_warnings "$ACTIVE_REPORTS_DIR" "${resolved_target_path%/}/strix_runs"
local report_failure_signal=0
Expand Down
Loading
Loading