Honor SkillSpector analysis completeness - #112
Conversation
|
End-to-end follow-up:
The full source suite for this PR also passed: 5160 passed, 17 skipped, 4 deselected. Lint and build passed. |
rng1995
left a comment
There was a problem hiding this comment.
The new contract checks still accept contradictory incomplete evidence.
| "security scan did not complete" | ||
| ) | ||
| return False | ||
| if ( |
There was a problem hiding this comment.
These three flags do not cover the full completeness contract. A report with is_complete=true, status=complete, and both execution flags true is accepted as SAFE even when coverage_percent=0, entirely_uninspected_files=1, or ledger_exceptions contains a fatal entry. Validate those authoritative fields and reject contradictions so an incomplete SkillSpector report cannot fail open; add regressions for the contradictory cases.
There was a problem hiding this comment.
Addressed in 6fd3a5d and updated onto current main in merge commit 4ffb55c. A claimed-complete report now requires present authoritative details with numeric 100% coverage, zero integer partial/uninspected counts, and empty ledger-exception/limitation lists. Missing or contradictory details fail closed; reports that omit analysis_completeness entirely retain the legacy path.
Verification after merging current main: 1,053 validator tests passed; the full suite passed with 5,482 passed, 17 skipped, and 4 deselected; Ruff passed; source and wheel builds passed; git diff --check passed. The merge also incorporates main's Gitleaks workflow repair.
Fresh CI, DCO, and Security runs were created, but GitHub marked them action_required before running. The contributor account cannot approve fork workflows, so they are waiting for maintainer approval.
There was a problem hiding this comment.
[P1] Completeness accounting still has an unchecked contradiction
The follow-up addresses coverage, partial/uninspected counts, exceptions, and limitations, but leaves required counters unchecked. A report with total_components=2, scanned_components=1, fully_inspected_files=1, coverage_percent=100, and otherwise-complete flags is accepted. Please require nonnegative integer total/scanned/fully fields; for a complete report require scanned_components == total_components, validate fully_inspected_files against the producer's documented file-count invariant, and add missing/mismatched regressions.
|
@Tomauskasz Gentle ping when you have a chance: the remaining completeness-contract review thread is still waiting for an update or response. Thank you for your patience throughout the review and for your contribution. |
|
Independent reproduction — this matches the root cause described here exactly, and I bisected the SkillSpector side. Minimal reproducer. A skill with no findings at all is enough; the only trigger is a ---
name: repro
description: Minimal reproducer for the SkillSpector completeness contract mismatch. Use when reproducing the reported validation failure.
---
# Repro
## Overview
Prose only. No executable content.
### Input/Output Separation
Keep inputs and outputs distinct.Behaviour across SkillSpector versions (same skill, same SkillEvaluator commit,
Failure message on 2.10.0+: Three things worth noting:
Environment: SkillEvaluator Until this lands, we are pinning SkillSpector to |
|
Follow-up from the complete three-lane review is in bdd69c1. The ten contradictory/missing completeness-detail cases now share one parameter matrix and one scanner/assertion body. Runtime behavior and case coverage are unchanged; the test removes 23 net lines of duplicated mechanics. Verification:
|
|
Final test-only polish is in 1f25501. The partial-report regression now overrides only fields that differ from the shared fixture. Current and legacy clean-report coverage now shares one parameterized test path. Production behavior and contract coverage are unchanged; the test file is 20 lines smaller. Final verification: 5,482 passed, 17 skipped, 4 deselected; Ruff passed; source and wheel builds passed; Fresh CI, DCO, and Security runs for this head are |
1f25501 to
18b8fc9
Compare
|
The DCO-only failure is corrected in the rebased head The branch was rebased onto current The only rebase conflict was additive in Post-rebase verification: 5,488 passed, 17 skipped, 4 deselected; Ruff passed; source and wheel builds passed; Fresh DCO, CI, and Security runs were created but are currently |
| result.add_error("skillspector reported execution_successful=false; security scan did not complete") | ||
| return False | ||
|
|
||
| analysis_completeness = data.get("analysis_completeness") |
There was a problem hiding this comment.
[P1] Version-gate the completeness schema
This uses analysis_completeness field presence as the schema boundary, but real SkillSpector 2.9.6 --no-llm reports include that object without the 2.10 status field, so valid legacy scans fail here. Conversely, a report still labeled 2.10.0 can omit both new fields and take the legacy path; I reproduced that report being accepted. Please select the contract from a validated metadata.skillspector_version (with an explicit compatibility policy), require the 2.10+ fields, and add a captured real 2.9.6 fixture.
| "skillspector JSON field 'analysis_completeness' reports incomplete analysis " | ||
| f"(status '{completeness_status}'); security scan did not complete" | ||
| ) | ||
| return False |
There was a problem hiding this comment.
[P1] Preserve findings from partial scans
This returns to the caller before _process_skillspector_cli_result runs, so structurally valid issues from a partial report are discarded. I reproduced this with released SkillSpector 2.10.0 and 2.11.0: both partial JSON reports retained HIGH findings, while SkillEvaluator showed only the incompleteness error. Please separate structural validity from completeness, process trustworthy issues, then mark the scan incomplete; add a regression containing a valid HIGH issue.
Signed-off-by: Tomas <tomas.bitvinskas@copla.com> Signed-off-by: Tomas <180413002+Tomauskasz@users.noreply.github.com>
Context: SkillSpector complete-summary flags could contradict authoritative coverage, inspection-count, exception, or limitation details while SkillEvaluator still accepted the scan. Changes: - Require present completeness objects to report numeric 100% coverage, zero integer partial and uninspected counts, and empty exception and limitation lists. - Reject missing authoritative detail fields when the completeness object exists. - Add regressions for contradictory and missing details plus the legacy report path without completeness metadata. Impact: Contradictory or malformed claimed-complete reports fail closed. Older reports that omit the completeness object retain their existing validation path. Validation: - Contradictory-detail regression: 5 passed. - Missing-detail regression: 5 passed. - Focused current, contradictory, missing, and legacy cases: 12 passed. - Validator test suite: 847 passed. - Ruff and `git diff --check`: passed. Notes: The full repository suite was not run locally. Signed-off-by: Tomas <180413002+Tomauskasz@users.noreply.github.com>
Context: Contradictory and missing SkillSpector completeness details used separate parameterized tests with identical scanner setup, execution, and assertions. Use one ten-case matrix for the shared fail-closed contract. Changes: - Pair each invalid detail mutation with an optional missing-field selector. - Preserve all five contradictory-value cases and all five missing-field cases. - Keep one public validation call and one assertion body for every case. Impact: The validator behavior and coverage remain unchanged while the test removes 23 net lines of duplicated mechanics. Validation: - Focused completeness and legacy contract set: 12 passed. - `uv run pytest -q`: 5482 passed, 17 skipped, 4 deselected. - `uv run ruff check src tests`: passed. - `uv build`: source archive and wheel built successfully. - `git diff --check`: passed. Notes: The repository-wide formatter check remains red on pre-existing files and is not part of the configured Makefile lint target. Signed-off-by: Tomas <180413002+Tomauskasz@users.noreply.github.com>
Context: The current and legacy SkillSpector report-contract tests repeated complete fixture values and duplicated the validator execution and assertions. Changes: - Update only the completeness fields that differ in the partial-report case. - Parameterize the shared clean-report acceptance path for current and legacy metadata. Impact: Preserve the current, legacy, and incomplete report assertions while removing 20 lines of repeated fixture and mock setup. Validation: - Full suite: 5482 passed, 17 skipped, 4 deselected. - Lint: All checks passed. - Build: source distribution and wheel built successfully. - Focused report-contract cases: passed. - git diff --check: passed. Notes: None. Signed-off-by: Tomas <180413002+Tomauskasz@users.noreply.github.com>
Context: SkillSpector reports now require coherent version-specific completeness evidence before SecurityValidator converts their findings or returns a successful result. Changes: - Select a strict status-less compatibility contract for SkillSpector 2.9.6 and the status-bearing contract for versions 2.10 and newer. - Validate execution markers, component and coverage equations, required analyzer rosters, universal analyzer work accounting, limitation reconciliation, and risk recommendations. - Require coherent pre/post-filter finding counts and reconcile them with serialized active and suppressed findings without rejecting report-deduplicated or occurrence-expanded 2.10 output. - Require non-empty 2.10 finding IDs and derive a conservative risk-score floor across SkillSpector's pre-compaction scoring and post-compaction report representations. - Require versioned findings to identify a non-empty path and require a complete, unique component inventory with boolean executable evidence, reconciled counts, and exact source-scoped issue coverage. - Preserve source scopes, match fingerprints, distinct modern finding IDs, and legacy findings whose display text is null. - Reject occurrence-expanded rows that disagree on the severity, confidence, or finding ID copied from one compacted identity. - Allocate compacted and hidden raw findings once across the most score-reducing rule slots while preserving independently reconstructable visible contributions and explicit rule floors. - Preserve executable-component evidence and a conservative reported-score floor when generated findings are filtered. - Keep SkillSpector's shipped-bytecode finding, blocking score floor, and shipped bytecode bytes authoritative while staging a generated-output-free scan tree. - Preserve findings from coherent partial reports while retaining an incomplete result and suppressing clean summaries. - Add a captured 2.9.6 report fixture, regression coverage for complete, partial, failed, and malformed reports, and changelog documentation. Impact: Failed, contradictory, duplicate, or materially understated SkillSpector output is rejected before findings are processed. Valid partial, compacted, source-scoped, null-fingerprint, legacy null-text, and shipped-bytecode findings remain available without representing an incomplete scan as complete or overstating evidence lost during compaction. Validation: - uv run make test: 5955 passed, 17 skipped, 4 deselected. - uv run make lint: all checks passed. - uv run make build: source distribution and wheel built successfully. - Focused validator suite: 353 passed. - The null-fingerprint public-seam regression failed before the fix and passed after distinct finding IDs became authoritative. - The fractional score-floor and staged-SC8 regressions failed before their fixes and passed afterward. - Eight component-inventory, executable-occurrence, and hidden-multiplicity regressions failed against the prior immutable head and passed after the fixes. - Self-review added passing regressions for duplicate component identities and producer source-scope priority. - Six empty-path, zero/under-counted analyzer-work, and compacted-confidence counterexamples failed against the reviewed head and passed after the fixes; 2.9.6 and future-analyzer compatibility cases also pass. - Two hidden and occurrence-expanded score-floor counterexamples failed against the reviewed head and passed with global unknown-finding allocation; an impossible raw-finding/compact-identity count also fails closed. - A forged compacted-identity report claiming 15/LOW/SAFE for raw findings that score 69/HIGH/DO_NOT_INSTALL failed before the fix and now fails closed; a conflicting-finding-ID variant is also covered. - Live SkillSpector 2.10.0 clean and 14-advisory reference-skill probes passed against clean-checkout content. - SkillSpector 2.10.0 report-deduplication, source-scoped score, null-fingerprint, and SC8 floor probes matched the validator contract. - The SC8 score-floor regression failed under the no-floor mutation and passed after restoration. - git diff --check and JSON fixture parsing passed. Notes: Compatibility covers the captured SkillSpector 2.9.6 contract and the completeness and report-compaction behavior used by SkillSpector 2.10 and newer. Signed-off-by: Tomas <180413002+Tomauskasz@users.noreply.github.com>
18b8fc9 to
debc843
Compare
|
The three September 3 P1 review findings and the subsequent contract findings are addressed in rebased head
The follow-up also requires the captured 2.9.6 analyzer roster, the stable 2.10+ roster, and all semantic analyzers when LLM availability is confirmed. It validates analyzer work partitions and state agreement, and checks both execution markers, stage-specific LLM metadata, limitations, recommendation semantics, and non-empty 2.10 finding IDs. Self-review caught and fixed the partial LOW/CAUTION path, huge-integer coverage ordering, incomplete analyzer-roster acceptance, duplicate transitive analyzer IDs, released transitive-truncation output, unvalidated finding totals and identities, a real 2.10 pre-compaction score compatibility failure, source-provenance loss in score reconstruction, modern null-fingerprint findings collapsed by display prose, legacy null-text findings collapsed into one row, executable component evidence lost during post-filter scoring, lossy replacement of the producer score, fractional score truncation at the policy threshold, shipped bytecode removed before the artifact-integrity analyzer ran, inconsistent source-scope priority, and duplicate component identities. Exact SkillSpector 2.10.0 probes confirm that report-time deduplication can reduce two post-filter findings to one serialized issue, a non-executable source remains at score 40 even when another source uses the same executable path, three source scopes score 70 rather than collapsing to 40, and distinct null-fingerprint finding IDs remain score-distinct. Independent review of the prior immutable head reproduced three additional counterexamples. Missing components allowed executable-risk understatement; compacted mixed executable/non-executable occurrences could select the wrong multiplier; and hidden raw duplicates made a serialized-only producer-score bound unsafe. The final contract rejects missing evidence and preserves only independently provable score evidence across compaction. Final immutable-head review found three more P1s. Empty or absent issue paths bypassed executable-score matching; a complete report could claim zero universal analyzer work; and representative confidence copied during compaction could reject a genuine producer score. All six exact public-seam cases failed against the reviewed head and pass after the fixes. Captured 2.9.6, future-analyzer, and partial-report compatibility cases also pass. A subsequent immutable-head review found one more P1 in that correction: one hidden raw finding or one occurrence-expanded identity erased independently provable risk from every visible rule. The final implementation deduplicates modern report identities, computes the finite global count of unknown raw findings, and allocates those findings once to the largest possible diminishing-weight reductions. The six-rule counterexamples now retain conservative score floors of 55 with one hidden raw finding and 30 with six expanded duplicates. Reports that claim fewer raw findings than their distinct compact identities also fail closed. The last immutable-head review found that contradictory representative fields under one compact identity could forge a passing score. A six-rule report claiming Post-rebase verification: 5,955 passed, 17 skipped, 4 deselected; Ruff passed; source and wheel builds passed; the focused validator suite passed 353 tests; live SkillSpector 2.10.0 clean and 14-advisory reference-skill probes passed against clean-checkout content; report-deduplication, source-scoped score, null-fingerprint, and Final exact-head producer-contract and repository-standards reviews found no P0-P2 issues. |
Summary
metadata.skillspector_version.match_fingerprintis null and legacy findings when display text is null.Root cause
SkillEvaluator previously treated completeness-field presence as the schema boundary. Real SkillSpector 2.9.6
--no-llmoutput already containsanalysis_completeness, but it does not contain the 2.10statusfield. Conversely, a report labeled 2.10+ could omit the new fields and take the legacy path.The previous validation also trusted summary flags without reconciling component counts, coverage, analyzer work, and limitations. Valid findings from partial scans were discarded because validation returned before finding conversion.
Contract
The validator now:
metadata.skillspector_versionand exactmetadata.llm_requestedagreement with the scan stage;before < after, and reconciles those counts with the serialized active and suppressed findings under the version-specific report behavior;scanned_components == fully_inspected_files;total_components == fully_inspected_files + partially_inspected_files + entirely_uninspected_files;metadata.has_executable_scripts;SC8issue in a complete report to resolve to exact source/path component evidence;coverage_percentfrom the component counts;finding_idvalues, scopes executable-file matching and report deduplication by producer provenance, uses serialized match fingerprints before finding IDs, and keeps legacy null-text rows distinct;SC8shipped-bytecode finding and rule-specific score floor, and keeps shipped bytecode in generated-output-free staged scans;Reviewer follow-up
This revision addresses all three P1 findings:
--no-llmfixture;Self-review also caught and corrected the partial LOW/CAUTION invariant, huge-integer coverage ordering, missing execution/version/recommendation evidence, incomplete analyzer rosters, analyzer status/work contradictions, duplicate transitive analyzer IDs, released 2.10/2.11 transitive-truncation output, unvalidated finding counts and identities, a false rejection caused by rebuilding a pre-compaction score from compacted findings, source-provenance loss in score reconstruction, null-fingerprint findings collapsed by display prose, legacy null-text findings collapsed into one row, executable component evidence lost during post-filter scoring, lossy replacement of the producer score, fractional score truncation at the policy threshold, and shipped bytecode removed before the artifact-integrity analyzer ran. Exact SkillSpector 2.10.0 producer probes confirm the report-deduplication, source-scoped scoring, null-fingerprint, and
SC8score-floor behavior covered by the public-seam regressions.Independent immutable-head review then reproduced three further defects: a missing component inventory could understate executable risk, report compaction could attach executable metadata from the wrong occurrence, and hidden pre-compaction multiplicity could make the reported-score bound unsafe. Those cases now fail closed or use independently reconstructed evidence. Final self-review also removed inconsistent duplicate source-scope logic and rejected duplicate component identities that could overwrite executable evidence.
Final immutable-head review reproduced three more P1 defects: empty or absent issue paths bypassed executable-score reconciliation; complete reports could claim zero work from every required analyzer; and representative confidence copied during compaction could reject a genuine producer score. Versioned paths now fail closed, complete universal-analyzer work is tied to the component inventory, and compacted identities use a conservative global unknown-finding budget.
A subsequent immutable-head review found that the first compaction fix erased all visible numeric risk whenever one raw finding was hidden or one identity expanded into multiple rows. The final score floor now counts one proven representative per compact identity, assigns the finite global unknown-finding budget to the largest possible diminishing-weight reductions, and preserves explicit producer rule floors. It also rejects reports that claim fewer raw findings than their distinct serialized compact identities.
The last immutable-head review found that rows under one modern compact identity could disagree on the producer-copied severity, confidence, or finding ID. That allowed a forged
15/LOW/SAFEreport to pass even though the corresponding raw findings score69/HIGH/DO_NOT_INSTALL. The validator now rejects inconsistent representative fields before score reconciliation while still allowing occurrence-specific paths and source details to differ.Verification
Full suite after rebasing onto current
main:5955 passed, 17 skipped, 4 deselectedFocused validator suite:
353 passedmake lint: passedmake build: source distribution and wheel built successfullyCaptured 2.9.6 fixture: valid JSON and accepted by the validator
Installed SkillSpector 2.10.0: clean and 14-advisory reference-skill probes passed against clean-checkout content; report-deduplicated and source-scoped score probes match the validator contract
Mutation check: the
SC8score-floor regression failed when the floor was removed and passed after restorationRed/green checks: fractional score-floor and staged-bytecode regressions failed before their fixes and passed afterward
Red/green check: the conflicting compacted-identity report passed before the fix and now fails closed; a conflicting-finding-ID variant also fails closed
Local DCO reproduction: all five PR commits have parsed
Signed-off-bytrailersgit diff --check: passedIndependent pre-publication review: analyzer-roster, component-inventory, path, universal-work, compacted-score, hidden-multiplicity, and visible-score-floor findings were reproduced and corrected
Final exact-head producer-contract and repository-standards reviews: no P0-P2 findings
I am familiar with the Contributing Guidelines
Added or updated focused tests
Updated documentation for user-visible changes
Ran
make lintRan the full test suite
Ran
make buildDid not add credentials, private datasets, or proprietary benchmark content
Release Impact
CHANGELOG.mdCompatibility
SkillSpector 2.9.6 reports use the strict captured compatibility path. Reports from 2.10 and newer must provide the complete status-bearing schema. Older versioned reports without
analysis_completenessretain the legacy path; unsupported pre-2.10 completeness objects fail closed.AI assistance disclosure
Codex inspected the SkillEvaluator and SkillSpector producer contracts, reproduced the reviewer cases, drafted the implementation and tests, captured the 2.9.6 fixture, and ran the verification commands. I reviewed the compatibility boundary, partial-finding behavior, fail-closed invariants, diff, and final pull-request text.