diff --git a/.jules/bolt.md b/.jules/bolt.md index a86b7aaf..89c5ff73 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -43,3 +43,6 @@ ## 2026-07-09 - Avoid N+1 API blocking in SBOM aggregator **Learning:** The `collect_inventories` function in `scripts/ci/sbom_inventory_aggregator.py` was fetching SBOMs from the GitHub dependency graph synchronously for every repository in the organization. For large organizations (up to 500 repos), this N+1 network/CLI bottleneck significantly stalled the aggregation workflow. **Action:** Use `concurrent.futures.ThreadPoolExecutor` to fetch SBOMs concurrently when multiple repositories are provided, bounded by a `max_workers` limit (e.g., 10) to avoid overwhelming the CLI/API, while preserving the fast serial path for single-item inputs. +## 2026-07-09 - Pre-compile Regex Patterns in Embedded Python Loop-called Functions +**Learning:** Found a regex recompilation bottleneck in `scripts/ci/opencode_review_approve_gate.sh` where `hunk_header = re.compile(...)` was defined inside the top-level `changed_new_lines` helper in the embedded Python module. Even when Python execution is embedded in a shell script, recompiling a regex object inside a repetitively called function (like processing git diff lines for multiple files) incurs measurable overhead. +**Action:** Move inline regex compilation (using `re.compile()`) outside loop-called functions to the module level, including when the Python module is embedded in a Bash heredoc (`python3 - ... <<'PY'`). Ensure global variables/constants are well documented. diff --git a/scripts/ci/opencode_review_approve_gate.sh b/scripts/ci/opencode_review_approve_gate.sh index bf21c0b4..5c157b3e 100755 --- a/scripts/ci/opencode_review_approve_gate.sh +++ b/scripts/ci/opencode_review_approve_gate.sh @@ -233,6 +233,11 @@ def normalized_line(value: str) -> str: return " ".join(value.strip().split()) +# ⚡ Bolt: Pre-compile regex at the module level to prevent recompilation in loop-called functions +# Impact: Reduces regex recompilation overhead when processing git diff hunk headers for every changed file +HUNK_HEADER_RE = re.compile(r"^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@") + + # ⚡ Bolt: Memoize changed_new_lines to prevent N+1 git diff subprocess calls # Impact: Substantially reduces I/O wait overhead when multiple findings are on the same file path @functools.cache @@ -265,9 +270,8 @@ def changed_new_lines(path_value: str) -> frozenset[int]: return frozenset() line_numbers: set[int] = set() - hunk_header = re.compile(r"^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@") for raw_line in completed.stdout.splitlines(): - match = hunk_header.match(raw_line) + match = HUNK_HEADER_RE.match(raw_line) if not match: continue start = int(match.group(1))