Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions lenses/skillspector.sh
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,17 @@ for skill in "${skills[@]}"; do
echo "scan produced no valid JSON for: $skill" >>"$work/errors.log"
errors=$((errors+1)); continue
fi
# Normalize v2.0.0 `issues[]` into honey's finding shape (schema verified
# against SkillSpector v2.0.0 --format json output).
# Schema guard: honey normalizes the `issues[]` array. If a future SkillSpector
# renames/drops it, `(.issues // [])` would silently yield ZERO findings — a
# false "clean". Treat valid-JSON-without-`issues` as a schema-drift ERROR so
# it surfaces as scan_error (visible), never a silent all-clear.
if ! jq -e 'has("issues")' "$raw" >/dev/null 2>&1; then
echo "SCHEMA DRIFT: SkillSpector output for $skill has no top-level .issues (output format changed? re-verify the lens normalizer)" >>"$work/errors.log"
errors=$((errors+1)); continue
fi
# Normalize `issues[]` into honey's finding shape. Schema verified against
# SkillSpector v2.0.0 and v2.3.11 --format json output (issues[] is the tool's
# documented "core contract": id/pattern/severity/category/location).
norm="$(jq --arg skill "$skill" '
(.issues // []) | map({
severity: ((.severity // "unknown") | ascii_downcase),
Expand Down
10 changes: 9 additions & 1 deletion win/lenses/skillspector.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,16 @@ foreach ($skill in $skills) {
$data = $null
try { $data = Get-Content -LiteralPath $raw -Raw | ConvertFrom-Json } catch { $data = $null }
if ($null -eq $data) { Add-Content -LiteralPath $errLog -Value "no valid JSON for: $skill"; $errors++; continue }
# Schema guard: honey normalizes the `issues[]` array. If a future SkillSpector
# renames/drops it, iterating a missing property yields ZERO findings — a false
# "clean". Treat valid-JSON-without-`issues` as schema-drift ERROR (surfaces as
# scan_error), never a silent all-clear.
if ($data.PSObject.Properties.Name -notcontains 'issues') {
Add-Content -LiteralPath $errLog -Value "SCHEMA DRIFT: SkillSpector output for $skill has no top-level .issues (output format changed? re-verify the lens normalizer)"
$errors++; continue
}

foreach ($issue in @(if ($data.PSObject.Properties.Name -contains 'issues') { $data.issues } else { @() })) {
foreach ($issue in @($data.issues)) {
$id = if ($issue.PSObject.Properties.Name -contains 'id' -and $issue.id) { $issue.id } else { '' }
$pattern = if ($issue.PSObject.Properties.Name -contains 'pattern' -and $issue.pattern) { $issue.pattern } else { '' }
$title = (($id + ' ' + $pattern).Trim())
Expand Down
Loading