From 3053eeacd5828b81fa5e7be8c67277f8549abdd1 Mon Sep 17 00:00:00 2001 From: Mohit Gupta Date: Tue, 15 Sep 2026 19:13:59 +0530 Subject: [PATCH 01/12] release: SkillSpector 2.11.3 Signed-off-by: Mohit Gupta --- CHANGELOG.md | 14 ++++++ docs/release/skillspector-2.11.3.md | 70 +++++++++++++++++++++++++++++ pyproject.toml | 2 +- uv.lock | 2 +- 4 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 docs/release/skillspector-2.11.3.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 886c25432..ff6802c7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +### 2.11.3 (Tuesday, September 15, 2026) +### Features/Bug Fixes +* fix: avoid false analysis limits in documentation (#516) +* fix: scan JSON quote candidates in linear time (#521) +* feat: configure the static analysis time allowance (#522) +* fix(cli): emit recursive JSON reports to stdout (#467) +* fix(analyzer): project manifest version for RP3 (#474) +* fix(supply-chain): prefer exact known-package matches in SC6 (#530) +* Fix false local references from slash-separated prose (#451) +* test(build-context): skip symlink cases where the platform refuses symlinks (#501) +* docs(providers): align setup guidance (#434) +* docs(readme): add HVTrust badge (#428) +* docs(readme): clarify research background counts (#543) +--- ### 2.11.2 (Thursday, September 10, 2026) ### Features/Bug Fixes * fix: prevent duplicate reference coverage from causing fatal scan-accounting errors (#507) diff --git a/docs/release/skillspector-2.11.3.md b/docs/release/skillspector-2.11.3.md new file mode 100644 index 000000000..a1f9a837a --- /dev/null +++ b/docs/release/skillspector-2.11.3.md @@ -0,0 +1,70 @@ +# SkillSpector v2.11.3 + +Released: 2026-09-15 + +## Summary + +SkillSpector 2.11.3 fixes false AE1 incomplete-analysis results caused by ordinary Markdown and JSON documentation. It preserves incomplete coverage for unresolved runtime commands, adds a configurable static analysis time allowance, and corrects reference, manifest, package-name, and recursive JSON reporting behavior. + +## Highlights + +- Recognize complete JSON strings and Markdown code spans in their document context, avoiding false analysis limits while retaining analysis of their contents. +- Keep delimiter pairing within Markdown blocks and table cells so unrelated documentation cannot hide unresolved runtime commands. +- Scan JSON quote candidates in linear time and retain cancellation handling. + +## Added + +- `SKILLSPECTOR_MAX_STATIC_ANALYSIS_SECONDS_PER_ARTIFACT` configures the static pattern and YARA time allowance per artifact; its default increases from 30 to 300 seconds. The remaining workflow deadline still bounds both analyzers. + +## Changed + +- Align provider setup guidance and update research background documentation. + +## Fixed + +- Avoid false AE1 results from valid JSON placeholders, inline code, list and blockquote containers, indented JSON, Markdown tables, and literal Make syntax ([#516](https://github.com/NVIDIA/SkillSpector/pull/516)). +- Bound JSON quote traversal without repeatedly scanning overlapping suffixes ([#521](https://github.com/NVIDIA/SkillSpector/pull/521)). +- Emit recursive JSON reports to standard output when no output path is provided ([#467](https://github.com/NVIDIA/SkillSpector/pull/467)). +- Use the project manifest version for RP3 analysis ([#474](https://github.com/NVIDIA/SkillSpector/pull/474)). +- Prefer exact known-package matches when evaluating SC6 package-name similarity ([#530](https://github.com/NVIDIA/SkillSpector/pull/530)). +- Avoid treating slash-separated prose as local file references ([#451](https://github.com/NVIDIA/SkillSpector/pull/451)). +- Skip symlink test cases when the platform refuses symlink creation ([#501](https://github.com/NVIDIA/SkillSpector/pull/501)). + +## Security + +- Genuine removal instructions remain reportable. Unresolved runtime commands retain incomplete coverage and fail strict CLI/MCP installation gates, including when semantic analysis succeeds. +- JSON string ownership preserves source evidence and does not exempt string contents from analysis. + +## Breaking Changes and Migration + +- No required configuration changes. Static analysis can now run longer within the existing workflow deadline. Set `SKILLSPECTOR_MAX_STATIC_ANALYSIS_SECONDS_PER_ARTIFACT=30` to retain the previous per-artifact allowance, and restart the SkillSpector process after changing the setting ([#522](https://github.com/NVIDIA/SkillSpector/pull/522)). +- Third-party dependency versions are unchanged from 2.11.2. + +## Deprecations + +- None. + +## Validation + +Validated locally with Python 3.12 and uv 0.10.10: + +- Locked dependency verification, Ruff lint, and formatting checks passed. +- `make test-ci` passed: 4,825 passed, 14 skipped, 38 deselected, and 4 expected failures; 89% coverage. +- Wheel and source distributions built successfully and passed `twine check`. All 97 Python source files in the wheel match the release candidate. +- `skillspector --version` reports `SkillSpector v2.11.3`; the GitHub release helper dry run resolves the matching tag and release notes. +- A fresh Linux/arm64 Docker image passed both repository smoke tests: the local safe fixture and a public GitHub repository scan completed with 100% coverage and no findings. +- Eight targeted CLI and MCP-helper scan scenarios passed, including paired static/live documentation checks and unresolved-runtime-command controls. All 20 recorded LLM attempts with the actual `codex_cli` provider succeeded. Benign documentation completed without AE1; unresolved runtime commands retained incomplete coverage and failed strict installation gates as expected. + +The release PR records the full regression-suite results and additional integration validation. + +## Known Limitations + +- Local sanity checks cover the tested inputs and environment; live provider and deployment behavior depend on their configuration. + +## References + +- [Changes since v2.11.2](https://github.com/NVIDIA/SkillSpector/compare/v2.11.2...v2.11.3) +- [AE1 documentation fix #516](https://github.com/NVIDIA/SkillSpector/pull/516) +- [Static analysis time allowance #522](https://github.com/NVIDIA/SkillSpector/pull/522) + +Prepared by Codex for Mohit Gupta. diff --git a/pyproject.toml b/pyproject.toml index 5b7fa7b29..3bbe5dcac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "skillspector" -version = "2.11.2" +version = "2.11.3" description = "SkillSpector: Security scanner for AI agent skills (Claude Code, Cursor, and similar). Scans skills for vulnerabilities, malicious patterns, and security risks before installation. Supports Git repos, URLs, zips, and local directories; runs static pattern checks and optional LLM semantic analysis; outputs terminal, JSON, and Markdown reports with risk scoring." readme = "README.md" license = "Apache-2.0" diff --git a/uv.lock b/uv.lock index 3a0df7ea1..bf081f918 100644 --- a/uv.lock +++ b/uv.lock @@ -2687,7 +2687,7 @@ wheels = [ [[package]] name = "skillspector" -version = "2.11.2" +version = "2.11.3" source = { editable = "." } dependencies = [ { name = "boto3" }, From 39c711f6deb768ee792e284025b09fc531c4b4fb Mon Sep 17 00:00:00 2001 From: Mohit Gupta Date: Wed, 16 Sep 2026 17:48:59 +0530 Subject: [PATCH 02/12] docs(release): refresh 2.11.3 changes and validation status Signed-off-by: Mohit Gupta --- CHANGELOG.md | 7 ++++++- docs/release/skillspector-2.11.3.md | 31 ++++++++++++++++++----------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff6802c7c..3eb191a5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ -### 2.11.3 (Tuesday, September 15, 2026) +### 2.11.3 (Unreleased) ### Features/Bug Fixes +* fix(security): enforce discovery and requested analysis completeness (#410) +* fix(security): detect letter-spaced P3/P4 instructions and report ambiguous reconstruction as AE6 (#470) +* feat(cli): add opt-in --fail-on-findings across single-skill, recursive, and MCP registry scans (#469) +* fix(security): preserve exact finding identity, evidence, and occurrence locations (#409) +* fix: report oversized-file coverage gaps as AE7 and bound their LLM input (#509) * fix: avoid false analysis limits in documentation (#516) * fix: scan JSON quote candidates in linear time (#521) * feat: configure the static analysis time allowance (#522) diff --git a/docs/release/skillspector-2.11.3.md b/docs/release/skillspector-2.11.3.md index a1f9a837a..6eec98b10 100644 --- a/docs/release/skillspector-2.11.3.md +++ b/docs/release/skillspector-2.11.3.md @@ -1,29 +1,38 @@ # SkillSpector v2.11.3 -Released: 2026-09-15 +Release status: candidate; publication pending. ## Summary -SkillSpector 2.11.3 fixes false AE1 incomplete-analysis results caused by ordinary Markdown and JSON documentation. It preserves incomplete coverage for unresolved runtime commands, adds a configurable static analysis time allowance, and corrects reference, manifest, package-name, and recursive JSON reporting behavior. +SkillSpector 2.11.3 fixes false AE1 incomplete-analysis results caused by ordinary Markdown and JSON documentation. It also makes discovery and requested-analysis gaps explicit, preserves distinct findings and their source locations, detects letter-spaced prompt instructions, and adds an opt-in CLI gate for any active finding. Oversized files now produce an explicit coverage finding and bounded LLM input. ## Highlights - Recognize complete JSON strings and Markdown code spans in their document context, avoiding false analysis limits while retaining analysis of their contents. - Keep delimiter pairing within Markdown blocks and table cells so unrelated documentation cannot hide unresolved runtime commands. - Scan JSON quote candidates in linear time and retain cancellation handling. +- Preserve distinct full-evidence and rule identities, including findings with identical shortened previews, and retain precise locations for repeated occurrences. +- Keep requested but unavailable or incomplete semantic analysis visible in completeness metadata and strict CLI/MCP decisions. ## Added - `SKILLSPECTOR_MAX_STATIC_ANALYSIS_SECONDS_PER_ARTIFACT` configures the static pattern and YARA time allowance per artifact; its default increases from 30 to 300 seconds. The remaining workflow deadline still bounds both analyzers. +- `skillspector scan --fail-on-findings` exits with code 1 when a scan reports any active finding, including findings below the default risk-score threshold. It applies to single-skill, recursive, and MCP registry scans. Skill scans evaluate active findings after suppression ([#469](https://github.com/NVIDIA/SkillSpector/pull/469)). ## Changed - Align provider setup guidance and update research background documentation. +- Reports retain requested LLM intent separately from runtime availability. Incomplete semantic execution remains visible through aggregate reports and CLI/MCP installation gates ([#410](https://github.com/NVIDIA/SkillSpector/pull/410)). ## Fixed - Avoid false AE1 results from valid JSON placeholders, inline code, list and blockquote containers, indented JSON, Markdown tables, and literal Make syntax ([#516](https://github.com/NVIDIA/SkillSpector/pull/516)). - Bound JSON quote traversal without repeatedly scanning overlapping suffixes ([#521](https://github.com/NVIDIA/SkillSpector/pull/521)). +- Emit a HIGH AE7 analysis-evasion finding for per-file size limits that leave an artifact partially inspected, unless AE1 already covers that path. Supply a bounded text prefix and an explicit unreviewed-region marker to enabled LLM analysis; the unread region remains incomplete ([#509](https://github.com/NVIDIA/SkillSpector/pull/509)). +- Preserve full-evidence fingerprints, concrete YARA rule identity, and precise occurrence locations through projection, deduplication, and report compaction. Separate findings are retained while duplicate projections of the same occurrence are collapsed ([#409](https://github.com/NVIDIA/SkillSpector/pull/409)). +- Detect letter-spaced P3/P4 prompt instructions through bounded reconstruction, retain source evidence, and report ambiguous or irregular letter-spacing reconstruction as AE6 incomplete coverage ([#470](https://github.com/NVIDIA/SkillSpector/pull/470)). +- Discover skills inside dot-prefixed directories, retain inherited local-only restrictions for child skills, and partition transitive scan caching by those privacy restrictions ([#410](https://github.com/NVIDIA/SkillSpector/pull/410)). +- Preserve incomplete discovery and requested semantic-analysis failures, including unavailable providers and mixed success/failure telemetry, instead of allowing a complete scan result ([#410](https://github.com/NVIDIA/SkillSpector/pull/410)). - Emit recursive JSON reports to standard output when no output path is provided ([#467](https://github.com/NVIDIA/SkillSpector/pull/467)). - Use the project manifest version for RP3 analysis ([#474](https://github.com/NVIDIA/SkillSpector/pull/474)). - Prefer exact known-package matches when evaluating SC6 package-name similarity ([#530](https://github.com/NVIDIA/SkillSpector/pull/530)). @@ -34,10 +43,13 @@ SkillSpector 2.11.3 fixes false AE1 incomplete-analysis results caused by ordina - Genuine removal instructions remain reportable. Unresolved runtime commands retain incomplete coverage and fail strict CLI/MCP installation gates, including when semantic analysis succeeds. - JSON string ownership preserves source evidence and does not exempt string contents from analysis. +- Findings and exit status can change after upgrading: oversized files can add HIGH AE7 findings, letter-spaced instructions can produce P3/P4 or AE6 findings, and previously collapsed distinct matches can increase the retained finding count and risk score. Missing requested analysis remains incomplete even when static analysis finishes. ## Breaking Changes and Migration -- No required configuration changes. Static analysis can now run longer within the existing workflow deadline. Set `SKILLSPECTOR_MAX_STATIC_ANALYSIS_SECONDS_PER_ARTIFACT=30` to retain the previous per-artifact allowance, and restart the SkillSpector process after changing the setting ([#522](https://github.com/NVIDIA/SkillSpector/pull/522)). +- No new configuration is required. Static analysis can now run longer within the existing workflow deadline. Set `SKILLSPECTOR_MAX_STATIC_ANALYSIS_SECONDS_PER_ARTIFACT=30` to retain the previous per-artifact allowance, and restart the SkillSpector process after changing the setting ([#522](https://github.com/NVIDIA/SkillSpector/pull/522)). +- `--fail-on-findings` is opt-in. Combine it with `--fail-on-incomplete` when CI must reject either active findings or incomplete coverage. Code 2 still denotes an input or execution error; a nonzero exit alone does not identify which condition occurred. +- Consumers should retain completeness/degradation metadata and inspect findings as well as exit status. Explicitly use `--no-llm` for an intended static-only scan; requesting LLM analysis without an available provider is incomplete. - Third-party dependency versions are unchanged from 2.11.2. ## Deprecations @@ -46,20 +58,15 @@ SkillSpector 2.11.3 fixes false AE1 incomplete-analysis results caused by ordina ## Validation -Validated locally with Python 3.12 and uv 0.10.10: +The release candidate includes main commit `0a8b80c36cad7c503f98548d0fa166f90a50294c`. Validation is being repeated against the resulting 2.11.3 artifact after the merges listed above. Earlier results apply only to their recorded commits and are not current-candidate certification. -- Locked dependency verification, Ruff lint, and formatting checks passed. -- `make test-ci` passed: 4,825 passed, 14 skipped, 38 deselected, and 4 expected failures; 89% coverage. -- Wheel and source distributions built successfully and passed `twine check`. All 97 Python source files in the wheel match the release candidate. -- `skillspector --version` reports `SkillSpector v2.11.3`; the GitHub release helper dry run resolves the matching tag and release notes. -- A fresh Linux/arm64 Docker image passed both repository smoke tests: the local safe fixture and a public GitHub repository scan completed with 100% coverage and no findings. -- Eight targeted CLI and MCP-helper scan scenarios passed, including paired static/live documentation checks and unresolved-runtime-command controls. All 20 recorded LLM attempts with the actual `codex_cli` provider succeeded. Benign documentation completed without AE1; unresolved runtime commands retained incomplete coverage and failed strict installation gates as expected. - -The release PR records the full regression-suite results and additional integration validation. +[Release PR #550](https://github.com/NVIDIA/SkillSpector/pull/550) records the candidate commit, artifact identity, regression and integration results, and remaining release gates. ## Known Limitations - Local sanity checks cover the tested inputs and environment; live provider and deployment behavior depend on their configuration. +- Incomplete inspection is a reportable result. Unsupported inputs, unavailable requested analysis, and resource limits must remain visible; these conditions cannot be treated as a clean scan. +- The release remains a draft while current-candidate validation and outstanding release issues are assessed. Proposed fixes in unmerged PRs are not included in this candidate. ## References From b8cfdaa62df80a44c479d4875677f14cf7e3d1cc Mon Sep 17 00:00:00 2001 From: Mohit Gupta Date: Wed, 16 Sep 2026 18:00:41 +0530 Subject: [PATCH 03/12] docs(release): qualify known report and completeness gaps Signed-off-by: Mohit Gupta --- docs/release/skillspector-2.11.3.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/release/skillspector-2.11.3.md b/docs/release/skillspector-2.11.3.md index 6eec98b10..312a5a1f8 100644 --- a/docs/release/skillspector-2.11.3.md +++ b/docs/release/skillspector-2.11.3.md @@ -41,7 +41,7 @@ SkillSpector 2.11.3 fixes false AE1 incomplete-analysis results caused by ordina ## Security -- Genuine removal instructions remain reportable. Unresolved runtime commands retain incomplete coverage and fail strict CLI/MCP installation gates, including when semantic analysis succeeds. +- Genuine removal instructions remain reportable. The covered unresolved-runtime-command controls retain incomplete coverage and fail strict CLI/MCP installation gates, including when semantic analysis succeeds. Additional runtime-selected command variants remain under investigation (see Known Limitations). - JSON string ownership preserves source evidence and does not exempt string contents from analysis. - Findings and exit status can change after upgrading: oversized files can add HIGH AE7 findings, letter-spaced instructions can produce P3/P4 or AE6 findings, and previously collapsed distinct matches can increase the retained finding count and risk score. Missing requested analysis remains incomplete even when static analysis finishes. @@ -67,6 +67,8 @@ The release candidate includes main commit `0a8b80c36cad7c503f98548d0fa166f90a50 - Local sanity checks cover the tested inputs and environment; live provider and deployment behavior depend on their configuration. - Incomplete inspection is a reportable result. Unsupported inputs, unavailable requested analysis, and resource limits must remain visible; these conditions cannot be treated as a clean scan. - The release remains a draft while current-candidate validation and outstanding release issues are assessed. Proposed fixes in unmerged PRs are not included in this candidate. +- Current validation found that public report serialization can repeat the first occurrence's columns for other matches; SARIF does not yet preserve these column coordinates. The internal occurrence improvements in #409 do not establish correct locations in every output format. See [release validation](https://github.com/NVIDIA/SkillSpector/pull/550) for the tracked report defect. +- Some runtime-selected command variants and Markdown reference destinations still have open completeness defects. Proposed fixes [#514](https://github.com/NVIDIA/SkillSpector/pull/514) and [#553](https://github.com/NVIDIA/SkillSpector/pull/553) are not included in this candidate. ## References From af97d3f2bcf83a97692c7be9f2564b39ebdbc01e Mon Sep 17 00:00:00 2001 From: Narendran Raghavan Date: Wed, 16 Sep 2026 09:44:13 -0700 Subject: [PATCH 04/12] release: prepare SkillSpector 2.12.0 Signed-off-by: Narendran Raghavan --- CHANGELOG.md | 3 ++- ...ector-2.11.3.md => skillspector-2.12.0.md} | 27 ++++++++++++++----- pyproject.toml | 2 +- uv.lock | 2 +- 4 files changed, 24 insertions(+), 10 deletions(-) rename docs/release/{skillspector-2.11.3.md => skillspector-2.12.0.md} (72%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3eb191a5e..712a21699 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ -### 2.11.3 (Unreleased) +### 2.12.0 (Unreleased) ### Features/Bug Fixes +* fix: classify companion CLI documentation by context (#547) * fix(security): enforce discovery and requested analysis completeness (#410) * fix(security): detect letter-spaced P3/P4 instructions and report ambiguous reconstruction as AE6 (#470) * feat(cli): add opt-in --fail-on-findings across single-skill, recursive, and MCP registry scans (#469) diff --git a/docs/release/skillspector-2.11.3.md b/docs/release/skillspector-2.12.0.md similarity index 72% rename from docs/release/skillspector-2.11.3.md rename to docs/release/skillspector-2.12.0.md index 312a5a1f8..29a85aeba 100644 --- a/docs/release/skillspector-2.11.3.md +++ b/docs/release/skillspector-2.12.0.md @@ -1,10 +1,10 @@ -# SkillSpector v2.11.3 +# SkillSpector v2.12.0 Release status: candidate; publication pending. ## Summary -SkillSpector 2.11.3 fixes false AE1 incomplete-analysis results caused by ordinary Markdown and JSON documentation. It also makes discovery and requested-analysis gaps explicit, preserves distinct findings and their source locations, detects letter-spaced prompt instructions, and adds an opt-in CLI gate for any active finding. Oversized files now produce an explicit coverage finding and bounded LLM input. +SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configurable static-analysis allowance. It also fixes false AE1 incomplete-analysis results caused by ordinary Markdown and JSON documentation, makes discovery and requested-analysis gaps explicit, preserves distinct findings and their source locations, detects letter-spaced prompt instructions, and reduces false positives in companion CLI documentation. Oversized files now produce an explicit coverage finding and bounded LLM input. ## Highlights @@ -13,6 +13,7 @@ SkillSpector 2.11.3 fixes false AE1 incomplete-analysis results caused by ordina - Scan JSON quote candidates in linear time and retain cancellation handling. - Preserve distinct full-evidence and rule identities, including findings with identical shortened previews, and retain precise locations for repeated occurrences. - Keep requested but unavailable or incomplete semantic analysis visible in completeness metadata and strict CLI/MCP decisions. +- Classify narrowly proven OAuth, signed self-update, and warned installer documentation in context while retaining the underlying findings and fail-closed controls. ## Added @@ -21,7 +22,7 @@ SkillSpector 2.11.3 fixes false AE1 incomplete-analysis results caused by ordina ## Changed -- Align provider setup guidance and update research background documentation. +- Align provider setup guidance, add the HVTrust badge, and update research background counts ([#434](https://github.com/NVIDIA/SkillSpector/pull/434), [#428](https://github.com/NVIDIA/SkillSpector/pull/428), [#543](https://github.com/NVIDIA/SkillSpector/pull/543)). - Reports retain requested LLM intent separately from runtime availability. Incomplete semantic execution remains visible through aggregate reports and CLI/MCP installation gates ([#410](https://github.com/NVIDIA/SkillSpector/pull/410)). ## Fixed @@ -37,6 +38,7 @@ SkillSpector 2.11.3 fixes false AE1 incomplete-analysis results caused by ordina - Use the project manifest version for RP3 analysis ([#474](https://github.com/NVIDIA/SkillSpector/pull/474)). - Prefer exact known-package matches when evaluating SC6 package-name similarity ([#530](https://github.com/NVIDIA/SkillSpector/pull/530)). - Avoid treating slash-separated prose as local file references ([#451](https://github.com/NVIDIA/SkillSpector/pull/451)). +- Reduce false-positive severity for narrowly proven companion CLI OAuth results and signed self-update documentation while preserving risky findings, and provide contextual explanations for warned pipe-to-shell installers ([#547](https://github.com/NVIDIA/SkillSpector/pull/547)). - Skip symlink test cases when the platform refuses symlink creation ([#501](https://github.com/NVIDIA/SkillSpector/pull/501)). ## Security @@ -44,6 +46,7 @@ SkillSpector 2.11.3 fixes false AE1 incomplete-analysis results caused by ordina - Genuine removal instructions remain reportable. The covered unresolved-runtime-command controls retain incomplete coverage and fail strict CLI/MCP installation gates, including when semantic analysis succeeds. Additional runtime-selected command variants remain under investigation (see Known Limitations). - JSON string ownership preserves source evidence and does not exempt string contents from analysis. - Findings and exit status can change after upgrading: oversized files can add HIGH AE7 findings, letter-spaced instructions can produce P3/P4 or AE6 findings, and previously collapsed distinct matches can increase the retained finding count and risk score. Missing requested analysis remains incomplete even when static analysis finishes. +- Context-aware companion CLI classification can lower severity, scores, or recommendations for narrowly proven benign documentation. Risky token transfers, unsafe self-update variants, and pipe-to-shell installers remain reportable. ## Breaking Changes and Migration @@ -58,21 +61,31 @@ SkillSpector 2.11.3 fixes false AE1 incomplete-analysis results caused by ordina ## Validation -The release candidate includes main commit `0a8b80c36cad7c503f98548d0fa166f90a50294c`. Validation is being repeated against the resulting 2.11.3 artifact after the merges listed above. Earlier results apply only to their recorded commits and are not current-candidate certification. +The release candidate includes main commit `fc500a19e518ec1f25914b2e0fc9a50bd516d669`. Validated locally with Python 3.12.13: -[Release PR #550](https://github.com/NVIDIA/SkillSpector/pull/550) records the candidate commit, artifact identity, regression and integration results, and remaining release gates. +- `uv lock --check --offline` passed with the locked dependency set. +- `make test-ci` passed 5,221 tests, with 14 skipped, 38 deselected, 4 expected failures, and 90% coverage. +- Ruff lint and format checks passed for all source and test files. +- The CLI reported `SkillSpector v2.12.0`; the release helper dry run resolved `v2.12.0` and the matching versioned notes. +- All 10 release helper and workflow tests passed. +- Wheel and source distributions built successfully, and Twine validated both artifacts. +- `git diff --check` passed. + +Hosted checks, deployment/provider validation, and the separate release gates below remain pending for the final PR head. Earlier candidate results apply only to their recorded commits and are not certification of this candidate. + +[Release PR #550](https://github.com/NVIDIA/SkillSpector/pull/550) records the candidate baseline, validation results, known gaps, and remaining release gates. ## Known Limitations - Local sanity checks cover the tested inputs and environment; live provider and deployment behavior depend on their configuration. - Incomplete inspection is a reportable result. Unsupported inputs, unavailable requested analysis, and resource limits must remain visible; these conditions cannot be treated as a clean scan. -- The release remains a draft while current-candidate validation and outstanding release issues are assessed. Proposed fixes in unmerged PRs are not included in this candidate. +- The release remains a candidate while current-head CI and outstanding release issues are assessed. Proposed fixes in unmerged PRs are not included in this candidate. - Current validation found that public report serialization can repeat the first occurrence's columns for other matches; SARIF does not yet preserve these column coordinates. The internal occurrence improvements in #409 do not establish correct locations in every output format. See [release validation](https://github.com/NVIDIA/SkillSpector/pull/550) for the tracked report defect. - Some runtime-selected command variants and Markdown reference destinations still have open completeness defects. Proposed fixes [#514](https://github.com/NVIDIA/SkillSpector/pull/514) and [#553](https://github.com/NVIDIA/SkillSpector/pull/553) are not included in this candidate. ## References -- [Changes since v2.11.2](https://github.com/NVIDIA/SkillSpector/compare/v2.11.2...v2.11.3) +- [Changes since v2.11.2](https://github.com/NVIDIA/SkillSpector/compare/v2.11.2...v2.12.0) - [AE1 documentation fix #516](https://github.com/NVIDIA/SkillSpector/pull/516) - [Static analysis time allowance #522](https://github.com/NVIDIA/SkillSpector/pull/522) diff --git a/pyproject.toml b/pyproject.toml index 3bbe5dcac..e04a8ccaa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "skillspector" -version = "2.11.3" +version = "2.12.0" description = "SkillSpector: Security scanner for AI agent skills (Claude Code, Cursor, and similar). Scans skills for vulnerabilities, malicious patterns, and security risks before installation. Supports Git repos, URLs, zips, and local directories; runs static pattern checks and optional LLM semantic analysis; outputs terminal, JSON, and Markdown reports with risk scoring." readme = "README.md" license = "Apache-2.0" diff --git a/uv.lock b/uv.lock index bf081f918..c2dd47c50 100644 --- a/uv.lock +++ b/uv.lock @@ -2687,7 +2687,7 @@ wheels = [ [[package]] name = "skillspector" -version = "2.11.3" +version = "2.12.0" source = { editable = "." } dependencies = [ { name = "boto3" }, From 5134f62458fa235b487e823d1c0472be54678295 Mon Sep 17 00:00:00 2001 From: Narendran Raghavan Date: Wed, 16 Sep 2026 10:20:57 -0700 Subject: [PATCH 05/12] docs(release): include AS3 self-reference fix Signed-off-by: Narendran Raghavan --- CHANGELOG.md | 1 + docs/release/skillspector-2.12.0.md | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 712a21699..c73262cd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### 2.12.0 (Unreleased) ### Features/Bug Fixes +* fix(as3): ignore current-skill self references (#506) * fix: classify companion CLI documentation by context (#547) * fix(security): enforce discovery and requested analysis completeness (#410) * fix(security): detect letter-spaced P3/P4 instructions and report ambiguous reconstruction as AE6 (#470) diff --git a/docs/release/skillspector-2.12.0.md b/docs/release/skillspector-2.12.0.md index 29a85aeba..1142f8834 100644 --- a/docs/release/skillspector-2.12.0.md +++ b/docs/release/skillspector-2.12.0.md @@ -4,7 +4,7 @@ Release status: candidate; publication pending. ## Summary -SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configurable static-analysis allowance. It also fixes false AE1 incomplete-analysis results caused by ordinary Markdown and JSON documentation, makes discovery and requested-analysis gaps explicit, preserves distinct findings and their source locations, detects letter-spaced prompt instructions, and reduces false positives in companion CLI documentation. Oversized files now produce an explicit coverage finding and bounded LLM input. +SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configurable static-analysis allowance. It also fixes false AE1 incomplete-analysis results caused by ordinary Markdown and JSON documentation, makes discovery and requested-analysis gaps explicit, preserves distinct findings and their source locations, detects letter-spaced prompt instructions, and reduces false positives in companion CLI documentation and literal current-skill references. Oversized files now produce an explicit coverage finding and bounded LLM input. ## Highlights @@ -14,6 +14,7 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configu - Preserve distinct full-evidence and rule identities, including findings with identical shortened previews, and retain precise locations for repeated occurrences. - Keep requested but unavailable or incomplete semantic analysis visible in completeness metadata and strict CLI/MCP decisions. - Classify narrowly proven OAuth, signed self-update, and warned installer documentation in context while retaining the underlying findings and fail-closed controls. +- Suppress AS3 only when a literal `skills//SKILL.md` path identifies the skill currently being scanned, while retaining peer-skill, transformed, and enumeration findings. ## Added @@ -39,6 +40,7 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configu - Prefer exact known-package matches when evaluating SC6 package-name similarity ([#530](https://github.com/NVIDIA/SkillSpector/pull/530)). - Avoid treating slash-separated prose as local file references ([#451](https://github.com/NVIDIA/SkillSpector/pull/451)). - Reduce false-positive severity for narrowly proven companion CLI OAuth results and signed self-update documentation while preserving risky findings, and provide contextual explanations for warned pipe-to-shell installers ([#547](https://github.com/NVIDIA/SkillSpector/pull/547)). +- Ignore literal AS3 references to the current skill, derived from the scan-root basename or manifest name, without suppressing peer-skill or obfuscated-path access ([#506](https://github.com/NVIDIA/SkillSpector/pull/506)). - Skip symlink test cases when the platform refuses symlink creation ([#501](https://github.com/NVIDIA/SkillSpector/pull/501)). ## Security @@ -47,6 +49,7 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configu - JSON string ownership preserves source evidence and does not exempt string contents from analysis. - Findings and exit status can change after upgrading: oversized files can add HIGH AE7 findings, letter-spaced instructions can produce P3/P4 or AE6 findings, and previously collapsed distinct matches can increase the retained finding count and risk score. Missing requested analysis remains incomplete even when static analysis finishes. - Context-aware companion CLI classification can lower severity, scores, or recommendations for narrowly proven benign documentation. Risky token transfers, unsafe self-update variants, and pipe-to-shell installers remain reportable. +- Literal current-skill references no longer produce AS3 findings. Peer-skill references, transformed or obfuscated paths, explicit enumeration, AS1, and AS2 remain reportable. ## Breaking Changes and Migration @@ -61,10 +64,10 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configu ## Validation -The release candidate includes main commit `fc500a19e518ec1f25914b2e0fc9a50bd516d669`. Validated locally with Python 3.12.13: +The release candidate includes main commit `9e078093eb8e621852e937cdc1757dca1c41ad05`. Validated locally with Python 3.12.13: - `uv lock --check --offline` passed with the locked dependency set. -- `make test-ci` passed 5,221 tests, with 14 skipped, 38 deselected, 4 expected failures, and 90% coverage. +- `make test-ci` passed 5,235 tests, with 14 skipped, 38 deselected, 4 expected failures, and 90% coverage. - Ruff lint and format checks passed for all source and test files. - The CLI reported `SkillSpector v2.12.0`; the release helper dry run resolved `v2.12.0` and the matching versioned notes. - All 10 release helper and workflow tests passed. From e6bcf1044b781d9a28ae537cd8a56147edc9afa4 Mon Sep 17 00:00:00 2001 From: Narendran Raghavan Date: Wed, 16 Sep 2026 10:55:00 -0700 Subject: [PATCH 06/12] docs(release): record hosted CI result Signed-off-by: Narendran Raghavan --- docs/release/skillspector-2.12.0.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/release/skillspector-2.12.0.md b/docs/release/skillspector-2.12.0.md index 1142f8834..43f9c7529 100644 --- a/docs/release/skillspector-2.12.0.md +++ b/docs/release/skillspector-2.12.0.md @@ -74,7 +74,7 @@ The release candidate includes main commit `9e078093eb8e621852e937cdc1757dca1c41 - Wheel and source distributions built successfully, and Twine validated both artifacts. - `git diff --check` passed. -Hosted checks, deployment/provider validation, and the separate release gates below remain pending for the final PR head. Earlier candidate results apply only to their recorded commits and are not certification of this candidate. +All five hosted checks passed on the validated release head `5134f62458fa235b487e823d1c0472be54678295`: change detection, lint, unit tests, DCO, and Docker smoke ([run 35127688213](https://github.com/NVIDIA/SkillSpector/actions/runs/35127688213)). Deployment/provider validation and the separate release gates below remain pending. Earlier candidate results apply only to their recorded commits and are not certification of this candidate. [Release PR #550](https://github.com/NVIDIA/SkillSpector/pull/550) records the candidate baseline, validation results, known gaps, and remaining release gates. @@ -82,7 +82,7 @@ Hosted checks, deployment/provider validation, and the separate release gates be - Local sanity checks cover the tested inputs and environment; live provider and deployment behavior depend on their configuration. - Incomplete inspection is a reportable result. Unsupported inputs, unavailable requested analysis, and resource limits must remain visible; these conditions cannot be treated as a clean scan. -- The release remains a candidate while current-head CI and outstanding release issues are assessed. Proposed fixes in unmerged PRs are not included in this candidate. +- The release remains a candidate while outstanding review and release issues are assessed. Proposed fixes in unmerged PRs are not included in this candidate. - Current validation found that public report serialization can repeat the first occurrence's columns for other matches; SARIF does not yet preserve these column coordinates. The internal occurrence improvements in #409 do not establish correct locations in every output format. See [release validation](https://github.com/NVIDIA/SkillSpector/pull/550) for the tracked report defect. - Some runtime-selected command variants and Markdown reference destinations still have open completeness defects. Proposed fixes [#514](https://github.com/NVIDIA/SkillSpector/pull/514) and [#553](https://github.com/NVIDIA/SkillSpector/pull/553) are not included in this candidate. From 4437775257772b974fb7145d922c345ff08af6db Mon Sep 17 00:00:00 2001 From: Narendran Raghavan Date: Wed, 16 Sep 2026 12:36:10 -0700 Subject: [PATCH 07/12] docs(release): document scanner limitations Signed-off-by: Narendran Raghavan --- CHANGELOG.md | 2 +- docs/release/skillspector-2.12.0.md | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c73262cd0..55a307877 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ * fix(as3): ignore current-skill self references (#506) * fix: classify companion CLI documentation by context (#547) * fix(security): enforce discovery and requested analysis completeness (#410) -* fix(security): detect letter-spaced P3/P4 instructions and report ambiguous reconstruction as AE6 (#470) +* fix(security): add bounded reconstruction for letter-spaced P3/P4 instructions with an AE6 fallback for some ambiguous reconstructions (#470) * feat(cli): add opt-in --fail-on-findings across single-skill, recursive, and MCP registry scans (#469) * fix(security): preserve exact finding identity, evidence, and occurrence locations (#409) * fix: report oversized-file coverage gaps as AE7 and bound their LLM input (#509) diff --git a/docs/release/skillspector-2.12.0.md b/docs/release/skillspector-2.12.0.md index 43f9c7529..faccc39e0 100644 --- a/docs/release/skillspector-2.12.0.md +++ b/docs/release/skillspector-2.12.0.md @@ -4,7 +4,7 @@ Release status: candidate; publication pending. ## Summary -SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configurable static-analysis allowance. It also fixes false AE1 incomplete-analysis results caused by ordinary Markdown and JSON documentation, makes discovery and requested-analysis gaps explicit, preserves distinct findings and their source locations, detects letter-spaced prompt instructions, and reduces false positives in companion CLI documentation and literal current-skill references. Oversized files now produce an explicit coverage finding and bounded LLM input. +SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configurable static-analysis allowance. It also fixes false AE1 incomplete-analysis results caused by ordinary Markdown and JSON documentation, makes discovery and requested-analysis gaps explicit, preserves distinct findings and their source locations, adds bounded reconstruction for letter-spaced prompt instructions, and reduces false positives in companion CLI documentation and literal current-skill references. Oversized files now produce an explicit coverage finding and bounded LLM input. ## Highlights @@ -13,7 +13,7 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configu - Scan JSON quote candidates in linear time and retain cancellation handling. - Preserve distinct full-evidence and rule identities, including findings with identical shortened previews, and retain precise locations for repeated occurrences. - Keep requested but unavailable or incomplete semantic analysis visible in completeness metadata and strict CLI/MCP decisions. -- Classify narrowly proven OAuth, signed self-update, and warned installer documentation in context while retaining the underlying findings and fail-closed controls. +- Classify selected OAuth, signed self-update, and warned installer documentation based on surrounding context, subject to the PE3 and RA1 gaps recorded under Known Limitations. - Suppress AS3 only when a literal `skills//SKILL.md` path identifies the skill currently being scanned, while retaining peer-skill, transformed, and enumeration findings. ## Added @@ -32,14 +32,14 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configu - Bound JSON quote traversal without repeatedly scanning overlapping suffixes ([#521](https://github.com/NVIDIA/SkillSpector/pull/521)). - Emit a HIGH AE7 analysis-evasion finding for per-file size limits that leave an artifact partially inspected, unless AE1 already covers that path. Supply a bounded text prefix and an explicit unreviewed-region marker to enabled LLM analysis; the unread region remains incomplete ([#509](https://github.com/NVIDIA/SkillSpector/pull/509)). - Preserve full-evidence fingerprints, concrete YARA rule identity, and precise occurrence locations through projection, deduplication, and report compaction. Separate findings are retained while duplicate projections of the same occurrence are collapsed ([#409](https://github.com/NVIDIA/SkillSpector/pull/409)). -- Detect letter-spaced P3/P4 prompt instructions through bounded reconstruction, retain source evidence, and report ambiguous or irregular letter-spacing reconstruction as AE6 incomplete coverage ([#470](https://github.com/NVIDIA/SkillSpector/pull/470)). +- Add bounded reconstruction for letter-spaced P3/P4 prompt instructions, retain source evidence, and use AE6 as an incomplete-coverage fallback for some ambiguous reconstructions. Some alternating-width short runs can evade both P3/P4 and AE6 (see Known Limitations) ([#470](https://github.com/NVIDIA/SkillSpector/pull/470)). - Discover skills inside dot-prefixed directories, retain inherited local-only restrictions for child skills, and partition transitive scan caching by those privacy restrictions ([#410](https://github.com/NVIDIA/SkillSpector/pull/410)). - Preserve incomplete discovery and requested semantic-analysis failures, including unavailable providers and mixed success/failure telemetry, instead of allowing a complete scan result ([#410](https://github.com/NVIDIA/SkillSpector/pull/410)). - Emit recursive JSON reports to standard output when no output path is provided ([#467](https://github.com/NVIDIA/SkillSpector/pull/467)). - Use the project manifest version for RP3 analysis ([#474](https://github.com/NVIDIA/SkillSpector/pull/474)). - Prefer exact known-package matches when evaluating SC6 package-name similarity ([#530](https://github.com/NVIDIA/SkillSpector/pull/530)). - Avoid treating slash-separated prose as local file references ([#451](https://github.com/NVIDIA/SkillSpector/pull/451)). -- Reduce false-positive severity for narrowly proven companion CLI OAuth results and signed self-update documentation while preserving risky findings, and provide contextual explanations for warned pipe-to-shell installers ([#547](https://github.com/NVIDIA/SkillSpector/pull/547)). +- Reduce false-positive severity for companion CLI OAuth results and signed self-update documentation classified as benign, and provide contextual explanations for warned pipe-to-shell installers. The contextual classifiers have unresolved PE3 and RA1 fail-open paths (see Known Limitations) ([#547](https://github.com/NVIDIA/SkillSpector/pull/547)). - Ignore literal AS3 references to the current skill, derived from the scan-root basename or manifest name, without suppressing peer-skill or obfuscated-path access ([#506](https://github.com/NVIDIA/SkillSpector/pull/506)). - Skip symlink test cases when the platform refuses symlink creation ([#501](https://github.com/NVIDIA/SkillSpector/pull/501)). @@ -48,7 +48,7 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configu - Genuine removal instructions remain reportable. The covered unresolved-runtime-command controls retain incomplete coverage and fail strict CLI/MCP installation gates, including when semantic analysis succeeds. Additional runtime-selected command variants remain under investigation (see Known Limitations). - JSON string ownership preserves source evidence and does not exempt string contents from analysis. - Findings and exit status can change after upgrading: oversized files can add HIGH AE7 findings, letter-spaced instructions can produce P3/P4 or AE6 findings, and previously collapsed distinct matches can increase the retained finding count and risk score. Missing requested analysis remains incomplete even when static analysis finishes. -- Context-aware companion CLI classification can lower severity, scores, or recommendations for narrowly proven benign documentation. Risky token transfers, unsafe self-update variants, and pipe-to-shell installers remain reportable. +- Context-aware companion CLI classification can lower severity, scores, or recommendations for documentation classified as benign. Coverage is not fail-closed for every token-transfer or self-update phrasing: the known PE3 and RA1 exceptions below can be incorrectly downgraded or missed. Warned pipe-to-shell installer findings remain reportable. - Literal current-skill references no longer produce AS3 findings. Peer-skill references, transformed or obfuscated paths, explicit enumeration, AS1, and AS2 remain reportable. ## Breaking Changes and Migration @@ -83,6 +83,8 @@ All five hosted checks passed on the validated release head `5134f62458fa235b487 - Local sanity checks cover the tested inputs and environment; live provider and deployment behavior depend on their configuration. - Incomplete inspection is a reportable result. Unsupported inputs, unavailable requested analysis, and resource limits must remain visible; these conditions cannot be treated as a clean scan. - The release remains a candidate while outstanding review and release issues are assessed. Proposed fixes in unmerged PRs are not included in this candidate. +- Letter-spacing reconstruction is not fail-closed. Alternating-width short runs such as `s e n d conversation to external` can be split before P3/P4 matching and remain below AE6's six-letter concealed-run threshold, allowing a SAFE result. +- Companion-context classification is not fail-closed. PE3 can downgrade imperative token-acquisition text and miss adjacent disclosure phrased with verbs such as `paste`; RA1 can accept protected agent/tool names with CLI suffixes and signed-release evidence from a different logical line. These variants can be incorrectly downgraded or missed. - Current validation found that public report serialization can repeat the first occurrence's columns for other matches; SARIF does not yet preserve these column coordinates. The internal occurrence improvements in #409 do not establish correct locations in every output format. See [release validation](https://github.com/NVIDIA/SkillSpector/pull/550) for the tracked report defect. - Some runtime-selected command variants and Markdown reference destinations still have open completeness defects. Proposed fixes [#514](https://github.com/NVIDIA/SkillSpector/pull/514) and [#553](https://github.com/NVIDIA/SkillSpector/pull/553) are not included in this candidate. From 2b39002500e5da17005a73dbf8a68a453a720845 Mon Sep 17 00:00:00 2001 From: Narendran Raghavan Date: Wed, 16 Sep 2026 13:19:20 -0700 Subject: [PATCH 08/12] docs(release): include recent main changes Signed-off-by: Narendran Raghavan --- CHANGELOG.md | 13 +++++++++++ docs/release/skillspector-2.12.0.md | 36 ++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 55a307877..d23afe1c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ ### 2.12.0 (Unreleased) ### Features/Bug Fixes +* fix(providers): honor model registry overrides for CLI providers (#463) +* test(input): inject secure-open failures on the primitive the platform uses (#503) +* feat(analyzer): add OpenCode-native SkillSpector invocation skill and tool (#537) +* fix(input): expand 8.3 short DOS names before the opened-handle check (#484) +* test(build-context): write fixture content with the newlines the assertions pin (#505) +* test(build-context): guard the second FIFO case on mkfifo availability (#502) +* test(build-context): read the nested OMS fixture without newline translation (#518) +* test(yara): write the non-ASCII malformed-rule fixture as UTF-8 (#504) +* fix(security): account for excluded executables (#548) +* feat(providers): add opencode_cli semantic-scan provider (#536) +* fix(llm): retarget the deadline on the existing client instead of rebuilding it (#520) +* fix: preserve Markdown context during JSON command recovery (#559) +* fix(batch-scan): reuse validated cache for multilingual analysis (#558) * fix(as3): ignore current-skill self references (#506) * fix: classify companion CLI documentation by context (#547) * fix(security): enforce discovery and requested analysis completeness (#410) diff --git a/docs/release/skillspector-2.12.0.md b/docs/release/skillspector-2.12.0.md index faccc39e0..de247656d 100644 --- a/docs/release/skillspector-2.12.0.md +++ b/docs/release/skillspector-2.12.0.md @@ -4,10 +4,15 @@ Release status: candidate; publication pending. ## Summary -SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configurable static-analysis allowance. It also fixes false AE1 incomplete-analysis results caused by ordinary Markdown and JSON documentation, makes discovery and requested-analysis gaps explicit, preserves distinct findings and their source locations, adds bounded reconstruction for letter-spaced prompt instructions, and reduces false positives in companion CLI documentation and literal current-skill references. Oversized files now produce an explicit coverage finding and bounded LLM input. +SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurable static-analysis allowance, an OpenCode CLI semantic-analysis provider, and an OpenCode-native scan command and tool. It also fixes false AE1 incomplete-analysis results caused by ordinary Markdown and JSON documentation, makes discovery and requested-analysis gaps explicit, inventories excluded executable content, preserves distinct findings and their source locations, adds bounded reconstruction for letter-spaced prompt instructions, and reduces false positives in companion CLI documentation and literal current-skill references. Oversized files now produce an explicit coverage finding and bounded LLM input. ## Highlights +- Run semantic analysis through the new `opencode_cli` provider and invoke SkillSpector from OpenCode through a native `/skillspector` command and `skillspector_scan` tool. +- Inventory executable and loadable content in normally excluded locations, preserving coverage evidence and failing closed when referenced or otherwise outside inspection coverage. +- Keep multilingual batch language detection and gap-fill on the graph's validated provider-eligible cache instead of rereading paths after inspection. +- Retarget per-call LLM deadlines on existing clients to avoid connection-pool churn and closed-event-loop cleanup failures. +- Honor model-registry overrides for CLI providers and accept valid Windows 8.3 aliases without weakening opened-handle validation. - Recognize complete JSON strings and Markdown code spans in their document context, avoiding false analysis limits while retaining analysis of their contents. - Keep delimiter pairing within Markdown blocks and table cells so unrelated documentation cannot hide unresolved runtime commands. - Scan JSON quote candidates in linear time and retain cancellation handling. @@ -18,16 +23,24 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configu ## Added +- `SKILLSPECTOR_PROVIDER=opencode_cli` runs semantic analysis through a local OpenCode login. The verified deny-all policy requires exactly OpenCode 1.18.30; authentication, version, policy, empty-output, or event-envelope failures fail closed. `SKILLSPECTOR_MODEL` remains optional ([#536](https://github.com/NVIDIA/SkillSpector/pull/536)). +- The repository-provided OpenCode extension adds a static-by-default `/skillspector` command and `skillspector_scan` tool. Copy `.opencode/` from a checkout to install it; the wheel does not install the extension. It resolves the binary from `SKILLSPECTOR_BIN`, a worktree `.venv`, or `PATH`, requests required host capabilities before launch, rejects symlinked target/output/binary paths, and uses a 120-second timeout with bounded, redacted output. Semantic analysis is opt-in through `noLlm=false` and the provider environment ([#537](https://github.com/NVIDIA/SkillSpector/pull/537)). - `SKILLSPECTOR_MAX_STATIC_ANALYSIS_SECONDS_PER_ARTIFACT` configures the static pattern and YARA time allowance per artifact; its default increases from 30 to 300 seconds. The remaining workflow deadline still bounds both analyzers. - `skillspector scan --fail-on-findings` exits with code 1 when a scan reports any active finding, including findings below the default risk-score threshold. It applies to single-skill, recursive, and MCP registry scans. Skill scans evaluate active findings after suppression ([#469](https://github.com/NVIDIA/SkillSpector/pull/469)). ## Changed +- CLI-backed providers now honor `SKILLSPECTOR_MODEL_REGISTRY` for context and output-token limits. Missing entries retain the existing fallback behavior; malformed registry structures or invalid and non-positive budgets warn and fall back ([#463](https://github.com/NVIDIA/SkillSpector/pull/463)). +- The repository's `contrib/batch_scan` tool reuses the graph's validated `llm_file_cache` for multilingual language detection and gap-fill, avoiding a second raw filesystem read and retaining provider/local-only boundaries. `contrib` remains outside the wheel ([#558](https://github.com/NVIDIA/SkillSpector/pull/558)). - Align provider setup guidance, add the HVTrust badge, and update research background counts ([#434](https://github.com/NVIDIA/SkillSpector/pull/434), [#428](https://github.com/NVIDIA/SkillSpector/pull/428), [#543](https://github.com/NVIDIA/SkillSpector/pull/543)). - Reports retain requested LLM intent separately from runtime availability. Incomplete semantic execution remains visible through aggregate reports and CLI/MCP installation gates ([#410](https://github.com/NVIDIA/SkillSpector/pull/410)). ## Fixed +- Retarget dynamic workflow deadlines on existing OpenAI, Anthropic, and agent-CLI clients instead of constructing a new client per call, preventing connection-pool churn and closed-event-loop cleanup errors while preserving retry and concurrency behavior ([#520](https://github.com/NVIDIA/SkillSpector/pull/520)). +- Preserve whole-document Markdown ownership when recovering commands from validated JSON strings so fenced or literal content is not reinterpreted as standalone Markdown and unresolved commands cannot become a clean result through unrelated JSON adjacency ([#559](https://github.com/NVIDIA/SkillSpector/pull/559)). +- Inventory normally excluded executable and loadable content, retain root-coverage evidence, resolve explicit extensionless command paths, and inspect excluded ZIP-family containers within existing limits. Referenced executable exclusions or incomplete excluded-artifact inspection now emit HIGH SC9/incomplete evidence with the existing minimum score of 51 (`DO_NOT_INSTALL`); the narrow exception for direct, non-binary `.git/hooks/*.sample` files remains ([#548](https://github.com/NVIDIA/SkillSpector/pull/548)). +- Expand Windows 8.3 short-name components before comparing a requested path with its opened handle, allowing valid paths under spaced profile directories while retaining reparse-point and fail-closed checks ([#484](https://github.com/NVIDIA/SkillSpector/pull/484)). - Avoid false AE1 results from valid JSON placeholders, inline code, list and blockquote containers, indented JSON, Markdown tables, and literal Make syntax ([#516](https://github.com/NVIDIA/SkillSpector/pull/516)). - Bound JSON quote traversal without repeatedly scanning overlapping suffixes ([#521](https://github.com/NVIDIA/SkillSpector/pull/521)). - Emit a HIGH AE7 analysis-evasion finding for per-file size limits that leave an artifact partially inspected, unless AE1 already covers that path. Supply a bounded text prefix and an explicit unreviewed-region marker to enabled LLM analysis; the unread region remains incomplete ([#509](https://github.com/NVIDIA/SkillSpector/pull/509)). @@ -43,8 +56,16 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configu - Ignore literal AS3 references to the current skill, derived from the scan-root basename or manifest name, without suppressing peer-skill or obfuscated-path access ([#506](https://github.com/NVIDIA/SkillSpector/pull/506)). - Skip symlink test cases when the platform refuses symlink creation ([#501](https://github.com/NVIDIA/SkillSpector/pull/501)). +## Testing and Portability + +- Make secure-open, FIFO, newline-sensitive build-context, nested OMS, and non-ASCII YARA fixtures deterministic across Windows and non-POSIX environments ([#503](https://github.com/NVIDIA/SkillSpector/pull/503), [#502](https://github.com/NVIDIA/SkillSpector/pull/502), [#505](https://github.com/NVIDIA/SkillSpector/pull/505), [#518](https://github.com/NVIDIA/SkillSpector/pull/518), [#504](https://github.com/NVIDIA/SkillSpector/pull/504)). +- Add dependency-free Node 22+ tests for the OpenCode tool helpers and an exact-head OpenCode TypeScript CI job ([#537](https://github.com/NVIDIA/SkillSpector/pull/537)). + ## Security +- Excluded executable or loadable content is inventoried before exclusion. Referenced or out-of-coverage bytes now produce SC9 and incomplete-analysis evidence that blocks strict installation gates; the narrow exception is limited to direct, non-binary `.git/hooks/*.sample` files. +- Multilingual batch analysis consumes only the validated provider-eligible snapshot, so language detection and gap-fill do not reread local-only or replaced path content after the core scan. +- OpenCode integration is static by default. The native tool redacts common secret forms and bounds output, while the semantic provider uses argv/stdin and treats missing authentication, empty output, or unsupported event streams as failures. - Genuine removal instructions remain reportable. The covered unresolved-runtime-command controls retain incomplete coverage and fail strict CLI/MCP installation gates, including when semantic analysis succeeds. Additional runtime-selected command variants remain under investigation (see Known Limitations). - JSON string ownership preserves source evidence and does not exempt string contents from analysis. - Findings and exit status can change after upgrading: oversized files can add HIGH AE7 findings, letter-spaced instructions can produce P3/P4 or AE6 findings, and previously collapsed distinct matches can increase the retained finding count and risk score. Missing requested analysis remains incomplete even when static analysis finishes. @@ -53,6 +74,9 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configu ## Breaking Changes and Migration +- `opencode_cli` is opt-in and requires an authenticated OpenCode 1.18.30 executable; other versions fail closed because their deny-all policy has not been verified. The OpenCode-native tool is installed by copying `.opencode/` from a checkout and defaults to static analysis; set `noLlm=false` and configure the provider environment to request semantic analysis. +- Existing CLI-provider deployments that set `SKILLSPECTOR_MODEL_REGISTRY` now use its valid token budgets. Invalid or non-positive values warn and fall back instead of aborting. +- Scans that previously treated excluded executable content as clean can now become incomplete with SC9 and `DO_NOT_INSTALL`; consumers should retain completeness and exclusion evidence. - No new configuration is required. Static analysis can now run longer within the existing workflow deadline. Set `SKILLSPECTOR_MAX_STATIC_ANALYSIS_SECONDS_PER_ARTIFACT=30` to retain the previous per-artifact allowance, and restart the SkillSpector process after changing the setting ([#522](https://github.com/NVIDIA/SkillSpector/pull/522)). - `--fail-on-findings` is opt-in. Combine it with `--fail-on-incomplete` when CI must reject either active findings or incomplete coverage. Code 2 still denotes an input or execution error; a nonzero exit alone does not identify which condition occurred. - Consumers should retain completeness/degradation metadata and inspect findings as well as exit status. Explicitly use `--no-llm` for an intended static-only scan; requesting LLM analysis without an available provider is incomplete. @@ -64,7 +88,7 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding and a configu ## Validation -The release candidate includes main commit `9e078093eb8e621852e937cdc1757dca1c41ad05`. Validated locally with Python 3.12.13: +The release candidate is synchronized through main commit `4d5204893f0cd117d138990b28434ee37348fffc`. The earlier application-code head `5134f62458fa235b487e823d1c0472be54678295` was validated locally with Python 3.12.13: - `uv lock --check --offline` passed with the locked dependency set. - `make test-ci` passed 5,235 tests, with 14 skipped, 38 deselected, 4 expected failures, and 90% coverage. @@ -74,7 +98,9 @@ The release candidate includes main commit `9e078093eb8e621852e937cdc1757dca1c41 - Wheel and source distributions built successfully, and Twine validated both artifacts. - `git diff --check` passed. -All five hosted checks passed on the validated release head `5134f62458fa235b487e823d1c0472be54678295`: change detection, lint, unit tests, DCO, and Docker smoke ([run 35127688213](https://github.com/NVIDIA/SkillSpector/actions/runs/35127688213)). Deployment/provider validation and the separate release gates below remain pending. Earlier candidate results apply only to their recorded commits and are not certification of this candidate. +For the release-catalog reconciliation through `4d5204893f0cd117d138990b28434ee37348fffc`, `uv lock --check --offline`, `uv run skillspector --version`, all 10 release-helper and workflow tests, and `git diff --check` passed locally. + +All five hosted checks passed on the historical release head `5134f62458fa235b487e823d1c0472be54678295`: change detection, lint, unit tests, DCO, and Docker smoke ([run 35127688213](https://github.com/NVIDIA/SkillSpector/actions/runs/35127688213)). The current PR head and its exact-head checks are the source of truth after subsequent `main` synchronizations. Deployment/provider validation and the separate release gates below remain pending. Earlier candidate results apply only to their recorded commits and are not certification of this candidate. [Release PR #550](https://github.com/NVIDIA/SkillSpector/pull/550) records the candidate baseline, validation results, known gaps, and remaining release gates. @@ -87,11 +113,15 @@ All five hosted checks passed on the validated release head `5134f62458fa235b487 - Companion-context classification is not fail-closed. PE3 can downgrade imperative token-acquisition text and miss adjacent disclosure phrased with verbs such as `paste`; RA1 can accept protected agent/tool names with CLI suffixes and signed-release evidence from a different logical line. These variants can be incorrectly downgraded or missed. - Current validation found that public report serialization can repeat the first occurrence's columns for other matches; SARIF does not yet preserve these column coordinates. The internal occurrence improvements in #409 do not establish correct locations in every output format. See [release validation](https://github.com/NVIDIA/SkillSpector/pull/550) for the tracked report defect. - Some runtime-selected command variants and Markdown reference destinations still have open completeness defects. Proposed fixes [#514](https://github.com/NVIDIA/SkillSpector/pull/514) and [#553](https://github.com/NVIDIA/SkillSpector/pull/553) are not included in this candidate. +- `opencode_cli` currently reports no token-usage accounting, and model availability or rate limits remain external. Multilingual batch gap-fill was validated with mocked providers; live-provider qualification remains pending. ## References - [Changes since v2.11.2](https://github.com/NVIDIA/SkillSpector/compare/v2.11.2...v2.12.0) - [AE1 documentation fix #516](https://github.com/NVIDIA/SkillSpector/pull/516) - [Static analysis time allowance #522](https://github.com/NVIDIA/SkillSpector/pull/522) +- [OpenCode CLI provider #536](https://github.com/NVIDIA/SkillSpector/pull/536) +- [OpenCode-native integration #537](https://github.com/NVIDIA/SkillSpector/pull/537) +- [Excluded executable coverage #548](https://github.com/NVIDIA/SkillSpector/pull/548) Prepared by Codex for Mohit Gupta. From 3dd2defa4beee58b9342fcdad2f0fe0e1a7add64 Mon Sep 17 00:00:00 2001 From: Narendran Raghavan Date: Thu, 17 Sep 2026 12:56:42 -0700 Subject: [PATCH 09/12] docs(release): include latest main changes Signed-off-by: Narendran Raghavan --- CHANGELOG.md | 7 +++++++ docs/release/skillspector-2.12.0.md | 32 +++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d23afe1c4..db82f4739 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ ### 2.12.0 (Unreleased) ### Features/Bug Fixes +* fix(hooks): fail closed on unmodeled payload analysis (#573) +* perf(security): cache pure security-view predicates (#570) +* perf(security): accelerate token-gap classification with ASCII fast paths (#569) +* fix(input): download raw content for GitHub and GitLab blob URLs (#566) +* fix(cli): emit recursive SARIF reports to stdout (#565) +* fix(security): keep line breaks out of letter-spacing runs (#564) +* feat(cli): add streamed progress, file discovery, and Gemini 3.5 Flash metadata (#7) * fix(providers): honor model registry overrides for CLI providers (#463) * test(input): inject secure-open failures on the primitive the platform uses (#503) * feat(analyzer): add OpenCode-native SkillSpector invocation skill and tool (#537) diff --git a/docs/release/skillspector-2.12.0.md b/docs/release/skillspector-2.12.0.md index de247656d..7fcdbaf50 100644 --- a/docs/release/skillspector-2.12.0.md +++ b/docs/release/skillspector-2.12.0.md @@ -4,12 +4,16 @@ Release status: candidate; publication pending. ## Summary -SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurable static-analysis allowance, an OpenCode CLI semantic-analysis provider, and an OpenCode-native scan command and tool. It also fixes false AE1 incomplete-analysis results caused by ordinary Markdown and JSON documentation, makes discovery and requested-analysis gaps explicit, inventories excluded executable content, preserves distinct findings and their source locations, adds bounded reconstruction for letter-spaced prompt instructions, and reduces false positives in companion CLI documentation and literal current-skill references. Oversized files now produce an explicit coverage finding and bounded LLM input. +SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurable static-analysis allowance, an OpenCode CLI semantic-analysis provider, an OpenCode-native scan command and tool, Gemini 3.5 Flash registry guidance, and bounded interactive CLI progress with discovered-file visibility. It also fixes false AE1 incomplete-analysis results caused by ordinary Markdown and JSON documentation, makes discovery and requested-analysis gaps explicit, inventories excluded executable content, fails closed on unmodeled active-hook payloads, preserves distinct findings and their source locations, emits valid recursive SARIF to standard output, handles forge `/blob/` links as raw files, and reduces both false positives and repeated security-view work. Oversized files now produce an explicit coverage finding and bounded LLM input. ## Highlights - Run semantic analysis through the new `opencode_cli` provider and invoke SkillSpector from OpenCode through a native `/skillspector` command and `skillspector_scan` tool. +- Use `gemini-3.5-flash` through the existing OpenAI-compatible provider, and see bounded live progress plus a control-safe discovered-file tree during non-verbose interactive scans. +- Emit merged recursive SARIF on standard output without status-text contamination, and scan GitHub/GitLab `/blob/` links as their raw file contents instead of forge HTML. - Inventory executable and loadable content in normally excluded locations, preserving coverage evidence and failing closed when referenced or otherwise outside inspection coverage. +- Mark active hooks with unmodeled payload data flow as partial and opaque, retaining BH1 while preventing a misleading `SAFE` recommendation. +- Reduce security-view CPU and tail latency with ASCII token-gap fast paths and bounded memoization while preserving findings and coverage outcomes. - Keep multilingual batch language detection and gap-fill on the graph's validated provider-eligible cache instead of rereading paths after inspection. - Retarget per-call LLM deadlines on existing clients to avoid connection-pool churn and closed-event-loop cleanup failures. - Honor model-registry overrides for CLI providers and accept valid Windows 8.3 aliases without weakening opened-handle validation. @@ -27,9 +31,12 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab - The repository-provided OpenCode extension adds a static-by-default `/skillspector` command and `skillspector_scan` tool. Copy `.opencode/` from a checkout to install it; the wheel does not install the extension. It resolves the binary from `SKILLSPECTOR_BIN`, a worktree `.venv`, or `PATH`, requests required host capabilities before launch, rejects symlinked target/output/binary paths, and uses a 120-second timeout with bounded, redacted output. Semantic analysis is opt-in through `noLlm=false` and the provider environment ([#537](https://github.com/NVIDIA/SkillSpector/pull/537)). - `SKILLSPECTOR_MAX_STATIC_ANALYSIS_SECONDS_PER_ARTIFACT` configures the static pattern and YARA time allowance per artifact; its default increases from 30 to 300 seconds. The remaining workflow deadline still bounds both analyzers. - `skillspector scan --fail-on-findings` exits with code 1 when a scan reports any active finding, including findings below the default risk-score threshold. It applies to single-skill, recursive, and MCP registry scans. Skill scans evaluate active findings after suppression ([#469](https://github.com/NVIDIA/SkillSpector/pull/469)). +- `gemini-3.5-flash` model budgets are registered for the root and OpenAI-compatible registries, with a Gemini setup example using the existing `openai` provider ([#7](https://github.com/NVIDIA/SkillSpector/pull/7)). ## Changed +- Non-verbose scans attached to an interactive terminal now stream graph execution and render bounded progress, completed analyzer rules, and a control-safe discovered-file tree to standard error. Machine-readable standard output and exit-code behavior remain intact ([#7](https://github.com/NVIDIA/SkillSpector/pull/7)). +- Printable-ASCII token-gap scans use precomputed classification tables and a whole-text fast path; repeated pure security-view predicates use bounded memoization. The measured 901-skill corpus retained byte-identical findings and coverage outcomes while reducing p95, p99, and total CPU cost ([#569](https://github.com/NVIDIA/SkillSpector/pull/569), [#570](https://github.com/NVIDIA/SkillSpector/pull/570)). - CLI-backed providers now honor `SKILLSPECTOR_MODEL_REGISTRY` for context and output-token limits. Missing entries retain the existing fallback behavior; malformed registry structures or invalid and non-positive budgets warn and fall back ([#463](https://github.com/NVIDIA/SkillSpector/pull/463)). - The repository's `contrib/batch_scan` tool reuses the graph's validated `llm_file_cache` for multilingual language detection and gap-fill, avoiding a second raw filesystem read and retaining provider/local-only boundaries. `contrib` remains outside the wheel ([#558](https://github.com/NVIDIA/SkillSpector/pull/558)). - Align provider setup guidance, add the HVTrust badge, and update research background counts ([#434](https://github.com/NVIDIA/SkillSpector/pull/434), [#428](https://github.com/NVIDIA/SkillSpector/pull/428), [#543](https://github.com/NVIDIA/SkillSpector/pull/543)). @@ -37,6 +44,10 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab ## Fixed +- Active hook declarations whose payload data flow remains unmodeled now retain the BH1 mechanism finding and record partial `opaque_content` coverage, making completeness false and preventing a `SAFE` recommendation ([#573](https://github.com/NVIDIA/SkillSpector/pull/573)). +- Letter-spacing reconstruction no longer treats a logical line break as the start of a token run, so CRLF or punctuation on the previous heading cannot turn identifier-adjacent text into false P3/P4 findings; AE6 still records the ambiguous form ([#564](https://github.com/NVIDIA/SkillSpector/pull/564)). +- Recursive `--format sarif` scans without `--output` now emit the merged SARIF log to standard output. SARIF advisories, progress, verbose status, and transitive warnings stay on standard error so the output remains parseable ([#565](https://github.com/NVIDIA/SkillSpector/pull/565)). +- GitHub and GitLab `/blob/` file URLs are rewritten to their raw-file forms before download, preventing scans of forge HTML in place of the requested file ([#566](https://github.com/NVIDIA/SkillSpector/pull/566)). - Retarget dynamic workflow deadlines on existing OpenAI, Anthropic, and agent-CLI clients instead of constructing a new client per call, preventing connection-pool churn and closed-event-loop cleanup errors while preserving retry and concurrency behavior ([#520](https://github.com/NVIDIA/SkillSpector/pull/520)). - Preserve whole-document Markdown ownership when recovering commands from validated JSON strings so fenced or literal content is not reinterpreted as standalone Markdown and unresolved commands cannot become a clean result through unrelated JSON adjacency ([#559](https://github.com/NVIDIA/SkillSpector/pull/559)). - Inventory normally excluded executable and loadable content, retain root-coverage evidence, resolve explicit extensionless command paths, and inspect excluded ZIP-family containers within existing limits. Referenced executable exclusions or incomplete excluded-artifact inspection now emit HIGH SC9/incomplete evidence with the existing minimum score of 51 (`DO_NOT_INSTALL`); the narrow exception for direct, non-binary `.git/hooks/*.sample` files remains ([#548](https://github.com/NVIDIA/SkillSpector/pull/548)). @@ -63,6 +74,7 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab ## Security +- Active hook payloads whose data flow is not modeled remain visible through BH1 and now make analysis partial with `opaque_content`, preventing a complete or `SAFE` result for those hooks. - Excluded executable or loadable content is inventoried before exclusion. Referenced or out-of-coverage bytes now produce SC9 and incomplete-analysis evidence that blocks strict installation gates; the narrow exception is limited to direct, non-binary `.git/hooks/*.sample` files. - Multilingual batch analysis consumes only the validated provider-eligible snapshot, so language detection and gap-fill do not reread local-only or replaced path content after the core scan. - OpenCode integration is static by default. The native tool redacts common secret forms and bounds output, while the semantic provider uses argv/stdin and treats missing authentication, empty output, or unsupported event streams as failures. @@ -74,6 +86,9 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab ## Breaking Changes and Migration +- Interactive non-verbose scans now show progress and discovered files on standard error. Machine-readable JSON and SARIF remain clean on standard output; use `--verbose` to retain the non-streamed diagnostic path. +- Scanning GitHub or GitLab `/blob/` links now analyzes raw file bytes rather than the forge viewer page. Findings and recommendations can change because the intended content is finally scanned. +- Active hooks with unmodeled payload flows now produce incomplete coverage and cannot remain `SAFE`; identifier-adjacent letter spacing can lose false P3/P4 findings while retaining AE6. - `opencode_cli` is opt-in and requires an authenticated OpenCode 1.18.30 executable; other versions fail closed because their deny-all policy has not been verified. The OpenCode-native tool is installed by copying `.opencode/` from a checkout and defaults to static analysis; set `noLlm=false` and configure the provider environment to request semantic analysis. - Existing CLI-provider deployments that set `SKILLSPECTOR_MODEL_REGISTRY` now use its valid token budgets. Invalid or non-positive values warn and fall back instead of aborting. - Scans that previously treated excluded executable content as clean can now become incomplete with SC9 and `DO_NOT_INSTALL`; consumers should retain completeness and exclusion evidence. @@ -88,19 +103,19 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab ## Validation -The release candidate is synchronized through main commit `4d5204893f0cd117d138990b28434ee37348fffc`. The earlier application-code head `5134f62458fa235b487e823d1c0472be54678295` was validated locally with Python 3.12.13: +The release candidate is synchronized through main commit `548e5e0afd25595ef039c27cdeb283413c282c71` and was validated locally on the refreshed release-catalog working tree with Python 3.12.13: - `uv lock --check --offline` passed with the locked dependency set. -- `make test-ci` passed 5,235 tests, with 14 skipped, 38 deselected, 4 expected failures, and 90% coverage. +- `make test-ci` passed 5,744 tests, with 14 skipped, 39 deselected, 4 expected failures, and 90% coverage. +- The affected CLI, model-registry, input, security-view, hook-completeness, and release-helper suites passed 1,177 tests, with 10 skipped and 1 deselected. - Ruff lint and format checks passed for all source and test files. - The CLI reported `SkillSpector v2.12.0`; the release helper dry run resolved `v2.12.0` and the matching versioned notes. - All 10 release helper and workflow tests passed. +- All 44 OpenCode TypeScript tests passed. - Wheel and source distributions built successfully, and Twine validated both artifacts. - `git diff --check` passed. -For the release-catalog reconciliation through `4d5204893f0cd117d138990b28434ee37348fffc`, `uv lock --check --offline`, `uv run skillspector --version`, all 10 release-helper and workflow tests, and `git diff --check` passed locally. - -All five hosted checks passed on the historical release head `5134f62458fa235b487e823d1c0472be54678295`: change detection, lint, unit tests, DCO, and Docker smoke ([run 35127688213](https://github.com/NVIDIA/SkillSpector/actions/runs/35127688213)). The current PR head and its exact-head checks are the source of truth after subsequent `main` synchronizations. Deployment/provider validation and the separate release gates below remain pending. Earlier candidate results apply only to their recorded commits and are not certification of this candidate. +The current PR head and its exact-head checks are the source of truth for hosted validation. Deployment/provider validation and the separate release gates below remain pending. Earlier candidate results apply only to their recorded commits and are not certification of this candidate. [Release PR #550](https://github.com/NVIDIA/SkillSpector/pull/550) records the candidate baseline, validation results, known gaps, and remaining release gates. @@ -123,5 +138,10 @@ All five hosted checks passed on the historical release head `5134f62458fa235b48 - [OpenCode CLI provider #536](https://github.com/NVIDIA/SkillSpector/pull/536) - [OpenCode-native integration #537](https://github.com/NVIDIA/SkillSpector/pull/537) - [Excluded executable coverage #548](https://github.com/NVIDIA/SkillSpector/pull/548) +- [Gemini registry and CLI progress #7](https://github.com/NVIDIA/SkillSpector/pull/7) +- [Recursive SARIF stdout #565](https://github.com/NVIDIA/SkillSpector/pull/565) +- [Raw forge file URLs #566](https://github.com/NVIDIA/SkillSpector/pull/566) +- [Security-view performance #569](https://github.com/NVIDIA/SkillSpector/pull/569), [#570](https://github.com/NVIDIA/SkillSpector/pull/570) +- [Fail-closed hook payload coverage #573](https://github.com/NVIDIA/SkillSpector/pull/573) Prepared by Codex for Mohit Gupta. From 3646bb3ed3b38e41ac1a265cba53b868fbc230cd Mon Sep 17 00:00:00 2001 From: Narendran Raghavan Date: Mon, 21 Sep 2026 09:19:21 -0700 Subject: [PATCH 10/12] docs(release): refresh 2.12.0 through latest merged fixes Signed-off-by: Narendran Raghavan --- CHANGELOG.md | 9 ++++++ docs/release/skillspector-2.12.0.md | 43 +++++++++++++++++++++-------- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db82f4739..fabf983c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ ### 2.12.0 (Unreleased) ### Features/Bug Fixes +* fix(llm): retry transient provider failures within the workflow deadline (#555) +* feat(providers): verify OpenCode 1.18.31 for the deny-all policy (#575) +* fix(sc8): detect shipped bytecode in Python virtual environments (#571) +* fix(ast): detect reflective module namespace lookups (#517) +* fix(static): keep prose pattern matches within paragraph boundaries (#491) +* feat(tp4): analyze executable Markdown fences as skill implementation (#421) +* fix(mcp): distinguish missing references from ambiguous installation blockers (#526) +* docs(readme): remove third-party status badges (#582) +* fix(security): bound local inputs and isolate Pi extension report writes (#562) * fix(hooks): fail closed on unmodeled payload analysis (#573) * perf(security): cache pure security-view predicates (#570) * perf(security): accelerate token-gap classification with ASCII fast paths (#569) diff --git a/docs/release/skillspector-2.12.0.md b/docs/release/skillspector-2.12.0.md index 7fcdbaf50..a8befbacd 100644 --- a/docs/release/skillspector-2.12.0.md +++ b/docs/release/skillspector-2.12.0.md @@ -4,10 +4,13 @@ Release status: candidate; publication pending. ## Summary -SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurable static-analysis allowance, an OpenCode CLI semantic-analysis provider, an OpenCode-native scan command and tool, Gemini 3.5 Flash registry guidance, and bounded interactive CLI progress with discovered-file visibility. It also fixes false AE1 incomplete-analysis results caused by ordinary Markdown and JSON documentation, makes discovery and requested-analysis gaps explicit, inventories excluded executable content, fails closed on unmodeled active-hook payloads, preserves distinct findings and their source locations, emits valid recursive SARIF to standard output, handles forge `/blob/` links as raw files, and reduces both false positives and repeated security-view work. Oversized files now produce an explicit coverage finding and bounded LLM input. +SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurable static-analysis allowance, OpenCode integrations, Gemini 3.5 Flash registry guidance, interactive scan progress, and TP4 analysis of executable Markdown fences. It also strengthens local input and report handling, expands detection of reflective Python access and shipped bytecode, retries transient provider failures, and distinguishes missing references from ambiguous MCP installation blockers. The release includes discovery, completeness, finding-identity, SARIF output, raw forge-file input, performance, and false-positive fixes described below. ## Highlights +- Extend TP4 semantic checks to executable Markdown fences, detect reflective Python module lookups, and find shipped bytecode inside Python environments. +- Retry transient provider failures within the workflow deadline and constrain local registry, baseline, and Pi extension inputs and report writes. +- Distinguish missing file references from ambiguous references in the MCP installation decision, while preserving completeness caveats in reports. - Run semantic analysis through the new `opencode_cli` provider and invoke SkillSpector from OpenCode through a native `/skillspector` command and `skillspector_scan` tool. - Use `gemini-3.5-flash` through the existing OpenAI-compatible provider, and see bounded live progress plus a control-safe discovered-file tree during non-verbose interactive scans. - Emit merged recursive SARIF on standard output without status-text contamination, and scan GitHub/GitLab `/blob/` links as their raw file contents instead of forge HTML. @@ -27,7 +30,8 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab ## Added -- `SKILLSPECTOR_PROVIDER=opencode_cli` runs semantic analysis through a local OpenCode login. The verified deny-all policy requires exactly OpenCode 1.18.30; authentication, version, policy, empty-output, or event-envelope failures fail closed. `SKILLSPECTOR_MODEL` remains optional ([#536](https://github.com/NVIDIA/SkillSpector/pull/536)). +- `SKILLSPECTOR_PROVIDER=opencode_cli` runs semantic analysis through a local OpenCode login. The verified deny-all policy requires exactly OpenCode 1.18.31; authentication, version, policy, empty-output, or event-envelope failures fail closed. `SKILLSPECTOR_MODEL` remains optional ([#536](https://github.com/NVIDIA/SkillSpector/pull/536), [#575](https://github.com/NVIDIA/SkillSpector/pull/575)). +- TP4 semantic analysis includes non-empty, closed Markdown/text fences with recognized executable-language labels, using the validated provider-eligible cache and original document line numbers. Size, count, prompt, and runtime limits remain explicit coverage constraints ([#421](https://github.com/NVIDIA/SkillSpector/pull/421)). - The repository-provided OpenCode extension adds a static-by-default `/skillspector` command and `skillspector_scan` tool. Copy `.opencode/` from a checkout to install it; the wheel does not install the extension. It resolves the binary from `SKILLSPECTOR_BIN`, a worktree `.venv`, or `PATH`, requests required host capabilities before launch, rejects symlinked target/output/binary paths, and uses a 120-second timeout with bounded, redacted output. Semantic analysis is opt-in through `noLlm=false` and the provider environment ([#537](https://github.com/NVIDIA/SkillSpector/pull/537)). - `SKILLSPECTOR_MAX_STATIC_ANALYSIS_SECONDS_PER_ARTIFACT` configures the static pattern and YARA time allowance per artifact; its default increases from 30 to 300 seconds. The remaining workflow deadline still bounds both analyzers. - `skillspector scan --fail-on-findings` exits with code 1 when a scan reports any active finding, including findings below the default risk-score threshold. It applies to single-skill, recursive, and MCP registry scans. Skill scans evaluate active findings after suppression ([#469](https://github.com/NVIDIA/SkillSpector/pull/469)). @@ -35,15 +39,22 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab ## Changed +- Missing local references now use `reference_missing`; ambiguous matches retain `reference_unresolved`. The MCP skill-scan installation decision can allow a scan whose only caveats are missing references, provided all discovered files were inspected and the other risk, execution, and requested-analysis checks pass. Completeness metadata and the report recommendation still retain the caveat ([#526](https://github.com/NVIDIA/SkillSpector/pull/526)). +- Remove the OpenSSF Scorecard and HVTrust README badges ([#582](https://github.com/NVIDIA/SkillSpector/pull/582)). - Non-verbose scans attached to an interactive terminal now stream graph execution and render bounded progress, completed analyzer rules, and a control-safe discovered-file tree to standard error. Machine-readable standard output and exit-code behavior remain intact ([#7](https://github.com/NVIDIA/SkillSpector/pull/7)). - Printable-ASCII token-gap scans use precomputed classification tables and a whole-text fast path; repeated pure security-view predicates use bounded memoization. The measured 901-skill corpus retained byte-identical findings and coverage outcomes while reducing p95, p99, and total CPU cost ([#569](https://github.com/NVIDIA/SkillSpector/pull/569), [#570](https://github.com/NVIDIA/SkillSpector/pull/570)). - CLI-backed providers now honor `SKILLSPECTOR_MODEL_REGISTRY` for context and output-token limits. Missing entries retain the existing fallback behavior; malformed registry structures or invalid and non-positive budgets warn and fall back ([#463](https://github.com/NVIDIA/SkillSpector/pull/463)). - The repository's `contrib/batch_scan` tool reuses the graph's validated `llm_file_cache` for multilingual language detection and gap-fill, avoiding a second raw filesystem read and retaining provider/local-only boundaries. `contrib` remains outside the wheel ([#558](https://github.com/NVIDIA/SkillSpector/pull/558)). -- Align provider setup guidance, add the HVTrust badge, and update research background counts ([#434](https://github.com/NVIDIA/SkillSpector/pull/434), [#428](https://github.com/NVIDIA/SkillSpector/pull/428), [#543](https://github.com/NVIDIA/SkillSpector/pull/543)). +- Align provider setup guidance and update research background counts ([#434](https://github.com/NVIDIA/SkillSpector/pull/434), [#543](https://github.com/NVIDIA/SkillSpector/pull/543)). The HVTrust badge added in [#428](https://github.com/NVIDIA/SkillSpector/pull/428) was subsequently removed in #582. - Reports retain requested LLM intent separately from runtime availability. Incomplete semantic execution remains visible through aggregate reports and CLI/MCP installation gates ([#410](https://github.com/NVIDIA/SkillSpector/pull/410)). ## Fixed +- Retry transient connection, timeout, selected HTTP status, and Bedrock service/throttling failures with bounded backoff and bounded `Retry-After` handling. Retry waits respect the workflow deadline; Bedrock SDK retries are disabled to avoid stacking retry budgets, and unrecovered failures retain incomplete analysis with sanitized diagnostics ([#555](https://github.com/NVIDIA/SkillSpector/pull/555)). +- Bound local MCP Registry JSON and suppression-baseline YAML/JSON before expansion, reject non-regular input files, and limit bytes, nesting, and records. The Pi extension resolves an explicit installed binary and stages report writes before atomically publishing within the workspace, preserving diagnostic reports where available ([#562](https://github.com/NVIDIA/SkillSpector/pull/562)). +- Constrain prose-oriented static patterns to a single paragraph so unrelated text across blank lines does not combine into a finding; executable and structured-code patterns retain multiline matching ([#491](https://github.com/NVIDIA/SkillSpector/pull/491)). +- Detect imported-module namespace access through `__dict__` or `vars(module)` using subscripts, `get`, `setdefault`, and `pop`: dynamic keys produce AST7 and dangerous literal names produce AST9 ([#517](https://github.com/NVIDIA/SkillSpector/pull/517)). +- Inspect `.venv`, `venv`, and `.tox` for shipped `.pyc`/`.pyo` files under existing traversal limits so Python environments cannot silently hide SC8 bytecode findings ([#571](https://github.com/NVIDIA/SkillSpector/pull/571)). - Active hook declarations whose payload data flow remains unmodeled now retain the BH1 mechanism finding and record partial `opaque_content` coverage, making completeness false and preventing a `SAFE` recommendation ([#573](https://github.com/NVIDIA/SkillSpector/pull/573)). - Letter-spacing reconstruction no longer treats a logical line break as the start of a token run, so CRLF or punctuation on the previous heading cannot turn identifier-adjacent text into false P3/P4 findings; AE6 still records the ambiguous form ([#564](https://github.com/NVIDIA/SkillSpector/pull/564)). - Recursive `--format sarif` scans without `--output` now emit the merged SARIF log to standard output. SARIF advisories, progress, verbose status, and transitive warnings stay on standard error so the output remains parseable ([#565](https://github.com/NVIDIA/SkillSpector/pull/565)). @@ -74,6 +85,9 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab ## Security +- Local registry files are limited to 16 MiB, 64 nesting levels, and 10,000 combined server/package/remote records. Baselines are limited to 2 MiB, 64 nesting levels, and 10,000 rules/fingerprints, with additional bounds on YAML nodes, scalars, and alias expansion. +- Pi extension reports must remain within the workspace. Staged replacement avoids writing through existing hard links; symlink and non-file destinations are rejected. This changes the Pi extension's output-path and executable-discovery requirements. +- Agent CLI subprocesses also remove Anthropic proxy and SkillSpector API credentials from inherited environment variables ([#562](https://github.com/NVIDIA/SkillSpector/pull/562)). - Active hook payloads whose data flow is not modeled remain visible through BH1 and now make analysis partial with `opaque_content`, preventing a complete or `SAFE` result for those hooks. - Excluded executable or loadable content is inventoried before exclusion. Referenced or out-of-coverage bytes now produce SC9 and incomplete-analysis evidence that blocks strict installation gates; the narrow exception is limited to direct, non-binary `.git/hooks/*.sample` files. - Multilingual batch analysis consumes only the validated provider-eligible snapshot, so language detection and gap-fill do not reread local-only or replaced path content after the core scan. @@ -89,10 +103,14 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab - Interactive non-verbose scans now show progress and discovered files on standard error. Machine-readable JSON and SARIF remain clean on standard output; use `--verbose` to retain the non-streamed diagnostic path. - Scanning GitHub or GitLab `/blob/` links now analyzes raw file bytes rather than the forge viewer page. Findings and recommendations can change because the intended content is finally scanned. - Active hooks with unmodeled payload flows now produce incomplete coverage and cannot remain `SAFE`; identifier-adjacent letter spacing can lose false P3/P4 findings while retaining AE6. -- `opencode_cli` is opt-in and requires an authenticated OpenCode 1.18.30 executable; other versions fail closed because their deny-all policy has not been verified. The OpenCode-native tool is installed by copying `.opencode/` from a checkout and defaults to static analysis; set `noLlm=false` and configure the provider environment to request semantic analysis. +- `opencode_cli` is opt-in and requires an authenticated OpenCode 1.18.31 executable. Users of earlier 2.12.0 candidates pinned to 1.18.30 must update OpenCode; all other versions fail closed. The OpenCode-native tool is installed by copying `.opencode/` from a checkout and defaults to static analysis; set `noLlm=false` and configure the provider environment to request semantic analysis. +- Pi extension users must install SkillSpector in the extension's `.venv` or set `SKILLSPECTOR_BIN` to an existing absolute executable path; ambient `PATH` lookup is no longer used. Move report outputs into the current workspace. These restrictions apply to the Pi extension, not the standalone CLI or OpenCode tool. +- Oversized or over-complex local registry and baseline files must be reduced to the documented bounds. Consumers of ledger reason codes should recognize `reference_missing` separately from `reference_unresolved`; `safe_to_install` may now be true when missing references are the only completeness caveat. +- TP4 checks can add semantic work and findings for accepted Markdown fences; AST7/AST9 and SC8 can add findings for reflective lookups and bytecode in Python environments. Paragraph-boundary fixes can remove false prose matches. +- Transient provider failures can now incur bounded additional requests and backoff within the workflow deadline; live-provider cost and latency depend on the configured service. - Existing CLI-provider deployments that set `SKILLSPECTOR_MODEL_REGISTRY` now use its valid token budgets. Invalid or non-positive values warn and fall back instead of aborting. - Scans that previously treated excluded executable content as clean can now become incomplete with SC9 and `DO_NOT_INSTALL`; consumers should retain completeness and exclusion evidence. -- No new configuration is required. Static analysis can now run longer within the existing workflow deadline. Set `SKILLSPECTOR_MAX_STATIC_ANALYSIS_SECONDS_PER_ARTIFACT=30` to retain the previous per-artifact allowance, and restart the SkillSpector process after changing the setting ([#522](https://github.com/NVIDIA/SkillSpector/pull/522)). +- The static-analysis allowance needs no new configuration. Static analysis can now run longer within the existing workflow deadline. Set `SKILLSPECTOR_MAX_STATIC_ANALYSIS_SECONDS_PER_ARTIFACT=30` to retain the previous per-artifact allowance, and restart the SkillSpector process after changing the setting ([#522](https://github.com/NVIDIA/SkillSpector/pull/522)). - `--fail-on-findings` is opt-in. Combine it with `--fail-on-incomplete` when CI must reject either active findings or incomplete coverage. Code 2 still denotes an input or execution error; a nonzero exit alone does not identify which condition occurred. - Consumers should retain completeness/degradation metadata and inspect findings as well as exit status. Explicitly use `--no-llm` for an intended static-only scan; requesting LLM analysis without an available provider is incomplete. - Third-party dependency versions are unchanged from 2.11.2. @@ -103,19 +121,16 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab ## Validation -The release candidate is synchronized through main commit `548e5e0afd25595ef039c27cdeb283413c282c71` and was validated locally on the refreshed release-catalog working tree with Python 3.12.13: +The release catalog covers 47 merged PRs since v2.11.2 and is synchronized through main commit `a345778d75e833d25ab6a3f4c968985f3bf35c2d`. Local release checks use Python 3.12.13: -- `uv lock --check --offline` passed with the locked dependency set. -- `make test-ci` passed 5,744 tests, with 14 skipped, 39 deselected, 4 expected failures, and 90% coverage. -- The affected CLI, model-registry, input, security-view, hook-completeness, and release-helper suites passed 1,177 tests, with 10 skipped and 1 deselected. +- `uv sync --locked --all-extras --python 3.12` installed the locked dependency set without changing the lockfile. - Ruff lint and format checks passed for all source and test files. - The CLI reported `SkillSpector v2.12.0`; the release helper dry run resolved `v2.12.0` and the matching versioned notes. -- All 10 release helper and workflow tests passed. -- All 44 OpenCode TypeScript tests passed. +- All 65 OpenCode and Pi extension JavaScript/TypeScript tests passed. - Wheel and source distributions built successfully, and Twine validated both artifacts. - `git diff --check` passed. -The current PR head and its exact-head checks are the source of truth for hosted validation. Deployment/provider validation and the separate release gates below remain pending. Earlier candidate results apply only to their recorded commits and are not certification of this candidate. +The release PR records the full Python test results and hosted checks for the current commit. Earlier test counts and hosted runs apply only to their recorded commits. Deployment/provider validation and the separate release gates below remain pending. [Release PR #550](https://github.com/NVIDIA/SkillSpector/pull/550) records the candidate baseline, validation results, known gaps, and remaining release gates. @@ -143,5 +158,9 @@ The current PR head and its exact-head checks are the source of truth for hosted - [Raw forge file URLs #566](https://github.com/NVIDIA/SkillSpector/pull/566) - [Security-view performance #569](https://github.com/NVIDIA/SkillSpector/pull/569), [#570](https://github.com/NVIDIA/SkillSpector/pull/570) - [Fail-closed hook payload coverage #573](https://github.com/NVIDIA/SkillSpector/pull/573) +- [Local input and Pi extension hardening #562](https://github.com/NVIDIA/SkillSpector/pull/562) +- [MCP missing-reference handling #526](https://github.com/NVIDIA/SkillSpector/pull/526) +- [Markdown fence analysis #421](https://github.com/NVIDIA/SkillSpector/pull/421) +- [Transient provider retries #555](https://github.com/NVIDIA/SkillSpector/pull/555) Prepared by Codex for Mohit Gupta. From 41fca42e980d955d355b717a93a30831c26b284c Mon Sep 17 00:00:00 2001 From: Narendran Raghavan Date: Tue, 22 Sep 2026 21:52:54 -0700 Subject: [PATCH 11/12] docs(release): refresh 2.12.0 through 65 merged PRs Signed-off-by: Narendran Raghavan --- CHANGELOG.md | 18 ++++++++++++ docs/release/skillspector-2.12.0.md | 44 +++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52c093568..d927b25db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ ### 2.12.0 (Unreleased) ### Features/Bug Fixes +* fix(analyzer): distinguish narrowly verified passive PNG references from active opaque targets in AE1 (#597) +* fix(yara): require a word boundary for ROP exploit-framework matches (#607) +* fix(analyzers): report registry load failures as incomplete coverage (#591) +* fix(supply-chain): normalize GHSA MODERATE severity to MEDIUM (#588) +* feat(providers): expand OpenAI and Azure model budget metadata (#539) +* fix(ast): detect bounded joined reflective execution names (#544) +* fix(static): analyze activation intent in descriptions when legacy triggers are absent (#541) +* fix(patterns): detect bounded literal XOR-decoded script-fetch commands (#546) +* feat(llm): add opt-in compact prompt line numbering (#542) +* feat(input): support GitHub tree subdirectories and slash-containing refs (#561) +* fix(static): detect literal shell flags with scope and reassignment checks (#560) +* test: make the Basic-auth fixture explicitly synthetic (#600) +* fix(report): preserve occurrence columns in JSON and SARIF (#584) +* feat(supply-chain): detect dependency source redirection with SC10 (#383) +* fix(as3): preserve trusted selected-source identity across input materialization (#580) +* test(references): cover missing, ambiguous, existing, and self-reference acceptance cases (#551) +* feat(report): add sanitized LLM analysis provenance (#556) +* fix(cli): preserve recursive failures and completeness under reporting limits (#576) * fix(llm): retry transient provider failures within the workflow deadline (#555) * feat(providers): verify OpenCode 1.18.31 for the deny-all policy (#575) * fix(sc8): detect shipped bytecode in Python virtual environments (#571) diff --git a/docs/release/skillspector-2.12.0.md b/docs/release/skillspector-2.12.0.md index a8befbacd..7aceed16f 100644 --- a/docs/release/skillspector-2.12.0.md +++ b/docs/release/skillspector-2.12.0.md @@ -6,8 +6,13 @@ Release status: candidate; publication pending. SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurable static-analysis allowance, OpenCode integrations, Gemini 3.5 Flash registry guidance, interactive scan progress, and TP4 analysis of executable Markdown fences. It also strengthens local input and report handling, expands detection of reflective Python access and shipped bytecode, retries transient provider failures, and distinguishes missing references from ambiguous MCP installation blockers. The release includes discovery, completeness, finding-identity, SARIF output, raw forge-file input, performance, and false-positive fixes described below. +The latest additions include sanitized LLM provenance, SC10 dependency-source analysis, GitHub tree-directory inputs, opt-in compact prompt numbering, expanded model-budget metadata, fail-closed recursive reporting, and occurrence-specific JSON/SARIF columns. Further detection and coverage fixes distinguish narrow passive-image cases from active or unknown opaque content without treating uninspected bytes as safe. + ## Highlights +- Record sanitized LLM configuration/execution provenance and preserve occurrence-specific locations in JSON and SARIF. +- Detect dependency-source redirection with SC10 and retain recursive failure, risk, and completeness evidence even when reports are bounded. +- Scan selected GitHub tree subdirectories, optionally compact prompt line labels, and use expanded OpenAI/Azure model-budget metadata. - Extend TP4 semantic checks to executable Markdown fences, detect reflective Python module lookups, and find shipped bytecode inside Python environments. - Retry transient provider failures within the workflow deadline and constrain local registry, baseline, and Pi extension inputs and report writes. - Distinguish missing file references from ambiguous references in the MCP installation decision, while preserving completeness caveats in reports. @@ -30,6 +35,10 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab ## Added +- JSON reports add `metadata.llm_provenance` (schema version 1), distinguishing configured, resolved, and effective providers and requested versus observed forwarded sampling/reasoning controls. It records bounded, sanitized model/package/source identity without endpoint URLs or credentials, and explicitly does not guarantee deterministic provider behavior. `SKILLSPECTOR_BUILD_REVISION` can supply source revision metadata when unavailable from the installed package ([#556](https://github.com/NVIDIA/SkillSpector/pull/556)). +- SC10 detects noncanonical or unresolved dependency sources in npm, Yarn, pip, Poetry, Maven, and Cargo configuration, supported shell scripts, generated configuration heredocs, and actionable shell fences in `SKILL.md`/`README.md`. Deterministic HIGH findings survive optional LLM filtering, subject to explicit runtime/finding budgets; intentional private registries may need reviewed baseline suppression. This is not a registry reputation or network-reachability check ([#383](https://github.com/NVIDIA/SkillSpector/pull/383)). +- HTTPS GitHub `/tree/` URLs can select an existing repository subdirectory. Resolution uses the longest advertised branch/tag name, including refs containing slashes, and rejects decoded traversal or out-of-checkout selections. Arbitrary commit-SHA tree URLs are not supported by this ref-resolution path ([#561](https://github.com/NVIDIA/SkillSpector/pull/561)). +- `SKILLSPECTOR_COMPACT_PROMPTS=1`, `true`, or `yes` enables unpadded LLM prompt line labels such as `L1:` instead of `L01:`. Values are trimmed and case-insensitive; unset and other values retain the existing format ([#542](https://github.com/NVIDIA/SkillSpector/pull/542)). - `SKILLSPECTOR_PROVIDER=opencode_cli` runs semantic analysis through a local OpenCode login. The verified deny-all policy requires exactly OpenCode 1.18.31; authentication, version, policy, empty-output, or event-envelope failures fail closed. `SKILLSPECTOR_MODEL` remains optional ([#536](https://github.com/NVIDIA/SkillSpector/pull/536), [#575](https://github.com/NVIDIA/SkillSpector/pull/575)). - TP4 semantic analysis includes non-empty, closed Markdown/text fences with recognized executable-language labels, using the validated provider-eligible cache and original document line numbers. Size, count, prompt, and runtime limits remain explicit coverage constraints ([#421](https://github.com/NVIDIA/SkillSpector/pull/421)). - The repository-provided OpenCode extension adds a static-by-default `/skillspector` command and `skillspector_scan` tool. Copy `.opencode/` from a checkout to install it; the wheel does not install the extension. It resolves the binary from `SKILLSPECTOR_BIN`, a worktree `.venv`, or `PATH`, requests required host capabilities before launch, rejects symlinked target/output/binary paths, and uses a 120-second timeout with bounded, redacted output. Semantic analysis is opt-in through `noLlm=false` and the provider environment ([#537](https://github.com/NVIDIA/SkillSpector/pull/537)). @@ -39,6 +48,9 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab ## Changed +- Expand GPT-family context/output-budget entries in the OpenAI and Azure registries, including correction of the OpenAI GPT-5.4 context entry. These are metadata changes only: default models and API adapters are unchanged, and Responses-only model entries do not establish compatibility with another API ([#539](https://github.com/NVIDIA/SkillSpector/pull/539)). +- JSON findings retain each occurrence's own zero-based columns; SARIF emits one-based Unicode-codepoint columns for active and suppressed findings. Unknown occurrence columns remain unknown rather than inheriting another occurrence's location ([#584](https://github.com/NVIDIA/SkillSpector/pull/584)). +- GHSA/OSV `MODERATE` severity maps to `MEDIUM`, correcting the previous `LOW` fallback and potentially increasing affected supply-chain risk scores ([#588](https://github.com/NVIDIA/SkillSpector/pull/588)). - Missing local references now use `reference_missing`; ambiguous matches retain `reference_unresolved`. The MCP skill-scan installation decision can allow a scan whose only caveats are missing references, provided all discovered files were inspected and the other risk, execution, and requested-analysis checks pass. Completeness metadata and the report recommendation still retain the caveat ([#526](https://github.com/NVIDIA/SkillSpector/pull/526)). - Remove the OpenSSF Scorecard and HVTrust README badges ([#582](https://github.com/NVIDIA/SkillSpector/pull/582)). - Non-verbose scans attached to an interactive terminal now stream graph execution and render bounded progress, completed analyzer rules, and a control-safe discovered-file tree to standard error. Machine-readable standard output and exit-code behavior remain intact ([#7](https://github.com/NVIDIA/SkillSpector/pull/7)). @@ -50,6 +62,15 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab ## Fixed +- Recursive and transitive scans retain failed-child, risk, completeness, and omission evidence when output or ledger budgets omit detailed bodies. Recursive Markdown stdout includes child report sections without requiring `--output`. Actual execution failures return exit 2; bounded static path postprocessing shares analysis budgets and preserves syntax/coverage limitations ([#576](https://github.com/NVIDIA/SkillSpector/pull/576)). +- Analyzer import/registry-load failures produce SYSTEM/PARTIAL ledger evidence with reason `analyzer_load_error`, so a missing analyzer cannot silently yield complete coverage. This remains a coverage gap rather than an execution crash ([#591](https://github.com/NVIDIA/SkillSpector/pull/591)). +- Suppress AE1 only for narrowly verified passive rendered Markdown-image references to structurally valid minimal non-interlaced PNG data when the only limitations are unsupported binary/opaque format. Incomplete coverage, `CAUTION`, strict incomplete gates, and MCP installation blocking remain. Other uses of resolved targets, malformed or non-PNG content, concealed payloads, and mixed/unknown limitations retain AE1. DEX and Lua bytecode signatures are also recognized as binary/executable content ([#597](https://github.com/NVIDIA/SkillSpector/pull/597)). +- Analyze bounded activation-intent clauses in descriptions when legacy `triggers` are absent or empty, covering broad trigger phrases, command interception, and catch-all activation while excluding ordinary capability prose. Excess signal-bearing clauses are recorded as incomplete coverage; explicit legacy triggers retain their behavior ([#541](https://github.com/NVIDIA/SkillSpector/pull/541)). +- Detect nearby literal `True` variables passed to subprocess `shell=`, with reassignment and Python-scope checks to avoid treating unrelated assignments as data flow ([#560](https://github.com/NVIDIA/SkillSpector/pull/560)). +- Recognize bounded literal XOR-decoded script-fetch commands from supported local Python helper patterns without general execution or deobfuscation, preserving other findings and logical source-line locations ([#546](https://github.com/NVIDIA/SkillSpector/pull/546)). +- Resolve bounded literal list/tuple joins used as reflective `getattr` names: dangerous names produce AST9, while unresolved or constructed benign names retain AST7. Prospective output length is checked before allocation ([#544](https://github.com/NVIDIA/SkillSpector/pull/544)). +- Require a word boundary for the YARA exploit-framework `ROP` token, retaining `ROP(elf)` controls without false HIGH findings for Rust `drop(&mut self)` ([#607](https://github.com/NVIDIA/SkillSpector/pull/607)). +- Redact credential-bearing URL userinfo and sensitive query fields throughout nested finding evidence and dependency-source meta-analysis inputs ([#383](https://github.com/NVIDIA/SkillSpector/pull/383)). - Retry transient connection, timeout, selected HTTP status, and Bedrock service/throttling failures with bounded backoff and bounded `Retry-After` handling. Retry waits respect the workflow deadline; Bedrock SDK retries are disabled to avoid stacking retry budgets, and unrecovered failures retain incomplete analysis with sanitized diagnostics ([#555](https://github.com/NVIDIA/SkillSpector/pull/555)). - Bound local MCP Registry JSON and suppression-baseline YAML/JSON before expansion, reject non-regular input files, and limit bytes, nesting, and records. The Pi extension resolves an explicit installed binary and stages report writes before atomically publishing within the workspace, preserving diagnostic reports where available ([#562](https://github.com/NVIDIA/SkillSpector/pull/562)). - Constrain prose-oriented static patterns to a single paragraph so unrelated text across blank lines does not combine into a finding; executable and structured-code patterns retain multiline matching ([#491](https://github.com/NVIDIA/SkillSpector/pull/491)). @@ -75,16 +96,20 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab - Prefer exact known-package matches when evaluating SC6 package-name similarity ([#530](https://github.com/NVIDIA/SkillSpector/pull/530)). - Avoid treating slash-separated prose as local file references ([#451](https://github.com/NVIDIA/SkillSpector/pull/451)). - Reduce false-positive severity for companion CLI OAuth results and signed self-update documentation classified as benign, and provide contextual explanations for warned pipe-to-shell installers. The contextual classifiers have unresolved PE3 and RA1 fail-open paths (see Known Limitations) ([#547](https://github.com/NVIDIA/SkillSpector/pull/547)). -- Ignore literal AS3 references to the current skill, derived from the scan-root basename or manifest name, without suppressing peer-skill or obfuscated-path access ([#506](https://github.com/NVIDIA/SkillSpector/pull/506)). +- Ignore literal AS3 references to the current skill only with trusted selected-source identity, preserving that identity across local, repository, and archive materialization. Manifest names corroborate that identity but do not independently authorize suppression; ambiguous sources, peer-skill paths, and obfuscated access remain reportable ([#506](https://github.com/NVIDIA/SkillSpector/pull/506), [#580](https://github.com/NVIDIA/SkillSpector/pull/580)). - Skip symlink test cases when the platform refuses symlink creation ([#501](https://github.com/NVIDIA/SkillSpector/pull/501)). ## Testing and Portability +- Add acceptance regressions for self/existing references and distinct missing/ambiguous outcomes; these add test coverage rather than new runtime behavior ([#551](https://github.com/NVIDIA/SkillSpector/pull/551)). +- Make the Basic-auth test fixture explicitly synthetic ([#600](https://github.com/NVIDIA/SkillSpector/pull/600)). - Make secure-open, FIFO, newline-sensitive build-context, nested OMS, and non-ASCII YARA fixtures deterministic across Windows and non-POSIX environments ([#503](https://github.com/NVIDIA/SkillSpector/pull/503), [#502](https://github.com/NVIDIA/SkillSpector/pull/502), [#505](https://github.com/NVIDIA/SkillSpector/pull/505), [#518](https://github.com/NVIDIA/SkillSpector/pull/518), [#504](https://github.com/NVIDIA/SkillSpector/pull/504)). - Add dependency-free Node 22+ tests for the OpenCode tool helpers and an exact-head OpenCode TypeScript CI job ([#537](https://github.com/NVIDIA/SkillSpector/pull/537)). ## Security +- Dependency-source SC10 findings remain authoritative through optional LLM filtering; intentional private endpoints are still policy-visible and require review. Nested report evidence and provenance use credential sanitization. +- Registry-load failures, recursive omissions/failures, and description-analysis budget exhaustion remain visible as incomplete coverage. The narrow passive-PNG AE1 exception does not claim semantic inspection or permit MCP installation of an incomplete scan. - Local registry files are limited to 16 MiB, 64 nesting levels, and 10,000 combined server/package/remote records. Baselines are limited to 2 MiB, 64 nesting levels, and 10,000 rules/fingerprints, with additional bounds on YAML nodes, scalars, and alias expansion. - Pi extension reports must remain within the workspace. Staged replacement avoids writing through existing hard links; symlink and non-file destinations are rejected. This changes the Pi extension's output-path and executable-discovery requirements. - Agent CLI subprocesses also remove Anthropic proxy and SkillSpector API credentials from inherited environment variables ([#562](https://github.com/NVIDIA/SkillSpector/pull/562)). @@ -96,10 +121,14 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab - JSON string ownership preserves source evidence and does not exempt string contents from analysis. - Findings and exit status can change after upgrading: oversized files can add HIGH AE7 findings, letter-spaced instructions can produce P3/P4 or AE6 findings, and previously collapsed distinct matches can increase the retained finding count and risk score. Missing requested analysis remains incomplete even when static analysis finishes. - Context-aware companion CLI classification can lower severity, scores, or recommendations for documentation classified as benign. Coverage is not fail-closed for every token-transfer or self-update phrasing: the known PE3 and RA1 exceptions below can be incorrectly downgraded or missed. Warned pipe-to-shell installer findings remain reportable. -- Literal current-skill references no longer produce AS3 findings. Peer-skill references, transformed or obfuscated paths, explicit enumeration, AS1, and AS2 remain reportable. +- Literal current-skill references backed by trusted selected-source identity no longer produce AS3 findings; manifest text alone cannot exempt a peer-skill reference. Transformed or obfuscated paths, explicit enumeration, AS1, and AS2 remain reportable. ## Breaking Changes and Migration +- Report consumers should tolerate additive `metadata.llm_provenance` fields and ledger reasons such as `analyzer_load_error` and `transitive_child_scan_failed`, preserve aggregate omission/failure evidence, and handle JSON zero-based versus SARIF one-based Unicode-codepoint columns. +- LLM seeds must fit a signed 64-bit integer. Provenance distinguishes requested settings from observed forwarded parameters and is not a reproducibility guarantee; source revision may be unknown unless packaged or supplied with `SKILLSPECTOR_BUILD_REVISION`. +- SC10 can flag intentional private registries as HIGH; review the source and use the existing baseline workflow for accepted cases. New trigger, shell-flag, reflective, XOR, and bytecode detection and corrected GHSA severity can increase findings or scores. False Rust ROP matches and narrowly verified passive-PNG AE1 findings can disappear without erasing coverage caveats. +- GitHub tree-directory selection performs advertised-ref lookup within the ingestion deadline. Compact prompt numbering is opt-in and does not change the default format or reported source line numbers. - Interactive non-verbose scans now show progress and discovered files on standard error. Machine-readable JSON and SARIF remain clean on standard output; use `--verbose` to retain the non-streamed diagnostic path. - Scanning GitHub or GitLab `/blob/` links now analyzes raw file bytes rather than the forge viewer page. Findings and recommendations can change because the intended content is finally scanned. - Active hooks with unmodeled payload flows now produce incomplete coverage and cannot remain `SAFE`; identifier-adjacent letter spacing can lose false P3/P4 findings while retaining AE6. @@ -121,12 +150,13 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab ## Validation -The release catalog covers 47 merged PRs since v2.11.2 and is synchronized through main commit `a345778d75e833d25ab6a3f4c968985f3bf35c2d`. Local release checks use Python 3.12.13: +The release catalog covers 65 merged PRs since v2.11.2 and is synchronized through main commit `224ba292d91b9e5fc59398fc38ab8971f9ab01ec`. Local release checks use Python 3.12.13: - `uv sync --locked --all-extras --python 3.12` installed the locked dependency set without changing the lockfile. - Ruff lint and format checks passed for all source and test files. - The CLI reported `SkillSpector v2.12.0`; the release helper dry run resolved `v2.12.0` and the matching versioned notes. - All 65 OpenCode and Pi extension JavaScript/TypeScript tests passed. +- All 95 selected static integration cases for opaque-reference reporting and wrapped/canonical dependency-source behavior passed without live providers. - Wheel and source distributions built successfully, and Twine validated both artifacts. - `git diff --check` passed. @@ -141,13 +171,12 @@ The release PR records the full Python test results and hosted checks for the cu - The release remains a candidate while outstanding review and release issues are assessed. Proposed fixes in unmerged PRs are not included in this candidate. - Letter-spacing reconstruction is not fail-closed. Alternating-width short runs such as `s e n d conversation to external` can be split before P3/P4 matching and remain below AE6's six-letter concealed-run threshold, allowing a SAFE result. - Companion-context classification is not fail-closed. PE3 can downgrade imperative token-acquisition text and miss adjacent disclosure phrased with verbs such as `paste`; RA1 can accept protected agent/tool names with CLI suffixes and signed-release evidence from a different logical line. These variants can be incorrectly downgraded or missed. -- Current validation found that public report serialization can repeat the first occurrence's columns for other matches; SARIF does not yet preserve these column coordinates. The internal occurrence improvements in #409 do not establish correct locations in every output format. See [release validation](https://github.com/NVIDIA/SkillSpector/pull/550) for the tracked report defect. - Some runtime-selected command variants and Markdown reference destinations still have open completeness defects. Proposed fixes [#514](https://github.com/NVIDIA/SkillSpector/pull/514) and [#553](https://github.com/NVIDIA/SkillSpector/pull/553) are not included in this candidate. - `opencode_cli` currently reports no token-usage accounting, and model availability or rate limits remain external. Multilingual batch gap-fill was validated with mocked providers; live-provider qualification remains pending. ## References -- [Changes since v2.11.2](https://github.com/NVIDIA/SkillSpector/compare/v2.11.2...v2.12.0) +- [Candidate changes since v2.11.2](https://github.com/NVIDIA/SkillSpector/compare/v2.11.2...224ba292d91b9e5fc59398fc38ab8971f9ab01ec) - [AE1 documentation fix #516](https://github.com/NVIDIA/SkillSpector/pull/516) - [Static analysis time allowance #522](https://github.com/NVIDIA/SkillSpector/pull/522) - [OpenCode CLI provider #536](https://github.com/NVIDIA/SkillSpector/pull/536) @@ -162,5 +191,10 @@ The release PR records the full Python test results and hosted checks for the cu - [MCP missing-reference handling #526](https://github.com/NVIDIA/SkillSpector/pull/526) - [Markdown fence analysis #421](https://github.com/NVIDIA/SkillSpector/pull/421) - [Transient provider retries #555](https://github.com/NVIDIA/SkillSpector/pull/555) +- [Recursive failure reporting #576](https://github.com/NVIDIA/SkillSpector/pull/576) +- [LLM provenance #556](https://github.com/NVIDIA/SkillSpector/pull/556) +- [Dependency-source analysis #383](https://github.com/NVIDIA/SkillSpector/pull/383) +- [Occurrence columns #584](https://github.com/NVIDIA/SkillSpector/pull/584) +- [Passive-image coverage distinction #597](https://github.com/NVIDIA/SkillSpector/pull/597) Prepared by Codex for Mohit Gupta. From 29f7acb52866a634c5ad84b1c37d5023e64b47c9 Mon Sep 17 00:00:00 2001 From: Narendran Raghavan Date: Wed, 23 Sep 2026 14:00:14 -0700 Subject: [PATCH 12/12] docs(release): include completeness fixes in 2.12.0 Signed-off-by: Narendran Raghavan --- CHANGELOG.md | 4 ++++ docs/release/skillspector-2.12.0.md | 32 +++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d927b25db..b924b4113 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ### 2.12.0 (Unreleased) ### Features/Bug Fixes +* fix(security): retain incomplete coverage for runtime-selected commands and remeasure active Git clones strictly (#514) +* fix(scan): preserve required-input failures and multiline prompt uncertainty (#563) +* fix(analyzer): preserve Perl print literal ownership and explain referenced-artifact limitations (#615) +* fix(references): preserve complete bounded Markdown destinations and URI semantics (#553) * fix(analyzer): distinguish narrowly verified passive PNG references from active opaque targets in AE1 (#597) * fix(yara): require a word boundary for ROP exploit-framework matches (#607) * fix(analyzers): report registry load failures as incomplete coverage (#591) diff --git a/docs/release/skillspector-2.12.0.md b/docs/release/skillspector-2.12.0.md index 7aceed16f..b22d27c8d 100644 --- a/docs/release/skillspector-2.12.0.md +++ b/docs/release/skillspector-2.12.0.md @@ -8,8 +8,12 @@ SkillSpector 2.12.0 adds an opt-in CLI gate for any active finding, a configurab The latest additions include sanitized LLM provenance, SC10 dependency-source analysis, GitHub tree-directory inputs, opt-in compact prompt numbering, expanded model-budget metadata, fail-closed recursive reporting, and occurrence-specific JSON/SARIF columns. Further detection and coverage fixes distinguish narrow passive-image cases from active or unknown opaque content without treating uninspected bytes as safe. +The candidate also includes the previously pending Markdown-reference and runtime-command completeness fixes, required-input and multiline-prompt accounting, and conservative Perl literal handling with clearer referenced-artifact diagnostics. + ## Highlights +- Preserve fatal outcomes for recognized unsupported required input and incomplete coverage for bounded runtime-command and multiline-prompt reconstruction. +- Resolve complete Markdown reference destinations without losing URI or source ownership, and distinguish proven Perl print literals from ambiguous source. - Record sanitized LLM configuration/execution provenance and preserve occurrence-specific locations in JSON and SARIF. - Detect dependency-source redirection with SC10 and retain recursive failure, risk, and completeness evidence even when reports are bounded. - Scan selected GitHub tree subdirectories, optionally compact prompt line labels, and use expanded OpenAI/Azure model-budget metadata. @@ -62,6 +66,14 @@ The latest additions include sanitized LLM provenance, SC10 dependency-source an ## Fixed +- Preserve incomplete coverage for runtime-selected `printf` and executable wrappers, bounded `eval`/shell `-c` strings, shell commands embedded in PowerShell, unsupported brace expansion, and commands crossing analysis windows. Parser and deadline uncertainty remains visible through `static_parse_limit` and CLI/MCP completeness gates even when semantic analysis succeeds. Literal/documentation controls remain distinct; this is bounded analysis, not general shell emulation ([#514](https://github.com/NVIDIA/SkillSpector/pull/514)). +- Tolerate transiently missing `.git` metadata only while a clone is active, then strictly remeasure the completed checkout. Permission errors, checkout failures, and final ingestion limits still fail closed ([#514](https://github.com/NVIDIA/SkillSpector/pull/514)). +- Record fatal `unsupported_primary_content` for recognized unsupported selected inputs and in-profile `SKILL.md`/`skill.md` instructions, including nested or renamed ZIP members. Preserve required-file identity, reject lossy required UTF-8 decoding, retain canonical bytes, and omit rejected primary text from provider input. Supported ZIP inspection and incidental-asset policy remain bounded and unchanged; a valid UTF-8 code point cut by a recorded byte limit remains partial rather than an unsupported-encoding failure ([#563](https://github.com/NVIDIA/SkillSpector/pull/563)). +- Retain failed artifact outcomes and excluded-executable evidence even when detailed ledger output is truncated or manifest parsing also fails. Fatal required-content failures remain execution failures rather than being downgraded to partial coverage ([#563](https://github.com/NVIDIA/SkillSpector/pull/563)). +- Account for covered pure or mixed singleton newline/horizontal spacing with source-preserving AE6 and `obfuscated_instruction_text` partial evidence. The projection preserves structural boundaries and uses interruptible, workflow-bounded matching; it does not manufacture a confirmed P3/P4 finding or claim universal deobfuscation ([#563](https://github.com/NVIDIA/SkillSpector/pull/563)). +- Parse bounded inline and reference-definition Markdown destinations with angle-wrapped spaces, balanced/escaped parentheses, and quoted titles. Split URI components before one-time decoding, preserve decoded containment and reference ownership, retain genuine missing targets, and report destination/title limit exhaustion as incomplete analysis. Title text is not reinterpreted as an extra reference ([#553](https://github.com/NVIDIA/SkillSpector/pull/553)). +- Classify `.pl` as Perl while retaining its existing security checks, and avoid false shell-parse-limit AE1 for narrowly proven standalone non-interpolated print literals. Printed content still receives security analysis; interpolation, quote-like syntax, heredocs, ambiguous fragments, and genuine limits remain conservative ([#615](https://github.com/NVIDIA/SkillSpector/pull/615)). +- Explain AE1 referenced-artifact failures with bounded, sanitized target disposition and canonical reason evidence, including truncation metadata and reason-specific remediation. Guidance preserves required references rather than suggesting their removal ([#615](https://github.com/NVIDIA/SkillSpector/pull/615)). - Recursive and transitive scans retain failed-child, risk, completeness, and omission evidence when output or ledger budgets omit detailed bodies. Recursive Markdown stdout includes child report sections without requiring `--output`. Actual execution failures return exit 2; bounded static path postprocessing shares analysis budgets and preserves syntax/coverage limitations ([#576](https://github.com/NVIDIA/SkillSpector/pull/576)). - Analyzer import/registry-load failures produce SYSTEM/PARTIAL ledger evidence with reason `analyzer_load_error`, so a missing analyzer cannot silently yield complete coverage. This remains a coverage gap rather than an execution crash ([#591](https://github.com/NVIDIA/SkillSpector/pull/591)). - Suppress AE1 only for narrowly verified passive rendered Markdown-image references to structurally valid minimal non-interlaced PNG data when the only limitations are unsupported binary/opaque format. Incomplete coverage, `CAUTION`, strict incomplete gates, and MCP installation blocking remain. Other uses of resolved targets, malformed or non-PNG content, concealed payloads, and mixed/unknown limitations retain AE1. DEX and Lua bytecode signatures are also recognized as binary/executable content ([#597](https://github.com/NVIDIA/SkillSpector/pull/597)). @@ -88,7 +100,7 @@ The latest additions include sanitized LLM provenance, SC10 dependency-source an - Bound JSON quote traversal without repeatedly scanning overlapping suffixes ([#521](https://github.com/NVIDIA/SkillSpector/pull/521)). - Emit a HIGH AE7 analysis-evasion finding for per-file size limits that leave an artifact partially inspected, unless AE1 already covers that path. Supply a bounded text prefix and an explicit unreviewed-region marker to enabled LLM analysis; the unread region remains incomplete ([#509](https://github.com/NVIDIA/SkillSpector/pull/509)). - Preserve full-evidence fingerprints, concrete YARA rule identity, and precise occurrence locations through projection, deduplication, and report compaction. Separate findings are retained while duplicate projections of the same occurrence are collapsed ([#409](https://github.com/NVIDIA/SkillSpector/pull/409)). -- Add bounded reconstruction for letter-spaced P3/P4 prompt instructions, retain source evidence, and use AE6 as an incomplete-coverage fallback for some ambiguous reconstructions. Some alternating-width short runs can evade both P3/P4 and AE6 (see Known Limitations) ([#470](https://github.com/NVIDIA/SkillSpector/pull/470)). +- Add bounded reconstruction for letter-spaced P3/P4 prompt instructions, retain source evidence, and use AE6 as an incomplete-coverage fallback for covered ambiguous reconstructions; the later multiline work extends this accounting without making it a universal decoder ([#470](https://github.com/NVIDIA/SkillSpector/pull/470), [#563](https://github.com/NVIDIA/SkillSpector/pull/563)). - Discover skills inside dot-prefixed directories, retain inherited local-only restrictions for child skills, and partition transitive scan caching by those privacy restrictions ([#410](https://github.com/NVIDIA/SkillSpector/pull/410)). - Preserve incomplete discovery and requested semantic-analysis failures, including unavailable providers and mixed success/failure telemetry, instead of allowing a complete scan result ([#410](https://github.com/NVIDIA/SkillSpector/pull/410)). - Emit recursive JSON reports to standard output when no output path is provided ([#467](https://github.com/NVIDIA/SkillSpector/pull/467)). @@ -108,6 +120,7 @@ The latest additions include sanitized LLM provenance, SC10 dependency-source an ## Security +- Recognized unsupported required bytes produce failed execution and CLI exit 2, while covered unresolved reconstruction produces partial coverage, an incomplete-report caveat, and MCP installation blocking. Successful semantic analysis or truncated ledger details do not erase those outcomes. - Dependency-source SC10 findings remain authoritative through optional LLM filtering; intentional private endpoints are still policy-visible and require review. Nested report evidence and provenance use credential sanitization. - Registry-load failures, recursive omissions/failures, and description-analysis budget exhaustion remain visible as incomplete coverage. The narrow passive-PNG AE1 exception does not claim semantic inspection or permit MCP installation of an incomplete scan. - Local registry files are limited to 16 MiB, 64 nesting levels, and 10,000 combined server/package/remote records. Baselines are limited to 2 MiB, 64 nesting levels, and 10,000 rules/fingerprints, with additional bounds on YAML nodes, scalars, and alias expansion. @@ -117,7 +130,7 @@ The latest additions include sanitized LLM provenance, SC10 dependency-source an - Excluded executable or loadable content is inventoried before exclusion. Referenced or out-of-coverage bytes now produce SC9 and incomplete-analysis evidence that blocks strict installation gates; the narrow exception is limited to direct, non-binary `.git/hooks/*.sample` files. - Multilingual batch analysis consumes only the validated provider-eligible snapshot, so language detection and gap-fill do not reread local-only or replaced path content after the core scan. - OpenCode integration is static by default. The native tool redacts common secret forms and bounds output, while the semantic provider uses argv/stdin and treats missing authentication, empty output, or unsupported event streams as failures. -- Genuine removal instructions remain reportable. The covered unresolved-runtime-command controls retain incomplete coverage and fail strict CLI/MCP installation gates, including when semantic analysis succeeds. Additional runtime-selected command variants remain under investigation (see Known Limitations). +- Genuine removal instructions remain reportable. The runtime-command fixes in #514 retain incomplete coverage for covered unresolved forms and fail strict CLI/MCP installation gates, including when semantic analysis succeeds. Reconstruction remains bounded rather than a complete shell interpreter. - JSON string ownership preserves source evidence and does not exempt string contents from analysis. - Findings and exit status can change after upgrading: oversized files can add HIGH AE7 findings, letter-spaced instructions can produce P3/P4 or AE6 findings, and previously collapsed distinct matches can increase the retained finding count and risk score. Missing requested analysis remains incomplete even when static analysis finishes. - Context-aware companion CLI classification can lower severity, scores, or recommendations for documentation classified as benign. Coverage is not fail-closed for every token-transfer or self-update phrasing: the known PE3 and RA1 exceptions below can be incorrectly downgraded or missed. Warned pipe-to-shell installer findings remain reportable. @@ -125,6 +138,9 @@ The latest additions include sanitized LLM provenance, SC10 dependency-source an ## Breaking Changes and Migration +- Previously accepted unsupported primary files or invalid required instruction encodings can now fail with `unsupported_primary_content` and CLI exit 2 regardless of strict flags. Use supported UTF-8 instructions or supported ZIP inputs; required identity also applies inside bounded nested archives. +- Runtime-selected commands, multiline prompt ambiguity, and over-limit Markdown references can now change a complete/`SAFE` result to partial/`CAUTION`, `--fail-on-incomplete` exit 1, and MCP `safe_to_install=false`. Default CLI exit 0 is not proof of completeness; AE6 marks unresolved interpretation rather than confirmed semantic wrongdoing. +- AE1 consumers should tolerate the additive `Incomplete referenced artifact analysis` pattern and bounded evidence fields such as `target_path`, `target_disposition`, `reasons`, and `reasons_truncated`. Proven literal Perl help text can lose false AE1 findings without exempting its payload or ambiguous source from analysis. - Report consumers should tolerate additive `metadata.llm_provenance` fields and ledger reasons such as `analyzer_load_error` and `transitive_child_scan_failed`, preserve aggregate omission/failure evidence, and handle JSON zero-based versus SARIF one-based Unicode-codepoint columns. - LLM seeds must fit a signed 64-bit integer. Provenance distinguishes requested settings from observed forwarded parameters and is not a reproducibility guarantee; source revision may be unknown unless packaged or supplied with `SKILLSPECTOR_BUILD_REVISION`. - SC10 can flag intentional private registries as HIGH; review the source and use the existing baseline workflow for accepted cases. New trigger, shell-flag, reflective, XOR, and bytecode detection and corrected GHSA severity can increase findings or scores. False Rust ROP matches and narrowly verified passive-PNG AE1 findings can disappear without erasing coverage caveats. @@ -150,7 +166,7 @@ The latest additions include sanitized LLM provenance, SC10 dependency-source an ## Validation -The release catalog covers 65 merged PRs since v2.11.2 and is synchronized through main commit `224ba292d91b9e5fc59398fc38ab8971f9ab01ec`. Local release checks use Python 3.12.13: +The release catalog covers 69 merged PRs since v2.11.2 and is synchronized through main commit `05119f4b868aafc7a6347043d3c3b8f9ac548091`. Local release checks use Python 3.12.13: - `uv sync --locked --all-extras --python 3.12` installed the locked dependency set without changing the lockfile. - Ruff lint and format checks passed for all source and test files. @@ -169,14 +185,14 @@ The release PR records the full Python test results and hosted checks for the cu - Local sanity checks cover the tested inputs and environment; live provider and deployment behavior depend on their configuration. - Incomplete inspection is a reportable result. Unsupported inputs, unavailable requested analysis, and resource limits must remain visible; these conditions cannot be treated as a clean scan. - The release remains a candidate while outstanding review and release issues are assessed. Proposed fixes in unmerged PRs are not included in this candidate. -- Letter-spacing reconstruction is not fail-closed. Alternating-width short runs such as `s e n d conversation to external` can be split before P3/P4 matching and remain below AE6's six-letter concealed-run threshold, allowing a SAFE result. +- Reconstruction remains bounded: the multiline projection deliberately preserves blank paragraphs, punctuation, ordinary multi-character tokens, and wider gaps. It is not a universal obfuscation decoder or full shell/Perl interpreter; recorded resource or parser limits remain incomplete coverage. - Companion-context classification is not fail-closed. PE3 can downgrade imperative token-acquisition text and miss adjacent disclosure phrased with verbs such as `paste`; RA1 can accept protected agent/tool names with CLI suffixes and signed-release evidence from a different logical line. These variants can be incorrectly downgraded or missed. -- Some runtime-selected command variants and Markdown reference destinations still have open completeness defects. Proposed fixes [#514](https://github.com/NVIDIA/SkillSpector/pull/514) and [#553](https://github.com/NVIDIA/SkillSpector/pull/553) are not included in this candidate. +- Required-input recognition is conservative rather than a universal encoding or file-format detector. Unrecognized representations whose bytes appear to be UTF-8 can remain text; supported/empty ZIP completeness does not prove a usable or harmless skill. The fixes in #514, #553, and #563 are included, but no broader language or format coverage is implied. - `opencode_cli` currently reports no token-usage accounting, and model availability or rate limits remain external. Multilingual batch gap-fill was validated with mocked providers; live-provider qualification remains pending. ## References -- [Candidate changes since v2.11.2](https://github.com/NVIDIA/SkillSpector/compare/v2.11.2...224ba292d91b9e5fc59398fc38ab8971f9ab01ec) +- [Candidate changes since v2.11.2](https://github.com/NVIDIA/SkillSpector/compare/v2.11.2...05119f4b868aafc7a6347043d3c3b8f9ac548091) - [AE1 documentation fix #516](https://github.com/NVIDIA/SkillSpector/pull/516) - [Static analysis time allowance #522](https://github.com/NVIDIA/SkillSpector/pull/522) - [OpenCode CLI provider #536](https://github.com/NVIDIA/SkillSpector/pull/536) @@ -196,5 +212,9 @@ The release PR records the full Python test results and hosted checks for the cu - [Dependency-source analysis #383](https://github.com/NVIDIA/SkillSpector/pull/383) - [Occurrence columns #584](https://github.com/NVIDIA/SkillSpector/pull/584) - [Passive-image coverage distinction #597](https://github.com/NVIDIA/SkillSpector/pull/597) +- [Runtime-command completeness #514](https://github.com/NVIDIA/SkillSpector/pull/514) +- [Markdown destinations #553](https://github.com/NVIDIA/SkillSpector/pull/553) +- [Required-input and multiline completeness #563](https://github.com/NVIDIA/SkillSpector/pull/563) +- [Perl ownership and referenced-artifact diagnostics #615](https://github.com/NVIDIA/SkillSpector/pull/615) Prepared by Codex for Mohit Gupta.