sourcecode 1.30.25__tar.gz → 1.30.27__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-1.30.25 → sourcecode-1.30.27}/PKG-INFO +3 -3
- {sourcecode-1.30.25 → sourcecode-1.30.27}/README.md +2 -2
- {sourcecode-1.30.25 → sourcecode-1.30.27}/pyproject.toml +1 -1
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/__init__.py +1 -1
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/confidence_analyzer.py +10 -2
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/file_classifier.py +11 -10
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/prepare_context.py +4 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/ranking_engine.py +92 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/serializer.py +201 -58
- sourcecode-1.30.27/tests/test_scoring_calibration.py +561 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/.agents/skills/source-command-gsd-join-discord/SKILL.md +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/.agents/skills/source-command-gsd-review-backlog/SKILL.md +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/.agents/skills/source-command-gsd-workstreams/SKILL.md +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/.continue-here.md +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/.gitignore +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/.ruff.toml +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/CONTRIBUTING.md +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/LICENSE +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/SECURITY.md +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/docs/privacy.md +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/docs/schema.md +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/raw +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/run_cli.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/classifier.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/cli.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/flow_analyzer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/progress.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/redactor.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/repository_ir.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/scanner.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/schema.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/src/sourcecode/workspace.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/__init__.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/conftest.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/coverage.xml +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/fastapi_app/pyproject.toml +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/fastapi_app/src/main.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/go_service/cmd/api/main.go +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/go_service/go.mod +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/jacoco.xml +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/latin1_sample.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/latin1_sample_iso.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/lcov.info +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/nextjs_app/app/page.tsx +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/nextjs_app/package.json +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/nextjs_app/pnpm-lock.yaml +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/pnpm_monorepo/apps/web/app/page.tsx +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/pnpm_monorepo/apps/web/package.json +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/pnpm_monorepo/packages/api/main.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/pnpm_monorepo/packages/api/pyproject.toml +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/pnpm_monorepo/pnpm-workspace.yaml +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/pom.xml +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/application/service/FindAusenteService.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/domain/entities/Ausente.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/infrastructure/rest/AusenteRestController.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/application/service/FindAutocoberturasService.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/domain/entities/Autocoberturas.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/infrastructure/rest/AutocoberturasRestController.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/application/service/FindCalendarioTrabajadorService.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/domain/entities/CalendarioTrabajador.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/infrastructure/rest/CalendarioTrabajadorRestController.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/application/service/FindDepartamentoService.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/domain/entities/Departamento.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/infrastructure/rest/DepartamentoRestController.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/application/service/FindEmpleadoService.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/domain/entities/Empleado.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/infrastructure/rest/EmpleadoRestController.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/DemoApplication.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/config/FilterConfig.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/domain/Health.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/mapper/HealthMapper.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/repository/HealthRepository.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/service/HealthService.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/HealthRestController.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/NominaRestController.java +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/resources/application-dev.yml +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/resources/application.yml +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/fixtures/spring_boot_minimal/src/main/resources/mapper/HealthMapper.xml +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_architecture_analyzer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_architecture_summary.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_ast_extractor.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_block1_reliability.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_block2_coverage.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_block5_quality.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_bug_fixes_v16.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_classifier.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_cli.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_code_notes_analyzer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_context_scorer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_contract_pipeline.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_coverage_parser.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_cross_consistency.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_dependency_analyzer_node_python.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_dependency_analyzer_polyglot.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_dependency_schema.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_detector_dotnet.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_detector_go_rust_java.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_detector_nodejs.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_detector_php_ruby_dart.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_detector_python.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_detector_universal_managed.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_detector_universal_systems.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_detectors_base.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_doc_analyzer_jsdom.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_doc_analyzer_python.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_encoding_regression.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_graph_analyzer_polyglot.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_graph_analyzer_python_node.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_graph_schema.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_hybrid_inference.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_integration.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_integration_dependencies.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_integration_detection.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_integration_docs.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_integration_graph_modules.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_integration_lqn.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_integration_metrics.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_integration_multistack.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_integration_semantics.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_integration_universal.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_java_spring_integration.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_metrics_analyzer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_output_ux.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_packaging.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_phase1_improvements.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_pipeline_integrity.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_real_projects.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_redactor.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_repository_ir.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_scanner.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_schema.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_schema_normalization.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_semantic_analyzer_node.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_semantic_analyzer_python.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_semantic_import_resolution.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_semantic_schema.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_signal_hierarchy.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_summarizer.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_surface_honesty.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_task_differentiation.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_telemetry.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_v131_improvements.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_v1_10_regressions.py +0 -0
- {sourcecode-1.30.25 → sourcecode-1.30.27}/tests/test_workspace_analyzer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 1.30.
|
|
3
|
+
Version: 1.30.27
|
|
4
4
|
Summary: Deterministic codebase context for AI coding agents
|
|
5
5
|
License: Apache License
|
|
6
6
|
Version 2.0, January 2004
|
|
@@ -221,7 +221,7 @@ Description-Content-Type: text/markdown
|
|
|
221
221
|
|
|
222
222
|
**Deterministic, behavior-aware codebase context for AI agents and PR review.**
|
|
223
223
|
|
|
224
|
-

