sourcecode 4.8.0__tar.gz → 4.9.1__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.
- {sourcecode-4.8.0 → sourcecode-4.9.1}/CHANGELOG.md +40 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/PKG-INFO +24 -12
- {sourcecode-4.8.0 → sourcecode-4.9.1}/README.md +23 -11
- {sourcecode-4.8.0 → sourcecode-4.9.1}/pyproject.toml +1 -1
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/__init__.py +1 -1
- sourcecode-4.9.1/src/sourcecode/audit_report.py +158 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/cli.py +287 -18
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/environment_resolution.py +88 -6
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/migrate_check.py +307 -1
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/non_coverage.py +12 -10
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/posture.py +2 -1
- sourcecode-4.9.1/src/sourcecode/provenance.py +202 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/risk.py +234 -16
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/rule_catalog.py +6 -1
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/sarif.py +12 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/spring_security_audit.py +338 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/.gitignore +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/.ruff.toml +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/CLAUDE.md +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/CONTRIBUTING.md +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/LICENSE +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/SECURITY.md +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/raw +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/scripts/compare_integration_engines.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/scripts/customer_smoke_test.sh +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/scripts/generate_jdk_exports.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/scripts/perf_harness.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/archetype.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/architectural_baseline.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/architectural_delta.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/baseline_autocapture.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/cache.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/cache_model.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/call_surface.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/caller_metrics.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/caller_reach.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/canonical_ir.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/chain_rules.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/change_plan.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/cir_graphs.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/classifier.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/client_calls.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/compare.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/constraint_diff.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/context_cache.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/context_graph.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/contract_diff.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/contract_init.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/data_exposure.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/data_labels.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/defect_identity.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/degradation.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/deployment_prefix.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/dynamic_argument_surface.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/endpoint_literals.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/endpoint_metrics.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/envelope.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/error_schema.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/evidence_provider.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/explain.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/facts/__init__.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/facts/registry.json +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/file_chunker.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/filter_surface.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/format_contract.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/fqn_utils.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/git_checkout.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/graph_evidence.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/hibernate_strat.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/identity_fallback.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/integration_coordinates.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/jdk_exports.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/license.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/mcp/__init__.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/mcp/onboarding/applier.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/mcp/onboarding/backup.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/mcp/onboarding/detector.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/mcp/onboarding/planner.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/mcp/orchestrator.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/mcp/registry.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/mcp/runner.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/mcp/server.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/mcp_nudge.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/migration_blast.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/openapi_surface.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/openrewrite_recipe.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/output_budget.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/parse_cache.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/path_admission.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/path_filters.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/perf.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/pipe_contract.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/pr_impact.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/prepare_context.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/progress.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/readiness_timeline.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/reconciliation.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/redactor.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/reference_facts.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/release_info.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/remedies.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/rename_refactor.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/repository_ir.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/__init__.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/context.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/errors.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/executor.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/planner.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/query.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/request.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/resolution.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/result.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/retriever.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/runtime.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/steps.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/steps_graph.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/steps_impact.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/steps_intf.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/steps_struct.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/retrieval/steps_txsec.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/ris.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/scanner.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/schema.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/schemas/envelope-v1.schema.json +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/security_config.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/security_config_scan.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/security_posture.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/semantic_impact_engine.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/semantic_integration_engine.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/semantic_services.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/serializer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/servlet_surface.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/source_text.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/spring_event_topology.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/spring_findings.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/spring_impact.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/spring_model.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/spring_profiles.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/spring_properties.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/spring_semantic.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/spring_tx_analyzer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/target_admission.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/test_gap_ranking.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/test_sources.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/token_estimate.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/type_usage_surface.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/validation_inference.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/validation_surface.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/verify_edit.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/verify_repo.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/verify_rules.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/version_check.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/src/sourcecode/workspace.py +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/supabase/functions/README.md +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/supabase/functions/get-license/index.ts +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/supabase/functions/telemetry/index.ts +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/supabase/sql/license_event_ordering.sql +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/supabase/sql/licensing_schema.sql +0 -0
- {sourcecode-4.8.0 → sourcecode-4.9.1}/supabase/sql/telemetry_events.sql +0 -0
|
@@ -2,6 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [4.9.1] — 2026-08-04
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Java LTS/licensing inventory in `migrate-check`.** Reports Java 8/11/17/21/25
|
|
10
|
+
evidence from Maven/Gradle, local runtime hints and container files, target-LTS
|
|
11
|
+
blockers via `--target-jdk`, and explicit Oracle JDK licensing-review signals
|
|
12
|
+
without changing migration readiness scoring.
|
|
13
|
+
- **Claim provenance ledger.** `risk`, `enrich`, `migrate-check`, `audit-report`
|
|
14
|
+
and `prepare-context` now emit `evidence_manifest` with stable claim IDs,
|
|
15
|
+
source paths/lines, command inputs, ASK version, git HEAD and freshness metadata.
|
|
16
|
+
|
|
17
|
+
## [4.9.0] — 2026-08-04
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- **Custom AOP security gate audit.** `spring-audit` now emits `GATE-001` through
|
|
22
|
+
`GATE-004` for custom authorization gates detected by the security posture
|
|
23
|
+
authority: Spring AOP proxy bypass, fail-open advice, disabled/tautological
|
|
24
|
+
annotation attributes, and fragile positional/reflection binding.
|
|
25
|
+
- **Deployment evidence for runtime posture.** `posture --resolve-environments`
|
|
26
|
+
accepts `--env-file FILE` and binds explicit deployment profile evidence to
|
|
27
|
+
`decided_case` while keeping repository defaults as lower-priority evidence.
|
|
28
|
+
- **Bounded HTTP-input-to-sink flow in `risk`.** The `query_construction` factor
|
|
29
|
+
now distinguishes a proven bounded path from annotated HTTP input, through
|
|
30
|
+
positional calls in repository Java sources, into known concatenated query
|
|
31
|
+
sinks. General taint remains explicitly outside scope.
|
|
32
|
+
- **SARIF triage table for `enrich`.** `enrich --table` now provides
|
|
33
|
+
auditor-facing filtering by scanner rule, composed band and top-N while
|
|
34
|
+
leaving JSON as the contract.
|
|
35
|
+
- **Signed audit report bundle.** New experimental `audit-report` command packages
|
|
36
|
+
existing `risk` and `posture` evidence into JSON or Markdown, with optional
|
|
37
|
+
HMAC-SHA256 signing over the canonical JSON payload via `--sign-key`.
|
|
38
|
+
|
|
39
|
+
### Documentation
|
|
40
|
+
|
|
41
|
+
- README, user guide and root `ask --help` now list `audit-report`, the 4.9.0
|
|
42
|
+
version, `posture --env-file`, `enrich --table`, bounded `risk` flow and the
|
|
43
|
+
`GATE-*` rule family.
|
|
44
|
+
|
|
5
45
|
## [4.8.0] — 2026-08-04
|
|
6
46
|
|
|
7
47
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.9.1
|
|
4
4
|
Summary: Persistent structural context and ultra-fast repeated analysis for AI coding agents
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Keywords: agents,ai,codebase,context,developer-tools,llm
|
|
@@ -42,7 +42,7 @@ Description-Content-Type: text/markdown
|
|
|
42
42
|
|
|
43
43
|
**Context · Impact · Migration · Architecture · Review — everything from one structural model.**
|
|
44
44
|
|
|
45
|
-

