sourcecode 4.5.3__tar.gz → 4.7.0__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.5.3 → sourcecode-4.7.0}/CHANGELOG.md +149 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/PKG-INFO +4 -4
- {sourcecode-4.5.3 → sourcecode-4.7.0}/README.md +3 -3
- {sourcecode-4.5.3 → sourcecode-4.7.0}/pyproject.toml +1 -1
- {sourcecode-4.5.3 → sourcecode-4.7.0}/scripts/perf_harness.py +38 -1
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/__init__.py +1 -1
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/archetype.py +44 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/baseline_autocapture.py +13 -1
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/cache.py +27 -1
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/cli.py +18 -4
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/java.py +4 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/explain.py +133 -40
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/mcp/registry.py +9 -4
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/mcp/server.py +13 -4
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/migrate_check.py +24 -1
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/path_filters.py +50 -40
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/perf.py +112 -1
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/posture.py +65 -5
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/repository_ir.py +20 -13
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/risk.py +119 -31
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/rule_catalog.py +10 -3
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/security_config_scan.py +172 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/source_text.py +2 -3
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/spring_impact.py +107 -11
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/spring_security_audit.py +20 -2
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/test_sources.py +47 -4
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/verify_rules.py +1 -1
- {sourcecode-4.5.3 → sourcecode-4.7.0}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/.gitignore +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/.ruff.toml +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/CLAUDE.md +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/CONTRIBUTING.md +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/LICENSE +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/SECURITY.md +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/raw +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/scripts/compare_integration_engines.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/scripts/customer_smoke_test.sh +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/scripts/generate_jdk_exports.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/architectural_baseline.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/architectural_delta.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/cache_model.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/call_surface.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/caller_metrics.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/caller_reach.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/canonical_ir.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/chain_rules.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/change_plan.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/cir_graphs.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/classifier.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/client_calls.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/compare.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/constraint_diff.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/context_cache.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/context_graph.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/contract_diff.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/contract_init.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/data_exposure.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/data_labels.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/defect_identity.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/degradation.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/deployment_prefix.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/dynamic_argument_surface.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/endpoint_literals.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/endpoint_metrics.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/envelope.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/environment_resolution.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/error_schema.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/evidence_provider.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/facts/__init__.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/facts/registry.json +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/file_chunker.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/filter_surface.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/format_contract.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/fqn_utils.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/git_checkout.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/graph_evidence.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/hibernate_strat.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/identity_fallback.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/integration_coordinates.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/jdk_exports.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/license.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/mcp/__init__.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/mcp/onboarding/applier.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/mcp/onboarding/backup.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/mcp/onboarding/detector.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/mcp/onboarding/planner.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/mcp/orchestrator.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/mcp/runner.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/mcp_nudge.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/migration_blast.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/non_coverage.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/openapi_surface.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/openrewrite_recipe.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/output_budget.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/parse_cache.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/path_admission.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/pipe_contract.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/pr_impact.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/prepare_context.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/progress.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/readiness_timeline.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/reconciliation.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/redactor.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/reference_facts.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/release_info.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/remedies.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/rename_refactor.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/__init__.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/context.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/errors.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/executor.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/planner.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/query.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/request.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/resolution.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/result.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/retriever.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/runtime.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/steps.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/steps_endpoint.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/steps_graph.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/steps_impact.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/steps_intf.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/steps_struct.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/retrieval/steps_txsec.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/ris.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/sarif.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/scanner.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/schema.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/schemas/envelope-v1.schema.json +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/security_config.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/security_posture.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/semantic_impact_engine.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/semantic_integration_engine.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/semantic_services.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/serializer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/servlet_surface.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/spring_event_topology.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/spring_findings.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/spring_model.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/spring_profiles.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/spring_properties.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/spring_semantic.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/spring_tx_analyzer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/target_admission.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/test_gap_ranking.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/token_estimate.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/type_usage_surface.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/validation_inference.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/validation_surface.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/verify_edit.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/verify_repo.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/version_check.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/src/sourcecode/workspace.py +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/supabase/functions/README.md +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/supabase/functions/get-license/index.ts +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/supabase/functions/telemetry/index.ts +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/supabase/sql/license_event_ordering.sql +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/supabase/sql/licensing_schema.sql +0 -0
- {sourcecode-4.5.3 → sourcecode-4.7.0}/supabase/sql/telemetry_events.sql +0 -0
|
@@ -2,6 +2,155 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [4.7.0] — 2026-08-04
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- **`impact-chain` no longer pays a repository-wide TX + security audit by default.**
|
|
10
|
+
`impact_findings` is now opt-in with `--with-findings`, so the common query cost
|
|
11
|
+
follows the queried subgraph instead of the whole repository.
|
|
12
|
+
- **`migrate-check` now separates migration blockers from broad blockers.**
|
|
13
|
+
The payload publishes `migration_blocking_count` while keeping the legacy
|
|
14
|
+
`blocking_count` for compatibility.
|
|
15
|
+
- **Disabled security controls are reported explicitly.** Commented-out
|
|
16
|
+
framework security annotations now emit `DEAD-001`, and security catalog/help
|
|
17
|
+
output includes disabled-control findings.
|
|
18
|
+
- **MyBatis SQL interpolation is classified as SQL-injection risk.** Mapper
|
|
19
|
+
`${...}` interpolation emits `SEC-008` instead of being treated as a generic
|
|
20
|
+
raw SQL smell.
|
|
21
|
+
- **Performance claims now have endpoint-scale coverage.** The battery includes
|
|
22
|
+
a high-endpoint fixture, publishes scale dimensions, and gates unexplained
|
|
23
|
+
performance regressions against prior measurements.
|
|
24
|
+
- **Framework detection covers Jersey and Governator.** Migration/readiness
|
|
25
|
+
output no longer misses those stacks when scanning mixed Java repositories.
|
|
26
|
+
|
|
27
|
+
## [4.6.0] — 2026-08-04
|
|
28
|
+
|
|
29
|
+
Field evaluation #11 (7,5/10), by the evaluator who measured 4.5.2 twelve hours
|
|
30
|
+
earlier, on the build that closed their previous list. **Eight complaints, eight
|
|
31
|
+
reproductions, eight fixes** — the first evaluation where every complaint
|
|
32
|
+
survives verification and none re-derives a closed row.
|
|
33
|
+
|
|
34
|
+
The headline is not in the list below and is worth stating: the four false
|
|
35
|
+
positives measured on 4.5.2 are **gone**, verified line by line in the field, and
|
|
36
|
+
the run reports **0 false positives across 19 findings** — precision 9/10,
|
|
37
|
+
epistemic honesty 10/10 (*"no he visto nada mejor en ninguna herramienta de
|
|
38
|
+
análisis, comercial o no"*). E-2 is closed in the field, not only in the battery.
|
|
39
|
+
|
|
40
|
+
Minor, not patch: `risk` publishes a sixth reachability value and three new
|
|
41
|
+
fields, `posture` publishes two, `impact-chain` publishes two, and the test/
|
|
42
|
+
production split moves published populations. **No field was removed and no exit
|
|
43
|
+
code moved.**
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
|
|
47
|
+
- **`impact-chain` spent 2 300× longer answering than building the model it
|
|
48
|
+
answers from** (C3-42, **high**). The field published `query_time_ms: 1 187 063`
|
|
49
|
+
beside `model_build_time_ms: 516` and abandoned two more invocations past 25
|
|
50
|
+
minutes — the axis this evaluation scored **3/10**, with the verdict that
|
|
51
|
+
decides it: *"un gate de CI que tarda 45 min no es un gate"*. The seed
|
|
52
|
+
expansions (CH-001a/b) answered *"every symbol of this class"* by scanning the
|
|
53
|
+
whole symbol table once per subtype, with the seed set rebuilt for every symbol
|
|
54
|
+
tested. Both now read one class→symbols index memoized on the CIR, which
|
|
55
|
+
matters twice: `RiskComposer.reach` calls that path **once per defect**, and
|
|
56
|
+
that is where the field's ~45-minute `risk` comes from. Measured A/B on
|
|
57
|
+
keycloak (5 525 files, 59 410 symbols), identical results in all four queries:
|
|
58
|
+
`Provider` **8.15 s → 2.60 s**. Second half, and the reason the rest is flat:
|
|
59
|
+
`query_time_ms` was never the walk — it includes a repository-wide TX +
|
|
60
|
+
security audit, now published as `audit_time_ms` with a `query_time_basis`
|
|
61
|
+
stating that the walk is the difference between the two and that
|
|
62
|
+
`model_build_time_ms` is not comparable with either.
|
|
63
|
+
- **`risk` did not read the other authority that answered its own access axis**
|
|
64
|
+
(C1-26, **high**). It asked `posture` only when `--profile` was given, so the
|
|
65
|
+
default invocation weighed an endpoint at `unknown` (×1.4) that `posture`, in
|
|
66
|
+
the same process and over the same CIR, decided was reachable without
|
|
67
|
+
authentication (×2.0). The resolution is now read always; with no set named it
|
|
68
|
+
is the one Spring performs with none given — `default` alone, which CL-8
|
|
69
|
+
records as the permissive case, not a neutral one — and every row publishes
|
|
70
|
+
`profile_set`, `profile_set_basis` (*"a default, never a guarantee: the process
|
|
71
|
+
environment outranks every file"*) and `profile_decisions`. It cannot
|
|
72
|
+
manufacture a verdict: `no_rule_matched` stays unknown coverage, the
|
|
73
|
+
combination is per endpoint, and on a fixture where both chains are
|
|
74
|
+
profile-gated the answer stays `unknown`. Measured on the field's shape: **8.06
|
|
75
|
+
→ 11.52**, exactly the ratio of the two access weights, every other factor
|
|
76
|
+
unmoved.
|
|
77
|
+
- **`risk` degraded a repository-wide control defect with a sentence that is
|
|
78
|
+
false in effect** (C1-25, configuration half; second field witness). *"No HTTP
|
|
79
|
+
endpoint in this repository reaches it"* — about the file that decides whether
|
|
80
|
+
any endpoint is reachable at all. Reach for such a defect is **declared, not
|
|
81
|
+
walked**: `posture` already knew which configuration file decided which
|
|
82
|
+
request and now publishes it as `chains.decides_endpoints`, `risk` reads it as
|
|
83
|
+
the reachability value `request_chain`, and the two units stay apart —
|
|
84
|
+
`endpoints_reached` remains the walk, `decides_requests` is the scope.
|
|
85
|
+
Evidence-bound both ways: only a file declaring readable chain rules qualifies,
|
|
86
|
+
and an unresolved servlet path clears the attribution entirely. Fixture: **low
|
|
87
|
+
2.8 → medium 4.48**.
|
|
88
|
+
- **`posture --resolve-environments` truncated the open-endpoint list without
|
|
89
|
+
declaring the cap** (C2-25). 50 entries under a count of 2 635, with no
|
|
90
|
+
`total`, no `omitted`, no `direction: under_reports` — in the module that
|
|
91
|
+
defines the cap helper and applies it to four other lists. *"Rompe la garantía
|
|
92
|
+
que el resto del tool cumple escrupulosamente, y es precisamente en la lista
|
|
93
|
+
que un auditor necesita completa."* The helper grew the one parameter it was
|
|
94
|
+
missing (the limit that actually bit) and every other slice in the module was
|
|
95
|
+
checked.
|
|
96
|
+
- **`explain` answered a configuration class with every section empty**,
|
|
97
|
+
`found: true` and no warning (C3-41, **high**) — on the command the same
|
|
98
|
+
evaluation calls the product's best asset, for the class an auditor opens
|
|
99
|
+
first. One model error with three faces: a factory member is a method
|
|
100
|
+
(`symbol_kind: "bean"` was excluded by kind, so **every** `@Configuration` in
|
|
101
|
+
every repository published no methods); a configuration class wires through its
|
|
102
|
+
members' signatures and bodies, not through an injection graph (both are atoms
|
|
103
|
+
already published, read only when the class really declares factory members);
|
|
104
|
+
and its constraints are in a DSL, so the section now reads `chain_rules` — the
|
|
105
|
+
authority `posture` uses on that same file — with `file:line` per rule. Fourth,
|
|
106
|
+
and the reason the report was silent: every section was wrapped in a bare
|
|
107
|
+
`except: []`, so a crash and a measured emptiness were one output. A failed
|
|
108
|
+
section now says which one failed.
|
|
109
|
+
- **`cache freshness` called a snapshot STALE over a file no analyser reads**
|
|
110
|
+
(C1-27) — with `RIS HEAD == current HEAD` and `Delta: 0` beside it. C3-40
|
|
111
|
+
(4.5.3) replaced a false *fresh* with a false *stale* by counting any porcelain
|
|
112
|
+
line. One authority now decides which paths qualify
|
|
113
|
+
(`path_filters.analysis_reads`) and both consumers ask it: the freshness
|
|
114
|
+
boolean and the **tree signature**, which is what actually decides the verdict
|
|
115
|
+
and is also the cache key — so an agent writing its own settings file was
|
|
116
|
+
discarding every warm answer. The excused set is state nothing opens and is
|
|
117
|
+
**not** every dot directory: `.github` is read as tooling evidence and stays a
|
|
118
|
+
change. The default is inclusive, because a missed change is a false *fresh*.
|
|
119
|
+
- **The test/production split still had two authorities** (C1-28).
|
|
120
|
+
`path_filters.is_test_path` was never retired after C1-2 made `test_sources`
|
|
121
|
+
the authority in 3.2.1, and the two disagreed on five path shapes in both
|
|
122
|
+
directions. Field symptom: *"`--compact` counts 1 test file that is actually in
|
|
123
|
+
`src/main`"* — verdict right, numerator wrong. The second module is now a
|
|
124
|
+
passthrough, after absorbing everything it knew that the authority did not; and
|
|
125
|
+
a declared **main** source root now outranks a naming convention, the same rule
|
|
126
|
+
the directory half always applied, in the other direction. Fleet effect,
|
|
127
|
+
measured cold: keycloak 5 525 → 5 486 Java files with endpoints **676 → 678**,
|
|
128
|
+
openmrs-core 866 → 861, Broadleaf / alfresco / petclinic unchanged.
|
|
129
|
+
- **`archetype` never read the endpoint surface for the dimension the endpoint
|
|
130
|
+
surface decides** (C3-43). A 3 574-endpoint CRUD REST monolith was labelled
|
|
131
|
+
`engine` at medium confidence on a fan-in Gini, while the legacy classifier it
|
|
132
|
+
supersedes answered `api` and was right. The density `_primary_interface`
|
|
133
|
+
already reads is now positive evidence for `application` and **named negative
|
|
134
|
+
evidence** against `engine` — the shape the library de-bias uses — scaled by
|
|
135
|
+
the measured density, and emitted only when the surface was measured.
|
|
136
|
+
Measured: Broadleaf and keycloak `engine/high → application/low`, petclinic
|
|
137
|
+
`engine/low → application/medium`, jobrunr `engine/high → engine/low`,
|
|
138
|
+
openmrs-core unchanged (1 endpoint, no density, no discount — the negative
|
|
139
|
+
control).
|
|
140
|
+
|
|
141
|
+
### Notes
|
|
142
|
+
|
|
143
|
+
Two rows from this evaluation are **not** fixed here, on purpose: **P-9** is a
|
|
144
|
+
pricing decision (a fifth pass, and the fourth to argue itself off the seat axis
|
|
145
|
+
— the ceiling is conditioned on this battery's performance work and on a tier
|
|
146
|
+
promotion, not on any missing capability), and **CL-13** is the narrow rule
|
|
147
|
+
catalogue (7 SEC + 6 TX), queued as **F-F** with the *test surface in
|
|
148
|
+
production* rule first, because C1-28 just gave it its admission surface for
|
|
149
|
+
free. Full record in `.planning/FIELD-EVAL-11-2026-08-04.md`; every row is in
|
|
150
|
+
`docs/DEFECT-LEDGER.md`.
|
|
151
|
+
|
|
152
|
+
Suite: 6 468 passed, 6 skipped.
|
|
153
|
+
|
|
5
154
|
## [4.5.3] — 2026-08-04
|
|
6
155
|
|
|
7
156
|
Patch: the fixable half of field evaluation #10 (7,5/10, CI reliability **4/10**), in one
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.7.0
|
|
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.7.0 — and, on a build that has aged,
|
|
101
101
|
# how many releases have probably shipped since
|
|
102
102
|
```
|
|
103
103
|
|
|
@@ -211,7 +211,7 @@ Bounded, noise-free repo context designed to drop straight into an agent's conte
|
|
|
211
211
|
|
|
212
212
|
### 2 · Impact Analysis
|
|
213
213
|
Blast radius from a class or interface — reverse dependencies, through Spring DI, to the HTTP endpoints a change reaches.
|
|
214
|
-
`ask impact` · `ask impact-chain` (TX/SEC
|
|
214
|
+
`ask impact` · `ask impact-chain` (blast radius; `--with-findings` for TX/SEC audit findings) · `ask pr-impact`
|
|
215
215
|
→ [reference](docs/USER_GUIDE.md#core-commands)
|
|
216
216
|
|
|
217
217
|
### 3 · Architecture Intelligence
|
|
@@ -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.7.0 — and, on a build that has aged,
|
|
63
63
|
# how many releases have probably shipped since
|
|
64
64
|
```
|
|
65
65
|
|
|
@@ -173,7 +173,7 @@ Bounded, noise-free repo context designed to drop straight into an agent's conte
|
|
|
173
173
|
|
|
174
174
|
### 2 · Impact Analysis
|
|
175
175
|
Blast radius from a class or interface — reverse dependencies, through Spring DI, to the HTTP endpoints a change reaches.
|
|
176
|
-
`ask impact` · `ask impact-chain` (TX/SEC
|
|
176
|
+
`ask impact` · `ask impact-chain` (blast radius; `--with-findings` for TX/SEC audit findings) · `ask pr-impact`
|
|
177
177
|
→ [reference](docs/USER_GUIDE.md#core-commands)
|
|
178
178
|
|
|
179
179
|
### 3 · Architecture Intelligence
|
|
@@ -201,6 +201,12 @@ def main() -> int:
|
|
|
201
201
|
ap.add_argument("--fleet-root", type=Path, default=DEFAULT_FLEET_ROOT)
|
|
202
202
|
ap.add_argument("--out", type=Path, default=None,
|
|
203
203
|
help="Output dir (default: docs/perf/baselines/<tool_version>).")
|
|
204
|
+
ap.add_argument("--compare-dir", type=Path, default=None,
|
|
205
|
+
help="Previous perf-baseline directory to gate against.")
|
|
206
|
+
ap.add_argument("--max-regression", type=float, default=0.25,
|
|
207
|
+
help="Allowed wall p50/p95 regression ratio before failing (default: 0.25).")
|
|
208
|
+
ap.add_argument("--allow-incomparable", action="store_true",
|
|
209
|
+
help="Do not fail when baseline/current cells are incomparable.")
|
|
204
210
|
ap.add_argument("--quick", action="store_true", help="petclinic only, 2 runs — smoke test.")
|
|
205
211
|
ap.add_argument("--dry-run", action="store_true", help="Print the plan, run nothing.")
|
|
206
212
|
args = ap.parse_args()
|
|
@@ -227,6 +233,7 @@ def main() -> int:
|
|
|
227
233
|
return 0
|
|
228
234
|
|
|
229
235
|
out_dir.mkdir(parents=True, exist_ok=True)
|
|
236
|
+
failures: list[tuple[str, dict]] = []
|
|
230
237
|
for cmd, name, mode in plan:
|
|
231
238
|
subdir = FLEET.get(name, name)
|
|
232
239
|
repo_path = args.fleet_root / subdir
|
|
@@ -242,9 +249,39 @@ def main() -> int:
|
|
|
242
249
|
fname = f"{name}__{cmd or 'ask'}__{mode}.json"
|
|
243
250
|
(out_dir / fname).write_text(json.dumps(cell, indent=2) + "\n", encoding="utf-8")
|
|
244
251
|
w = cell["wall_ms"]
|
|
245
|
-
|
|
252
|
+
gate = None
|
|
253
|
+
if args.compare_dir:
|
|
254
|
+
base_path = args.compare_dir / fname
|
|
255
|
+
if base_path.exists():
|
|
256
|
+
try:
|
|
257
|
+
baseline = json.loads(base_path.read_text(encoding="utf-8"))
|
|
258
|
+
gate = perf.regression_gate(
|
|
259
|
+
baseline,
|
|
260
|
+
cell,
|
|
261
|
+
max_regression=args.max_regression,
|
|
262
|
+
allow_incomparable=args.allow_incomparable,
|
|
263
|
+
)
|
|
264
|
+
(out_dir / f"{fname}.gate.json").write_text(
|
|
265
|
+
json.dumps(gate, indent=2) + "\n", encoding="utf-8"
|
|
266
|
+
)
|
|
267
|
+
if not gate.get("passed"):
|
|
268
|
+
failures.append((fname, gate))
|
|
269
|
+
except (OSError, ValueError) as exc:
|
|
270
|
+
failures.append((fname, {
|
|
271
|
+
"status": "incomparable",
|
|
272
|
+
"passed": False,
|
|
273
|
+
"reasons": [f"could not read baseline: {exc}"],
|
|
274
|
+
}))
|
|
275
|
+
_gate_text = f" gate={gate['status']}" if gate else ""
|
|
276
|
+
print(f" p50={w['p50']}ms p95={w['p95']}ms{_gate_text} -> {fname}")
|
|
246
277
|
|
|
247
278
|
print(f"done. artifacts in {out_dir}")
|
|
279
|
+
if failures:
|
|
280
|
+
print("perf regression gate failed:", file=sys.stderr)
|
|
281
|
+
for fname, gate in failures:
|
|
282
|
+
detail = gate.get("failed_metrics") or gate.get("reasons")
|
|
283
|
+
print(f" {fname}: {gate.get('status')} {detail}", file=sys.stderr)
|
|
284
|
+
return 1
|
|
248
285
|
return 0
|
|
249
286
|
|
|
250
287
|
|
|
@@ -86,6 +86,14 @@ _MIN_CONFIDENT_SCORE = 0.5
|
|
|
86
86
|
# discriminating. Tuned so a clear library (no app/server/servlet entry) is not confidently
|
|
87
87
|
# labeled an engine, while runnable systems (which never trigger the gate) are untouched.
|
|
88
88
|
_LIBRARY_ENGINE_DISCOUNT = 0.55
|
|
89
|
+
# The same shape for the opposite mistake (C3-43): a repository whose primary
|
|
90
|
+
# surface is HTTP owns storage/kernel packages and hub topology *because* it
|
|
91
|
+
# serves requests with them, so that evidence is not discriminating for "engine"
|
|
92
|
+
# either. Scaled by the measured density, so a repository with a marginal surface
|
|
93
|
+
# is barely discounted and one that is nothing but endpoints is discounted fully.
|
|
94
|
+
# Below the library figure on purpose: an application CAN be built around an
|
|
95
|
+
# engine, whereas a non-runnable artifact cannot be an engine product at all.
|
|
96
|
+
_HTTP_ENGINE_DISCOUNT = 0.45
|
|
89
97
|
# Entry kinds that make a repo a runnable system (an app/server/servlet/daemon) rather
|
|
90
98
|
# than a consumable library. Used to gate the library de-bias (P0).
|
|
91
99
|
_RUNNABLE_ENTRY_KINDS = frozenset({
|
|
@@ -409,6 +417,42 @@ class ArchetypeClassifier:
|
|
|
409
417
|
add("application", "runtime_entry_plus_services",
|
|
410
418
|
f"bootstrap/server entry + service mass ≈ {cm['service']:.0%}",
|
|
411
419
|
2.0, 1.0, max(cm["service"], 0.2))
|
|
420
|
+
# C3-43. The strongest MEASURED discriminator this build has for what a
|
|
421
|
+
# repository is — its HTTP surface — was read by `_primary_interface` and
|
|
422
|
+
# ignored here, so a 3 574-endpoint CRUD REST monolith was labelled
|
|
423
|
+
# `engine` on package-name masses and a fan-in Gini, while the legacy
|
|
424
|
+
# classifier it supersedes answered `api` and was right. Same ramp as the
|
|
425
|
+
# interface dimension, from the same features: one authority for the
|
|
426
|
+
# figure, two dimensions reading it.
|
|
427
|
+
if f.endpoint_share is None:
|
|
428
|
+
# Unmeasured is not zero: contribute nothing, and say so.
|
|
429
|
+
add("application", "http_surface_density",
|
|
430
|
+
"endpoint surface not measured — this dimension is scored without it",
|
|
431
|
+
2.5, 0.0, 0.0)
|
|
432
|
+
else:
|
|
433
|
+
density = f.endpoint_share * 100
|
|
434
|
+
http_strength = (
|
|
435
|
+
max(0.0, min(1.0, (density - 0.5) / 1.5)) if f.endpoint_total else 0.0
|
|
436
|
+
)
|
|
437
|
+
add("application", "http_surface_density",
|
|
438
|
+
f"{f.endpoint_total} endpoints over {f.total_files} files "
|
|
439
|
+
f"({density:.2f}/100 files) — the repository's primary surface is HTTP",
|
|
440
|
+
2.5, http_strength, 1.0)
|
|
441
|
+
# And the same fact as NAMED negative evidence for `engine`, the way
|
|
442
|
+
# the library de-bias below does it: a codebase whose product is a
|
|
443
|
+
# request surface owns storage and kernel packages *because* it is an
|
|
444
|
+
# application, so that mass is not, alone, evidence of an engine.
|
|
445
|
+
engine_positive_http = sum(max(0.0, e.contribution) for e in cands["engine"])
|
|
446
|
+
if http_strength > 0 and engine_positive_http > 0:
|
|
447
|
+
cands["engine"].append(Evidence(
|
|
448
|
+
"http_surface_discount",
|
|
449
|
+
f"{f.endpoint_total} endpoints over {f.total_files} files: the "
|
|
450
|
+
"primary surface of this repository is HTTP, and the storage/"
|
|
451
|
+
"kernel mass and hub topology an application needs to serve it "
|
|
452
|
+
"are not, alone, evidence of an engine product",
|
|
453
|
+
1.0, 1.0, 1.0,
|
|
454
|
+
-engine_positive_http * _HTTP_ENGINE_DISCOUNT * http_strength,
|
|
455
|
+
))
|
|
412
456
|
# platform: many modules + multiple concept clusters + distribution
|
|
413
457
|
multi = 1.0 if f.module_count >= 8 else f.module_count / 8
|
|
414
458
|
add("platform", "many_modules_multi_concern",
|
|
@@ -210,7 +210,19 @@ def worktree_dirty(
|
|
|
210
210
|
return None
|
|
211
211
|
if out.returncode != 0:
|
|
212
212
|
return None
|
|
213
|
-
|
|
213
|
+
# C1-27. "Dirty" means the tree *the analysis reads* differs from HEAD. A
|
|
214
|
+
# change under an editor or agent state directory is not one — no analyser
|
|
215
|
+
# opens those files — and counting it reported STALE on a snapshot that
|
|
216
|
+
# described the tree exactly, with `Delta: 0` beside it. One authority answers
|
|
217
|
+
# which paths qualify (`path_filters.analysis_reads`) and its default is
|
|
218
|
+
# inclusive: anything not named there still counts, because a missed change
|
|
219
|
+
# is a false *fresh* and a spurious one only costs a rebuild.
|
|
220
|
+
from sourcecode.path_filters import analysis_reads
|
|
221
|
+
|
|
222
|
+
lines = [
|
|
223
|
+
ln for ln in out.stdout.splitlines()
|
|
224
|
+
if ln.strip() and analysis_reads(_porcelain_path(ln))
|
|
225
|
+
]
|
|
214
226
|
if ignore is None:
|
|
215
227
|
return bool(lines)
|
|
216
228
|
candidates = [ignore] if isinstance(ignore, (str, Path)) else list(ignore)
|
|
@@ -213,6 +213,14 @@ def _untracked_tree_fingerprint(target: Path) -> str:
|
|
|
213
213
|
return f"ff{h.hexdigest()[:14]}"
|
|
214
214
|
|
|
215
215
|
|
|
216
|
+
def _porcelain_status_path(line: str) -> str:
|
|
217
|
+
"""The path a `git status --porcelain` line refers to (destination on renames)."""
|
|
218
|
+
body = line[3:] if len(line) > 3 else ""
|
|
219
|
+
if " -> " in body:
|
|
220
|
+
body = body.split(" -> ", 1)[1]
|
|
221
|
+
return body.strip().strip('"')
|
|
222
|
+
|
|
223
|
+
|
|
216
224
|
def worktree_signature(repo_root: Path, scope: Optional[Path] = None) -> str:
|
|
217
225
|
"""Hex fingerprint of the **exact tree state an analysis would read**.
|
|
218
226
|
|
|
@@ -252,12 +260,30 @@ def worktree_signature(repo_root: Path, scope: Optional[Path] = None) -> str:
|
|
|
252
260
|
porcelain = st.stdout if st.returncode == 0 else ""
|
|
253
261
|
except Exception:
|
|
254
262
|
porcelain = ""
|
|
263
|
+
# C1-27. The signature describes *the tree an analysis would read*, so a line
|
|
264
|
+
# about a file no analyser opens does not belong in it — an editor settings
|
|
265
|
+
# file was invalidating every cached answer and publishing STALE beside
|
|
266
|
+
# `Delta: 0`. One authority decides which paths qualify, and its default is
|
|
267
|
+
# inclusive: anything not named there still invalidates.
|
|
268
|
+
from sourcecode.path_filters import analysis_reads
|
|
269
|
+
|
|
270
|
+
porcelain = "\n".join(
|
|
271
|
+
ln for ln in porcelain.splitlines()
|
|
272
|
+
if ln.strip() and analysis_reads(_porcelain_status_path(ln))
|
|
273
|
+
)
|
|
255
274
|
if not porcelain.strip():
|
|
256
275
|
return head # clean — HEAD fully describes the tree
|
|
257
276
|
|
|
258
277
|
try:
|
|
278
|
+
from sourcecode.path_filters import _TOOL_STATE_DIRS
|
|
279
|
+
|
|
280
|
+
# The same exclusion, expressed to git for the half that is not a list of
|
|
281
|
+
# paths. A tracked editor-state file must not enter the signature through
|
|
282
|
+
# the diff after being kept out of the status.
|
|
283
|
+
_diff_spec = list(pathspec) or ["--", "."]
|
|
284
|
+
_diff_spec += [f":(exclude,glob)**/{d}/**" for d in sorted(_TOOL_STATE_DIRS)]
|
|
259
285
|
df = subprocess.run(
|
|
260
|
-
["git", "-C", str(root), "diff", "HEAD", *
|
|
286
|
+
["git", "-C", str(root), "diff", "HEAD", *_diff_spec],
|
|
261
287
|
capture_output=True, text=True, timeout=20,
|
|
262
288
|
)
|
|
263
289
|
diff_txt = df.stdout if df.returncode == 0 else ""
|
|
@@ -354,7 +354,7 @@ of files) in minutes. Semantic analysis itself is sub-second; repo indexing domi
|
|
|
354
354
|
ask --agent [dim]# full structured JSON for AI agents[/dim]
|
|
355
355
|
|
|
356
356
|
[bold]Change and risk:[/bold]
|
|
357
|
-
impact-chain <Class> . [dim]# blast radius
|
|
357
|
+
impact-chain <Class> . [dim]# blast radius; TX/SEC findings opt-in[/dim]
|
|
358
358
|
impact <Class> . [dim]# reverse deps → endpoints reached[/dim]
|
|
359
359
|
pr-impact . --files - [dim]# same, scoped to a diff on stdin; gating codes[/dim]
|
|
360
360
|
posture . --since main [dim]# did this branch open an endpoint? (exp.)[/dim]
|
|
@@ -8419,8 +8419,16 @@ def impact_chain_cmd(
|
|
|
8419
8419
|
"surfaces). Totals stay exact in metadata/truncated_lists. "
|
|
8420
8420
|
"0 disables the cap.",
|
|
8421
8421
|
),
|
|
8422
|
+
with_findings: bool = typer.Option(
|
|
8423
|
+
False, "--with-findings",
|
|
8424
|
+
help=(
|
|
8425
|
+
"Also run the repository-wide TX + security audit and filter findings "
|
|
8426
|
+
"to this chain. Off by default so query cost follows the queried "
|
|
8427
|
+
"subgraph rather than the whole repository."
|
|
8428
|
+
),
|
|
8429
|
+
),
|
|
8422
8430
|
) -> None:
|
|
8423
|
-
"""Spring impact-chain: systemic blast radius of a symbol
|
|
8431
|
+
"""Spring impact-chain: systemic blast radius of a symbol; TX/SEC findings are opt-in.
|
|
8424
8432
|
|
|
8425
8433
|
\b
|
|
8426
8434
|
Given a symbol (class or method), returns:
|
|
@@ -8431,6 +8439,7 @@ def impact_chain_cmd(
|
|
|
8431
8439
|
- security_surfaces — per-endpoint security verdict + confidence
|
|
8432
8440
|
(security_posture authority) + declared policy + SEC findings
|
|
8433
8441
|
- impact_findings — TX/SEC audit findings touching the call chain
|
|
8442
|
+
(only with --with-findings)
|
|
8434
8443
|
- risk_level — critical | high | medium | low
|
|
8435
8444
|
|
|
8436
8445
|
\b
|
|
@@ -8537,7 +8546,10 @@ def impact_chain_cmd(
|
|
|
8537
8546
|
)
|
|
8538
8547
|
return
|
|
8539
8548
|
|
|
8540
|
-
result = run_impact_chain(
|
|
8549
|
+
result = run_impact_chain(
|
|
8550
|
+
cir, symbol, depth=depth, root=target, model=_model,
|
|
8551
|
+
include_findings=with_findings,
|
|
8552
|
+
)
|
|
8541
8553
|
|
|
8542
8554
|
data = result.to_dict()
|
|
8543
8555
|
# Same rule as `impact`: a file is a request for the whole answer (C2-2). An
|
|
@@ -8853,7 +8865,9 @@ def explain_cmd(
|
|
|
8853
8865
|
except Exception:
|
|
8854
8866
|
cir = ContextGraph.build(file_list, target).cir # fallback: never break explain
|
|
8855
8867
|
model = SpringSemanticModel.build(cir)
|
|
8856
|
-
|
|
8868
|
+
# `root` is what lets the security section read the request-chain rules a
|
|
8869
|
+
# configuration class declares in a DSL rather than in annotations (C3-41).
|
|
8870
|
+
explanation = explain_class(class_name, cir, model, root=target).capped(limit)
|
|
8857
8871
|
finally:
|
|
8858
8872
|
_prog.finish()
|
|
8859
8873
|
if _cc_look is not None:
|
|
@@ -457,6 +457,10 @@ class JavaDetector(AbstractDetector):
|
|
|
457
457
|
or "resteasy" in text # RESTEasy — a JAX-RS implementation
|
|
458
458
|
):
|
|
459
459
|
frameworks.append(FrameworkDetection(name="JAX-RS", source=source))
|
|
460
|
+
if "com.sun.jersey" in text or "org.glassfish.jersey" in text:
|
|
461
|
+
frameworks.append(FrameworkDetection(name="Jersey", source=source))
|
|
462
|
+
if "com.netflix.governator" in text:
|
|
463
|
+
frameworks.append(FrameworkDetection(name="Governator", source=source))
|
|
460
464
|
if "mybatis" in text:
|
|
461
465
|
frameworks.append(FrameworkDetection(name="MyBatis", source=source))
|
|
462
466
|
if "thymeleaf" in text:
|