You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG] Rate-limited providers silently lose analyzer coverage: max_concurrency=10 hardcoded, 429 batches dropped without retry, partial LLM pass not flagged #303
On a rate-limited provider (typical free tier), arun_batches bursts up to a hardcoded max_concurrency=10 and drops any 429'd batch ("logged and omitted from the result") with no retry/backoff. There is no way to lower the concurrency or make the client respect the provider's RPM/TPM. The result is a scan that silently loses analyzer coverage while still emitting a full risk_assessment — including losing the security-critical semantic_security_discovery batch, so a genuinely malicious skill can read as clean.
This is distinct from #290 (provider unavailable): here the provider is available and answering, but throttling, and the partial result is not surfaced as such.
metadata.llm_calls_attempted: 4, llm_calls_succeeded: 3, yet risk_assessment.severity is emitted normally and issues: 0. On a known-malicious test skill (natural-language exfiltration of ~/.config/gh/hosts.yml), the dropped batch was exactly the analyzer that catches it — the scan reported LOW/clean.
Same pattern on Groq free tier: the ~33k-token semantic_security_discovery prompt exceeds the free TPM cap → 413 → dropped → clean-looking report.
Why the current design makes this invisible
max_concurrency=10 is a fixed default in arun_batches; nothing threads a lower value or reads an env/flag. Ten parallel requests against a 5 RPM budget guarantee 429s.
429s are caught per-batch and omitted; there is no retry honoring Retry-After.
llm_calls_succeeded < llm_calls_attempted is recorded in metadata but the risk assessment does not treat a partial LLM pass as degraded, so downstream consumers see a normal verdict.
Requests (any subset helps)
Configurable concurrency — an env var / CLI flag (e.g. SKILLSPECTOR_MAX_LLM_CONCURRENCY) so users on rate-limited tiers can serialize.
Retry with backoff on 429/RESOURCE_EXHAUSTED, honoring Retry-After, before giving up on a batch.
Surface incompleteness in the verdict: when any batch is dropped, mark the report degraded / refuse to assert a clean risk_assessment — same failure mode Deep scan can report SAFE when provider is unavailable #290 guards against, one step earlier. A metadata flag like llm_batches_dropped: N would let callers gate on it.
Happy to send a PR for (1) and (3) if the direction is agreeable.
Environment
SkillSpector (current main), SKILLSPECTOR_PROVIDER=openai against generativelanguage.googleapis.com/v1beta/openai/ and api.groq.com/openai/v1, free tiers.
Progress is linked in both directions: merged PR #305 delivered configurable LLM concurrency, and active PR #362 addresses the partial-failure/degraded-verdict requirement. Keeping this issue open because the retry/backoff portion remains outstanding.
Status update: configurable concurrency (PR #305) and degraded partial-batch reporting (PR #362) are merged. The remaining retry/backoff requirement is under review in comprehensive PR #555, with the older 429-specific alternative in PR #403. Keeping this issue open until an accepted retry implementation merges.
Degraded reporting when LLM batches are lost: PR #362.
Bounded transient/rate-limit retries and Retry-After handling: PR #555, merged September 21.
Retry, concurrency, and partial-LLM report regressions pass on main at 6685a1b. Exhausted or non-retryable failures still remain visible as incomplete/degraded analysis; retries do not promise to overcome a provider's quota or an oversized request.
Closing as completed on main. The newest retry change is not yet in the latest published release, v2.11.2.
Activity
feat(llm): make analyzer fan-out concurrency configurable via env (#305)
rng1995 commentedon Aug 14, 2026
Progress is linked in both directions: merged PR #305 delivered configurable LLM concurrency, and active PR #362 addresses the partial-failure/degraded-verdict requirement. Keeping this issue open because the retry/backoff portion remains outstanding.
fix(report): flag a partial LLM failure as degraded, not only a total…
fix(report): flag a partial LLM failure as degraded, not only a total…
rng1995 commentedon Sep 16, 2026
Status update: configurable concurrency (PR #305) and degraded partial-batch reporting (PR #362) are merged. The remaining retry/backoff requirement is under review in comprehensive PR #555, with the older 429-specific alternative in PR #403. Keeping this issue open until an accepted retry implementation merges.
rng1995 commentedon Sep 21, 2026
All three requested parts are now merged:
Retry-Afterhandling: PR #555, merged September 21.Retry, concurrency, and partial-LLM report regressions pass on
mainat6685a1b. Exhausted or non-retryable failures still remain visible as incomplete/degraded analysis; retries do not promise to overcome a provider's quota or an oversized request.Closing as completed on
main. The newest retry change is not yet in the latest published release, v2.11.2.