scaneval 2.0.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scaneval-2.0.0a1/.github/workflows/ci.yml +155 -0
- scaneval-2.0.0a1/.github/workflows/publish-packages.yml +116 -0
- scaneval-2.0.0a1/.gitignore +35 -0
- scaneval-2.0.0a1/LICENSE +21 -0
- scaneval-2.0.0a1/MANIFEST.in +29 -0
- scaneval-2.0.0a1/PKG-INFO +145 -0
- scaneval-2.0.0a1/README.md +149 -0
- scaneval-2.0.0a1/README_PYPI.md +110 -0
- scaneval-2.0.0a1/containers/sv-agent/Dockerfile +155 -0
- scaneval-2.0.0a1/containers/sv-agent/Dockerfile.dockerignore +23 -0
- scaneval-2.0.0a1/containers/sv-agent/README.md +238 -0
- scaneval-2.0.0a1/containers/sv-agent/build.sh +62 -0
- scaneval-2.0.0a1/containers/sv-agent/package-lock.json +1537 -0
- scaneval-2.0.0a1/containers/sv-agent/package.json +15 -0
- scaneval-2.0.0a1/containers/sv-agent/pi-cli.mjs +8 -0
- scaneval-2.0.0a1/containers/sv-agent/write-runtime-receipt.mjs +142 -0
- scaneval-2.0.0a1/corpus/benchmarks/README.md +32 -0
- scaneval-2.0.0a1/corpus/benchmarks/inventory.json +199 -0
- scaneval-2.0.0a1/corpus/diverse/README.md +123 -0
- scaneval-2.0.0a1/corpus/diverse/machine-review.json +3272 -0
- scaneval-2.0.0a1/corpus/diverse/machine-validation.json +102 -0
- scaneval-2.0.0a1/corpus/diverse/pack.json +12211 -0
- scaneval-2.0.0a1/corpus/diverse/review-history/18-case-selection-review.json +50 -0
- scaneval-2.0.0a1/corpus/diverse/selection-rationale.json +396 -0
- scaneval-2.0.0a1/corpus/diverse/severity-distribution.json +1830 -0
- scaneval-2.0.0a1/corpus/diverse/snapshot-inventory.json +5274 -0
- scaneval-2.0.0a1/corpus/diverse/upstream-evidence.json +5278 -0
- scaneval-2.0.0a1/docs/AGGREGATION.md +172 -0
- scaneval-2.0.0a1/docs/BRING_YOUR_OWN_CORPUS.md +1298 -0
- scaneval-2.0.0a1/docs/CLOSED_BOOK.md +121 -0
- scaneval-2.0.0a1/docs/CODEX_QUOTA_GUARD.md +254 -0
- scaneval-2.0.0a1/docs/COLLECTORS.md +659 -0
- scaneval-2.0.0a1/docs/DATASET_ADAPTERS.md +285 -0
- scaneval-2.0.0a1/docs/DESIGN_DECISIONS.md +547 -0
- scaneval-2.0.0a1/docs/DIAGNOSTICS.md +417 -0
- scaneval-2.0.0a1/docs/EVALUATION_MATH.md +332 -0
- scaneval-2.0.0a1/docs/EXPERIMENT_MATRIX.md +181 -0
- scaneval-2.0.0a1/docs/GATE.md +82 -0
- scaneval-2.0.0a1/docs/IDENTITY_REDUCTION.md +180 -0
- scaneval-2.0.0a1/docs/INITIAL_BUILD.md +524 -0
- scaneval-2.0.0a1/docs/INSPECT_OBSERVABILITY_COMPARISON.md +284 -0
- scaneval-2.0.0a1/docs/INVESTIGATION.md +140 -0
- scaneval-2.0.0a1/docs/MODEL_CUTOFFS.md +206 -0
- scaneval-2.0.0a1/docs/OBSERVER_SDK.md +428 -0
- scaneval-2.0.0a1/docs/OPEN_CONTEXT.md +344 -0
- scaneval-2.0.0a1/docs/PRECISION.md +132 -0
- scaneval-2.0.0a1/docs/RELEASING.md +84 -0
- scaneval-2.0.0a1/docs/SARIF_IMPORT.md +229 -0
- scaneval-2.0.0a1/docs/SEVERITY.md +115 -0
- scaneval-2.0.0a1/docs/THREAT_MODEL.md +426 -0
- scaneval-2.0.0a1/docs/designs/chronology-projection.md +78 -0
- scaneval-2.0.0a1/docs/designs/codex-quota-guard.md +202 -0
- scaneval-2.0.0a1/docs/designs/condition-review-fixes.md +283 -0
- scaneval-2.0.0a1/docs/designs/deepsec-curated-processing.md +230 -0
- scaneval-2.0.0a1/docs/designs/deepsec-native-kinds.md +35 -0
- scaneval-2.0.0a1/docs/designs/model-cutoff-eligibility.md +109 -0
- scaneval-2.0.0a1/docs/designs/scanner-adapter-builder.md +25 -0
- scaneval-2.0.0a1/docs/designs/sv-agent-open-context.md +123 -0
- scaneval-2.0.0a1/docs/designs/sv-completion-bounded-verification.md +127 -0
- scaneval-2.0.0a1/docs/designs/sv-review-workflow.md +115 -0
- scaneval-2.0.0a1/docs/research/recent-cve-candidates.json +4451 -0
- scaneval-2.0.0a1/docs/research/recent-cve-chronology.json +106 -0
- scaneval-2.0.0a1/docs/reviews/DATASET_COUNCIL_2026-10-22.json +92 -0
- scaneval-2.0.0a1/docs/reviews/DATASET_COUNCIL_2026-10-22.md +76 -0
- scaneval-2.0.0a1/docs/specs/CVSS_CALIBRATION_60.md +81 -0
- scaneval-2.0.0a1/examples/aggregation-policy.json +21 -0
- scaneval-2.0.0a1/examples/dataset_plugin/README.md +25 -0
- scaneval-2.0.0a1/examples/dataset_plugin/pyproject.toml +16 -0
- scaneval-2.0.0a1/examples/dataset_plugin/scaneval_example_dataset.py +25 -0
- scaneval-2.0.0a1/examples/experiment_matrix_fixture.py +83 -0
- scaneval-2.0.0a1/examples/gate-policy.json +70 -0
- scaneval-2.0.0a1/examples/observer/README.md +152 -0
- scaneval-2.0.0a1/examples/observer/python_harness.py +259 -0
- scaneval-2.0.0a1/examples/observer/typescript_harness.mts +233 -0
- scaneval-2.0.0a1/examples/open_context_fixture.py +85 -0
- scaneval-2.0.0a1/pyproject.toml +68 -0
- scaneval-2.0.0a1/schema/v2/fixtures/collectors/claude-code-edge-cases.jsonl +12 -0
- scaneval-2.0.0a1/schema/v2/fixtures/collectors/claude-code-result.json +19 -0
- scaneval-2.0.0a1/schema/v2/fixtures/collectors/claude-code-stream-json-error.jsonl +3 -0
- scaneval-2.0.0a1/schema/v2/fixtures/collectors/claude-code-stream-json.jsonl +11 -0
- scaneval-2.0.0a1/schema/v2/fixtures/collectors/claude-code-subagent.jsonl +17 -0
- scaneval-2.0.0a1/schema/v2/fixtures/collectors/claude-code-transcript.jsonl +32 -0
- scaneval-2.0.0a1/schema/v2/fixtures/collectors/codex-exec-edge-cases.jsonl +6 -0
- scaneval-2.0.0a1/schema/v2/fixtures/collectors/codex-exec.jsonl +9 -0
- scaneval-2.0.0a1/schema/v2/fixtures/trace-event-v2.json +14 -0
- scaneval-2.0.0a1/schema/v2/trace-event.schema.json +20 -0
- scaneval-2.0.0a1/scripts/check_python_package.py +144 -0
- scaneval-2.0.0a1/scripts/check_sv_completion_properties.py +1085 -0
- scaneval-2.0.0a1/scripts/oci_ci_path_gate.py +161 -0
- scaneval-2.0.0a1/scripts/sanitize_native_trace.py +390 -0
- scaneval-2.0.0a1/sdk/typescript/.gitignore +2 -0
- scaneval-2.0.0a1/sdk/typescript/package-lock.json +548 -0
- scaneval-2.0.0a1/sdk/typescript/package.json +24 -0
- scaneval-2.0.0a1/sdk/typescript/src/index.ts +1243 -0
- scaneval-2.0.0a1/sdk/typescript/test/observer.test.mjs +934 -0
- scaneval-2.0.0a1/sdk/typescript/tsconfig.json +13 -0
- scaneval-2.0.0a1/setup.cfg +4 -0
- scaneval-2.0.0a1/skills/cve-corpus-review/SKILL.md +56 -0
- scaneval-2.0.0a1/skills/cve-corpus-review/agents/openai.yaml +4 -0
- scaneval-2.0.0a1/skills/cve-corpus-review/references/evidence-review.md +39 -0
- scaneval-2.0.0a1/skills/cve-corpus-review/references/machine-records.md +61 -0
- scaneval-2.0.0a1/skills/scanner-adapter-builder/SKILL.md +51 -0
- scaneval-2.0.0a1/skills/scanner-adapter-builder/agents/openai.yaml +4 -0
- scaneval-2.0.0a1/skills/scanner-adapter-builder/references/failure-patterns.md +149 -0
- scaneval-2.0.0a1/skills/scanner-adapter-builder/references/property-verification.md +34 -0
- scaneval-2.0.0a1/src/scaneval/__init__.py +13 -0
- scaneval-2.0.0a1/src/scaneval/__main__.py +3 -0
- scaneval-2.0.0a1/src/scaneval/adapters/__init__.py +30 -0
- scaneval-2.0.0a1/src/scaneval/adapters/base.py +535 -0
- scaneval-2.0.0a1/src/scaneval/adapters/deepsec.py +3944 -0
- scaneval-2.0.0a1/src/scaneval/adapters/llm_harness.py +3312 -0
- scaneval-2.0.0a1/src/scaneval/adapters/llm_harness_driver.mts +2160 -0
- scaneval-2.0.0a1/src/scaneval/adapters/pi_oci_runner.mts +317 -0
- scaneval-2.0.0a1/src/scaneval/adapters/pi_open_context.mts +19 -0
- scaneval-2.0.0a1/src/scaneval/adapters/pi_open_context_tools.mjs +506 -0
- scaneval-2.0.0a1/src/scaneval/adapters/pi_synthetic_provider.mts +115 -0
- scaneval-2.0.0a1/src/scaneval/adapters/pr.py +252 -0
- scaneval-2.0.0a1/src/scaneval/adapters/runsortie.py +3279 -0
- scaneval-2.0.0a1/src/scaneval/adapters/runsortie_evidence.py +2232 -0
- scaneval-2.0.0a1/src/scaneval/adapters/semgrep.py +1081 -0
- scaneval-2.0.0a1/src/scaneval/aggregate.py +2548 -0
- scaneval-2.0.0a1/src/scaneval/artifacts.py +38 -0
- scaneval-2.0.0a1/src/scaneval/benchmark.py +486 -0
- scaneval-2.0.0a1/src/scaneval/benchmark_cli.py +61 -0
- scaneval-2.0.0a1/src/scaneval/blinding.py +1886 -0
- scaneval-2.0.0a1/src/scaneval/cases.py +1573 -0
- scaneval-2.0.0a1/src/scaneval/cli.py +1799 -0
- scaneval-2.0.0a1/src/scaneval/collectors/__init__.py +545 -0
- scaneval-2.0.0a1/src/scaneval/collectors/claude_code.py +1600 -0
- scaneval-2.0.0a1/src/scaneval/collectors/codex.py +494 -0
- scaneval-2.0.0a1/src/scaneval/collectors/source.py +63 -0
- scaneval-2.0.0a1/src/scaneval/conditions.py +624 -0
- scaneval-2.0.0a1/src/scaneval/conditions_identity.py +93 -0
- scaneval-2.0.0a1/src/scaneval/contracts.py +2695 -0
- scaneval-2.0.0a1/src/scaneval/corpus.py +57 -0
- scaneval-2.0.0a1/src/scaneval/data/model-cutoffs.json +1717 -0
- scaneval-2.0.0a1/src/scaneval/datasets/__init__.py +35 -0
- scaneval-2.0.0a1/src/scaneval/datasets/base.py +139 -0
- scaneval-2.0.0a1/src/scaneval/datasets/builtin.py +224 -0
- scaneval-2.0.0a1/src/scaneval/datasets/cli.py +50 -0
- scaneval-2.0.0a1/src/scaneval/datasets/locks/aacr-bench.json +54 -0
- scaneval-2.0.0a1/src/scaneval/datasets/locks/martian.json +522 -0
- scaneval-2.0.0a1/src/scaneval/datasets/locks/openssf.json +1628 -0
- scaneval-2.0.0a1/src/scaneval/datasets/locks/reviewbench.json +1578 -0
- scaneval-2.0.0a1/src/scaneval/demo.py +64 -0
- scaneval-2.0.0a1/src/scaneval/diagnostics.py +1089 -0
- scaneval-2.0.0a1/src/scaneval/evaluator.py +27 -0
- scaneval-2.0.0a1/src/scaneval/execution.py +1764 -0
- scaneval-2.0.0a1/src/scaneval/experiment.py +507 -0
- scaneval-2.0.0a1/src/scaneval/experiment_execution.py +405 -0
- scaneval-2.0.0a1/src/scaneval/experiment_report.py +457 -0
- scaneval-2.0.0a1/src/scaneval/gate.py +1344 -0
- scaneval-2.0.0a1/src/scaneval/identity_policy.py +1278 -0
- scaneval-2.0.0a1/src/scaneval/investigation.py +467 -0
- scaneval-2.0.0a1/src/scaneval/investigation_html.py +138 -0
- scaneval-2.0.0a1/src/scaneval/isolation/__init__.py +275 -0
- scaneval-2.0.0a1/src/scaneval/isolation/egress_proxy.py +302 -0
- scaneval-2.0.0a1/src/scaneval/isolation/oci.py +1335 -0
- scaneval-2.0.0a1/src/scaneval/isolation/public_retrieval.py +556 -0
- scaneval-2.0.0a1/src/scaneval/kinds.py +86 -0
- scaneval-2.0.0a1/src/scaneval/machine_review.py +299 -0
- scaneval-2.0.0a1/src/scaneval/mappings/kinds.json +43 -0
- scaneval-2.0.0a1/src/scaneval/materialize.py +1243 -0
- scaneval-2.0.0a1/src/scaneval/model_cutoff_projection.py +148 -0
- scaneval-2.0.0a1/src/scaneval/model_cutoffs.py +261 -0
- scaneval-2.0.0a1/src/scaneval/model_cutoffs_cli.py +36 -0
- scaneval-2.0.0a1/src/scaneval/observer/__init__.py +81 -0
- scaneval-2.0.0a1/src/scaneval/observer/emitter.py +1795 -0
- scaneval-2.0.0a1/src/scaneval/open_context.py +341 -0
- scaneval-2.0.0a1/src/scaneval/open_context_evidence.py +285 -0
- scaneval-2.0.0a1/src/scaneval/precision.py +929 -0
- scaneval-2.0.0a1/src/scaneval/report.py +114 -0
- scaneval-2.0.0a1/src/scaneval/resampling.py +93 -0
- scaneval-2.0.0a1/src/scaneval/review.py +475 -0
- scaneval-2.0.0a1/src/scaneval/runner.py +1257 -0
- scaneval-2.0.0a1/src/scaneval/sarif.py +2240 -0
- scaneval-2.0.0a1/src/scaneval/schedule.py +277 -0
- scaneval-2.0.0a1/src/scaneval/schemas/aggregate-report.schema.json +2011 -0
- scaneval-2.0.0a1/src/scaneval/schemas/aggregation-policy.schema.json +131 -0
- scaneval-2.0.0a1/src/scaneval/schemas/blinding-map.schema.json +426 -0
- scaneval-2.0.0a1/src/scaneval/schemas/case-pack-2.1.schema.json +1172 -0
- scaneval-2.0.0a1/src/scaneval/schemas/case-pack.schema.json +257 -0
- scaneval-2.0.0a1/src/scaneval/schemas/comparison-report.schema.json +2078 -0
- scaneval-2.0.0a1/src/scaneval/schemas/condition-record.schema.json +41 -0
- scaneval-2.0.0a1/src/scaneval/schemas/dataset.schema.json +61 -0
- scaneval-2.0.0a1/src/scaneval/schemas/evaluation-plan-2.1.schema.json +329 -0
- scaneval-2.0.0a1/src/scaneval/schemas/evaluation-plan.schema.json +52 -0
- scaneval-2.0.0a1/src/scaneval/schemas/evaluation-schedule.schema.json +647 -0
- scaneval-2.0.0a1/src/scaneval/schemas/execution-record-2.1.schema.json +501 -0
- scaneval-2.0.0a1/src/scaneval/schemas/execution-record.schema.json +79 -0
- scaneval-2.0.0a1/src/scaneval/schemas/experiment-matrix.schema.json +99 -0
- scaneval-2.0.0a1/src/scaneval/schemas/gate-decision.schema.json +387 -0
- scaneval-2.0.0a1/src/scaneval/schemas/gate-policy.schema.json +436 -0
- scaneval-2.0.0a1/src/scaneval/schemas/identity-transformation-manifest.schema.json +136 -0
- scaneval-2.0.0a1/src/scaneval/schemas/import-record.schema.json +680 -0
- scaneval-2.0.0a1/src/scaneval/schemas/machine-judgments.schema.json +72 -0
- scaneval-2.0.0a1/src/scaneval/schemas/precision-estimate.schema.json +807 -0
- scaneval-2.0.0a1/src/scaneval/schemas/precision-reviews.schema.json +96 -0
- scaneval-2.0.0a1/src/scaneval/schemas/precision-sample.schema.json +667 -0
- scaneval-2.0.0a1/src/scaneval/schemas/review-decisions.schema.json +40 -0
- scaneval-2.0.0a1/src/scaneval/schemas/review-record.schema.json +21 -0
- scaneval-2.0.0a1/src/scaneval/schemas/run-config-2.1.schema.json +275 -0
- scaneval-2.0.0a1/src/scaneval/schemas/run-config.schema.json +29 -0
- scaneval-2.0.0a1/src/scaneval/schemas/run-manifest-2.1.schema.json +599 -0
- scaneval-2.0.0a1/src/scaneval/schemas/run-manifest.schema.json +140 -0
- scaneval-2.0.0a1/src/scaneval/schemas/scan-request.schema.json +52 -0
- scaneval-2.0.0a1/src/scaneval/schemas/scan-result-2.1.schema.json +295 -0
- scaneval-2.0.0a1/src/scaneval/schemas/scan-result.schema.json +73 -0
- scaneval-2.0.0a1/src/scaneval/schemas/severity-report.schema.json +1158 -0
- scaneval-2.0.0a1/src/scaneval/schemas/trace-event.schema.json +20 -0
- scaneval-2.0.0a1/src/scaneval/scoring.py +379 -0
- scaneval-2.0.0a1/src/scaneval/severity.py +422 -0
- scaneval-2.0.0a1/src/scaneval/source.py +20 -0
- scaneval-2.0.0a1/src/scaneval/trace.py +80 -0
- scaneval-2.0.0a1/src/scaneval.egg-info/PKG-INFO +145 -0
- scaneval-2.0.0a1/src/scaneval.egg-info/SOURCES.txt +310 -0
- scaneval-2.0.0a1/src/scaneval.egg-info/dependency_links.txt +1 -0
- scaneval-2.0.0a1/src/scaneval.egg-info/entry_points.txt +2 -0
- scaneval-2.0.0a1/src/scaneval.egg-info/requires.txt +9 -0
- scaneval-2.0.0a1/src/scaneval.egg-info/top_level.txt +1 -0
- scaneval-2.0.0a1/tests/conftest.py +49 -0
- scaneval-2.0.0a1/tests/fixtures/deepsec-capture-matrix.json +24 -0
- scaneval-2.0.0a1/tests/fixtures/runsortie/fake_runsortie.py +1392 -0
- scaneval-2.0.0a1/tests/fixtures/runsortie/fake_tools.py +174 -0
- scaneval-2.0.0a1/tests/fixtures/sarif/codeql.sarif +174 -0
- scaneval-2.0.0a1/tests/fixtures/sarif/semgrep-shell.json +23 -0
- scaneval-2.0.0a1/tests/fixtures/sarif/semgrep.sarif +117 -0
- scaneval-2.0.0a1/tests/fixtures/sv-completion.json +71 -0
- scaneval-2.0.0a1/tests/fixtures/sv-review-workflow-summary.json +906 -0
- scaneval-2.0.0a1/tests/node/sv_pi_oci.test.mjs +283 -0
- scaneval-2.0.0a1/tests/node/sv_runtime_dependencies.test.mjs +161 -0
- scaneval-2.0.0a1/tests/test_ci_oci_path_gate.py +177 -0
- scaneval-2.0.0a1/tests/test_codex_guard_docker.py +347 -0
- scaneval-2.0.0a1/tests/test_codex_quota_buckets.py +263 -0
- scaneval-2.0.0a1/tests/test_codex_quota_guard.py +820 -0
- scaneval-2.0.0a1/tests/test_dataset_adapters.py +252 -0
- scaneval-2.0.0a1/tests/test_dataset_benchmark.py +643 -0
- scaneval-2.0.0a1/tests/test_identifier_evidence_boundaries.py +113 -0
- scaneval-2.0.0a1/tests/test_identifier_python_boundaries.py +134 -0
- scaneval-2.0.0a1/tests/test_identifier_run_boundaries.py +123 -0
- scaneval-2.0.0a1/tests/test_identifier_schema_boundaries.py +154 -0
- scaneval-2.0.0a1/tests/test_local_command_cleanup.py +223 -0
- scaneval-2.0.0a1/tests/test_machine_review.py +188 -0
- scaneval-2.0.0a1/tests/test_model_cutoff_projection.py +410 -0
- scaneval-2.0.0a1/tests/test_model_cutoffs.py +384 -0
- scaneval-2.0.0a1/tests/test_native_trace_sanitizer.py +90 -0
- scaneval-2.0.0a1/tests/test_sv_completion_properties.py +129 -0
- scaneval-2.0.0a1/tests/test_v2_adapter_modes.py +345 -0
- scaneval-2.0.0a1/tests/test_v2_aggregate.py +3181 -0
- scaneval-2.0.0a1/tests/test_v2_artifact_recovery.py +49 -0
- scaneval-2.0.0a1/tests/test_v2_blinding.py +3040 -0
- scaneval-2.0.0a1/tests/test_v2_cases.py +2981 -0
- scaneval-2.0.0a1/tests/test_v2_cli.py +261 -0
- scaneval-2.0.0a1/tests/test_v2_cli_corpus.py +1773 -0
- scaneval-2.0.0a1/tests/test_v2_collectors.py +2381 -0
- scaneval-2.0.0a1/tests/test_v2_condition_history.py +124 -0
- scaneval-2.0.0a1/tests/test_v2_condition_identity.py +187 -0
- scaneval-2.0.0a1/tests/test_v2_condition_reporting.py +299 -0
- scaneval-2.0.0a1/tests/test_v2_conditions.py +672 -0
- scaneval-2.0.0a1/tests/test_v2_contracts.py +1884 -0
- scaneval-2.0.0a1/tests/test_v2_contracts_21.py +418 -0
- scaneval-2.0.0a1/tests/test_v2_deepsec.py +6054 -0
- scaneval-2.0.0a1/tests/test_v2_diagnostics.py +1443 -0
- scaneval-2.0.0a1/tests/test_v2_execution.py +3484 -0
- scaneval-2.0.0a1/tests/test_v2_experiment_cli.py +57 -0
- scaneval-2.0.0a1/tests/test_v2_experiment_docker.py +78 -0
- scaneval-2.0.0a1/tests/test_v2_experiment_execution.py +783 -0
- scaneval-2.0.0a1/tests/test_v2_experiment_freeze.py +150 -0
- scaneval-2.0.0a1/tests/test_v2_experiment_matrix.py +158 -0
- scaneval-2.0.0a1/tests/test_v2_experiment_report.py +203 -0
- scaneval-2.0.0a1/tests/test_v2_gate.py +3835 -0
- scaneval-2.0.0a1/tests/test_v2_identity_exports.py +451 -0
- scaneval-2.0.0a1/tests/test_v2_identity_policy.py +935 -0
- scaneval-2.0.0a1/tests/test_v2_investigation.py +612 -0
- scaneval-2.0.0a1/tests/test_v2_investigation_cli.py +48 -0
- scaneval-2.0.0a1/tests/test_v2_isolation.py +1489 -0
- scaneval-2.0.0a1/tests/test_v2_isolation_docker.py +1235 -0
- scaneval-2.0.0a1/tests/test_v2_kinds.py +96 -0
- scaneval-2.0.0a1/tests/test_v2_llm_harness.py +4890 -0
- scaneval-2.0.0a1/tests/test_v2_materialize.py +1345 -0
- scaneval-2.0.0a1/tests/test_v2_native_mapping.py +94 -0
- scaneval-2.0.0a1/tests/test_v2_numeric_readers.py +125 -0
- scaneval-2.0.0a1/tests/test_v2_observer.py +3534 -0
- scaneval-2.0.0a1/tests/test_v2_observer_parity.py +2971 -0
- scaneval-2.0.0a1/tests/test_v2_observer_python.py +556 -0
- scaneval-2.0.0a1/tests/test_v2_open_context.py +350 -0
- scaneval-2.0.0a1/tests/test_v2_open_context_docker.py +168 -0
- scaneval-2.0.0a1/tests/test_v2_open_context_evidence.py +180 -0
- scaneval-2.0.0a1/tests/test_v2_open_context_reporting.py +17 -0
- scaneval-2.0.0a1/tests/test_v2_open_context_runner.py +157 -0
- scaneval-2.0.0a1/tests/test_v2_pr.py +765 -0
- scaneval-2.0.0a1/tests/test_v2_precision.py +1342 -0
- scaneval-2.0.0a1/tests/test_v2_public_retrieval.py +798 -0
- scaneval-2.0.0a1/tests/test_v2_public_retrieval_deadline_fragments.py +91 -0
- scaneval-2.0.0a1/tests/test_v2_repository_hygiene.py +91 -0
- scaneval-2.0.0a1/tests/test_v2_resampling.py +77 -0
- scaneval-2.0.0a1/tests/test_v2_review.py +857 -0
- scaneval-2.0.0a1/tests/test_v2_runner.py +1053 -0
- scaneval-2.0.0a1/tests/test_v2_runner_inputs.py +602 -0
- scaneval-2.0.0a1/tests/test_v2_runsortie.py +2447 -0
- scaneval-2.0.0a1/tests/test_v2_sarif.py +2550 -0
- scaneval-2.0.0a1/tests/test_v2_schedule.py +533 -0
- scaneval-2.0.0a1/tests/test_v2_scoring.py +701 -0
- scaneval-2.0.0a1/tests/test_v2_semgrep.py +1772 -0
- scaneval-2.0.0a1/tests/test_v2_semgrep_full_coverage.py +287 -0
- scaneval-2.0.0a1/tests/test_v2_severity.py +427 -0
- scaneval-2.0.0a1/tests/test_v2_sv_open_context.py +846 -0
- scaneval-2.0.0a1/tests/test_v2_sv_open_context_docker.py +219 -0
- scaneval-2.0.0a1/tests/test_v2_trace_contract.py +41 -0
- scaneval-2.0.0a1/tests/test_v2_trace_reader.py +62 -0
- scaneval-2.0.0a1/tools/codex_guard_docker.py +334 -0
- scaneval-2.0.0a1/tools/codex_quota_guard.py +829 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
test:
|
|
18
|
+
name: Python ${{ matrix.python }} and TypeScript
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
timeout-minutes: 20
|
|
21
|
+
strategy:
|
|
22
|
+
fail-fast: false
|
|
23
|
+
matrix:
|
|
24
|
+
python: ['3.11', '3.13', '3.14']
|
|
25
|
+
env:
|
|
26
|
+
PYTHONDONTWRITEBYTECODE: '1'
|
|
27
|
+
SEMGREP_SEND_METRICS: 'off'
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
30
|
+
with:
|
|
31
|
+
persist-credentials: false
|
|
32
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
33
|
+
with:
|
|
34
|
+
python-version: ${{ matrix.python }}
|
|
35
|
+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
36
|
+
with:
|
|
37
|
+
node-version: '24'
|
|
38
|
+
cache: npm
|
|
39
|
+
cache-dependency-path: sdk/typescript/package-lock.json
|
|
40
|
+
- name: Install test dependencies
|
|
41
|
+
run: |
|
|
42
|
+
python -m pip install -e '.[dev]' build 'semgrep==1.177.0'
|
|
43
|
+
npm ci --prefix sdk/typescript
|
|
44
|
+
- name: TypeScript tests and build
|
|
45
|
+
run: npm test --prefix sdk/typescript
|
|
46
|
+
- name: Python tests including Observer parity
|
|
47
|
+
# Tests use fixtures and mock runners, never paid models. Tests requiring
|
|
48
|
+
# external harness checkouts or preserved private bundles report skips.
|
|
49
|
+
run: python -m pytest -q -rs
|
|
50
|
+
- name: Build wheel
|
|
51
|
+
run: python -m build --wheel --outdir "$RUNNER_TEMP/scaneval-dist"
|
|
52
|
+
- name: Installed-wheel demo and replay
|
|
53
|
+
working-directory: ${{ runner.temp }}
|
|
54
|
+
env:
|
|
55
|
+
PYTHONPATH: ''
|
|
56
|
+
run: |
|
|
57
|
+
python -m venv "$RUNNER_TEMP/scaneval-wheel-env"
|
|
58
|
+
"$RUNNER_TEMP/scaneval-wheel-env/bin/python" -m pip install "$RUNNER_TEMP"/scaneval-dist/*.whl
|
|
59
|
+
"$RUNNER_TEMP/scaneval-wheel-env/bin/scaneval" demo "$RUNNER_TEMP/scaneval-demo"
|
|
60
|
+
"$RUNNER_TEMP/scaneval-wheel-env/bin/scaneval" replay "$RUNNER_TEMP/scaneval-demo" --output "$RUNNER_TEMP/scaneval-replay.json"
|
|
61
|
+
cmp "$RUNNER_TEMP/scaneval-demo/evaluation.json" "$RUNNER_TEMP/scaneval-replay.json"
|
|
62
|
+
|
|
63
|
+
runtime-dependencies:
|
|
64
|
+
name: Audited SV-Agent runtime dependencies
|
|
65
|
+
runs-on: ubuntu-latest
|
|
66
|
+
timeout-minutes: 10
|
|
67
|
+
env:
|
|
68
|
+
PI_OFFLINE: '1'
|
|
69
|
+
PI_SKIP_VERSION_CHECK: '1'
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
72
|
+
with:
|
|
73
|
+
persist-credentials: false
|
|
74
|
+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
75
|
+
with:
|
|
76
|
+
node-version: '26.7.0'
|
|
77
|
+
cache: npm
|
|
78
|
+
cache-dependency-path: containers/sv-agent/package-lock.json
|
|
79
|
+
- name: Install the image's runtime dependencies
|
|
80
|
+
run: npm ci --prefix containers/sv-agent --omit=dev --ignore-scripts --engine-strict
|
|
81
|
+
- name: Audit both dependency locks
|
|
82
|
+
run: |
|
|
83
|
+
npm audit --prefix containers/sv-agent --omit=dev --audit-level=low
|
|
84
|
+
npm audit --prefix sdk/typescript --package-lock-only --audit-level=low
|
|
85
|
+
- name: Exercise the native CLI, glob selection, and proxy transport
|
|
86
|
+
# Real installed Pi and dependencies against local fixtures, with no model calls.
|
|
87
|
+
run: node --test tests/node/sv_runtime_dependencies.test.mjs
|
|
88
|
+
|
|
89
|
+
oci_path_gate:
|
|
90
|
+
name: Decide whether OCI integration is relevant
|
|
91
|
+
runs-on: ubuntu-latest
|
|
92
|
+
timeout-minutes: 5
|
|
93
|
+
outputs:
|
|
94
|
+
run_oci: ${{ steps.filter.outputs.run_oci }}
|
|
95
|
+
steps:
|
|
96
|
+
# pull_request checks out GitHub's merge ref. Depth two contains the merge commit and its
|
|
97
|
+
# base parent, so HEAD^..HEAD is the complete PR change, not merely its last commit.
|
|
98
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
99
|
+
with:
|
|
100
|
+
fetch-depth: 2
|
|
101
|
+
persist-credentials: false
|
|
102
|
+
- name: Match OCI-relevant paths
|
|
103
|
+
id: filter
|
|
104
|
+
env:
|
|
105
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
106
|
+
run: |
|
|
107
|
+
set -euo pipefail
|
|
108
|
+
decision="$(python3 scripts/oci_ci_path_gate.py --event-name "$EVENT_NAME")"
|
|
109
|
+
case "$decision" in
|
|
110
|
+
true|false) ;;
|
|
111
|
+
*) echo "OCI path gate returned an invalid decision: $decision" >&2; exit 1 ;;
|
|
112
|
+
esac
|
|
113
|
+
echo "run_oci=$decision" >> "$GITHUB_OUTPUT"
|
|
114
|
+
|
|
115
|
+
oci-integration:
|
|
116
|
+
name: OCI backend against a real Docker engine
|
|
117
|
+
needs: oci_path_gate
|
|
118
|
+
# A failed filter must surface as a failed required check, never as a silently skipped Docker
|
|
119
|
+
# run. Pushes to main and workflow_dispatch return true without consulting the diff.
|
|
120
|
+
if: ${{ always() && (needs.oci_path_gate.result != 'success' || needs.oci_path_gate.outputs.run_oci != 'false') }}
|
|
121
|
+
runs-on: ubuntu-latest
|
|
122
|
+
timeout-minutes: 20
|
|
123
|
+
env:
|
|
124
|
+
PYTHONDONTWRITEBYTECODE: '1'
|
|
125
|
+
# Without this the module skips when no engine or image is present; here that is a failure.
|
|
126
|
+
SCANEVAL_REQUIRE_DOCKER: '1'
|
|
127
|
+
steps:
|
|
128
|
+
- name: Require a successful path decision
|
|
129
|
+
if: ${{ needs.oci_path_gate.result != 'success' }}
|
|
130
|
+
run: |
|
|
131
|
+
echo "The OCI path gate failed; refusing to hide the Docker check." >&2
|
|
132
|
+
exit 1
|
|
133
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
134
|
+
with:
|
|
135
|
+
persist-credentials: false
|
|
136
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
137
|
+
with:
|
|
138
|
+
python-version: '3.13'
|
|
139
|
+
- name: Install test dependencies
|
|
140
|
+
run: python -m pip install -e '.[dev]'
|
|
141
|
+
- name: Describe the engine
|
|
142
|
+
# model_provider_only needs an engine that applies gateway_mode_ipv4=isolated; the record
|
|
143
|
+
# of which engine ran is here when that test says it did not.
|
|
144
|
+
run: |
|
|
145
|
+
docker version
|
|
146
|
+
docker info
|
|
147
|
+
- name: Pull the pinned images
|
|
148
|
+
# The backend never pulls an image, so the tests use only what is already present.
|
|
149
|
+
run: |
|
|
150
|
+
docker pull python:3.12-slim@sha256:2f17fc044b579bab302c2e8054d3a686e2cb9a83de48e70534b94cd8ebbe06a9
|
|
151
|
+
docker pull semgrep/semgrep:1.177.0@sha256:acaac22ffc7b7cc5926de0751b223bce0b2491c33d18422fa72f632c78d81198
|
|
152
|
+
- name: OCI integration tests
|
|
153
|
+
# Real containers, local fixture services, and benign example.com retrieval; no model
|
|
154
|
+
# or target application is called. Native Linux also checks cross-UID capture reads.
|
|
155
|
+
run: python -m pytest -q -rs tests/test_v2_isolation_docker.py tests/test_v2_open_context_docker.py tests/test_v2_experiment_docker.py
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
name: Python alpha package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
paths:
|
|
6
|
+
- '.github/workflows/publish-packages.yml'
|
|
7
|
+
- 'pyproject.toml'
|
|
8
|
+
- 'MANIFEST.in'
|
|
9
|
+
- 'README_PYPI.md'
|
|
10
|
+
- 'LICENSE'
|
|
11
|
+
- 'src/**'
|
|
12
|
+
- 'scripts/check_python_package.py'
|
|
13
|
+
push:
|
|
14
|
+
branches: [main]
|
|
15
|
+
paths:
|
|
16
|
+
- '.github/workflows/publish-packages.yml'
|
|
17
|
+
- 'pyproject.toml'
|
|
18
|
+
- 'MANIFEST.in'
|
|
19
|
+
- 'README_PYPI.md'
|
|
20
|
+
- 'LICENSE'
|
|
21
|
+
- 'src/**'
|
|
22
|
+
- 'scripts/check_python_package.py'
|
|
23
|
+
workflow_dispatch:
|
|
24
|
+
inputs:
|
|
25
|
+
publish:
|
|
26
|
+
description: Publish the verified Python artifacts (requires PyPI trusted-publisher setup)
|
|
27
|
+
type: boolean
|
|
28
|
+
default: false
|
|
29
|
+
|
|
30
|
+
permissions:
|
|
31
|
+
contents: read
|
|
32
|
+
|
|
33
|
+
concurrency:
|
|
34
|
+
group: python-alpha-package-${{ github.ref }}
|
|
35
|
+
cancel-in-progress: false
|
|
36
|
+
|
|
37
|
+
jobs:
|
|
38
|
+
python-artifacts:
|
|
39
|
+
name: Python wheel and source archive
|
|
40
|
+
runs-on: ubuntu-latest
|
|
41
|
+
timeout-minutes: 10
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
44
|
+
with:
|
|
45
|
+
persist-credentials: false
|
|
46
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
47
|
+
with:
|
|
48
|
+
python-version: '3.11'
|
|
49
|
+
- name: Build and validate distribution metadata
|
|
50
|
+
run: |
|
|
51
|
+
python -m pip install build twine
|
|
52
|
+
python - <<'PY'
|
|
53
|
+
import tomllib
|
|
54
|
+
from packaging.version import Version
|
|
55
|
+
with open('pyproject.toml', 'rb') as source:
|
|
56
|
+
project = tomllib.load(source)['project']
|
|
57
|
+
assert project['name'] == 'scaneval'
|
|
58
|
+
assert Version(project['version']).is_prerelease, 'This workflow publishes alpha releases only'
|
|
59
|
+
PY
|
|
60
|
+
python -m build --outdir "$RUNNER_TEMP/python-dist"
|
|
61
|
+
python -m twine check --strict "$RUNNER_TEMP"/python-dist/*
|
|
62
|
+
- name: Install and exercise the exact wheel and source archive
|
|
63
|
+
run: |
|
|
64
|
+
for artifact in "$RUNNER_TEMP"/python-dist/*; do
|
|
65
|
+
python scripts/check_python_package.py "$artifact"
|
|
66
|
+
done
|
|
67
|
+
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
68
|
+
with:
|
|
69
|
+
name: python-dist-${{ github.sha }}
|
|
70
|
+
path: ${{ runner.temp }}/python-dist/*
|
|
71
|
+
if-no-files-found: error
|
|
72
|
+
retention-days: 14
|
|
73
|
+
|
|
74
|
+
verified-main:
|
|
75
|
+
name: Require successful main CI before publishing
|
|
76
|
+
if: github.event_name == 'workflow_dispatch' && inputs.publish
|
|
77
|
+
runs-on: ubuntu-latest
|
|
78
|
+
timeout-minutes: 5
|
|
79
|
+
permissions:
|
|
80
|
+
contents: read
|
|
81
|
+
actions: read
|
|
82
|
+
steps:
|
|
83
|
+
- name: Refuse publication outside main or before its CI passes
|
|
84
|
+
env:
|
|
85
|
+
GH_TOKEN: ${{ github.token }}
|
|
86
|
+
REPOSITORY: ${{ github.repository }}
|
|
87
|
+
RELEASE_SHA: ${{ github.sha }}
|
|
88
|
+
RELEASE_REF: ${{ github.ref }}
|
|
89
|
+
run: |
|
|
90
|
+
test "$RELEASE_REF" = refs/heads/main
|
|
91
|
+
gh api --method GET "repos/$REPOSITORY/actions/workflows/ci.yml/runs" \
|
|
92
|
+
-f head_sha="$RELEASE_SHA" -f status=success -f event=push > "$RUNNER_TEMP/ci.json"
|
|
93
|
+
python3 - <<'PY'
|
|
94
|
+
import json, os
|
|
95
|
+
from pathlib import Path
|
|
96
|
+
runs = json.loads(Path(os.environ['RUNNER_TEMP'], 'ci.json').read_text())['workflow_runs']
|
|
97
|
+
assert any(run['head_sha'] == os.environ['RELEASE_SHA'] and run['conclusion'] == 'success'
|
|
98
|
+
and run['event'] == 'push' for run in runs), 'Current main CI has not passed'
|
|
99
|
+
PY
|
|
100
|
+
|
|
101
|
+
publish-pypi:
|
|
102
|
+
name: Publish Python alpha to PyPI
|
|
103
|
+
needs: [python-artifacts, verified-main]
|
|
104
|
+
if: github.event_name == 'workflow_dispatch' && inputs.publish
|
|
105
|
+
runs-on: ubuntu-latest
|
|
106
|
+
timeout-minutes: 5
|
|
107
|
+
environment: pypi
|
|
108
|
+
permissions:
|
|
109
|
+
contents: read
|
|
110
|
+
id-token: write
|
|
111
|
+
steps:
|
|
112
|
+
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
113
|
+
with:
|
|
114
|
+
name: python-dist-${{ github.sha }}
|
|
115
|
+
path: dist
|
|
116
|
+
- uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.pyc
|
|
4
|
+
*.pyo
|
|
5
|
+
*.egg-info/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
.venv/
|
|
9
|
+
venv/
|
|
10
|
+
|
|
11
|
+
# Rust
|
|
12
|
+
target/
|
|
13
|
+
|
|
14
|
+
# Node
|
|
15
|
+
node_modules/
|
|
16
|
+
|
|
17
|
+
# IDE
|
|
18
|
+
.vscode/
|
|
19
|
+
.idea/
|
|
20
|
+
|
|
21
|
+
# OS
|
|
22
|
+
.DS_Store
|
|
23
|
+
Thumbs.db
|
|
24
|
+
|
|
25
|
+
# ScanEval
|
|
26
|
+
.repos/
|
|
27
|
+
results/
|
|
28
|
+
*.html
|
|
29
|
+
|
|
30
|
+
# Scanner artifacts
|
|
31
|
+
.securevibes/
|
|
32
|
+
.claude/
|
|
33
|
+
|
|
34
|
+
# case-build scratch dirs
|
|
35
|
+
.*_build/
|
scaneval-2.0.0a1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ScanEval contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
include LICENSE README.md README_PYPI.md pyproject.toml .gitignore
|
|
2
|
+
recursive-include src *.py *.json *.mts *.mjs
|
|
3
|
+
recursive-include docs *.md *.json
|
|
4
|
+
recursive-include examples *.py *.mts *.md *.json *.toml
|
|
5
|
+
recursive-include schema *.json *.jsonl
|
|
6
|
+
recursive-include corpus *.md *.json
|
|
7
|
+
recursive-include scripts *.py
|
|
8
|
+
recursive-include tools *.py
|
|
9
|
+
recursive-include tests *.py *.json *.sarif *.mjs
|
|
10
|
+
recursive-include sdk/typescript *.json *.ts *.mjs *.md LICENSE
|
|
11
|
+
include sdk/typescript/.gitignore
|
|
12
|
+
recursive-include containers/sv-agent Dockerfile Dockerfile.dockerignore *.json *.mjs *.md *.sh
|
|
13
|
+
recursive-include skills *.md *.yaml
|
|
14
|
+
recursive-include .github *.yml
|
|
15
|
+
|
|
16
|
+
# Source archives carry runnable examples and test fixtures, never local runs or caches.
|
|
17
|
+
prune .git
|
|
18
|
+
prune .repos
|
|
19
|
+
prune results
|
|
20
|
+
prune build
|
|
21
|
+
prune dist
|
|
22
|
+
prune .venv
|
|
23
|
+
prune .pytest_cache
|
|
24
|
+
prune .claude
|
|
25
|
+
prune .securevibes
|
|
26
|
+
prune sdk/typescript/node_modules
|
|
27
|
+
prune sdk/typescript/dist
|
|
28
|
+
prune containers/sv-agent/node_modules
|
|
29
|
+
global-exclude __pycache__ *.py[cod] .DS_Store
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: scaneval
|
|
3
|
+
Version: 2.0.0a1
|
|
4
|
+
Summary: Alpha framework for reproducible security-scanner evaluation and observability.
|
|
5
|
+
Author: ScanEval contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Har1sh-k/scaneval
|
|
8
|
+
Project-URL: Repository, https://github.com/Har1sh-k/scaneval
|
|
9
|
+
Project-URL: Documentation, https://github.com/Har1sh-k/scaneval/blob/main/docs/INITIAL_BUILD.md
|
|
10
|
+
Project-URL: Issues, https://github.com/Har1sh-k/scaneval/issues
|
|
11
|
+
Keywords: security,scanner,evaluation,benchmark,observability
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: Operating System :: POSIX
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Classifier: Topic :: Security
|
|
23
|
+
Classifier: Topic :: Software Development :: Testing
|
|
24
|
+
Requires-Python: >=3.11
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: jsonschema<5,>=4.23
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
30
|
+
Requires-Dist: PyYAML>=6.0; extra == "dev"
|
|
31
|
+
Requires-Dist: ruamel.yaml>=0.18; extra == "dev"
|
|
32
|
+
Provides-Extra: official-adapters
|
|
33
|
+
Requires-Dist: semgrep>=1.77.0; extra == "official-adapters"
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
# ScanEval
|
|
37
|
+
|
|
38
|
+
ScanEval evaluates structured security-scanner results against a versioned plan and
|
|
39
|
+
supplied review decisions. Import the Python package and call
|
|
40
|
+
`scaneval.evaluate(plan, result, decisions)` to produce an evaluation report offline.
|
|
41
|
+
The same distribution includes a CLI, versioned data contracts, replay, local reports,
|
|
42
|
+
and optional tracing through `scaneval.observer`.
|
|
43
|
+
|
|
44
|
+
**Alpha version: `2.0.0a1`.** No benchmark results or scanner comparisons are published.
|
|
45
|
+
The selected corpus contains 50 CVEs, but fixed controls remain unvalidated and scanner
|
|
46
|
+
miss rates remain unmeasured. Live scanner integrations need separate installations and
|
|
47
|
+
configuration. The default SV-Agent harness pin cannot yet produce a completed
|
|
48
|
+
source-scan score. See the
|
|
49
|
+
[current capabilities and limits](https://github.com/Har1sh-k/scaneval/blob/main/README.md#current-limits).
|
|
50
|
+
|
|
51
|
+
## Install and evaluate
|
|
52
|
+
|
|
53
|
+
Requires Python 3.11 or newer. Source materialization also requires Git. From a virtual
|
|
54
|
+
environment on macOS or Linux:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
python -m pip install "scaneval==2.0.0a1"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Load your saved ScanEval evaluation plan, normalized scan result, and review decisions:
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
import json
|
|
64
|
+
from pathlib import Path
|
|
65
|
+
import scaneval
|
|
66
|
+
|
|
67
|
+
plan = json.loads(Path("plan.json").read_text(encoding="utf-8"))
|
|
68
|
+
result = json.loads(Path("result.json").read_text(encoding="utf-8"))
|
|
69
|
+
decisions = json.loads(Path("decisions.json").read_text(encoding="utf-8"))
|
|
70
|
+
|
|
71
|
+
report = scaneval.evaluate(plan, result, decisions)
|
|
72
|
+
print(json.dumps(report, indent=2))
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Scoring requires structured saved records and supplied finding-review decisions bound to
|
|
76
|
+
those records. The plan assigns targets and controls; the decisions say which findings
|
|
77
|
+
establish their alleged issues. Unreviewed findings remain unresolved. The evaluation API
|
|
78
|
+
validates these inputs and computes scores; producing scanner findings and adjudicating
|
|
79
|
+
natural-language allegations are separate steps.
|
|
80
|
+
|
|
81
|
+
## Try the offline demo
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
scaneval demo demo-run
|
|
85
|
+
scaneval replay demo-run --output demo-replay.json
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Open `demo-run/report.html` locally. The demo uses fabricated evaluator fixtures and
|
|
89
|
+
makes no scanner or model calls. Output paths must be new. Run `scaneval --help` for
|
|
90
|
+
commands; the
|
|
91
|
+
[execution guide](https://github.com/Har1sh-k/scaneval/blob/main/docs/INITIAL_BUILD.md)
|
|
92
|
+
explains scanner configuration, review, and saved evidence.
|
|
93
|
+
|
|
94
|
+
## Instrument a Python harness
|
|
95
|
+
|
|
96
|
+
The public Python SDK is available from `scaneval.observer`. Emit events at the model,
|
|
97
|
+
tool, context, and finding boundaries your harness exposes:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from scaneval.observer import Observer
|
|
101
|
+
|
|
102
|
+
events = []
|
|
103
|
+
observer = Observer(
|
|
104
|
+
mode="metadata",
|
|
105
|
+
sink=events.append,
|
|
106
|
+
run_id="example-run",
|
|
107
|
+
producer_id="my-harness",
|
|
108
|
+
)
|
|
109
|
+
observer.emit(
|
|
110
|
+
type="model.request",
|
|
111
|
+
capture_status="complete",
|
|
112
|
+
call_id="call-1",
|
|
113
|
+
metadata={"model": "example-model"},
|
|
114
|
+
)
|
|
115
|
+
observer.flush()
|
|
116
|
+
observer.close()
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
This example records one event in memory; it calls no model. Recording defaults to
|
|
120
|
+
`off` unless the caller chooses a mode. Capture gaps remain explicit, and traces cannot
|
|
121
|
+
prove hidden reasoning. The
|
|
122
|
+
[Observer SDK guide](https://github.com/Har1sh-k/scaneval/blob/main/docs/OBSERVER_SDK.md)
|
|
123
|
+
describes sinks, recording modes, and capture states. This Observer is part of `scaneval`;
|
|
124
|
+
no separate Python Observer distribution is needed. A
|
|
125
|
+
[TypeScript SDK](https://github.com/Har1sh-k/scaneval/tree/main/sdk/typescript)
|
|
126
|
+
shares the trace contract and remains available as source. This release publishes only
|
|
127
|
+
the Python `scaneval` distribution.
|
|
128
|
+
|
|
129
|
+
## Cases, datasets, and execution limits
|
|
130
|
+
|
|
131
|
+
Start with the
|
|
132
|
+
[selected CVE corpus](https://github.com/Har1sh-k/scaneval/blob/main/corpus/diverse/README.md),
|
|
133
|
+
[bring your own corpus](https://github.com/Har1sh-k/scaneval/blob/main/docs/BRING_YOUR_OWN_CORPUS.md),
|
|
134
|
+
or [dataset adapters](https://github.com/Har1sh-k/scaneval/blob/main/docs/DATASET_ADAPTERS.md).
|
|
135
|
+
Scoring uses supplied review decisions; unreviewed findings remain unresolved.
|
|
136
|
+
|
|
137
|
+
The local execution backend runs scanners as the operator and enforces no isolation.
|
|
138
|
+
The OCI backend supports specific adapters and configurations; read the
|
|
139
|
+
[threat model](https://github.com/Har1sh-k/scaneval/blob/main/docs/THREAT_MODEL.md)
|
|
140
|
+
before live runs. Keep scanner outputs, private findings, credentials, and content traces
|
|
141
|
+
local.
|
|
142
|
+
|
|
143
|
+
[Source and issues](https://github.com/Har1sh-k/scaneval) are on GitHub. ScanEval is
|
|
144
|
+
[MIT licensed](https://github.com/Har1sh-k/scaneval/blob/main/LICENSE); external scanners
|
|
145
|
+
and source snapshots retain their own licenses.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# ScanEval
|
|
2
|
+
|
|
3
|
+
ScanEval evaluates security scanners on versioned cases and records how instrumented harnesses reach their findings. Scoring uses structured outputs and recorded review decisions. Static corpus labels can be assessed separately through evidence-bound machine review.
|
|
4
|
+
|
|
5
|
+
> Alpha (`2.0.0a1`). No benchmark results are published. The [selected CVE corpus](corpus/diverse/README.md) contains 50 CVEs from 32 repositories across seven target languages: 9 Critical, 13 High, 20 Medium and 8 Low by the documented published-CVSS policy. Its 48 pinned vulnerable exports have mechanical checks and a separate machine-review workflow for static labels. Selection emphasizes contextual security reasoning; scanner miss rates remain unmeasured. Fixed controls remain unvalidated. Scanner outputs and traces stay local.
|
|
6
|
+
|
|
7
|
+
## Python alpha package
|
|
8
|
+
|
|
9
|
+
The planned PyPI release is `scaneval==2.0.0a1`; publication is pending. The Python distribution includes the evaluation API, CLI, and optional tracing through `scaneval.observer`. After publication, install the alpha:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
python -m pip install scaneval==2.0.0a1
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
import scaneval
|
|
17
|
+
|
|
18
|
+
report = scaneval.evaluate(plan, result, decisions)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The arguments are structured saved ScanEval records: an evaluation plan, normalized scanner result, and supplied review decisions bound to those records. Scoring is offline; scanner execution and finding adjudication are separate steps. See the [Python package guide](README_PYPI.md) for loading the records and the [Observer guide](docs/OBSERVER_SDK.md) for optional instrumentation. The TypeScript Observer remains available as source; this release publishes only the Python `scaneval` distribution. [Release instructions](docs/RELEASING.md) cover artifact verification and PyPI publishing. Use a source checkout for the corpus, examples, and development workflow below.
|
|
22
|
+
|
|
23
|
+
## Quick start
|
|
24
|
+
|
|
25
|
+
Requires Git and Python 3.11+. Live runs also need the configured scanner.
|
|
26
|
+
From a terminal on macOS or Linux:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
git clone https://github.com/Har1sh-k/scaneval.git
|
|
30
|
+
cd scaneval
|
|
31
|
+
python3 -m venv .venv
|
|
32
|
+
source .venv/bin/activate
|
|
33
|
+
python -m pip install -e ".[dev]"
|
|
34
|
+
scaneval demo results/diagnostic-demo
|
|
35
|
+
scaneval replay results/diagnostic-demo --output results/diagnostic-replay.json
|
|
36
|
+
# Open results/diagnostic-demo/report.html locally.
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The demo uses fabricated evaluator fixtures, not a live scanner or admitted CVEs. It exercises scoring without model calls. Output paths must be new.
|
|
40
|
+
|
|
41
|
+
Start with the [CVE corpus](corpus/diverse/README.md) for the 50 curated cases, severity sources, selection rationale and machine review. [Dataset adapters](docs/DATASET_ADAPTERS.md) add separate PR-review and CVE-detection tracks for AACR-Bench, ReviewBench, Martian, OpenSSF, and your own datasets. The [execution guide](docs/INITIAL_BUILD.md#run-configuration) explains scanner configuration and review. To supply your own security fixes, findings, or documents as case packs, follow [bring your own corpus](docs/BRING_YOUR_OWN_CORPUS.md).
|
|
42
|
+
|
|
43
|
+
## Evaluation
|
|
44
|
+
|
|
45
|
+
One scan can cover several targets on the same input. A finding needs an accepted security allegation, not just a matching line and vulnerability category. Unreviewed findings remain unresolved; they are not automatically false positives.
|
|
46
|
+
|
|
47
|
+
The scorer reports known-target detection, recall within review budgets, and false allegations against assigned fixed/safe controls. Reviewed precision is estimated separately, from a seeded, human-reviewed sample of delivered claims. Unavailable controls do not become a zero false-alarm rate. Errors and incomplete scans remain distinct from successful scans with no findings. Recorded decisions can be replayed offline.
|
|
48
|
+
|
|
49
|
+
| Command | Purpose |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `scaneval validate <kind> <path>` | Validate a versioned contract. |
|
|
52
|
+
| `scaneval demo <new dir>` | Create the fabricated conformance bundle. No scanner or model runs. |
|
|
53
|
+
| `scaneval score --plan --result --decisions` | Score separately stored records. |
|
|
54
|
+
| `scaneval replay <bundle>` | Recompute a saved bundle offline. |
|
|
55
|
+
| `scaneval report <bundle> --output` | Render a standalone HTML report. |
|
|
56
|
+
| `scaneval investigate <run> --output <new-directory>` | Export a local investigation view and JSON with judgments, trace links, capture states, and artifact bindings ([guide](docs/INVESTIGATION.md)). |
|
|
57
|
+
| `scaneval corpus init\|add-snapshot\|import\|validate\|approve\|admit\|disposition` | Prepare case packs, run mechanical checks, and record explicit reviews and admissions. |
|
|
58
|
+
| `scaneval corpus machine-prepare\|machine-record\|machine-check` | Prepare evidence packets and validate machine judgments of static CVE labels without HITL. |
|
|
59
|
+
| `scaneval corpus add-change-set\|pr-scope\|canonical` | Declare a base/head change set, state which targets and controls are scored in its PR review, and group records by canonical root cause. |
|
|
60
|
+
| `scaneval plan --pack --snapshot-id --tree-hash --output` | Build an evaluation plan for one materialized input, or with `--mode pr --change-set-id` and the hashes that identify it, the PR plan of a change set. |
|
|
61
|
+
| `scaneval run <config> --output <new dir>` | Run a frozen configuration and save its artifacts. |
|
|
62
|
+
| `scaneval matrix freeze\|run\|report` | Freeze and execute the three evaluation conditions, retaining missingness and paired effects ([guide and diagnostic fixture](docs/EXPERIMENT_MATRIX.md)). |
|
|
63
|
+
| `scaneval dataset list\|fetch\|import\|validate\|inspect` | Load a pinned public dataset, native JSON, or an installed Python dataset adapter ([guide](docs/DATASET_ADAPTERS.md)). |
|
|
64
|
+
| `scaneval benchmark plan\|run\|judge-packet\|score` | Evaluate imported datasets with existing scanner adapters, frozen schedules, and supplied machine judgments. |
|
|
65
|
+
| `scaneval blinding check\|review` | Dry-run a metadata blinding map against its snapshots, and record a named review of it. |
|
|
66
|
+
| `scaneval import sarif <log> --pack --snapshot-id --tree-hash --system-id --output` | Import one run of a saved SARIF 2.1.0 log into a new bundle for review, offline. |
|
|
67
|
+
| `scaneval review init\|record\|approve\|status` | Prepare and record the review of an invocation bundle. |
|
|
68
|
+
| `scaneval diagnose context-coverage <bundle>` | Compare captured context spans with labeled targets. Does not change scores. |
|
|
69
|
+
| `scaneval condition <bundle>... [--output]` | Inspect saved condition evidence and separate system/policy/status coverage, offline. |
|
|
70
|
+
| `scaneval aggregate <run dir>... --output` | Weight every scheduled assignment of saved runs into corpus metrics with cluster-bootstrap intervals. |
|
|
71
|
+
| `scaneval severity <run dir>... --pack --output [--html]` | Compare adjudicated claimed severity with reference CVSS, with coverage, provenance and offline replay. See [severity calibration](docs/SEVERITY.md). |
|
|
72
|
+
| `scaneval aggregate <run dir>... --by-condition --output` | Report separate condition/status/policy strata, complete missingness, and descriptive target outcomes. |
|
|
73
|
+
| `scaneval compare <run dir>... --baseline --candidate --output` | Compare two systems assigned the same frozen work, with paired intervals. Decides no promotion. |
|
|
74
|
+
| `scaneval precision sample\|queue\|record\|estimate` | Sample delivered claims from saved runs, record human reviews, and estimate reviewed precision. Does not change scores. |
|
|
75
|
+
| `scaneval gate --policy --comparison --output` | Hold a comparison, and optionally precision estimates, to a gate policy and write a pass, fail, or inconclusive decision with every requirement explained. Promotes nothing. |
|
|
76
|
+
|
|
77
|
+
Run `scaneval <command> --help` for required arguments. `corpus validate --snapshot-id`, `blinding check`, `run`, `dataset fetch`, and `benchmark run` can reach the network; contacts depend on the configured sources and scanners. Exit code `2` means the command could not be carried out, `1` means it ran and reports a negative result, and `0` means it ran and reports nothing wrong. None certifies that a security label is correct.
|
|
78
|
+
|
|
79
|
+
## Scanners and visibility
|
|
80
|
+
|
|
81
|
+
The current adapters are `semgrep` with pinned local rules, `llm-harness` for an own-harness integration that drives the Fieldglass/SV-Agent engine directly, `deepsec` for the third-party scanner, and an initial `runsortie` integration that retains the evidence contract for full RunSortie orchestration: its Fieldglass engine, a primary agent's packet review, a separate challenger model, and RunSortie's own evidence commit. The production RunSortie route is currently fail-closed, as described below. `semgrep` (`--baseline-commit`) and `deepsec` (`process --diff`) also review a native PR request that names a base and a head commit in the scanner's workspace; [Current capabilities](docs/INITIAL_BUILD.md) says what each does with it. Scanner CLIs are installed separately. The optional `official-adapters` extra installs Semgrep; a reproducible comparison must also pin its version and rules. To build or review another execution integration, use the [scanner adapter builder skill](skills/scanner-adapter-builder/SKILL.md); it covers native workflow evidence and verification, not dataset import or corpus-label review.
|
|
82
|
+
|
|
83
|
+
The **ScanEval Observer SDK**, available in Python and TypeScript, records model calls, tool use, supplied context, and finding lifecycle events at instrumented boundaries. It is opt-in. Native collectors can import Claude Code and Codex records without claiming to see decisions the harness never exposed. Capture gaps remain explicit; traces cannot prove hidden reasoning or absence of memorization.
|
|
84
|
+
|
|
85
|
+
For the TypeScript SDK and harness driver:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm ci --prefix sdk/typescript
|
|
89
|
+
npm run build --prefix sdk/typescript
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
On its default `local` runtime the `llm-harness` adapter needs a local harness checkout and the built SDK; its `oci_image` runtime uses the harness and observer SDK in its pinned image instead ([SV-Agent image runtime](docs/OPEN_CONTEXT.md#sv-agent-image-runtime)). The `deepsec` adapter needs an installed scanner workspace; it runs the scanner in a separate private workspace. The initial `runsortie` adapter parses the exact RunSortie `af8f240…`/`0.1.0` configuration and retains a deeply checked native evidence/completion implementation, but secure v1 has no runnable direct-agent boundary. Preparation records the requested routes as not runnable, and scan returns `unsupported` before checkout identity/content inspection or launch. Its deterministic fake and fabricated-agent conformance paths exercise the retained commit/tree, packet, prompt, journal, budget, snapshot, and reconciliation checks only; they are not live readiness ([details and limits](docs/INITIAL_BUILD.md#adapters)).
|
|
93
|
+
|
|
94
|
+
Guides: [Observer SDK](docs/OBSERVER_SDK.md), [native CLI collectors](docs/COLLECTORS.md), [context-coverage diagnostics](docs/DIAGNOSTICS.md).
|
|
95
|
+
|
|
96
|
+
Implementation review: [Inspect AI visibility and observability comparison](docs/INSPECT_OBSERVABILITY_COMPARISON.md).
|
|
97
|
+
|
|
98
|
+
## Current limits
|
|
99
|
+
|
|
100
|
+
- Full-scan execution, native PR execution (a case pack declares a change set and states which targets and controls each PR review scores), case packs, source export, review, scoring, replay, and reports are implemented.
|
|
101
|
+
- Each run freezes its evaluation schedule (every assignment, pre-registered plan, and vulnerable/fixed pair) before it prepares an input. An input it cannot prepare is recorded with its skipped assignments, and the other inputs still run.
|
|
102
|
+
- The `metadata_blinded` profile applies reviewed token edits to documentation and display metadata. The `identity_reduced` profile adds hash-pinned identity-document/instruction removals and narrowly verified package URL leaf edits. An explicit strict policy validates answer coverage and records skipped transformations and residual cues; a profile name alone does not establish an experimental condition. Runtime code, dependency declarations, licenses, build/CI/security configuration, and source paths stay intact. Originals and transformation manifests remain evaluator-side. See [identity reduction](docs/IDENTITY_REDUCTION.md) for the reviewed workflow and limits.
|
|
103
|
+
- A saved SARIF 2.1.0 log imports offline into a bundle that review, score, and replay read; its execution report is recorded unverified ([SARIF import](docs/SARIF_IMPORT.md)). Other saved vendor formats have no importer.
|
|
104
|
+
- A system whose 2.1 run configuration selects the `oci` execution backend runs each scanner process in a locked-down Docker container from a digest-pinned image, with its network policy enforced (`unrestricted` is recorded as unenforced). `semgrep` can run under it, and so can the SV-Agent (`securevibes-agent`) harness through `llm-harness` with `config.runtime: "oci_image"`. That image runtime carries out full scans only, and only under the `oci` backend with the `public_research` policy; it is refused anywhere else. `deepsec`, `runsortie`, and `llm-harness` on `config.runtime: "local"` (a host checkout), are refused under `oci`. Under the `local` execution backend, systems run as the operator, unenforced. Implemented isolation does not show that a live-model scan has been validated or completed: at the default harness pin a scan still cannot reach a completed source-scan score, and no broad benchmark readiness is claimed. See [the threat model](docs/THREAT_MODEL.md) and [SV-Agent image runtime](docs/OPEN_CONTEXT.md#sv-agent-image-runtime).
|
|
105
|
+
- [Closed-book standard](docs/CLOSED_BOOK.md) preserves repository identity and classifies saved history, retrieval, network, and provider evidence as attested, declared-only, failed, or unavailable. A local policy declaration never attests isolation.
|
|
106
|
+
- The explicit `open_context` condition supplies bounded original ancestor history and controlled, recorded public retrieval under OCI. It measures assisted investigation; known-vulnerability retrieval may contribute to detection. History/capture coverage and provider visibility gaps stay visible, and its results remain separate from closed-book and identity-reduced observations ([guide and runnable fixture](docs/OPEN_CONTEXT.md)).
|
|
107
|
+
- `runsortie` has been validated only deterministically: by a stand-in that follows RunSortie's scan control flow, and by an opt-in run of the real pinned CLI with fabricated engine and agents. It has not run against a live model. Secure v1 has no runnable native direct-agent route: preparation records `runnable: false`, and invocation returns `unsupported` with an empty command before checkout identity/content inspection, credentials, probes, adapter-private state, or any RunSortie/agent process. Codex persists an API-key credential file readable by workspace tools; Claude 2.1.310 can fetch and apply remote managed helpers and additional filesystem roots; Cursor and Gemini likewise lack the externally attestable process/filesystem sandbox plus endpoint-specific egress control required here. The retained fake/conformance path tests native evidence and completion logic only and cannot be enabled by configuration. Unsupported assignments remain visible in evaluation accounting.
|
|
108
|
+
- Native PR review runs each scanner's own diff workflow over a neutral two-commit history of a declared change set: the harness's pr mode for `llm-harness`, `--baseline-commit` for `semgrep`, and `process --diff` for `deepsec`. An adapter without a PR mode is recorded as unsupported and stays in every denominator, and a full scan of the head never stands in for a PR review ([native PR review](docs/INITIAL_BUILD.md#native-pr-review)).
|
|
109
|
+
- Corpus aggregation and paired comparison read saved, frozen run directories ([aggregation](docs/AGGREGATION.md)). They compute no reviewed precision and decide no promotion.
|
|
110
|
+
- Reviewed precision comes only from people reviewing a seeded probability sample of delivered claims ([precision guide](docs/PRECISION.md)). It is not a repository false-positive rate.
|
|
111
|
+
- A gate decision holds a saved comparison to a policy you write and says whether its requirements held ([gate guide](docs/GATE.md)). It promotes nothing: the workflow that owns the harness decides.
|
|
112
|
+
- Fifty CVEs are selected in the [diverse corpus](corpus/diverse/README.md), including GitLab, Kubernetes, Airflow, Langflow, LangChain and Twenty. The [Astra-authored review skill](skills/cve-corpus-review/SKILL.md) supports machine review without a human gate; shared deployment context, claim-specific runtime validation and scanner preflight remain separate work. Java and Ruby are accepted by the corpus contract, but the current adapters still record them as unsupported. No representative benchmark or scanner comparison is claimed.
|
|
113
|
+
- External [dataset tracks](corpus/benchmarks/README.md) provide 469 PR cases and 223 additional OpenSSF CVE cases. Their publisher labels remain separate from the curated corpus. Dataset benchmark runs use the local execution backend; scoring measures reference coverage and named fixed controls, not true precision or an official upstream leaderboard score. Missing or uncertain semantic judgments remain explicit.
|
|
114
|
+
|
|
115
|
+
[Current capabilities](docs/INITIAL_BUILD.md) describes the implementation. [Design decisions](docs/DESIGN_DECISIONS.md) and [evaluation math](docs/EVALUATION_MATH.md) describe the broader contract and planned work.
|
|
116
|
+
|
|
117
|
+
## Development
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
python -m pytest -q
|
|
121
|
+
npm test --prefix sdk/typescript
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Tests use local fixtures and mock model runners. They do not launch paid model evaluations. CI checks Python 3.11, 3.13, and 3.14, the TypeScript SDK, and demo/replay from an installed wheel.
|
|
125
|
+
|
|
126
|
+
| Path | Contents |
|
|
127
|
+
|---|---|
|
|
128
|
+
| `src/scaneval/` | CLI, corpus, runner, evaluator, adapters, collectors, and Python Observer |
|
|
129
|
+
| `src/scaneval/schemas/` | Versioned evaluation contracts |
|
|
130
|
+
| `sdk/typescript/` | TypeScript Observer SDK |
|
|
131
|
+
| `schema/v2/` | Shared trace contract and conformance fixtures |
|
|
132
|
+
| `corpus/diverse/` | 50 selected CVEs, sourced severity distribution, pinned sources and machine review |
|
|
133
|
+
| `scripts/sanitize_native_trace.py` | Scrub native records for collector fixtures |
|
|
134
|
+
| `tests/` | Contract, scoring, runner, adapter, Observer, and collector tests |
|
|
135
|
+
| `docs/` | Public design and usage guides |
|
|
136
|
+
|
|
137
|
+
Generated runs belong under ignored `results/`; source caches belong under ignored `.repos/`. Do not commit scanner outputs, private findings, credentials, or content traces.
|
|
138
|
+
|
|
139
|
+
## License
|
|
140
|
+
|
|
141
|
+
[MIT](LICENSE). Source snapshots and external scanners retain their own licenses.
|
|
142
|
+
|
|
143
|
+
### Model cutoffs and recent CVE research
|
|
144
|
+
|
|
145
|
+
Inspect sourced provider cutoffs and check reviewed public-evidence chronology with
|
|
146
|
+
`scaneval model-cutoffs list` and `scaneval model-cutoffs check`. The read-only
|
|
147
|
+
helper preserves unknown dates and routes, distinguishes training from knowledge
|
|
148
|
+
cutoffs, and reports the 2 Low / 3 Medium / 3 High / 2 Critical research target.
|
|
149
|
+
See [model cutoffs](docs/MODEL_CUTOFFS.md) for usage, evidence limits, and maintenance.
|