Skip to content

Deep scan can report SAFE when provider is unavailable #290

Description

@tuodijihua

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions