diff --git a/.jules/bolt.md b/.jules/bolt.md index a86b7aaf..cee3b49c 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-14 - Optimize JSON Parsing with `raw_decode` +**Learning:** While using `json.JSONDecoder().raw_decode(text, start)` instead of string slicing (`text[start:end+1]`) is a crucial performance optimization to avoid O(N^2) memory copying when iteratively parsing large JSON blobs, applying it to short strings like individual LLM responses is technically a micro-optimization with negligible performance impact. +**Action:** However, use it anyway in these cases! Not for performance, but for robustness. `.rfind('}')` is fragile and can incorrectly capture trailing conversational garbage that happens to contain a closing brace. `raw_decode` safely parses the first complete JSON object and ignores the rest, fixing real-world LLM parsing edge cases while being technically more efficient. diff --git a/scripts/ci/noema_review_gate.py b/scripts/ci/noema_review_gate.py index 5b024c84..b2f896b4 100644 --- a/scripts/ci/noema_review_gate.py +++ b/scripts/ci/noema_review_gate.py @@ -423,12 +423,23 @@ def extract_json_object(text: str) -> dict[str, Any]: """Extract a JSON object from a strict or lightly wrapped LLM response.""" stripped = text.strip() if stripped.startswith("{"): - return json.loads(stripped) + try: + return json.loads(stripped) + except json.JSONDecodeError: + pass + start = stripped.find("{") - end = stripped.rfind("}") - if start < 0 or end < start: + if start < 0: + raise RuntimeError("Noema LLM response did not contain a JSON object") + + try: + # ⚡ Bolt: Use raw_decode to prevent O(N) memory copying overhead from string slicing + value, _ = json.JSONDecoder().raw_decode(stripped, start) + if not isinstance(value, dict): + raise RuntimeError("Noema LLM response did not contain a JSON object") + return value + except json.JSONDecodeError: raise RuntimeError("Noema LLM response did not contain a JSON object") - return json.loads(stripped[start : end + 1]) def call_llm(