Skip to content
Closed
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@
## 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-08-02 - O(NΒ²) Character-by-Character Parsing Overhead
**Learning:** Character-by-character parsing with `cursor += 1` on failures in Python string processing leads to massive overhead and O(NΒ²) behavior on long continuous strings.
**Action:** When parsing fails on an unquoted token that does not match an unanchored sensitive-key regex, skip the entire token since a mathematically guaranteed non-match ensures no suffix can match either. For quoted keys or partially matched keys, conservatively return `start + 1` to preserve suffix-reinspection correctness for shifted keys.
94 changes: 5 additions & 89 deletions scripts/ci/materialize_base_python_requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,11 @@
import json
import pathlib
import re
import shutil
import subprocess
import sys
import tempfile


SHA_RE = re.compile(r"^[0-9a-fA-F]{40}$")
UV_EXPORT_TIMEOUT_SECONDS = 120


def _is_candidate_lock_name(name: str) -> bool:
Expand Down Expand Up @@ -80,84 +77,6 @@ def _git(repo_root: pathlib.Path, *args: str) -> bytes:
return completed.stdout


def _run_uv_export(
work_dir: pathlib.Path,
uv_path: str,
*,
timeout: float = UV_EXPORT_TIMEOUT_SECONDS,
) -> subprocess.CompletedProcess[bytes]:
"""Run ``uv export`` for a reconstructed base project and return the result.

``--frozen`` forbids lock mutation and ``--offline`` forbids network access,
so the export is a pure function of the already-trusted base ``uv.lock`` and
``pyproject.toml``; ``--no-emit-project``/``--no-editable`` drop the project
itself (installed via ``PYTHONPATH`` in the sandbox) and keep only its
hash-pinned dependency closure.
"""
return subprocess.run(
[
uv_path,
"export",
"--frozen",
"--offline",
"--no-emit-project",
"--no-editable",
"--format",
"requirements-txt",
],
cwd=str(work_dir),
check=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
timeout=timeout,
)


def _export_uv_lock(
repo_root: pathlib.Path, base_sha: str, lock_path: str
) -> bytes | None:
"""Export a base ``uv.lock`` to a hash-pinned requirements closure, or ``None``.

``uv.lock`` is not a pip-installable format, so a uv-managed repository
materializes no dependencies and its offline coverage run fails at import.
When ``uv`` is available, reconstruct the exact base ``uv.lock`` and its
sibling ``pyproject.toml`` in an isolated temporary directory and run
``uv export --frozen`` to produce a fully hash-pinned closure the trusted
installer can consume like any other lock. Both inputs are read only from
the validated base commit, so no PR-mutable content reaches ``uv``. Return
``None`` β€” degrading to the prior no-uv behavior β€” when ``uv`` is absent,
the sibling ``pyproject.toml`` is missing at the base commit, the export
fails, or its output is not fully hash-pinned, so this can never break an
otherwise-working build.
"""
uv_path = shutil.which("uv")
if uv_path is None:
return None
project_dir = pathlib.PurePosixPath(lock_path).parent
pyproject_path = (
"pyproject.toml"
if str(project_dir) == "."
else f"{project_dir}/pyproject.toml"
)
try:
lock_content = _git(repo_root, "show", f"{base_sha}:{lock_path}")
pyproject_content = _git(repo_root, "show", f"{base_sha}:{pyproject_path}")
except RuntimeError:
return None
with tempfile.TemporaryDirectory() as work_dir:
work_path = pathlib.Path(work_dir)
(work_path / "uv.lock").write_bytes(lock_content)
(work_path / "pyproject.toml").write_bytes(pyproject_content)
try:
completed = _run_uv_export(work_path, uv_path)
except (OSError, subprocess.TimeoutExpired):
return None
if completed.returncode != 0:
return None
exported = completed.stdout
return exported if _is_hash_pinned(exported) else None


