sourcecode 1.30.13__tar.gz → 1.30.15__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.15/.continue-here.md +231 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/PKG-INFO +48 -25
- {sourcecode-1.30.13 → sourcecode-1.30.15}/README.md +47 -24
- {sourcecode-1.30.13 → sourcecode-1.30.15}/pyproject.toml +1 -1
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/__init__.py +1 -1
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/cli.py +11 -1
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/flow_analyzer.py +60 -35
- sourcecode-1.30.15/src/sourcecode/pr_comment_renderer.py +369 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/prepare_context.py +111 -70
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/repository_ir.py +498 -24
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_repository_ir.py +623 -12
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_v1_10_regressions.py +1 -1
- sourcecode-1.30.13/.continue-here.md +0 -166
- {sourcecode-1.30.13 → sourcecode-1.30.15}/.agents/skills/source-command-gsd-join-discord/SKILL.md +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/.agents/skills/source-command-gsd-review-backlog/SKILL.md +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/.agents/skills/source-command-gsd-workstreams/SKILL.md +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/.gitignore +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/.ruff.toml +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/CONTRIBUTING.md +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/LICENSE +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/SECURITY.md +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/docs/privacy.md +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/docs/schema.md +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/raw +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/run_cli.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/classifier.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/progress.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/redactor.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/scanner.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/schema.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/serializer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/src/sourcecode/workspace.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/__init__.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/conftest.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/coverage.xml +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/fastapi_app/pyproject.toml +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/fastapi_app/src/main.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/go_service/cmd/api/main.go +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/go_service/go.mod +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/jacoco.xml +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/latin1_sample.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/latin1_sample_iso.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/lcov.info +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/nextjs_app/app/page.tsx +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/nextjs_app/package.json +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/nextjs_app/pnpm-lock.yaml +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/pnpm_monorepo/apps/web/app/page.tsx +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/pnpm_monorepo/apps/web/package.json +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/pnpm_monorepo/packages/api/main.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/pnpm_monorepo/packages/api/pyproject.toml +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/pnpm_monorepo/pnpm-workspace.yaml +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/pom.xml +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/application/service/FindAusenteService.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/domain/entities/Ausente.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/infrastructure/rest/AusenteRestController.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/application/service/FindAutocoberturasService.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/domain/entities/Autocoberturas.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/infrastructure/rest/AutocoberturasRestController.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/application/service/FindCalendarioTrabajadorService.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/domain/entities/CalendarioTrabajador.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/infrastructure/rest/CalendarioTrabajadorRestController.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/application/service/FindDepartamentoService.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/domain/entities/Departamento.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/infrastructure/rest/DepartamentoRestController.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/application/service/FindEmpleadoService.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/domain/entities/Empleado.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/infrastructure/rest/EmpleadoRestController.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/DemoApplication.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/config/FilterConfig.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/domain/Health.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/mapper/HealthMapper.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/repository/HealthRepository.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/service/HealthService.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/HealthRestController.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/NominaRestController.java +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/resources/application-dev.yml +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/resources/application.yml +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/fixtures/spring_boot_minimal/src/main/resources/mapper/HealthMapper.xml +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_architecture_analyzer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_architecture_summary.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_ast_extractor.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_block1_reliability.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_block2_coverage.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_block5_quality.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_bug_fixes_v16.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_classifier.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_cli.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_code_notes_analyzer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_context_scorer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_contract_pipeline.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_coverage_parser.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_cross_consistency.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_dependency_analyzer_node_python.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_dependency_analyzer_polyglot.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_dependency_schema.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_detector_dotnet.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_detector_go_rust_java.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_detector_nodejs.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_detector_php_ruby_dart.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_detector_python.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_detector_universal_managed.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_detector_universal_systems.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_detectors_base.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_doc_analyzer_jsdom.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_doc_analyzer_python.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_encoding_regression.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_graph_analyzer_polyglot.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_graph_analyzer_python_node.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_graph_schema.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_hybrid_inference.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_integration.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_integration_dependencies.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_integration_detection.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_integration_docs.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_integration_graph_modules.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_integration_lqn.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_integration_metrics.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_integration_multistack.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_integration_semantics.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_integration_universal.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_java_spring_integration.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_metrics_analyzer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_packaging.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_phase1_improvements.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_pipeline_integrity.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_real_projects.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_redactor.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_scanner.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_schema.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_schema_normalization.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_semantic_analyzer_node.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_semantic_analyzer_python.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_semantic_import_resolution.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_semantic_schema.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_signal_hierarchy.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_summarizer.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_surface_honesty.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_task_differentiation.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_telemetry.py +0 -0
- {sourcecode-1.30.13 → sourcecode-1.30.15}/tests/test_workspace_analyzer.py +0 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# Continue Here — atlas-cli sesión 14
|
|
2
|
+
|
|
3
|
+
**Paused:** 2026-05-17 (sesión 14)
|
|
4
|
+
**Repo:** `/Users/user/Downloads/atlas-cli`
|
|
5
|
+
**Branch:** master
|
|
6
|
+
**Working tree:** 4 ficheros modificados, SIN commit (trabajo listo para commit)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Trabajo de esta sesión (NO commiteado)
|
|
11
|
+
|
|
12
|
+
Esta sesión completó 3 tareas sobre `repository_ir.py`. Todo el trabajo incluye la sesión 13 (stable IDs) + sesión 14 (route diffing + reverse graph). Hacer UN solo commit con todo.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
### Tarea 1 (sesión 13): Rearchitecture Directive — eliminar lenguaje especulativo
|
|
17
|
+
|
|
18
|
+
**Ficheros:** `src/sourcecode/prepare_context.py`, `src/sourcecode/flow_analyzer.py`
|
|
19
|
+
|
|
20
|
+
| Eliminado | Reemplazado con |
|
|
21
|
+
|---|---|
|
|
22
|
+
| `_ARTIFACT_CHANGE_EFFECT` con "may affect/inferred from role" | Labels estructurales: `"HTTP routing layer (request-to-handler mapping)"` |
|
|
23
|
+
| `"type": "inferred"` en `_role_obj` | `{basis, has_annotation_signal, has_symbol_signal}` |
|
|
24
|
+
| `"confidence": _f_conf` en runtime change entries | `"evidence_completeness"` del impact dict |
|
|
25
|
+
| `_score_to_confidence()` function | Deleted completely |
|
|
26
|
+
| `"confidence": score_band` en `impact_score_per_file` | `"evidence": {has_reverse_edges, has_route_diff, has_security_diff, has_wiring_evidence}` |
|
|
27
|
+
| `behavioral_changes` sin graph evidence | Gateado en `has_graph_evidence == True` |
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
### Tarea 2 (sesión 13): Stable Symbol Identities
|
|
32
|
+
|
|
33
|
+
**Ficheros:** `src/sourcecode/repository_ir.py`, `tests/test_repository_ir.py`
|
|
34
|
+
|
|
35
|
+
**Nuevas funciones helper:**
|
|
36
|
+
- `_normalize_type_name(raw)` — strip annotations/modifiers/param names → solo tipo
|
|
37
|
+
- `_parse_param_types(params_str)` — `"Long id, String name"` → `["Long", "String"]` (depth-aware, maneja generics)
|
|
38
|
+
- `_compute_stable_id(package, class_simple, kind, name, param_types, return_type)` — ID determinista
|
|
39
|
+
|
|
40
|
+
**`SymbolRecord`** — 8 nuevos campos: `stable_id`, `symbol_kind`, `canonical_name`, `source_file`, `signature`, `param_types`, `return_type`, `annotation_values`
|
|
41
|
+
|
|
42
|
+
**`symbol_kind` values:** `enum`, `annotation`, `endpoint`, `bean`, `constructor` (además de `class`, `interface`, `method`, `field`)
|
|
43
|
+
|
|
44
|
+
**Formato stable_id:**
|
|
45
|
+
```
|
|
46
|
+
{package}:{class_simple}:{kind}:{name}[:{(param_types)}[:{return_type}]]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
### Tarea 3 (sesión 14): Spring Route-Surface Diffing
|
|
52
|
+
|
|
53
|
+
**Ficheros:** `src/sourcecode/repository_ir.py`, `tests/test_repository_ir.py`
|
|
54
|
+
|
|
55
|
+
**Qué se implementó:**
|
|
56
|
+
|
|
57
|
+
| Componente | Cambio |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `_ANN_WITH_ARGS_RE` | Captura args de anotaciones (`@GetMapping("/path")`) |
|
|
60
|
+
| `SymbolRecord.annotation_values` | `dict[str, str]` — ann_name → raw args string |
|
|
61
|
+
| `_HTTP_METHOD_MAP` | `@GetMapping → GET` etc. |
|
|
62
|
+
| `_parse_route_path/http_method/extras` | Extraen path, method, produces/consumes |
|
|
63
|
+
| `_is_route_symbol / _route_annotation_name / _enclosing_class` | Helpers de routes |
|
|
64
|
+
| `_symbol_fingerprint` | Incluye valores de route annotations — cambio de path → fingerprint cambia |
|
|
65
|
+
| `_diff_symbols` | Detecta `route_surface_change` antes de `annotation_change` genérico |
|
|
66
|
+
| `_DIFF_INTENSITY_MAP` | `route_surface_change: 1.0` |
|
|
67
|
+
| `_diff_routes` | Diff estructurado: old/new path, HTTP method, produces/consumes, evidence dict |
|
|
68
|
+
| `_assemble` | Emite `route_surface: [...]` |
|
|
69
|
+
|
|
70
|
+
**Output cuando route cambia:**
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"route_surface": [{
|
|
74
|
+
"symbol": "com.example.HealthController#health",
|
|
75
|
+
"controller": "com.example.HealthController",
|
|
76
|
+
"route_surface_changed": true,
|
|
77
|
+
"old_route": "/health",
|
|
78
|
+
"new_route": "/health/v3",
|
|
79
|
+
"stable_id": "com.example:HealthController:endpoint:health:():String",
|
|
80
|
+
"evidence": {
|
|
81
|
+
"annotation_value_changed": true,
|
|
82
|
+
"mapping_annotation": "RequestMapping",
|
|
83
|
+
"old_value": "/health",
|
|
84
|
+
"new_value": "/health/v3"
|
|
85
|
+
}
|
|
86
|
+
}]
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### Tarea 4 (sesión 14): Reverse Impact Graph
|
|
93
|
+
|
|
94
|
+
**Ficheros:** `src/sourcecode/repository_ir.py`, `tests/test_repository_ir.py`
|
|
95
|
+
|
|
96
|
+
**Problema raíz resuelto:** `_propagate_impact` traversaba grafo hacia ADELANTE (si A cambia → impacta B que A usa). Incorrecto. Impact analysis necesita grafo INVERSO (si A cambia → impacta quién DEPENDE de A).
|
|
97
|
+
|
|
98
|
+
**Qué se implementó:**
|
|
99
|
+
|
|
100
|
+
| Componente | Cambio |
|
|
101
|
+
|---|---|
|
|
102
|
+
| `contained_in` edges | `_build_relations` emite `method/field → enclosing class` |
|
|
103
|
+
| `_build_reverse_adjacency` | Invierte todas las relaciones (excluye `annotated_with`, `mapped_to`) |
|
|
104
|
+
| `_EDGE_REASON_TEMPLATES` + `_edge_reason` | Edge → string legible |
|
|
105
|
+
| `_bfs_impact_with_paths` | Reemplaza `_propagate_impact`. BFS en grafo inverso con path tracking |
|
|
106
|
+
| `enclosing_seeds` param | Omite `contained_in` edges al sembrar desde clase enclosing para no incluir métodos hermanos |
|
|
107
|
+
| `reverse_graph` en output | `{target_fqn: {edge_type: [from_fqn, ...]}}` — índice para agentes |
|
|
108
|
+
|
|
109
|
+
**Cadena de propagación funcional:**
|
|
110
|
+
```
|
|
111
|
+
UserRepository#findById cambia →
|
|
112
|
+
[1] UserService ← "UserService depends on UserRepository (import)"
|
|
113
|
+
[2] UserService#getUser ← "... is a member of UserService"
|
|
114
|
+
[2] OrderController ← "OrderController depends on UserService (import)"
|
|
115
|
+
[3] OrderController#getUser ← "... is a member of OrderController"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
`UserRepository#save` (hermano, sin cambios) correctamente excluido.
|
|
119
|
+
|
|
120
|
+
**Cada entidad impactada expone:**
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"entity": "com.example.web.OrderController",
|
|
124
|
+
"depth": 2,
|
|
125
|
+
"impact_score": 0.0113,
|
|
126
|
+
"via": "com.example.service.UserService",
|
|
127
|
+
"graph_path": ["com.example.repo.UserRepository", "com.example.service.UserService", "com.example.web.OrderController"],
|
|
128
|
+
"included_because": [
|
|
129
|
+
"com.example.service.UserService depends on com.example.repo.UserRepository (import)",
|
|
130
|
+
"com.example.web.OrderController depends on com.example.service.UserService (import)"
|
|
131
|
+
]
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Estado de tests
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
920 passed, 3 skipped (era 885 antes de sesión 13)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Pre-existing failures (no tocar):
|
|
144
|
+
- `tests/test_block2_coverage.py` — bug `DocRecord` en `doc_analyzer.py`
|
|
145
|
+
- `tests/test_dependency_analyzer_node_python.py::test_python_requirements_without_lockfile_keeps_declared_versions`
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Cambios sin commitear
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
src/sourcecode/flow_analyzer.py | 22 +-
|
|
153
|
+
src/sourcecode/prepare_context.py | 113 ++++---
|
|
154
|
+
src/sourcecode/repository_ir.py | 522 +++++++++++++++++++++++++++++--
|
|
155
|
+
tests/test_repository_ir.py | 635 +++++++++++++++++++++++++++++++++++++-
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Para commitear TODO (primera acción al retomar):**
|
|
159
|
+
```bash
|
|
160
|
+
cd /Users/user/Downloads/atlas-cli
|
|
161
|
+
git add src/sourcecode/flow_analyzer.py \
|
|
162
|
+
src/sourcecode/prepare_context.py \
|
|
163
|
+
src/sourcecode/repository_ir.py \
|
|
164
|
+
tests/test_repository_ir.py
|
|
165
|
+
|
|
166
|
+
git commit -m "feat: stable IDs + route-surface diffing + reverse impact graph
|
|
167
|
+
|
|
168
|
+
- Stable deterministic IDs for all symbol kinds (class/interface/enum/
|
|
169
|
+
method/constructor/field/endpoint/bean) — survives formatting/body changes
|
|
170
|
+
- symbol_kind, canonical_name, signature, annotation_values on all graph nodes
|
|
171
|
+
- Replace heuristic confidence scoring with evidence completeness dicts
|
|
172
|
+
- Remove speculative behavioral prose (may affect / inferred from role)
|
|
173
|
+
- Gate behavioral_changes on has_graph_evidence
|
|
174
|
+
- Route-surface diffing: annotation value changes detected as route_surface_change;
|
|
175
|
+
evidence dict with old/new path, HTTP method, produces/consumes
|
|
176
|
+
- Reverse impact graph: BFS on inverted graph; each impacted symbol carries
|
|
177
|
+
graph_path + included_because explaining the dependency chain
|
|
178
|
+
- contained_in edges expose method/field → class membership for propagation
|
|
179
|
+
- reverse_graph output: {target: {edge_type: [from_fqns]}} for agent queries
|
|
180
|
+
- 35 new acceptance tests (920 total passing)"
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Pendientes (próxima sesión)
|
|
186
|
+
|
|
187
|
+
### Prioridad alta
|
|
188
|
+
1. **Spring bean wiring graph** — `_build_relations` ya emite `injects` edges para `@Autowired` fields. Falta: trazar grafo completo `@Configuration → @Bean → @Autowired` y exponer como `wiring_graph` en IR output.
|
|
189
|
+
|
|
190
|
+
2. **Smoke test en repo spring-boot real:**
|
|
191
|
+
```bash
|
|
192
|
+
cd ~/Documents/workspace/spring-boot-realworld-example-app
|
|
193
|
+
sourcecode repo-ir . --since HEAD~1 2>/dev/null | python3 -c "
|
|
194
|
+
import json, sys
|
|
195
|
+
d = json.load(sys.stdin)
|
|
196
|
+
print('schema:', d['schema_version'])
|
|
197
|
+
print('nodes:', len(d['graph']['nodes']))
|
|
198
|
+
print('route_surface:', d.get('route_surface', []))
|
|
199
|
+
rg = d.get('reverse_graph', {})
|
|
200
|
+
print('reverse_graph keys:', len(rg))
|
|
201
|
+
"
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
3. **Transaction boundary tracking** — `@Transactional` ya detectado. Falta: emitir `transactional_boundary` edges.
|
|
205
|
+
|
|
206
|
+
### Prioridad media
|
|
207
|
+
4. **`_diff_routes` para `@RequestMapping` en clase** — si class-level mapping cambia (`/api/v1` → `/api/v2`), debería propagarse a todos los endpoints del controller.
|
|
208
|
+
|
|
209
|
+
5. **Tests unitarios para `_classify_diff_severity`** — sin cobertura
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Para retomar
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
cd /Users/user/Downloads/atlas-cli
|
|
217
|
+
git log --oneline -5 # último commit: 31aa91a
|
|
218
|
+
git status # debe mostrar 4 ficheros modificados sin trackear
|
|
219
|
+
|
|
220
|
+
python3 -m pytest tests/ \
|
|
221
|
+
--ignore=tests/test_block2_coverage.py \
|
|
222
|
+
--ignore=tests/test_dependency_analyzer_node_python.py \
|
|
223
|
+
-q
|
|
224
|
+
# Expected: 920 passed, 3 skipped
|
|
225
|
+
|
|
226
|
+
# Primera acción: commitear (comando arriba)
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
*Pausado 2026-05-17 sesión 14 — gsd:pause-work*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 1.30.
|
|
3
|
+
Version: 1.30.15
|
|
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.15
|
|
261
261
|
```
|
|
262
262
|
|
|
263
263
|
---
|
|
@@ -353,6 +353,7 @@ sourcecode prepare-context TASK [PATH] [OPTIONS]
|
|
|
353
353
|
|--------|-------------|
|
|
354
354
|
| `--since REF` | Git ref for `delta` task (e.g. `HEAD~3`, `main`, `v1.2.0`). Required for `delta`; ignored for other tasks. |
|
|
355
355
|
| `--symptom TEXT` | *(fix-bug only)* Keyword hint for the bug — boosts matching files and surfaces related code notes. |
|
|
356
|
+
| `--format TEXT` | Output format: `json` (default) \| `github-comment` (Markdown PR comment, `review-pr` only). |
|
|
356
357
|
| `--llm-prompt` | Append a ready-to-use LLM prompt to the output. |
|
|
357
358
|
| `--dry-run` | Show what would be analyzed without running it. |
|
|
358
359
|
| `--copy` / `-c` | Copy output to clipboard after a successful run. |
|
|
@@ -374,6 +375,9 @@ sourcecode prepare-context delta . --since main
|
|
|
374
375
|
# Onboard with a ready-to-paste LLM prompt
|
|
375
376
|
sourcecode prepare-context onboard --llm-prompt
|
|
376
377
|
|
|
378
|
+
# PR analysis as a GitHub Markdown comment (paste directly into PR)
|
|
379
|
+
sourcecode prepare-context review-pr --since main --format github-comment
|
|
380
|
+
|
|
377
381
|
# List all tasks
|
|
378
382
|
sourcecode prepare-context --task-help
|
|
379
383
|
```
|
|
@@ -444,22 +448,25 @@ sourcecode prepare-context review-pr
|
|
|
444
448
|
"name": "Order",
|
|
445
449
|
"entry_point": {
|
|
446
450
|
"step": "OrderController.createOrder",
|
|
447
|
-
"notes": [
|
|
451
|
+
"notes": [
|
|
452
|
+
{ "note": "condition: authorization check present (@PreAuthorize / @Secured)",
|
|
453
|
+
"epistemic_level": "STRUCTURAL SIGNAL" }
|
|
454
|
+
]
|
|
448
455
|
},
|
|
449
456
|
"path": [
|
|
450
457
|
{
|
|
451
458
|
"step": "ShippingService.process",
|
|
452
459
|
"notes": [
|
|
453
|
-
"branch: Spring cache
|
|
454
|
-
|
|
460
|
+
{ "note": "branch: Spring cache annotation present — downstream call may be short-circuited",
|
|
461
|
+
"epistemic_level": "STRUCTURAL SIGNAL" },
|
|
462
|
+
{ "note": "async: @Async annotation present — runs in separate thread",
|
|
463
|
+
"epistemic_level": "STRUCTURAL SIGNAL" }
|
|
455
464
|
]
|
|
456
465
|
},
|
|
457
|
-
{
|
|
458
|
-
"step": "OrderRepository.save",
|
|
459
|
-
"notes": []
|
|
460
|
-
}
|
|
466
|
+
{ "step": "OrderRepository.save", "notes": [] }
|
|
461
467
|
],
|
|
462
|
-
"end_state": "DB write"
|
|
468
|
+
"end_state": "DB write",
|
|
469
|
+
"end_state_epistemic_level": "INFERRED (LOW CONFIDENCE)"
|
|
463
470
|
}
|
|
464
471
|
]
|
|
465
472
|
}
|
|
@@ -474,17 +481,33 @@ sourcecode prepare-context review-pr
|
|
|
474
481
|
|
|
475
482
|
**Runtime signals detected per step:**
|
|
476
483
|
|
|
477
|
-
| Signal | Example code | Note emitted |
|
|
478
|
-
|
|
479
|
-
| Auth guard | `@PreAuthorize`, `@Secured
|
|
480
|
-
|
|
|
481
|
-
|
|
|
482
|
-
|
|
|
483
|
-
|
|
|
484
|
-
|
|
|
485
|
-
|
|
|
486
|
-
|
|
|
487
|
-
|
|
|
484
|
+
| Signal | Example code | Note emitted | Epistemic level |
|
|
485
|
+
|--------|-------------|--------------|-----------------|
|
|
486
|
+
| Auth guard | `@PreAuthorize`, `@Secured` | `condition: authorization check present (@PreAuthorize / @Secured)` | `STRUCTURAL SIGNAL` |
|
|
487
|
+
| Auth context read | `isAuthenticated()`, `SecurityContextHolder` | `condition: reads authentication context` | `STRUCTURAL SIGNAL` |
|
|
488
|
+
| Feature flag | `featureFlag.isEnabled()`, `FeatureToggle` | `condition: feature flag gates execution` | `INFERRED (LOW CONFIDENCE)` |
|
|
489
|
+
| Null/empty guard | `if (x == null) return` | `condition: null/empty guard with early return` | `STRUCTURAL SIGNAL` |
|
|
490
|
+
| Spring cache | `@Cacheable`, `@CacheEvict` | `branch: Spring cache annotation present — downstream call may be short-circuited` | `STRUCTURAL SIGNAL` |
|
|
491
|
+
| Manual cache | `cache.get()`, `cacheManager.` | `branch: manual cache lookup detected — downstream call may be short-circuited` | `INFERRED (LOW CONFIDENCE)` |
|
|
492
|
+
| Optional absence | `Optional<>`, `.orElseThrow()` | `branch: Optional type in use — result may be absent` | `STRUCTURAL SIGNAL` |
|
|
493
|
+
| Async thread | `@Async` | `async: @Async annotation present — runs in separate thread` | `STRUCTURAL SIGNAL` |
|
|
494
|
+
| CompletableFuture | `CompletableFuture`, `.supplyAsync()` | `async: CompletableFuture detected — non-blocking execution` | `STRUCTURAL SIGNAL` |
|
|
495
|
+
| Event publishing | `publishEvent()`, `applicationEventPublisher` | `async: Spring application event emitted` | `STRUCTURAL SIGNAL` |
|
|
496
|
+
| Kafka | `kafkaTemplate.`, `KafkaProducer` | `async: Kafka producer detected` | `STRUCTURAL SIGNAL` |
|
|
497
|
+
| RabbitMQ | `rabbitTemplate.`, `amqpTemplate.` | `async: RabbitMQ producer detected` | `STRUCTURAL SIGNAL` |
|
|
498
|
+
|
|
499
|
+
**Epistemic contract:**
|
|
500
|
+
|
|
501
|
+
Every output field in `review-pr` carries an explicit `epistemic_level`:
|
|
502
|
+
|
|
503
|
+
| Level | Meaning |
|
|
504
|
+
|-------|---------|
|
|
505
|
+
| `FACT` | Directly observed in diff (file present, config changed) |
|
|
506
|
+
| `STRUCTURAL SIGNAL` | Annotation or type-system evidence in source (`@Service`, `@Transactional`, injection) |
|
|
507
|
+
| `INFERRED (LOW CONFIDENCE)` | Heuristic pattern match — no full structural proof |
|
|
508
|
+
| `OMITTED` | Insufficient evidence — field not emitted |
|
|
509
|
+
|
|
510
|
+
No field blends certainty levels without labeling. `end_state` (e.g. `"DB write"`) is always accompanied by `end_state_epistemic_level: "INFERRED (LOW CONFIDENCE)"` — it is a keyword-match heuristic, not an AST-verified fact.
|
|
488
511
|
|
|
489
512
|
**Other `review-pr` output fields:**
|
|
490
513
|
|
|
@@ -492,9 +515,9 @@ sourcecode prepare-context review-pr
|
|
|
492
515
|
|-------|-------------|
|
|
493
516
|
| `review_hotspots` | Top changed files ranked by impact score |
|
|
494
517
|
| `suggested_review_order` | Security → API → Service → Persistence → Config |
|
|
495
|
-
| `security_impact` | Changed files
|
|
496
|
-
| `transactional_impact` |
|
|
497
|
-
| `test_coverage_risk` | Changed source files with no corresponding test |
|
|
518
|
+
| `security_impact` | Changed security-classified files (`epistemic_level: STRUCTURAL SIGNAL`) + risk note (`INFERRED (LOW CONFIDENCE)`) |
|
|
519
|
+
| `transactional_impact` | Changed service/business-logic files with possible transaction boundary effect |
|
|
520
|
+
| `test_coverage_risk` | Changed source files with no corresponding test (`epistemic_level: INFERRED (LOW CONFIDENCE)`) |
|
|
498
521
|
| `affected_modules` | DDD domain modules touched by the change |
|
|
499
522
|
|
|
500
523
|
---
|
|
@@ -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.15
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
---
|
|
@@ -134,6 +134,7 @@ sourcecode prepare-context TASK [PATH] [OPTIONS]
|
|
|
134
134
|
|--------|-------------|
|
|
135
135
|
| `--since REF` | Git ref for `delta` task (e.g. `HEAD~3`, `main`, `v1.2.0`). Required for `delta`; ignored for other tasks. |
|
|
136
136
|
| `--symptom TEXT` | *(fix-bug only)* Keyword hint for the bug — boosts matching files and surfaces related code notes. |
|
|
137
|
+
| `--format TEXT` | Output format: `json` (default) \| `github-comment` (Markdown PR comment, `review-pr` only). |
|
|
137
138
|
| `--llm-prompt` | Append a ready-to-use LLM prompt to the output. |
|
|
138
139
|
| `--dry-run` | Show what would be analyzed without running it. |
|
|
139
140
|
| `--copy` / `-c` | Copy output to clipboard after a successful run. |
|
|
@@ -155,6 +156,9 @@ sourcecode prepare-context delta . --since main
|
|
|
155
156
|
# Onboard with a ready-to-paste LLM prompt
|
|
156
157
|
sourcecode prepare-context onboard --llm-prompt
|
|
157
158
|
|
|
159
|
+
# PR analysis as a GitHub Markdown comment (paste directly into PR)
|
|
160
|
+
sourcecode prepare-context review-pr --since main --format github-comment
|
|
161
|
+
|
|
158
162
|
# List all tasks
|
|
159
163
|
sourcecode prepare-context --task-help
|
|
160
164
|
```
|
|
@@ -225,22 +229,25 @@ sourcecode prepare-context review-pr
|
|
|
225
229
|
"name": "Order",
|
|
226
230
|
"entry_point": {
|
|
227
231
|
"step": "OrderController.createOrder",
|
|
228
|
-
"notes": [
|
|
232
|
+
"notes": [
|
|
233
|
+
{ "note": "condition: authorization check present (@PreAuthorize / @Secured)",
|
|
234
|
+
"epistemic_level": "STRUCTURAL SIGNAL" }
|
|
235
|
+
]
|
|
229
236
|
},
|
|
230
237
|
"path": [
|
|
231
238
|
{
|
|
232
239
|
"step": "ShippingService.process",
|
|
233
240
|
"notes": [
|
|
234
|
-
"branch: Spring cache
|
|
235
|
-
|
|
241
|
+
{ "note": "branch: Spring cache annotation present — downstream call may be short-circuited",
|
|
242
|
+
"epistemic_level": "STRUCTURAL SIGNAL" },
|
|
243
|
+
{ "note": "async: @Async annotation present — runs in separate thread",
|
|
244
|
+
"epistemic_level": "STRUCTURAL SIGNAL" }
|
|
236
245
|
]
|
|
237
246
|
},
|
|
238
|
-
{
|
|
239
|
-
"step": "OrderRepository.save",
|
|
240
|
-
"notes": []
|
|
241
|
-
}
|
|
247
|
+
{ "step": "OrderRepository.save", "notes": [] }
|
|
242
248
|
],
|
|
243
|
-
"end_state": "DB write"
|
|
249
|
+
"end_state": "DB write",
|
|
250
|
+
"end_state_epistemic_level": "INFERRED (LOW CONFIDENCE)"
|
|
244
251
|
}
|
|
245
252
|
]
|
|
246
253
|
}
|
|
@@ -255,17 +262,33 @@ sourcecode prepare-context review-pr
|
|
|
255
262
|
|
|
256
263
|
**Runtime signals detected per step:**
|
|
257
264
|
|
|
258
|
-
| Signal | Example code | Note emitted |
|
|
259
|
-
|
|
260
|
-
| Auth guard | `@PreAuthorize`, `@Secured
|
|
261
|
-
|
|
|
262
|
-
|
|
|
263
|
-
|
|
|
264
|
-
|
|
|
265
|
-
|
|
|
266
|
-
|
|
|
267
|
-
|
|
|
268
|
-
|
|
|
265
|
+
| Signal | Example code | Note emitted | Epistemic level |
|
|
266
|
+
|--------|-------------|--------------|-----------------|
|
|
267
|
+
| Auth guard | `@PreAuthorize`, `@Secured` | `condition: authorization check present (@PreAuthorize / @Secured)` | `STRUCTURAL SIGNAL` |
|
|
268
|
+
| Auth context read | `isAuthenticated()`, `SecurityContextHolder` | `condition: reads authentication context` | `STRUCTURAL SIGNAL` |
|
|
269
|
+
| Feature flag | `featureFlag.isEnabled()`, `FeatureToggle` | `condition: feature flag gates execution` | `INFERRED (LOW CONFIDENCE)` |
|
|
270
|
+
| Null/empty guard | `if (x == null) return` | `condition: null/empty guard with early return` | `STRUCTURAL SIGNAL` |
|
|
271
|
+
| Spring cache | `@Cacheable`, `@CacheEvict` | `branch: Spring cache annotation present — downstream call may be short-circuited` | `STRUCTURAL SIGNAL` |
|
|
272
|
+
| Manual cache | `cache.get()`, `cacheManager.` | `branch: manual cache lookup detected — downstream call may be short-circuited` | `INFERRED (LOW CONFIDENCE)` |
|
|
273
|
+
| Optional absence | `Optional<>`, `.orElseThrow()` | `branch: Optional type in use — result may be absent` | `STRUCTURAL SIGNAL` |
|
|
274
|
+
| Async thread | `@Async` | `async: @Async annotation present — runs in separate thread` | `STRUCTURAL SIGNAL` |
|
|
275
|
+
| CompletableFuture | `CompletableFuture`, `.supplyAsync()` | `async: CompletableFuture detected — non-blocking execution` | `STRUCTURAL SIGNAL` |
|
|
276
|
+
| Event publishing | `publishEvent()`, `applicationEventPublisher` | `async: Spring application event emitted` | `STRUCTURAL SIGNAL` |
|
|
277
|
+
| Kafka | `kafkaTemplate.`, `KafkaProducer` | `async: Kafka producer detected` | `STRUCTURAL SIGNAL` |
|
|
278
|
+
| RabbitMQ | `rabbitTemplate.`, `amqpTemplate.` | `async: RabbitMQ producer detected` | `STRUCTURAL SIGNAL` |
|
|
279
|
+
|
|
280
|
+
**Epistemic contract:**
|
|
281
|
+
|
|
282
|
+
Every output field in `review-pr` carries an explicit `epistemic_level`:
|
|
283
|
+
|
|
284
|
+
| Level | Meaning |
|
|
285
|
+
|-------|---------|
|
|
286
|
+
| `FACT` | Directly observed in diff (file present, config changed) |
|
|
287
|
+
| `STRUCTURAL SIGNAL` | Annotation or type-system evidence in source (`@Service`, `@Transactional`, injection) |
|
|
288
|
+
| `INFERRED (LOW CONFIDENCE)` | Heuristic pattern match — no full structural proof |
|
|
289
|
+
| `OMITTED` | Insufficient evidence — field not emitted |
|
|
290
|
+
|
|
291
|
+
No field blends certainty levels without labeling. `end_state` (e.g. `"DB write"`) is always accompanied by `end_state_epistemic_level: "INFERRED (LOW CONFIDENCE)"` — it is a keyword-match heuristic, not an AST-verified fact.
|
|
269
292
|
|
|
270
293
|
**Other `review-pr` output fields:**
|
|
271
294
|
|
|
@@ -273,9 +296,9 @@ sourcecode prepare-context review-pr
|
|
|
273
296
|
|-------|-------------|
|
|
274
297
|
| `review_hotspots` | Top changed files ranked by impact score |
|
|
275
298
|
| `suggested_review_order` | Security → API → Service → Persistence → Config |
|
|
276
|
-
| `security_impact` | Changed files
|
|
277
|
-
| `transactional_impact` |
|
|
278
|
-
| `test_coverage_risk` | Changed source files with no corresponding test |
|
|
299
|
+
| `security_impact` | Changed security-classified files (`epistemic_level: STRUCTURAL SIGNAL`) + risk note (`INFERRED (LOW CONFIDENCE)`) |
|
|
300
|
+
| `transactional_impact` | Changed service/business-logic files with possible transaction boundary effect |
|
|
301
|
+
| `test_coverage_risk` | Changed source files with no corresponding test (`epistemic_level: INFERRED (LOW CONFIDENCE)`) |
|
|
279
302
|
| `affected_modules` | DDD domain modules touched by the change |
|
|
280
303
|
|
|
281
304
|
---
|
|
@@ -1622,6 +1622,11 @@ def prepare_context_cmd(
|
|
|
1622
1622
|
"--symptom",
|
|
1623
1623
|
help="(fix-bug) Keyword hint for the bug: boosts matching files and surfaces related code notes.",
|
|
1624
1624
|
),
|
|
1625
|
+
format: Optional[str] = typer.Option(
|
|
1626
|
+
None,
|
|
1627
|
+
"--format",
|
|
1628
|
+
help="Output format: json (default) | github-comment (Markdown PR comment for review-pr task)",
|
|
1629
|
+
),
|
|
1625
1630
|
) -> None:
|
|
1626
1631
|
"""Task-specific context for AI coding agents.
|
|
1627
1632
|
|
|
@@ -1895,7 +1900,12 @@ def prepare_context_cmd(
|
|
|
1895
1900
|
if llm_prompt:
|
|
1896
1901
|
out["llm_prompt"] = builder.render_prompt(output)
|
|
1897
1902
|
|
|
1898
|
-
|
|
1903
|
+
if format == "github-comment" and task == "review-pr":
|
|
1904
|
+
from sourcecode.pr_comment_renderer import render_github_comment
|
|
1905
|
+
_pc_content = render_github_comment(out)
|
|
1906
|
+
else:
|
|
1907
|
+
_pc_content = json.dumps(out, indent=2, ensure_ascii=False)
|
|
1908
|
+
|
|
1899
1909
|
if output_path is not None:
|
|
1900
1910
|
output_path.write_text(_pc_content, encoding="utf-8")
|
|
1901
1911
|
else:
|