|
|
46
46
|

|
|
47
47
|
|
|
48
48
|
> **ASK Engine** is the product. The CLI command is **`ask`**. The legacy **`sourcecode`**
|
|
@@ -97,7 +97,7 @@ brew tap haroundominique/sourcecode && brew install sourcecode
|
|
|
97
97
|
# pip / pipx
|
|
98
98
|
pipx install sourcecode # or: pip install sourcecode
|
|
99
99
|
|
|
100
|
-
ask version # ask 4.
|
|
100
|
+
ask version # ask 4.9.1 — and, on a build that has aged,
|
|
101
101
|
# how many releases have probably shipped since
|
|
102
102
|
```
|
|
103
103
|
|
|
@@ -137,8 +137,9 @@ ask endpoints /path/to/repo
|
|
|
137
137
|
# CGLIB no-op), security surface, request-body validation.
|
|
138
138
|
ask spring-audit /path/to/repo
|
|
139
139
|
|
|
140
|
-
# Spring Boot 2→3 readiness
|
|
140
|
+
# Spring Boot 2→3 readiness plus Java LTS/licensing inventory.
|
|
141
141
|
ask migrate-check /path/to/repo --compact
|
|
142
|
+
# Add --target-jdk 25 to make the LTS route explicit.
|
|
142
143
|
```
|
|
143
144
|
|
|
144
145
|
**Then the three that finish the sentence the four above start.** A profile-set answer stays
|
|
@@ -260,10 +261,10 @@ figures and the authority behind each — and an axis this build cannot measure
|
|
|
260
261
|
weighted 1.0 and named in `blind_axes` rather than silently treated as safe. Measured on a
|
|
261
262
|
field case: a defect both `spring-audit` and `impact-chain` called *medium* composes to
|
|
262
263
|
**high (8.06)** once *reachable unauthenticated* and *writes to the database* are in it.
|
|
263
|
-
The last two factors describe the input path
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
264
|
+
The last two factors describe the input path: a query assembled by concatenation, a bounded
|
|
265
|
+
HTTP-input-to-query-sink path when ASK can prove one, and a route accepting a body with no
|
|
266
|
+
declared constraint. General taint remains `NC-001` and is published in the payload's own
|
|
267
|
+
`non_coverage` block.
|
|
267
268
|
`ask risk .` · `ask risk . --min-band high` · `ask risk . --limit 10`
|
|
268
269
|
→ [reference](docs/USER_GUIDE.md)
|
|
269
270
|
|
|
@@ -289,7 +290,7 @@ experimental: both are true, and they are two different facts.
|
|
|
289
290
|
|---|---|---|
|
|
290
291
|
| **core** | contract stable within a major — safe to gate CI on | `endpoints` · `spring-audit` · `migrate-check` · `impact` · `impact-chain` · `pr-impact` · `verify` |
|
|
291
292
|
| **supported** | maintained; fields are added, never removed without a major | every command not named in another row |
|
|
292
|
-
| **experimental** | shape may change in a minor — do not gate CI on it | `risk` · `enrich` · `data-exposure` · `migrate-recipe` · `posture` · `archetype` |
|
|
293
|
+
| **experimental** | shape may change in a minor — do not gate CI on it | `risk` · `enrich` · `audit-report` · `data-exposure` · `migrate-recipe` · `posture` · `archetype` |
|
|
293
294
|
| **parked** | kept working, no longer developed | `retrieve` |
|
|
294
295
|
|
|
295
296
|
The same table is printed by `ask --help`, and both are generated from one authority
|
|
@@ -307,12 +308,13 @@ from it.
|
|
|
307
308
|
|---|---|---|---|
|
|
308
309
|
| `posture` | experimental | which beans a profile set wires, and how effective endpoint access differs between two sets | the most differentiated capability here |
|
|
309
310
|
| `risk` | experimental | what each defect actually costs, once reach, access, write effect and the shape of the input path are in it | `defect_severity × reachability × auth_verdict × write_effect × query_construction × input_constraints`; every factor names its authority; `--table --rule SEC-008 --band high --top-n 20` gives audit triage without `jq` |
|
|
310
|
-
| `enrich` | experimental | another scanner's SARIF findings, ranked by what this repository does with them | `--sarif <log>`;
|
|
311
|
+
| `enrich` | experimental | another scanner's SARIF findings, ranked by what this repository does with them | `--sarif <log>`; same composition as `risk`, with `--table --rule <id> --band high --top-n 20` for triage |
|
|
312
|
+
| `audit-report` | experimental | human audit bundle over existing `risk` + `posture` evidence, optionally signed | includes `evidence_manifest` claim provenance; `--format markdown`; `--sign-key <file>` signs canonical JSON with HMAC-SHA256 |
|
|
311
313
|
| `migrate-recipe` | experimental | the migration report as the OpenRewrite recipe that applies it | only recipes a finding named; the manual remainder published beside them; writes nothing without `--write`, and never a runnable command for an empty recipe list |
|
|
312
314
|
| `data-exposure` | experimental | which routes can carry the data you labelled, and who reaches them | labels declared in `sourcecode.config.json` — never inferred from a name; `signature` and `call_reach` evidence published apart, field-level flow out of scope (NC-008). With nothing declared, `ask data-exposure /path/to/repo` answers `answered: false` and hands back the file, the key and an example to declare — it never reports zero exposed routes |
|
|
313
315
|
| `endpoints` | core | every REST endpoint, effective path, security policy, confidence | Spring MVC + JAX-RS (~65 % recall on JAX-RS sub-resource locators). `--compact` answers the exposure census without the rows; `--servlets` lists the servlet-mounted surface as its own population; `--client-usage` says which routes the TS/JS client in this repository actually calls |
|
|
314
316
|
| `spring-audit` | core | transactional anomalies + security surface + validation gaps | `--ci`, `-f github-comment`; `--table --rule SEC-008 --top-n 20` for human-scale review |
|
|
315
|
-
| `migrate-check` | core | Boot 2→3 readiness: located blockers, per-dimension score, effort | `--blast-radius` orders the re-test plan; `--table --rule MIG-001 --band critical --top-n 20` for blocker triage |
|
|
317
|
+
| `migrate-check` | core | Boot 2→3 readiness + Java LTS/licensing inventory: located blockers, per-dimension score, effort, detected Java 8/11/17/21/25 evidence and explicit licensing-review signals | `--target-jdk 25` sets the target LTS route; `--blast-radius` orders the re-test plan; `--table --rule MIG-001 --band critical --top-n 20` for blocker triage |
|
|
316
318
|
| `impact` / `impact-chain` | core | blast radius of a change, to the endpoints it reaches | target the **interface**, not the `Impl` |
|
|
317
319
|
| `pr-impact` | core | the same, scoped to a PR diff | gating command: `--fail-on`, exit codes |
|
|
318
320
|
| `verify` | core | does the repo satisfy its declared contracts, **relative to a baseline** | `.ask/contracts.yml`; exit 0/1/2 |
|
|
@@ -356,7 +358,7 @@ reading JSON sees the same boundary a buyer reads here.
|
|
|
356
358
|
|
|
357
359
|
| Not covered | Why | What answers it |
|
|
358
360
|
|---|---|---|
|
|
359
|
-
| **
|
|
361
|
+
| **General request-input-to-sink taint analysis.** | `ask risk` includes a bounded slice for annotated HTTP parameters, positional calls in repository Java sources and known query sinks. Anything broader needs value flow through a program, which is a different analysis with a different failure mode: an unsound one produces confident findings that are wrong, and every claim here is meant to be checkable against the line that produced it. | A dataflow scanner (Semgrep, CodeQL) for complete taint. What this product adds on top is reachability and, for the bounded slice, whether an annotated HTTP input reaches a known concatenated query sink. |
|
|
360
362
|
| **Secrets outside Java, Spring configuration and the deployment descriptors — a Helm value, a CI variable file, a shell script.** | The file population this analyzer reads is the Java source, the Spring configuration convention and the descriptors it already parses to resolve an environment. A secret elsewhere is not missed by a weak rule; it is outside the set of files anything here opens. Narrowed by CL-10: a credential stored in `web.xml` or a Spring XML context IS reported (SEC-007), because those files were already being read. | A dedicated secret scanner over the whole tree (gitleaks, trufflehog). |
|
|
361
363
|
| **Filter-chain order and per-filter URL patterns — the presence of a custom filter is structural only.** | Which filter runs first is decided by bean ordering this analyzer does not resolve. Where two active configurations both match a request, the answer published is `undecided` rather than a guess. | `ask posture --profile <set>` states per endpoint what the readable rules decide and what they leave undecided. |
|
|
362
364
|
| **Known vulnerabilities in dependencies — no CVE database, no version advisory matching.** | Enriching a vulnerability feed is a different product with a different update cadence; a stale embedded database is worse than no database, because it reads as a clean bill of health. | A dependency scanner (Trivy, OWASP Dependency-Check). `impact-chain` then answers which of its findings anything actually reaches. |
|
|
@@ -400,6 +402,16 @@ and that gap is the honest description, not a defect to argue with. `migrate-che
|
|
|
400
402
|
the OpenRewrite recipe each finding carries so the executor that does apply changes has its
|
|
401
403
|
input.
|
|
402
404
|
|
|
405
|
+
**Java LTS/licensing inventory.** `migrate-check` emits `java_lts_inventory` beside the migration
|
|
406
|
+
scores. It reads Maven/Gradle, local runtime hints and container files for Java 8/11/17/21/25
|
|
407
|
+
evidence, reports target-LTS blockers with `--target-jdk`, and marks explicit Oracle JDK evidence
|
|
408
|
+
as `licensing_review_needed`. This is inventory evidence, not legal advice.
|
|
409
|
+
|
|
410
|
+
**Claim provenance ledger.** JSON outputs from `risk`, `enrich`, `migrate-check`,
|
|
411
|
+
`audit-report` and `prepare-context` include `evidence_manifest`: stable claim IDs mapped to
|
|
412
|
+
source paths/lines, command inputs, ASK version, git HEAD and freshness metadata. The manifest
|
|
413
|
+
indexes claims already in the payload; it does not add analysis or certify compliance.
|
|
414
|
+
|
|
403
415
|
|
|
404
416
|
---
|
|
405
417
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**Context · Impact · Migration · Architecture · Review — everything from one structural model.**
|
|
6
6
|
|
|
7
|
-

|
|
8
8
|

|
|
9
9
|
|
|
10
10
|
> **ASK Engine** is the product. The CLI command is **`ask`**. The legacy **`sourcecode`**
|
|
@@ -59,7 +59,7 @@ brew tap haroundominique/sourcecode && brew install sourcecode
|
|
|
59
59
|
# pip / pipx
|
|
60
60
|
pipx install sourcecode # or: pip install sourcecode
|
|
61
61
|
|
|
62
|
-
ask version # ask 4.
|
|
62
|
+
ask version # ask 4.9.1 — and, on a build that has aged,
|
|
63
63
|
# how many releases have probably shipped since
|
|
64
64
|
```
|
|
65
65
|
|
|
@@ -99,8 +99,9 @@ ask endpoints /path/to/repo
|
|
|
99
99
|
# CGLIB no-op), security surface, request-body validation.
|
|
100
100
|
ask spring-audit /path/to/repo
|
|
101
101
|
|
|
102
|
-
# Spring Boot 2→3 readiness
|
|
102
|
+
# Spring Boot 2→3 readiness plus Java LTS/licensing inventory.
|
|
103
103
|
ask migrate-check /path/to/repo --compact
|
|
104
|
+
# Add --target-jdk 25 to make the LTS route explicit.
|
|
104
105
|
```
|
|
105
106
|
|
|
106
107
|
**Then the three that finish the sentence the four above start.** A profile-set answer stays
|
|
@@ -222,10 +223,10 @@ figures and the authority behind each — and an axis this build cannot measure
|
|
|
222
223
|
weighted 1.0 and named in `blind_axes` rather than silently treated as safe. Measured on a
|
|
223
224
|
field case: a defect both `spring-audit` and `impact-chain` called *medium* composes to
|
|
224
225
|
**high (8.06)** once *reachable unauthenticated* and *writes to the database* are in it.
|
|
225
|
-
The last two factors describe the input path
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
226
|
+
The last two factors describe the input path: a query assembled by concatenation, a bounded
|
|
227
|
+
HTTP-input-to-query-sink path when ASK can prove one, and a route accepting a body with no
|
|
228
|
+
declared constraint. General taint remains `NC-001` and is published in the payload's own
|
|
229
|
+
`non_coverage` block.
|
|
229
230
|
`ask risk .` · `ask risk . --min-band high` · `ask risk . --limit 10`
|
|
230
231
|
→ [reference](docs/USER_GUIDE.md)
|
|
231
232
|
|
|
@@ -251,7 +252,7 @@ experimental: both are true, and they are two different facts.
|
|
|
251
252
|
|---|---|---|
|
|
252
253
|
| **core** | contract stable within a major — safe to gate CI on | `endpoints` · `spring-audit` · `migrate-check` · `impact` · `impact-chain` · `pr-impact` · `verify` |
|
|
253
254
|
| **supported** | maintained; fields are added, never removed without a major | every command not named in another row |
|
|
254
|
-
| **experimental** | shape may change in a minor — do not gate CI on it | `risk` · `enrich` · `data-exposure` · `migrate-recipe` · `posture` · `archetype` |
|
|
255
|
+
| **experimental** | shape may change in a minor — do not gate CI on it | `risk` · `enrich` · `audit-report` · `data-exposure` · `migrate-recipe` · `posture` · `archetype` |
|
|
255
256
|
| **parked** | kept working, no longer developed | `retrieve` |
|
|
256
257
|
|
|
257
258
|
The same table is printed by `ask --help`, and both are generated from one authority
|
|
@@ -269,12 +270,13 @@ from it.
|
|
|
269
270
|
|---|---|---|---|
|
|
270
271
|
| `posture` | experimental | which beans a profile set wires, and how effective endpoint access differs between two sets | the most differentiated capability here |
|
|
271
272
|
| `risk` | experimental | what each defect actually costs, once reach, access, write effect and the shape of the input path are in it | `defect_severity × reachability × auth_verdict × write_effect × query_construction × input_constraints`; every factor names its authority; `--table --rule SEC-008 --band high --top-n 20` gives audit triage without `jq` |
|
|
272
|
-
| `enrich` | experimental | another scanner's SARIF findings, ranked by what this repository does with them | `--sarif <log>`;
|
|
273
|
+
| `enrich` | experimental | another scanner's SARIF findings, ranked by what this repository does with them | `--sarif <log>`; same composition as `risk`, with `--table --rule <id> --band high --top-n 20` for triage |
|
|
274
|
+
| `audit-report` | experimental | human audit bundle over existing `risk` + `posture` evidence, optionally signed | includes `evidence_manifest` claim provenance; `--format markdown`; `--sign-key <file>` signs canonical JSON with HMAC-SHA256 |
|
|
273
275
|
| `migrate-recipe` | experimental | the migration report as the OpenRewrite recipe that applies it | only recipes a finding named; the manual remainder published beside them; writes nothing without `--write`, and never a runnable command for an empty recipe list |
|
|
274
276
|
| `data-exposure` | experimental | which routes can carry the data you labelled, and who reaches them | labels declared in `sourcecode.config.json` — never inferred from a name; `signature` and `call_reach` evidence published apart, field-level flow out of scope (NC-008). With nothing declared, `ask data-exposure /path/to/repo` answers `answered: false` and hands back the file, the key and an example to declare — it never reports zero exposed routes |
|
|
275
277
|
| `endpoints` | core | every REST endpoint, effective path, security policy, confidence | Spring MVC + JAX-RS (~65 % recall on JAX-RS sub-resource locators). `--compact` answers the exposure census without the rows; `--servlets` lists the servlet-mounted surface as its own population; `--client-usage` says which routes the TS/JS client in this repository actually calls |
|
|
276
278
|
| `spring-audit` | core | transactional anomalies + security surface + validation gaps | `--ci`, `-f github-comment`; `--table --rule SEC-008 --top-n 20` for human-scale review |
|
|
277
|
-
| `migrate-check` | core | Boot 2→3 readiness: located blockers, per-dimension score, effort | `--blast-radius` orders the re-test plan; `--table --rule MIG-001 --band critical --top-n 20` for blocker triage |
|
|
279
|
+
| `migrate-check` | core | Boot 2→3 readiness + Java LTS/licensing inventory: located blockers, per-dimension score, effort, detected Java 8/11/17/21/25 evidence and explicit licensing-review signals | `--target-jdk 25` sets the target LTS route; `--blast-radius` orders the re-test plan; `--table --rule MIG-001 --band critical --top-n 20` for blocker triage |
|
|
278
280
|
| `impact` / `impact-chain` | core | blast radius of a change, to the endpoints it reaches | target the **interface**, not the `Impl` |
|
|
279
281
|
| `pr-impact` | core | the same, scoped to a PR diff | gating command: `--fail-on`, exit codes |
|
|
280
282
|
| `verify` | core | does the repo satisfy its declared contracts, **relative to a baseline** | `.ask/contracts.yml`; exit 0/1/2 |
|
|
@@ -318,7 +320,7 @@ reading JSON sees the same boundary a buyer reads here.
|
|
|
318
320
|
|
|
319
321
|
| Not covered | Why | What answers it |
|
|
320
322
|
|---|---|---|
|
|
321
|
-
| **
|
|
323
|
+
| **General request-input-to-sink taint analysis.** | `ask risk` includes a bounded slice for annotated HTTP parameters, positional calls in repository Java sources and known query sinks. Anything broader needs value flow through a program, which is a different analysis with a different failure mode: an unsound one produces confident findings that are wrong, and every claim here is meant to be checkable against the line that produced it. | A dataflow scanner (Semgrep, CodeQL) for complete taint. What this product adds on top is reachability and, for the bounded slice, whether an annotated HTTP input reaches a known concatenated query sink. |
|
|
322
324
|
| **Secrets outside Java, Spring configuration and the deployment descriptors — a Helm value, a CI variable file, a shell script.** | The file population this analyzer reads is the Java source, the Spring configuration convention and the descriptors it already parses to resolve an environment. A secret elsewhere is not missed by a weak rule; it is outside the set of files anything here opens. Narrowed by CL-10: a credential stored in `web.xml` or a Spring XML context IS reported (SEC-007), because those files were already being read. | A dedicated secret scanner over the whole tree (gitleaks, trufflehog). |
|
|
323
325
|
| **Filter-chain order and per-filter URL patterns — the presence of a custom filter is structural only.** | Which filter runs first is decided by bean ordering this analyzer does not resolve. Where two active configurations both match a request, the answer published is `undecided` rather than a guess. | `ask posture --profile <set>` states per endpoint what the readable rules decide and what they leave undecided. |
|
|
324
326
|
| **Known vulnerabilities in dependencies — no CVE database, no version advisory matching.** | Enriching a vulnerability feed is a different product with a different update cadence; a stale embedded database is worse than no database, because it reads as a clean bill of health. | A dependency scanner (Trivy, OWASP Dependency-Check). `impact-chain` then answers which of its findings anything actually reaches. |
|
|
@@ -362,6 +364,16 @@ and that gap is the honest description, not a defect to argue with. `migrate-che
|
|
|
362
364
|
the OpenRewrite recipe each finding carries so the executor that does apply changes has its
|
|
363
365
|
input.
|
|
364
366
|
|
|
367
|
+
**Java LTS/licensing inventory.** `migrate-check` emits `java_lts_inventory` beside the migration
|
|
368
|
+
scores. It reads Maven/Gradle, local runtime hints and container files for Java 8/11/17/21/25
|
|
369
|
+
evidence, reports target-LTS blockers with `--target-jdk`, and marks explicit Oracle JDK evidence
|
|
370
|
+
as `licensing_review_needed`. This is inventory evidence, not legal advice.
|
|
371
|
+
|
|
372
|
+
**Claim provenance ledger.** JSON outputs from `risk`, `enrich`, `migrate-check`,
|
|
373
|
+
`audit-report` and `prepare-context` include `evidence_manifest`: stable claim IDs mapped to
|
|
374
|
+
source paths/lines, command inputs, ASK version, git HEAD and freshness metadata. The manifest
|
|
375
|
+
indexes claims already in the payload; it does not add analysis or certify compliance.
|
|
376
|
+
|
|
365
377
|
|
|
366
378
|
---
|
|
367
379
|
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""Signed audit report over existing ASK evidence.
|
|
2
|
+
|
|
3
|
+
This module packages facts other commands already publish. It does not score ROI,
|
|
4
|
+
choose a fix, or introduce a second judgement layer: the report summary is a
|
|
5
|
+
reader-friendly index over the embedded evidence blocks.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import hashlib
|
|
11
|
+
import hmac
|
|
12
|
+
import json
|
|
13
|
+
from datetime import datetime, timezone
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Any, Optional
|
|
16
|
+
|
|
17
|
+
from sourcecode import __version__
|
|
18
|
+
|
|
19
|
+
AUDIT_REPORT_SCHEMA = "audit-report-v1"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _canonical_json(data: dict[str, Any]) -> bytes:
|
|
23
|
+
return json.dumps(data, sort_keys=True, separators=(",", ":"), ensure_ascii=False).encode("utf-8")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _sign(payload: dict[str, Any], key: bytes) -> dict[str, str]:
|
|
27
|
+
canonical = _canonical_json(payload)
|
|
28
|
+
return {
|
|
29
|
+
"algorithm": "hmac-sha256",
|
|
30
|
+
"payload_sha256": hashlib.sha256(canonical).hexdigest(),
|
|
31
|
+
"key_id": hashlib.sha256(key).hexdigest()[:12],
|
|
32
|
+
"signature": hmac.new(key, canonical, hashlib.sha256).hexdigest(),
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def build_audit_report(
|
|
37
|
+
root: Path,
|
|
38
|
+
*,
|
|
39
|
+
profiles: Optional[set[str]] = None,
|
|
40
|
+
sign_key: Optional[bytes] = None,
|
|
41
|
+
risk_limit: int = 10,
|
|
42
|
+
) -> dict[str, Any]:
|
|
43
|
+
"""Build the buyer-readable audit bundle from existing command payloads."""
|
|
44
|
+
from sourcecode.posture import build_posture
|
|
45
|
+
from sourcecode.risk import build_risk
|
|
46
|
+
|
|
47
|
+
root = Path(root).resolve()
|
|
48
|
+
risk = build_risk(root, limit=risk_limit, min_band="low", profiles=profiles)
|
|
49
|
+
posture = build_posture(root, profiles or set())
|
|
50
|
+
top_risks = risk.get("risks", [])[:risk_limit]
|
|
51
|
+
access = ((posture.get("endpoints") or {}).get("effective_access") or {})
|
|
52
|
+
|
|
53
|
+
unsigned: dict[str, Any] = {
|
|
54
|
+
"schema_version": AUDIT_REPORT_SCHEMA,
|
|
55
|
+
"tool": {"name": "ask", "version": __version__},
|
|
56
|
+
"generated_at": datetime.now(timezone.utc).isoformat(),
|
|
57
|
+
"repository": {"path": str(root)},
|
|
58
|
+
**({"profile_set": sorted(profiles)} if profiles else {}),
|
|
59
|
+
"summary": {
|
|
60
|
+
"risk_model": risk.get("model"),
|
|
61
|
+
"total_defects": risk.get("total_defects"),
|
|
62
|
+
"total_findings": risk.get("total_findings"),
|
|
63
|
+
"risk_bands": risk.get("by_band", {}),
|
|
64
|
+
"top_risks_shown": len(top_risks),
|
|
65
|
+
"endpoint_access": access.get("summary", {}),
|
|
66
|
+
"unresolved_beans": len(posture.get("unresolved") or []),
|
|
67
|
+
},
|
|
68
|
+
"top_risks": top_risks,
|
|
69
|
+
"evidence": {
|
|
70
|
+
"risk": risk,
|
|
71
|
+
"posture": posture,
|
|
72
|
+
},
|
|
73
|
+
"limits": {
|
|
74
|
+
"statement": (
|
|
75
|
+
"This report packages existing ASK evidence. It does not certify "
|
|
76
|
+
"compliance, choose fixes, assign ROI, or replace a human audit decision."
|
|
77
|
+
),
|
|
78
|
+
"non_coverage": (risk.get("non_coverage") or {}).get("items", []),
|
|
79
|
+
},
|
|
80
|
+
}
|
|
81
|
+
from sourcecode.provenance import build_evidence_manifest
|
|
82
|
+
unsigned["evidence_manifest"] = build_evidence_manifest(
|
|
83
|
+
unsigned,
|
|
84
|
+
command="audit-report",
|
|
85
|
+
root=root,
|
|
86
|
+
inputs={
|
|
87
|
+
"profiles": sorted(profiles) if profiles else None,
|
|
88
|
+
"risk_limit": risk_limit,
|
|
89
|
+
"signed": bool(sign_key),
|
|
90
|
+
},
|
|
91
|
+
)
|
|
92
|
+
# Sign and publish the same JSON-normalized material. Some embedded evidence
|
|
93
|
+
# may contain tuples or other JSON-coercible values; normalizing before signing
|
|
94
|
+
# avoids a signature over an in-memory shape the user never receives.
|
|
95
|
+
normalized = json.loads(_canonical_json(unsigned).decode("utf-8"))
|
|
96
|
+
if sign_key:
|
|
97
|
+
normalized["signature"] = _sign(normalized, sign_key)
|
|
98
|
+
return normalized
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def render_markdown(report: dict[str, Any]) -> str:
|
|
102
|
+
"""Human report renderer over the JSON contract."""
|
|
103
|
+
summary = report.get("summary") or {}
|
|
104
|
+
repo = (report.get("repository") or {}).get("path", "")
|
|
105
|
+
profile = ", ".join(report.get("profile_set") or []) or "default"
|
|
106
|
+
lines = [
|
|
107
|
+
"# ASK Audit Report",
|
|
108
|
+
"",
|
|
109
|
+
f"- Repository: `{repo}`",
|
|
110
|
+
f"- ASK version: `{(report.get('tool') or {}).get('version', '')}`",
|
|
111
|
+
f"- Profile set: `{profile}`",
|
|
112
|
+
f"- Total defects: `{summary.get('total_defects')}`",
|
|
113
|
+
f"- Risk bands: `{summary.get('risk_bands')}`",
|
|
114
|
+
f"- Endpoint access: `{summary.get('endpoint_access')}`",
|
|
115
|
+
"",
|
|
116
|
+
"## Top Risks",
|
|
117
|
+
"",
|
|
118
|
+
]
|
|
119
|
+
risks = report.get("top_risks") or []
|
|
120
|
+
if not risks:
|
|
121
|
+
lines.append("No composed risks were reported.")
|
|
122
|
+
else:
|
|
123
|
+
lines.extend([
|
|
124
|
+
"| Band | Score | Rules | File | Line | Title |",
|
|
125
|
+
"|---|---:|---|---|---:|---|",
|
|
126
|
+
])
|
|
127
|
+
for row in risks:
|
|
128
|
+
rules = ", ".join(str(r) for r in row.get("rule_ids", []))
|
|
129
|
+
lines.append(
|
|
130
|
+
"| "
|
|
131
|
+
+ " | ".join([
|
|
132
|
+
str(row.get("band", "")),
|
|
133
|
+
str(row.get("severity_effective", "")),
|
|
134
|
+
rules,
|
|
135
|
+
str(row.get("source_file", "")),
|
|
136
|
+
str(row.get("first_line", "")),
|
|
137
|
+
str(row.get("title", "")).replace("|", "\\|"),
|
|
138
|
+
])
|
|
139
|
+
+ " |"
|
|
140
|
+
)
|
|
141
|
+
lines.extend([
|
|
142
|
+
"",
|
|
143
|
+
"## Limits",
|
|
144
|
+
"",
|
|
145
|
+
str((report.get("limits") or {}).get("statement", "")),
|
|
146
|
+
])
|
|
147
|
+
signature = report.get("signature")
|
|
148
|
+
if isinstance(signature, dict):
|
|
149
|
+
lines.extend([
|
|
150
|
+
"",
|
|
151
|
+
"## Signature",
|
|
152
|
+
"",
|
|
153
|
+
f"- Algorithm: `{signature.get('algorithm')}`",
|
|
154
|
+
f"- Payload SHA-256: `{signature.get('payload_sha256')}`",
|
|
155
|
+
f"- Key ID: `{signature.get('key_id')}`",
|
|
156
|
+
f"- Signature: `{signature.get('signature')}`",
|
|
157
|
+
])
|
|
158
|
+
return "\n".join(lines) + "\n"
|