|
|
225
225
|

|
|
226
226
|
|
|
227
227
|
---
|
|
@@ -257,7 +257,7 @@ pipx install sourcecode
|
|
|
257
257
|
|
|
258
258
|
```bash
|
|
259
259
|
sourcecode version
|
|
260
|
-
# sourcecode 1.30.
|
|
260
|
+
# sourcecode 1.30.27
|
|
261
261
|
```
|
|
262
262
|
|
|
263
263
|
---
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Deterministic, behavior-aware codebase context for AI agents and PR review.**
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|

|
|
7
7
|
|
|
8
8
|
---
|
|
@@ -38,7 +38,7 @@ pipx install sourcecode
|
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
40
|
sourcecode version
|
|
41
|
-
# sourcecode 1.30.
|
|
41
|
+
# sourcecode 1.30.27
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
---
|
|
@@ -290,10 +290,18 @@ class ConfidenceAnalyzer:
|
|
|
290
290
|
elif production_eps and all(ep.runtime_relevance == "low" for ep in production_eps):
|
|
291
291
|
overall = _min_confidence([overall, "low"])
|
|
292
292
|
|
|
293
|
-
# Factor in architecture confidence when available
|
|
293
|
+
# Factor in architecture confidence when available.
|
|
294
|
+
# Key rule: if a pattern was detected (not None/"unknown"), arch.confidence="low"
|
|
295
|
+
# typically reflects missing documentation (no OpenAPI/ADR), not structural uncertainty.
|
|
296
|
+
# In that case, clamp the downgrade to "medium" so that high stack + high entry_points
|
|
297
|
+
# is not contradicted by a docs gap.
|
|
294
298
|
arch = sm.architecture
|
|
295
299
|
if arch is not None and arch.requested:
|
|
296
|
-
|
|
300
|
+
arch_conf_for_overall = arch.confidence
|
|
301
|
+
if arch.confidence == "low" and arch.pattern not in (None, "unknown"):
|
|
302
|
+
# Pattern was detected — low is docs-only, not structural; cap downgrade at medium
|
|
303
|
+
arch_conf_for_overall = "medium"
|
|
304
|
+
overall = _min_confidence([overall, arch_conf_for_overall])
|
|
297
305
|
if arch.pattern in (None, "unknown"):
|
|
298
306
|
# Architecture could not be inferred — don't let stack alone push to high
|
|
299
307
|
if overall == "high":
|
|
@@ -84,16 +84,17 @@ _JAVA_ANNOTATION_RE = re.compile(r'@(RestController|Controller|Service|Repositor
|
|
|
84
84
|
# (annotation_set, category, relevance, why_template)
|
|
85
85
|
# Checked in priority order; first match wins.
|
|
86
86
|
_JAVA_STEREOTYPE_RULES: list[tuple[frozenset, str, float, str]] = [
|
|
87
|
-
(frozenset({"EnableWebSecurity"}), "security",
|
|
88
|
-
(frozenset({"RestController"}), "api_endpoint",
|
|
89
|
-
(frozenset({"Controller", "RequestMapping"}), "api_endpoint",
|
|
90
|
-
(frozenset({"
|
|
91
|
-
(frozenset({"Service"}),
|
|
92
|
-
(frozenset({"
|
|
93
|
-
(frozenset({"
|
|
94
|
-
(frozenset({"
|
|
95
|
-
(frozenset({"
|
|
96
|
-
(frozenset({"
|
|
87
|
+
(frozenset({"EnableWebSecurity"}), "security", 0.85, "Spring Security configuration"),
|
|
88
|
+
(frozenset({"RestController"}), "api_endpoint", 0.90, "Spring REST controller — defines HTTP API surface"),
|
|
89
|
+
(frozenset({"Controller", "RequestMapping"}), "api_endpoint", 0.80, "Spring MVC controller"),
|
|
90
|
+
(frozenset({"ControllerAdvice"}), "exception_handler", 0.75, "Spring @ControllerAdvice — cross-cutting exception handling"),
|
|
91
|
+
(frozenset({"Service", "Transactional"}), "business_logic", 0.75, "Transactional service — business logic boundary"),
|
|
92
|
+
(frozenset({"Service"}), "business_logic", 0.65, "Spring service component"),
|
|
93
|
+
(frozenset({"Repository"}), "data_access", 0.65, "Spring repository — data access layer"),
|
|
94
|
+
(frozenset({"Mapper"}), "data_access", 0.65, "MyBatis mapper — SQL data access"),
|
|
95
|
+
(frozenset({"Configuration"}), "configuration", 0.70, "Spring configuration class"),
|
|
96
|
+
(frozenset({"Entity"}), "domain_model", 0.50, "JPA entity — domain model"),
|
|
97
|
+
(frozenset({"Data"}), "dto", 0.40, "Lombok DTO"),
|
|
97
98
|
]
|
|
98
99
|
|
|
99
100
|
# Categories produced by Java stereotype detection — used downstream to apply direct relevance
|
|
@@ -2596,6 +2596,10 @@ class TaskContextBuilder:
|
|
|
2596
2596
|
# These are INFERRED (LOW CONFIDENCE) — stem match, not annotation evidence.
|
|
2597
2597
|
if any(kw in stem_lower for kw in ("validator", "validation")):
|
|
2598
2598
|
return "validation_component"
|
|
2599
|
+
if any(kw in stem_lower for kw in ("filter", "interceptor", "aspect")):
|
|
2600
|
+
return "runtime_filter"
|
|
2601
|
+
if any(kw in stem_lower for kw in ("advice", "advise", "exceptionhandler", "errorhandler")):
|
|
2602
|
+
return "exception_handler"
|
|
2599
2603
|
if any(kw in stem_lower for kw in ("controller", "resource", "endpoint", "rest")):
|
|
2600
2604
|
return "external_interface"
|
|
2601
2605
|
if any(kw in stem_lower for kw in ("service", "svc", "usecase", "facade")):
|
|
@@ -251,3 +251,95 @@ class RankingEngine:
|
|
|
251
251
|
|
|
252
252
|
def is_auxiliary(self, path: str) -> bool:
|
|
253
253
|
return self._scorer.is_auxiliary(path)
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
# ---------------------------------------------------------------------------
|
|
257
|
+
# Mandatory scoring formula — deterministic 5-component impact model
|
|
258
|
+
# ---------------------------------------------------------------------------
|
|
259
|
+
|
|
260
|
+
# runtime_impact: execution-path role of the file
|
|
261
|
+
_RUNTIME_IMPACT: dict[str | None, float] = {
|
|
262
|
+
"api_endpoint": 1.0, # @RestController / @Controller
|
|
263
|
+
"security": 1.0, # @EnableWebSecurity / security filters
|
|
264
|
+
"runtime_core": 1.0, # confirmed production entrypoint
|
|
265
|
+
"cli_entrypoint": 1.0,
|
|
266
|
+
"exception_handler": 0.8, # @ControllerAdvice
|
|
267
|
+
"business_logic": 0.7, # @Service (with or without @Transactional)
|
|
268
|
+
"api_layer": 0.7, # API framework import (non-annotation evidence)
|
|
269
|
+
"data_access": 0.5, # @Repository / @Mapper
|
|
270
|
+
"database_layer": 0.5, # DB framework import
|
|
271
|
+
"infrastructure": 0.5, # infra dependency import
|
|
272
|
+
"configuration": 0.4, # @Configuration
|
|
273
|
+
"application_logic": 0.3, # code defs + imports, no framework annotation
|
|
274
|
+
"domain_model": 0.3, # @Entity / domain models
|
|
275
|
+
"dto": 0.2, # @Data / pure data carriers
|
|
276
|
+
"build_system": 0.15,
|
|
277
|
+
"tests": 0.1,
|
|
278
|
+
"tooling": 0.05,
|
|
279
|
+
None: 0.15, # unclassified source file
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
# framework_signal_strength: annotation / import evidence quality
|
|
283
|
+
# Spring annotation → 0.3; security component → +0.2 (total 0.5); import only → 0.2
|
|
284
|
+
_FRAMEWORK_SIGNAL: dict[str | None, float] = {
|
|
285
|
+
"security": 0.5, # Spring Security annotation + security component
|
|
286
|
+
"api_endpoint": 0.3, # @RestController / @Controller
|
|
287
|
+
"exception_handler": 0.3, # @ControllerAdvice
|
|
288
|
+
"business_logic": 0.3, # @Service
|
|
289
|
+
"data_access": 0.3, # @Repository / @Mapper
|
|
290
|
+
"configuration": 0.3, # @Configuration
|
|
291
|
+
"domain_model": 0.3, # JPA @Entity
|
|
292
|
+
"dto": 0.3, # Lombok @Data
|
|
293
|
+
"api_layer": 0.2, # framework import (weaker than annotation)
|
|
294
|
+
"database_layer": 0.2,
|
|
295
|
+
"infrastructure": 0.2,
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
# Normalization ceiling per evidence tier — used when spread < 0.40
|
|
299
|
+
_NORM_TARGET_HI: dict[str, float] = {
|
|
300
|
+
"api_endpoint": 0.90,
|
|
301
|
+
"security": 0.90,
|
|
302
|
+
"exception_handler": 0.82,
|
|
303
|
+
"business_logic": 0.80,
|
|
304
|
+
"api_layer": 0.80,
|
|
305
|
+
"data_access": 0.70,
|
|
306
|
+
"database_layer": 0.70,
|
|
307
|
+
"infrastructure": 0.70,
|
|
308
|
+
"configuration": 0.65,
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def resolve_runtime_impact(category: str | None) -> float:
|
|
313
|
+
"""Map FileClassifier category → runtime_impact [0.0, 1.0]."""
|
|
314
|
+
return _RUNTIME_IMPACT.get(category, _RUNTIME_IMPACT[None])
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def resolve_framework_signal(category: str | None) -> float:
|
|
318
|
+
"""Map FileClassifier category → framework_signal_strength [0.0, 0.5]."""
|
|
319
|
+
return _FRAMEWORK_SIGNAL.get(category, 0.0)
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def compute_impact_score(
|
|
323
|
+
runtime_impact: float,
|
|
324
|
+
dependency_centrality: float,
|
|
325
|
+
framework_signal_strength: float,
|
|
326
|
+
change_type_severity: float,
|
|
327
|
+
test_risk_factor: float,
|
|
328
|
+
) -> float:
|
|
329
|
+
"""Mandatory weighted scoring formula.
|
|
330
|
+
|
|
331
|
+
score = 0.35×runtime_impact + 0.25×dependency_centrality
|
|
332
|
+
+ 0.20×framework_signal_strength + 0.10×change_type_severity
|
|
333
|
+
+ 0.10×test_risk_factor
|
|
334
|
+
|
|
335
|
+
All inputs [0.0, 1.0]. Output clamped [0.0, 1.0].
|
|
336
|
+
Deterministic: same inputs always produce same output.
|
|
337
|
+
"""
|
|
338
|
+
raw = (
|
|
339
|
+
0.35 * runtime_impact
|
|
340
|
+
+ 0.25 * dependency_centrality
|
|
341
|
+
+ 0.20 * framework_signal_strength
|
|
342
|
+
+ 0.10 * change_type_severity
|
|
343
|
+
+ 0.10 * test_risk_factor
|
|
344
|
+
)
|
|
345
|
+
return max(0.0, min(1.0, raw))
|
|
@@ -660,6 +660,116 @@ def _jndi_datasources(sm: "SourceMap") -> "Optional[list[dict[str, Any]]]":
|
|
|
660
660
|
return datasources
|
|
661
661
|
|
|
662
662
|
|
|
663
|
+
def _tiered_display_score(
|
|
664
|
+
pre_bonus_combined: float,
|
|
665
|
+
file_class: Any,
|
|
666
|
+
path: str,
|
|
667
|
+
entry_paths: set,
|
|
668
|
+
has_structural_signals: bool = False,
|
|
669
|
+
) -> float:
|
|
670
|
+
"""Evidence-tiered display score [0.0, 1.0].
|
|
671
|
+
|
|
672
|
+
Tiers enforce: strong evidence > medium evidence > filesystem/path only.
|
|
673
|
+
M3 sort bonuses must NOT be included in pre_bonus_combined — they are for
|
|
674
|
+
ordering only and must not inflate the displayed score.
|
|
675
|
+
|
|
676
|
+
Tier ceilings:
|
|
677
|
+
T1 confirmed production entrypoint 0.92–1.00
|
|
678
|
+
T2 entrypoint (weaker category) 0.80–0.91
|
|
679
|
+
T3 annotation-confirmed stereotype 0.40–0.90 (table-calibrated)
|
|
680
|
+
T4 framework import evidence 0.55–0.79
|
|
681
|
+
T5 code definitions + imports 0.38–0.54
|
|
682
|
+
T6 build manifest / tooling / test 0.25–0.45
|
|
683
|
+
T7 path/filesystem signal only 0.10–0.39
|
|
684
|
+
"""
|
|
685
|
+
from sourcecode.file_classifier import JAVA_STEREOTYPE_CATEGORIES
|
|
686
|
+
|
|
687
|
+
cat = file_class.category if file_class else None
|
|
688
|
+
base_rel = file_class.relevance if file_class else 0.0
|
|
689
|
+
|
|
690
|
+
# T1: confirmed production entrypoint
|
|
691
|
+
if path in entry_paths and cat in ("runtime_core", "cli_entrypoint"):
|
|
692
|
+
return round(min(1.0, max(0.92, base_rel)), 3)
|
|
693
|
+
|
|
694
|
+
# T2: in entry_paths but weaker evidence category
|
|
695
|
+
if path in entry_paths:
|
|
696
|
+
return round(min(0.91, max(0.80, pre_bonus_combined / 2.0)), 3)
|
|
697
|
+
|
|
698
|
+
# T3: annotation-confirmed stereotype — table values are already calibrated
|
|
699
|
+
if file_class and cat in JAVA_STEREOTYPE_CATEGORIES:
|
|
700
|
+
return round(base_rel, 3)
|
|
701
|
+
|
|
702
|
+
# T4: framework import evidence (medium strength)
|
|
703
|
+
if cat in ("api_layer", "database_layer", "infrastructure"):
|
|
704
|
+
return round(min(0.79, max(0.55, pre_bonus_combined / 2.0)), 3)
|
|
705
|
+
|
|
706
|
+
# T5: code definitions with imports (medium-low)
|
|
707
|
+
if cat in ("application_logic", "domain_model"):
|
|
708
|
+
return round(min(0.54, max(0.38, pre_bonus_combined / 2.0)), 3)
|
|
709
|
+
|
|
710
|
+
# T6: build manifest / tooling / test
|
|
711
|
+
if cat == "build_system":
|
|
712
|
+
return round(min(0.45, base_rel), 3)
|
|
713
|
+
if cat in ("tests", "tooling"):
|
|
714
|
+
return round(min(0.35, base_rel), 3)
|
|
715
|
+
|
|
716
|
+
# T7: no content classification — filesystem/structural signals only
|
|
717
|
+
# has_structural_signals: fan_in, churn, export — allows up to 0.54
|
|
718
|
+
# pure path/filename only — hard cap 0.39
|
|
719
|
+
if has_structural_signals:
|
|
720
|
+
return round(min(0.54, max(0.10, pre_bonus_combined / 2.0)), 3)
|
|
721
|
+
return round(min(0.39, max(0.10, pre_bonus_combined / 2.0)), 3)
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
def _build_file_signals(
|
|
725
|
+
file_class: Any,
|
|
726
|
+
path: str,
|
|
727
|
+
entry_paths: set,
|
|
728
|
+
fs_reasons: list,
|
|
729
|
+
sem_hub: float,
|
|
730
|
+
) -> list[dict]:
|
|
731
|
+
"""Minimal per-file signal breakdown: what contributed to this file's score."""
|
|
732
|
+
from sourcecode.file_classifier import JAVA_STEREOTYPE_CATEGORIES
|
|
733
|
+
|
|
734
|
+
signals: list[dict] = []
|
|
735
|
+
|
|
736
|
+
if path in entry_paths:
|
|
737
|
+
signals.append({"type": "runtime_entrypoint", "strength": "strong"})
|
|
738
|
+
|
|
739
|
+
if file_class:
|
|
740
|
+
cat = file_class.category
|
|
741
|
+
if cat in JAVA_STEREOTYPE_CATEGORIES:
|
|
742
|
+
signals.append({"type": "framework_annotation", "strength": "strong"})
|
|
743
|
+
elif cat in ("api_layer", "database_layer", "infrastructure"):
|
|
744
|
+
ev = [e for e in (file_class.evidence or [])[:2] if e]
|
|
745
|
+
signals.append({"type": "framework_import", "strength": "medium", "evidence": ev})
|
|
746
|
+
elif cat in ("application_logic",):
|
|
747
|
+
signals.append({"type": "code_definitions_with_imports", "strength": "medium"})
|
|
748
|
+
elif cat in ("domain_model",):
|
|
749
|
+
signals.append({"type": "domain_model_definitions", "strength": "medium"})
|
|
750
|
+
elif cat in ("build_system",):
|
|
751
|
+
signals.append({"type": "build_manifest", "strength": "medium"})
|
|
752
|
+
|
|
753
|
+
for r in fs_reasons:
|
|
754
|
+
r_lower = r.lower()
|
|
755
|
+
if "import centrality" in r_lower or "imported by" in r_lower:
|
|
756
|
+
signals.append({"type": "import_centrality", "strength": "medium"})
|
|
757
|
+
elif "hub module" in r_lower:
|
|
758
|
+
signals.append({"type": "hub_module", "strength": "medium"})
|
|
759
|
+
elif "recent churn" in r_lower:
|
|
760
|
+
signals.append({"type": "git_churn", "strength": "medium"})
|
|
761
|
+
elif "uncommitted" in r_lower:
|
|
762
|
+
signals.append({"type": "uncommitted_changes", "strength": "medium"})
|
|
763
|
+
|
|
764
|
+
if sem_hub >= 0.15:
|
|
765
|
+
signals.append({"type": "call_graph_hub", "strength": "strong"})
|
|
766
|
+
|
|
767
|
+
if not signals:
|
|
768
|
+
signals.append({"type": "filesystem_path", "strength": "weak"})
|
|
769
|
+
|
|
770
|
+
return signals
|
|
771
|
+
|
|
772
|
+
|
|
663
773
|
def _file_relevance(sm: SourceMap, *, limit: int = _FILE_RELEVANCE_LIMIT) -> list[dict[str, Any]]:
|
|
664
774
|
from sourcecode.ranking_engine import RankingEngine
|
|
665
775
|
|
|
@@ -692,13 +802,13 @@ def _file_relevance(sm: SourceMap, *, limit: int = _FILE_RELEVANCE_LIMIT) -> lis
|
|
|
692
802
|
semantic_hub_scores[p] = h.get("importance_score", 0.0) / max_importance
|
|
693
803
|
|
|
694
804
|
entry_paths = {ep.path for ep in sm.entry_points}
|
|
695
|
-
# REST/MVC controllers are HTTP surface — surface before @Transactional services
|
|
696
|
-
_rest_ctrl_paths = {
|
|
697
|
-
ep.path for ep in sm.entry_points
|
|
698
|
-
if getattr(ep, "kind", "") in {"rest_controller", "mvc_controller"}
|
|
699
|
-
}
|
|
700
805
|
scored: list[tuple[float, dict[str, Any]]] = []
|
|
701
806
|
|
|
807
|
+
from sourcecode.ranking_engine import (
|
|
808
|
+
compute_impact_score, resolve_runtime_impact, resolve_framework_signal,
|
|
809
|
+
_NORM_TARGET_HI,
|
|
810
|
+
)
|
|
811
|
+
|
|
702
812
|
for path in sm.file_paths:
|
|
703
813
|
file_class = classifier.classify(path)
|
|
704
814
|
fs = engine.score(
|
|
@@ -711,96 +821,129 @@ def _file_relevance(sm: SourceMap, *, limit: int = _FILE_RELEVANCE_LIMIT) -> lis
|
|
|
711
821
|
if fs.score < -50: # hard noise
|
|
712
822
|
continue
|
|
713
823
|
|
|
714
|
-
content_rel = file_class.relevance if file_class else 0.0
|
|
715
|
-
# Semantic hub bonus: normalised call-graph centrality adds up to +0.30
|
|
716
|
-
sem_hub = semantic_hub_scores.get(path, 0.0) * 0.30
|
|
717
|
-
combined = fs.score + content_rel + sem_hub
|
|
718
|
-
# REST controller boost: surface above @Transactional service files
|
|
719
|
-
if path in _rest_ctrl_paths:
|
|
720
|
-
combined += 2.0
|
|
721
|
-
|
|
722
|
-
# M3: Structural importance scoring — priority over alphabetical ordering.
|
|
723
824
|
stem = Path(path).stem
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
#
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
#
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
))
|
|
742
|
-
|
|
743
|
-
#
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
825
|
+
cat = file_class.category if file_class else None
|
|
826
|
+
|
|
827
|
+
# ── Component 1: runtime_impact — execution-path role ─────────────────
|
|
828
|
+
runtime_impact = resolve_runtime_impact(cat)
|
|
829
|
+
|
|
830
|
+
# ── Component 2: dependency_centrality — call-graph importance ─────────
|
|
831
|
+
# Entry points treat external HTTP/CLI callers as high centrality.
|
|
832
|
+
# Isolated files (no semantic data) score 0.0 — negative weighting by omission.
|
|
833
|
+
dep_centrality = semantic_hub_scores.get(path, 0.0)
|
|
834
|
+
if path in entry_paths:
|
|
835
|
+
dep_centrality = max(dep_centrality, 0.8)
|
|
836
|
+
|
|
837
|
+
# ── Component 3: framework_signal_strength — annotation quality ─────────
|
|
838
|
+
fw_signal = resolve_framework_signal(cat)
|
|
839
|
+
|
|
840
|
+
# ── Component 4: change_type_severity — git churn as structural proxy ───
|
|
841
|
+
churn = git_churn.get(path, 0)
|
|
842
|
+
change_sev = min(churn / max(max_churn, 1), 1.0) * 0.8
|
|
843
|
+
|
|
844
|
+
# ── Component 5: test_risk_factor — no per-file coverage data ──────────
|
|
845
|
+
test_risk = 0.2
|
|
846
|
+
|
|
847
|
+
formula_raw = compute_impact_score(
|
|
848
|
+
runtime_impact, dep_centrality, fw_signal, change_sev, test_risk
|
|
849
|
+
)
|
|
850
|
+
|
|
851
|
+
# T1 override: confirmed production entrypoints → 0.92–1.00.
|
|
852
|
+
# Only runtime_core / cli_entrypoint categories justify scores ≥ 0.92.
|
|
853
|
+
if path in entry_paths and cat in ("runtime_core", "cli_entrypoint"):
|
|
854
|
+
score_val = round(
|
|
855
|
+
min(1.0, max(0.92, file_class.relevance if file_class else 0.92)), 3
|
|
856
|
+
)
|
|
857
|
+
else:
|
|
858
|
+
score_val = round(formula_raw, 3)
|
|
859
|
+
|
|
860
|
+
# Visibility threshold: formula score or high-relevance content exception.
|
|
861
|
+
if score_val < _FILE_RELEVANCE_MIN_COMBINED:
|
|
751
862
|
if not (file_class
|
|
752
863
|
and file_class.relevance > 0.45
|
|
753
864
|
and file_class.confidence in {"high", "medium"}):
|
|
754
865
|
continue
|
|
755
866
|
|
|
756
|
-
# Suppress low-confidence auxiliary/config files
|
|
867
|
+
# Suppress low-confidence auxiliary/config files
|
|
757
868
|
if (file_class
|
|
758
869
|
and file_class.confidence == "low"
|
|
759
870
|
and file_class.category in {"config", "auxiliary"}
|
|
760
|
-
and
|
|
871
|
+
and score_val < 0.45):
|
|
761
872
|
continue
|
|
762
873
|
|
|
763
|
-
#
|
|
764
|
-
#
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
874
|
+
# relevance: content evidence only — intentionally diverges from score
|
|
875
|
+
# when dep_centrality or churn are non-zero (score ≠ relevance invariant)
|
|
876
|
+
relevance_val = round(file_class.relevance, 3) if file_class else round(
|
|
877
|
+
min(0.39, max(0.10, runtime_impact)), 3
|
|
878
|
+
)
|
|
879
|
+
|
|
880
|
+
# sem_hub retained for signal reporting only — not used in score formula
|
|
881
|
+
sem_hub = semantic_hub_scores.get(path, 0.0) * 0.30
|
|
882
|
+
ranking_reasons = [r for r in fs.reasons if r != "source file"]
|
|
883
|
+
if sem_hub >= 0.15:
|
|
884
|
+
ranking_reasons.append("call graph hub")
|
|
885
|
+
|
|
886
|
+
signals = _build_file_signals(file_class, path, entry_paths, ranking_reasons, sem_hub)
|
|
770
887
|
|
|
771
888
|
item: dict[str, Any] = {
|
|
772
889
|
"path": path,
|
|
773
890
|
"category": file_class.category if file_class else "source",
|
|
774
891
|
"confidence": file_class.confidence if file_class else "low",
|
|
892
|
+
"score": score_val,
|
|
775
893
|
"relevance": relevance_val,
|
|
776
|
-
"score": relevance_val,
|
|
777
894
|
"reason": file_class.reason if file_class else (fs.reasons[0] if fs.reasons else "source file"),
|
|
778
895
|
"evidence": file_class.evidence if file_class else [],
|
|
896
|
+
"signals": signals,
|
|
779
897
|
}
|
|
780
898
|
|
|
781
|
-
ranking_reasons = [r for r in fs.reasons if r != "source file"]
|
|
782
|
-
if sem_hub >= 0.15:
|
|
783
|
-
ranking_reasons.append("call graph hub")
|
|
784
899
|
if ranking_reasons:
|
|
785
900
|
item["ranking_reasons"] = ranking_reasons
|
|
786
901
|
|
|
787
|
-
# Override
|
|
902
|
+
# Override: universal base controller classes score as runtime_core
|
|
788
903
|
if any(k in stem for k in ("GenericRestController", "GenericCRUDRestController")):
|
|
789
904
|
item["category"] = "runtime_core"
|
|
790
|
-
item["relevance"] = 0.95
|
|
791
905
|
item["score"] = 0.95
|
|
906
|
+
item["relevance"] = 0.95
|
|
792
907
|
item["reason"] = (
|
|
793
908
|
"base class for all REST controllers — extends this to get "
|
|
794
909
|
"centralized exception handling via handlerException()"
|
|
795
910
|
)
|
|
796
911
|
item["evidence"] = ["base_rest_controller"]
|
|
797
912
|
item["ranking_reasons"] = ["universal base class", "exception handling contract"]
|
|
913
|
+
item["signals"] = [{"type": "framework_annotation", "strength": "strong"}]
|
|
798
914
|
|
|
799
|
-
|
|
915
|
+
# sort_key = final score (rank consistency: score order = output order)
|
|
916
|
+
scored.append((item["score"], item))
|
|
800
917
|
|
|
801
|
-
#
|
|
918
|
+
# Initial sort: score desc, path asc for deterministic tie-break
|
|
802
919
|
scored.sort(key=lambda x: (-x[0], x[1]["path"]))
|
|
803
920
|
|
|
921
|
+
# Normalization: enforce minimum spread ≥ 0.4 among non-T1 files.
|
|
922
|
+
# T1 files (confirmed entrypoints, 0.92–1.0) are excluded — already correct.
|
|
923
|
+
# Prevents score compression when structural signals (--semantics, git) absent.
|
|
924
|
+
_nonep = [(sk, it) for sk, it in scored if it["path"] not in entry_paths]
|
|
925
|
+
if len(_nonep) > 1:
|
|
926
|
+
_vals = [it["score"] for _, it in _nonep]
|
|
927
|
+
_lo, _hi = min(_vals), max(_vals)
|
|
928
|
+
_spread = _hi - _lo
|
|
929
|
+
if _spread < 0.40:
|
|
930
|
+
_top_cat = max(_nonep, key=lambda x: x[1]["score"])[1].get("category", "")
|
|
931
|
+
_target_hi = _NORM_TARGET_HI.get(_top_cat, 0.60)
|
|
932
|
+
_target_lo = max(0.10, _target_hi - 0.50)
|
|
933
|
+
if _spread > 0:
|
|
934
|
+
_scale = (_target_hi - _target_lo) / _spread
|
|
935
|
+
for _, it in _nonep:
|
|
936
|
+
it["score"] = round(
|
|
937
|
+
max(0.0, min(1.0, _target_lo + (it["score"] - _lo) * _scale)), 3
|
|
938
|
+
)
|
|
939
|
+
else:
|
|
940
|
+
_mid = round((_target_hi + _target_lo) / 2.0, 3)
|
|
941
|
+
for _, it in _nonep:
|
|
942
|
+
it["score"] = _mid
|
|
943
|
+
|
|
944
|
+
# Re-sort by final score to guarantee rank consistency after normalization
|
|
945
|
+
scored.sort(key=lambda x: (-x[1]["score"], x[1]["path"]))
|
|
946
|
+
|
|
804
947
|
# Diversity cap: at most half the budget from any single category.
|
|
805
948
|
# Prevents 10/10 controllers drowning out services, repositories, domain.
|
|
806
949
|
_CAT_CAP = max(1, limit // 2)
|