Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
3 changes: 3 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
## 2024-11-20 - JSON Decoding Performance - Index Advancement
**Learning:** Even when avoiding string slicing using `json.JSONDecoder().raw_decode(text, index)`, failing to correctly advance the index by ignoring the returned `end` index (`value, _ = decoder.raw_decode(...)`) forces the search loop to repeatedly attempt to decode nested JSON structures (e.g., inner braces `{`) sequentially. This leads to massive O(N^2) time complexity and redundant parsing for large, deeply nested JSON objects.
**Action:** Always capture and use the new end index returned by `raw_decode` (e.g., `value, next_idx = decoder.raw_decode(text, index)`) to jump over the completely parsed object and proceed efficiently.
## 2024-06-26 - [Concurrent Network Calls via ThreadPoolExecutor]
**Learning:** Sequential execution of subprocesses making network calls (like `gh api`) inside a loop causes accumulated O(N) I/O wait latency, which forms a significant performance bottleneck during bulk PR inspections.
**Action:** Use `concurrent.futures.ThreadPoolExecutor` to execute independent subprocess I/O calls concurrently, avoiding O(N) wait times while maintaining safety since `subprocess.run` drops the Python GIL.
Comment thread
Copilot marked this conversation as resolved.
Outdated
8 changes: 8 additions & 0 deletions debug.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
--- scripts/ci/emit_opencode_failed_check_fallback_findings.sh
+++ scripts/ci/emit_opencode_failed_check_fallback_findings.sh
@@ -743,6 +743,7 @@
emit_strix_report_findings "$strix_evidence_file"
+echo "before provider failure: $finding_index" >&2
emit_strix_provider_failure_finding "$strix_evidence_file"
+echo "after provider failure: $finding_index" >&2
emit_strix_cancelled_without_log_finding "$strix_evidence_file"
2 changes: 2 additions & 0 deletions scripts/ci/collect_failed_check_evidence.sh
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ emit_failure_signal_summary() {
/LLM CONNECTION FAILED/ ||
/RateLimitError/ ||
/Too many requests/ ||
/For more on scraping GitHub/ ||
/HTTPStatusError/ ||
/401 Unauthorized/ ||
/api\.deepseek\.com/ ||
Expand Down Expand Up @@ -111,6 +112,7 @@ emit_strix_vulnerability_evidence() {
/LLM CONNECTION FAILED/ ||
/RateLimitError/ ||
/Too many requests/ ||
/For more on scraping GitHub/ ||
/HTTPStatusError/ ||
/401 Unauthorized/ ||
/api\.deepseek\.com/ ||
Expand Down
6 changes: 3 additions & 3 deletions scripts/ci/emit_opencode_failed_check_fallback_findings.sh
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ emit_strix_provider_failure_finding() {
local path=".github/workflows/strix.yml"
local line="1"

if ! grep -Eq "LLM CONNECTION FAILED|RateLimitError|Too many requests|HTTPStatusError|401 Unauthorized|api\\.deepseek\\.com|Authentication Fails|DeepseekException|budget limit|Configured model and fallback models were unavailable|provider infrastructure|Below-threshold findings detected|Unable to map Strix findings" "$strix_evidence_file"; then
if ! grep -Eq "LLM CONNECTION FAILED|RateLimitError|Too many requests|For more on scraping GitHub|HTTPStatusError|401 Unauthorized|api\\.deepseek\\.com|Authentication Fails|DeepseekException|budget limit|Configured model and fallback models were unavailable|provider infrastructure|Below-threshold findings detected|Unable to map Strix findings" "$strix_evidence_file"; then
return 0
fi

Expand Down Expand Up @@ -666,12 +666,12 @@ emit_strix_provider_failure_finding() {
else
printf '### %s. HIGH %s:%s - Strix provider failure blocked current-head security evidence\n' "$finding_index" "$path" "$line"
if grep -Eq "api\\.deepseek\\.com|401 Unauthorized|Authentication Fails|DeepseekException" "$strix_evidence_file"; then
printf -- '- Problem: Strix failed before producing vulnerability reports. The failed log reported `RateLimitError` / `Too many requests` for the primary `openai/gpt-5` attempt, then fallback attempts reached direct DeepSeek (`api.deepseek.com`) and failed with `401 Unauthorized` or `Authentication Fails`, ending with `Configured model and fallback models were unavailable`.\n'
printf -- '- Problem: Strix failed before producing vulnerability reports. The failed log reported `RateLimitError` / `Too many requests` (or `For more on scraping GitHub`) for the primary `openai/gpt-5` attempt, then fallback attempts reached direct DeepSeek (`api.deepseek.com`) and failed with `401 Unauthorized` or `Authentication Fails`, ending with `Configured model and fallback models were unavailable`.\n'
printf -- '- Root cause: The fallback model names were not routed through the GitHub Models endpoint for this failed PR check, so a GitHub Models token was used against direct DeepSeek instead of `https://models.github.ai/inference`; no Strix Vulnerability Report window was produced.\n'
printf -- '- Fix: Do not approve from this failed scan. Keep %s:%s using the GitHub Models-qualified fallback list (`github_models/deepseek/deepseek-v3-0324 github_models/deepseek/deepseek-r1-0528`) and keep the Strix gate mapping those values to `openai/deepseek/...` for the GitHub Models API base, then rerun the failed PR Strix check.\n' "$path" "$line"
printf -- '- Suggested edit: `%s:%s` must use `STRIX_FALLBACK_MODELS: ${{ steps.gate.outputs.provider_mode == '\''github_models'\'' && '\''github_models/deepseek/deepseek-v3-0324 github_models/deepseek/deepseek-r1-0528'\'' || '\'''\'' }}` instead of unqualified `deepseek/...` values that route to `api.deepseek.com`.\n' "$path" "$line"
else
printf -- '- Problem: Strix failed before producing vulnerability reports. The failed log reported LLM CONNECTION FAILED, RateLimitError or Too many requests for the primary model, provider/budget output for fallback models, and Configured model and fallback models were unavailable.\n'
printf -- '- Problem: Strix failed before producing vulnerability reports. The failed log reported LLM CONNECTION FAILED, RateLimitError, Too many requests, or For more on scraping GitHub for the primary model, provider/budget output for fallback models, and Configured model and fallback models were unavailable.\n'
printf -- '- Root cause: The configured GitHub Models primary/fallback provider capacity or provider route failed for this run; no Strix Vulnerability Report window was produced, so there is no application source line to patch from this evidence.\n'
printf -- '- Fix: Do not approve from this failed scan. Re-run Strix after GitHub Models capacity recovers or run an explicitly configured manual provider evidence scan with valid credentials; keep the configured fallback line at %s:%s aligned with the approved model list.\n' "$path" "$line"
printf -- '- Suggested edit: keep `%s:%s` on the approved GitHub Models fallback list and rerun the current-head Strix check; there is no application source patch until Strix emits a vulnerability Code Location.\n' "$path" "$line"
Expand Down
18 changes: 15 additions & 3 deletions scripts/ci/pr_review_merge_scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,12 +407,22 @@ def fetch_rest_mergeable_state(repo: str, number: int) -> str:

def enrich_rest_mergeable_states(repo: str, prs: list[dict[str, Any]]) -> None:
"""Attach REST mergeability evidence to GraphQL pull request payloads."""
for pr in prs:
import concurrent.futures

def enrich(pr: dict[str, Any]) -> None:
"""Fetch and attach REST mergeability for one PR."""
try:
pr["restMergeableState"] = fetch_rest_mergeable_state(repo, int(pr["number"]))
except RuntimeError as exc:
pr["restMergeableStateError"] = bounded_error_summary(str(exc))

# ⚡ Bolt: Execute gh api calls concurrently to prevent O(N) network latency accumulation
# ThreadPoolExecutor is safe here since subprocess.run drops the GIL during execution.
with concurrent.futures.ThreadPoolExecutor(max_workers=min(len(prs) or 1, 10)) as executor:
# We must exhaust the iterator to ensure exceptions (if any unhandled) are raised
# or just to wait for all threads to finish.
list(executor.map(enrich, prs))
Comment thread
github-actions[bot] marked this conversation as resolved.
Outdated


def effective_merge_state(pr: dict[str, Any]) -> str:
"""Return the safest merge state from GraphQL plus REST mergeability evidence."""
Expand Down Expand Up @@ -1329,7 +1339,7 @@ def summarize_action_error(exc: RuntimeError) -> str:

def self_test() -> None:
"""Exercise scheduler invariants without GitHub network access."""
sample = {
sample: dict[str, Any] = {
"number": 1,
"headRefOid": "abc",
"baseRefName": "main",
Expand Down Expand Up @@ -1574,7 +1584,9 @@ def self_test() -> None:
)
assert decision.action == "wait"
assert "external/repo" in decision.reason
assert decision_guidance(decision)["type"] == "external_head_update_required"
wait_guidance = decision_guidance(decision)
assert wait_guidance is not None
assert wait_guidance["type"] == "external_head_update_required"
sample["maintainerCanModify"] = True
decision = inspect_pr(
"owner/repo",
Expand Down
4 changes: 4 additions & 0 deletions test_evidence.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## Failed check: Strix Security Scan / strix (28242573264 / 1)
LLM CONNECTION FAILED
Error: litellm.RateLimitError: RateLimitError: OpenAIException - Too many requests. For more on scraping GitHub and how it may affect your rights, please review our Terms of Service.
Configured model and fallback models were unavailable
11 changes: 11 additions & 0 deletions test_fallback.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash
export REPO_ROOT="$(pwd)"

cat << 'LOG' > test_evidence.txt
## Failed check: Strix Security Scan / strix (28242573264 / 1)
LLM CONNECTION FAILED
Error: litellm.RateLimitError: RateLimitError: OpenAIException - Too many requests. For more on scraping GitHub and how it may affect your rights, please review our Terms of Service.
Configured model and fallback models were unavailable
LOG

bash -x ./scripts/ci/emit_opencode_failed_check_fallback_findings.sh test_evidence.txt
18 changes: 18 additions & 0 deletions tests/test_pr_review_merge_scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -1205,3 +1205,21 @@ def test_action_error_guidance_distinguishes_update_branch_from_merge():
)
assert "PR head likely changed after inspection" in stale_head_error
assert "reads the new head before mutating" in stale_head_error

def test_enrich_rest_mergeable_states_concurrently(monkeypatch):
"""Test that enrich_rest_mergeable_states calls enrich properly."""
Comment thread
github-actions[bot] marked this conversation as resolved.
Outdated
import scripts.ci.pr_review_merge_scheduler as scheduler

def mock_fetch(repo, number):
if number == 1:
return "CLEAN"
raise RuntimeError("API limit")

monkeypatch.setattr(scheduler, "fetch_rest_mergeable_state", mock_fetch)

prs = [{"number": 1}, {"number": 2}]
scheduler.enrich_rest_mergeable_states("repo", prs)

assert prs[0]["restMergeableState"] == "CLEAN"
assert "restMergeableStateError" in prs[1]
assert prs[1]["restMergeableStateError"] == "API limit"