Summary
A requested deep scan can return SAFE even when the configured LLM provider is unavailable.
This happens when at least one semantic analyzer records a real failure while other analyzers
swallow per-batch exceptions, return no findings, and record ok=true.
The report's fail-closed floor currently activates only when every recorded LLM call failed,
so the false success records bypass the intended SAFE -> CAUTION degradation behavior.
Reproduction
Using SkillSpector 2.4.1 at commit 11567e8d, configure an unavailable CLI provider and scan
a synthetic skill that contains explicit data-exfiltration instructions:
SKILLSPECTOR_PROVIDER=codex_cli skillspector scan ./fixture --format json
In the reproduced run, the configured codex binary was unavailable. The JSON report contained:
{
"risk_assessment": {
"score": 8,
"severity": "LOW",
"recommendation": "SAFE"
},
"metadata": {
"llm_requested": true,
"llm_available": false,
"llm_calls_attempted": 4,
"llm_calls_succeeded": 3,
"llm_error": "'codex' binary not found on PATH"
},
"analysis_completeness": {
"is_complete": false
}
}
The semantic batch failures are logged, but several nodes still contribute successful telemetry
records after their batch runners return an empty successful-result list.
Expected behavior
When a deep scan was requested, the provider is actually unavailable, and at least one LLM-stage
failure is recorded, the install recommendation should not remain SAFE. It should be floored at
CAUTION, consistent with the existing degraded-scan policy.
Proposed fix
At report time, combine the existing call-log degradation signal with provider availability. Keep
the check narrow so healthy deep scans and explicit static-only scans retain their current behavior.
A regression test should cover mixed success/failure telemetry with an unavailable provider.
Summary
A requested deep scan can return
SAFEeven when the configured LLM provider is unavailable.This happens when at least one semantic analyzer records a real failure while other analyzers
swallow per-batch exceptions, return no findings, and record
ok=true.The report's fail-closed floor currently activates only when every recorded LLM call failed,
so the false success records bypass the intended
SAFE->CAUTIONdegradation behavior.Reproduction
Using SkillSpector 2.4.1 at commit
11567e8d, configure an unavailable CLI provider and scana synthetic skill that contains explicit data-exfiltration instructions:
SKILLSPECTOR_PROVIDER=codex_cli skillspector scan ./fixture --format jsonIn the reproduced run, the configured
codexbinary was unavailable. The JSON report contained:{ "risk_assessment": { "score": 8, "severity": "LOW", "recommendation": "SAFE" }, "metadata": { "llm_requested": true, "llm_available": false, "llm_calls_attempted": 4, "llm_calls_succeeded": 3, "llm_error": "'codex' binary not found on PATH" }, "analysis_completeness": { "is_complete": false } }The semantic batch failures are logged, but several nodes still contribute successful telemetry
records after their batch runners return an empty successful-result list.
Expected behavior
When a deep scan was requested, the provider is actually unavailable, and at least one LLM-stage
failure is recorded, the install recommendation should not remain
SAFE. It should be floored atCAUTION, consistent with the existing degraded-scan policy.Proposed fix
At report time, combine the existing call-log degradation signal with provider availability. Keep
the check narrow so healthy deep scans and explicit static-only scans retain their current behavior.
A regression test should cover mixed success/failure telemetry with an unavailable provider.