def base_hash_locks(repo_root: pathlib.Path, base_sha: str) -> list[tuple[str, bytes]]:
"""Return regular hash-lock blobs from the exact validated base commit."""
if not SHA_RE.fullmatch(base_sha):
Expand All @@ -184,16 +103,13 @@ def base_hash_locks(repo_root: pathlib.Path, base_sha: str) -> list[tuple[str, b
or not mode.startswith("100")
or candidate.is_absolute()
or ".." in candidate.parts
or not _is_candidate_lock_name(candidate.name)
):
continue
if _is_candidate_lock_name(candidate.name):
content = _git(repo_root, "show", f"{base_sha}:{path}")
if _is_hash_pinned(content):
locks.append((path, content))
elif candidate.name == "uv.lock":
exported = _export_uv_lock(repo_root, base_sha, path)
if exported is not None:
locks.append((path, exported))
content = _git(repo_root, "show", f"{base_sha}:{path}")
if not _is_hash_pinned(content):
continue
locks.append((path, content))
return sorted(locks, key=lambda item: item[0])


Expand Down
45 changes: 26 additions & 19 deletions scripts/ci/redact_sensitive_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
from typing import Any

REDACTED = "[REDACTED]"
KEY_CHARS = frozenset("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-")
KEY_CHARS = frozenset(
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-"
)
SENSITIVE_KEY_RE = re.compile(
r"(?:token|secret|password|passwd|credential|authorization|jwt|"
r"api[_-]?key|private[_-]?key|access[_-]?key|session[_-]?key)",
Expand All @@ -20,8 +22,7 @@
r"[A-Za-z0-9_-]{3,}(?![A-Za-z0-9_-])"
)
BEARER_RE = re.compile(
r"(?P<prefix>\b(?:authorization\s*:\s*)?(?:bearer|basic)\s+)"
r"[^\s\"'\\]+",
r"(?P<prefix>\b(?:authorization\s*:\s*)?(?:bearer|basic)\s+)" r"[^\s\"'\\]+",
re.IGNORECASE,
)
PROVIDER_TOKEN_RES = (
Expand All @@ -44,34 +45,37 @@ def _redact_json(value: Any) -> Any:
return value


def _consume_sensitive_assignment(text: str, start: int) -> tuple[str, int] | None:
"""Return a redacted key/value assignment parsed in linear time."""
def _consume_sensitive_assignment(text: str, start: int) -> tuple[str | None, int]:
"""Return a redacted key/value assignment parsed in linear time, or the skip index."""
cursor = start
key_quote = ""
if cursor < len(text) and text[cursor] in "\"'":
key_quote = text[cursor]
cursor += 1
key_start = cursor
if cursor >= len(text) or text[cursor] not in KEY_CHARS or text[cursor].isdigit():
return None
return None, start + 1
while cursor < len(text) and text[cursor] in KEY_CHARS:
cursor += 1
key = text[key_start:cursor]
if key_quote:
if cursor >= len(text) or text[cursor] != key_quote:
return None
return None, start + 1
cursor += 1

if not SENSITIVE_KEY_RE.search(key):
return None
if not key_quote:
return None, key_start + len(key)
return None, start + 1
while cursor < len(text) and text[cursor].isspace():
cursor += 1
if cursor >= len(text) or text[cursor] not in ":=":
return None
return None, start + 1
cursor += 1
while cursor < len(text) and text[cursor].isspace():
cursor += 1
if cursor >= len(text):
return None
return None, start + 1

value_start = cursor
if text[cursor] in "\"'":
Expand All @@ -88,10 +92,14 @@ def _consume_sensitive_assignment(text: str, start: int) -> tuple[str, int] | No
elif char == value_quote:
break
else:
while cursor < len(text) and not text[cursor].isspace() and text[cursor] not in ",}":
while (
cursor < len(text)
and not text[cursor].isspace()
and text[cursor] not in ",}"
):
cursor += 1
if cursor == value_start:
return None
return None, start + 1
return text[start:value_start] + REDACTED, cursor


Expand All @@ -100,13 +108,12 @@ def _redact_assignments(text: str) -> str:
output: list[str] = []
cursor = 0
while cursor < len(text):
match = _consume_sensitive_assignment(text, cursor)
if match is None:
output.append(text[cursor])
cursor += 1
continue
replacement, cursor = match
output.append(replacement)
replacement, next_cursor = _consume_sensitive_assignment(text, cursor)
if replacement is None:
output.append(text[cursor:next_cursor])
else:
output.append(replacement)
cursor = next_cursor
Comment thread
seonghobae marked this conversation as resolved.
return "".join(output)


Expand Down
Loading
Loading